@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.
Files changed (480) hide show
  1. package/LICENSE +21 -0
  2. package/bin/agenthippo.js +2 -0
  3. package/out/agentpack/github.js +547 -0
  4. package/out/agentpack/index.js +66 -0
  5. package/out/agentpack/install.js +297 -0
  6. package/out/agentpack/manager.js +441 -0
  7. package/out/agentpack/manifest.js +135 -0
  8. package/out/agentpack/paths.js +475 -0
  9. package/out/agentpack/publish.js +248 -0
  10. package/out/agentpack/stores.js +554 -0
  11. package/out/agentpack/types.js +5 -0
  12. package/out/analytics/dashboard/artifactManager.js +439 -0
  13. package/out/analytics/dashboard/fleetDisplayUtils.js +159 -0
  14. package/out/analytics/dashboard/fleetOrchestrator.js +142 -0
  15. package/out/analytics/dashboard/fleetRegistry.js +79 -0
  16. package/out/analytics/dashboard/fleetRowDefaults.js +87 -0
  17. package/out/analytics/dashboard/fleetScriptAdapter.js +146 -0
  18. package/out/analytics/dashboard/fleetStatusUtils.js +30 -0
  19. package/out/analytics/dashboard/fleetTitleUtils.js +68 -0
  20. package/out/analytics/dashboard/fleetTypes.js +29 -0
  21. package/out/analytics/dashboard/index.js +17 -0
  22. package/out/analytics/dashboard/indexingService.js +422 -0
  23. package/out/analytics/dashboard/localFleetAdapter.js +222 -0
  24. package/out/analytics/dashboard/performanceMonitor.js +76 -0
  25. package/out/analytics/dashboard/processManager.js +209 -0
  26. package/out/analytics/dashboard/provider.js +3885 -0
  27. package/out/analytics/dashboard/queryRunner.js +994 -0
  28. package/out/analytics/dashboard/refreshPolicy.js +16 -0
  29. package/out/analytics/dashboard/scheduledFleetFingerprint.js +22 -0
  30. package/out/analytics/dashboard/scheduledFleetStorage.js +241 -0
  31. package/out/analytics/dashboard/scheduledFleetUtils.js +22 -0
  32. package/out/analytics/dashboard/sessionEventFleetStats.js +118 -0
  33. package/out/analytics/dashboard/sessionJsonlFleet.js +204 -0
  34. package/out/analytics/dashboard/teamViewDiscovery.js +106 -0
  35. package/out/analytics/dashboard/viewsConfigMerge.js +221 -0
  36. package/out/analytics/dashboard/webview/analytics-panel.html +155 -0
  37. package/out/analytics/dashboard/webview/codicon.ttf +0 -0
  38. package/out/analytics/dashboard/webview/index.html +78 -0
  39. package/out/analytics/dashboard/webview/panel.js +2295 -0
  40. package/out/analytics/dashboard/webview/runtime-bridge.js +82 -0
  41. package/out/analytics/dashboard/webview/styles.css +1009 -0
  42. package/out/analytics/lifecycle.js +43 -0
  43. package/out/analytics/service.js +1279 -0
  44. package/out/analytics/sessionEvents.js +231 -0
  45. package/out/auth/bootstrapApply.js +72 -0
  46. package/out/auth/brokerClient.js +126 -0
  47. package/out/auth/callbackUri.js +59 -0
  48. package/out/auth/callbackUriParse.js +59 -0
  49. package/out/auth/githubStoreGate.js +70 -0
  50. package/out/auth/loopbackAuthServer.js +165 -0
  51. package/out/auth/pkce.js +9 -0
  52. package/out/auth/provider.js +239 -0
  53. package/out/auth/sessionStore.js +193 -0
  54. package/out/auth/signInFlow.js +182 -0
  55. package/out/auth/types.js +12 -0
  56. package/out/auth-broker/config.js +62 -0
  57. package/out/auth-broker/jwt.js +105 -0
  58. package/out/auth-broker/pkce.js +57 -0
  59. package/out/auth-broker/server.js +539 -0
  60. package/out/auth-broker/store.js +273 -0
  61. package/out/base-prompts/gateway/openclaw-starter.json5 +144 -0
  62. package/out/base-prompts/gateway/slack-socket-mode-minimal.manifest.json +44 -0
  63. package/out/base-prompts/mcp-servers/.mcp.json +13 -0
  64. package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +142 -0
  65. package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +13 -0
  66. package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +1192 -0
  67. package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +23 -0
  68. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +12 -0
  69. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +102 -0
  70. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +137 -0
  71. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +118 -0
  72. package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +209 -0
  73. package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +431 -0
  74. package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +270 -0
  75. package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +18 -0
  76. package/out/base-prompts/rules/AGENTS.md +204 -0
  77. package/out/base-prompts/skills/agent-browser/SKILL.md +102 -0
  78. package/out/base-prompts/skills/agent-builder/SKILL.md +73 -0
  79. package/out/base-prompts/skills/agent-builder/references/agent-pack.md +63 -0
  80. package/out/base-prompts/skills/agent-builder/references/crewai.md +66 -0
  81. package/out/base-prompts/skills/agent-builder/references/langchain.md +60 -0
  82. package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +73 -0
  83. package/out/base-prompts/skills/agent-engine-creator/SKILL.md +586 -0
  84. package/out/base-prompts/skills/agent-engine-installer/SKILL.md +106 -0
  85. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +259 -0
  86. package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +189 -0
  87. package/out/base-prompts/skills/agenthippo-cli/SKILL.md +69 -0
  88. package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +63 -0
  89. package/out/base-prompts/skills/agentpack-creator/SKILL.md +375 -0
  90. package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +261 -0
  91. package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +195 -0
  92. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +391 -0
  93. package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +294 -0
  94. package/out/base-prompts/skills/agentpack-testbench/SKILL.md +135 -0
  95. package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +202 -0
  96. package/out/base-prompts/skills/algorithmic-art/SKILL.md +405 -0
  97. package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +223 -0
  98. package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +599 -0
  99. package/out/base-prompts/skills/debug-agent/SKILL.md +83 -0
  100. package/out/base-prompts/skills/desktop-automation/SKILL.md +166 -0
  101. package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +441 -0
  102. package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +280 -0
  103. package/out/base-prompts/skills/docx/LICENSE.txt +30 -0
  104. package/out/base-prompts/skills/docx/SKILL.md +197 -0
  105. package/out/base-prompts/skills/docx/docx-js.md +350 -0
  106. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  107. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  108. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  109. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  110. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  111. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  112. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  113. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  114. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  115. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  116. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  117. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  118. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  119. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  120. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  121. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  122. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  123. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  124. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  125. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  126. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  127. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  128. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  129. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  130. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  131. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  132. package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  133. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  134. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  135. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  136. package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  137. package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  138. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  139. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  140. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  141. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  142. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  143. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  144. package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  145. package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +159 -0
  146. package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +29 -0
  147. package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +69 -0
  148. package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  149. package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +951 -0
  150. package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  151. package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  152. package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  153. package/out/base-prompts/skills/docx/ooxml.md +610 -0
  154. package/out/base-prompts/skills/docx/scripts/__init__.py +1 -0
  155. package/out/base-prompts/skills/docx/scripts/document.py +1276 -0
  156. package/out/base-prompts/skills/docx/scripts/templates/comments.xml +3 -0
  157. package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  158. package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  159. package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +3 -0
  160. package/out/base-prompts/skills/docx/scripts/templates/people.xml +3 -0
  161. package/out/base-prompts/skills/docx/scripts/utilities.py +374 -0
  162. package/out/base-prompts/skills/gateway-outbound/SKILL.md +136 -0
  163. package/out/base-prompts/skills/mcp-builder/LICENSE.txt +202 -0
  164. package/out/base-prompts/skills/mcp-builder/SKILL.md +328 -0
  165. package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +602 -0
  166. package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  167. package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  168. package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  169. package/out/base-prompts/skills/mcp-builder/scripts/connections.py +151 -0
  170. package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +373 -0
  171. package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  172. package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +2 -0
  173. package/out/base-prompts/skills/openclaw/SKILL.md +406 -0
  174. package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +61 -0
  175. package/out/base-prompts/skills/pdf/LICENSE.txt +30 -0
  176. package/out/base-prompts/skills/pdf/SKILL.md +294 -0
  177. package/out/base-prompts/skills/pdf/forms.md +205 -0
  178. package/out/base-prompts/skills/pdf/reference.md +612 -0
  179. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  180. package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  181. package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +12 -0
  182. package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  183. package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +41 -0
  184. package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +152 -0
  185. package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  186. package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  187. package/out/base-prompts/skills/pptx/LICENSE.txt +30 -0
  188. package/out/base-prompts/skills/pptx/SKILL.md +484 -0
  189. package/out/base-prompts/skills/pptx/html2pptx.md +625 -0
  190. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  191. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  192. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  193. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  194. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  195. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  196. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  197. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  198. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  199. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  200. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  201. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  202. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  203. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  204. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  205. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  206. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  207. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  208. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  209. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  210. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  211. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  212. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  213. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  214. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  215. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  216. package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  217. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  218. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  219. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  220. package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  221. package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  222. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  223. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  224. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  225. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  226. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  227. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  228. package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  229. package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +159 -0
  230. package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +29 -0
  231. package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +69 -0
  232. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  233. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  234. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  235. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  236. package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  237. package/out/base-prompts/skills/pptx/ooxml.md +427 -0
  238. package/out/base-prompts/skills/pptx/scripts/html2pptx.js +984 -0
  239. package/out/base-prompts/skills/pptx/scripts/inventory.py +1020 -0
  240. package/out/base-prompts/skills/pptx/scripts/rearrange.py +231 -0
  241. package/out/base-prompts/skills/pptx/scripts/replace.py +385 -0
  242. package/out/base-prompts/skills/pptx/scripts/thumbnail.py +450 -0
  243. package/out/base-prompts/skills/prompt-lab/SKILL.md +149 -0
  244. package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +2551 -0
  245. package/out/base-prompts/skills/skill-creator/LICENSE.txt +202 -0
  246. package/out/base-prompts/skills/skill-creator/SKILL.md +371 -0
  247. package/out/base-prompts/skills/skill-creator/references/output-patterns.md +82 -0
  248. package/out/base-prompts/skills/skill-creator/references/workflows.md +28 -0
  249. package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +303 -0
  250. package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +110 -0
  251. package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +95 -0
  252. package/out/base-prompts/skills/skill-installer/SKILL.md +251 -0
  253. package/out/base-prompts/skills/skill-installer/references/store-api.md +219 -0
  254. package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +83 -0
  255. package/out/base-prompts/skills/spotlight-insights/SKILL.md +101 -0
  256. package/out/base-prompts/skills/spotlight-optimize/SKILL.md +93 -0
  257. package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +2551 -0
  258. package/out/base-prompts/skills/spotlight-query/SKILL.md +314 -0
  259. package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +163 -0
  260. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +2551 -0
  261. package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +744 -0
  262. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +14 -0
  263. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +7 -0
  264. package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +5 -0
  265. package/out/base-prompts/skills/spotlight-report/SKILL.md +86 -0
  266. package/out/base-prompts/skills/spotlight-visualize/SKILL.md +92 -0
  267. package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +2551 -0
  268. package/out/base-prompts/skills/xlsx/LICENSE.txt +30 -0
  269. package/out/base-prompts/skills/xlsx/SKILL.md +289 -0
  270. package/out/base-prompts/skills/xlsx/recalc.py +178 -0
  271. package/out/branding.js +23 -0
  272. package/out/cli/commands/anywhere.js +66 -0
  273. package/out/cli/commands/ask.js +243 -0
  274. package/out/cli/commands/auth-broker.js +24 -0
  275. package/out/cli/commands/auth.js +219 -0
  276. package/out/cli/commands/chat.js +354 -0
  277. package/out/cli/commands/deploy.js +223 -0
  278. package/out/cli/commands/gateway.js +160 -0
  279. package/out/cli/commands/pack.js +220 -0
  280. package/out/cli/commands/probe-custom-engine.js +82 -0
  281. package/out/cli/commands/serve.js +583 -0
  282. package/out/cli/commands/store.js +919 -0
  283. package/out/cli/credential-context.js +113 -0
  284. package/out/cli/deploy-init.js +2087 -0
  285. package/out/cli/deps.js +238 -0
  286. package/out/cli/index.js +390 -0
  287. package/out/cli/pack-loader.js +376 -0
  288. package/out/cli/run-custom-engine-runner.js +318 -0
  289. package/out/cli/runtime.js +409 -0
  290. package/out/cli/serve-hardening.js +325 -0
  291. package/out/cli/state-sync.js +135 -0
  292. package/out/cli/utils.js +220 -0
  293. package/out/cli/vscode-shim.js +86 -0
  294. package/out/engines/base.js +159 -0
  295. package/out/engines/claude.js +1215 -0
  296. package/out/engines/codex.js +759 -0
  297. package/out/engines/custom.js +632 -0
  298. package/out/engines/customEngineIpc.js +95 -0
  299. package/out/engines/customEngineRunnerEmbed.js +107 -0
  300. package/out/engines/customRegistry.js +274 -0
  301. package/out/engines/embeddedCustomEngineRunner.generated.js +9 -0
  302. package/out/engines/engineApiKey.js +138 -0
  303. package/out/engines/factory.js +45 -0
  304. package/out/engines/install.js +372 -0
  305. package/out/engines/persistentEngineWorker.js +320 -0
  306. package/out/engines/publish.js +341 -0
  307. package/out/engines/types.js +17 -0
  308. package/out/examples/run-headless-repl.js +291 -0
  309. package/out/examples/run-headless.js +187 -0
  310. package/out/extension.js +4472 -0
  311. package/out/gateway/bridge.js +805 -0
  312. package/out/gateway/cli-agent-id.js +36 -0
  313. package/out/gateway/client.js +303 -0
  314. package/out/gateway/client.test.js +395 -0
  315. package/out/gateway/gateway-scope-errors.js +14 -0
  316. package/out/gateway/gatewayBackup.js +76 -0
  317. package/out/gateway/gatewayRouteIndex.js +371 -0
  318. package/out/gateway/gatewaySessionStore.js +243 -0
  319. package/out/gateway/index.js +31 -0
  320. package/out/gateway/lifecycle.js +3056 -0
  321. package/out/gateway/openclaw-channel-routing.js +317 -0
  322. package/out/gateway/outboundHandles.js +373 -0
  323. package/out/gateway/outboundPaths.js +72 -0
  324. package/out/gateway/outboundSend.js +254 -0
  325. package/out/gateway/protocol.js +48 -0
  326. package/out/gateway/resetMappings.js +52 -0
  327. package/out/gateway/service.js +1244 -0
  328. package/out/gateway/sessionRouting.js +77 -0
  329. package/out/headless/index.js +505 -0
  330. package/out/headless/sync.js +473 -0
  331. package/out/mcp/publish.js +143 -0
  332. package/out/mcp.js +597 -0
  333. package/out/permissions.js +108 -0
  334. package/out/permissions.mapping.yaml +68 -0
  335. package/out/registry/index.js +332 -0
  336. package/out/remote/handleRemoteChat.js +122 -0
  337. package/out/remote/remotePackStatusBar.js +103 -0
  338. package/out/remote/serveClient.js +216 -0
  339. package/out/remoteSkills.js +191 -0
  340. package/out/runtime/index.js +32 -0
  341. package/out/runtime/interfaces/config-provider.js +32 -0
  342. package/out/runtime/interfaces/edit-tracker.js +22 -0
  343. package/out/runtime/interfaces/index.js +29 -0
  344. package/out/runtime/interfaces/logger.js +40 -0
  345. package/out/runtime/interfaces/permission-handler.js +66 -0
  346. package/out/runtime/interfaces/session-store.js +342 -0
  347. package/out/runtime/vscode/index.js +20 -0
  348. package/out/runtime/vscode/vscode-config-provider.js +77 -0
  349. package/out/runtime/vscode/vscode-edit-tracker.js +120 -0
  350. package/out/runtime/vscode/vscode-logger.js +30 -0
  351. package/out/runtime/vscode/vscode-permission-handler.js +72 -0
  352. package/out/runtime/vscode/vscode-session-store.js +22 -0
  353. package/out/scripts/agentide-litellm.ps1 +501 -0
  354. package/out/scripts/agentide-litellm.sh +700 -0
  355. package/out/scripts/agentide_litellm_hooks_v1.py +604 -0
  356. package/out/scripts/analytics/agent-fleet-widget.js +954 -0
  357. package/out/scripts/analytics/agentide-litellm-otel.config.yaml +160 -0
  358. package/out/scripts/analytics/default-seed-scripts.json +12 -0
  359. package/out/scripts/analytics/duckdbLocator.js +29 -0
  360. package/out/scripts/analytics/fleet-local-adapter.js +246 -0
  361. package/out/scripts/analytics/fleet-workflow.sh +263 -0
  362. package/out/scripts/analytics/generate-default-charts.py +685 -0
  363. package/out/scripts/analytics/hotspot-analysis-widget.js +909 -0
  364. package/out/scripts/analytics/index-traces.py +1394 -0
  365. package/out/scripts/analytics/install-analytics.sh +286 -0
  366. package/out/scripts/analytics/live-fleet-4-collector.cjs +315 -0
  367. package/out/scripts/analytics/live-fleet-4-daemon.mjs +134 -0
  368. package/out/scripts/analytics/live-fleet-4-widget.cjs +433 -0
  369. package/out/scripts/analytics/otel-collector.yaml +55 -0
  370. package/out/scripts/analytics/query-analytics.ps1 +396 -0
  371. package/out/scripts/analytics/query-analytics.sh +2551 -0
  372. package/out/scripts/analytics/session-comparison-widget.js +1468 -0
  373. package/out/scripts/analytics/session-timeline-widget.js +2137 -0
  374. package/out/scripts/analytics/setup-analytics.ps1 +432 -0
  375. package/out/scripts/analytics/setup-analytics.sh +854 -0
  376. package/out/scripts/analytics/start-analytics.ps1 +169 -0
  377. package/out/scripts/analytics/start-analytics.sh +323 -0
  378. package/out/scripts/analytics/token-cost-flamegraph-widget.js +954 -0
  379. package/out/scripts/analytics/token-cost-trend-widget.js +1062 -0
  380. package/out/scripts/analytics/workflows-collector.cjs +315 -0
  381. package/out/scripts/analytics/workflows-daemon.mjs +186 -0
  382. package/out/scripts/analytics/workflows-widget.cjs +433 -0
  383. package/out/scripts/analytics/wow-model-widget.js +191 -0
  384. package/out/scripts/gateway/Dockerfile.serve +45 -0
  385. package/out/scripts/gateway/docker-serve.sh +248 -0
  386. package/out/scripts/gateway/setup-gateway-server.ps1 +953 -0
  387. package/out/scripts/gateway/setup-gateway-server.sh +935 -0
  388. package/out/scripts/gateway/setup-gateway.ps1 +1813 -0
  389. package/out/scripts/gateway/setup-gateway.sh +1541 -0
  390. package/out/scripts/setup-cli.ps1 +86 -0
  391. package/out/scripts/setup-cli.sh +117 -0
  392. package/out/scripts/tools-manifest.json +83 -0
  393. package/out/scripts/vendor-tools.mjs +234 -0
  394. package/out/session.js +272 -0
  395. package/out/shared/agentEngines.js +170 -0
  396. package/out/shared/index.js +109 -0
  397. package/out/shared/models.js +235 -0
  398. package/out/shared/providers.js +202 -0
  399. package/out/skills/publish.js +178 -0
  400. package/out/spotlight/install.js +339 -0
  401. package/out/spotlight/publish.js +544 -0
  402. package/out/spotlight/yaml.js +31 -0
  403. package/out/store/github/setup.js +235 -0
  404. package/out/store/github/templates/build-index.ts +339 -0
  405. package/out/store/github/templates/build-index.yml +97 -0
  406. package/out/store/github/templates/package.json +11 -0
  407. package/out/store/index.js +755 -0
  408. package/out/store/oramaIndex.js +884 -0
  409. package/out/store/shared.js +241 -0
  410. package/out/sync.js +1827 -0
  411. package/out/terminalLogger.js +358 -0
  412. package/out/test/agentEnvFile.test.js +97 -0
  413. package/out/test/agentYaml.test.js +373 -0
  414. package/out/test/agentpack.test.js +639 -0
  415. package/out/test/analytics-lifecycle.test.js +174 -0
  416. package/out/test/analytics.test.js +524 -0
  417. package/out/test/auth-bootstrapApply.test.js +102 -0
  418. package/out/test/auth-broker.test.js +434 -0
  419. package/out/test/auth-callback.test.js +62 -0
  420. package/out/test/branding.test.js +229 -0
  421. package/out/test/cli-agent-id.test.js +55 -0
  422. package/out/test/credential-context.test.js +105 -0
  423. package/out/test/customEngineInstall.test.js +100 -0
  424. package/out/test/customRegistry.test.js +122 -0
  425. package/out/test/deploy-init.test.js +532 -0
  426. package/out/test/deps-auto-install.test.js +81 -0
  427. package/out/test/engine-integration.test.js +297 -0
  428. package/out/test/enginePaths.test.js +195 -0
  429. package/out/test/enginePublish.test.js +82 -0
  430. package/out/test/fleetDisplayUtils.test.js +96 -0
  431. package/out/test/gateway-client.test.js +381 -0
  432. package/out/test/gateway-lifecycle.test.js +608 -0
  433. package/out/test/gateway-outbound.test.js +531 -0
  434. package/out/test/gateway-reset-mappings.test.js +221 -0
  435. package/out/test/gateway-route-index.test.js +235 -0
  436. package/out/test/gateway-session-routing.test.js +47 -0
  437. package/out/test/gateway-session-store.test.js +216 -0
  438. package/out/test/github.test.js +232 -0
  439. package/out/test/headless-sync.test.js +279 -0
  440. package/out/test/helpers/manifest-fixtures.js +27 -0
  441. package/out/test/mcp-obo.test.js +82 -0
  442. package/out/test/mcp.test.js +307 -0
  443. package/out/test/openclaw-channel-routing.test.js +191 -0
  444. package/out/test/pathSafety.test.js +63 -0
  445. package/out/test/permissions.test.js +175 -0
  446. package/out/test/persistent-engine-worker.test.js +220 -0
  447. package/out/test/refreshPolicy.test.js +60 -0
  448. package/out/test/registry.test.js +351 -0
  449. package/out/test/runtime.test.js +349 -0
  450. package/out/test/scheduledFleetStorage.test.js +72 -0
  451. package/out/test/serve-hardening.test.js +192 -0
  452. package/out/test/serveClient.test.js +173 -0
  453. package/out/test/sessionJsonlFleet.test.js +78 -0
  454. package/out/test/shared.test.js +173 -0
  455. package/out/test/skills-mcp.test.js +299 -0
  456. package/out/test/spotlightPublish.test.js +299 -0
  457. package/out/test/spotlightYaml.test.js +58 -0
  458. package/out/test/state-sync-peer.test.js +74 -0
  459. package/out/test/store.test.js +331 -0
  460. package/out/test/stores.test.js +504 -0
  461. package/out/test/sync-switch.test.js +251 -0
  462. package/out/test/teamViewDiscovery.test.js +90 -0
  463. package/out/test/toolPath.test.js +120 -0
  464. package/out/test/utils.test.js +308 -0
  465. package/out/test/viewsConfigMerge.test.js +180 -0
  466. package/out/test/windows-command-line.test.js +75 -0
  467. package/out/utils/agentEnvFile.js +131 -0
  468. package/out/utils/binary.js +175 -0
  469. package/out/utils/index.js +37 -0
  470. package/out/utils/network.js +74 -0
  471. package/out/utils/pathSafety.js +60 -0
  472. package/out/utils/paths.js +116 -0
  473. package/out/utils/pid.js +180 -0
  474. package/out/utils/pythonRunner.js +258 -0
  475. package/out/utils/resolveNodeBinary.js +168 -0
  476. package/out/utils/toolPath.js +83 -0
  477. package/out/utils/windowsCommandLine.js +29 -0
  478. package/out/utils.js +915 -0
  479. package/out/workspaceFolders.js +59 -0
  480. 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()