initial commit

This commit is contained in:
Michael Clervi 2025-10-21 11:28:59 +00:00
commit a0d7f6ed26
6 changed files with 837 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
venv/
log/

36
export_shared_agents.js Executable file
View file

@ -0,0 +1,36 @@
// export_shared_agents.js
// Emits strict Extended JSON to stdout (safe JSON for ObjectId/Date)
const pipeline = [
{ $match: { resourceType: "agent" } },
{ $group: { _id: "$resourceId", count: { $sum: 1 } } },
{ $match: { count: { $gt: 1 } } },
{
$lookup: {
from: "agents",
localField: "_id",
foreignField: "_id",
as: "agentDetails"
}
},
{ $unwind: "$agentDetails" },
{
$lookup: {
from: "users",
localField: "agentDetails.author",
foreignField: "_id",
as: "authorDetails"
}
},
{ $unwind: { path: "$authorDetails", preserveNullAndEmptyArrays: true } },
{ $set: { "agentDetails.author": "$authorDetails.email" } },
{ $project: {
"agentDetails.versions": 0,
"agentDetails.instructions": 0,
"authorDetails": 0
}
}
];
const out = db.aclentries.aggregate(pipeline).toArray();
print(EJSON.stringify(out, { relaxed: false, indent: 2 }));

288
register_agents.py Executable file
View file

@ -0,0 +1,288 @@
#!/usr/bin/env python3
"""
Register agents from a JSON file with the Agent Registration API.
Usage:
python register_agents.py --input /path/to/shared_agents.json \
[--base-url https://ai-sandbox.oliver.solutions/agent_collector/agents] \
[--api-key YOUR_KEY] \
[--dry-run]
Notes:
- If --api-key is not provided, the script will fall back to the static key from the docs.
- The input can be either:
* a list of agent documents, or
* a list of wrapper objects that contain an "agentDetails" object (common when exported from MongoDB aggregations).
- The script maps fields best-effort to the API schema and prunes any empty/None fields.
"""
import argparse
import json
import os
import re
import sys
import time
import urllib3
from typing import Any, Dict, List, Optional
# Suppress SSL warnings when verification is disabled
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
try:
import requests # type: ignore
except Exception as e:
print("This script requires the 'requests' package. Install with: pip install requests")
raise
DEFAULT_BASE_URL = "https://ai-sandbox.oliver.solutions/agent_collector/agents"
# Fallback to the static key from the documentation if not supplied via --api-key
DEFAULT_API_KEY = "agent-collector-static-key-2024-secure"
def parse_iso(value: Any) -> Optional[str]:
"""
Best-effort: return ISO8601 string or None.
- If value is already a string, return it (assuming it's already ISO8601).
- If value looks like 'ISODate(\"...\")', extract the inner string.
- Otherwise, return None.
"""
if value is None:
return None
if isinstance(value, str):
# Handle Mongo shell export style: ISODate('2025-07-09T06:33:12.682Z')
m = re.match(r"^ISODate\(['\"]?([^'\"]+)['\"]?\)$", value.strip())
return m.group(1) if m else value
# Could try to parse datetime objects here if needed; for now, prefer string passthrough
return None
def ensure_list_of_str(value: Any) -> Optional[List[str]]:
"""Convert to a list[str] if reasonable; otherwise return None."""
if value is None:
return None
if isinstance(value, list):
out = []
for v in value:
if isinstance(v, str):
out.append(v)
else:
out.append(str(v))
return out if out else None
# Single string -> wrap
if isinstance(value, str) and value.strip():
return [value]
return None
def extract_agent(doc: Dict[str, Any]) -> Dict[str, Any]:
"""Handle two shapes: raw agent doc OR wrapper { ..., agentDetails: {...} }"""
if isinstance(doc, dict) and "agentDetails" in doc and isinstance(doc["agentDetails"], dict):
return doc["agentDetails"]
return doc
def build_payload(agent: Dict[str, Any]) -> Dict[str, Any]:
"""
Map agent fields to Agent Registration API payload.
Required by API: name, description, purpose, tool
Optional fields are filled best-effort; empty/None/blank fields are pruned.
"""
name = agent.get("name") or agent.get("id") or str(agent.get("_id") or "Unnamed Agent")
description = agent.get("description") or agent.get("instructions") or f"{name} agent"
purpose = agent.get("purpose") or description
# API's "tool" = platform where agent operates; best-effort map to provider
tool = "LibreChat (chat-sandbox)"
# Optional mappings
version = agent.get("version") or agent.get("model")
creation_date = parse_iso(agent.get("createdAt"))
last_updated = parse_iso(agent.get("updatedAt"))
capabilities = ensure_list_of_str(agent.get("capabilities") or agent.get("tools"))
department = agent.get("department") or agent.get("category")
# contact_person: prefer a support contact email or name; else use author (often email)
contact_person = None
sc = agent.get("support_contact")
if isinstance(sc, dict):
contact_person = sc.get("email") or sc.get("name")
if not contact_person:
contact_person = agent.get("contact_person") or agent.get("author")
# tags: compact context about provider/model/category
tags = [t for t in [agent.get("provider"), agent.get("model"), agent.get("category")] if t]
# metadata: stash extras for traceability
avatar_path = None
avatar = agent.get("avatar")
if isinstance(avatar, dict):
avatar_path = avatar.get("filepath")
elif isinstance(avatar, str):
avatar_path = avatar
metadata = {
"source_id": agent.get("id"),
"provider": agent.get("provider"),
"model": agent.get("model"),
"artifacts": agent.get("artifacts"),
"tool_kwargs": agent.get("tool_kwargs"),
"agent_ids": agent.get("agent_ids"),
"projectIds": agent.get("projectIds"),
"avatar": avatar_path,
"author_email": agent.get("author"),
"raw_category": agent.get("category"),
}
# Prune empty metadata
metadata = {k: v for k, v in metadata.items() if v not in (None, "", [], {})}
payload: Dict[str, Any] = {
"name": name,
"description": description,
"purpose": purpose,
"tool": tool,
# Optionals:
"version": version,
"creation_date": creation_date,
"last_updated": last_updated,
"capabilities": capabilities,
"department": department,
"contact_person": contact_person,
"tags": tags or None,
"metadata": metadata or None,
}
# Final prune of empties so the API only sees meaningful data
for k in list(payload.keys()):
if payload[k] in (None, "", [], {}):
payload.pop(k, None)
return payload
def post_agent(session: requests.Session, base_url: str, api_key: str, payload: Dict[str, Any],
retries: int = 3, backoff: float = 1.5) -> Dict[str, Any]:
"""POST with simple retry on transient errors. Return parsed JSON or a structured error."""
headers = {
"Content-Type": "application/json",
"X-API-Key": api_key,
}
attempt = 0
last_err: Optional[str] = None
while attempt <= retries:
try:
resp = session.post(base_url, headers=headers, json=payload, timeout=30)
if resp.status_code >= 200 and resp.status_code < 300:
try:
return {"ok": True, "status_code": resp.status_code, "data": resp.json(), "payload_name": payload.get("name")}
except Exception:
return {"ok": True, "status_code": resp.status_code, "data": {"raw": resp.text}, "payload_name": payload.get("name")}
else:
# Retry on 429/5xx
if resp.status_code in (429, 500, 502, 503, 504) and attempt < retries:
time.sleep((attempt + 1) * backoff)
attempt += 1
continue
try:
detail = resp.json()
except Exception:
detail = {"raw": resp.text}
return {"ok": False, "status_code": resp.status_code, "error": detail, "payload_name": payload.get("name")}
except requests.RequestException as e:
last_err = str(e)
if attempt < retries:
time.sleep((attempt + 1) * backoff)
attempt += 1
continue
return {"ok": False, "status_code": None, "error": {"exception": last_err}, "payload_name": payload.get("name")}
return {"ok": False, "status_code": None, "error": {"exception": last_err or "unknown"}, "payload_name": payload.get("name")}
def load_records(path: str) -> List[Dict[str, Any]]:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
if isinstance(data, dict) and "agents" in data and isinstance(data["agents"], list):
items = data["agents"]
elif isinstance(data, list):
items = data
else:
raise ValueError("Unrecognized JSON structure. Expected a list, or an object with an 'agents' list.")
return [extract_agent(item) for item in items]
def main():
parser = argparse.ArgumentParser(description="Register agents with the Agent Registration API")
parser.add_argument("--input", "-i", default="shared_agents.json", help="Path to input JSON (default: shared_agents.json)")
parser.add_argument("--base-url", default=os.environ.get("AGENT_REG_URL", DEFAULT_BASE_URL),
help=f"API endpoint URL (default: {DEFAULT_BASE_URL})")
parser.add_argument("--api-key", default=os.environ.get("AGENT_REG_KEY", DEFAULT_API_KEY),
help="API key (default: uses static key from the docs unless AGENT_REG_KEY is set)")
parser.add_argument("--dry-run", action="store_true", help="Print payloads without sending to the API")
parser.add_argument("--save-log", default="registration_results.json", help="Path to write results log JSON")
args = parser.parse_args()
# Load items
try:
agents = load_records(args.input)
except Exception as e:
print(f"Failed to load input JSON: {e}")
sys.exit(2)
session = requests.Session()
# Disable SSL certificate verification for development/internal APIs
session.verify = False
# Create an adapter with SSL verification disabled
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
from urllib3.util import ssl_
class SSLAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
kwargs['ssl_context'] = ssl_.create_urllib3_context()
kwargs['ssl_context'].check_hostname = False
kwargs['ssl_context'].verify_mode = 0
return super().init_poolmanager(*args, **kwargs)
session.mount('https://', SSLAdapter())
results: List[Dict[str, Any]] = []
success = 0
usage_logged = 0
failures = 0
for idx, agent in enumerate(agents, start=1):
payload = build_payload(agent)
if args.dry_run:
print(f"[DRY RUN {idx}/{len(agents)}] Would register: {payload.get('name')}")
print(json.dumps(payload, indent=2, ensure_ascii=False))
results.append({"ok": True, "dry_run": True, "payload": payload})
continue
res = post_agent(session, args.base_url, args.api_key, payload)
results.append(res)
if res.get("ok"):
data = res.get("data", {})
status = str(data.get("status", "")).lower()
if status == "usage_logged":
usage_logged += 1
print(f"[{idx}/{len(agents)}] Usage tracked for existing agent: {payload.get('name')}")
else:
success += 1
print(f"[{idx}/{len(agents)}] Registered: {payload.get('name')}")
else:
failures += 1
print(f"[{idx}/{len(agents)}] FAILED for {payload.get('name')}: {res.get('error')}")
# Write log
try:
with open(args.save_log, "w", encoding="utf-8") as f:
json.dump(results, f, indent=2, ensure_ascii=False)
print(f"\nWrote results to {args.save_log}")
except Exception as e:
print(f"Failed to write results log: {e}")
print(f"\nSummary: registered={success}, usage_logged={usage_logged}, failed={failures}, total={len(agents)}")
if __name__ == "__main__":
main()

472
registration_results.json Normal file
View file

@ -0,0 +1,472 @@
[
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Risk Management Simulator"
},
"payload_name": "Risk Management Simulator"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "GenAI Scale - Image Evaluator "
},
"payload_name": "GenAI Scale - Image Evaluator "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Oliver Prospect Agent"
},
"payload_name": "Oliver Prospect Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Open AI Image Generator"
},
"payload_name": "Open AI Image Generator"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Veo3 Prompt Builder"
},
"payload_name": "Veo3 Prompt Builder"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "WBS AGENT"
},
"payload_name": "WBS AGENT"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Nano Banana"
},
"payload_name": "Nano Banana"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Terry Translate"
},
"payload_name": "Terry Translate"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "clervi test agent"
},
"payload_name": "clervi test agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Dev - Solve Design"
},
"payload_name": "Dev - Solve Design"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "H&M | HR_hr glossary"
},
"payload_name": "H&M | HR_hr glossary"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Dove - brand tone & copywriting"
},
"payload_name": "Dove - brand tone & copywriting"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "The Agent-Agent"
},
"payload_name": "The Agent-Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": " Copywriting - B&W, BAIS, Legal Social Adaptation"
},
"payload_name": " Copywriting - B&W, BAIS, Legal Social Adaptation"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "GPT-Image-1 Prompt Builder"
},
"payload_name": "GPT-Image-1 Prompt Builder"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "AI Opportunity Guide"
},
"payload_name": "AI Opportunity Guide"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Matthieu Math"
},
"payload_name": "Matthieu Math"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Sustainability POC"
},
"payload_name": "Sustainability POC"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "DEI Agent"
},
"payload_name": "DEI Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Bria"
},
"payload_name": "Bria"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Leadership Update Creator"
},
"payload_name": "Leadership Update Creator"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "BeakMail - Release Email Generator"
},
"payload_name": "BeakMail - Release Email Generator"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "OLIVER Case Study Agent"
},
"payload_name": "OLIVER Case Study Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "H&M - MPC KB"
},
"payload_name": "H&M - MPC KB"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "success",
"message": "Agent data collected successfully",
"agent_id": "68c2ade635df973fa04ea5fb"
},
"payload_name": "Barclaycard Daily Brand Opportunities "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "MPC - Project Plan Builder"
},
"payload_name": "MPC - Project Plan Builder"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Copywriting - crafting competitive claims "
},
"payload_name": "Copywriting - crafting competitive claims "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "success",
"message": "Agent data collected successfully",
"agent_id": "68c2ade635df973fa04ea5fe"
},
"payload_name": "Barclaycard TOV"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "OLIVER Scale - Idea Evaluator "
},
"payload_name": "OLIVER Scale - Idea Evaluator "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Social copy - crafting social copy"
},
"payload_name": "Social copy - crafting social copy"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "TEXTOS DE APOIO - ITAÚ"
},
"payload_name": "TEXTOS DE APOIO - ITAÚ"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Infinite Idea Generator Agent"
},
"payload_name": "Infinite Idea Generator Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "U-Studio awards case-study writer "
},
"payload_name": "U-Studio awards case-study writer "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "U-Studio PM Helper (UK)"
},
"payload_name": "U-Studio PM Helper (UK)"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "H&M - CIA (Pilot 4012)"
},
"payload_name": "H&M - CIA (Pilot 4012)"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "U-Studio job description writer "
},
"payload_name": "U-Studio job description writer "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Internal Training Comms Assistant"
},
"payload_name": "Internal Training Comms Assistant"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Runway Prompt Helper"
},
"payload_name": "Runway Prompt Helper"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "BAIS Helper (Brazil)"
},
"payload_name": "BAIS Helper (Brazil)"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Slipstream Brief Builder Ai - AJ (TEST GROUP ONLY)"
},
"payload_name": "Slipstream Brief Builder Ai - AJ (TEST GROUP ONLY)"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Latam BR - Revisor Gramatical (RevisAI)"
},
"payload_name": "Latam BR - Revisor Gramatical (RevisAI)"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Pencil Training Material Agent"
},
"payload_name": "Pencil Training Material Agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Category entry points agent"
},
"payload_name": "Category entry points agent"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "QC Buddy"
},
"payload_name": "QC Buddy"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Agent Billie Billing Email Assistant"
},
"payload_name": "Agent Billie Billing Email Assistant"
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Comms Writing Assistant "
},
"payload_name": "Comms Writing Assistant "
},
{
"ok": true,
"status_code": 200,
"data": {
"status": "usage_logged",
"message": "Agent already exists, usage tracked",
"agent_name": "Instructional Design Assistant "
},
"payload_name": "Instructional Design Assistant "
}
]

1
shared_agents.json Normal file

File diff suppressed because one or more lines are too long

38
weekly_agent_sync.sh Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -euo pipefail
# ======== CONFIGURE THESE ========
MONGO_CONT="chat-mongodb" # Docker container name/ID for MongoDB
DB_NAME="LibreChat" # MongoDB database name
EXPORT_JS="/opt/agent-sync/export_shared_agents.js"
OUT_JSON="/opt/agent-sync/shared_agents.json"
PY_SCRIPT="/opt/agent-sync/register_agents.py"
# Path to the Python executable inside your EXISTING venv
VENV_PY="/opt/agent-sync/venv/bin/python"
# Optional log file; set to /dev/null to disable
LOG_FILE="/opt/agent-sync/log/agent_sync.log"
# =================================
timestamp() { date -Is; }
# quick sanity checks
[[ -x "$VENV_PY" ]] || { echo "[$(timestamp)] ERROR: venv python not found at $VENV_PY"; exit 1; }
command -v docker >/dev/null 2>&1 || { echo "[$(timestamp)] ERROR: docker not found"; exit 1; }
echo "[$(timestamp)] Starting weekly agent sync" >> "$LOG_FILE"
# 1) Export from Mongo (valid JSON to host file)
docker exec -i "$MONGO_CONT" env MONGOSH_NO_RC=1 mongosh --norc --quiet "$DB_NAME" --file /dev/stdin < "$EXPORT_JS" > "$OUT_JSON"
# 2) (Optional) sanity-check JSON if jq is present
if command -v jq >/dev/null 2>&1; then
jq -e . "$OUT_JSON" >/dev/null 2>&1 || { echo "[$(timestamp)] ERROR: Output is not valid JSON: $OUT_JSON" >> "$LOG_FILE"; exit 1; }
fi
# 3) Register with the API using your existing venv
"$VENV_PY" "$PY_SCRIPT" --input "$OUT_JSON" >> "$LOG_FILE" 2>&1
echo "[$(timestamp)] Done" >> "$LOG_FILE"