@agenthippo-ai/agenthippo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/agenthippo.js +2 -0
- package/out/agentpack/github.js +547 -0
- package/out/agentpack/index.js +66 -0
- package/out/agentpack/install.js +297 -0
- package/out/agentpack/manager.js +441 -0
- package/out/agentpack/manifest.js +135 -0
- package/out/agentpack/paths.js +475 -0
- package/out/agentpack/publish.js +248 -0
- package/out/agentpack/stores.js +554 -0
- package/out/agentpack/types.js +5 -0
- package/out/analytics/dashboard/artifactManager.js +439 -0
- package/out/analytics/dashboard/fleetDisplayUtils.js +159 -0
- package/out/analytics/dashboard/fleetOrchestrator.js +142 -0
- package/out/analytics/dashboard/fleetRegistry.js +79 -0
- package/out/analytics/dashboard/fleetRowDefaults.js +87 -0
- package/out/analytics/dashboard/fleetScriptAdapter.js +146 -0
- package/out/analytics/dashboard/fleetStatusUtils.js +30 -0
- package/out/analytics/dashboard/fleetTitleUtils.js +68 -0
- package/out/analytics/dashboard/fleetTypes.js +29 -0
- package/out/analytics/dashboard/index.js +17 -0
- package/out/analytics/dashboard/indexingService.js +422 -0
- package/out/analytics/dashboard/localFleetAdapter.js +222 -0
- package/out/analytics/dashboard/performanceMonitor.js +76 -0
- package/out/analytics/dashboard/processManager.js +209 -0
- package/out/analytics/dashboard/provider.js +3885 -0
- package/out/analytics/dashboard/queryRunner.js +994 -0
- package/out/analytics/dashboard/refreshPolicy.js +16 -0
- package/out/analytics/dashboard/scheduledFleetFingerprint.js +22 -0
- package/out/analytics/dashboard/scheduledFleetStorage.js +241 -0
- package/out/analytics/dashboard/scheduledFleetUtils.js +22 -0
- package/out/analytics/dashboard/sessionEventFleetStats.js +118 -0
- package/out/analytics/dashboard/sessionJsonlFleet.js +204 -0
- package/out/analytics/dashboard/teamViewDiscovery.js +106 -0
- package/out/analytics/dashboard/viewsConfigMerge.js +221 -0
- package/out/analytics/dashboard/webview/analytics-panel.html +155 -0
- package/out/analytics/dashboard/webview/codicon.ttf +0 -0
- package/out/analytics/dashboard/webview/index.html +78 -0
- package/out/analytics/dashboard/webview/panel.js +2295 -0
- package/out/analytics/dashboard/webview/runtime-bridge.js +82 -0
- package/out/analytics/dashboard/webview/styles.css +1009 -0
- package/out/analytics/lifecycle.js +43 -0
- package/out/analytics/service.js +1279 -0
- package/out/analytics/sessionEvents.js +231 -0
- package/out/auth/bootstrapApply.js +72 -0
- package/out/auth/brokerClient.js +126 -0
- package/out/auth/callbackUri.js +59 -0
- package/out/auth/callbackUriParse.js +59 -0
- package/out/auth/githubStoreGate.js +70 -0
- package/out/auth/loopbackAuthServer.js +165 -0
- package/out/auth/pkce.js +9 -0
- package/out/auth/provider.js +239 -0
- package/out/auth/sessionStore.js +193 -0
- package/out/auth/signInFlow.js +182 -0
- package/out/auth/types.js +12 -0
- package/out/auth-broker/config.js +62 -0
- package/out/auth-broker/jwt.js +105 -0
- package/out/auth-broker/pkce.js +57 -0
- package/out/auth-broker/server.js +539 -0
- package/out/auth-broker/store.js +273 -0
- package/out/base-prompts/gateway/openclaw-starter.json5 +144 -0
- package/out/base-prompts/gateway/slack-socket-mode-minimal.manifest.json +44 -0
- package/out/base-prompts/mcp-servers/.mcp.json +13 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +142 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +13 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +1192 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +23 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +12 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +102 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +137 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +118 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +209 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +431 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +270 -0
- package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +18 -0
- package/out/base-prompts/rules/AGENTS.md +204 -0
- package/out/base-prompts/skills/agent-browser/SKILL.md +102 -0
- package/out/base-prompts/skills/agent-builder/SKILL.md +73 -0
- package/out/base-prompts/skills/agent-builder/references/agent-pack.md +63 -0
- package/out/base-prompts/skills/agent-builder/references/crewai.md +66 -0
- package/out/base-prompts/skills/agent-builder/references/langchain.md +60 -0
- package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +73 -0
- package/out/base-prompts/skills/agent-engine-creator/SKILL.md +586 -0
- package/out/base-prompts/skills/agent-engine-installer/SKILL.md +106 -0
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +259 -0
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +189 -0
- package/out/base-prompts/skills/agenthippo-cli/SKILL.md +69 -0
- package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +63 -0
- package/out/base-prompts/skills/agentpack-creator/SKILL.md +375 -0
- package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +261 -0
- package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +195 -0
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +391 -0
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +294 -0
- package/out/base-prompts/skills/agentpack-testbench/SKILL.md +135 -0
- package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +202 -0
- package/out/base-prompts/skills/algorithmic-art/SKILL.md +405 -0
- package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +599 -0
- package/out/base-prompts/skills/debug-agent/SKILL.md +83 -0
- package/out/base-prompts/skills/desktop-automation/SKILL.md +166 -0
- package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +441 -0
- package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +280 -0
- package/out/base-prompts/skills/docx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/docx/SKILL.md +197 -0
- package/out/base-prompts/skills/docx/docx-js.md +350 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +159 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +69 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/out/base-prompts/skills/docx/ooxml.md +610 -0
- package/out/base-prompts/skills/docx/scripts/__init__.py +1 -0
- package/out/base-prompts/skills/docx/scripts/document.py +1276 -0
- package/out/base-prompts/skills/docx/scripts/templates/comments.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/templates/people.xml +3 -0
- package/out/base-prompts/skills/docx/scripts/utilities.py +374 -0
- package/out/base-prompts/skills/gateway-outbound/SKILL.md +136 -0
- package/out/base-prompts/skills/mcp-builder/LICENSE.txt +202 -0
- package/out/base-prompts/skills/mcp-builder/SKILL.md +328 -0
- package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +602 -0
- package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/out/base-prompts/skills/mcp-builder/scripts/connections.py +151 -0
- package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/out/base-prompts/skills/openclaw/SKILL.md +406 -0
- package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +61 -0
- package/out/base-prompts/skills/pdf/LICENSE.txt +30 -0
- package/out/base-prompts/skills/pdf/SKILL.md +294 -0
- package/out/base-prompts/skills/pdf/forms.md +205 -0
- package/out/base-prompts/skills/pdf/reference.md +612 -0
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +41 -0
- package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/out/base-prompts/skills/pptx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/pptx/SKILL.md +484 -0
- package/out/base-prompts/skills/pptx/html2pptx.md +625 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/out/base-prompts/skills/pptx/ooxml.md +427 -0
- package/out/base-prompts/skills/pptx/scripts/html2pptx.js +984 -0
- package/out/base-prompts/skills/pptx/scripts/inventory.py +1020 -0
- package/out/base-prompts/skills/pptx/scripts/rearrange.py +231 -0
- package/out/base-prompts/skills/pptx/scripts/replace.py +385 -0
- package/out/base-prompts/skills/pptx/scripts/thumbnail.py +450 -0
- package/out/base-prompts/skills/prompt-lab/SKILL.md +149 -0
- package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/skill-creator/LICENSE.txt +202 -0
- package/out/base-prompts/skills/skill-creator/SKILL.md +371 -0
- package/out/base-prompts/skills/skill-creator/references/output-patterns.md +82 -0
- package/out/base-prompts/skills/skill-creator/references/workflows.md +28 -0
- package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +303 -0
- package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +110 -0
- package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/out/base-prompts/skills/skill-installer/SKILL.md +251 -0
- package/out/base-prompts/skills/skill-installer/references/store-api.md +219 -0
- package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +83 -0
- package/out/base-prompts/skills/spotlight-insights/SKILL.md +101 -0
- package/out/base-prompts/skills/spotlight-optimize/SKILL.md +93 -0
- package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/spotlight-query/SKILL.md +314 -0
- package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +163 -0
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +744 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +14 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +7 -0
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +5 -0
- package/out/base-prompts/skills/spotlight-report/SKILL.md +86 -0
- package/out/base-prompts/skills/spotlight-visualize/SKILL.md +92 -0
- package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +2551 -0
- package/out/base-prompts/skills/xlsx/LICENSE.txt +30 -0
- package/out/base-prompts/skills/xlsx/SKILL.md +289 -0
- package/out/base-prompts/skills/xlsx/recalc.py +178 -0
- package/out/branding.js +23 -0
- package/out/cli/commands/anywhere.js +66 -0
- package/out/cli/commands/ask.js +243 -0
- package/out/cli/commands/auth-broker.js +24 -0
- package/out/cli/commands/auth.js +219 -0
- package/out/cli/commands/chat.js +354 -0
- package/out/cli/commands/deploy.js +223 -0
- package/out/cli/commands/gateway.js +160 -0
- package/out/cli/commands/pack.js +220 -0
- package/out/cli/commands/probe-custom-engine.js +82 -0
- package/out/cli/commands/serve.js +583 -0
- package/out/cli/commands/store.js +919 -0
- package/out/cli/credential-context.js +113 -0
- package/out/cli/deploy-init.js +2087 -0
- package/out/cli/deps.js +238 -0
- package/out/cli/index.js +390 -0
- package/out/cli/pack-loader.js +376 -0
- package/out/cli/run-custom-engine-runner.js +318 -0
- package/out/cli/runtime.js +409 -0
- package/out/cli/serve-hardening.js +325 -0
- package/out/cli/state-sync.js +135 -0
- package/out/cli/utils.js +220 -0
- package/out/cli/vscode-shim.js +86 -0
- package/out/engines/base.js +159 -0
- package/out/engines/claude.js +1215 -0
- package/out/engines/codex.js +759 -0
- package/out/engines/custom.js +632 -0
- package/out/engines/customEngineIpc.js +95 -0
- package/out/engines/customEngineRunnerEmbed.js +107 -0
- package/out/engines/customRegistry.js +274 -0
- package/out/engines/embeddedCustomEngineRunner.generated.js +9 -0
- package/out/engines/engineApiKey.js +138 -0
- package/out/engines/factory.js +45 -0
- package/out/engines/install.js +372 -0
- package/out/engines/persistentEngineWorker.js +320 -0
- package/out/engines/publish.js +341 -0
- package/out/engines/types.js +17 -0
- package/out/examples/run-headless-repl.js +291 -0
- package/out/examples/run-headless.js +187 -0
- package/out/extension.js +4472 -0
- package/out/gateway/bridge.js +805 -0
- package/out/gateway/cli-agent-id.js +36 -0
- package/out/gateway/client.js +303 -0
- package/out/gateway/client.test.js +395 -0
- package/out/gateway/gateway-scope-errors.js +14 -0
- package/out/gateway/gatewayBackup.js +76 -0
- package/out/gateway/gatewayRouteIndex.js +371 -0
- package/out/gateway/gatewaySessionStore.js +243 -0
- package/out/gateway/index.js +31 -0
- package/out/gateway/lifecycle.js +3056 -0
- package/out/gateway/openclaw-channel-routing.js +317 -0
- package/out/gateway/outboundHandles.js +373 -0
- package/out/gateway/outboundPaths.js +72 -0
- package/out/gateway/outboundSend.js +254 -0
- package/out/gateway/protocol.js +48 -0
- package/out/gateway/resetMappings.js +52 -0
- package/out/gateway/service.js +1244 -0
- package/out/gateway/sessionRouting.js +77 -0
- package/out/headless/index.js +505 -0
- package/out/headless/sync.js +473 -0
- package/out/mcp/publish.js +143 -0
- package/out/mcp.js +597 -0
- package/out/permissions.js +108 -0
- package/out/permissions.mapping.yaml +68 -0
- package/out/registry/index.js +332 -0
- package/out/remote/handleRemoteChat.js +122 -0
- package/out/remote/remotePackStatusBar.js +103 -0
- package/out/remote/serveClient.js +216 -0
- package/out/remoteSkills.js +191 -0
- package/out/runtime/index.js +32 -0
- package/out/runtime/interfaces/config-provider.js +32 -0
- package/out/runtime/interfaces/edit-tracker.js +22 -0
- package/out/runtime/interfaces/index.js +29 -0
- package/out/runtime/interfaces/logger.js +40 -0
- package/out/runtime/interfaces/permission-handler.js +66 -0
- package/out/runtime/interfaces/session-store.js +342 -0
- package/out/runtime/vscode/index.js +20 -0
- package/out/runtime/vscode/vscode-config-provider.js +77 -0
- package/out/runtime/vscode/vscode-edit-tracker.js +120 -0
- package/out/runtime/vscode/vscode-logger.js +30 -0
- package/out/runtime/vscode/vscode-permission-handler.js +72 -0
- package/out/runtime/vscode/vscode-session-store.js +22 -0
- package/out/scripts/agentide-litellm.ps1 +501 -0
- package/out/scripts/agentide-litellm.sh +700 -0
- package/out/scripts/agentide_litellm_hooks_v1.py +604 -0
- package/out/scripts/analytics/agent-fleet-widget.js +954 -0
- package/out/scripts/analytics/agentide-litellm-otel.config.yaml +160 -0
- package/out/scripts/analytics/default-seed-scripts.json +12 -0
- package/out/scripts/analytics/duckdbLocator.js +29 -0
- package/out/scripts/analytics/fleet-local-adapter.js +246 -0
- package/out/scripts/analytics/fleet-workflow.sh +263 -0
- package/out/scripts/analytics/generate-default-charts.py +685 -0
- package/out/scripts/analytics/hotspot-analysis-widget.js +909 -0
- package/out/scripts/analytics/index-traces.py +1394 -0
- package/out/scripts/analytics/install-analytics.sh +286 -0
- package/out/scripts/analytics/live-fleet-4-collector.cjs +315 -0
- package/out/scripts/analytics/live-fleet-4-daemon.mjs +134 -0
- package/out/scripts/analytics/live-fleet-4-widget.cjs +433 -0
- package/out/scripts/analytics/otel-collector.yaml +55 -0
- package/out/scripts/analytics/query-analytics.ps1 +396 -0
- package/out/scripts/analytics/query-analytics.sh +2551 -0
- package/out/scripts/analytics/session-comparison-widget.js +1468 -0
- package/out/scripts/analytics/session-timeline-widget.js +2137 -0
- package/out/scripts/analytics/setup-analytics.ps1 +432 -0
- package/out/scripts/analytics/setup-analytics.sh +854 -0
- package/out/scripts/analytics/start-analytics.ps1 +169 -0
- package/out/scripts/analytics/start-analytics.sh +323 -0
- package/out/scripts/analytics/token-cost-flamegraph-widget.js +954 -0
- package/out/scripts/analytics/token-cost-trend-widget.js +1062 -0
- package/out/scripts/analytics/workflows-collector.cjs +315 -0
- package/out/scripts/analytics/workflows-daemon.mjs +186 -0
- package/out/scripts/analytics/workflows-widget.cjs +433 -0
- package/out/scripts/analytics/wow-model-widget.js +191 -0
- package/out/scripts/gateway/Dockerfile.serve +45 -0
- package/out/scripts/gateway/docker-serve.sh +248 -0
- package/out/scripts/gateway/setup-gateway-server.ps1 +953 -0
- package/out/scripts/gateway/setup-gateway-server.sh +935 -0
- package/out/scripts/gateway/setup-gateway.ps1 +1813 -0
- package/out/scripts/gateway/setup-gateway.sh +1541 -0
- package/out/scripts/setup-cli.ps1 +86 -0
- package/out/scripts/setup-cli.sh +117 -0
- package/out/scripts/tools-manifest.json +83 -0
- package/out/scripts/vendor-tools.mjs +234 -0
- package/out/session.js +272 -0
- package/out/shared/agentEngines.js +170 -0
- package/out/shared/index.js +109 -0
- package/out/shared/models.js +235 -0
- package/out/shared/providers.js +202 -0
- package/out/skills/publish.js +178 -0
- package/out/spotlight/install.js +339 -0
- package/out/spotlight/publish.js +544 -0
- package/out/spotlight/yaml.js +31 -0
- package/out/store/github/setup.js +235 -0
- package/out/store/github/templates/build-index.ts +339 -0
- package/out/store/github/templates/build-index.yml +97 -0
- package/out/store/github/templates/package.json +11 -0
- package/out/store/index.js +755 -0
- package/out/store/oramaIndex.js +884 -0
- package/out/store/shared.js +241 -0
- package/out/sync.js +1827 -0
- package/out/terminalLogger.js +358 -0
- package/out/test/agentEnvFile.test.js +97 -0
- package/out/test/agentYaml.test.js +373 -0
- package/out/test/agentpack.test.js +639 -0
- package/out/test/analytics-lifecycle.test.js +174 -0
- package/out/test/analytics.test.js +524 -0
- package/out/test/auth-bootstrapApply.test.js +102 -0
- package/out/test/auth-broker.test.js +434 -0
- package/out/test/auth-callback.test.js +62 -0
- package/out/test/branding.test.js +229 -0
- package/out/test/cli-agent-id.test.js +55 -0
- package/out/test/credential-context.test.js +105 -0
- package/out/test/customEngineInstall.test.js +100 -0
- package/out/test/customRegistry.test.js +122 -0
- package/out/test/deploy-init.test.js +532 -0
- package/out/test/deps-auto-install.test.js +81 -0
- package/out/test/engine-integration.test.js +297 -0
- package/out/test/enginePaths.test.js +195 -0
- package/out/test/enginePublish.test.js +82 -0
- package/out/test/fleetDisplayUtils.test.js +96 -0
- package/out/test/gateway-client.test.js +381 -0
- package/out/test/gateway-lifecycle.test.js +608 -0
- package/out/test/gateway-outbound.test.js +531 -0
- package/out/test/gateway-reset-mappings.test.js +221 -0
- package/out/test/gateway-route-index.test.js +235 -0
- package/out/test/gateway-session-routing.test.js +47 -0
- package/out/test/gateway-session-store.test.js +216 -0
- package/out/test/github.test.js +232 -0
- package/out/test/headless-sync.test.js +279 -0
- package/out/test/helpers/manifest-fixtures.js +27 -0
- package/out/test/mcp-obo.test.js +82 -0
- package/out/test/mcp.test.js +307 -0
- package/out/test/openclaw-channel-routing.test.js +191 -0
- package/out/test/pathSafety.test.js +63 -0
- package/out/test/permissions.test.js +175 -0
- package/out/test/persistent-engine-worker.test.js +220 -0
- package/out/test/refreshPolicy.test.js +60 -0
- package/out/test/registry.test.js +351 -0
- package/out/test/runtime.test.js +349 -0
- package/out/test/scheduledFleetStorage.test.js +72 -0
- package/out/test/serve-hardening.test.js +192 -0
- package/out/test/serveClient.test.js +173 -0
- package/out/test/sessionJsonlFleet.test.js +78 -0
- package/out/test/shared.test.js +173 -0
- package/out/test/skills-mcp.test.js +299 -0
- package/out/test/spotlightPublish.test.js +299 -0
- package/out/test/spotlightYaml.test.js +58 -0
- package/out/test/state-sync-peer.test.js +74 -0
- package/out/test/store.test.js +331 -0
- package/out/test/stores.test.js +504 -0
- package/out/test/sync-switch.test.js +251 -0
- package/out/test/teamViewDiscovery.test.js +90 -0
- package/out/test/toolPath.test.js +120 -0
- package/out/test/utils.test.js +308 -0
- package/out/test/viewsConfigMerge.test.js +180 -0
- package/out/test/windows-command-line.test.js +75 -0
- package/out/utils/agentEnvFile.js +131 -0
- package/out/utils/binary.js +175 -0
- package/out/utils/index.js +37 -0
- package/out/utils/network.js +74 -0
- package/out/utils/pathSafety.js +60 -0
- package/out/utils/paths.js +116 -0
- package/out/utils/pid.js +180 -0
- package/out/utils/pythonRunner.js +258 -0
- package/out/utils/resolveNodeBinary.js +168 -0
- package/out/utils/toolPath.js +83 -0
- package/out/utils/windowsCommandLine.js +29 -0
- package/out/utils.js +915 -0
- package/out/workspaceFolders.js +59 -0
- package/package.json +41 -0
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
#---------------------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) AgentHippo.ai. All rights reserved.
|
|
3
|
+
#---------------------------------------------------------------------------------------------
|
|
4
|
+
"""
|
|
5
|
+
AgentIDE LiteLLM proxy hooks - Clean structured assistant output with separate input/output
|
|
6
|
+
Mimics langfuse_otel style: gen_ai.input.messages (history) + gen_ai.output.messages (new reply only)
|
|
7
|
+
|
|
8
|
+
Usage in litellm config.yaml:
|
|
9
|
+
callbacks: ["agentide_litellm_hooks_v1.clean_separated_otel_output"]
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
from typing import Any
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
from litellm.integrations.custom_logger import CustomLogger
|
|
17
|
+
from litellm.integrations.opentelemetry import OpenTelemetry
|
|
18
|
+
from opentelemetry.trace import Status, StatusCode
|
|
19
|
+
|
|
20
|
+
_OTEL_TEXT_MAX_LEN = 4000 # per text block
|
|
21
|
+
_OTEL_PREVIEW_LEN = 180 # short preview in event
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _read_field(obj: Any, key: str, default: Any = None) -> Any:
|
|
25
|
+
if isinstance(obj, dict):
|
|
26
|
+
return obj.get(key, default)
|
|
27
|
+
return getattr(obj, key, default)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _content_blocks_to_text(content: Any) -> str:
|
|
31
|
+
if isinstance(content, str):
|
|
32
|
+
return content
|
|
33
|
+
if not isinstance(content, (list, tuple)):
|
|
34
|
+
return ""
|
|
35
|
+
parts: list[str] = []
|
|
36
|
+
for block in content:
|
|
37
|
+
if isinstance(block, str):
|
|
38
|
+
if block.strip():
|
|
39
|
+
parts.append(block)
|
|
40
|
+
continue
|
|
41
|
+
if not isinstance(block, dict):
|
|
42
|
+
continue
|
|
43
|
+
text = block.get("text") or block.get("output_text") or block.get("content")
|
|
44
|
+
if isinstance(text, str) and text.strip():
|
|
45
|
+
parts.append(text)
|
|
46
|
+
return "\n".join(parts)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _extract_assistant_text(response_obj: Any) -> str:
|
|
50
|
+
if response_obj is None:
|
|
51
|
+
return ""
|
|
52
|
+
# OpenAI-style
|
|
53
|
+
choices = _read_field(response_obj, "choices")
|
|
54
|
+
if isinstance(choices, list) and choices:
|
|
55
|
+
msg = _read_field(choices[0], "message")
|
|
56
|
+
content = _read_field(msg, "content")
|
|
57
|
+
text = _content_blocks_to_text(content)
|
|
58
|
+
if text.strip():
|
|
59
|
+
return text
|
|
60
|
+
# Direct output fields
|
|
61
|
+
for key in ("output_text", "content", "output", "text"):
|
|
62
|
+
val = _read_field(response_obj, key)
|
|
63
|
+
if val:
|
|
64
|
+
text = _content_blocks_to_text(val)
|
|
65
|
+
if text.strip():
|
|
66
|
+
return text
|
|
67
|
+
return ""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _extract_text_from_success_kwargs(kwargs: dict) -> str:
|
|
71
|
+
text = _extract_assistant_text(kwargs.get("response_obj"))
|
|
72
|
+
if text:
|
|
73
|
+
return text
|
|
74
|
+
for k in ("complete_response", "model_response", "response", "original_response"):
|
|
75
|
+
candidate = kwargs.get(k)
|
|
76
|
+
if candidate:
|
|
77
|
+
text = _extract_assistant_text(candidate)
|
|
78
|
+
if text:
|
|
79
|
+
return text
|
|
80
|
+
return ""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _make_output_messages_structured(text: str) -> list:
|
|
84
|
+
if not text.strip():
|
|
85
|
+
return []
|
|
86
|
+
trimmed = text[:_OTEL_TEXT_MAX_LEN]
|
|
87
|
+
# Align with LiteLLM's GEN_AI_OUTPUT_MESSAGES shape: parts + inner content (not content + text).
|
|
88
|
+
return [{"role": "assistant", "parts": [{"type": "text", "content": trimmed}]}]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _model_name(model: Any) -> str:
|
|
92
|
+
return model.lower() if isinstance(model, str) else ""
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _is_reasoning_unsupported_model(model: Any) -> bool:
|
|
96
|
+
"""True when model is known to reject reasoning parameters."""
|
|
97
|
+
return "gpt-4.1-nano" in _model_name(model)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _is_anthropic_route(model: Any) -> bool:
|
|
101
|
+
"""True when the request will be forwarded to Anthropic."""
|
|
102
|
+
name = _model_name(model)
|
|
103
|
+
return "claude" in name or "anthropic" in name
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _is_web_search_unsupported_model(model: Any) -> bool:
|
|
107
|
+
"""True when the upstream model rejects Codex web-search tools."""
|
|
108
|
+
return "gpt-4.1-nano" in _model_name(model)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# OpenAI Responses API fields that Anthropic (and some gateways) reject if forwarded verbatim.
|
|
112
|
+
_OPENAI_RESPONSES_ONLY_KEYS = ("client_metadata",)
|
|
113
|
+
|
|
114
|
+
# Codex built-in tools not supported on all OpenAI models.
|
|
115
|
+
_UNSUPPORTED_TOOL_IDENTIFIERS = frozenset({"web_search_preview", "web_search"})
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _strip_key_recursive(data: Any, key: str, _visited: set[int] | None = None) -> None:
|
|
119
|
+
"""Remove a key in nested dict/list payloads (bounded; avoids cyclic graphs)."""
|
|
120
|
+
if _visited is None:
|
|
121
|
+
_visited = set()
|
|
122
|
+
if isinstance(data, dict):
|
|
123
|
+
obj_id = id(data)
|
|
124
|
+
if obj_id in _visited:
|
|
125
|
+
return
|
|
126
|
+
_visited.add(obj_id)
|
|
127
|
+
data.pop(key, None)
|
|
128
|
+
for value in list(data.values()):
|
|
129
|
+
_strip_key_recursive(value, key, _visited)
|
|
130
|
+
return
|
|
131
|
+
if isinstance(data, list):
|
|
132
|
+
obj_id = id(data)
|
|
133
|
+
if obj_id in _visited:
|
|
134
|
+
return
|
|
135
|
+
_visited.add(obj_id)
|
|
136
|
+
for item in data:
|
|
137
|
+
_strip_key_recursive(item, key, _visited)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _resolve_route_model(payload: dict, model: Any) -> str:
|
|
141
|
+
name = _model_name(model)
|
|
142
|
+
if name:
|
|
143
|
+
return name
|
|
144
|
+
for candidate in (
|
|
145
|
+
payload.get("model"),
|
|
146
|
+
payload.get("model_group"),
|
|
147
|
+
payload.get("model_name"),
|
|
148
|
+
payload.get("deployment"),
|
|
149
|
+
):
|
|
150
|
+
name = _model_name(candidate)
|
|
151
|
+
if name:
|
|
152
|
+
return name
|
|
153
|
+
metadata = payload.get("metadata")
|
|
154
|
+
if isinstance(metadata, dict):
|
|
155
|
+
for candidate in (metadata.get("model_group"), metadata.get("model")):
|
|
156
|
+
name = _model_name(candidate)
|
|
157
|
+
if name:
|
|
158
|
+
return name
|
|
159
|
+
return ""
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _tool_is_unsupported(tool: Any) -> bool:
|
|
163
|
+
if not isinstance(tool, dict):
|
|
164
|
+
return False
|
|
165
|
+
tool_type = tool.get("type")
|
|
166
|
+
if isinstance(tool_type, str) and tool_type in _UNSUPPORTED_TOOL_IDENTIFIERS:
|
|
167
|
+
return True
|
|
168
|
+
name = tool.get("name")
|
|
169
|
+
if isinstance(name, str) and name in _UNSUPPORTED_TOOL_IDENTIFIERS:
|
|
170
|
+
return True
|
|
171
|
+
fn = tool.get("function")
|
|
172
|
+
if isinstance(fn, dict):
|
|
173
|
+
fn_name = fn.get("name")
|
|
174
|
+
if isinstance(fn_name, str) and fn_name in _UNSUPPORTED_TOOL_IDENTIFIERS:
|
|
175
|
+
return True
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _strip_unsupported_tools(data: dict) -> None:
|
|
180
|
+
tools = data.get("tools")
|
|
181
|
+
if not isinstance(tools, list):
|
|
182
|
+
return
|
|
183
|
+
filtered = [tool for tool in tools if not _tool_is_unsupported(tool)]
|
|
184
|
+
if len(filtered) == len(tools):
|
|
185
|
+
return
|
|
186
|
+
if filtered:
|
|
187
|
+
data["tools"] = filtered
|
|
188
|
+
else:
|
|
189
|
+
data.pop("tools", None)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _apply_codex_proxy_sanitizers(data: dict, model: Any) -> None:
|
|
193
|
+
route_model = _resolve_route_model(data, model)
|
|
194
|
+
if _is_anthropic_route(route_model):
|
|
195
|
+
for key in _OPENAI_RESPONSES_ONLY_KEYS:
|
|
196
|
+
_strip_key_recursive(data, key)
|
|
197
|
+
if _is_web_search_unsupported_model(route_model):
|
|
198
|
+
_strip_unsupported_tools(data)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _strip_unsupported_reasoning_params(data: Any, _visited: set[int] | None = None) -> None:
|
|
202
|
+
"""
|
|
203
|
+
Mutates `data` in-place by removing unsupported reasoning controls.
|
|
204
|
+
|
|
205
|
+
OpenAI's API error reports `reasoning.effort`, but the payload is sent as:
|
|
206
|
+
{ "reasoning": { "effort": ... } }
|
|
207
|
+
"""
|
|
208
|
+
if _visited is None:
|
|
209
|
+
_visited = set()
|
|
210
|
+
if isinstance(data, dict):
|
|
211
|
+
obj_id = id(data)
|
|
212
|
+
if obj_id in _visited:
|
|
213
|
+
return
|
|
214
|
+
_visited.add(obj_id)
|
|
215
|
+
data.pop("reasoning", None)
|
|
216
|
+
data.pop("reasoning_effort", None)
|
|
217
|
+
for v in list(data.values()):
|
|
218
|
+
_strip_unsupported_reasoning_params(v, _visited)
|
|
219
|
+
return
|
|
220
|
+
if isinstance(data, list):
|
|
221
|
+
obj_id = id(data)
|
|
222
|
+
if obj_id in _visited:
|
|
223
|
+
return
|
|
224
|
+
_visited.add(obj_id)
|
|
225
|
+
for item in data:
|
|
226
|
+
_strip_unsupported_reasoning_params(item, _visited)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _extract_text_content(message: dict[str, Any]) -> str:
|
|
230
|
+
"""Extract text content from OpenAI-style message content."""
|
|
231
|
+
content = message.get("content")
|
|
232
|
+
if isinstance(content, str):
|
|
233
|
+
return content
|
|
234
|
+
if not isinstance(content, list):
|
|
235
|
+
return ""
|
|
236
|
+
parts: list[str] = []
|
|
237
|
+
for block in content:
|
|
238
|
+
if isinstance(block, dict) and block.get("type") == "text":
|
|
239
|
+
text = block.get("text")
|
|
240
|
+
if isinstance(text, str) and text.strip():
|
|
241
|
+
parts.append(text)
|
|
242
|
+
return "\n".join(parts)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def _set_text_content(message: dict[str, Any], text: str) -> None:
|
|
246
|
+
"""Set text content while preserving existing content shape when possible."""
|
|
247
|
+
content = message.get("content")
|
|
248
|
+
if isinstance(content, list):
|
|
249
|
+
# Keep non-text blocks and append merged text as final text block.
|
|
250
|
+
preserved = [b for b in content if not (isinstance(b, dict) and b.get("type") == "text")]
|
|
251
|
+
if text.strip():
|
|
252
|
+
preserved.append({"type": "text", "text": text})
|
|
253
|
+
message["content"] = preserved
|
|
254
|
+
return
|
|
255
|
+
message["content"] = text
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _is_text_only_assistant(message: Any) -> bool:
|
|
259
|
+
"""True when assistant message has text and no tool calls."""
|
|
260
|
+
if not isinstance(message, dict) or message.get("role") != "assistant":
|
|
261
|
+
return False
|
|
262
|
+
tool_calls = message.get("tool_calls")
|
|
263
|
+
if isinstance(tool_calls, list) and len(tool_calls) > 0:
|
|
264
|
+
return False
|
|
265
|
+
return bool(_extract_text_content(message).strip())
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _tool_result_ids_from_message(message: Any) -> set[str]:
|
|
269
|
+
"""Collect tool result ids from OpenAI or Anthropic-style tool result messages."""
|
|
270
|
+
if not isinstance(message, dict):
|
|
271
|
+
return set()
|
|
272
|
+
|
|
273
|
+
role = message.get("role")
|
|
274
|
+
if role == "tool":
|
|
275
|
+
tool_call_id = message.get("tool_call_id")
|
|
276
|
+
return {tool_call_id} if isinstance(tool_call_id, str) and tool_call_id else set()
|
|
277
|
+
|
|
278
|
+
content = message.get("content")
|
|
279
|
+
if not isinstance(content, list):
|
|
280
|
+
return set()
|
|
281
|
+
ids: set[str] = set()
|
|
282
|
+
for block in content:
|
|
283
|
+
if isinstance(block, dict) and block.get("type") == "tool_result":
|
|
284
|
+
tool_use_id = block.get("tool_use_id")
|
|
285
|
+
if isinstance(tool_use_id, str) and tool_use_id:
|
|
286
|
+
ids.add(tool_use_id)
|
|
287
|
+
return ids
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def sanitize_messages(messages: Any) -> Any:
|
|
291
|
+
"""
|
|
292
|
+
Lightweight tool-order sanitizer for Codex/OpenAI-style tool calls.
|
|
293
|
+
|
|
294
|
+
Ensures assistant tool calls are followed immediately by tool results.
|
|
295
|
+
If text-only assistant messages appear between tool call and tool result,
|
|
296
|
+
merge text into the tool-call assistant message.
|
|
297
|
+
If no immediate tool result exists, inject placeholder tool results.
|
|
298
|
+
"""
|
|
299
|
+
if not isinstance(messages, list) or not messages:
|
|
300
|
+
return messages
|
|
301
|
+
|
|
302
|
+
result: list[Any] = []
|
|
303
|
+
i = 0
|
|
304
|
+
changed = False
|
|
305
|
+
|
|
306
|
+
while i < len(messages):
|
|
307
|
+
msg = messages[i]
|
|
308
|
+
if not isinstance(msg, dict):
|
|
309
|
+
result.append(msg)
|
|
310
|
+
i += 1
|
|
311
|
+
continue
|
|
312
|
+
|
|
313
|
+
role = msg.get("role")
|
|
314
|
+
tool_calls = msg.get("tool_calls")
|
|
315
|
+
if role != "assistant" or not isinstance(tool_calls, list) or len(tool_calls) == 0:
|
|
316
|
+
result.append(msg)
|
|
317
|
+
i += 1
|
|
318
|
+
continue
|
|
319
|
+
|
|
320
|
+
# Assistant tool-call message.
|
|
321
|
+
tool_ids: list[str] = []
|
|
322
|
+
for tc in tool_calls:
|
|
323
|
+
if isinstance(tc, dict):
|
|
324
|
+
tid = tc.get("id")
|
|
325
|
+
if isinstance(tid, str) and tid:
|
|
326
|
+
tool_ids.append(tid)
|
|
327
|
+
|
|
328
|
+
merged = dict(msg)
|
|
329
|
+
merged_text = _extract_text_content(merged)
|
|
330
|
+
j = i + 1
|
|
331
|
+
|
|
332
|
+
# Merge consecutive text-only assistant messages.
|
|
333
|
+
while j < len(messages) and _is_text_only_assistant(messages[j]):
|
|
334
|
+
extra = _extract_text_content(messages[j])
|
|
335
|
+
if extra.strip():
|
|
336
|
+
merged_text = f"{merged_text}\n{extra}" if merged_text.strip() else extra
|
|
337
|
+
j += 1
|
|
338
|
+
changed = True
|
|
339
|
+
|
|
340
|
+
if merged_text != _extract_text_content(merged):
|
|
341
|
+
_set_text_content(merged, merged_text)
|
|
342
|
+
|
|
343
|
+
result.append(merged)
|
|
344
|
+
|
|
345
|
+
# Immediate next message must carry tool results for all tool ids.
|
|
346
|
+
next_ids = _tool_result_ids_from_message(messages[j]) if j < len(messages) else set()
|
|
347
|
+
missing_ids = [tid for tid in tool_ids if tid not in next_ids]
|
|
348
|
+
if missing_ids:
|
|
349
|
+
changed = True
|
|
350
|
+
for tid in missing_ids:
|
|
351
|
+
result.append({
|
|
352
|
+
"role": "tool",
|
|
353
|
+
"tool_call_id": tid,
|
|
354
|
+
"content": "[Placeholder: tool result was not provided]",
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
i = j
|
|
358
|
+
|
|
359
|
+
return result if changed else messages
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class ReasoningParamsSanitizer(CustomLogger):
|
|
363
|
+
"""LiteLLM proxy hook: strip reasoning controls for gpt-4.1-nano."""
|
|
364
|
+
|
|
365
|
+
async def async_pre_call_hook(
|
|
366
|
+
self,
|
|
367
|
+
user_api_key_dict: Any,
|
|
368
|
+
cache: Any,
|
|
369
|
+
data: dict,
|
|
370
|
+
call_type: Any,
|
|
371
|
+
) -> dict:
|
|
372
|
+
if not isinstance(data, dict):
|
|
373
|
+
return data
|
|
374
|
+
model = data.get("model")
|
|
375
|
+
if not _is_reasoning_unsupported_model(model):
|
|
376
|
+
return data
|
|
377
|
+
_strip_unsupported_reasoning_params(data)
|
|
378
|
+
return data
|
|
379
|
+
|
|
380
|
+
async def async_pre_call_deployment_hook(
|
|
381
|
+
self,
|
|
382
|
+
request_kwargs: dict,
|
|
383
|
+
call_type: Any,
|
|
384
|
+
) -> dict:
|
|
385
|
+
"""Extra safety: strip during deployment-layer payload building."""
|
|
386
|
+
if not isinstance(request_kwargs, dict):
|
|
387
|
+
return request_kwargs
|
|
388
|
+
model = request_kwargs.get("model")
|
|
389
|
+
if not _is_reasoning_unsupported_model(model):
|
|
390
|
+
return request_kwargs
|
|
391
|
+
_strip_unsupported_reasoning_params(request_kwargs)
|
|
392
|
+
return request_kwargs
|
|
393
|
+
|
|
394
|
+
async def async_pre_request_hook(
|
|
395
|
+
self,
|
|
396
|
+
model: str,
|
|
397
|
+
messages: list[Any],
|
|
398
|
+
request_kwargs: dict,
|
|
399
|
+
) -> dict:
|
|
400
|
+
"""Extra safety: strip right before provider call."""
|
|
401
|
+
if not _is_reasoning_unsupported_model(model):
|
|
402
|
+
return request_kwargs
|
|
403
|
+
if isinstance(request_kwargs, dict):
|
|
404
|
+
_strip_unsupported_reasoning_params(request_kwargs)
|
|
405
|
+
return request_kwargs
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class CodexProxySanitizer(CustomLogger):
|
|
409
|
+
"""
|
|
410
|
+
LiteLLM proxy hook: strip Codex/OpenAI Responses fields/tools that break proxy routes.
|
|
411
|
+
|
|
412
|
+
- Anthropic: drop client_metadata (OpenAI-only Responses telemetry).
|
|
413
|
+
- gpt-4.1-nano: drop web_search_preview and related built-in search tools.
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
def _sanitize(self, payload: dict, model: Any) -> dict:
|
|
417
|
+
if isinstance(payload, dict):
|
|
418
|
+
_apply_codex_proxy_sanitizers(payload, model)
|
|
419
|
+
return payload
|
|
420
|
+
|
|
421
|
+
async def async_pre_call_hook(
|
|
422
|
+
self,
|
|
423
|
+
user_api_key_dict: Any,
|
|
424
|
+
cache: Any,
|
|
425
|
+
data: dict,
|
|
426
|
+
call_type: Any,
|
|
427
|
+
) -> dict:
|
|
428
|
+
if not isinstance(data, dict):
|
|
429
|
+
return data
|
|
430
|
+
return self._sanitize(data, data.get("model"))
|
|
431
|
+
|
|
432
|
+
async def async_pre_call_deployment_hook(
|
|
433
|
+
self,
|
|
434
|
+
request_kwargs: dict,
|
|
435
|
+
call_type: Any,
|
|
436
|
+
) -> dict:
|
|
437
|
+
if not isinstance(request_kwargs, dict):
|
|
438
|
+
return request_kwargs
|
|
439
|
+
return self._sanitize(request_kwargs, request_kwargs.get("model"))
|
|
440
|
+
|
|
441
|
+
async def async_pre_request_hook(
|
|
442
|
+
self,
|
|
443
|
+
model: str,
|
|
444
|
+
messages: list[Any],
|
|
445
|
+
request_kwargs: dict,
|
|
446
|
+
) -> dict:
|
|
447
|
+
if isinstance(request_kwargs, dict):
|
|
448
|
+
self._sanitize(request_kwargs, model)
|
|
449
|
+
return request_kwargs
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
class ToolOrderSanitizer(CustomLogger):
|
|
453
|
+
"""LiteLLM proxy hook: sanitize tool call/result ordering for Claude routes."""
|
|
454
|
+
|
|
455
|
+
async def async_pre_call_hook(
|
|
456
|
+
self,
|
|
457
|
+
user_api_key_dict: Any,
|
|
458
|
+
cache: Any,
|
|
459
|
+
data: dict,
|
|
460
|
+
call_type: Any,
|
|
461
|
+
) -> dict:
|
|
462
|
+
if not isinstance(data, dict):
|
|
463
|
+
return data
|
|
464
|
+
messages = data.get("messages")
|
|
465
|
+
if isinstance(messages, list) and messages:
|
|
466
|
+
data["messages"] = sanitize_messages(messages)
|
|
467
|
+
return data
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def strip_empty_thinking_blocks(messages: list[Any]) -> list[Any]:
|
|
471
|
+
"""
|
|
472
|
+
Strip empty thinking/reasoning blocks from OpenAI-format messages.
|
|
473
|
+
|
|
474
|
+
Anthropic's API rejects empty `thinking` content blocks and empty
|
|
475
|
+
`reasoning_content` strings. LiteLLM proxies these fields unchanged,
|
|
476
|
+
so we sanitize outbound messages here at the proxy layer.
|
|
477
|
+
|
|
478
|
+
Handles three shapes:
|
|
479
|
+
1. Top-level `reasoning_content: ""` on assistant messages
|
|
480
|
+
2. `{ type: "thinking", thinking: "" }` inside content arrays
|
|
481
|
+
3. Removes assistant messages that become entirely empty after stripping
|
|
482
|
+
"""
|
|
483
|
+
result: list[Any] = []
|
|
484
|
+
|
|
485
|
+
for msg in messages:
|
|
486
|
+
if not isinstance(msg, dict):
|
|
487
|
+
result.append(msg)
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
cleaned = msg
|
|
491
|
+
|
|
492
|
+
# 1. Strip empty top-level reasoning_content on assistant messages
|
|
493
|
+
if cleaned.get("role") == "assistant" and "reasoning_content" in cleaned:
|
|
494
|
+
rc = cleaned["reasoning_content"]
|
|
495
|
+
if not rc or (isinstance(rc, str) and not rc.strip()):
|
|
496
|
+
cleaned = {k: v for k, v in cleaned.items() if k != "reasoning_content"}
|
|
497
|
+
|
|
498
|
+
# 2. Filter empty thinking blocks from content arrays
|
|
499
|
+
content = cleaned.get("content")
|
|
500
|
+
if isinstance(content, list):
|
|
501
|
+
original_len = len(content)
|
|
502
|
+
filtered = [
|
|
503
|
+
block for block in content
|
|
504
|
+
if not (
|
|
505
|
+
isinstance(block, dict)
|
|
506
|
+
and block.get("type") == "thinking"
|
|
507
|
+
and (not block.get("thinking") or (isinstance(block.get("thinking"), str) and not block["thinking"].strip()))
|
|
508
|
+
)
|
|
509
|
+
]
|
|
510
|
+
if len(filtered) != original_len:
|
|
511
|
+
# Preserve turn structure: if assistant becomes empty, keep a placeholder
|
|
512
|
+
if not filtered and cleaned.get("role") == "assistant":
|
|
513
|
+
filtered = [{"type": "text", "text": ""}]
|
|
514
|
+
cleaned = {**cleaned, "content": filtered}
|
|
515
|
+
|
|
516
|
+
# 3. Skip entirely empty assistant messages (no content, no tool_calls)
|
|
517
|
+
if cleaned.get("role") == "assistant" and not cleaned.get("tool_calls"):
|
|
518
|
+
c = cleaned.get("content")
|
|
519
|
+
if (isinstance(c, str) and not c.strip()) or (isinstance(c, list) and len(c) == 0):
|
|
520
|
+
continue
|
|
521
|
+
|
|
522
|
+
result.append(cleaned)
|
|
523
|
+
|
|
524
|
+
return result
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
class EmptyThinkingBlockSanitizer(CustomLogger):
|
|
528
|
+
"""LiteLLM proxy hook: strip empty thinking/reasoning blocks before Anthropic dispatch."""
|
|
529
|
+
|
|
530
|
+
async def async_pre_call_hook(
|
|
531
|
+
self,
|
|
532
|
+
user_api_key_dict: Any,
|
|
533
|
+
cache: Any,
|
|
534
|
+
data: dict,
|
|
535
|
+
call_type: Any,
|
|
536
|
+
) -> dict:
|
|
537
|
+
if not isinstance(data, dict):
|
|
538
|
+
return data
|
|
539
|
+
messages = data.get("messages")
|
|
540
|
+
if isinstance(messages, list) and messages:
|
|
541
|
+
data["messages"] = strip_empty_thinking_blocks(messages)
|
|
542
|
+
return data
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
class CleanSeparatedOtelOutput(OpenTelemetry):
|
|
546
|
+
"""
|
|
547
|
+
LiteLLM OTEL with clean separation:
|
|
548
|
+
- gen_ai.input.messages → full history (as set by LiteLLM)
|
|
549
|
+
- gen_ai.output.messages → only the new assistant reply (stringified structured array)
|
|
550
|
+
- Short preview event for quick visibility
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
def _start_primary_span(
|
|
554
|
+
self,
|
|
555
|
+
kwargs: dict,
|
|
556
|
+
response_obj: Any,
|
|
557
|
+
start_time: Any,
|
|
558
|
+
end_time: Any,
|
|
559
|
+
context: Any,
|
|
560
|
+
):
|
|
561
|
+
otel_tracer = self.get_tracer_to_use_for_request(kwargs)
|
|
562
|
+
|
|
563
|
+
span = otel_tracer.start_span(
|
|
564
|
+
name=self._get_span_name(kwargs),
|
|
565
|
+
start_time=self._to_ns(start_time),
|
|
566
|
+
context=context,
|
|
567
|
+
)
|
|
568
|
+
span.set_status(Status(StatusCode.OK))
|
|
569
|
+
self.set_attributes(span, kwargs, response_obj)
|
|
570
|
+
|
|
571
|
+
# -- Extract only the new assistant output -------------------------------
|
|
572
|
+
text = _extract_text_from_success_kwargs(kwargs) or \
|
|
573
|
+
_extract_assistant_text(response_obj)
|
|
574
|
+
|
|
575
|
+
if text.strip():
|
|
576
|
+
# Structured output (separate from input history)
|
|
577
|
+
structured_msgs = _make_output_messages_structured(text)
|
|
578
|
+
span.set_attribute(
|
|
579
|
+
"gen_ai.output.messages",
|
|
580
|
+
json.dumps(structured_msgs, ensure_ascii=False)
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
# Short preview event - easy to spot, low noise
|
|
584
|
+
preview = text[:_OTEL_PREVIEW_LEN] + ("..." if len(text) > _OTEL_PREVIEW_LEN else "")
|
|
585
|
+
span.add_event(
|
|
586
|
+
name="gen_ai.output.generated",
|
|
587
|
+
attributes={
|
|
588
|
+
"gen_ai.output.preview": preview,
|
|
589
|
+
"gen_ai.output.length": len(text),
|
|
590
|
+
"gen_ai.output.truncated": len(text) > _OTEL_TEXT_MAX_LEN,
|
|
591
|
+
"gen_ai.response.model": _read_field(kwargs, "model", "unknown")
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
span.end(end_time=self._to_ns(end_time))
|
|
596
|
+
return span
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
# Register
|
|
600
|
+
structured_genai_otel = CleanSeparatedOtelOutput()
|
|
601
|
+
reasoning_params_sanitizer = ReasoningParamsSanitizer()
|
|
602
|
+
codex_proxy_sanitizer = CodexProxySanitizer()
|
|
603
|
+
tool_order_sanitizer = ToolOrderSanitizer()
|
|
604
|
+
empty_thinking_sanitizer = EmptyThinkingBlockSanitizer()
|