diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..0097893 Binary files /dev/null and b/.DS_Store differ diff --git a/SYNC_INSTRUCTIONS_FIELD.md b/SYNC_INSTRUCTIONS_FIELD.md new file mode 100644 index 0000000..715dd1c --- /dev/null +++ b/SYNC_INSTRUCTIONS_FIELD.md @@ -0,0 +1,96 @@ +# Agent-Sync: Add `instructions` Field + +## Background + +AgentHub now supports an `instructions` field on agents. This field stores the **system prompt** from LibreChat agents (the `instructions` field in the LibreChat `agents` collection). The AgentHub collector API (`POST /agents`) accepts `instructions` as an optional string field. + +This document describes the two changes needed in the agent-sync tool to start syncing instructions through. + +--- + +## Change 1: `export_shared_agents.js` — Include `instructions` in the output + +The MongoDB aggregation pipeline already does a `$lookup` against the `agents` collection and stores the result in `agentDetails`. The `instructions` field exists on LibreChat agent documents but is currently excluded in the final `$project` stage (only `versions` is explicitly excluded, but `instructions` needs to survive the pipeline). + +**What to verify:** Run this query in mongosh to confirm the field exists: + +```js +use LibreChat +db.agents.find({}, { name: 1, instructions: 1, _id: 0 }).limit(5).pretty() +``` + +You should see output like: + +```js +{ name: "Test-Demo-Agent", instructions: "talk like a pirate" } +``` + +**What to check in the pipeline:** The `agentDetails` object (from the `$lookup` on the `agents` collection) should already contain `instructions` since it's not excluded. The final `$project` stage (around line 199) only excludes `agentDetails.versions`, `authorDetails`, `usageTimeline`, `usageSummary`, and `tokenUsage` — so `instructions` should flow through inside `agentDetails`. + +**Action:** After export runs, verify `instructions` appears in `shared_agents.json`: + +```bash +cat shared_agents.json | jq '.[0].agentDetails.instructions' +``` + +If it returns `null` for agents that should have instructions, the pipeline may need an explicit `$addFields` or the field path may differ. Debug with: + +```bash +docker exec -i chat-mongodb mongosh --quiet LibreChat --eval 'JSON.stringify(db.agents.findOne({name: "Test-Demo-Agent"}, {instructions: 1}), null, 2)' +``` + +--- + +## Change 2: `register_agents.py` — Map `instructions` in `build_payload()` + +The `build_payload()` function maps exported agent fields to the AgentHub collector API schema. Add `instructions` to the payload. + +### Current code (around line 97): + +```python +description = agent.get("description") or agent.get("instructions") or f"{name} agent" +``` + +This currently uses `instructions` only as a **fallback** for description. Keep that fallback, but also pass `instructions` as its own field. + +### What to add: + +In the `build_payload()` function, add `instructions` to the payload dict. Find the section where core fields are assembled (around lines 95-105) and add: + +```python +"instructions": agent.get("instructions"), +``` + +### Where the field comes from: + +The exported JSON nests agent data inside `agentDetails`. Check how `build_payload()` receives its data — if it receives the top-level export object, the path is `agent.get("agentDetails", {}).get("instructions")`. If it receives the unwrapped `agentDetails` object directly, it's just `agent.get("instructions")`. + +Look at how `description` or `name` are accessed in `build_payload()` to determine which pattern to follow. + +### Pruning: + +The function already prunes `None` values at the end (around line 187-191), so if an agent has no instructions, the field simply won't be sent and AgentHub will store `null`. + +--- + +## Testing + +1. Run the export: `bash weekly_agent_sync.sh` +2. Check the exported JSON: + ```bash + cat shared_agents.json | jq '[.[] | {name: .agentDetails.name, instructions: .agentDetails.instructions}]' + ``` +3. Check the AgentHub API received it — log into AgentHub as admin and look for the "Instructions" badge on agent rows in the admin dashboard +4. Or query directly: + ```bash + curl -s -H "X-API-Key: $AGENT_COLLECTOR_API_KEY" https://your-agenthub-url/agents | jq '.instructions' + ``` + +--- + +## Summary + +| File | Change | Effort | +|------|--------|--------| +| `export_shared_agents.js` | Verify `instructions` survives the pipeline (likely no code change needed) | Small — verify and test | +| `register_agents.py` | Add `"instructions": agent.get("instructions")` to `build_payload()` | One line | diff --git a/register_agents.py b/register_agents.py index d4ab93d..e3c951d 100755 --- a/register_agents.py +++ b/register_agents.py @@ -170,6 +170,8 @@ def build_payload(agent: Dict[str, Any]) -> Dict[str, Any]: "metadata": metadata or None, # System prompt for audit analysis: "system_prompt": agent.get("instructions") or None, + # Instructions field (AgentHub): + "instructions": agent.get("instructions") or None, # Agent URL: "url": agent_url, # Usage data: