@nodetool-ai/websocket 0.8.1 → 0.8.3
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/dist/.nodetool-build-stamp +1 -1
- package/dist/chat-turn-registry.d.ts +2 -1
- package/dist/chat-turn-registry.d.ts.map +1 -1
- package/dist/chat-turn-registry.js +8 -1
- package/dist/chat-turn-registry.js.map +1 -1
- package/dist/collection-api.d.ts.map +1 -1
- package/dist/collection-api.js +41 -6
- package/dist/collection-api.js.map +1 -1
- package/dist/custom-providers.d.ts.map +1 -1
- package/dist/custom-providers.js +6 -1
- package/dist/custom-providers.js.map +1 -1
- package/dist/error-traces.d.ts +56 -0
- package/dist/error-traces.d.ts.map +1 -0
- package/dist/error-traces.js +179 -0
- package/dist/error-traces.js.map +1 -0
- package/dist/example-workflows.d.ts.map +1 -1
- package/dist/example-workflows.js +6 -0
- package/dist/example-workflows.js.map +1 -1
- package/dist/fake-runtime.d.ts +41 -6
- package/dist/fake-runtime.d.ts.map +1 -1
- package/dist/fake-runtime.js +247 -16
- package/dist/fake-runtime.js.map +1 -1
- package/dist/file-api.d.ts.map +1 -1
- package/dist/file-api.js +6 -8
- package/dist/file-api.js.map +1 -1
- package/dist/generation-recovery.d.ts.map +1 -1
- package/dist/generation-recovery.js +32 -7
- package/dist/generation-recovery.js.map +1 -1
- package/dist/headless-job-runner.d.ts.map +1 -1
- package/dist/headless-job-runner.js +5 -1
- package/dist/headless-job-runner.js.map +1 -1
- package/dist/http-api.d.ts +3 -1
- package/dist/http-api.d.ts.map +1 -1
- package/dist/http-api.js +66 -9
- package/dist/http-api.js.map +1 -1
- package/dist/http-body-schemas.d.ts +2 -0
- package/dist/http-body-schemas.d.ts.map +1 -1
- package/dist/http-body-schemas.js +8 -1
- package/dist/http-body-schemas.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/interrupted-jobs.d.ts +14 -0
- package/dist/interrupted-jobs.d.ts.map +1 -0
- package/dist/interrupted-jobs.js +28 -0
- package/dist/interrupted-jobs.js.map +1 -0
- package/dist/lib/admin.d.ts +7 -0
- package/dist/lib/admin.d.ts.map +1 -0
- package/dist/lib/admin.js +20 -0
- package/dist/lib/admin.js.map +1 -0
- package/dist/lib/app-debug-service.js +1 -1
- package/dist/lib/app-debug-service.js.map +1 -1
- package/dist/lib/app-instances-service.d.ts +1319 -0
- package/dist/lib/app-instances-service.d.ts.map +1 -0
- package/dist/lib/app-instances-service.js +377 -0
- package/dist/lib/app-instances-service.js.map +1 -0
- package/dist/lib/app-project-export.d.ts +12 -0
- package/dist/lib/app-project-export.d.ts.map +1 -0
- package/dist/lib/app-project-export.js +42 -0
- package/dist/lib/app-project-export.js.map +1 -0
- package/dist/lib/app-run-cancellation.d.ts +4 -0
- package/dist/lib/app-run-cancellation.d.ts.map +1 -0
- package/dist/lib/app-run-cancellation.js +28 -0
- package/dist/lib/app-run-cancellation.js.map +1 -0
- package/dist/lib/applications-service.d.ts +182 -1
- package/dist/lib/applications-service.d.ts.map +1 -1
- package/dist/lib/applications-service.js +27 -6
- package/dist/lib/applications-service.js.map +1 -1
- package/dist/lib/asset-export.d.ts +6 -2
- package/dist/lib/asset-export.d.ts.map +1 -1
- package/dist/lib/asset-export.js +15 -7
- package/dist/lib/asset-export.js.map +1 -1
- package/dist/lib/asset-paths.d.ts +7 -11
- package/dist/lib/asset-paths.d.ts.map +1 -1
- package/dist/lib/asset-paths.js +8 -56
- package/dist/lib/asset-paths.js.map +1 -1
- package/dist/lib/asset-response.d.ts.map +1 -1
- package/dist/lib/asset-response.js +3 -1
- package/dist/lib/asset-response.js.map +1 -1
- package/dist/lib/audio-peaks.d.ts.map +1 -1
- package/dist/lib/audio-peaks.js +5 -1
- package/dist/lib/audio-peaks.js.map +1 -1
- package/dist/lib/bridge.d.ts.map +1 -1
- package/dist/lib/bridge.js.map +1 -1
- package/dist/lib/cloud-profile.d.ts +10 -0
- package/dist/lib/cloud-profile.d.ts.map +1 -0
- package/dist/lib/cloud-profile.js +13 -0
- package/dist/lib/cloud-profile.js.map +1 -0
- package/dist/lib/document-model-interfaces.d.ts.map +1 -1
- package/dist/lib/document-model-interfaces.js +9 -8
- package/dist/lib/document-model-interfaces.js.map +1 -1
- package/dist/lib/example-apps.d.ts +9 -0
- package/dist/lib/example-apps.d.ts.map +1 -1
- package/dist/lib/example-apps.js +61 -14
- package/dist/lib/example-apps.js.map +1 -1
- package/dist/lib/http-tracing.d.ts +12 -0
- package/dist/lib/http-tracing.d.ts.map +1 -0
- package/dist/lib/http-tracing.js +81 -0
- package/dist/lib/http-tracing.js.map +1 -0
- package/dist/lib/http-user-id.d.ts +2 -0
- package/dist/lib/http-user-id.d.ts.map +1 -0
- package/dist/lib/http-user-id.js +4 -0
- package/dist/lib/http-user-id.js.map +1 -0
- package/dist/lib/json-body.d.ts +11 -0
- package/dist/lib/json-body.d.ts.map +1 -0
- package/dist/lib/json-body.js +13 -0
- package/dist/lib/json-body.js.map +1 -0
- package/dist/lib/media.d.ts +1 -6
- package/dist/lib/media.d.ts.map +1 -1
- package/dist/lib/media.js +8 -44
- package/dist/lib/media.js.map +1 -1
- package/dist/lib/public-routes.d.ts +22 -0
- package/dist/lib/public-routes.d.ts.map +1 -1
- package/dist/lib/public-routes.js +41 -0
- package/dist/lib/public-routes.js.map +1 -1
- package/dist/lib/public-workflow-share.d.ts +31 -0
- package/dist/lib/public-workflow-share.d.ts.map +1 -0
- package/dist/lib/public-workflow-share.js +88 -0
- package/dist/lib/public-workflow-share.js.map +1 -0
- package/dist/lib/python-metadata-roots.d.ts +27 -0
- package/dist/lib/python-metadata-roots.d.ts.map +1 -0
- package/dist/lib/python-metadata-roots.js +92 -0
- package/dist/lib/python-metadata-roots.js.map +1 -0
- package/dist/lib/run-trace-live-delivery.d.ts +25 -0
- package/dist/lib/run-trace-live-delivery.d.ts.map +1 -0
- package/dist/lib/run-trace-live-delivery.js +91 -0
- package/dist/lib/run-trace-live-delivery.js.map +1 -0
- package/dist/lib/runtime-detection.d.ts +1 -1
- package/dist/lib/runtime-detection.d.ts.map +1 -1
- package/dist/lib/runtime-detection.js +2 -1
- package/dist/lib/runtime-detection.js.map +1 -1
- package/dist/lib/server-auth-token.d.ts +18 -0
- package/dist/lib/server-auth-token.d.ts.map +1 -0
- package/dist/lib/server-auth-token.js +28 -0
- package/dist/lib/server-auth-token.js.map +1 -0
- package/dist/lib/test-ui-run-routes.d.ts +8 -0
- package/dist/lib/test-ui-run-routes.d.ts.map +1 -0
- package/dist/lib/test-ui-run-routes.js +42 -0
- package/dist/lib/test-ui-run-routes.js.map +1 -0
- package/dist/lib/thumbnail.d.ts.map +1 -1
- package/dist/lib/thumbnail.js +12 -9
- package/dist/lib/thumbnail.js.map +1 -1
- package/dist/lib/timeline-bundle.d.ts +159 -16
- package/dist/lib/timeline-bundle.d.ts.map +1 -1
- package/dist/lib/timeline-bundle.js +34 -6
- package/dist/lib/timeline-bundle.js.map +1 -1
- package/dist/lib/timeline-media-export.d.ts +18 -0
- package/dist/lib/timeline-media-export.d.ts.map +1 -0
- package/dist/lib/timeline-media-export.js +66 -0
- package/dist/lib/timeline-media-export.js.map +1 -0
- package/dist/lib/timeline-premiere-import.d.ts +24 -0
- package/dist/lib/timeline-premiere-import.d.ts.map +1 -0
- package/dist/lib/timeline-premiere-import.js +102 -0
- package/dist/lib/timeline-premiere-import.js.map +1 -0
- package/dist/lib/timeline-premiere.d.ts +38 -0
- package/dist/lib/timeline-premiere.d.ts.map +1 -0
- package/dist/lib/timeline-premiere.js +87 -0
- package/dist/lib/timeline-premiere.js.map +1 -0
- package/dist/lib/video-proxy.d.ts.map +1 -1
- package/dist/lib/video-proxy.js +3 -2
- package/dist/lib/video-proxy.js.map +1 -1
- package/dist/lib/workflow-service.d.ts.map +1 -1
- package/dist/lib/workflow-service.js +4 -1
- package/dist/lib/workflow-service.js.map +1 -1
- package/dist/mcp-agent-tools.d.ts.map +1 -1
- package/dist/mcp-agent-tools.js +95 -162
- package/dist/mcp-agent-tools.js.map +1 -1
- package/dist/mcp-client-config.d.ts +64 -0
- package/dist/mcp-client-config.d.ts.map +1 -0
- package/dist/mcp-client-config.js +353 -0
- package/dist/mcp-client-config.js.map +1 -0
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +163 -16
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp-skill-prompts.d.ts +23 -0
- package/dist/mcp-skill-prompts.d.ts.map +1 -0
- package/dist/mcp-skill-prompts.js +91 -0
- package/dist/mcp-skill-prompts.js.map +1 -0
- package/dist/mcp-tool-deps.d.ts.map +1 -1
- package/dist/mcp-tool-deps.js +8 -1
- package/dist/mcp-tool-deps.js.map +1 -1
- package/dist/models-api.d.ts +10 -0
- package/dist/models-api.d.ts.map +1 -1
- package/dist/models-api.js +29 -2
- package/dist/models-api.js.map +1 -1
- package/dist/node-registry-setup.d.ts +1 -1
- package/dist/node-registry-setup.d.ts.map +1 -1
- package/dist/node-registry-setup.js +21 -114
- package/dist/node-registry-setup.js.map +1 -1
- package/dist/oauth-api.d.ts.map +1 -1
- package/dist/oauth-api.js +45 -23
- package/dist/oauth-api.js.map +1 -1
- package/dist/openai-api.d.ts.map +1 -1
- package/dist/openai-api.js +10 -2
- package/dist/openai-api.js.map +1 -1
- package/dist/plugins/websocket.d.ts.map +1 -1
- package/dist/plugins/websocket.js +27 -59
- package/dist/plugins/websocket.js.map +1 -1
- package/dist/python-bridge-gate.d.ts +28 -0
- package/dist/python-bridge-gate.d.ts.map +1 -0
- package/dist/python-bridge-gate.js +36 -0
- package/dist/python-bridge-gate.js.map +1 -0
- package/dist/routes/app-runs.d.ts +4 -0
- package/dist/routes/app-runs.d.ts.map +1 -0
- package/dist/routes/app-runs.js +173 -0
- package/dist/routes/app-runs.js.map +1 -0
- package/dist/routes/applications.d.ts +1 -0
- package/dist/routes/applications.d.ts.map +1 -1
- package/dist/routes/applications.js +24 -0
- package/dist/routes/applications.js.map +1 -1
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +31 -41
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +6 -0
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/documents.d.ts.map +1 -1
- package/dist/routes/documents.js +24 -0
- package/dist/routes/documents.js.map +1 -1
- package/dist/routes/fal-pricing-estimate.d.ts.map +1 -1
- package/dist/routes/fal-pricing-estimate.js +2 -0
- package/dist/routes/fal-pricing-estimate.js.map +1 -1
- package/dist/routes/files.d.ts.map +1 -1
- package/dist/routes/files.js +2 -0
- package/dist/routes/files.js.map +1 -1
- package/dist/routes/games.d.ts +38 -0
- package/dist/routes/games.d.ts.map +1 -0
- package/dist/routes/games.js +158 -0
- package/dist/routes/games.js.map +1 -0
- package/dist/routes/integrations.d.ts.map +1 -1
- package/dist/routes/integrations.js +22 -26
- package/dist/routes/integrations.js.map +1 -1
- package/dist/routes/js-scripts.d.ts +10 -4
- package/dist/routes/js-scripts.d.ts.map +1 -1
- package/dist/routes/js-scripts.js +451 -69
- package/dist/routes/js-scripts.js.map +1 -1
- package/dist/routes/nodes.d.ts.map +1 -1
- package/dist/routes/nodes.js +34 -1
- package/dist/routes/nodes.js.map +1 -1
- package/dist/routes/public-shared-workflows.d.ts +16 -0
- package/dist/routes/public-shared-workflows.d.ts.map +1 -0
- package/dist/routes/public-shared-workflows.js +55 -0
- package/dist/routes/public-shared-workflows.js.map +1 -0
- package/dist/routes/run-spans.d.ts +4 -0
- package/dist/routes/run-spans.d.ts.map +1 -0
- package/dist/routes/run-spans.js +53 -0
- package/dist/routes/run-spans.js.map +1 -0
- package/dist/routes/storage.d.ts.map +1 -1
- package/dist/routes/storage.js +2 -0
- package/dist/routes/storage.js.map +1 -1
- package/dist/routes/storyboards.d.ts.map +1 -1
- package/dist/routes/storyboards.js +6 -3
- package/dist/routes/storyboards.js.map +1 -1
- package/dist/routes/timeline-fonts.d.ts +22 -0
- package/dist/routes/timeline-fonts.d.ts.map +1 -1
- package/dist/routes/timeline-fonts.js +138 -7
- package/dist/routes/timeline-fonts.js.map +1 -1
- package/dist/routes/timelines.d.ts +8 -4
- package/dist/routes/timelines.d.ts.map +1 -1
- package/dist/routes/timelines.js +209 -16
- package/dist/routes/timelines.js.map +1 -1
- package/dist/screenshot-docs-seed.d.ts +24 -0
- package/dist/screenshot-docs-seed.d.ts.map +1 -0
- package/dist/screenshot-docs-seed.js +414 -0
- package/dist/screenshot-docs-seed.js.map +1 -0
- package/dist/screenshot-projects.d.ts.map +1 -1
- package/dist/screenshot-projects.js +9 -9
- package/dist/screenshot-projects.js.map +1 -1
- package/dist/screenshot-server.js +114 -20
- package/dist/screenshot-server.js.map +1 -1
- package/dist/sdk/sdk-model-download-service.d.ts.map +1 -1
- package/dist/sdk/sdk-model-download-service.js +5 -2
- package/dist/sdk/sdk-model-download-service.js.map +1 -1
- package/dist/server.js +173 -109
- package/dist/server.js.map +1 -1
- package/dist/session/app-run-fold.d.ts +7 -0
- package/dist/session/app-run-fold.d.ts.map +1 -0
- package/dist/session/app-run-fold.js +45 -0
- package/dist/session/app-run-fold.js.map +1 -0
- package/dist/session/chat-prompt.d.ts.map +1 -1
- package/dist/session/chat-prompt.js +37 -15
- package/dist/session/chat-prompt.js.map +1 -1
- package/dist/session/chat-turn.d.ts +11 -0
- package/dist/session/chat-turn.d.ts.map +1 -1
- package/dist/session/chat-turn.js +270 -116
- package/dist/session/chat-turn.js.map +1 -1
- package/dist/session/commands.d.ts +14 -0
- package/dist/session/commands.d.ts.map +1 -1
- package/dist/session/commands.js +119 -14
- package/dist/session/commands.js.map +1 -1
- package/dist/session/inference.d.ts +30 -2
- package/dist/session/inference.d.ts.map +1 -1
- package/dist/session/inference.js +165 -16
- package/dist/session/inference.js.map +1 -1
- package/dist/session/job-execution.d.ts +7 -1
- package/dist/session/job-execution.d.ts.map +1 -1
- package/dist/session/job-execution.js +329 -42
- package/dist/session/job-execution.js.map +1 -1
- package/dist/session/model-interfaces.d.ts +2 -1
- package/dist/session/model-interfaces.d.ts.map +1 -1
- package/dist/session/model-interfaces.js +1 -0
- package/dist/session/model-interfaces.js.map +1 -1
- package/dist/storage-api.d.ts +0 -4
- package/dist/storage-api.d.ts.map +1 -1
- package/dist/storage-api.js +3 -26
- package/dist/storage-api.js.map +1 -1
- package/dist/storage-retention.d.ts +5 -0
- package/dist/storage-retention.d.ts.map +1 -1
- package/dist/storage-retention.js +22 -1
- package/dist/storage-retention.js.map +1 -1
- package/dist/test-ui-server.d.ts +11 -0
- package/dist/test-ui-server.d.ts.map +1 -1
- package/dist/test-ui-server.js +84 -6
- package/dist/test-ui-server.js.map +1 -1
- package/dist/timeline-generation-recovery.d.ts +4 -0
- package/dist/timeline-generation-recovery.d.ts.map +1 -0
- package/dist/timeline-generation-recovery.js +72 -0
- package/dist/timeline-generation-recovery.js.map +1 -0
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +26 -6
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/file-watch.d.ts.map +1 -1
- package/dist/triggers/file-watch.js +35 -19
- package/dist/triggers/file-watch.js.map +1 -1
- package/dist/triggers/scheduler.d.ts.map +1 -1
- package/dist/triggers/scheduler.js +7 -5
- package/dist/triggers/scheduler.js.map +1 -1
- package/dist/triggers/stores.js +8 -8
- package/dist/triggers/stores.js.map +1 -1
- package/dist/triggers/webhook-route.js +2 -2
- package/dist/triggers/webhook-route.js.map +1 -1
- package/dist/trpc/error-formatter.d.ts.map +1 -1
- package/dist/trpc/error-formatter.js +2 -1
- package/dist/trpc/error-formatter.js.map +1 -1
- package/dist/trpc/error-logging.d.ts +10 -0
- package/dist/trpc/error-logging.d.ts.map +1 -1
- package/dist/trpc/error-logging.js +21 -0
- package/dist/trpc/error-logging.js.map +1 -1
- package/dist/trpc/router.d.ts +100 -31028
- package/dist/trpc/router.d.ts.map +1 -1
- package/dist/trpc/router.js +12 -3
- package/dist/trpc/router.js.map +1 -1
- package/dist/trpc/routers/app-instances.d.ts +2332 -0
- package/dist/trpc/routers/app-instances.d.ts.map +1 -0
- package/dist/trpc/routers/app-instances.js +52 -0
- package/dist/trpc/routers/app-instances.js.map +1 -0
- package/dist/trpc/routers/app-runs.d.ts +1120 -0
- package/dist/trpc/routers/app-runs.d.ts.map +1 -0
- package/dist/trpc/routers/app-runs.js +28 -0
- package/dist/trpc/routers/app-runs.js.map +1 -0
- package/dist/trpc/routers/applications.d.ts +1102 -0
- package/dist/trpc/routers/applications.d.ts.map +1 -1
- package/dist/trpc/routers/applications.js +5 -2
- package/dist/trpc/routers/applications.js.map +1 -1
- package/dist/trpc/routers/assets.d.ts +18 -0
- package/dist/trpc/routers/assets.d.ts.map +1 -1
- package/dist/trpc/routers/assets.js +20 -5
- package/dist/trpc/routers/assets.js.map +1 -1
- package/dist/trpc/routers/bug-reports.d.ts +33 -0
- package/dist/trpc/routers/bug-reports.d.ts.map +1 -0
- package/dist/trpc/routers/bug-reports.js +69 -0
- package/dist/trpc/routers/bug-reports.js.map +1 -0
- package/dist/trpc/routers/collections.d.ts.map +1 -1
- package/dist/trpc/routers/collections.js +16 -10
- package/dist/trpc/routers/collections.js.map +1 -1
- package/dist/trpc/routers/credits.d.ts.map +1 -1
- package/dist/trpc/routers/credits.js +11 -1
- package/dist/trpc/routers/credits.js.map +1 -1
- package/dist/trpc/routers/documents.d.ts.map +1 -1
- package/dist/trpc/routers/documents.js +8 -2
- package/dist/trpc/routers/documents.js.map +1 -1
- package/dist/trpc/routers/error-traces.d.ts +132 -0
- package/dist/trpc/routers/error-traces.d.ts.map +1 -0
- package/dist/trpc/routers/error-traces.js +118 -0
- package/dist/trpc/routers/error-traces.js.map +1 -0
- package/dist/trpc/routers/extension.d.ts +3 -3
- package/dist/trpc/routers/extension.d.ts.map +1 -1
- package/dist/trpc/routers/extension.js +13 -9
- package/dist/trpc/routers/extension.js.map +1 -1
- package/dist/trpc/routers/gameDraftHistory.d.ts +7 -0
- package/dist/trpc/routers/gameDraftHistory.d.ts.map +1 -0
- package/dist/trpc/routers/gameDraftHistory.js +40 -0
- package/dist/trpc/routers/gameDraftHistory.js.map +1 -0
- package/dist/trpc/routers/games.d.ts +59974 -5414
- package/dist/trpc/routers/games.d.ts.map +1 -1
- package/dist/trpc/routers/games.js +531 -136
- package/dist/trpc/routers/games.js.map +1 -1
- package/dist/trpc/routers/jobs.d.ts +42 -0
- package/dist/trpc/routers/jobs.d.ts.map +1 -1
- package/dist/trpc/routers/jobs.js +89 -4
- package/dist/trpc/routers/jobs.js.map +1 -1
- package/dist/trpc/routers/js-scripts.d.ts.map +1 -1
- package/dist/trpc/routers/js-scripts.js +18 -2
- package/dist/trpc/routers/js-scripts.js.map +1 -1
- package/dist/trpc/routers/mcp-config.d.ts +3 -1
- package/dist/trpc/routers/mcp-config.d.ts.map +1 -1
- package/dist/trpc/routers/mcp-config.js +46 -208
- package/dist/trpc/routers/mcp-config.js.map +1 -1
- package/dist/trpc/routers/messages.d.ts +10 -0
- package/dist/trpc/routers/messages.d.ts.map +1 -1
- package/dist/trpc/routers/messages.js +16 -2
- package/dist/trpc/routers/messages.js.map +1 -1
- package/dist/trpc/routers/models.d.ts +130 -0
- package/dist/trpc/routers/models.d.ts.map +1 -1
- package/dist/trpc/routers/models.js +119 -61
- package/dist/trpc/routers/models.js.map +1 -1
- package/dist/trpc/routers/packs.d.ts.map +1 -1
- package/dist/trpc/routers/packs.js +18 -4
- package/dist/trpc/routers/packs.js.map +1 -1
- package/dist/trpc/routers/projects.d.ts +66 -2
- package/dist/trpc/routers/projects.d.ts.map +1 -1
- package/dist/trpc/routers/projects.js +19 -2
- package/dist/trpc/routers/projects.js.map +1 -1
- package/dist/trpc/routers/runs.d.ts +472 -0
- package/dist/trpc/routers/runs.d.ts.map +1 -0
- package/dist/trpc/routers/runs.js +40 -0
- package/dist/trpc/routers/runs.js.map +1 -0
- package/dist/trpc/routers/settings.d.ts +3 -0
- package/dist/trpc/routers/settings.d.ts.map +1 -1
- package/dist/trpc/routers/settings.js +32 -5
- package/dist/trpc/routers/settings.js.map +1 -1
- package/dist/trpc/routers/sketch.d.ts +44 -0
- package/dist/trpc/routers/sketch.d.ts.map +1 -1
- package/dist/trpc/routers/sketch.js +2 -2
- package/dist/trpc/routers/sketch.js.map +1 -1
- package/dist/trpc/routers/storyboards.d.ts +903 -1
- package/dist/trpc/routers/storyboards.d.ts.map +1 -1
- package/dist/trpc/routers/storyboards.js +8 -5
- package/dist/trpc/routers/storyboards.js.map +1 -1
- package/dist/trpc/routers/threads.d.ts.map +1 -1
- package/dist/trpc/routers/threads.js +8 -2
- package/dist/trpc/routers/threads.js.map +1 -1
- package/dist/trpc/routers/timeline.d.ts +647 -63
- package/dist/trpc/routers/timeline.d.ts.map +1 -1
- package/dist/trpc/routers/timeline.js +193 -4
- package/dist/trpc/routers/timeline.js.map +1 -1
- package/dist/trpc/routers/triggers.d.ts.map +1 -1
- package/dist/trpc/routers/triggers.js +18 -3
- package/dist/trpc/routers/triggers.js.map +1 -1
- package/dist/trpc/routers/users.d.ts +3 -2
- package/dist/trpc/routers/users.d.ts.map +1 -1
- package/dist/trpc/routers/users.js +25 -27
- package/dist/trpc/routers/users.js.map +1 -1
- package/dist/trpc/routers/worker.d.ts +10 -9
- package/dist/trpc/routers/worker.d.ts.map +1 -1
- package/dist/trpc/routers/worker.js +40 -16
- package/dist/trpc/routers/worker.js.map +1 -1
- package/dist/trpc/routers/workflows.d.ts +202 -3
- package/dist/trpc/routers/workflows.d.ts.map +1 -1
- package/dist/trpc/routers/workflows.js +72 -12
- package/dist/trpc/routers/workflows.js.map +1 -1
- package/dist/trpc/sandbox-coverage.d.ts.map +1 -1
- package/dist/trpc/sandbox-coverage.js +119 -0
- package/dist/trpc/sandbox-coverage.js.map +1 -1
- package/dist/websocket-client-session.d.ts +4 -2
- package/dist/websocket-client-session.d.ts.map +1 -1
- package/dist/websocket-client-session.js +23 -3
- package/dist/websocket-client-session.js.map +1 -1
- package/dist/worker-settings-env.d.ts +23 -0
- package/dist/worker-settings-env.d.ts.map +1 -0
- package/dist/worker-settings-env.js +47 -0
- package/dist/worker-settings-env.js.map +1 -0
- package/dist/workflow-interface-service.d.ts +7 -0
- package/dist/workflow-interface-service.d.ts.map +1 -1
- package/package.json +58 -41
- package/dist/extension-cdp-bridge.d.ts +0 -85
- package/dist/extension-cdp-bridge.d.ts.map +0 -1
- package/dist/extension-cdp-bridge.js +0 -163
- package/dist/extension-cdp-bridge.js.map +0 -1
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { registerChatRunTrace, registerWorkflowRunTrace, withRegisteredRunTrace, settleRegisteredRunTrace } from "@nodetool-ai/execution";
|
|
2
|
+
import { getRunTraceScope, suppressRunTraceContent } from "@nodetool-ai/runtime";
|
|
3
|
+
import { TRACE_RESTRICTED_CAPABILITY_MODULES, isFullResourceId } from "@nodetool-ai/protocol";
|
|
4
|
+
import { trace, SpanStatusCode } from "@opentelemetry/api";
|
|
5
|
+
import { settleRunTrace, registerRunTraceParent, registerRunTraceParents, threadHasTraceContentTools } from "@nodetool-ai/models";
|
|
6
|
+
import { capabilityModuleOf, listCapabilitySpecs } from "@nodetool-ai/agents";
|
|
1
7
|
import { createLogger } from "@nodetool-ai/config";
|
|
2
8
|
import { randomUUID } from "node:crypto";
|
|
3
9
|
import { SUPERSEDED_TOOL_RESULT, repairOrphanedToolCalls } from "../chat-tool-call-repair.js";
|
|
4
10
|
import { attachChatPredictionForwarder } from "../chat-prediction-forwarder.js";
|
|
11
|
+
import { admitSpend } from "../credit-gate.js";
|
|
5
12
|
import { isGoogleWorkspaceEnabled } from "@nodetool-ai/config";
|
|
6
13
|
import { isFunctionValue, isNonEmptyString, isNumber, isObjectLike, isRecord, isString } from "../lib/wire-values.js";
|
|
7
14
|
import { storeAssetWithThumbnail } from "../lib/thumbnail.js";
|
|
@@ -13,7 +20,7 @@ import { ACTIVE_MODEL_CONTEXT_KEY, DIRECT_TOOL_NAMES, RUN_BUDGET_CONTEXT_KEY, cr
|
|
|
13
20
|
import { isModelSelection, PROVIDER_IDS, NO_MODEL_SELECTED_MESSAGE, noMediaModelSelectedMessage } from "@nodetool-ai/protocol";
|
|
14
21
|
import { Tool, compactAssetUris, compactResourceIds } from "@nodetool-ai/agents";
|
|
15
22
|
import { createChatCodeActSession, createSandboxClock, sandboxPackagesForChat, CODEACT_RESIDENT_TOOL_NAMES, EXECUTE_CODE_TOOL_NAME } from "@nodetool-ai/agents";
|
|
16
|
-
import {
|
|
23
|
+
import { availableBuiltinToolNames, GOOGLE_WORKSPACE_TOOL_NAMES, APIFY_TOOL_NAMES, SERPAPI_TOOL_NAMES, capabilityForName, capabilityProviderTool, getAllMcpCapabilitySpecs, toolFromCapability, capabilityFromTool, createCapabilityRun, contextSecretAvailability, BackgroundSubtaskRegistry, PERMISSION_GATE_CONTEXT_KEY, GAME_ASSET_NODE_RUNNER_CONTEXT_KEY, extractInjectableImages, registerTemporaryImageHandle } from "@nodetool-ai/agents";
|
|
17
24
|
import { mcpToolHostDeps } from "../mcp-tool-deps.js";
|
|
18
25
|
import { externalMcpToolsFor } from "../external-mcp.js";
|
|
19
26
|
import { formatSkillCatalogForPrompt, mergeSystemSkills, formatMemoriesForPrompt } from "@nodetool-ai/agents";
|
|
@@ -25,7 +32,41 @@ import { getSetting } from "../settings-registry.js";
|
|
|
25
32
|
import { appendContextToLastUser, createWorkflowResponseContent, dbMessageToProviderMessage, extractTextContent, historySinceCompaction, invokedSkillsSection, toolResultDisplayText } from "./chat-history.js";
|
|
26
33
|
import { chooseCompactionCut, compactionThreshold, COMPACTION_SUMMARY_MAX_TOKENS, holdsTranscriptServerSide, readCompactionSettings, summarizeForCompaction } from "./chat-compaction.js";
|
|
27
34
|
import { createRelayActivityWaiter, DEFAULT_RUN_JOB_EXECUTION_OPTIONS } from "./job-execution.js";
|
|
35
|
+
function restrictedTraceToolNames() {
|
|
36
|
+
const modules = new Set(TRACE_RESTRICTED_CAPABILITY_MODULES);
|
|
37
|
+
return listCapabilitySpecs().filter((spec) => modules.has(capabilityModuleOf(spec.name) ?? "")).map((spec) => spec.name);
|
|
38
|
+
}
|
|
39
|
+
function seedStoredToolProvenance(messages) {
|
|
40
|
+
for (const message of messages) {
|
|
41
|
+
const names = message.name ? [message.name] : [];
|
|
42
|
+
if (isCompactionMessage(message)) {
|
|
43
|
+
names.push(...(message.tools ?? []));
|
|
44
|
+
}
|
|
45
|
+
for (const call of message.tool_calls ?? []) {
|
|
46
|
+
if (!isRecord(call)) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (isString(call.name)) {
|
|
50
|
+
names.push(call.name);
|
|
51
|
+
}
|
|
52
|
+
if (isRecord(call.function) && isString(call.function.name)) {
|
|
53
|
+
names.push(call.function.name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const name of names) {
|
|
57
|
+
const moduleName = capabilityModuleOf(name);
|
|
58
|
+
if (moduleName === "email" || moduleName === "google" || moduleName === "browser") {
|
|
59
|
+
suppressRunTraceContent();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
28
64
|
const log = createLogger("nodetool.websocket.runner");
|
|
65
|
+
/** Providers whose credential is an account sign-in, not an API key. */
|
|
66
|
+
const SIGN_IN_PROVIDER_LABELS = {
|
|
67
|
+
[PROVIDER_IDS.CODEX]: "Codex",
|
|
68
|
+
[PROVIDER_IDS.CLAUDE_AGENT_SDK]: "Claude"
|
|
69
|
+
};
|
|
29
70
|
const GENERIC_CHAT_ERROR = "Something went wrong while processing your request. Please try again.";
|
|
30
71
|
/**
|
|
31
72
|
* Keep implementation details out of the client error envelope. Provider
|
|
@@ -105,24 +146,20 @@ function providerFailureMessage(error, providerId, model) {
|
|
|
105
146
|
const gemini = geminiFailureSummary(error, providerId);
|
|
106
147
|
const groq = groqRequestFailureMessage(error);
|
|
107
148
|
const status = httpStatusFromError(error) ?? gemini?.status ?? null;
|
|
149
|
+
const statusCode = status ?? undefined;
|
|
108
150
|
const rawMessage = groq ?? gemini?.message ?? safeClientErrorText(error);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const safe = safeClientErrorText(bodyError.message);
|
|
116
|
-
bodyMessage = safe === GENERIC_CHAT_ERROR ? null : safe;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
151
|
+
const body = isObjectLike(error) ? (error.body ?? error.response) : undefined;
|
|
152
|
+
const bodyError = isObjectLike(body) && isObjectLike(body.error) ? body.error : body;
|
|
153
|
+
const bodyText = isObjectLike(bodyError) && isString(bodyError.message)
|
|
154
|
+
? safeClientErrorText(bodyError.message)
|
|
155
|
+
: null;
|
|
156
|
+
const bodyMessage = bodyText === GENERIC_CHAT_ERROR ? null : bodyText;
|
|
120
157
|
if (providerId.toLowerCase() === "openai" &&
|
|
121
158
|
/\borganization must be verified\b/i.test(bodyMessage ?? rawMessage)) {
|
|
122
159
|
return {
|
|
123
160
|
errorType: status === null ? "error" : "http_status_error",
|
|
124
161
|
message: "This model requires a verified OpenAI organization. Verify your provider organization or choose a model your account can access.",
|
|
125
|
-
statusCode
|
|
162
|
+
statusCode
|
|
126
163
|
};
|
|
127
164
|
}
|
|
128
165
|
const detail = providerFailureDetail(error);
|
|
@@ -131,28 +168,31 @@ function providerFailureMessage(error, providerId, model) {
|
|
|
131
168
|
return {
|
|
132
169
|
errorType: "error",
|
|
133
170
|
message: `The ${target} request is too large for the model context window. Shorten the conversation or remove some attachments and try again.`,
|
|
134
|
-
statusCode
|
|
171
|
+
statusCode
|
|
135
172
|
};
|
|
136
173
|
}
|
|
137
174
|
if (detail?.code === "provider_auth") {
|
|
175
|
+
const signIn = SIGN_IN_PROVIDER_LABELS[detail.provider];
|
|
176
|
+
const remedy = signIn ? `Sign in to ${signIn} again` : "Check the API key";
|
|
138
177
|
return {
|
|
139
178
|
errorType: "error",
|
|
140
|
-
message: `Authentication failed: ${detail.provider} rejected the configured credentials.
|
|
141
|
-
statusCode
|
|
179
|
+
message: `Authentication failed: ${detail.provider} rejected the configured credentials. ${remedy} in Settings → Models & Providers.`,
|
|
180
|
+
statusCode
|
|
142
181
|
};
|
|
143
182
|
}
|
|
144
183
|
if (status === null) {
|
|
145
|
-
return { errorType: "error", message: rawMessage, statusCode
|
|
184
|
+
return { errorType: "error", message: rawMessage, statusCode };
|
|
146
185
|
}
|
|
147
|
-
|
|
186
|
+
const modelName = model || "requested";
|
|
187
|
+
let message;
|
|
148
188
|
if (gemini?.kind === "quota") {
|
|
149
189
|
message = `Account quota exhausted for ${providerId}/${model}. Check your ${providerId} quota or billing and try again later.`;
|
|
150
190
|
}
|
|
151
191
|
else if (gemini?.kind === "model") {
|
|
152
|
-
message = `Model ${
|
|
192
|
+
message = `Model ${modelName} is unavailable on ${providerId}. Choose another model or check that your account has access to it.`;
|
|
153
193
|
}
|
|
154
194
|
else if (gemini?.kind === "tools") {
|
|
155
|
-
message = `Model ${
|
|
195
|
+
message = `Model ${modelName} does not support the requested tools on ${providerId}. Choose a model with tool support or disable tools.`;
|
|
156
196
|
}
|
|
157
197
|
else if (status === 400) {
|
|
158
198
|
message = `Bad request: ${groq ?? bodyMessage ?? rawMessage}`;
|
|
@@ -168,20 +208,20 @@ function providerFailureMessage(error, providerId, model) {
|
|
|
168
208
|
"Access forbidden: You don't have permission for this resource. Check the provider key's model and account access.";
|
|
169
209
|
}
|
|
170
210
|
else if (status === 404) {
|
|
171
|
-
message = `Model ${
|
|
211
|
+
message = `Model ${modelName} was not found or is unavailable on ${providerId}. Choose another model or check account access.`;
|
|
172
212
|
}
|
|
173
213
|
else if (status === 413) {
|
|
174
|
-
const
|
|
214
|
+
const bodyDetail = bodyMessage ?? rawMessage;
|
|
175
215
|
message =
|
|
176
216
|
groq ??
|
|
177
|
-
(
|
|
217
|
+
(bodyDetail === GENERIC_CHAT_ERROR
|
|
178
218
|
? "Request is too large for the provider. Shorten the conversation or remove some attachments and try again."
|
|
179
|
-
: `Request is too large for the provider (${
|
|
219
|
+
: `Request is too large for the provider (${bodyDetail}). Shorten the conversation or remove some attachments and try again.`);
|
|
180
220
|
}
|
|
181
221
|
else if (status === 429) {
|
|
182
|
-
message =
|
|
183
|
-
|
|
184
|
-
|
|
222
|
+
message =
|
|
223
|
+
groq ??
|
|
224
|
+
"Rate limited: Too many requests or insufficient provider quota. Check your provider plan and try again later.";
|
|
185
225
|
}
|
|
186
226
|
else if (status >= 500) {
|
|
187
227
|
message =
|
|
@@ -192,7 +232,7 @@ function providerFailureMessage(error, providerId, model) {
|
|
|
192
232
|
else {
|
|
193
233
|
message = `HTTP error (${status}): ${rawMessage}`;
|
|
194
234
|
}
|
|
195
|
-
return { errorType: "http_status_error", message, statusCode
|
|
235
|
+
return { errorType: "http_status_error", message, statusCode };
|
|
196
236
|
}
|
|
197
237
|
/**
|
|
198
238
|
* How many of a user's newest memories the turn reads to build its block. The
|
|
@@ -209,6 +249,27 @@ const MEMORY_BLOCK_LIMIT = 100;
|
|
|
209
249
|
* full thread load.
|
|
210
250
|
*/
|
|
211
251
|
const SESSION_PROBE_WINDOW = 50;
|
|
252
|
+
/** The most rows of a thread a turn loads as its history. */
|
|
253
|
+
const THREAD_HISTORY_LIMIT = 1000;
|
|
254
|
+
/**
|
|
255
|
+
* The thread's newest rows, oldest first. An ascending page would return the
|
|
256
|
+
* oldest rows instead, and a thread past the limit would then lose its latest
|
|
257
|
+
* turns, the user message just sent among them.
|
|
258
|
+
*
|
|
259
|
+
* A window cut by the limit starts at its first user row, so it never opens on
|
|
260
|
+
* a tool result whose call fell outside it.
|
|
261
|
+
*/
|
|
262
|
+
export async function loadRecentThreadRows(threadId, limit = THREAD_HISTORY_LIMIT) {
|
|
263
|
+
const [newestFirst] = await Message.paginate(threadId, {
|
|
264
|
+
reverse: true,
|
|
265
|
+
limit
|
|
266
|
+
});
|
|
267
|
+
const rows = newestFirst.reverse();
|
|
268
|
+
if (rows.length < limit)
|
|
269
|
+
return rows;
|
|
270
|
+
const firstUser = rows.findIndex((row) => row.role === "user");
|
|
271
|
+
return firstUser > 0 ? rows.slice(firstUser) : rows;
|
|
272
|
+
}
|
|
212
273
|
/**
|
|
213
274
|
* Output-token worst case assumed when reserving a chat turn. The chat loop
|
|
214
275
|
* sends no `maxTokens`, so nothing bounds the answer from this side; the
|
|
@@ -466,6 +527,12 @@ export class ChatTurnHandler {
|
|
|
466
527
|
const existing = await Thread.find(userId, threadId);
|
|
467
528
|
if (existing)
|
|
468
529
|
return existing.id;
|
|
530
|
+
// `create` upserts on the primary key, so creating under an id another
|
|
531
|
+
// user's thread already holds would reassign that thread (and its
|
|
532
|
+
// history) to this caller.
|
|
533
|
+
if (await Thread.get(threadId)) {
|
|
534
|
+
throw new Error("Thread not found");
|
|
535
|
+
}
|
|
469
536
|
const thread = await Thread.create({
|
|
470
537
|
id: threadId,
|
|
471
538
|
user_id: userId,
|
|
@@ -479,19 +546,30 @@ export class ChatTurnHandler {
|
|
|
479
546
|
* Save a message dict to the database.
|
|
480
547
|
* Mirrors Python's _save_message_to_db_async: pops id, type, user_id before create.
|
|
481
548
|
*/
|
|
482
|
-
async saveMessageToDb(messageData) {
|
|
549
|
+
async saveMessageToDb(messageData, options = {}) {
|
|
483
550
|
const data = { ...messageData };
|
|
551
|
+
const clientId = data.id;
|
|
484
552
|
delete data.id;
|
|
485
553
|
delete data.type;
|
|
486
554
|
const threadId = isString(data.thread_id) ? data.thread_id : "";
|
|
487
555
|
delete data.thread_id;
|
|
488
556
|
const userId = this.session.requireUserId();
|
|
489
557
|
delete data.user_id;
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
558
|
+
// The user's own turn keeps the id the client minted for it, so the client
|
|
559
|
+
// can name that turn later (Regenerate, edit a sent message) without a
|
|
560
|
+
// round-trip. Anything that is not a fresh 32-hex id is replaced.
|
|
561
|
+
if (options.keepClientId &&
|
|
562
|
+
isString(clientId) &&
|
|
563
|
+
isFullResourceId(clientId) &&
|
|
564
|
+
!(await Message.find(clientId))) {
|
|
565
|
+
data.id = clientId;
|
|
566
|
+
}
|
|
567
|
+
const message = await Message.create({ thread_id: threadId, user_id: userId, ...data });
|
|
568
|
+
const scope = getRunTraceScope();
|
|
569
|
+
if (scope) {
|
|
570
|
+
await registerRunTraceParent(userId, scope.runId, { kind: "message", id: message.id });
|
|
571
|
+
}
|
|
572
|
+
return message;
|
|
495
573
|
}
|
|
496
574
|
/**
|
|
497
575
|
* Persist raw image bytes carried on an assistant message (native providers
|
|
@@ -923,6 +1001,7 @@ export class ChatTurnHandler {
|
|
|
923
1001
|
: null,
|
|
924
1002
|
assetOutputMode: this.session.mode === "text" ? "data_uri" : "temp_url"
|
|
925
1003
|
});
|
|
1004
|
+
context.runTraceContext = getRunTraceScope() ?? null;
|
|
926
1005
|
// This context is built here rather than copied from the turn, so the
|
|
927
1006
|
// turn's gate has to be put on it by hand. The node's own loops read it
|
|
928
1007
|
// with `gateFromContext`; a node run outside a chat turn carries none and
|
|
@@ -1042,10 +1121,33 @@ export class ChatTurnHandler {
|
|
|
1042
1121
|
const userId = this.session.requireUserId();
|
|
1043
1122
|
log.debug("Chat message", { threadId, model, provider: providerId });
|
|
1044
1123
|
// Save user message to DB — matches Python's _save_message_to_db_async(data)
|
|
1045
|
-
const turnMessage = await this.saveMessageToDb(data);
|
|
1124
|
+
const turnMessage = await this.saveMessageToDb(data, { keepClientId: true });
|
|
1125
|
+
const rootContext = createRuntimeContext({ jobId: turnMessage.id, threadId, workflowId, userId, workspace: null });
|
|
1126
|
+
await registerChatRunTrace(rootContext, { messageId: turnMessage.id, threadId });
|
|
1127
|
+
return withRegisteredRunTrace(rootContext, "chat.turn", async () => {
|
|
1128
|
+
try {
|
|
1129
|
+
if (await threadHasTraceContentTools(userId, threadId, restrictedTraceToolNames())) {
|
|
1130
|
+
suppressRunTraceContent();
|
|
1131
|
+
}
|
|
1132
|
+
await this.handlePersistedChatTurn(data, turnMessage, rootContext, requestSeq, signal);
|
|
1133
|
+
await settleRegisteredRunTrace(rootContext, signal?.aborted ? "cancelled" : "completed");
|
|
1134
|
+
}
|
|
1135
|
+
catch (error) {
|
|
1136
|
+
await settleRegisteredRunTrace(rootContext, signal?.aborted ? "cancelled" : "failed", error instanceof Error ? error.message : String(error));
|
|
1137
|
+
throw error;
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
async handlePersistedChatTurn(data, turnMessage, rootContext, requestSeq, signal) {
|
|
1142
|
+
const threadId = String(data.thread_id);
|
|
1143
|
+
const workflowId = isString(data.workflow_id) ? data.workflow_id : null;
|
|
1144
|
+
const userId = this.session.requireUserId();
|
|
1145
|
+
const providerId = String(data.provider);
|
|
1146
|
+
const model = String(data.model);
|
|
1046
1147
|
if (requestSeq !== undefined && requestSeq !== this.chatRequestSeq)
|
|
1047
1148
|
return;
|
|
1048
1149
|
if (!this.session.resolveProvider) {
|
|
1150
|
+
await settleRegisteredRunTrace(rootContext, "failed", "No provider resolver configured");
|
|
1049
1151
|
await this.session.send({
|
|
1050
1152
|
type: "error",
|
|
1051
1153
|
message: "No provider resolver configured",
|
|
@@ -1053,6 +1155,21 @@ export class ChatTurnHandler {
|
|
|
1053
1155
|
});
|
|
1054
1156
|
return;
|
|
1055
1157
|
}
|
|
1158
|
+
// The managed provider spends NodeTool's own keys against the user's
|
|
1159
|
+
// credits. Every other managed entry point admits against the balance and
|
|
1160
|
+
// the operator's model whitelist first, and so does a chat turn.
|
|
1161
|
+
if (providerId === "nodetool") {
|
|
1162
|
+
const decision = await admitSpend(userId, 0, [model]);
|
|
1163
|
+
if (!decision.allowed) {
|
|
1164
|
+
await settleRegisteredRunTrace(rootContext, "failed", decision.reason);
|
|
1165
|
+
await this.session.send({
|
|
1166
|
+
type: "error",
|
|
1167
|
+
message: decision.reason,
|
|
1168
|
+
thread_id: threadId
|
|
1169
|
+
});
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1056
1173
|
// Route to the workflow processor ONLY when the client explicitly opts in
|
|
1057
1174
|
// via `workflow_target: "workflow"`. A bare `workflow_id` is context, not a
|
|
1058
1175
|
// routing signal: the editor binds the open workflow so `ui_*` tools target
|
|
@@ -1063,7 +1180,7 @@ export class ChatTurnHandler {
|
|
|
1063
1180
|
? data.workflow_target
|
|
1064
1181
|
: null;
|
|
1065
1182
|
if (workflowTarget === "workflow") {
|
|
1066
|
-
await this.handleWorkflowMessage(data, requestSeq, signal);
|
|
1183
|
+
await this.handleWorkflowMessage(data, turnMessage.id, requestSeq, signal);
|
|
1067
1184
|
return;
|
|
1068
1185
|
}
|
|
1069
1186
|
// Route to media generation when the client requests a text-to-image or
|
|
@@ -1134,9 +1251,12 @@ export class ChatTurnHandler {
|
|
|
1134
1251
|
toolCalls: null,
|
|
1135
1252
|
threadId: null
|
|
1136
1253
|
});
|
|
1254
|
+
const copiedMessageIds = new Set();
|
|
1137
1255
|
const convertDbMessages = (rows) => {
|
|
1138
1256
|
const out = [];
|
|
1139
1257
|
for (const m of rows) {
|
|
1258
|
+
copiedMessageIds.add(m.id);
|
|
1259
|
+
seedStoredToolProvenance([m]);
|
|
1140
1260
|
const pm = dbMessageToProviderMessage(m, this.session.userId);
|
|
1141
1261
|
if (pm)
|
|
1142
1262
|
out.push(pm);
|
|
@@ -1160,6 +1280,7 @@ export class ChatTurnHandler {
|
|
|
1160
1280
|
reverse: true,
|
|
1161
1281
|
limit: SESSION_PROBE_WINDOW
|
|
1162
1282
|
});
|
|
1283
|
+
seedStoredToolProvenance(recent);
|
|
1163
1284
|
const probeHasWholeThread = recent.length < SESSION_PROBE_WINDOW;
|
|
1164
1285
|
// `recent` is newest-first. Walk to the first boundary marker: an
|
|
1165
1286
|
// assistant carrying a session token, or a compaction record. Both claim
|
|
@@ -1209,14 +1330,21 @@ export class ChatTurnHandler {
|
|
|
1209
1330
|
systemHash: probeSession.systemHash,
|
|
1210
1331
|
checkpoint: 1
|
|
1211
1332
|
};
|
|
1333
|
+
if (probeSession.traceContentSuppressed) {
|
|
1334
|
+
priorSession.traceContentSuppressed = true;
|
|
1335
|
+
}
|
|
1212
1336
|
// Absolute position to persist: prior prefix + the prior assistant + the
|
|
1213
1337
|
// new turns — identical to what the full-load path would store.
|
|
1214
1338
|
sessionCheckpointOverride =
|
|
1215
1339
|
probeSession.checkpoint + 1 + newTurns.length;
|
|
1216
1340
|
loadFullHistory = async () => {
|
|
1217
|
-
const
|
|
1341
|
+
const rows = await loadRecentThreadRows(threadId);
|
|
1218
1342
|
const full = convertDbMessages(historySinceCompaction(rows));
|
|
1219
1343
|
full.unshift(systemChatMessage());
|
|
1344
|
+
const scope = getRunTraceScope();
|
|
1345
|
+
if (scope) {
|
|
1346
|
+
await registerRunTraceParents(userId, scope.runId, [...copiedMessageIds].map((id) => ({ kind: "message", id })));
|
|
1347
|
+
}
|
|
1220
1348
|
return full;
|
|
1221
1349
|
};
|
|
1222
1350
|
}
|
|
@@ -1231,12 +1359,15 @@ export class ChatTurnHandler {
|
|
|
1231
1359
|
// all (a far-back session still resumes via the slice path). A session
|
|
1232
1360
|
// older than the compaction cut is not one of them: searching only the
|
|
1233
1361
|
// compacted slice is what keeps the newest marker winning here too.
|
|
1234
|
-
const
|
|
1362
|
+
const rows = await loadRecentThreadRows(threadId);
|
|
1235
1363
|
const kept = historySinceCompaction(rows);
|
|
1236
1364
|
chatHistory = convertDbMessages(kept);
|
|
1237
1365
|
priorSession = lastMatchingProviderSession(kept, providerId, model);
|
|
1238
1366
|
}
|
|
1239
1367
|
}
|
|
1368
|
+
if (priorSession?.traceContentSuppressed) {
|
|
1369
|
+
suppressRunTraceContent();
|
|
1370
|
+
}
|
|
1240
1371
|
// Expose the read-only `run_search` fan-out primitive by default. A client
|
|
1241
1372
|
// can opt out by sending `enable_read_only_search: false`.
|
|
1242
1373
|
const enableReadOnlySearch = data.enable_read_only_search !== false;
|
|
@@ -1286,13 +1417,6 @@ export class ChatTurnHandler {
|
|
|
1286
1417
|
// it starts (invariant I-2). A loop that made its own would hand every
|
|
1287
1418
|
// nested agent a fresh allowance, which is no ceiling at all.
|
|
1288
1419
|
const turnBudget = await createChatTurnBudget();
|
|
1289
|
-
const gatedRun = (context) => createCapabilityRun({
|
|
1290
|
-
context,
|
|
1291
|
-
gate: chatGate,
|
|
1292
|
-
projectId: chatProjectId,
|
|
1293
|
-
availableSecrets: contextSecretAvailability(context),
|
|
1294
|
-
budget: turnBudget
|
|
1295
|
-
});
|
|
1296
1420
|
// The user's external MCP servers (Blender, Hugging Face, …). Their tools
|
|
1297
1421
|
// are plain belt tools named `mcp_<server>_<tool>`, so every loop reaches
|
|
1298
1422
|
// them the same way; a server that does not answer is skipped, not fatal.
|
|
@@ -1305,40 +1429,48 @@ export class ChatTurnHandler {
|
|
|
1305
1429
|
error: err instanceof Error ? err.message : String(err)
|
|
1306
1430
|
});
|
|
1307
1431
|
}
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
...(
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
...
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
...getAllMcpTools({
|
|
1317
|
-
registry: this.session.nodeRegistry,
|
|
1318
|
-
providers: chatProviders,
|
|
1319
|
-
...mcpToolHostDeps()
|
|
1320
|
-
}),
|
|
1321
|
-
toolForCapabilityName("list_collections"),
|
|
1322
|
-
toolForCapabilityName("query_collection"),
|
|
1323
|
-
runNodeTool
|
|
1432
|
+
const legacyCapabilities = [runNodeTool, ...externalMcpTools].map(capabilityFromTool);
|
|
1433
|
+
const nativeSpecs = [
|
|
1434
|
+
...availableBuiltinToolNames().map((name) => capabilityForName(name).spec),
|
|
1435
|
+
...(googleWorkspace ? GOOGLE_WORKSPACE_TOOL_NAMES : []).map((name) => capabilityForName(name).spec),
|
|
1436
|
+
...[...APIFY_TOOL_NAMES, ...SERPAPI_TOOL_NAMES].map((name) => capabilityForName(name).spec),
|
|
1437
|
+
...getAllMcpCapabilitySpecs({ registry: this.session.nodeRegistry, providers: chatProviders }),
|
|
1438
|
+
capabilityForName("list_collections").spec,
|
|
1439
|
+
capabilityForName("query_collection").spec
|
|
1324
1440
|
];
|
|
1325
|
-
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
//
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1441
|
+
const specsByName = new Map();
|
|
1442
|
+
for (const spec of [...nativeSpecs, ...legacyCapabilities.map((entry) => entry.spec)]) {
|
|
1443
|
+
if (!specsByName.has(spec.name)) {
|
|
1444
|
+
specsByName.set(spec.name, spec);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
const baseSpecs = [...specsByName.values()];
|
|
1448
|
+
const legacyByName = new Map(legacyCapabilities.map((entry) => [entry.spec.name, entry]));
|
|
1449
|
+
// Delegated executors still consume Tool[]. Adapt only at that boundary.
|
|
1450
|
+
// Each child context owns a separate run so its memory and depth are local.
|
|
1451
|
+
const childRuns = new WeakMap();
|
|
1452
|
+
const childRun = (context) => {
|
|
1453
|
+
let run = childRuns.get(context);
|
|
1454
|
+
if (!run) {
|
|
1455
|
+
run = createCapabilityRun({
|
|
1456
|
+
context, gate: chatGate, nodeRegistry: this.session.nodeRegistry,
|
|
1457
|
+
providers: chatProviders, budget: turnBudget,
|
|
1458
|
+
availableSecrets: contextSecretAvailability(context),
|
|
1459
|
+
...mcpToolHostDeps(), capabilities: legacyCapabilities
|
|
1460
|
+
});
|
|
1461
|
+
childRuns.set(context, run);
|
|
1462
|
+
}
|
|
1463
|
+
return run;
|
|
1464
|
+
};
|
|
1465
|
+
const baseTools = baseSpecs.map((spec) => {
|
|
1466
|
+
const entry = legacyByName.get(spec.name)
|
|
1467
|
+
?? capabilityForName(spec.name);
|
|
1468
|
+
return toolFromCapability(entry.spec, entry.impl, childRun);
|
|
1469
|
+
});
|
|
1338
1470
|
// Inject the recursive-decomposition primitive (ungated — it spawns a
|
|
1339
1471
|
// child loop whose own tools are the gated `baseTools`). Child events
|
|
1340
1472
|
// stream back tagged with `parent_tool_call_id` so the UI can nest cards.
|
|
1341
|
-
const serverTools =
|
|
1473
|
+
const serverTools = baseSpecs.slice();
|
|
1342
1474
|
// The same runtime the delegation tools take, kept for the capability run
|
|
1343
1475
|
// below: provider, model, the parent belt, and the event forwarder.
|
|
1344
1476
|
let subAgentRuntime;
|
|
@@ -1384,18 +1516,9 @@ export class ChatTurnHandler {
|
|
|
1384
1516
|
// `parent_tool_call_id` / `subtask_depth` tagging are unchanged.
|
|
1385
1517
|
// `start_subtask` / `wait_subtasks` share the per-turn registry above:
|
|
1386
1518
|
// spawn returns immediately, and the parent collects on its own terms.
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
// effect of its own, and the child's tools are the gated `baseTools`.
|
|
1391
|
-
gate: UNGATED,
|
|
1392
|
-
availableSecrets: contextSecretAvailability(context),
|
|
1393
|
-
subAgent: subAgentRuntime,
|
|
1394
|
-
budget: turnBudget
|
|
1395
|
-
});
|
|
1396
|
-
serverTools.unshift(toolForCapabilityName("run_subtask", delegationRun));
|
|
1397
|
-
serverTools.unshift(toolForCapabilityName("start_subtask", delegationRun));
|
|
1398
|
-
serverTools.unshift(toolForCapabilityName("wait_subtasks", delegationRun));
|
|
1519
|
+
serverTools.unshift(capabilityForName("run_subtask").spec);
|
|
1520
|
+
serverTools.unshift(capabilityForName("start_subtask").spec);
|
|
1521
|
+
serverTools.unshift(capabilityForName("wait_subtasks").spec);
|
|
1399
1522
|
// Plan mode's own capability: `create_plan` runs the TaskPlanner over the
|
|
1400
1523
|
// objective and streams the plan into the thread, executing nothing. It
|
|
1401
1524
|
// is offered only here, because plan mode is the one place where a plan
|
|
@@ -1404,7 +1527,7 @@ export class ChatTurnHandler {
|
|
|
1404
1527
|
// mode the turn started in — `liveMode` covers a mid-turn switch for the
|
|
1405
1528
|
// gate, not for which tools were offered.
|
|
1406
1529
|
if (permissionMode === "plan") {
|
|
1407
|
-
serverTools.unshift(
|
|
1530
|
+
serverTools.unshift(capabilityForName("create_plan").spec);
|
|
1408
1531
|
}
|
|
1409
1532
|
// The other half: `execute_plan` runs a plan the user has already seen,
|
|
1410
1533
|
// on the same ParallelTaskExecutor `Agent` uses. It is on the belt in
|
|
@@ -1412,12 +1535,12 @@ export class ChatTurnHandler {
|
|
|
1412
1535
|
// `blocked_in_plan_mode`, which tells the model to have the user switch
|
|
1413
1536
|
// out, where dropping it from the belt entirely would only say the tool
|
|
1414
1537
|
// does not exist. It is *offered* everywhere but plan mode, below.
|
|
1415
|
-
serverTools.unshift(
|
|
1538
|
+
serverTools.unshift(capabilityForName("execute_plan").spec);
|
|
1416
1539
|
// Read-only fan-out search (opt-in). Reuses the same runtime — the
|
|
1417
1540
|
// capability filters the parent belt to its read-only allowlist
|
|
1418
1541
|
// internally, so passing the full snapshot is correct.
|
|
1419
1542
|
if (enableReadOnlySearch) {
|
|
1420
|
-
serverTools.unshift(
|
|
1543
|
+
serverTools.unshift(capabilityForName("run_search").spec);
|
|
1421
1544
|
}
|
|
1422
1545
|
}
|
|
1423
1546
|
const serverToolMap = new Map(serverTools.map((t) => [t.name, t]));
|
|
@@ -1426,7 +1549,7 @@ export class ChatTurnHandler {
|
|
|
1426
1549
|
permissionMode,
|
|
1427
1550
|
resolved: serverTools.map((t) => t.name)
|
|
1428
1551
|
});
|
|
1429
|
-
const serverSchemas = serverTools.map((t) => t
|
|
1552
|
+
const serverSchemas = serverTools.map((t) => capabilityProviderTool(t));
|
|
1430
1553
|
// Every client tool the connected UI registered is exposed. They used to be
|
|
1431
1554
|
// gated on an active workflow, which made the editor tools unreachable from
|
|
1432
1555
|
// plain chat; they are deferred behind `nodetool.searchTools()` anyway, and each one now
|
|
@@ -1484,7 +1607,11 @@ export class ChatTurnHandler {
|
|
|
1484
1607
|
workspace: chatWorkspace,
|
|
1485
1608
|
authToken: this.deps.authToken()
|
|
1486
1609
|
});
|
|
1610
|
+
ctx.runTraceContext = rootContext.runTraceContext;
|
|
1487
1611
|
ctx.set("chat_message_id", turnMessage.id);
|
|
1612
|
+
if (ctx.runTraceContext) {
|
|
1613
|
+
await registerRunTraceParents(userId, ctx.runTraceContext.runId, [...copiedMessageIds].map((id) => ({ kind: "message", id })));
|
|
1614
|
+
}
|
|
1488
1615
|
const detachPredictions = attachChatPredictionForwarder((listener) => ctx.addMessageListener(listener), (msg) => this.session.sendDetached(msg), { threadId: threadId || null, workflowId });
|
|
1489
1616
|
// A chat turn that generates an image or a video spends real money without
|
|
1490
1617
|
// ever constructing an ExecutionSession, so the ledger is attached here
|
|
@@ -1530,7 +1657,7 @@ export class ChatTurnHandler {
|
|
|
1530
1657
|
budget: turnBudget,
|
|
1531
1658
|
secretPrompt: (request) => this.requestSecretEntry(threadId, request),
|
|
1532
1659
|
...mcpToolHostDeps(),
|
|
1533
|
-
capabilities:
|
|
1660
|
+
capabilities: legacyCapabilities
|
|
1534
1661
|
});
|
|
1535
1662
|
const gameAssetRun = this.chatCapabilityRun;
|
|
1536
1663
|
const gameAssetNodeRunner = (args) => gameAssetRun.invoke("run_node", args);
|
|
@@ -1632,9 +1759,20 @@ export class ChatTurnHandler {
|
|
|
1632
1759
|
// What to persist onto the assistant message: the provider's token, but with
|
|
1633
1760
|
// the absolute checkpoint when the fast path sent only a delta (the
|
|
1634
1761
|
// provider's emitted checkpoint is relative to the trimmed view).
|
|
1635
|
-
const sessionForPersist = () =>
|
|
1636
|
-
|
|
1637
|
-
|
|
1762
|
+
const sessionForPersist = () => {
|
|
1763
|
+
if (!capturedSession) {
|
|
1764
|
+
return null;
|
|
1765
|
+
}
|
|
1766
|
+
const contentSuppressed = getRunTraceScope()?.policy.contentSuppressed || priorSession?.traceContentSuppressed || capturedSession.traceContentSuppressed;
|
|
1767
|
+
const persisted = { ...capturedSession };
|
|
1768
|
+
if (sessionCheckpointOverride != null) {
|
|
1769
|
+
persisted.checkpoint = sessionCheckpointOverride;
|
|
1770
|
+
}
|
|
1771
|
+
if (contentSuppressed) {
|
|
1772
|
+
persisted.traceContentSuppressed = true;
|
|
1773
|
+
}
|
|
1774
|
+
return persisted;
|
|
1775
|
+
};
|
|
1638
1776
|
// Cap on tool-calling rounds before the loop stops. Generous enough to
|
|
1639
1777
|
// build a multi-component app UI or run a long edit session in one turn —
|
|
1640
1778
|
// 10 was too low and cut off the app builder mid-build.
|
|
@@ -1715,9 +1853,14 @@ export class ChatTurnHandler {
|
|
|
1715
1853
|
}
|
|
1716
1854
|
else if (serverTool) {
|
|
1717
1855
|
try {
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1856
|
+
const args = { ...Tool.stripMessage(toolCall.args) };
|
|
1857
|
+
if (serverTool.needsToolCallId) {
|
|
1858
|
+
args["_tool_call_id"] = toolCall.id;
|
|
1859
|
+
}
|
|
1860
|
+
if (!this.chatCapabilityRun) {
|
|
1861
|
+
throw new Error("Chat capability run is unavailable");
|
|
1862
|
+
}
|
|
1863
|
+
toolResult = await this.chatCapabilityRun.invoke(serverTool.name, args);
|
|
1721
1864
|
}
|
|
1722
1865
|
catch (err) {
|
|
1723
1866
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -1973,7 +2116,7 @@ export class ChatTurnHandler {
|
|
|
1973
2116
|
* turn that cannot run at all.
|
|
1974
2117
|
*/
|
|
1975
2118
|
const compactThread = async (reason) => {
|
|
1976
|
-
const
|
|
2119
|
+
const rows = await loadRecentThreadRows(threadId);
|
|
1977
2120
|
const cut = chooseCompactionCut(historySinceCompaction(rows), compaction.keepUserTurns, {
|
|
1978
2121
|
// Leave room for the summary, turn context and subsequent replies.
|
|
1979
2122
|
maxTokens: compactionThresholdTokens * 0.75 -
|
|
@@ -2020,6 +2163,7 @@ export class ChatTurnHandler {
|
|
|
2020
2163
|
role: "user",
|
|
2021
2164
|
execution_event_type: COMPACTION_EVENT_TYPE,
|
|
2022
2165
|
content: compactionMessageContent(summary),
|
|
2166
|
+
tools: getRunTraceScope()?.policy.contentSuppressed ? restrictedTraceToolNames() : null,
|
|
2023
2167
|
created_at: Number.isFinite(boundary)
|
|
2024
2168
|
? new Date(boundary - 1).toISOString()
|
|
2025
2169
|
: cut.keep[0].created_at
|
|
@@ -2260,6 +2404,7 @@ export class ChatTurnHandler {
|
|
|
2260
2404
|
return;
|
|
2261
2405
|
}
|
|
2262
2406
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
2407
|
+
await settleRegisteredRunTrace(rootContext, "failed", errMsg);
|
|
2263
2408
|
log.error("Chat processing error", { threadId, error: errMsg });
|
|
2264
2409
|
let errorType = "error";
|
|
2265
2410
|
let statusCode;
|
|
@@ -3076,6 +3221,11 @@ export class ChatTurnHandler {
|
|
|
3076
3221
|
if (cancelled())
|
|
3077
3222
|
return;
|
|
3078
3223
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
3224
|
+
const scope = getRunTraceScope();
|
|
3225
|
+
if (scope) {
|
|
3226
|
+
trace.getActiveSpan()?.setStatus({ code: SpanStatusCode.ERROR });
|
|
3227
|
+
await settleRunTrace(userId, scope.runId, { status: "failed", error: scope.policy.contentSuppressed ? "Execution failed" : errMsg, secretValues: scope.secretValues, contentSuppressed: scope.policy.contentSuppressed });
|
|
3228
|
+
}
|
|
3079
3229
|
log.error("Media generation error", { threadId, mode, error: errMsg });
|
|
3080
3230
|
const failure = providerFailureMessage(err, providerId, modelId);
|
|
3081
3231
|
const failureMessage = `Generation failed: ${failure.message}`;
|
|
@@ -3117,7 +3267,7 @@ export class ChatTurnHandler {
|
|
|
3117
3267
|
* 6. Collect output_update results
|
|
3118
3268
|
* 7. Send response message with typed content, then the terminal chunk
|
|
3119
3269
|
*/
|
|
3120
|
-
async handleWorkflowMessage(data, requestSeq, signal) {
|
|
3270
|
+
async handleWorkflowMessage(data, turnMessageId, requestSeq, signal) {
|
|
3121
3271
|
const threadId = isString(data.thread_id) ? data.thread_id : "";
|
|
3122
3272
|
const workflowId = isString(data.workflow_id) ? data.workflow_id : null;
|
|
3123
3273
|
const providerId = isString(data.provider)
|
|
@@ -3159,7 +3309,12 @@ export class ChatTurnHandler {
|
|
|
3159
3309
|
messagesName ??
|
|
3160
3310
|
"messages";
|
|
3161
3311
|
// Build chat history for params — matches Python
|
|
3162
|
-
const
|
|
3312
|
+
const dbMessages = await loadRecentThreadRows(threadId);
|
|
3313
|
+
const inheritedTrace = getRunTraceScope();
|
|
3314
|
+
seedStoredToolProvenance(dbMessages);
|
|
3315
|
+
if (inheritedTrace) {
|
|
3316
|
+
await registerRunTraceParents(userId, inheritedTrace.runId, dbMessages.map((m) => ({ kind: "message", id: m.id })));
|
|
3317
|
+
}
|
|
3163
3318
|
const chatHistorySerialized = dbMessages.map((m) => ({
|
|
3164
3319
|
role: m.role,
|
|
3165
3320
|
content: m.content,
|
|
@@ -3178,7 +3333,12 @@ export class ChatTurnHandler {
|
|
|
3178
3333
|
// Prepare params — matches Python's WorkflowMessageProcessor
|
|
3179
3334
|
const params = {
|
|
3180
3335
|
[messageInputName]: currentMessage,
|
|
3181
|
-
|
|
3336
|
+
// The stored history already holds this turn's message; it is appended
|
|
3337
|
+
// once, as `currentMessage`.
|
|
3338
|
+
[messagesInputName]: [
|
|
3339
|
+
...chatHistorySerialized.filter((_, i) => dbMessages[i].id !== turnMessageId),
|
|
3340
|
+
currentMessage
|
|
3341
|
+
]
|
|
3182
3342
|
};
|
|
3183
3343
|
if (isObjectLike(data.params)) {
|
|
3184
3344
|
Object.assign(params, data.params);
|
|
@@ -3207,6 +3367,7 @@ export class ChatTurnHandler {
|
|
|
3207
3367
|
workspace,
|
|
3208
3368
|
assetOutputMode: this.session.mode === "text" ? "data_uri" : "temp_url"
|
|
3209
3369
|
});
|
|
3370
|
+
context.runTraceContext = getRunTraceScope() ?? null;
|
|
3210
3371
|
// Expose executor/node-type resolution for sub-workflow nodes
|
|
3211
3372
|
context.setResolveExecutor((node) => this.session.resolveExecutor(node));
|
|
3212
3373
|
if (this.session.resolveNodeType) {
|
|
@@ -3215,6 +3376,8 @@ export class ChatTurnHandler {
|
|
|
3215
3376
|
: this.session.resolveNodeType;
|
|
3216
3377
|
context.setResolveNodeType((nodeType) => resolverObj.resolveNodeType(nodeType));
|
|
3217
3378
|
}
|
|
3379
|
+
await Job.create({ id: jobId, workflow_id: workflowId, user_id: userId, status: "running", params, graph });
|
|
3380
|
+
await registerWorkflowRunTrace(context, { jobId, workflowId });
|
|
3218
3381
|
// Create and run workflow (A5: via the ExecutionSession facade — see
|
|
3219
3382
|
// the identical note in `startJobInner`).
|
|
3220
3383
|
const session = await ExecutionSession.create({
|
|
@@ -3249,20 +3412,6 @@ export class ChatTurnHandler {
|
|
|
3249
3412
|
}
|
|
3250
3413
|
};
|
|
3251
3414
|
this.deps.jobs.registerJob(jobId, active);
|
|
3252
|
-
// Persist job to DB (best-effort)
|
|
3253
|
-
try {
|
|
3254
|
-
await Job.create({
|
|
3255
|
-
id: jobId,
|
|
3256
|
-
workflow_id: workflowId,
|
|
3257
|
-
user_id: userId,
|
|
3258
|
-
status: "running",
|
|
3259
|
-
params,
|
|
3260
|
-
graph
|
|
3261
|
-
});
|
|
3262
|
-
}
|
|
3263
|
-
catch (error) {
|
|
3264
|
-
this.session.logError("workflow job persistence failed", error);
|
|
3265
|
-
}
|
|
3266
3415
|
// The run already started inside `ExecutionSession.create()` above.
|
|
3267
3416
|
const executePromise = session.result;
|
|
3268
3417
|
// Stream events, collect output_update results
|
|
@@ -3441,6 +3590,11 @@ export class ChatTurnHandler {
|
|
|
3441
3590
|
}
|
|
3442
3591
|
catch (err) {
|
|
3443
3592
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
3593
|
+
const scope = getRunTraceScope();
|
|
3594
|
+
if (scope) {
|
|
3595
|
+
trace.getActiveSpan()?.setStatus({ code: SpanStatusCode.ERROR });
|
|
3596
|
+
await settleRunTrace(userId, scope.runId, { status: "failed", error: scope.policy.contentSuppressed ? "Execution failed" : errMsg, secretValues: scope.secretValues, contentSuppressed: scope.policy.contentSuppressed });
|
|
3597
|
+
}
|
|
3444
3598
|
log.error("Workflow message error", {
|
|
3445
3599
|
threadId,
|
|
3446
3600
|
workflowId,
|