patchwork-os 0.2.0-beta.9.canary.93 → 1.1.0-beta.1
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/README.bridge.md +15 -16
- package/README.md +46 -458
- package/dist/activationMetrics.js +2 -3
- package/dist/activationMetrics.js.map +1 -1
- package/dist/activityLog.d.ts +1 -0
- package/dist/activityLog.js +8 -3
- package/dist/activityLog.js.map +1 -1
- package/dist/adapters/gemini.js +2 -2
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.js +6 -1
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.js +4 -0
- package/dist/adapters/openai.js.map +1 -1
- package/dist/approvalHttp.d.ts +9 -0
- package/dist/approvalHttp.js +210 -171
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalKpi.d.ts +102 -0
- package/dist/approvalKpi.js +282 -0
- package/dist/approvalKpi.js.map +1 -0
- package/dist/approvalQueue.d.ts +1 -1
- package/dist/approvalQueue.js.map +1 -1
- package/dist/automation.d.ts +45 -4
- package/dist/automation.js +123 -15
- package/dist/automation.js.map +1 -1
- package/dist/bridge.d.ts +10 -0
- package/dist/bridge.js +225 -46
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeLockDiscovery.d.ts +16 -1
- package/dist/bridgeLockDiscovery.js +38 -4
- package/dist/bridgeLockDiscovery.js.map +1 -1
- package/dist/bridgeToolsRules.js +3 -18
- package/dist/bridgeToolsRules.js.map +1 -1
- package/dist/claudeAuthHttp.d.ts +25 -0
- package/dist/claudeAuthHttp.js +219 -0
- package/dist/claudeAuthHttp.js.map +1 -0
- package/dist/claudeDriver.js +4 -1
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +15 -0
- package/dist/claudeOrchestrator.js +44 -0
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/connect.d.ts +47 -0
- package/dist/commands/connect.js +419 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/install.js +3 -10
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/launchd.d.ts +7 -0
- package/dist/commands/launchd.js +20 -2
- package/dist/commands/launchd.js.map +1 -1
- package/dist/commands/patchworkInit.d.ts +7 -0
- package/dist/commands/patchworkInit.js +26 -0
- package/dist/commands/patchworkInit.js.map +1 -1
- package/dist/commands/recipe.d.ts +59 -4
- package/dist/commands/recipe.js +206 -5
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +9 -0
- package/dist/commands/recipeInstall.js +56 -3
- package/dist/commands/recipeInstall.js.map +1 -1
- package/dist/commands/task.d.ts +25 -0
- package/dist/commands/task.js +61 -41
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tokenEfficiency.d.ts +4 -0
- package/dist/commands/tokenEfficiency.js +23 -26
- package/dist/commands/tokenEfficiency.js.map +1 -1
- package/dist/commands/tracesExport.d.ts +15 -1
- package/dist/commands/tracesExport.js +39 -5
- package/dist/commands/tracesExport.js.map +1 -1
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +613 -62
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/asana.js +9 -3
- package/dist/connectors/asana.js.map +1 -1
- package/dist/connectors/baseConnector.d.ts +16 -0
- package/dist/connectors/baseConnector.js +2 -0
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/caldiy.js +34 -0
- package/dist/connectors/caldiy.js.map +1 -1
- package/dist/connectors/confluence.js +9 -2
- package/dist/connectors/confluence.js.map +1 -1
- package/dist/connectors/connectorActivity.d.ts +24 -0
- package/dist/connectors/connectorActivity.js +32 -0
- package/dist/connectors/connectorActivity.js.map +1 -0
- package/dist/connectors/connectorRedirectUri.js +22 -2
- package/dist/connectors/connectorRedirectUri.js.map +1 -1
- package/dist/connectors/connectorRegistry.d.ts +0 -3
- package/dist/connectors/connectorRegistry.js +8 -8
- package/dist/connectors/connectorRegistry.js.map +1 -1
- package/dist/connectors/datadog.js +8 -1
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/discord.js +4 -3
- package/dist/connectors/discord.js.map +1 -1
- package/dist/connectors/elasticsearch.js +22 -0
- package/dist/connectors/elasticsearch.js.map +1 -1
- package/dist/connectors/github.d.ts +38 -0
- package/dist/connectors/github.js +91 -5
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gitlab.js +19 -16
- package/dist/connectors/gitlab.js.map +1 -1
- package/dist/connectors/gmail.d.ts +5 -0
- package/dist/connectors/gmail.js +53 -11
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.js +5 -4
- package/dist/connectors/googleCalendar.js.map +1 -1
- package/dist/connectors/googleDocs.js +7 -6
- package/dist/connectors/googleDocs.js.map +1 -1
- package/dist/connectors/googleDrive.js +15 -8
- package/dist/connectors/googleDrive.js.map +1 -1
- package/dist/connectors/grafana.js +39 -3
- package/dist/connectors/grafana.js.map +1 -1
- package/dist/connectors/jira.d.ts +1 -1
- package/dist/connectors/jira.js +19 -4
- package/dist/connectors/jira.js.map +1 -1
- package/dist/connectors/linear.js +2 -2
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/mcpClient.d.ts +29 -1
- package/dist/connectors/mcpClient.js +114 -44
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/connectors/mcpOAuth.d.ts +1 -0
- package/dist/connectors/mcpOAuth.js +49 -4
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/monday.js +5 -4
- package/dist/connectors/monday.js.map +1 -1
- package/dist/connectors/mongodb.js +32 -5
- package/dist/connectors/mongodb.js.map +1 -1
- package/dist/connectors/notion.d.ts +1 -1
- package/dist/connectors/notion.js +22 -6
- package/dist/connectors/notion.js.map +1 -1
- package/dist/connectors/oauthError.d.ts +17 -0
- package/dist/connectors/oauthError.js +50 -0
- package/dist/connectors/oauthError.js.map +1 -0
- package/dist/connectors/postgres.d.ts +7 -0
- package/dist/connectors/postgres.js +32 -2
- package/dist/connectors/postgres.js.map +1 -1
- package/dist/connectors/posthog.js +26 -0
- package/dist/connectors/posthog.js.map +1 -1
- package/dist/connectors/redis.d.ts +1 -0
- package/dist/connectors/redis.js +47 -20
- package/dist/connectors/redis.js.map +1 -1
- package/dist/connectors/salesforce.js +66 -5
- package/dist/connectors/salesforce.js.map +1 -1
- package/dist/connectors/sentry.js +2 -2
- package/dist/connectors/sentry.js.map +1 -1
- package/dist/connectors/slack.js +37 -14
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/snowflake.js +24 -0
- package/dist/connectors/snowflake.js.map +1 -1
- package/dist/connectors/stripe.js +9 -2
- package/dist/connectors/stripe.js.map +1 -1
- package/dist/connectors/supabase.js +34 -0
- package/dist/connectors/supabase.js.map +1 -1
- package/dist/connectors/tokenStorage.d.ts +20 -0
- package/dist/connectors/tokenStorage.js +196 -64
- package/dist/connectors/tokenStorage.js.map +1 -1
- package/dist/connectors/woocommerce.js +34 -0
- package/dist/connectors/woocommerce.js.map +1 -1
- package/dist/copilot/parseIntent.d.ts +58 -0
- package/dist/copilot/parseIntent.js +149 -0
- package/dist/copilot/parseIntent.js.map +1 -0
- package/dist/decisionReplay.d.ts +8 -6
- package/dist/decisionReplay.js +35 -11
- package/dist/decisionReplay.js.map +1 -1
- package/dist/decisionTraceLog.d.ts +9 -0
- package/dist/decisionTraceLog.js +6 -0
- package/dist/decisionTraceLog.js.map +1 -1
- package/dist/drivers/claude/api.js +49 -7
- package/dist/drivers/claude/api.js.map +1 -1
- package/dist/drivers/claude/envSanitizer.d.ts +9 -1
- package/dist/drivers/claude/envSanitizer.js +41 -3
- package/dist/drivers/claude/envSanitizer.js.map +1 -1
- package/dist/drivers/claude/streamParser.d.ts +13 -0
- package/dist/drivers/claude/streamParser.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +131 -16
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/claude/subprocessSettings.d.ts +1 -1
- package/dist/drivers/claude/subprocessSettings.js +18 -4
- package/dist/drivers/claude/subprocessSettings.js.map +1 -1
- package/dist/drivers/gemini/index.d.ts +13 -0
- package/dist/drivers/gemini/index.js +211 -67
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +2 -17
- package/dist/drivers/local/index.js +5 -92
- package/dist/drivers/local/index.js.map +1 -1
- package/dist/drivers/openai/index.js +69 -9
- package/dist/drivers/openai/index.js.map +1 -1
- package/dist/drivers/outputCap.d.ts +27 -0
- package/dist/drivers/outputCap.js +50 -0
- package/dist/drivers/outputCap.js.map +1 -0
- package/dist/embeddings/cosine.d.ts +23 -0
- package/dist/embeddings/cosine.js +59 -0
- package/dist/embeddings/cosine.js.map +1 -0
- package/dist/embeddings/index.d.ts +19 -0
- package/dist/embeddings/index.js +35 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/localEmbeddings.d.ts +29 -0
- package/dist/embeddings/localEmbeddings.js +103 -0
- package/dist/embeddings/localEmbeddings.js.map +1 -0
- package/dist/embeddings/localEndpoints.d.ts +24 -0
- package/dist/embeddings/localEndpoints.js +37 -0
- package/dist/embeddings/localEndpoints.js.map +1 -0
- package/dist/embeddings/types.d.ts +32 -0
- package/dist/embeddings/types.js +12 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/featureFlags.d.ts +18 -0
- package/dist/featureFlags.js +32 -0
- package/dist/featureFlags.js.map +1 -1
- package/dist/fp/automationInterpreter.js +118 -39
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +10 -0
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/automationState.d.ts +6 -0
- package/dist/fp/automationState.js +38 -0
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/commandDescription.d.ts +6 -0
- package/dist/fp/commandDescription.js +18 -5
- package/dist/fp/commandDescription.js.map +1 -1
- package/dist/fp/interpreterContext.d.ts +16 -5
- package/dist/fp/interpreterContext.js +59 -3
- package/dist/fp/interpreterContext.js.map +1 -1
- package/dist/fp/policyParser.js +18 -8
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/haltPushDispatch.d.ts +4 -0
- package/dist/haltPushDispatch.js +7 -22
- package/dist/haltPushDispatch.js.map +1 -1
- package/dist/inboxRoutes.js +2 -2
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.js +672 -135
- package/dist/index.js.map +1 -1
- package/dist/installGuard.js +6 -0
- package/dist/installGuard.js.map +1 -1
- package/dist/localEndpointGuard.d.ts +25 -0
- package/dist/localEndpointGuard.js +101 -0
- package/dist/localEndpointGuard.js.map +1 -0
- package/dist/mcpRoutes.js +1 -1
- package/dist/mcpRoutes.js.map +1 -1
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.js +53 -9
- package/dist/oauth.js.map +1 -1
- package/dist/orchestrator/childBridgeClient.d.ts +7 -0
- package/dist/orchestrator/childBridgeClient.js +42 -1
- package/dist/orchestrator/childBridgeClient.js.map +1 -1
- package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
- package/dist/orchestrator/orchestratorBridge.js +75 -9
- package/dist/orchestrator/orchestratorBridge.js.map +1 -1
- package/dist/patchworkConfig.d.ts +4 -0
- package/dist/patchworkConfig.js +33 -4
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/probe.js +39 -5
- package/dist/probe.js.map +1 -1
- package/dist/recipeOrchestration.d.ts +59 -0
- package/dist/recipeOrchestration.js +314 -60
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +93 -0
- package/dist/recipeRoutes.js +664 -27
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/RecipeOrchestrator.d.ts +14 -0
- package/dist/recipes/RecipeOrchestrator.js +42 -2
- package/dist/recipes/RecipeOrchestrator.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +51 -2
- package/dist/recipes/agentExecutor.js +86 -13
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +111 -3
- package/dist/recipes/chainedRunner.js +440 -45
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/compiler.js +42 -29
- package/dist/recipes/compiler.js.map +1 -1
- package/dist/recipes/connectorPreflight.js +31 -0
- package/dist/recipes/connectorPreflight.js.map +1 -1
- package/dist/recipes/dependencyGraph.d.ts +16 -0
- package/dist/recipes/dependencyGraph.js +37 -2
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/eventTriggerPrograms.d.ts +36 -0
- package/dist/recipes/eventTriggerPrograms.js +158 -0
- package/dist/recipes/eventTriggerPrograms.js.map +1 -0
- package/dist/recipes/githubInstallSource.d.ts +9 -2
- package/dist/recipes/githubInstallSource.js +36 -6
- package/dist/recipes/githubInstallSource.js.map +1 -1
- package/dist/recipes/haltCategory.d.ts +10 -0
- package/dist/recipes/haltCategory.js +11 -1
- package/dist/recipes/haltCategory.js.map +1 -1
- package/dist/recipes/idempotencyKey.d.ts +30 -3
- package/dist/recipes/idempotencyKey.js +89 -5
- package/dist/recipes/idempotencyKey.js.map +1 -1
- package/dist/recipes/installer.js +12 -35
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/judgeVerdict.d.ts +11 -1
- package/dist/recipes/judgeVerdict.js +47 -7
- package/dist/recipes/judgeVerdict.js.map +1 -1
- package/dist/recipes/names.d.ts +5 -0
- package/dist/recipes/names.js +10 -5
- package/dist/recipes/names.js.map +1 -1
- package/dist/recipes/parser.js +74 -10
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/pricing/costRouter.d.ts +43 -0
- package/dist/recipes/pricing/costRouter.js +44 -0
- package/dist/recipes/pricing/costRouter.js.map +1 -0
- package/dist/recipes/pricing/priceTable.d.ts +76 -0
- package/dist/recipes/pricing/priceTable.js +144 -0
- package/dist/recipes/pricing/priceTable.js.map +1 -0
- package/dist/recipes/replayRun.js +5 -2
- package/dist/recipes/replayRun.js.map +1 -1
- package/dist/recipes/resolveRecipePath.js +15 -1
- package/dist/recipes/resolveRecipePath.js.map +1 -1
- package/dist/recipes/runBudget.d.ts +93 -32
- package/dist/recipes/runBudget.js +213 -49
- package/dist/recipes/runBudget.js.map +1 -1
- package/dist/recipes/runRegistry.d.ts +32 -0
- package/dist/recipes/runRegistry.js +54 -0
- package/dist/recipes/runRegistry.js.map +1 -0
- package/dist/recipes/scheduler.js +6 -2
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schema.d.ts +59 -6
- package/dist/recipes/schemaGenerator.d.ts +9 -0
- package/dist/recipes/schemaGenerator.js +446 -77
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/simulation/aggregateRunRisk.d.ts +46 -0
- package/dist/recipes/simulation/aggregateRunRisk.js +120 -0
- package/dist/recipes/simulation/aggregateRunRisk.js.map +1 -0
- package/dist/recipes/simulation/costProjector.d.ts +32 -0
- package/dist/recipes/simulation/costProjector.js +194 -0
- package/dist/recipes/simulation/costProjector.js.map +1 -0
- package/dist/recipes/simulation/sideEffects.d.ts +32 -0
- package/dist/recipes/simulation/sideEffects.js +62 -0
- package/dist/recipes/simulation/sideEffects.js.map +1 -0
- package/dist/recipes/simulation/simulate.d.ts +36 -0
- package/dist/recipes/simulation/simulate.js +264 -0
- package/dist/recipes/simulation/simulate.js.map +1 -0
- package/dist/recipes/simulation/simulateMockedRun.d.ts +52 -0
- package/dist/recipes/simulation/simulateMockedRun.js +84 -0
- package/dist/recipes/simulation/simulateMockedRun.js.map +1 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.d.ts +31 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js +50 -0
- package/dist/recipes/simulation/synthesizeMockedOutputs.js.map +1 -0
- package/dist/recipes/simulation/types.d.ts +198 -0
- package/dist/recipes/simulation/types.js +30 -0
- package/dist/recipes/simulation/types.js.map +1 -0
- package/dist/recipes/stepObservation.d.ts +12 -0
- package/dist/recipes/stepObservation.js +21 -1
- package/dist/recipes/stepObservation.js.map +1 -1
- package/dist/recipes/toolRegistry.js +61 -24
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/airtable.d.ts +15 -0
- package/dist/recipes/tools/airtable.js +240 -0
- package/dist/recipes/tools/airtable.js.map +1 -0
- package/dist/recipes/tools/caldiy.d.ts +13 -0
- package/dist/recipes/tools/caldiy.js +215 -0
- package/dist/recipes/tools/caldiy.js.map +1 -0
- package/dist/recipes/tools/circleci.d.ts +10 -0
- package/dist/recipes/tools/circleci.js +204 -0
- package/dist/recipes/tools/circleci.js.map +1 -0
- package/dist/recipes/tools/cloudflare.d.ts +13 -0
- package/dist/recipes/tools/cloudflare.js +211 -0
- package/dist/recipes/tools/cloudflare.js.map +1 -0
- package/dist/recipes/tools/confluence.js +11 -10
- package/dist/recipes/tools/confluence.js.map +1 -1
- package/dist/recipes/tools/datadog.js +13 -12
- package/dist/recipes/tools/datadog.js.map +1 -1
- package/dist/recipes/tools/docs.d.ts +18 -0
- package/dist/recipes/tools/docs.js +95 -0
- package/dist/recipes/tools/docs.js.map +1 -0
- package/dist/recipes/tools/elasticsearch.d.ts +11 -0
- package/dist/recipes/tools/elasticsearch.js +157 -0
- package/dist/recipes/tools/elasticsearch.js.map +1 -0
- package/dist/recipes/tools/fanOut.js +4 -4
- package/dist/recipes/tools/fanOut.js.map +1 -1
- package/dist/recipes/tools/figma.d.ts +12 -0
- package/dist/recipes/tools/figma.js +195 -0
- package/dist/recipes/tools/figma.js.map +1 -0
- package/dist/recipes/tools/file.js +43 -22
- package/dist/recipes/tools/file.js.map +1 -1
- package/dist/recipes/tools/github.js +162 -5
- package/dist/recipes/tools/github.js.map +1 -1
- package/dist/recipes/tools/gmail.js +45 -33
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/tools/grafana.d.ts +11 -0
- package/dist/recipes/tools/grafana.js +216 -0
- package/dist/recipes/tools/grafana.js.map +1 -0
- package/dist/recipes/tools/http.d.ts +1 -1
- package/dist/recipes/tools/http.js +10 -28
- package/dist/recipes/tools/http.js.map +1 -1
- package/dist/recipes/tools/hubspot.js +13 -12
- package/dist/recipes/tools/hubspot.js.map +1 -1
- package/dist/recipes/tools/index.d.ts +28 -0
- package/dist/recipes/tools/index.js +28 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/intercom.js +11 -10
- package/dist/recipes/tools/intercom.js.map +1 -1
- package/dist/recipes/tools/jira.js +13 -0
- package/dist/recipes/tools/jira.js.map +1 -1
- package/dist/recipes/tools/meetingNotes.js +2 -2
- package/dist/recipes/tools/monday.d.ts +22 -0
- package/dist/recipes/tools/monday.js +242 -0
- package/dist/recipes/tools/monday.js.map +1 -0
- package/dist/recipes/tools/mongodb.d.ts +19 -0
- package/dist/recipes/tools/mongodb.js +194 -0
- package/dist/recipes/tools/mongodb.js.map +1 -0
- package/dist/recipes/tools/notion.js +11 -10
- package/dist/recipes/tools/notion.js.map +1 -1
- package/dist/recipes/tools/obsidian.d.ts +15 -0
- package/dist/recipes/tools/obsidian.js +173 -0
- package/dist/recipes/tools/obsidian.js.map +1 -0
- package/dist/recipes/tools/outcomes.d.ts +15 -0
- package/dist/recipes/tools/outcomes.js +111 -0
- package/dist/recipes/tools/outcomes.js.map +1 -0
- package/dist/recipes/tools/paystack.d.ts +11 -0
- package/dist/recipes/tools/paystack.js +212 -0
- package/dist/recipes/tools/paystack.js.map +1 -0
- package/dist/recipes/tools/pipedrive.d.ts +16 -0
- package/dist/recipes/tools/pipedrive.js +234 -0
- package/dist/recipes/tools/pipedrive.js.map +1 -0
- package/dist/recipes/tools/postgres.d.ts +15 -0
- package/dist/recipes/tools/postgres.js +186 -0
- package/dist/recipes/tools/postgres.js.map +1 -0
- package/dist/recipes/tools/posthog.d.ts +16 -0
- package/dist/recipes/tools/posthog.js +219 -0
- package/dist/recipes/tools/posthog.js.map +1 -0
- package/dist/recipes/tools/redis.d.ts +9 -0
- package/dist/recipes/tools/redis.js +141 -0
- package/dist/recipes/tools/redis.js.map +1 -0
- package/dist/recipes/tools/resend.d.ts +8 -0
- package/dist/recipes/tools/resend.js +153 -0
- package/dist/recipes/tools/resend.js.map +1 -0
- package/dist/recipes/tools/salesforce.d.ts +16 -0
- package/dist/recipes/tools/salesforce.js +184 -0
- package/dist/recipes/tools/salesforce.js.map +1 -0
- package/dist/recipes/tools/sendgrid.d.ts +9 -0
- package/dist/recipes/tools/sendgrid.js +175 -0
- package/dist/recipes/tools/sendgrid.js.map +1 -0
- package/dist/recipes/tools/shopify.d.ts +16 -0
- package/dist/recipes/tools/shopify.js +266 -0
- package/dist/recipes/tools/shopify.js.map +1 -0
- package/dist/recipes/tools/snowflake.d.ts +16 -0
- package/dist/recipes/tools/snowflake.js +173 -0
- package/dist/recipes/tools/snowflake.js.map +1 -0
- package/dist/recipes/tools/stripe.js +13 -12
- package/dist/recipes/tools/stripe.js.map +1 -1
- package/dist/recipes/tools/supabase.d.ts +9 -0
- package/dist/recipes/tools/supabase.js +133 -0
- package/dist/recipes/tools/supabase.js.map +1 -0
- package/dist/recipes/tools/todoist.d.ts +15 -0
- package/dist/recipes/tools/todoist.js +228 -0
- package/dist/recipes/tools/todoist.js.map +1 -0
- package/dist/recipes/tools/twilio.d.ts +11 -0
- package/dist/recipes/tools/twilio.js +180 -0
- package/dist/recipes/tools/twilio.js.map +1 -0
- package/dist/recipes/tools/vercel.d.ts +9 -0
- package/dist/recipes/tools/vercel.js +146 -0
- package/dist/recipes/tools/vercel.js.map +1 -0
- package/dist/recipes/tools/webflow.d.ts +11 -0
- package/dist/recipes/tools/webflow.js +244 -0
- package/dist/recipes/tools/webflow.js.map +1 -0
- package/dist/recipes/tools/woocommerce.d.ts +18 -0
- package/dist/recipes/tools/woocommerce.js +260 -0
- package/dist/recipes/tools/woocommerce.js.map +1 -0
- package/dist/recipes/tools/wrapConnectorExecute.d.ts +25 -0
- package/dist/recipes/tools/wrapConnectorExecute.js +37 -0
- package/dist/recipes/tools/wrapConnectorExecute.js.map +1 -0
- package/dist/recipes/tools/zendesk.js +11 -10
- package/dist/recipes/tools/zendesk.js.map +1 -1
- package/dist/recipes/triggerVars.d.ts +15 -0
- package/dist/recipes/triggerVars.js +57 -0
- package/dist/recipes/triggerVars.js.map +1 -0
- package/dist/recipes/validation.d.ts +1 -1
- package/dist/recipes/validation.js +536 -12
- package/dist/recipes/validation.js.map +1 -1
- package/dist/recipes/yamlPositions.d.ts +1 -1
- package/dist/recipes/yamlPositions.js +7 -2
- package/dist/recipes/yamlPositions.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +216 -4
- package/dist/recipes/yamlRunner.js +1030 -96
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +5 -0
- package/dist/recipesHttp.js +68 -6
- package/dist/recipesHttp.js.map +1 -1
- package/dist/resources.js +14 -1
- package/dist/resources.js.map +1 -1
- package/dist/riskSignals.d.ts +42 -0
- package/dist/riskSignals.js +197 -0
- package/dist/riskSignals.js.map +1 -0
- package/dist/riskTier.d.ts +9 -0
- package/dist/riskTier.js +48 -0
- package/dist/riskTier.js.map +1 -1
- package/dist/runLog.d.ts +53 -0
- package/dist/runLog.js +75 -16
- package/dist/runLog.js.map +1 -1
- package/dist/schemas/recipe.v1.json +360 -16
- package/dist/server.d.ts +60 -0
- package/dist/server.js +192 -31
- package/dist/server.js.map +1 -1
- package/dist/sessionCheckpoint.js +4 -1
- package/dist/sessionCheckpoint.js.map +1 -1
- package/dist/sessionDetail.d.ts +43 -0
- package/dist/sessionDetail.js +59 -0
- package/dist/sessionDetail.js.map +1 -0
- package/dist/settingsEnv.d.ts +47 -0
- package/dist/settingsEnv.js +88 -0
- package/dist/settingsEnv.js.map +1 -0
- package/dist/streamableHttp.js +44 -10
- package/dist/streamableHttp.js.map +1 -1
- package/dist/ta/backtest/abnday.d.ts +53 -0
- package/dist/ta/backtest/abnday.js +123 -0
- package/dist/ta/backtest/abnday.js.map +1 -0
- package/dist/ta/backtest/directional.d.ts +48 -0
- package/dist/ta/backtest/directional.js +103 -0
- package/dist/ta/backtest/directional.js.map +1 -0
- package/dist/ta/backtest/fundx.d.ts +67 -0
- package/dist/ta/backtest/fundx.js +264 -0
- package/dist/ta/backtest/fundx.js.map +1 -0
- package/dist/ta/backtest/fvg.d.ts +62 -0
- package/dist/ta/backtest/fvg.js +236 -0
- package/dist/ta/backtest/fvg.js.map +1 -0
- package/dist/ta/backtest/ichimoku.d.ts +41 -0
- package/dist/ta/backtest/ichimoku.js +146 -0
- package/dist/ta/backtest/ichimoku.js.map +1 -0
- package/dist/ta/backtest/ingest.d.ts +20 -0
- package/dist/ta/backtest/ingest.js +104 -0
- package/dist/ta/backtest/ingest.js.map +1 -0
- package/dist/ta/backtest/msb.d.ts +49 -0
- package/dist/ta/backtest/msb.js +162 -0
- package/dist/ta/backtest/msb.js.map +1 -0
- package/dist/ta/backtest/scoring.d.ts +33 -0
- package/dist/ta/backtest/scoring.js +82 -0
- package/dist/ta/backtest/scoring.js.map +1 -0
- package/dist/ta/backtest/summary.d.ts +20 -0
- package/dist/ta/backtest/summary.js +42 -0
- package/dist/ta/backtest/summary.js.map +1 -0
- package/dist/ta/backtest/tsmom.d.ts +72 -0
- package/dist/ta/backtest/tsmom.js +202 -0
- package/dist/ta/backtest/tsmom.js.map +1 -0
- package/dist/ta/backtest/volsq.d.ts +34 -0
- package/dist/ta/backtest/volsq.js +154 -0
- package/dist/ta/backtest/volsq.js.map +1 -0
- package/dist/ta/backtest/walkForward.d.ts +45 -0
- package/dist/ta/backtest/walkForward.js +136 -0
- package/dist/ta/backtest/walkForward.js.map +1 -0
- package/dist/ta/cycles.d.ts +15 -0
- package/dist/ta/cycles.js +31 -0
- package/dist/ta/cycles.js.map +1 -0
- package/dist/ta/desk/accrualEmitter.d.ts +59 -0
- package/dist/ta/desk/accrualEmitter.js +136 -0
- package/dist/ta/desk/accrualEmitter.js.map +1 -0
- package/dist/ta/desk/cellBacktest.d.ts +179 -0
- package/dist/ta/desk/cellBacktest.js +514 -0
- package/dist/ta/desk/cellBacktest.js.map +1 -0
- package/dist/ta/desk/cells/wpMaRejection.d.ts +49 -0
- package/dist/ta/desk/cells/wpMaRejection.js +141 -0
- package/dist/ta/desk/cells/wpMaRejection.js.map +1 -0
- package/dist/ta/desk/cells/wpVolumeClimax.d.ts +57 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js +193 -0
- package/dist/ta/desk/cells/wpVolumeClimax.js.map +1 -0
- package/dist/ta/desk/collectors.d.ts +18 -0
- package/dist/ta/desk/collectors.js +450 -0
- package/dist/ta/desk/collectors.js.map +1 -0
- package/dist/ta/desk/contract.d.ts +51 -0
- package/dist/ta/desk/contract.js +261 -0
- package/dist/ta/desk/contract.js.map +1 -0
- package/dist/ta/desk/deskLedger.d.ts +36 -0
- package/dist/ta/desk/deskLedger.js +239 -0
- package/dist/ta/desk/deskLedger.js.map +1 -0
- package/dist/ta/desk/liqTape.d.ts +37 -0
- package/dist/ta/desk/liqTape.js +99 -0
- package/dist/ta/desk/liqTape.js.map +1 -0
- package/dist/ta/desk/post.d.ts +20 -0
- package/dist/ta/desk/post.js +65 -0
- package/dist/ta/desk/post.js.map +1 -0
- package/dist/ta/desk/render.d.ts +25 -0
- package/dist/ta/desk/render.js +398 -0
- package/dist/ta/desk/render.js.map +1 -0
- package/dist/ta/desk/surfaces.d.ts +216 -0
- package/dist/ta/desk/surfaces.js +472 -0
- package/dist/ta/desk/surfaces.js.map +1 -0
- package/dist/ta/desk/types.d.ts +174 -0
- package/dist/ta/desk/types.js +104 -0
- package/dist/ta/desk/types.js.map +1 -0
- package/dist/ta/index.d.ts +23 -0
- package/dist/ta/index.js +54 -0
- package/dist/ta/index.js.map +1 -0
- package/dist/ta/ledger.d.ts +44 -0
- package/dist/ta/ledger.js +95 -0
- package/dist/ta/ledger.js.map +1 -0
- package/dist/ta/levels.d.ts +21 -0
- package/dist/ta/levels.js +41 -0
- package/dist/ta/levels.js.map +1 -0
- package/dist/ta/swings.d.ts +30 -0
- package/dist/ta/swings.js +83 -0
- package/dist/ta/swings.js.map +1 -0
- package/dist/ta/types.d.ts +81 -0
- package/dist/ta/types.js +20 -0
- package/dist/ta/types.js.map +1 -0
- package/dist/telemetry.js +20 -9
- package/dist/telemetry.js.map +1 -1
- package/dist/tokenUsageTracker.d.ts +2 -1
- package/dist/tokenUsageTracker.js +38 -20
- package/dist/tokenUsageTracker.js.map +1 -1
- package/dist/tools/contextBundle.js +13 -9
- package/dist/tools/contextBundle.js.map +1 -1
- package/dist/tools/ctxGetTaskContext.js +8 -3
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/ctxQueryTraces.d.ts +18 -1
- package/dist/tools/ctxQueryTraces.js +176 -27
- package/dist/tools/ctxQueryTraces.js.map +1 -1
- package/dist/tools/enrichCommit.js +5 -2
- package/dist/tools/enrichCommit.js.map +1 -1
- package/dist/tools/getDependencyTree.js +2 -2
- package/dist/tools/getDependencyTree.js.map +1 -1
- package/dist/tools/getDiagnostics.js +3 -0
- package/dist/tools/getDiagnostics.js.map +1 -1
- package/dist/tools/getDocumentSymbols.js +5 -1
- package/dist/tools/getDocumentSymbols.js.map +1 -1
- package/dist/tools/getGitHotspots.js +12 -1
- package/dist/tools/getGitHotspots.js.map +1 -1
- package/dist/tools/getGitLog.js +5 -2
- package/dist/tools/getGitLog.js.map +1 -1
- package/dist/tools/getGitStatus.js +6 -1
- package/dist/tools/getGitStatus.js.map +1 -1
- package/dist/tools/getProjectContext.js +3 -1
- package/dist/tools/getProjectContext.js.map +1 -1
- package/dist/tools/getToolCapabilities.js +39 -4
- package/dist/tools/getToolCapabilities.js.map +1 -1
- package/dist/tools/gitWrite.js +12 -3
- package/dist/tools/gitWrite.js.map +1 -1
- package/dist/tools/github/composite.d.ts +1 -1
- package/dist/tools/github/composite.js +7 -7
- package/dist/tools/github/composite.js.map +1 -1
- package/dist/tools/github/pr.d.ts +6 -6
- package/dist/tools/github/pr.js +18 -11
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/httpClient.js +55 -3
- package/dist/tools/httpClient.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +19 -12
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lsp.d.ts +6 -0
- package/dist/tools/lsp.js +81 -12
- package/dist/tools/lsp.js.map +1 -1
- package/dist/tools/previewEdit.js +16 -1
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/resumeClaudeTask.js +17 -0
- package/dist/tools/resumeClaudeTask.js.map +1 -1
- package/dist/tools/searchAndReplace.js +9 -5
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.d.ts +26 -0
- package/dist/tools/searchTools.js +42 -2
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/terminal.js +23 -51
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/transaction.d.ts +9 -1
- package/dist/tools/transaction.js +59 -4
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/utils.d.ts +16 -0
- package/dist/tools/utils.js +77 -7
- package/dist/tools/utils.js.map +1 -1
- package/dist/transport.d.ts +31 -0
- package/dist/transport.js +117 -14
- package/dist/transport.js.map +1 -1
- package/dist/wireHaltPushDispatch.js +12 -0
- package/dist/wireHaltPushDispatch.js.map +1 -1
- package/dist/workerGateDecisionLog.d.ts +141 -0
- package/dist/workerGateDecisionLog.js +361 -0
- package/dist/workerGateDecisionLog.js.map +1 -0
- package/dist/workers/actionClass.d.ts +38 -0
- package/dist/workers/actionClass.js +155 -0
- package/dist/workers/actionClass.js.map +1 -0
- package/dist/workers/backtest.d.ts +68 -0
- package/dist/workers/backtest.js +113 -0
- package/dist/workers/backtest.js.map +1 -0
- package/dist/workers/contextRisk.d.ts +35 -0
- package/dist/workers/contextRisk.js +20 -0
- package/dist/workers/contextRisk.js.map +1 -0
- package/dist/workers/contextRiskScorer.d.ts +48 -0
- package/dist/workers/contextRiskScorer.js +94 -0
- package/dist/workers/contextRiskScorer.js.map +1 -0
- package/dist/workers/graduation.d.ts +61 -0
- package/dist/workers/graduation.js +112 -0
- package/dist/workers/graduation.js.map +1 -0
- package/dist/workers/outcomeStore.d.ts +98 -0
- package/dist/workers/outcomeStore.js +146 -0
- package/dist/workers/outcomeStore.js.map +1 -0
- package/dist/workers/outcomesCli.d.ts +34 -0
- package/dist/workers/outcomesCli.js +91 -0
- package/dist/workers/outcomesCli.js.map +1 -0
- package/dist/workers/runWorkerShadow.d.ts +90 -0
- package/dist/workers/runWorkerShadow.js +323 -0
- package/dist/workers/runWorkerShadow.js.map +1 -0
- package/dist/workers/shadowGate.d.ts +30 -0
- package/dist/workers/shadowGate.js +58 -0
- package/dist/workers/shadowGate.js.map +1 -0
- package/dist/workers/shadowObserver.d.ts +165 -0
- package/dist/workers/shadowObserver.js +203 -0
- package/dist/workers/shadowObserver.js.map +1 -0
- package/dist/workers/shadowReport.d.ts +16 -0
- package/dist/workers/shadowReport.js +61 -0
- package/dist/workers/shadowReport.js.map +1 -0
- package/dist/workers/shadowRun.d.ts +38 -0
- package/dist/workers/shadowRun.js +44 -0
- package/dist/workers/shadowRun.js.map +1 -0
- package/dist/workers/trustLevel.d.ts +82 -0
- package/dist/workers/trustLevel.js +100 -0
- package/dist/workers/trustLevel.js.map +1 -0
- package/dist/workers/worker.d.ts +49 -0
- package/dist/workers/worker.js +88 -0
- package/dist/workers/worker.js.map +1 -0
- package/dist/workers/workerGate.d.ts +101 -0
- package/dist/workers/workerGate.js +210 -0
- package/dist/workers/workerGate.js.map +1 -0
- package/dist/workers/workerLevelStore.d.ts +33 -0
- package/dist/workers/workerLevelStore.js +87 -0
- package/dist/workers/workerLevelStore.js.map +1 -0
- package/dist/workers/workerLoader.d.ts +7 -0
- package/dist/workers/workerLoader.js +31 -0
- package/dist/workers/workerLoader.js.map +1 -0
- package/dist/writeFileAtomic.js +40 -13
- package/dist/writeFileAtomic.js.map +1 -1
- package/package.json +14 -6
- package/scripts/mcp-stdio-shim.cjs +247 -87
- package/templates/CLAUDE.bridge.md +1 -1
- package/templates/recipes/dependency-bump.yaml +33 -0
- package/templates/recipes/incident-to-pr.yaml +187 -0
- package/templates/recipes/outcome-ingester.yaml +53 -0
- package/templates/recipes/release-notes.yaml +30 -0
- package/templates/recipes/triage-failing-tests-autofile.yaml +152 -0
- package/templates/recipes/triage-failing-tests.yaml +38 -0
- package/templates/workers/dependency-upkeep.worker.yaml +26 -0
- package/templates/workers/release-notes.worker.yaml +17 -0
- package/templates/workers/test-guardian.worker.yaml +24 -0
- package/deploy/README.md +0 -172
- package/deploy/bootstrap-new-vps.sh +0 -364
- package/deploy/bootstrap-vps.sh +0 -192
- package/deploy/claude-ide-bridge.service.template +0 -67
- package/deploy/claude-ide-bridge@.service +0 -31
- package/deploy/deploy-dashboard.sh +0 -198
- package/deploy/deploy-landing.sh +0 -136
- package/deploy/ecosystem.config.js.example +0 -36
- package/deploy/install-vps-service.sh +0 -240
- package/deploy/macos/README.md +0 -153
- package/deploy/macos/com.patchwork.bridge.plist.template +0 -54
- package/deploy/macos/com.patchwork.tunnel.plist.template +0 -76
- package/deploy/macos/install-mac-bridge.sh +0 -244
- package/deploy/macos/uninstall-mac-bridge.sh +0 -22
- package/deploy/nginx-claude-bridge.conf.template +0 -129
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { truncateToBytes, truncateUtf8Bytes } from "../outputCap.js";
|
|
1
2
|
const OUTPUT_CAP = 50 * 1024;
|
|
2
3
|
/**
|
|
3
4
|
* OpenAI API driver — streams via chat.completions.create.
|
|
@@ -43,6 +44,16 @@ export class OpenAIApiDriver {
|
|
|
43
44
|
const opts = input.providerOptions ?? {};
|
|
44
45
|
const maxTokens = typeof opts.maxTokens === "number" ? opts.maxTokens : 4096;
|
|
45
46
|
const temperature = typeof opts.temperature === "number" ? opts.temperature : undefined;
|
|
47
|
+
// Structured-output passthrough (audit 2026-06-09): when a caller sets
|
|
48
|
+
// providerOptions.responseFormat (e.g. { type: "json_object" } or
|
|
49
|
+
// { type: "json_schema", json_schema: {...} }), forward it to the API so
|
|
50
|
+
// OpenAI-compatible servers that support constrained decoding (vLLM/XGrammar,
|
|
51
|
+
// llama.cpp, LM Studio) enforce valid structured output at the token level.
|
|
52
|
+
// Endpoints that don't support it simply ignore the field. Foundation for
|
|
53
|
+
// hardening the judge→refine verdict JSON on local models.
|
|
54
|
+
const responseFormat = opts.responseFormat && typeof opts.responseFormat === "object"
|
|
55
|
+
? opts.responseFormat
|
|
56
|
+
: undefined;
|
|
46
57
|
const contextNote = input.contextFiles && input.contextFiles.length > 0
|
|
47
58
|
? `\n\n--- BEGIN CONTEXT FILE LIST ---\n${input.contextFiles
|
|
48
59
|
.map((f) => f.slice(0, 500).replace(/[\x00-\x1f\x7f]/g, ""))
|
|
@@ -65,7 +76,10 @@ export class OpenAIApiDriver {
|
|
|
65
76
|
const model = input.model ?? this.opts.defaultModel ?? "gpt-4o";
|
|
66
77
|
this.log(`[${this.name}] streaming: model=${model} workspace=${input.workspace}`);
|
|
67
78
|
let text = "";
|
|
79
|
+
let outputBytesSent = 0;
|
|
68
80
|
let firstChunkAt;
|
|
81
|
+
let promptTokens;
|
|
82
|
+
let completionTokens;
|
|
69
83
|
try {
|
|
70
84
|
// biome-ignore lint/suspicious/noExplicitAny: dynamic import shape
|
|
71
85
|
const stream = await client.chat.completions.create({
|
|
@@ -74,21 +88,60 @@ export class OpenAIApiDriver {
|
|
|
74
88
|
...(temperature !== undefined ? { temperature } : {}),
|
|
75
89
|
messages,
|
|
76
90
|
stream: true,
|
|
91
|
+
...(responseFormat ? { response_format: responseFormat } : {}),
|
|
92
|
+
// Ask the API to emit a final usage chunk (prompt/completion token
|
|
93
|
+
// counts) so RunBudget can enforce a real token/USD budget instead
|
|
94
|
+
// of failing open. Compliant OpenAI-style endpoints return it; an
|
|
95
|
+
// endpoint that ignores the option simply omits usage and we fail
|
|
96
|
+
// open (providerMeta carries no tokens).
|
|
97
|
+
stream_options: { include_usage: true },
|
|
77
98
|
}, { signal: input.signal });
|
|
78
99
|
// biome-ignore lint/suspicious/noExplicitAny: stream shape from dynamic import
|
|
79
100
|
for await (const chunk of stream) {
|
|
101
|
+
// The include_usage final chunk carries an empty `choices` array and a
|
|
102
|
+
// `usage` object; capture it whenever present (so it works even if an
|
|
103
|
+
// endpoint attaches usage to a content-bearing chunk).
|
|
104
|
+
if (chunk.usage) {
|
|
105
|
+
if (typeof chunk.usage.prompt_tokens === "number")
|
|
106
|
+
promptTokens = chunk.usage.prompt_tokens;
|
|
107
|
+
if (typeof chunk.usage.completion_tokens === "number")
|
|
108
|
+
completionTokens = chunk.usage.completion_tokens;
|
|
109
|
+
}
|
|
80
110
|
const delta = chunk.choices?.[0]?.delta?.content ?? "";
|
|
81
111
|
if (delta) {
|
|
82
112
|
if (firstChunkAt === undefined)
|
|
83
113
|
firstChunkAt = Date.now();
|
|
84
|
-
if (
|
|
114
|
+
if (outputBytesSent < OUTPUT_CAP) {
|
|
85
115
|
// Cap accumulation in-loop to bound memory under runaway streams
|
|
86
116
|
// (e.g. local LLMs that loop). Once we hit the cap, stop appending
|
|
87
117
|
// and abort the upstream stream so sockets and decoder buffers
|
|
88
|
-
// are released.
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
118
|
+
// are released.
|
|
119
|
+
//
|
|
120
|
+
// LOW #19 audit 2026-06-03: use truncateToBytes so the chunk sent
|
|
121
|
+
// to onChunk is always the SAME bytes as what lands in result.text.
|
|
122
|
+
// The previous pattern appended the full `delta` to `text` then
|
|
123
|
+
// called `onChunk(delta)`, but `truncateUtf8Bytes(text, OUTPUT_CAP)`
|
|
124
|
+
// at the end could cut the last delta — so onChunk sum > result.text.
|
|
125
|
+
const remaining = OUTPUT_CAP - outputBytesSent;
|
|
126
|
+
const { send, bytes } = truncateToBytes(delta, remaining);
|
|
127
|
+
text += send;
|
|
128
|
+
outputBytesSent += bytes;
|
|
129
|
+
if (send)
|
|
130
|
+
input.onChunk?.(send);
|
|
131
|
+
if (bytes < Buffer.byteLength(delta, "utf8")) {
|
|
132
|
+
// We've hit the cap mid-delta — abort the stream.
|
|
133
|
+
// biome-ignore lint/suspicious/noExplicitAny: stream shape
|
|
134
|
+
const ctrl = stream.controller;
|
|
135
|
+
if (ctrl && typeof ctrl.abort === "function") {
|
|
136
|
+
try {
|
|
137
|
+
ctrl.abort();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
/* best effort */
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
92
145
|
}
|
|
93
146
|
else {
|
|
94
147
|
// biome-ignore lint/suspicious/noExplicitAny: stream shape
|
|
@@ -111,23 +164,30 @@ export class OpenAIApiDriver {
|
|
|
111
164
|
input.signal.aborted;
|
|
112
165
|
if (isAbort) {
|
|
113
166
|
return {
|
|
114
|
-
text: text
|
|
167
|
+
text: truncateUtf8Bytes(text, OUTPUT_CAP),
|
|
115
168
|
durationMs: Date.now() - start,
|
|
116
169
|
wasAborted: true,
|
|
117
170
|
startupMs: firstChunkAt !== undefined ? firstChunkAt - start : undefined,
|
|
118
171
|
};
|
|
119
172
|
}
|
|
120
173
|
return {
|
|
121
|
-
text: text
|
|
174
|
+
text: truncateUtf8Bytes(text, OUTPUT_CAP),
|
|
122
175
|
durationMs: Date.now() - start,
|
|
123
176
|
errorMessage: err instanceof Error ? err.message : String(err),
|
|
124
177
|
};
|
|
125
178
|
}
|
|
126
179
|
return {
|
|
127
|
-
text: text
|
|
180
|
+
text: truncateUtf8Bytes(text, OUTPUT_CAP),
|
|
128
181
|
durationMs: Date.now() - start,
|
|
129
182
|
startupMs: firstChunkAt !== undefined ? firstChunkAt - start : undefined,
|
|
130
|
-
providerMeta: {
|
|
183
|
+
providerMeta: {
|
|
184
|
+
model,
|
|
185
|
+
// Present only when the endpoint returned a usage chunk. Both fields
|
|
186
|
+
// together or neither — a half-populated count would mislead budgets.
|
|
187
|
+
...(promptTokens !== undefined && completionTokens !== undefined
|
|
188
|
+
? { inputTokens: promptTokens, outputTokens: completionTokens }
|
|
189
|
+
: {}),
|
|
190
|
+
},
|
|
131
191
|
};
|
|
132
192
|
}
|
|
133
193
|
/** Override in subclasses to use a different env var. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/openai/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/openai/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared UTF-8-aware output truncation for driver results.
|
|
3
|
+
*
|
|
4
|
+
* Audit 2026-06-03 (MEDIUM #30): the API drivers (claude/api, openai, gemini)
|
|
5
|
+
* capped output with `text.slice(0, OUTPUT_CAP)`, which counts UTF-16 code
|
|
6
|
+
* units — so a 50K "byte" cap could emit ~200KB of UTF-8 wire bytes for CJK /
|
|
7
|
+
* emoji content and could leave a lone surrogate at the boundary. These
|
|
8
|
+
* helpers (previously private to claude/subprocess.ts) measure and cut by
|
|
9
|
+
* UTF-8 bytes. Shared so every driver path uses one implementation.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Truncate `text` to at most `cap` UTF-8 bytes without splitting a multi-byte
|
|
13
|
+
* codepoint. `String.slice(0, cap)` counts UTF-16 code units, so a 50K cap can
|
|
14
|
+
* emit ~200KB of UTF-8 wire bytes for CJK / emoji content; this cuts by bytes
|
|
15
|
+
* at a codepoint boundary.
|
|
16
|
+
*/
|
|
17
|
+
export declare function truncateUtf8Bytes(text: string, cap: number): string;
|
|
18
|
+
/**
|
|
19
|
+
* Truncate `text` so it adds at most `remaining` UTF-8 bytes to a stream and
|
|
20
|
+
* never splits a multi-byte codepoint. Returns the safely-truncated slice plus
|
|
21
|
+
* its actual byte length so a running byte total can be advanced correctly
|
|
22
|
+
* (used by the streaming accumulators).
|
|
23
|
+
*/
|
|
24
|
+
export declare function truncateToBytes(text: string, remaining: number): {
|
|
25
|
+
send: string;
|
|
26
|
+
bytes: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared UTF-8-aware output truncation for driver results.
|
|
3
|
+
*
|
|
4
|
+
* Audit 2026-06-03 (MEDIUM #30): the API drivers (claude/api, openai, gemini)
|
|
5
|
+
* capped output with `text.slice(0, OUTPUT_CAP)`, which counts UTF-16 code
|
|
6
|
+
* units — so a 50K "byte" cap could emit ~200KB of UTF-8 wire bytes for CJK /
|
|
7
|
+
* emoji content and could leave a lone surrogate at the boundary. These
|
|
8
|
+
* helpers (previously private to claude/subprocess.ts) measure and cut by
|
|
9
|
+
* UTF-8 bytes. Shared so every driver path uses one implementation.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Largest byte length ≤ `cap` that ends on a UTF-8 codepoint boundary. UTF-8
|
|
13
|
+
* continuation bytes match `0b10xxxxxx`; if the byte at the cut is one, we're
|
|
14
|
+
* mid-sequence, so back off to the preceding lead byte. This drops a partial
|
|
15
|
+
* trailing codepoint cleanly (no U+FFFD, no lone surrogate, never over `cap`).
|
|
16
|
+
*/
|
|
17
|
+
function codepointBoundary(buf, cap) {
|
|
18
|
+
let end = cap;
|
|
19
|
+
while (end > 0 && (buf[end] & 0xc0) === 0x80)
|
|
20
|
+
end--;
|
|
21
|
+
return end;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Truncate `text` to at most `cap` UTF-8 bytes without splitting a multi-byte
|
|
25
|
+
* codepoint. `String.slice(0, cap)` counts UTF-16 code units, so a 50K cap can
|
|
26
|
+
* emit ~200KB of UTF-8 wire bytes for CJK / emoji content; this cuts by bytes
|
|
27
|
+
* at a codepoint boundary.
|
|
28
|
+
*/
|
|
29
|
+
export function truncateUtf8Bytes(text, cap) {
|
|
30
|
+
const buf = Buffer.from(text, "utf8");
|
|
31
|
+
if (buf.length <= cap)
|
|
32
|
+
return text;
|
|
33
|
+
return buf.subarray(0, codepointBoundary(buf, cap)).toString("utf8");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Truncate `text` so it adds at most `remaining` UTF-8 bytes to a stream and
|
|
37
|
+
* never splits a multi-byte codepoint. Returns the safely-truncated slice plus
|
|
38
|
+
* its actual byte length so a running byte total can be advanced correctly
|
|
39
|
+
* (used by the streaming accumulators).
|
|
40
|
+
*/
|
|
41
|
+
export function truncateToBytes(text, remaining) {
|
|
42
|
+
const buf = Buffer.from(text, "utf8");
|
|
43
|
+
if (buf.length <= remaining)
|
|
44
|
+
return { send: text, bytes: buf.length };
|
|
45
|
+
const send = buf
|
|
46
|
+
.subarray(0, codepointBoundary(buf, remaining))
|
|
47
|
+
.toString("utf8");
|
|
48
|
+
return { send, bytes: Buffer.byteLength(send, "utf8") };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=outputCap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputCap.js","sourceRoot":"","sources":["../../src/drivers/outputCap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,GAAW,EAAE,GAAW;IACjD,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,OAAO,GAAG,GAAG,CAAC,IAAI,CAAE,GAAG,CAAC,GAAG,CAAY,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,GAAG,EAAE,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,GAAW;IACzD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,SAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACtE,MAAM,IAAI,GAAG,GAAG;SACb,QAAQ,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;SAC9C,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, zero-dependency vector math. No imports — keep it that way so it can
|
|
3
|
+
* be reused anywhere (ranking, dedup, semantic search) without pulling in
|
|
4
|
+
* network / config / driver dependencies.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Cosine similarity = dot(a, b) / (|a| * |b|).
|
|
8
|
+
*
|
|
9
|
+
* Returns `0` (never `NaN`, never throws) on:
|
|
10
|
+
* - length mismatch between `a` and `b`
|
|
11
|
+
* - either vector being zero-magnitude
|
|
12
|
+
* - empty vectors
|
|
13
|
+
*
|
|
14
|
+
* Identical vectors → 1, orthogonal → 0, opposite → -1.
|
|
15
|
+
*/
|
|
16
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
17
|
+
/**
|
|
18
|
+
* Return the `k` highest-scoring items, sorted score-descending. Stable for
|
|
19
|
+
* ties — items with equal score keep their original relative order.
|
|
20
|
+
*
|
|
21
|
+
* `k` larger than the list returns all items (sorted). `k <= 0` returns `[]`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function topK<T>(items: T[], scoreOf: (item: T) => number, k: number): T[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, zero-dependency vector math. No imports — keep it that way so it can
|
|
3
|
+
* be reused anywhere (ranking, dedup, semantic search) without pulling in
|
|
4
|
+
* network / config / driver dependencies.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Cosine similarity = dot(a, b) / (|a| * |b|).
|
|
8
|
+
*
|
|
9
|
+
* Returns `0` (never `NaN`, never throws) on:
|
|
10
|
+
* - length mismatch between `a` and `b`
|
|
11
|
+
* - either vector being zero-magnitude
|
|
12
|
+
* - empty vectors
|
|
13
|
+
*
|
|
14
|
+
* Identical vectors → 1, orthogonal → 0, opposite → -1.
|
|
15
|
+
*/
|
|
16
|
+
export function cosineSimilarity(a, b) {
|
|
17
|
+
if (a.length !== b.length || a.length === 0)
|
|
18
|
+
return 0;
|
|
19
|
+
let dot = 0;
|
|
20
|
+
let magA = 0;
|
|
21
|
+
let magB = 0;
|
|
22
|
+
for (let i = 0; i < a.length; i++) {
|
|
23
|
+
// Bounds-safe: i < a.length === b.length (checked above).
|
|
24
|
+
const av = a[i];
|
|
25
|
+
const bv = b[i];
|
|
26
|
+
dot += av * bv;
|
|
27
|
+
magA += av * av;
|
|
28
|
+
magB += bv * bv;
|
|
29
|
+
}
|
|
30
|
+
if (magA === 0 || magB === 0)
|
|
31
|
+
return 0;
|
|
32
|
+
const denom = Math.sqrt(magA) * Math.sqrt(magB);
|
|
33
|
+
if (denom === 0)
|
|
34
|
+
return 0;
|
|
35
|
+
return dot / denom;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Return the `k` highest-scoring items, sorted score-descending. Stable for
|
|
39
|
+
* ties — items with equal score keep their original relative order.
|
|
40
|
+
*
|
|
41
|
+
* `k` larger than the list returns all items (sorted). `k <= 0` returns `[]`.
|
|
42
|
+
*/
|
|
43
|
+
export function topK(items, scoreOf, k) {
|
|
44
|
+
if (k <= 0)
|
|
45
|
+
return [];
|
|
46
|
+
// Decorate with original index to make the sort stable across ties.
|
|
47
|
+
const decorated = items.map((item, index) => ({
|
|
48
|
+
item,
|
|
49
|
+
index,
|
|
50
|
+
score: scoreOf(item),
|
|
51
|
+
}));
|
|
52
|
+
decorated.sort((x, y) => {
|
|
53
|
+
if (y.score !== x.score)
|
|
54
|
+
return y.score - x.score;
|
|
55
|
+
return x.index - y.index;
|
|
56
|
+
});
|
|
57
|
+
return decorated.slice(0, k).map((d) => d.item);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=cosine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cosine.js","sourceRoot":"","sources":["../../src/embeddings/cosine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAW,EAAE,CAAW;IACvD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,0DAA0D;QAC1D,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1B,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC;QACf,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;QAChB,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,GAAG,GAAG,KAAK,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAClB,KAAU,EACV,OAA4B,EAC5B,CAAS;IAET,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtB,oEAAoE;IACpE,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI;QACJ,KAAK;QACL,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC;KACrB,CAAC,CAAC,CAAC;IACJ,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtB,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAClD,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EmbeddingsProvider, EmbeddingsProviderOpts } from "./types.js";
|
|
2
|
+
export { cosineSimilarity, topK } from "./cosine.js";
|
|
3
|
+
export { LocalEmbeddingsProvider } from "./localEmbeddings.js";
|
|
4
|
+
export type { EmbeddingsProvider, EmbeddingsProviderOpts } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Build an embeddings provider, or `null` when no endpoint is configured
|
|
7
|
+
* (neither `opts.endpoint` nor `LOCAL_EMBEDDINGS_ENDPOINT` nor
|
|
8
|
+
* `LOCAL_ENDPOINT`). Returning `null` lets callers fail soft.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createEmbeddingsProvider(opts?: EmbeddingsProviderOpts): EmbeddingsProvider | null;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a bound embed function for the configured local provider, or
|
|
13
|
+
* `undefined` when embeddings are unconfigured. Wired into tool registration
|
|
14
|
+
* sites — `createCtxQueryTracesTool({ ..., embedFn: getLocalEmbedFn() })` — so
|
|
15
|
+
* the opt-in semantic ranking path activates only when a local endpoint is set
|
|
16
|
+
* and stays byte-identical to substring search otherwise. Binds `embed` so
|
|
17
|
+
* callers can pass the function value directly without losing `this`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getLocalEmbedFn(opts?: EmbeddingsProviderOpts): ((texts: string[]) => Promise<number[][] | null>) | undefined;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embeddings module — internal, NOT an MCP tool (no outputSchema, not
|
|
3
|
+
* registered in src/tools/index.ts).
|
|
4
|
+
*
|
|
5
|
+
* The factory is the fail-soft hinge: {@link createEmbeddingsProvider} returns
|
|
6
|
+
* `null` when no endpoint is configured at all, so every consumer can detect
|
|
7
|
+
* "embeddings unavailable" and fall back to existing behavior.
|
|
8
|
+
*/
|
|
9
|
+
import { LocalEmbeddingsProvider } from "./localEmbeddings.js";
|
|
10
|
+
import { resolveEmbeddingsEndpoint } from "./localEndpoints.js";
|
|
11
|
+
export { cosineSimilarity, topK } from "./cosine.js";
|
|
12
|
+
export { LocalEmbeddingsProvider } from "./localEmbeddings.js";
|
|
13
|
+
/**
|
|
14
|
+
* Build an embeddings provider, or `null` when no endpoint is configured
|
|
15
|
+
* (neither `opts.endpoint` nor `LOCAL_EMBEDDINGS_ENDPOINT` nor
|
|
16
|
+
* `LOCAL_ENDPOINT`). Returning `null` lets callers fail soft.
|
|
17
|
+
*/
|
|
18
|
+
export function createEmbeddingsProvider(opts = {}) {
|
|
19
|
+
if (!resolveEmbeddingsEndpoint(opts))
|
|
20
|
+
return null;
|
|
21
|
+
return new LocalEmbeddingsProvider(opts);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a bound embed function for the configured local provider, or
|
|
25
|
+
* `undefined` when embeddings are unconfigured. Wired into tool registration
|
|
26
|
+
* sites — `createCtxQueryTracesTool({ ..., embedFn: getLocalEmbedFn() })` — so
|
|
27
|
+
* the opt-in semantic ranking path activates only when a local endpoint is set
|
|
28
|
+
* and stays byte-identical to substring search otherwise. Binds `embed` so
|
|
29
|
+
* callers can pass the function value directly without losing `this`.
|
|
30
|
+
*/
|
|
31
|
+
export function getLocalEmbedFn(opts = {}) {
|
|
32
|
+
const provider = createEmbeddingsProvider(opts);
|
|
33
|
+
return provider ? (texts) => provider.embed(texts) : undefined;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/embeddings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAG/D;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAA+B,EAAE;IAEjC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA+B,EAAE;IAEjC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EmbeddingsProvider, EmbeddingsProviderOpts } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI-compatible embeddings client (Ollama / MLX / mlx-embeddings / vLLM).
|
|
4
|
+
*
|
|
5
|
+
* POSTs `{ model, input }` to `${endpoint}/embeddings` and parses the OpenAI
|
|
6
|
+
* shape `{ data: [{ embedding: number[] }, ...] }`.
|
|
7
|
+
*
|
|
8
|
+
* Fail-soft contract — `embed()` returns `null` (never throws) on:
|
|
9
|
+
* - a public/non-loopback endpoint when LOCAL_ENDPOINT_ALLOW_REMOTE !== "1"
|
|
10
|
+
* (anti-exfiltration — the texts we send are prompts/context)
|
|
11
|
+
* - non-ok HTTP status
|
|
12
|
+
* - JSON parse / unexpected shape
|
|
13
|
+
* - any network throw inside fetch
|
|
14
|
+
*
|
|
15
|
+
* Configuration precedence (see {@link resolveEmbeddingsEndpoint} /
|
|
16
|
+
* {@link resolveEmbeddingsModel}):
|
|
17
|
+
* endpoint: opts.endpoint ?? LOCAL_EMBEDDINGS_ENDPOINT ?? LOCAL_ENDPOINT
|
|
18
|
+
* model: opts.model ?? LOCAL_EMBEDDINGS_MODEL ?? LOCAL_MODEL ?? nomic-embed-text
|
|
19
|
+
* apiKey: opts.apiKey ?? LOCAL_API_KEY ?? "ollama"
|
|
20
|
+
*/
|
|
21
|
+
export declare class LocalEmbeddingsProvider implements EmbeddingsProvider {
|
|
22
|
+
private readonly endpoint;
|
|
23
|
+
private readonly model;
|
|
24
|
+
private readonly apiKey;
|
|
25
|
+
private readonly fetchImpl;
|
|
26
|
+
private readonly log;
|
|
27
|
+
constructor(opts?: EmbeddingsProviderOpts);
|
|
28
|
+
embed(texts: string[]): Promise<number[][] | null>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { isLoopbackOrPrivateEndpoint } from "../localEndpointGuard.js";
|
|
2
|
+
import { resolveEmbeddingsEndpoint, resolveEmbeddingsModel, } from "./localEndpoints.js";
|
|
3
|
+
/**
|
|
4
|
+
* OpenAI-compatible embeddings client (Ollama / MLX / mlx-embeddings / vLLM).
|
|
5
|
+
*
|
|
6
|
+
* POSTs `{ model, input }` to `${endpoint}/embeddings` and parses the OpenAI
|
|
7
|
+
* shape `{ data: [{ embedding: number[] }, ...] }`.
|
|
8
|
+
*
|
|
9
|
+
* Fail-soft contract — `embed()` returns `null` (never throws) on:
|
|
10
|
+
* - a public/non-loopback endpoint when LOCAL_ENDPOINT_ALLOW_REMOTE !== "1"
|
|
11
|
+
* (anti-exfiltration — the texts we send are prompts/context)
|
|
12
|
+
* - non-ok HTTP status
|
|
13
|
+
* - JSON parse / unexpected shape
|
|
14
|
+
* - any network throw inside fetch
|
|
15
|
+
*
|
|
16
|
+
* Configuration precedence (see {@link resolveEmbeddingsEndpoint} /
|
|
17
|
+
* {@link resolveEmbeddingsModel}):
|
|
18
|
+
* endpoint: opts.endpoint ?? LOCAL_EMBEDDINGS_ENDPOINT ?? LOCAL_ENDPOINT
|
|
19
|
+
* model: opts.model ?? LOCAL_EMBEDDINGS_MODEL ?? LOCAL_MODEL ?? nomic-embed-text
|
|
20
|
+
* apiKey: opts.apiKey ?? LOCAL_API_KEY ?? "ollama"
|
|
21
|
+
*/
|
|
22
|
+
export class LocalEmbeddingsProvider {
|
|
23
|
+
endpoint;
|
|
24
|
+
model;
|
|
25
|
+
apiKey;
|
|
26
|
+
fetchImpl;
|
|
27
|
+
log;
|
|
28
|
+
constructor(opts = {}) {
|
|
29
|
+
this.endpoint = resolveEmbeddingsEndpoint(opts);
|
|
30
|
+
this.model = resolveEmbeddingsModel(opts);
|
|
31
|
+
this.apiKey = opts.apiKey ?? process.env.LOCAL_API_KEY ?? "ollama";
|
|
32
|
+
this.fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
33
|
+
this.log = opts.log ?? (() => { });
|
|
34
|
+
}
|
|
35
|
+
async embed(texts) {
|
|
36
|
+
const endpoint = this.endpoint;
|
|
37
|
+
if (!endpoint) {
|
|
38
|
+
this.log("embeddings: no endpoint configured — returning null");
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
// Anti-exfiltration guard. The texts we POST are prompts/context — a
|
|
42
|
+
// public host would leak them. Mirror src/drivers/local/index.ts, but
|
|
43
|
+
// fail SOFT (return null) instead of throwing.
|
|
44
|
+
if (process.env.LOCAL_ENDPOINT_ALLOW_REMOTE !== "1" &&
|
|
45
|
+
!isLoopbackOrPrivateEndpoint(endpoint)) {
|
|
46
|
+
this.log(`embeddings: endpoint="${endpoint}" is not loopback/private — refusing ` +
|
|
47
|
+
`to send prompt/context (set LOCAL_ENDPOINT_ALLOW_REMOTE=1 to override)`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (texts.length === 0)
|
|
51
|
+
return [];
|
|
52
|
+
const url = `${endpoint.replace(/\/$/, "")}/embeddings`;
|
|
53
|
+
try {
|
|
54
|
+
const res = await this.fetchImpl(url, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/json",
|
|
58
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify({ model: this.model, input: texts }),
|
|
61
|
+
});
|
|
62
|
+
if (!res.ok) {
|
|
63
|
+
this.log(`embeddings: non-ok status ${res.status} from ${url}`);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const body = (await res.json());
|
|
67
|
+
const vectors = parseEmbeddings(body);
|
|
68
|
+
if (!vectors) {
|
|
69
|
+
this.log(`embeddings: unexpected response shape from ${url}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return vectors;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
this.log(`embeddings: request failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse the OpenAI embeddings response shape `{ data: [{ embedding: [...] }] }`.
|
|
82
|
+
* Returns `null` on any structural mismatch (so the caller can fail soft).
|
|
83
|
+
*/
|
|
84
|
+
function parseEmbeddings(body) {
|
|
85
|
+
if (typeof body !== "object" || body === null)
|
|
86
|
+
return null;
|
|
87
|
+
const data = body.data;
|
|
88
|
+
if (!Array.isArray(data))
|
|
89
|
+
return null;
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const row of data) {
|
|
92
|
+
if (typeof row !== "object" || row === null)
|
|
93
|
+
return null;
|
|
94
|
+
const embedding = row.embedding;
|
|
95
|
+
if (!Array.isArray(embedding))
|
|
96
|
+
return null;
|
|
97
|
+
if (!embedding.every((n) => typeof n === "number"))
|
|
98
|
+
return null;
|
|
99
|
+
out.push(embedding);
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=localEmbeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localEmbeddings.js","sourceRoot":"","sources":["../../src/embeddings/localEmbeddings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared endpoint/model precedence resolution for the embeddings module.
|
|
3
|
+
* Kept tiny + import-free (besides env reads) so both the factory
|
|
4
|
+
* (`index.ts`) and the provider (`localEmbeddings.ts`) agree on exactly the
|
|
5
|
+
* same precedence chain.
|
|
6
|
+
*/
|
|
7
|
+
import type { EmbeddingsProviderOpts } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the embeddings endpoint, honoring (in order):
|
|
10
|
+
* 1. `opts.endpoint`
|
|
11
|
+
* 2. `LOCAL_EMBEDDINGS_ENDPOINT` env
|
|
12
|
+
* 3. `LOCAL_ENDPOINT` env (reuse the chat endpoint when a dedicated
|
|
13
|
+
* embeddings endpoint isn't configured)
|
|
14
|
+
* Returns `undefined` when none is set — the fail-soft hinge.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveEmbeddingsEndpoint(opts?: EmbeddingsProviderOpts): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the embeddings model, honoring (in order):
|
|
19
|
+
* 1. `opts.model`
|
|
20
|
+
* 2. `LOCAL_EMBEDDINGS_MODEL` env
|
|
21
|
+
* 3. `LOCAL_MODEL` env
|
|
22
|
+
* 4. `nomic-embed-text` (sensible Ollama default)
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveEmbeddingsModel(opts?: EmbeddingsProviderOpts): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Treat empty / whitespace-only values as "unset" so the precedence chain is
|
|
3
|
+
* not shadowed by a stale `export LOCAL_EMBEDDINGS_ENDPOINT=` or a blank
|
|
4
|
+
* dashboard field — `??` alone would let `""` win over a real fallback. Also
|
|
5
|
+
* trims, avoiding `http://host /embeddings`-style trailing-space URL bugs.
|
|
6
|
+
*/
|
|
7
|
+
function clean(v) {
|
|
8
|
+
const t = v?.trim();
|
|
9
|
+
return t ? t : undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the embeddings endpoint, honoring (in order):
|
|
13
|
+
* 1. `opts.endpoint`
|
|
14
|
+
* 2. `LOCAL_EMBEDDINGS_ENDPOINT` env
|
|
15
|
+
* 3. `LOCAL_ENDPOINT` env (reuse the chat endpoint when a dedicated
|
|
16
|
+
* embeddings endpoint isn't configured)
|
|
17
|
+
* Returns `undefined` when none is set — the fail-soft hinge.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveEmbeddingsEndpoint(opts) {
|
|
20
|
+
return (clean(opts?.endpoint) ??
|
|
21
|
+
clean(process.env.LOCAL_EMBEDDINGS_ENDPOINT) ??
|
|
22
|
+
clean(process.env.LOCAL_ENDPOINT));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the embeddings model, honoring (in order):
|
|
26
|
+
* 1. `opts.model`
|
|
27
|
+
* 2. `LOCAL_EMBEDDINGS_MODEL` env
|
|
28
|
+
* 3. `LOCAL_MODEL` env
|
|
29
|
+
* 4. `nomic-embed-text` (sensible Ollama default)
|
|
30
|
+
*/
|
|
31
|
+
export function resolveEmbeddingsModel(opts) {
|
|
32
|
+
return (clean(opts?.model) ??
|
|
33
|
+
clean(process.env.LOCAL_EMBEDDINGS_MODEL) ??
|
|
34
|
+
clean(process.env.LOCAL_MODEL) ??
|
|
35
|
+
"nomic-embed-text");
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=localEndpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localEndpoints.js","sourceRoot":"","sources":["../../src/embeddings/localEndpoints.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,SAAS,KAAK,CAAC,CAAqB;IAClC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CACvC,IAA6B;IAE7B,OAAO,CACL,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;QACrB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC5C,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAClC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAA6B;IAClE,OAAO,CACL,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAClB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACzC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAC9B,kBAAkB,CACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal embeddings module — NOT an MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Turns text into vectors via an OpenAI-compatible /v1/embeddings endpoint
|
|
5
|
+
* (Ollama, MLX, mlx-embeddings, vLLM, llama.cpp, LM Studio, etc.). Every
|
|
6
|
+
* consumer is expected to fail soft: the factory returns `null` when no
|
|
7
|
+
* endpoint is configured, and `embed()` returns `null` on any failure
|
|
8
|
+
* (network / parse / non-ok / SSRF-rejected) rather than throwing — mirroring
|
|
9
|
+
* the driver `run()`-never-rejects convention.
|
|
10
|
+
*/
|
|
11
|
+
/** A provider that turns text into embedding vectors. */
|
|
12
|
+
export interface EmbeddingsProvider {
|
|
13
|
+
/**
|
|
14
|
+
* Embed a batch of texts. Returns one vector per input (in order), or `null`
|
|
15
|
+
* on ANY failure (network error, non-ok HTTP status, parse error,
|
|
16
|
+
* SSRF-rejected endpoint). Never throws.
|
|
17
|
+
*/
|
|
18
|
+
embed(texts: string[]): Promise<number[][] | null>;
|
|
19
|
+
}
|
|
20
|
+
/** Construction options for a {@link EmbeddingsProvider}. */
|
|
21
|
+
export interface EmbeddingsProviderOpts {
|
|
22
|
+
/** OpenAI-compatible base URL, e.g. `http://localhost:11434/v1`. */
|
|
23
|
+
endpoint?: string;
|
|
24
|
+
/** Model id, e.g. `nomic-embed-text`. */
|
|
25
|
+
model?: string;
|
|
26
|
+
/** Bearer token for `Authorization`. Defaults to the `ollama` placeholder. */
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
/** Injected fetch (for tests). Defaults to `globalThis.fetch`. */
|
|
29
|
+
fetchImpl?: typeof fetch;
|
|
30
|
+
/** Optional logger for fail-soft diagnostics. */
|
|
31
|
+
log?: (msg: string) => void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal embeddings module — NOT an MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Turns text into vectors via an OpenAI-compatible /v1/embeddings endpoint
|
|
5
|
+
* (Ollama, MLX, mlx-embeddings, vLLM, llama.cpp, LM Studio, etc.). Every
|
|
6
|
+
* consumer is expected to fail soft: the factory returns `null` when no
|
|
7
|
+
* endpoint is configured, and `embed()` returns `null` on any failure
|
|
8
|
+
* (network / parse / non-ok / SSRF-rejected) rather than throwing — mirroring
|
|
9
|
+
* the driver `run()`-never-rejects convention.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=types.js.map
|