committing to merge with main

This commit is contained in:
Salman Paracha 2024-10-22 17:01:23 -07:00
parent d799fc98fd
commit aa21f41d0b
6 changed files with 111 additions and 53 deletions

View file

@ -5,6 +5,7 @@ FROM base AS builder
WORKDIR /src
COPY requirements.txt /src/
COPY workforce_data.json /src/
RUN pip install --prefix=/runtime --force-reinstall -r requirements.txt
COPY . /src

View file

@ -27,11 +27,17 @@ 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
- name: hr_qa
endpoint:
name: app_server
path: /agent/headcount
path: /agent/hr_qa
description: Handle general Q/A related to HR.
default: true
- name: workforce
description: Get workforce data like headcount and satisfacton levels by region and staffing type
endpoint:
name: app_server
path: /agent/workforce
parameters:
- name: staffing_type
type: str
@ -40,10 +46,18 @@ prompt_targets:
- name: region
type: str
required: true
description: the geographical region for which you want headcount data.
- name: hr_qa
description: the geographical region for which you want workforce data.
- name: point_in_time
type: int
required: false
description: a point in time for which to retrieve data. For e.g 0 days ago, 30 days ago, etc.
- name: slack_message
endpoint:
name: app_server
path: /agent/hr_qa
description: Handle general Q/A related to HR.
default: true
path: /agent/slack_message
description: sends a slack message on a channel
parameters:
- name: slack_message
type: string
required: true
description: the message that should be sent to a slack channel

View file

@ -3,6 +3,8 @@ services:
build:
context: .
dockerfile: Dockerfile
environment:
- SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:?error}
ports:
- "18083:80"
healthcheck:

View file

@ -1,72 +1,82 @@
import os
import json
import pandas as pd
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import List, Optional
from typing import Optional
from enum import Enum
import re
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
app = FastAPI()
workforce_data_df = None
class StaffingType(Enum):
FTE = "fte"
AGENCY = "agency"
CONTRACT = "contract"
class RegionType(Enum):
ASIA = "asia"
EUROPE = "europe"
AMERICAS = "americas"
with open("workforce_data.json") as file:
workforce_data = json.load(file)
workforce_data_df = pd.json_normalize(
workforce_data, record_path=["regions"], meta=["point_in_time", "satisfaction"]
)
# Define the request model
class HeadcountRequest(BaseModel):
region: RegionType
staffing_type: StaffingType
class HeadcountResponseSummary(BaseModel):
class WorkforceRequset(BaseModel):
region: str
headcount: int
staffing_type: str
point_in_time: Optional[int] = None
HEADCOUNT = {
RegionType.ASIA: {
StaffingType.CONTRACT: 100,
StaffingType.FTE: 150,
StaffingType.AGENCY: 2000,
},
RegionType.EUROPE: {
StaffingType.CONTRACT: 80,
StaffingType.FTE: 120,
StaffingType.AGENCY: 2500,
},
RegionType.AMERICAS: {
StaffingType.CONTRACT: 90,
StaffingType.FTE: 200,
StaffingType.AGENCY: 3000,
},
}
class SlackRequest(BaseModel):
slack_message: str
class WorkforceResponse(BaseModel):
region: str
staffing_type: str
headcount: int
satisfaction: float
# Post method for device summary
@app.post("/agent/headcount")
def get_headcount(request: HeadcountRequest):
@app.post("/agent/workforce")
def get_workforce(request: WorkforceRequset):
"""
Endpoint to headcount data by region, staffing type over time range
Endpoint to workforce data by region, staffing type at a given point in time.
"""
headcount = HEADCOUNT[request.region][request.staffing_type]
region = request.region.lower()
staffing_type = request.staffing_type.lower()
point_in_time = request.point_in_time if request.point_in_time else 0
response = {
"region": request.region.value,
"staffing_type": f"Staffing agency: {request.staffing_type}",
"headcount": f"Headcount: {headcount}",
"region": region,
"staffing_type": f"Staffing agency: {staffing_type}",
"headcount": f"Headcount: {int(workforce_data_df[(workforce_data_df['region']==region) & (workforce_data_df['point_in_time']==point_in_time)][staffing_type].values[0])}",
"satisfaction": f"Satisifaction: {float(workforce_data_df[(workforce_data_df['region']==region) & (workforce_data_df['point_in_time']==point_in_time)][satisfaction].values[0])}",
}
return response
@app.post("/agent/slack_message")
def send_slack_message(request: SlackRequest):
"""
Endpoint that sends slack message
"""
slack_message = request.slack_message
# Load the bot token from an environment variable or replace it directly
slack_token = os.getenv(
"SLACK_BOT_TOKEN"
) # Replace with your token if needed: 'xoxb-your-token'
client = WebClient(token=slack_token)
channel = "hr_agent_demo"
try:
# Send the message
response = client.chat_postMessage(channel=channel, text=slack_message)
return f"Message sent to {channel}: {response['message']['text']}"
except SlackApiError as e:
print(f"Error sending message: {e.response['error']}")
@app.post("/agent/hr_qa")
async def general_hr_qa():
"""

View file

@ -1,4 +1,6 @@
fastapi
uvicorn
pydantic
slack-sdk
typing
pandas

View file

@ -0,0 +1,29 @@
[
{
"point_in_time": 0,
"regions": [
{ "region": "asia", "contract": 100, "fte": 150, "agency": 2000 },
{ "region": "europe", "contract": 80, "fte": 120, "agency": 2500 },
{ "region": "americas", "contract": 90, "fte": 200, "agency": 3100 }
],
"satisfaction": 3.5
},
{
"point_in_time": 30,
"regions": [
{ "region": "asia", "contract": 110, "fte": 155, "agency": 1000 },
{ "region": "europe", "contract": 85, "fte": 130, "agency": 1600 },
{ "region": "americas", "contract": 95, "fte": 210, "agency": 3100 }
],
"satisfaction": 4.0
},
{
"point_in_time": 60,
"regions": [
{ "region": "asia", "contract": 115, "fte": 160, "agency": 500 },
{ "region": "europe", "contract": 90, "fte": 140, "agency": 700 },
{ "region": "americas", "contract": 100, "fte": 220, "agency": 1200 }
],
"satisfaction": 4.7
}
]