commiting my hr_agent branch

This commit is contained in:
Salman Paracha 2024-10-12 17:58:35 -07:00
parent f72588c6da
commit 341344a583
6 changed files with 223 additions and 0 deletions

19
demos/hr_agent/Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM python:3.10 AS base
FROM base AS builder
WORKDIR /src
COPY requirements.txt /src/
RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
COPY . /src
FROM python:3.10-slim AS output
COPY --from=builder /runtime /usr/local
COPY . /app
WORKDIR /app
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--log-level", "info"]

View file

@ -0,0 +1,58 @@
version: v0.1
listener:
address: 127.0.0.1
port: 8080 #If you configure port 443, you'll need to update the listener with tls_certificates
message_format: huggingface
# Centralized way to manage LLMs, manage keys, retry logic, failover and limits in a central way
llm_providers:
- name: OpenAI
provider: openai
access_key: OPENAI_API_KEY
model: gpt-4o
default: true
# default system prompt used by all prompt targets
system_prompt: |
You are a HR agent assistant that helps HR decision makers with reporting and workfoce planning. Nothing else. Please stay on topic of HR.
prompt_targets:
- name: headcount
description: Get headcount data for a region by staffing type
endpoint:
name: app_server
path: /agent/headcount
parameters:
- name: staffing_type
type: str
description: The staffing type like contract, fte or agency
required: true
- name: region
type: str
required: true
description: the geographical region for which you want head count data.
- name: hr_qa
endpoint:
name: app_server
path: /agent/hr_qa
description: Handle general Q/A related to HR.
default: true
# Arch creates a round-robin load balancing between different endpoints, managed via the cluster subsystem.
endpoints:
app_server:
# value could be ip address or a hostname with port
# this could also be a list of endpoints for load balancing
# for example endpoint: [ ip1:port, ip2:port ]
endpoint: host.docker.internal:18083
# max time to wait for a connection to be established
connect_timeout: 0.005s
ratelimits:
- model: gpt-4
selector:
key: selector-key
value: selector-value
limit:
tokens: 1
unit: minute

View file

@ -0,0 +1,23 @@
services:
api_server:
build:
context: .
dockerfile: Dockerfile
ports:
- "18083:80"
healthcheck:
test: ["CMD", "curl" ,"http://localhost:80/healthz"]
interval: 5s
retries: 20
chatbot_ui:
build:
context: ../../chatbot_ui
dockerfile: Dockerfile
ports:
- "18080:8080"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY:?error}
- CHAT_COMPLETION_ENDPOINT=http://host.docker.internal:10000/v1
extra_hosts:
- "host.docker.internal:host-gateway"

73
demos/hr_agent/main.py Normal file
View file

@ -0,0 +1,73 @@
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import List, Optional
from enum import Enum
import re
app = FastAPI()
class StaffingType(Enum):
CONTRACT = "contract"
FTE = "fte"
AGENCY = "agency"
# Define the request model
class HeadcountRequest(BaseModel):
region: str
staffing_type: str
class HeadcountResponseSummary(BaseModel):
region: str
headcount: int
staffing_type: str
# Post method for device summary
@app.post("/agent/headcount")
def get_headcount(request: HeadcountRequest):
"""
Endpoint to headcount data by region, staffing type over time range
"""
staffing_type_value = request.staffing_type
if re.match(r"(?i)contract", staffing_type_value): # Case-insensitive regex match
headcount = 500
elif re.match(r"(?i)fte", staffing_type_value):
headcount = 1000
elif re.match(r"(?i)agency", staffing_type_value):
headcount = 4000
else:
raise HTTPException(
status_code=400, detail="staffing_type parameter is invalid."
)
response = {
"region": request.region,
"staffing_type": f"Staffing agency: {staffing_type_value}",
"headcount" : f"Headcount: {headcount}"
}
return response
@app.post("/agent/hr_qa")
async def general_hr_qa():
"""
This method handles Q/A related to general issues in HR.
It forwards the conversation to the OpenAI client via a local proxy and returns the response.
"""
return {
"choices": [
{
"message": {
"role": "assistant",
"content": "I am a helpful HR agent, and I can help you plan for workforce related questions",
},
"finish_reason": "completed",
"index": 0,
}
],
"model": "hr_agent",
"usage": {"completion_tokens": 0},
}
if __name__ == "__main__":
app.run(debug=True)

View file

@ -0,0 +1,4 @@
fastapi
uvicorn
pydantic
typing

View file

@ -0,0 +1,46 @@
#!/bin/bash
# Function to start the demo
start_demo() {
# Step 1: Check if .env file exists
if [ -f ".env" ]; then
echo ".env file already exists. Skipping creation."
else
# Step 2: Create `.env` file and set OpenAI key
if [ -z "$OPENAI_API_KEY" ]; then
echo "Error: OPENAI_API_KEY environment variable is not set for the demo."
exit 1
fi
echo "Creating .env file..."
echo "OPENAI_API_KEY=$OPENAI_API_KEY" > .env
echo ".env file created with OPENAI_API_KEY."
fi
# Step 3: Start Arch
echo "Starting Arch with arch_config.yaml..."
archgw up arch_config.yaml
# Step 4: Start Network Agent
echo "Starting Network Agent using Docker Compose..."
docker compose up -d # Run in detached mode
}
# Function to stop the demo
stop_demo() {
# Step 1: Stop Docker Compose services
echo "Stopping Network Agent using Docker Compose..."
docker compose down
# Step 2: Stop Arch
echo "Stopping Arch..."
archgw down
}
# Main script logic
if [ "$1" == "down" ]; then
stop_demo
else
# Default action is to bring the demo up
start_demo
fi