@agenthippo-ai/agenthippo 1.110.9 → 1.110.19
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/out/agentpack/types.js +2 -5
- package/out/analytics/dashboard/artifactManager.js +2 -439
- package/out/analytics/dashboard/fleetDisplayUtils.js +2 -162
- package/out/analytics/dashboard/fleetOrchestrator.js +3 -142
- package/out/analytics/dashboard/fleetRegistry.js +2 -79
- package/out/analytics/dashboard/fleetRowDefaults.js +2 -87
- package/out/analytics/dashboard/fleetScriptAdapter.js +2 -146
- package/out/analytics/dashboard/fleetTypes.js +2 -29
- package/out/analytics/dashboard/index.js +2 -17
- package/out/analytics/dashboard/indexingService.js +2 -422
- package/out/analytics/dashboard/localFleetAdapter.js +2 -222
- package/out/analytics/dashboard/performanceMonitor.js +5 -76
- package/out/analytics/dashboard/processManager.js +2 -209
- package/out/analytics/dashboard/provider.js +38 -3817
- package/out/analytics/dashboard/queryRunner.js +62 -750
- package/out/analytics/dashboard/scheduledFleetStorage.js +2 -241
- package/out/analytics/dashboard/sessionJsonlFleet.js +3 -204
- package/out/analytics/dashboard/teamViewDiscovery.js +2 -106
- package/out/analytics/dashboard/webview/panel.js +34 -2318
- package/out/analytics/dashboard/webview/runtime-bridge.js +2 -82
- package/out/analytics/lifecycle.js +2 -43
- package/out/analytics/service.js +8 -1277
- package/out/auth/authBaseUrl.js +2 -59
- package/out/auth/bootstrapApply.js +2 -71
- package/out/auth/brokerClient.js +2 -160
- package/out/auth/callbackUri.js +2 -59
- package/out/auth/githubStoreGate.js +2 -70
- package/out/auth/loopbackAuthServer.js +4 -159
- package/out/auth/onboardingPrompt.js +2 -112
- package/out/auth/pkce.js +2 -9
- package/out/auth/provider.js +2 -226
- package/out/auth/sessionStore.js +2 -156
- package/out/auth/signInFlow.js +2 -183
- package/out/cli/index.js +619 -551
- package/out/cli/run-custom-engine-runner.js +3 -318
- package/out/cli/vscode-shim.js +2 -86
- package/out/engines/factory.js +2 -45
- package/out/engines/types.js +2 -17
- package/out/examples/run-headless-repl.js +6 -286
- package/out/examples/run-headless.js +2 -187
- package/out/extension.js +32 -4473
- package/out/gateway/gatewayRouteIndex.js +6 -371
- package/out/gateway/gatewaySessionStore.js +3 -243
- package/out/gateway/index.js +2 -31
- package/out/gateway/resetMappings.js +2 -52
- package/out/gateway/service.js +5 -1249
- package/out/mcp/publish.js +2 -143
- package/out/remote/handleRemoteChat.js +2 -169
- package/out/remote/remotePackStatusBar.js +3 -103
- package/out/remote/remoteTrust.js +6 -277
- package/out/remote/serveClient.js +4 -277
- package/out/remoteSkills.js +3 -191
- package/out/runtime/index.js +2 -32
- package/out/runtime/vscode/index.js +2 -20
- package/out/runtime/vscode/vscode-config-provider.js +2 -77
- package/out/runtime/vscode/vscode-edit-tracker.js +2 -122
- package/out/runtime/vscode/vscode-logger.js +2 -30
- package/out/runtime/vscode/vscode-permission-handler.js +2 -72
- package/out/scripts/agentide-litellm.sh +0 -1
- package/out/scripts/agentide_litellm_hooks_v1.py +170 -418
- package/out/scripts/analytics/agent-fleet-widget.js +18 -257
- package/out/scripts/analytics/agentide-litellm-otel.config.yaml +4 -4
- package/out/scripts/analytics/duckdbLocator.js +2 -28
- package/out/scripts/analytics/generate-default-charts.py +43 -323
- package/out/scripts/analytics/hotspot-analysis-widget.js +4 -430
- package/out/scripts/analytics/index-traces.py +78 -1036
- package/out/scripts/analytics/session-comparison-widget.js +26 -472
- package/out/scripts/analytics/session-timeline-widget.js +25 -846
- package/out/scripts/analytics/setup-analytics.ps1 +8 -1
- package/out/scripts/analytics/setup-analytics.sh +13 -2
- package/out/scripts/analytics/token-cost-flamegraph-widget.js +4 -461
- package/out/scripts/analytics/token-cost-trend-widget.js +4 -534
- package/out/scripts/analytics/workflows-collector.cjs +4 -314
- package/out/scripts/analytics/workflows-daemon.mjs +9 -185
- package/out/scripts/analytics/workflows-widget.cjs +15 -159
- package/out/scripts/analytics/wow-model-widget.js +10 -120
- package/out/scripts/vendor-tools.mjs +2 -233
- package/out/skills/publish.js +3 -178
- package/out/store/github/setup.js +7 -212
- package/out/store/oramaIndex.js +2 -884
- package/out/sync.js +26 -1829
- package/out/terminalLogger.js +5 -358
- package/out/utils/pathSafety.js +2 -60
- package/out/utils/pythonRunner.js +4 -258
- package/out/utils/toolPath.js +2 -83
- package/out/workspaceFolders.js +2 -59
- package/package.json +1 -1
- package/out/agentpack/github.js +0 -547
- package/out/agentpack/index.js +0 -67
- package/out/agentpack/install.js +0 -297
- package/out/agentpack/manager.js +0 -441
- package/out/agentpack/manifest.js +0 -135
- package/out/agentpack/paths.js +0 -498
- package/out/agentpack/publish.js +0 -248
- package/out/agentpack/stores.js +0 -554
- package/out/analytics/dashboard/fleetStatusUtils.js +0 -30
- package/out/analytics/dashboard/fleetTitleUtils.js +0 -68
- package/out/analytics/dashboard/refreshPolicy.js +0 -16
- package/out/analytics/dashboard/scheduledFleetFingerprint.js +0 -22
- package/out/analytics/dashboard/scheduledFleetUtils.js +0 -22
- package/out/analytics/dashboard/sessionEventFleetStats.js +0 -118
- package/out/analytics/dashboard/viewsConfigMerge.js +0 -221
- package/out/analytics/dashboard/webview/codicon.ttf +0 -0
- package/out/analytics/identity.js +0 -0
- package/out/analytics/sessionEvents.js +0 -323
- package/out/auth/callbackUriParse.js +0 -59
- package/out/auth/types.js +0 -12
- package/out/auth-broker/config.js +0 -112
- package/out/auth-broker/jwt.js +0 -105
- package/out/auth-broker/pkce.js +0 -59
- package/out/auth-broker/server.js +0 -677
- package/out/auth-broker/store.js +0 -275
- package/out/authority/warrant.js +0 -206
- package/out/base-prompts/mcp-servers/.mcp.json +0 -13
- package/out/base-prompts/mcp-servers/langfuse-analytics/README.md +0 -142
- package/out/base-prompts/mcp-servers/langfuse-analytics/mcp.json +0 -13
- package/out/base-prompts/mcp-servers/langfuse-analytics/package-lock.json +0 -1192
- package/out/base-prompts/mcp-servers/langfuse-analytics/package.json +0 -23
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/run-with-env.sh +0 -12
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/sdk-test.js +0 -102
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/simple-test.js +0 -137
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-client.js +0 -118
- package/out/base-prompts/mcp-servers/langfuse-analytics/scripts/test-server.js +0 -209
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/client.ts +0 -431
- package/out/base-prompts/mcp-servers/langfuse-analytics/src/index.ts +0 -270
- package/out/base-prompts/mcp-servers/langfuse-analytics/tsconfig.json +0 -18
- package/out/base-prompts/rules/AGENTS.md +0 -204
- package/out/base-prompts/skills/agent-browser/SKILL.md +0 -102
- package/out/base-prompts/skills/agent-builder/SKILL.md +0 -73
- package/out/base-prompts/skills/agent-builder/references/agent-pack.md +0 -63
- package/out/base-prompts/skills/agent-builder/references/crewai.md +0 -66
- package/out/base-prompts/skills/agent-builder/references/langchain.md +0 -60
- package/out/base-prompts/skills/agent-builder/references/raw-sdk.md +0 -73
- package/out/base-prompts/skills/agent-engine-creator/SKILL.md +0 -586
- package/out/base-prompts/skills/agent-engine-installer/SKILL.md +0 -106
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.mjs +0 -259
- package/out/base-prompts/skills/agent-engine-installer/scripts/install-engine.ps1 +0 -189
- package/out/base-prompts/skills/agenthippo-cli/SKILL.md +0 -69
- package/out/base-prompts/skills/agenthippo-cli/scripts/install.sh +0 -63
- package/out/base-prompts/skills/agentpack-creator/SKILL.md +0 -375
- package/out/base-prompts/skills/agentpack-creator/references/agent-templates.md +0 -261
- package/out/base-prompts/skills/agentpack-creator/references/agents-md-guide.md +0 -195
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack.py +0 -391
- package/out/base-prompts/skills/agentpack-creator/scripts/init_pack_test.py +0 -294
- package/out/base-prompts/skills/agentpack-testbench/SKILL.md +0 -135
- package/out/base-prompts/skills/algorithmic-art/LICENSE.txt +0 -202
- package/out/base-prompts/skills/algorithmic-art/SKILL.md +0 -405
- package/out/base-prompts/skills/algorithmic-art/templates/generator_template.js +0 -223
- package/out/base-prompts/skills/algorithmic-art/templates/viewer.html +0 -599
- package/out/base-prompts/skills/debug-agent/SKILL.md +0 -83
- package/out/base-prompts/skills/desktop-automation/SKILL.md +0 -166
- package/out/base-prompts/skills/desktop-automation/references/agenthippo-ui-recipes.md +0 -441
- package/out/base-prompts/skills/desktop-automation/scripts/windows-desktop-uia.psm1 +0 -280
- package/out/base-prompts/skills/docx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/docx/SKILL.md +0 -197
- package/out/base-prompts/skills/docx/docx-js.md +0 -350
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/out/base-prompts/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/out/base-prompts/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/out/base-prompts/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/out/base-prompts/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/out/base-prompts/skills/docx/ooxml/scripts/pack.py +0 -159
- package/out/base-prompts/skills/docx/ooxml/scripts/unpack.py +0 -29
- package/out/base-prompts/skills/docx/ooxml/scripts/validate.py +0 -69
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/base.py +0 -951
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/docx.py +0 -274
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
- package/out/base-prompts/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
- package/out/base-prompts/skills/docx/ooxml.md +0 -610
- package/out/base-prompts/skills/docx/scripts/__init__.py +0 -1
- package/out/base-prompts/skills/docx/scripts/document.py +0 -1276
- package/out/base-prompts/skills/docx/scripts/templates/comments.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtended.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/commentsIds.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/templates/people.xml +0 -3
- package/out/base-prompts/skills/docx/scripts/utilities.py +0 -374
- package/out/base-prompts/skills/gateway-outbound/SKILL.md +0 -136
- package/out/base-prompts/skills/mcp-builder/LICENSE.txt +0 -202
- package/out/base-prompts/skills/mcp-builder/SKILL.md +0 -328
- package/out/base-prompts/skills/mcp-builder/reference/evaluation.md +0 -602
- package/out/base-prompts/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
- package/out/base-prompts/skills/mcp-builder/reference/node_mcp_server.md +0 -970
- package/out/base-prompts/skills/mcp-builder/reference/python_mcp_server.md +0 -719
- package/out/base-prompts/skills/mcp-builder/scripts/connections.py +0 -151
- package/out/base-prompts/skills/mcp-builder/scripts/evaluation.py +0 -373
- package/out/base-prompts/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
- package/out/base-prompts/skills/mcp-builder/scripts/requirements.txt +0 -2
- package/out/base-prompts/skills/openclaw/SKILL.md +0 -406
- package/out/base-prompts/skills/openclaw/scripts/run-smoke.sh +0 -61
- package/out/base-prompts/skills/pdf/LICENSE.txt +0 -30
- package/out/base-prompts/skills/pdf/SKILL.md +0 -294
- package/out/base-prompts/skills/pdf/forms.md +0 -205
- package/out/base-prompts/skills/pdf/reference.md +0 -612
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes.py +0 -70
- package/out/base-prompts/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
- package/out/base-prompts/skills/pdf/scripts/check_fillable_fields.py +0 -12
- package/out/base-prompts/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
- package/out/base-prompts/skills/pdf/scripts/create_validation_image.py +0 -41
- package/out/base-prompts/skills/pdf/scripts/extract_form_field_info.py +0 -152
- package/out/base-prompts/skills/pdf/scripts/fill_fillable_fields.py +0 -114
- package/out/base-prompts/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
- package/out/base-prompts/skills/pptx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/pptx/SKILL.md +0 -484
- package/out/base-prompts/skills/pptx/html2pptx.md +0 -625
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
- package/out/base-prompts/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
- package/out/base-prompts/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
- package/out/base-prompts/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
- package/out/base-prompts/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
- package/out/base-prompts/skills/pptx/ooxml/scripts/pack.py +0 -159
- package/out/base-prompts/skills/pptx/ooxml/scripts/unpack.py +0 -29
- package/out/base-prompts/skills/pptx/ooxml/scripts/validate.py +0 -69
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/base.py +0 -951
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
- package/out/base-prompts/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
- package/out/base-prompts/skills/pptx/ooxml.md +0 -427
- package/out/base-prompts/skills/pptx/scripts/html2pptx.js +0 -984
- package/out/base-prompts/skills/pptx/scripts/inventory.py +0 -1020
- package/out/base-prompts/skills/pptx/scripts/rearrange.py +0 -231
- package/out/base-prompts/skills/pptx/scripts/replace.py +0 -385
- package/out/base-prompts/skills/pptx/scripts/thumbnail.py +0 -450
- package/out/base-prompts/skills/prompt-lab/SKILL.md +0 -149
- package/out/base-prompts/skills/prompt-lab/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/skill-creator/LICENSE.txt +0 -202
- package/out/base-prompts/skills/skill-creator/SKILL.md +0 -371
- package/out/base-prompts/skills/skill-creator/references/output-patterns.md +0 -82
- package/out/base-prompts/skills/skill-creator/references/workflows.md +0 -28
- package/out/base-prompts/skills/skill-creator/scripts/init_skill.py +0 -303
- package/out/base-prompts/skills/skill-creator/scripts/package_skill.py +0 -110
- package/out/base-prompts/skills/skill-creator/scripts/quick_validate.py +0 -95
- package/out/base-prompts/skills/skill-installer/SKILL.md +0 -251
- package/out/base-prompts/skills/skill-installer/references/store-api.md +0 -219
- package/out/base-prompts/skills/spotlight-dashboard/SKILL.md +0 -83
- package/out/base-prompts/skills/spotlight-insights/SKILL.md +0 -101
- package/out/base-prompts/skills/spotlight-optimize/SKILL.md +0 -93
- package/out/base-prompts/skills/spotlight-optimize/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/spotlight-query/SKILL.md +0 -314
- package/out/base-prompts/skills/spotlight-query/references/otel-schema.md +0 -163
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/spotlight-query/scripts/query-analytics.test.sh +0 -744
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/sessions/sess-test-1.jsonl +0 -14
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/.duckdb-index.json +0 -7
- package/out/base-prompts/skills/spotlight-query/scripts/test-fixtures/analytics/traces/sample.jsonl +0 -5
- package/out/base-prompts/skills/spotlight-report/SKILL.md +0 -86
- package/out/base-prompts/skills/spotlight-visualize/SKILL.md +0 -92
- package/out/base-prompts/skills/spotlight-visualize/scripts/query-analytics.sh +0 -2551
- package/out/base-prompts/skills/xlsx/LICENSE.txt +0 -30
- package/out/base-prompts/skills/xlsx/SKILL.md +0 -289
- package/out/base-prompts/skills/xlsx/recalc.py +0 -178
- package/out/branding.js +0 -49
- package/out/cli/commands/anywhere.js +0 -66
- package/out/cli/commands/ask.js +0 -246
- package/out/cli/commands/auth-broker.js +0 -24
- package/out/cli/commands/auth.js +0 -219
- package/out/cli/commands/chat.js +0 -357
- package/out/cli/commands/conformance.js +0 -249
- package/out/cli/commands/data-plane.js +0 -67
- package/out/cli/commands/deploy.js +0 -263
- package/out/cli/commands/gateway.js +0 -218
- package/out/cli/commands/idp.js +0 -85
- package/out/cli/commands/pack.js +0 -399
- package/out/cli/commands/probe-custom-engine.js +0 -82
- package/out/cli/commands/sandbox.js +0 -332
- package/out/cli/commands/serve.js +0 -1758
- package/out/cli/commands/store.js +0 -927
- package/out/cli/credential-context.js +0 -91
- package/out/cli/data-plane/broker.js +0 -78
- package/out/cli/data-plane/connector-host.js +0 -121
- package/out/cli/data-plane/egress.js +0 -189
- package/out/cli/data-plane/gateway.js +0 -218
- package/out/cli/data-plane/index.js +0 -152
- package/out/cli/data-plane/registry.js +0 -89
- package/out/cli/data-plane/remote.js +0 -106
- package/out/cli/data-plane/sidecar.js +0 -161
- package/out/cli/deploy/blueprints/registry.js +0 -84
- package/out/cli/deploy/layers/identity.js +0 -172
- package/out/cli/deploy-init.js +0 -3023
- package/out/cli/deps.js +0 -342
- package/out/cli/idp-init.js +0 -338
- package/out/cli/pack-install-ref.js +0 -15
- package/out/cli/pack-loader.js +0 -418
- package/out/cli/pack-runtime.js +0 -61
- package/out/cli/runtime.js +0 -450
- package/out/cli/serve-hardening.js +0 -607
- package/out/cli/state-sync.js +0 -424
- package/out/cli/utils.js +0 -231
- package/out/engines/base.js +0 -188
- package/out/engines/claude.js +0 -1254
- package/out/engines/codex.js +0 -862
- package/out/engines/custom.js +0 -674
- package/out/engines/customEngineIpc.js +0 -95
- package/out/engines/customEngineRunnerEmbed.js +0 -107
- package/out/engines/customRegistry.js +0 -274
- package/out/engines/embeddedCustomEngineRunner.generated.js +0 -9
- package/out/engines/engineApiKey.js +0 -138
- package/out/engines/install.js +0 -372
- package/out/engines/persistentEngineWorker.js +0 -320
- package/out/engines/publish.js +0 -341
- package/out/evidence/sessionShip.js +0 -610
- package/out/gateway/bridge.js +0 -843
- package/out/gateway/cli-agent-id.js +0 -36
- package/out/gateway/client.js +0 -336
- package/out/gateway/client.test.js +0 -395
- package/out/gateway/gateway-scope-errors.js +0 -14
- package/out/gateway/gatewayBackup.js +0 -76
- package/out/gateway/installSource.js +0 -68
- package/out/gateway/lifecycle.js +0 -3190
- package/out/gateway/openclaw-channel-routing.js +0 -317
- package/out/gateway/outboundHandles.js +0 -373
- package/out/gateway/outboundPaths.js +0 -75
- package/out/gateway/outboundSend.js +0 -254
- package/out/gateway/protocol.js +0 -48
- package/out/gateway/secretsPreflight.js +0 -90
- package/out/gateway/sessionRouting.js +0 -77
- package/out/headless/index.js +0 -539
- package/out/headless/sync.js +0 -473
- package/out/live-e2e/mcp-demo/server.mjs +0 -32
- package/out/live-probe/connector.mjs +0 -8
- package/out/live-probe/env-report.mjs +0 -8
- package/out/mcp.js +0 -654
- package/out/pack/caps.js +0 -271
- package/out/pack/governor.js +0 -309
- package/out/pack/lease-schema.js +0 -270
- package/out/pack/lease.js +0 -640
- package/out/pack/reconcile.js +0 -217
- package/out/pack/signature.js +0 -839
- package/out/permissions.js +0 -108
- package/out/permissions.mapping.yaml +0 -68
- package/out/registry/index.js +0 -332
- package/out/runner/host.js +0 -131
- package/out/runner/protocol.js +0 -108
- package/out/runner/remoteEngine.js +0 -130
- package/out/runtime/interfaces/config-provider.js +0 -32
- package/out/runtime/interfaces/edit-tracker.js +0 -24
- package/out/runtime/interfaces/index.js +0 -29
- package/out/runtime/interfaces/logger.js +0 -40
- package/out/runtime/interfaces/permission-handler.js +0 -66
- package/out/runtime/interfaces/session-store.js +0 -342
- package/out/runtime/vscode/vscode-session-store.js +0 -22
- package/out/sandbox/containerDriver.js +0 -570
- package/out/sandbox/processDriver.js +0 -315
- package/out/sandbox/sandboxRunner.js +0 -191
- package/out/sandbox/support.js +0 -301
- package/out/sandbox/types.js +0 -55
- package/out/scripts/analytics/fleet-local-adapter.js +0 -246
- package/out/scripts/analytics/live-fleet-4-collector.cjs +0 -315
- package/out/scripts/analytics/live-fleet-4-daemon.mjs +0 -134
- package/out/scripts/analytics/live-fleet-4-widget.cjs +0 -433
- package/out/scripts/gateway/Dockerfile.serve +0 -45
- package/out/scripts/gateway/docker-serve.sh +0 -248
- package/out/scripts/gateway/setup-gateway-server.ps1 +0 -953
- package/out/scripts/gateway/setup-gateway-server.sh +0 -935
- package/out/session.js +0 -272
- package/out/shared/agentEngines.js +0 -170
- package/out/shared/index.js +0 -109
- package/out/shared/models.js +0 -136
- package/out/shared/providers.js +0 -205
- package/out/spotlight/install.js +0 -345
- package/out/spotlight/publish.js +0 -544
- package/out/spotlight/yaml.js +0 -31
- package/out/store/index.js +0 -786
- package/out/store/shared.js +0 -241
- package/out/test/agentEnvFile.test.js +0 -97
- package/out/test/agentYaml.test.js +0 -373
- package/out/test/agentpack.test.js +0 -639
- package/out/test/analytics-lifecycle.test.js +0 -174
- package/out/test/analytics.test.js +0 -756
- package/out/test/auth-baseurl.test.js +0 -132
- package/out/test/auth-bootstrapApply.test.js +0 -123
- package/out/test/auth-broker-hardening.test.js +0 -227
- package/out/test/auth-broker.test.js +0 -541
- package/out/test/auth-callback.test.js +0 -62
- package/out/test/blueprint-registry.test.js +0 -105
- package/out/test/branding.test.js +0 -242
- package/out/test/caps-governor.test.js +0 -455
- package/out/test/cli-agent-id.test.js +0 -55
- package/out/test/codex-new-file-survival.test.js +0 -119
- package/out/test/configuration-scopes.test.js +0 -131
- package/out/test/credential-context.test.js +0 -160
- package/out/test/custom-env-layering.test.js +0 -151
- package/out/test/customEngineInstall.test.js +0 -100
- package/out/test/customRegistry.test.js +0 -122
- package/out/test/data-plane-engine-wiring.test.js +0 -250
- package/out/test/data-plane.test.js +0 -311
- package/out/test/deploy-init.test.js +0 -854
- package/out/test/deps-auto-install.test.js +0 -81
- package/out/test/egress-broker.test.js +0 -172
- package/out/test/engine-integration.test.js +0 -297
- package/out/test/enginePaths.test.js +0 -195
- package/out/test/enginePublish.test.js +0 -82
- package/out/test/fleetDisplayUtils.test.js +0 -100
- package/out/test/gateway-client.test.js +0 -409
- package/out/test/gateway-install-source.test.js +0 -111
- package/out/test/gateway-lifecycle.test.js +0 -608
- package/out/test/gateway-outbound.test.js +0 -538
- package/out/test/gateway-reset-mappings.test.js +0 -221
- package/out/test/gateway-route-index.test.js +0 -235
- package/out/test/gateway-secrets-preflight.test.js +0 -127
- package/out/test/gateway-session-routing.test.js +0 -65
- package/out/test/gateway-session-store.test.js +0 -216
- package/out/test/github.test.js +0 -232
- package/out/test/governor-hardening.test.js +0 -217
- package/out/test/headless-sync.test.js +0 -301
- package/out/test/helpers/manifest-fixtures.js +0 -27
- package/out/test/idp-init.test.js +0 -151
- package/out/test/lease-signature.test.js +0 -357
- package/out/test/lease-trust-root.test.js +0 -273
- package/out/test/lease-validation.test.js +0 -169
- package/out/test/lease.test.js +0 -114
- package/out/test/mcp-obo.test.js +0 -107
- package/out/test/mcp.test.js +0 -389
- package/out/test/model-routing.test.js +0 -133
- package/out/test/openclaw-channel-routing.test.js +0 -191
- package/out/test/pack-admission.test.js +0 -216
- package/out/test/pack-digest-parity.test.js +0 -140
- package/out/test/pack-reconcile.test.js +0 -183
- package/out/test/pack-signature-artifact.test.js +0 -103
- package/out/test/pack-signature.test.js +0 -176
- package/out/test/pack-trust-root.test.js +0 -202
- package/out/test/pathSafety.test.js +0 -63
- package/out/test/permissions.test.js +0 -175
- package/out/test/persistent-engine-worker.test.js +0 -220
- package/out/test/refreshPolicy.test.js +0 -60
- package/out/test/registry.test.js +0 -351
- package/out/test/remote-trust.test.js +0 -242
- package/out/test/runner-protocol.test.js +0 -249
- package/out/test/runtime.test.js +0 -349
- package/out/test/sandbox-driver.test.js +0 -553
- package/out/test/sandbox-hardening.test.js +0 -395
- package/out/test/sandbox-runner.test.js +0 -343
- package/out/test/scheduledFleetStorage.test.js +0 -72
- package/out/test/serve-gateway-turn.test.js +0 -267
- package/out/test/serve-hardening.test.js +0 -418
- package/out/test/serveClient.test.js +0 -209
- package/out/test/sessionJsonlFleet.test.js +0 -78
- package/out/test/sessionShip.test.js +0 -560
- package/out/test/shared.test.js +0 -173
- package/out/test/skills-mcp.test.js +0 -299
- package/out/test/spotlightPublish.test.js +0 -327
- package/out/test/spotlightYaml.test.js +0 -58
- package/out/test/state-sync-peer.test.js +0 -156
- package/out/test/store-install-safe.test.js +0 -69
- package/out/test/store.test.js +0 -331
- package/out/test/stores.test.js +0 -504
- package/out/test/sync-switch.test.js +0 -251
- package/out/test/teamViewDiscovery.test.js +0 -90
- package/out/test/tls-bypass.test.js +0 -90
- package/out/test/toolPath.test.js +0 -120
- package/out/test/utils.test.js +0 -308
- package/out/test/viewsConfigMerge.test.js +0 -180
- package/out/test/warrant.test.js +0 -138
- package/out/test/windows-command-line.test.js +0 -75
- package/out/utils/agentEnvFile.js +0 -131
- package/out/utils/binary.js +0 -175
- package/out/utils/index.js +0 -37
- package/out/utils/network.js +0 -74
- package/out/utils/paths.js +0 -116
- package/out/utils/pid.js +0 -180
- package/out/utils/resolveNodeBinary.js +0 -168
- package/out/utils/windowsCommandLine.js +0 -29
- package/out/utils.js +0 -968
|
@@ -1,607 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
* Copyright (c) AgentHippo.ai. All rights reserved.
|
|
4
|
-
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.TurnGate = exports.TURN_LIMIT_BUSY_MESSAGE = exports.RATE_LIMIT_BUSY_MESSAGE = exports.TURN_GATE_BUSY_MESSAGE = exports.TURN_GATE_RETRY_AFTER_SECONDS = exports.TURN_QUEUE_ENV = exports.MAX_CONCURRENT_TURNS_ENV = exports.TurnLimiter = exports.SESSION_WITHOUT_USER_REASON = exports.IDENTITY_HEADER_ENV = exports.PIN_ONLY_IDENTITY_HEADERS = exports.RateLimiter = exports.XFF_TRUSTED_HOPS_ENV = exports.CONTAINER_SERVE_HOST = exports.SERVE_HOST_ENV = exports.DEFAULT_BIND_HOST = exports.DEFAULT_MAX_BODY_BYTES = void 0;
|
|
40
|
-
exports.resolveStateDir = resolveStateDir;
|
|
41
|
-
exports.resolveAnalyticsSessionsDir = resolveAnalyticsSessionsDir;
|
|
42
|
-
exports.isLoopbackHost = isLoopbackHost;
|
|
43
|
-
exports.resolveBindHost = resolveBindHost;
|
|
44
|
-
exports.clientIp = clientIp;
|
|
45
|
-
exports.identityHeaderAdvice = identityHeaderAdvice;
|
|
46
|
-
exports.resolveUserId = resolveUserId;
|
|
47
|
-
exports.resolveDataToken = resolveDataToken;
|
|
48
|
-
exports.peerToUserId = peerToUserId;
|
|
49
|
-
exports.userNamespaceHash = userNamespaceHash;
|
|
50
|
-
exports.resolveServeSessionKey = resolveServeSessionKey;
|
|
51
|
-
exports.corsHeaders = corsHeaders;
|
|
52
|
-
exports.createTurnGateFromEnv = createTurnGateFromEnv;
|
|
53
|
-
exports.createRejectionWarner = createRejectionWarner;
|
|
54
|
-
exports.readBodyWithCap = readBodyWithCap;
|
|
55
|
-
/**
|
|
56
|
-
* Serve helpers: state-dir resolution, identity header reading, CORS, turn limiting, body cap.
|
|
57
|
-
*
|
|
58
|
-
* Auth and credential checking are the deploy layer's responsibility (Caddy, Cloud Run IAP,
|
|
59
|
-
* Databricks Apps SSO, etc.). Serve trusts the identity headers set by the layer in front;
|
|
60
|
-
* it does not validate tokens or enforce bearer keys itself.
|
|
61
|
-
*
|
|
62
|
-
* SECURITY CONTRACT: serve trusts the identity and data-token headers below unconditionally.
|
|
63
|
-
* It MUST sit behind a proxy that (a) authenticates the caller and sets the identity header,
|
|
64
|
-
* and (b) STRIPS any client-supplied copies of these headers on the way in.
|
|
65
|
-
*/
|
|
66
|
-
const os = __importStar(require("os"));
|
|
67
|
-
const path = __importStar(require("path"));
|
|
68
|
-
const crypto = __importStar(require("crypto"));
|
|
69
|
-
const paths_1 = require("../utils/paths");
|
|
70
|
-
/** Default cap on a single request body (1 MiB). Chat messages are small; large bodies are abuse or bugs. */
|
|
71
|
-
exports.DEFAULT_MAX_BODY_BYTES = 1024 * 1024;
|
|
72
|
-
/**
|
|
73
|
-
* Resolve where session state is persisted. Precedence:
|
|
74
|
-
* 1. explicit --state-dir
|
|
75
|
-
* 2. AGENTHIPPO_HOME (the documented container mount point)
|
|
76
|
-
* 3. tmpdir (dev/local only; lost on restart)
|
|
77
|
-
*
|
|
78
|
-
* Returns `{ dir, ephemeral }` so the caller can warn when ephemeral state is
|
|
79
|
-
* detected in a long-lived deployment.
|
|
80
|
-
*/
|
|
81
|
-
function resolveStateDir(stateDirOpt, env = process.env) {
|
|
82
|
-
const explicit = stateDirOpt?.trim();
|
|
83
|
-
if (explicit) {
|
|
84
|
-
return { dir: path.resolve(explicit), ephemeral: false };
|
|
85
|
-
}
|
|
86
|
-
const home = env.AGENTHIPPO_HOME?.trim() || env.AGENTIDE_HOME?.trim();
|
|
87
|
-
if (home) {
|
|
88
|
-
return { dir: path.join(path.resolve(home), 'serve-state'), ephemeral: false };
|
|
89
|
-
}
|
|
90
|
-
return { dir: path.join(os.tmpdir(), 'agenthippo-server'), ephemeral: true };
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Where serve's Layer 2 analytics (tool-call/warrant JSONL) should live. Precedence:
|
|
94
|
-
* 1. AGENT_HOME_DIR / AGENTHIPPO_HOME set → getAgentideHome()/analytics/sessions — the
|
|
95
|
-
* exact location sessionJsonlFleet.ts and query-analytics.sh already scan by default,
|
|
96
|
-
* so this data stays discoverable to Spotlight/DuckDB.
|
|
97
|
-
* 2. Neither set, but the resolved state dir is non-ephemeral (an explicit --state-dir
|
|
98
|
-
* was given) → <stateDir>/analytics/sessions. Not the canonical scan location, but
|
|
99
|
-
* still durable — never regress below whatever durability the caller already
|
|
100
|
-
* established just to be discoverable.
|
|
101
|
-
* 3. Neither set and state is ephemeral (no --state-dir, no home-dir env var at all) →
|
|
102
|
-
* falls through to getAgentideHome()'s own os.homedir() default, matching the
|
|
103
|
-
* already-correct IDE-local behavior — nothing durable was configured either way.
|
|
104
|
-
*/
|
|
105
|
-
function resolveAnalyticsSessionsDir(stateDir, stateDirEphemeral, env = process.env) {
|
|
106
|
-
const homeOverride = env.AGENT_HOME_DIR?.trim() || env.AGENTHIPPO_HOME?.trim();
|
|
107
|
-
if (!homeOverride && !stateDirEphemeral) {
|
|
108
|
-
return path.join(stateDir, 'analytics', 'sessions');
|
|
109
|
-
}
|
|
110
|
-
return path.join((0, paths_1.getAgentideHome)(), 'analytics', 'sessions');
|
|
111
|
-
}
|
|
112
|
-
/** Loopback default — safe everywhere a human runs `serve` locally. */
|
|
113
|
-
exports.DEFAULT_BIND_HOST = '127.0.0.1';
|
|
114
|
-
/** True when a bind address is reachable only from this machine. */
|
|
115
|
-
function isLoopbackHost(host) {
|
|
116
|
-
const h = host.trim().toLowerCase().replace(/^\[|\]$/g, '');
|
|
117
|
-
return h === 'localhost' || h === '::1' || /^127\./.test(h);
|
|
118
|
-
}
|
|
119
|
-
/** Env var for the listen address (used by generated deploy Dockerfiles). */
|
|
120
|
-
exports.SERVE_HOST_ENV = 'AGENTHIPPO_SERVE_HOST';
|
|
121
|
-
/** Bind address baked into container deploy artifacts (Docker / Cloud Run sidecars). */
|
|
122
|
-
exports.CONTAINER_SERVE_HOST = '0.0.0.0';
|
|
123
|
-
/**
|
|
124
|
-
* Resolve the listen address. Precedence: explicit `--host` → AGENTHIPPO_SERVE_HOST → 127.0.0.1.
|
|
125
|
-
*
|
|
126
|
-
* Defaults to loopback so a local `serve` is never reachable off-box by accident. Containers
|
|
127
|
-
* (where the SSO proxy reaches the agent over a Docker network) MUST opt into `0.0.0.0` —
|
|
128
|
-
* generated deploy artifacts set `AGENTHIPPO_SERVE_HOST=0.0.0.0` for exactly this reason.
|
|
129
|
-
*/
|
|
130
|
-
function resolveBindHost(hostOpt, env = process.env) {
|
|
131
|
-
return hostOpt?.trim() || env.AGENTHIPPO_SERVE_HOST?.trim() || exports.DEFAULT_BIND_HOST;
|
|
132
|
-
}
|
|
133
|
-
/** Env var: number of trusted proxy hops in front of serve (default 1 — the single Caddy). */
|
|
134
|
-
exports.XFF_TRUSTED_HOPS_ENV = 'AGENTHIPPO_XFF_TRUSTED_HOPS';
|
|
135
|
-
/**
|
|
136
|
-
* Best-effort client IP for rate-limiting keys.
|
|
137
|
-
*
|
|
138
|
-
* Each trusted proxy appends the IP it observed to `X-Forwarded-For`, so with N trusted hops
|
|
139
|
-
* the real client is the Nth entry from the right (a client-spoofed left-most entry is just
|
|
140
|
-
* prepended and never reached). Default is 1 (the documented single Caddy). Behind
|
|
141
|
-
* Cloudflare Tunnel → Caddy there are two hops — Caddy appends cloudflared's container IP,
|
|
142
|
-
* which is identical for every client, so leaving hops at 1 there collapses all users into one
|
|
143
|
-
* rate-limit bucket. Set AGENTHIPPO_XFF_TRUSTED_HOPS=2 for the tunnel profile.
|
|
144
|
-
* Falls back to the socket address for direct/local callers. This is a coarse abuse key, not
|
|
145
|
-
* an identity — never use it for authorization.
|
|
146
|
-
*/
|
|
147
|
-
function clientIp(req, env = process.env) {
|
|
148
|
-
const xff = req.headers['x-forwarded-for'];
|
|
149
|
-
const raw = Array.isArray(xff) ? xff[0] : xff;
|
|
150
|
-
if (raw) {
|
|
151
|
-
const parts = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
|
152
|
-
if (parts.length > 0) {
|
|
153
|
-
const hopsRaw = Number(env[exports.XFF_TRUSTED_HOPS_ENV]);
|
|
154
|
-
const hops = Number.isInteger(hopsRaw) && hopsRaw >= 1 ? hopsRaw : 1;
|
|
155
|
-
return parts[Math.max(0, parts.length - hops)];
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return req.socket?.remoteAddress || 'unknown';
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Fixed-window request rate limiter (per key, in-memory, per-process). Complements the
|
|
162
|
-
* per-session TurnLimiter: keying on a stable identity (user id, or client IP) closes the
|
|
163
|
-
* "rotate session_id to bypass" gap. `maxPerWindow <= 0` disables it.
|
|
164
|
-
*/
|
|
165
|
-
class RateLimiter {
|
|
166
|
-
maxPerWindow;
|
|
167
|
-
windowMs;
|
|
168
|
-
hits = new Map();
|
|
169
|
-
/** Cap the key map so a flood of distinct keys can't grow memory unbounded. */
|
|
170
|
-
static MAX_KEYS = 100_000;
|
|
171
|
-
constructor(maxPerWindow, windowMs = 60_000) {
|
|
172
|
-
this.maxPerWindow = maxPerWindow;
|
|
173
|
-
this.windowMs = windowMs;
|
|
174
|
-
}
|
|
175
|
-
/** Returns true if the request is allowed (and records it); false when the window cap is hit. */
|
|
176
|
-
tryConsume(key, now = Date.now()) {
|
|
177
|
-
if (!Number.isFinite(this.maxPerWindow) || this.maxPerWindow <= 0) {
|
|
178
|
-
return true; // disabled
|
|
179
|
-
}
|
|
180
|
-
const entry = this.hits.get(key);
|
|
181
|
-
if (!entry || entry.resetAt <= now) {
|
|
182
|
-
if (this.hits.size >= RateLimiter.MAX_KEYS) {
|
|
183
|
-
this.prune(now);
|
|
184
|
-
}
|
|
185
|
-
this.hits.set(key, { count: 1, resetAt: now + this.windowMs });
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
if (entry.count >= this.maxPerWindow) {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
entry.count += 1;
|
|
192
|
-
return true;
|
|
193
|
-
}
|
|
194
|
-
/** Seconds until the key's window resets — for a Retry-After header. */
|
|
195
|
-
retryAfterSeconds(key, now = Date.now()) {
|
|
196
|
-
const entry = this.hits.get(key);
|
|
197
|
-
if (!entry) {
|
|
198
|
-
return Math.ceil(this.windowMs / 1000);
|
|
199
|
-
}
|
|
200
|
-
return Math.max(1, Math.ceil((entry.resetAt - now) / 1000));
|
|
201
|
-
}
|
|
202
|
-
prune(now) {
|
|
203
|
-
for (const [key, entry] of this.hits) {
|
|
204
|
-
if (entry.resetAt <= now) {
|
|
205
|
-
this.hits.delete(key);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
if (this.hits.size >= RateLimiter.MAX_KEYS) {
|
|
209
|
-
this.hits.clear();
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
exports.RateLimiter = RateLimiter;
|
|
214
|
-
/**
|
|
215
|
-
* Identity headers trusted when NOTHING is pinned.
|
|
216
|
-
*
|
|
217
|
-
* Every entry here is a header that exactly one platform sets AND owns the request path for, so
|
|
218
|
-
* a client-supplied copy cannot reach serve without that platform having been bypassed entirely.
|
|
219
|
-
*
|
|
220
|
-
* `x-agent-user` is deliberately NOT in this list, and this is a breaking change for anything
|
|
221
|
-
* that relied on it being trusted by default. It is AgentHippo's own canonical header — the name
|
|
222
|
-
* an arbitrary client is most likely to guess — it belongs to no platform that strips it, and it
|
|
223
|
-
* used to sit FIRST, so it beat every platform header that follows. The consequence on any
|
|
224
|
-
* deployment that had not pinned `AGENTHIPPO_IDENTITY_HEADER`: any HTTP client could send
|
|
225
|
-
* `x-agent-user: victim@example.com` and be namespaced into that user's session state, attach to
|
|
226
|
-
* their conversation, and be issued a data-plane turn nonce scoped to them. Cloud Run IAP makes
|
|
227
|
-
* this concrete — it strips `X-Goog-*` and forwards a client-supplied `x-agent-user` untouched.
|
|
228
|
-
*
|
|
229
|
-
* It remains perfectly valid as a PINNED header (`AGENTHIPPO_IDENTITY_HEADER=x-agent-user`),
|
|
230
|
-
* which is what a deployment whose proxy really does set and strip it should use — including the
|
|
231
|
-
* Caddy `forward_auth` flow, where `auth-broker/server.ts` sets `X-Agent-User` on `/api/ide/me`
|
|
232
|
-
* so Caddy can copy a VALIDATED identity upstream. That direction is the correct and only source
|
|
233
|
-
* of the header, and it is unaffected: pinning is exactly the declaration that it is trustworthy.
|
|
234
|
-
*/
|
|
235
|
-
const HEADER_ALIASES = [
|
|
236
|
-
'x-forwarded-email', // Databricks Apps
|
|
237
|
-
'x-forwarded-preferred-username', // Databricks Apps
|
|
238
|
-
'x-goog-authenticated-user-email', // Cloud Run IAP (prefixed value, stripped below)
|
|
239
|
-
'cf-access-authenticated-user-email', // Cloudflare Access
|
|
240
|
-
];
|
|
241
|
-
/**
|
|
242
|
-
* Headers that are only ever trusted when explicitly pinned.
|
|
243
|
-
*
|
|
244
|
-
* Kept as a named list rather than deleted, because "why is my identity header ignored?" needs an
|
|
245
|
-
* answer, and `identityHeaderAdvice` gives one that names the env var to set.
|
|
246
|
-
*/
|
|
247
|
-
exports.PIN_ONLY_IDENTITY_HEADERS = ['x-agent-user'];
|
|
248
|
-
/** Env var: pin the single identity header the deploy layer actually sets (and strips). */
|
|
249
|
-
exports.IDENTITY_HEADER_ENV = 'AGENTHIPPO_IDENTITY_HEADER';
|
|
250
|
-
/**
|
|
251
|
-
* Boot-time advice about identity trust. Returns the lines serve must print, loudest first.
|
|
252
|
-
*
|
|
253
|
-
* Not a refusal. Refusing to boot without a pin would stop deployments that are configured
|
|
254
|
-
* correctly today (Databricks Apps, Cloudflare Access) and whose platform header is genuinely
|
|
255
|
-
* unforgeable — a fail-closed default that mostly punishes the compliant is not a security win.
|
|
256
|
-
* What was actually dangerous was `x-agent-user` being trusted by default, and that is now gone.
|
|
257
|
-
*/
|
|
258
|
-
function identityHeaderAdvice(env = process.env, bindHost) {
|
|
259
|
-
const pinned = env[exports.IDENTITY_HEADER_ENV]?.trim();
|
|
260
|
-
if (pinned) {
|
|
261
|
-
return [];
|
|
262
|
-
}
|
|
263
|
-
// Severity follows reachability. On loopback nothing off-box can reach the port, so the same
|
|
264
|
-
// paragraph every local run is warning fatigue — and fatigue is why the message gets ignored
|
|
265
|
-
// on the deploy where it decides whether strangers can name themselves as another user.
|
|
266
|
-
const host = bindHost?.trim();
|
|
267
|
-
if (host && isLoopbackHost(host)) {
|
|
268
|
-
return [
|
|
269
|
-
`${exports.IDENTITY_HEADER_ENV} is not set. Fine for this loopback bind; pin it before exposing ` +
|
|
270
|
-
`serve on a network interface.`,
|
|
271
|
-
];
|
|
272
|
-
}
|
|
273
|
-
return [
|
|
274
|
-
...(host
|
|
275
|
-
? [`serve is bound to ${host} — reachable beyond this machine — with no ${exports.IDENTITY_HEADER_ENV} pinned. ` +
|
|
276
|
-
`Anyone who can reach this port is trusted to state who they are.`]
|
|
277
|
-
: []),
|
|
278
|
-
`${exports.IDENTITY_HEADER_ENV} is not set, so identity falls back to the platform header aliases ` +
|
|
279
|
-
`(${HEADER_ALIASES.join(', ')}). That is only safe when your proxy sets AND STRIPS every one of them. ` +
|
|
280
|
-
`Pin the single header your deploy layer really controls, e.g. ${exports.IDENTITY_HEADER_ENV}=x-goog-authenticated-user-email.`,
|
|
281
|
-
`NOTE: ${exports.PIN_ONLY_IDENTITY_HEADERS.join(', ')} is NO LONGER trusted by default — it is not stripped by any ` +
|
|
282
|
-
`platform, so an arbitrary client could send it and be namespaced as another user. If your proxy does set it ` +
|
|
283
|
-
`(the Caddy forward_auth / auth-broker flow does), pin it: ${exports.IDENTITY_HEADER_ENV}=x-agent-user.`,
|
|
284
|
-
];
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Resolve the end-user identity for a request.
|
|
288
|
-
*
|
|
289
|
-
* Proxy headers win over the request body. When AGENTHIPPO_IDENTITY_HEADER pins
|
|
290
|
-
* trust to one header, that pin is a hard boundary: if the pinned header is
|
|
291
|
-
* absent, identity resolves to undefined (never the request body) — a deployment
|
|
292
|
-
* that pins a header has declared it has a real proxy-verified identity, so an
|
|
293
|
-
* unauthenticated caller must not be able to name themselves via the client-
|
|
294
|
-
* controlled body. Body fallback is dev/internal convenience for the *unpinned*
|
|
295
|
-
* case only (e.g. direct curl against a local serve with no identity proxy) —
|
|
296
|
-
* and it must be OPTED INTO via AGENTHIPPO_ALLOW_BODY_IDENTITY=1 (serve-v4 §10
|
|
297
|
-
* hole 3). Before the gate it was safe "by convention": any deployment that
|
|
298
|
-
* forgot to pin a header silently let every caller name an arbitrary victim.
|
|
299
|
-
*
|
|
300
|
-
* The alias-list default (used when unpinned) is only safe when the proxy strips
|
|
301
|
-
* or overwrites ALL of the aliases; platforms that strip only their own header
|
|
302
|
-
* (Cloud Run IAP strips `X-Goog-*` but forwards a client-supplied `x-agent-user`
|
|
303
|
-
* untouched, which the alias list checks first) MUST pin theirs — deploy
|
|
304
|
-
* artifacts set it (e.g. cloudrun-deploy.sh pins `x-goog-authenticated-user-email`)
|
|
305
|
-
* so an authenticated caller cannot impersonate another user.
|
|
306
|
-
*
|
|
307
|
-
* Resolves identity for `analyticsUserId` attribution and the request-scoped
|
|
308
|
-
* credential context (per-user data scoping). Not folded into the session key —
|
|
309
|
-
* session continuity uses the client-supplied `session_id`.
|
|
310
|
-
*
|
|
311
|
-
* Per-turn *data credentials* (OBO token, e.g. X-Forwarded-Access-Token) are
|
|
312
|
-
* handled by resolveDataToken — not read here.
|
|
313
|
-
*/
|
|
314
|
-
function resolveUserId(headers, body, env = process.env) {
|
|
315
|
-
const pinned = env[exports.IDENTITY_HEADER_ENV]?.trim().toLowerCase();
|
|
316
|
-
const names = pinned ? [pinned] : HEADER_ALIASES;
|
|
317
|
-
for (const name of names) {
|
|
318
|
-
const v = headers[name];
|
|
319
|
-
const raw = (Array.isArray(v) ? v[0] : v)?.trim();
|
|
320
|
-
if (raw) {
|
|
321
|
-
// IAP sends "accounts.google.com:user@x.com"; keep the email half.
|
|
322
|
-
const colon = raw.lastIndexOf(':');
|
|
323
|
-
const value = colon >= 0 && raw.slice(colon + 1).includes('@') ? raw.slice(colon + 1) : raw;
|
|
324
|
-
return value;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
if (pinned) {
|
|
328
|
-
// Pinned but absent: fail closed. Falling back to the body here would let any
|
|
329
|
-
// caller that merely reaches this port (proxy misconfiguration, direct network
|
|
330
|
-
// access, gcloud run services proxy bypassing IAP) name an arbitrary victim.
|
|
331
|
-
return undefined;
|
|
332
|
-
}
|
|
333
|
-
// Unpinned body identity is an explicit opt-in, never a default (§10 hole 3).
|
|
334
|
-
if (env.AGENTHIPPO_ALLOW_BODY_IDENTITY?.trim() !== '1') {
|
|
335
|
-
return undefined;
|
|
336
|
-
}
|
|
337
|
-
const fromBody = body?.user_id?.trim();
|
|
338
|
-
return fromBody || undefined;
|
|
339
|
-
}
|
|
340
|
-
const DATA_TOKEN_HEADERS = [
|
|
341
|
-
'x-forwarded-access-token', // Databricks Apps OBO token
|
|
342
|
-
'x-agent-data-token', // AgentHippo generic per-turn data credential
|
|
343
|
-
];
|
|
344
|
-
/**
|
|
345
|
-
* Resolve the per-turn *data* credential (the OBO token), distinct from the
|
|
346
|
-
* identity in resolveUserId. Fed into the request-scoped credential context so
|
|
347
|
-
* a data tool can act as the asking user. serve-v3 §11.1 (Design B).
|
|
348
|
-
*
|
|
349
|
-
* Like the identity headers, this is trusted unconditionally and is only safe
|
|
350
|
-
* behind a proxy that strips client-supplied copies (see the module SECURITY
|
|
351
|
-
* CONTRACT above).
|
|
352
|
-
*/
|
|
353
|
-
function resolveDataToken(headers) {
|
|
354
|
-
for (const name of DATA_TOKEN_HEADERS) {
|
|
355
|
-
const v = headers[name];
|
|
356
|
-
const raw = (Array.isArray(v) ? v[0] : v)?.trim();
|
|
357
|
-
if (raw) {
|
|
358
|
-
return raw;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
return undefined;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Map a gateway channel sender (PeerInfo) to a stable `user_id` (serve-v3 §11 / #4).
|
|
365
|
-
* Prefers the stable channel id, namespaced by channel, so the Slack/Telegram
|
|
366
|
-
* sender becomes the user_id that drives per-user attribution and data scoping —
|
|
367
|
-
* extending the per-user-permission wedge to channel surfaces.
|
|
368
|
-
*/
|
|
369
|
-
function peerToUserId(peer) {
|
|
370
|
-
if (!peer) {
|
|
371
|
-
return undefined;
|
|
372
|
-
}
|
|
373
|
-
const id = peer.senderId?.trim() || peer.senderUsername?.trim() || peer.senderName?.trim();
|
|
374
|
-
if (!id) {
|
|
375
|
-
return undefined;
|
|
376
|
-
}
|
|
377
|
-
const channel = peer.channel?.trim();
|
|
378
|
-
return channel ? `${channel}:${id}` : id;
|
|
379
|
-
}
|
|
380
|
-
/** Stable reason code when a session_id is presented without a verified user on a pinned-identity deployment. */
|
|
381
|
-
exports.SESSION_WITHOUT_USER_REASON = 'session_without_verified_user';
|
|
382
|
-
/** Filesystem/S3-safe per-user namespace segment (user ids are emails/subjects — never raw path segments). */
|
|
383
|
-
function userNamespaceHash(userId) {
|
|
384
|
-
return crypto.createHash('sha256').update(userId).digest('hex').slice(0, 16);
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Namespace the session key by the verified user (secure-obo-design §3.4 / §8 Phase 0).
|
|
388
|
-
*
|
|
389
|
-
* `session_id` is client-supplied; un-namespaced, any authenticated user who guesses another
|
|
390
|
-
* user's session_id attaches to that session's conversation state (which holds the other
|
|
391
|
-
* user's row-filtered query results). Prefixing the key with a hash of the verified user makes
|
|
392
|
-
* cross-user attachment structurally impossible without changing client behavior.
|
|
393
|
-
*
|
|
394
|
-
* Fail-closed rule: when the deployment pins an identity header (it declared a real
|
|
395
|
-
* proxy-verified identity exists) and a request carries a session_id but no verified user,
|
|
396
|
-
* reject — never let an unauthenticated caller name a session. Unpinned deployments
|
|
397
|
-
* (local dev, no identity boundary at all) keep today's raw-key behavior.
|
|
398
|
-
*/
|
|
399
|
-
function resolveServeSessionKey(sessionId, userId, env = process.env) {
|
|
400
|
-
const sid = sessionId?.trim();
|
|
401
|
-
const uid = userId?.trim();
|
|
402
|
-
if (uid) {
|
|
403
|
-
return { sessionKey: `u${userNamespaceHash(uid)}--${sid || 'default'}` };
|
|
404
|
-
}
|
|
405
|
-
if (sid && env[exports.IDENTITY_HEADER_ENV]?.trim()) {
|
|
406
|
-
return { sessionKey: '', rejected: exports.SESSION_WITHOUT_USER_REASON };
|
|
407
|
-
}
|
|
408
|
-
return { sessionKey: sid || 'anon-unknown' };
|
|
409
|
-
}
|
|
410
|
-
/** Build CORS headers. Serve is always behind a proxy; CORS is wide-open here. */
|
|
411
|
-
function corsHeaders() {
|
|
412
|
-
return {
|
|
413
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
414
|
-
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Agent-User',
|
|
415
|
-
'Access-Control-Allow-Origin': '*',
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Per-session turn admission control. Caps the number of turns a single
|
|
420
|
-
* conversation may run (abuse / runaway-loop guard for exposed deployments).
|
|
421
|
-
* In-memory and per-process — sufficient for single-container tiers; a shared
|
|
422
|
-
* store is a later concern.
|
|
423
|
-
*/
|
|
424
|
-
class TurnLimiter {
|
|
425
|
-
maxPerSession;
|
|
426
|
-
counts = new Map();
|
|
427
|
-
constructor(maxPerSession) {
|
|
428
|
-
this.maxPerSession = maxPerSession;
|
|
429
|
-
}
|
|
430
|
-
/** Returns true if the turn is allowed (and records it); false when the cap is exceeded. */
|
|
431
|
-
tryConsume(sessionKey) {
|
|
432
|
-
if (!Number.isFinite(this.maxPerSession) || this.maxPerSession <= 0) {
|
|
433
|
-
return true; // disabled
|
|
434
|
-
}
|
|
435
|
-
const current = this.counts.get(sessionKey) ?? 0;
|
|
436
|
-
if (current >= this.maxPerSession) {
|
|
437
|
-
return false;
|
|
438
|
-
}
|
|
439
|
-
this.counts.set(sessionKey, current + 1);
|
|
440
|
-
return true;
|
|
441
|
-
}
|
|
442
|
-
reset(sessionKey) {
|
|
443
|
-
this.counts.delete(sessionKey);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
exports.TurnLimiter = TurnLimiter;
|
|
447
|
-
/** Env: max concurrent engine turns per process (default 10). `0` disables the gate. */
|
|
448
|
-
exports.MAX_CONCURRENT_TURNS_ENV = 'AGENTHIPPO_MAX_CONCURRENT_TURNS';
|
|
449
|
-
/** Env: bounded FIFO waiter depth when at inflight cap (default 20). */
|
|
450
|
-
exports.TURN_QUEUE_ENV = 'AGENTHIPPO_TURN_QUEUE';
|
|
451
|
-
/** Fixed Retry-After seconds when the turn gate rejects (matches default queue timeout). */
|
|
452
|
-
exports.TURN_GATE_RETRY_AFTER_SECONDS = 15;
|
|
453
|
-
/** User-visible capacity message for gateway channels (Slack/Telegram can't receive HTTP 429). */
|
|
454
|
-
exports.TURN_GATE_BUSY_MESSAGE = 'At capacity — please retry in a moment';
|
|
455
|
-
/** User-visible message for gateway channels when the per-identity RateLimiter rejects. */
|
|
456
|
-
exports.RATE_LIMIT_BUSY_MESSAGE = 'Rate limit exceeded — please retry in a moment';
|
|
457
|
-
/** User-visible message for gateway channels when the per-session TurnLimiter rejects. */
|
|
458
|
-
exports.TURN_LIMIT_BUSY_MESSAGE = 'Per-session turn limit reached';
|
|
459
|
-
/**
|
|
460
|
-
* Process-wide concurrency gate for engine turns (semaphore + bounded FIFO).
|
|
461
|
-
*
|
|
462
|
-
* Caps simultaneous engine subprocesses so a burst cannot OOM the container.
|
|
463
|
-
* `maxInflight <= 0` disables. Waiters time out after `queueTimeoutMs` (burst
|
|
464
|
-
* absorber, not a job queue). Rejected callers get `null` — HTTP maps that to
|
|
465
|
-
* 429 + Retry-After; the gateway path emits a short channel message instead.
|
|
466
|
-
*/
|
|
467
|
-
class TurnGate {
|
|
468
|
-
maxInflight;
|
|
469
|
-
maxQueue;
|
|
470
|
-
queueTimeoutMs;
|
|
471
|
-
inflightCount = 0;
|
|
472
|
-
waiters = [];
|
|
473
|
-
constructor(maxInflight, maxQueue, queueTimeoutMs = exports.TURN_GATE_RETRY_AFTER_SECONDS * 1000) {
|
|
474
|
-
this.maxInflight = maxInflight;
|
|
475
|
-
this.maxQueue = maxQueue;
|
|
476
|
-
this.queueTimeoutMs = queueTimeoutMs;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Acquire a turn slot. Resolves with a `release()` callback, or `null` when
|
|
480
|
-
* the queue is full or the wait timed out. Always call `release()` in a
|
|
481
|
-
* `finally` when non-null.
|
|
482
|
-
*/
|
|
483
|
-
async acquire() {
|
|
484
|
-
if (!Number.isFinite(this.maxInflight) || this.maxInflight <= 0) {
|
|
485
|
-
return () => { };
|
|
486
|
-
}
|
|
487
|
-
if (this.inflightCount < this.maxInflight) {
|
|
488
|
-
this.inflightCount += 1;
|
|
489
|
-
return () => this.releaseSlot();
|
|
490
|
-
}
|
|
491
|
-
if (this.waiters.length >= this.maxQueue) {
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
return new Promise((resolve) => {
|
|
495
|
-
let settled = false;
|
|
496
|
-
const settle = (release) => {
|
|
497
|
-
if (settled) {
|
|
498
|
-
// Timed out after a slot was already offered — give the slot back.
|
|
499
|
-
if (release) {
|
|
500
|
-
release();
|
|
501
|
-
}
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
settled = true;
|
|
505
|
-
clearTimeout(timer);
|
|
506
|
-
resolve(release);
|
|
507
|
-
};
|
|
508
|
-
const entry = {
|
|
509
|
-
resolve: settle,
|
|
510
|
-
timer: null,
|
|
511
|
-
};
|
|
512
|
-
const timer = setTimeout(() => {
|
|
513
|
-
const idx = this.waiters.indexOf(entry);
|
|
514
|
-
if (idx >= 0) {
|
|
515
|
-
this.waiters.splice(idx, 1);
|
|
516
|
-
}
|
|
517
|
-
settle(null);
|
|
518
|
-
}, this.queueTimeoutMs);
|
|
519
|
-
entry.timer = timer;
|
|
520
|
-
this.waiters.push(entry);
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
releaseSlot() {
|
|
524
|
-
const next = this.waiters.shift();
|
|
525
|
-
if (next) {
|
|
526
|
-
// Transfer the slot to the head waiter — do not decrement inflight.
|
|
527
|
-
next.resolve(() => this.releaseSlot());
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
this.inflightCount = Math.max(0, this.inflightCount - 1);
|
|
531
|
-
}
|
|
532
|
-
get inflight() {
|
|
533
|
-
return this.inflightCount;
|
|
534
|
-
}
|
|
535
|
-
get queued() {
|
|
536
|
-
return this.waiters.length;
|
|
537
|
-
}
|
|
538
|
-
get max() {
|
|
539
|
-
return this.maxInflight > 0 ? this.maxInflight : 0;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
exports.TurnGate = TurnGate;
|
|
543
|
-
/** Build a TurnGate from env (serve-v4 P0.1). Defaults: 10 inflight, 20 queued. */
|
|
544
|
-
function createTurnGateFromEnv(env = process.env) {
|
|
545
|
-
const inflightRaw = Number(env[exports.MAX_CONCURRENT_TURNS_ENV] ?? 10);
|
|
546
|
-
const queueRaw = Number(env[exports.TURN_QUEUE_ENV] ?? 20);
|
|
547
|
-
const maxInflight = Number.isFinite(inflightRaw) ? inflightRaw : 10;
|
|
548
|
-
const maxQueue = Number.isFinite(queueRaw) && queueRaw >= 0 ? queueRaw : 20;
|
|
549
|
-
return new TurnGate(maxInflight, maxQueue);
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Rate-limited rejection logger — at most one warn per `intervalMs` so a flood
|
|
553
|
-
* of 429s does not spam the console.
|
|
554
|
-
*/
|
|
555
|
-
function createRejectionWarner(intervalMs = 5_000) {
|
|
556
|
-
let lastAt = 0;
|
|
557
|
-
return (msg) => {
|
|
558
|
-
const now = Date.now();
|
|
559
|
-
if (now - lastAt < intervalMs) {
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
lastAt = now;
|
|
563
|
-
console.warn(msg);
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Read a request body with a hard size cap. Past the cap it stops accumulating
|
|
568
|
-
* and rejects with a `tooLarge`-tagged error so the caller can respond 413.
|
|
569
|
-
*
|
|
570
|
-
* Deliberately does NOT destroy the socket here: destroying mid-upload resets
|
|
571
|
-
* the connection before the 413 can flush (the client only ever sees the
|
|
572
|
-
* interim 100-continue). We detach our listeners and let the handler send 413
|
|
573
|
-
* with `Connection: close`. Replaces serve's unbounded body accumulation.
|
|
574
|
-
*/
|
|
575
|
-
function readBodyWithCap(req, maxBytes = exports.DEFAULT_MAX_BODY_BYTES) {
|
|
576
|
-
return new Promise((resolve, reject) => {
|
|
577
|
-
let size = 0;
|
|
578
|
-
const chunks = [];
|
|
579
|
-
const onData = (chunk) => {
|
|
580
|
-
size += chunk.length;
|
|
581
|
-
if (size > maxBytes) {
|
|
582
|
-
cleanup();
|
|
583
|
-
const err = new Error(`Request body exceeds ${maxBytes} bytes`);
|
|
584
|
-
err.tooLarge = true;
|
|
585
|
-
reject(err);
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
chunks.push(chunk);
|
|
589
|
-
};
|
|
590
|
-
const onEnd = () => {
|
|
591
|
-
cleanup();
|
|
592
|
-
resolve(Buffer.concat(chunks).toString('utf8'));
|
|
593
|
-
};
|
|
594
|
-
const onError = (err) => {
|
|
595
|
-
cleanup();
|
|
596
|
-
reject(err);
|
|
597
|
-
};
|
|
598
|
-
const cleanup = () => {
|
|
599
|
-
req.off('data', onData);
|
|
600
|
-
req.off('end', onEnd);
|
|
601
|
-
req.off('error', onError);
|
|
602
|
-
};
|
|
603
|
-
req.on('data', onData);
|
|
604
|
-
req.on('end', onEnd);
|
|
605
|
-
req.on('error', onError);
|
|
606
|
-
});
|
|
607
|
-
}
|