@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,3 +1,6 @@
|
|
|
1
|
+
import { ROOT_CONTEXT, propagation, trace, isSpanContextValid } from "@opentelemetry/api";
|
|
2
|
+
import { getRegisteredRunTrace } from "@nodetool-ai/models";
|
|
3
|
+
import { ensureRunTraceTelemetry, openAppRunTrace, registerWorkflowRunTrace } from "@nodetool-ai/execution";
|
|
1
4
|
/**
|
|
2
5
|
* Everything between "run_job arrived" and "terminal status persisted": the
|
|
3
6
|
* admission gates, the concurrency queue, run start-up, the message stream,
|
|
@@ -9,7 +12,9 @@
|
|
|
9
12
|
* {@link JobExecutionDeps}.
|
|
10
13
|
*/
|
|
11
14
|
import { randomUUID } from "node:crypto";
|
|
15
|
+
import { operationTarget, parseInputStateKey } from "@nodetool-ai/app-runtime";
|
|
12
16
|
import { ApiErrorCode } from "../error-codes.js";
|
|
17
|
+
import { captureError } from "../error-traces.js";
|
|
13
18
|
import { admitSpend, releaseSpend, reserveSpend } from "../credit-gate.js";
|
|
14
19
|
import { JobConcurrencyQueue } from "../job-queue.js";
|
|
15
20
|
import { isBoolean, isFiniteNumber, isFunctionValue, isNonEmptyString, isNumber, isObjectLike, isRecord, isString } from "../lib/wire-values.js";
|
|
@@ -18,17 +23,19 @@ import { ExecutionSession, isExecutionPreflightError, isUnitBilledCapability, pr
|
|
|
18
23
|
import { persistableOutputs, withoutInlineAssetBytes } from "@nodetool-ai/execution/service";
|
|
19
24
|
import { createRunSupervisor } from "../run-supervisor.js";
|
|
20
25
|
import { jobRunRegistry } from "../job-run-registry.js";
|
|
21
|
-
import { Application, Asset, Job, listApplicationVersions, invocationIdInUse, releasedApplicationRelease, releasedApplicationVersion, reserveInvocation, settleInvocation, Workflow } from "@nodetool-ai/models";
|
|
26
|
+
import { Application, AppRunError, claimAppRun, ensureDefaultAppInstance, findAppRunByInvocation, getAppInstance, getAppRun, Asset, Job, listApplicationVersions, invocationIdInUse, releasedApplicationRelease, releasedApplicationVersion, reconcileAppRunCost, reserveInvocation, reserveAppRun, setAppRunInputs, settleAppRun, updateAppRunEstimate, settleInvocation, Workflow } from "@nodetool-ai/models";
|
|
22
27
|
import { getInstanceId } from "../lib/instance-id.js";
|
|
23
28
|
import { requestRemoteJobCancel } from "../job-control.js";
|
|
24
29
|
import { estimateWorkflowCost, nodeExpectedQuantity } from "@nodetool-ai/node-sdk/cost-estimate";
|
|
25
30
|
import { extractPricingParams } from "@nodetool-ai/node-sdk/pricing-params";
|
|
26
31
|
import { getModelUnitPrice } from "@nodetool-ai/model-pricing";
|
|
27
32
|
import { applicationReleaseResponse } from "@nodetool-ai/protocol/api-schemas/applications.js";
|
|
33
|
+
import { appRunSnapshot } from "@nodetool-ai/protocol/api-schemas/app-runs.js";
|
|
28
34
|
import { confineRunRequest, isRunRefusal } from "../lib/app-session-scope.js";
|
|
29
35
|
import { releaseBlockedReason } from "../lib/app-deployment-service.js";
|
|
30
36
|
import { autoSaveAssets, primaryTextOutputName } from "./asset-autosave.js";
|
|
31
37
|
import { createRuntimeContext } from "./model-interfaces.js";
|
|
38
|
+
import { createAppRunFold } from "./app-run-fold.js";
|
|
32
39
|
import { formatSanitizedError, sanitizeLargeText } from "./sanitize.js";
|
|
33
40
|
import { createLogger } from "@nodetool-ai/config";
|
|
34
41
|
const log = createLogger("nodetool.websocket.runner");
|
|
@@ -50,9 +57,6 @@ export function resolveRunJobExecutionOptions(value, sdkDefaults = false) {
|
|
|
50
57
|
: "auto"
|
|
51
58
|
};
|
|
52
59
|
}
|
|
53
|
-
export function resolveRunJobUserId(requestUserId, connectionUserId) {
|
|
54
|
-
return requestUserId?.trim() || connectionUserId;
|
|
55
|
-
}
|
|
56
60
|
export function createRelayActivityWaiter(context, executionSettled, abortSignal) {
|
|
57
61
|
let pending = context.hasMessages();
|
|
58
62
|
let resolveWaiter = null;
|
|
@@ -374,7 +378,19 @@ export class JobExecutionManager {
|
|
|
374
378
|
*/
|
|
375
379
|
async emitBeforeRunFailure(jobId, workflowId, err, persistJob) {
|
|
376
380
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
381
|
+
const appRun = await findAppRunByInvocation(this.session.requireUserId(), jobId);
|
|
382
|
+
if (appRun) {
|
|
383
|
+
await settleAppRun(this.session.requireUserId(), appRun.id, {
|
|
384
|
+
status: "failed",
|
|
385
|
+
error: errorMessage
|
|
386
|
+
});
|
|
387
|
+
}
|
|
377
388
|
this.session.logError("beforeRunJob failed", err);
|
|
389
|
+
captureError(err, {
|
|
390
|
+
source: "job",
|
|
391
|
+
userId: this.session.userId,
|
|
392
|
+
context: { job_id: jobId, workflow_id: workflowId ?? "" }
|
|
393
|
+
});
|
|
378
394
|
await this.session.send({
|
|
379
395
|
type: "job_update",
|
|
380
396
|
status: "failed",
|
|
@@ -589,6 +605,9 @@ export class JobExecutionManager {
|
|
|
589
605
|
* telemetry, which is the same ledger.
|
|
590
606
|
*/
|
|
591
607
|
async admitApplicationRun(req) {
|
|
608
|
+
if (req.app_run_id || this.session.appSession) {
|
|
609
|
+
return this.admitDurableAppRun(req);
|
|
610
|
+
}
|
|
592
611
|
const applicationId = req.application_id;
|
|
593
612
|
if (!applicationId)
|
|
594
613
|
return true;
|
|
@@ -712,6 +731,144 @@ export class JobExecutionManager {
|
|
|
712
731
|
}
|
|
713
732
|
return true;
|
|
714
733
|
}
|
|
734
|
+
async admitDurableAppRun(req) {
|
|
735
|
+
const userId = this.session.requireUserId();
|
|
736
|
+
const jobId = req.job_id ?? randomUUID();
|
|
737
|
+
req.job_id = jobId;
|
|
738
|
+
let claimedRunId = null;
|
|
739
|
+
try {
|
|
740
|
+
if (this.session.appSession && req.application_id) {
|
|
741
|
+
const release = await releasedApplicationRelease(req.application_id, userId);
|
|
742
|
+
if (!release) {
|
|
743
|
+
throw new Error("Application release not found");
|
|
744
|
+
}
|
|
745
|
+
const instance = await ensureDefaultAppInstance({
|
|
746
|
+
userId,
|
|
747
|
+
applicationId: req.application_id,
|
|
748
|
+
sourceId: `public:${req.application_id}:${release.version}`,
|
|
749
|
+
version: release.version,
|
|
750
|
+
name: "Visitor runs",
|
|
751
|
+
snapshot: appRunSnapshot.parse({
|
|
752
|
+
document: release.document,
|
|
753
|
+
workflow_graphs: Object.fromEntries(release.workflows.flatMap((item) => item.graph ? [[item.workflowId, item.graph]] : [])),
|
|
754
|
+
script_documents: {}
|
|
755
|
+
})
|
|
756
|
+
});
|
|
757
|
+
const decision = await reserveAppRun({
|
|
758
|
+
userId,
|
|
759
|
+
instanceId: instance.id,
|
|
760
|
+
invocationId: jobId,
|
|
761
|
+
operationId: req.operation_id ?? "",
|
|
762
|
+
origin: "public",
|
|
763
|
+
estimatedUsd: this.estimateRunCost(req),
|
|
764
|
+
requireFiniteBudget: true
|
|
765
|
+
});
|
|
766
|
+
if (!decision.allowed) {
|
|
767
|
+
return this.refuseRun(req, jobId, ApiErrorCode.BUDGET_EXCEEDED, decision.reason);
|
|
768
|
+
}
|
|
769
|
+
req.app_run_id = decision.run.id;
|
|
770
|
+
req.instance_id = instance.id;
|
|
771
|
+
}
|
|
772
|
+
const run = req.app_run_id
|
|
773
|
+
? await getAppRun(userId, req.app_run_id)
|
|
774
|
+
: null;
|
|
775
|
+
const instance = req.instance_id
|
|
776
|
+
? await getAppInstance(userId, req.instance_id)
|
|
777
|
+
: null;
|
|
778
|
+
if (!run ||
|
|
779
|
+
!instance ||
|
|
780
|
+
run.instance_id !== instance.id ||
|
|
781
|
+
run.invocation_id !== jobId) {
|
|
782
|
+
return this.refuseRun(req, jobId, ApiErrorCode.NOT_FOUND, "App run not found");
|
|
783
|
+
}
|
|
784
|
+
if (run.status !== "running") {
|
|
785
|
+
return this.refuseRun(req, jobId, ApiErrorCode.ALREADY_EXISTS, "App run has already finished");
|
|
786
|
+
}
|
|
787
|
+
const operation = instance.snapshot.document.operations.find((item) => item.id === run.operation_id);
|
|
788
|
+
if (!operation ||
|
|
789
|
+
operationTarget(operation).kind !== "workflow" ||
|
|
790
|
+
(req.operation_id && req.operation_id !== run.operation_id)) {
|
|
791
|
+
return this.refuseRun(req, jobId, ApiErrorCode.INVALID_INPUT, "Operation does not match this run");
|
|
792
|
+
}
|
|
793
|
+
const target = operationTarget(operation);
|
|
794
|
+
if (target.kind !== "workflow" ||
|
|
795
|
+
!target.workflowId ||
|
|
796
|
+
(req.workflow_id && req.workflow_id !== target.workflowId)) {
|
|
797
|
+
return this.refuseRun(req, jobId, ApiErrorCode.INVALID_INPUT, "Workflow does not match this run");
|
|
798
|
+
}
|
|
799
|
+
if (run.origin !== "public") {
|
|
800
|
+
const frozen = run.snapshot?.workflow_graphs[target.workflowId];
|
|
801
|
+
if (!frozen) {
|
|
802
|
+
return this.refuseRun(req, jobId, ApiErrorCode.INVALID_INPUT, "Run has no frozen workflow");
|
|
803
|
+
}
|
|
804
|
+
const overlays = new Map();
|
|
805
|
+
const inputs = instance.variables["__app_inputs"];
|
|
806
|
+
for (const [key, value] of Object.entries(isRecord(inputs) ? inputs : {})) {
|
|
807
|
+
const binding = parseInputStateKey(key);
|
|
808
|
+
if (!binding?.property || binding.operationId !== run.operation_id) {
|
|
809
|
+
continue;
|
|
810
|
+
}
|
|
811
|
+
const properties = overlays.get(binding.nodeId) ?? {};
|
|
812
|
+
properties[binding.property] = value;
|
|
813
|
+
overlays.set(binding.nodeId, properties);
|
|
814
|
+
}
|
|
815
|
+
req.graph = {
|
|
816
|
+
...frozen,
|
|
817
|
+
nodes: frozen.nodes.map((node) => {
|
|
818
|
+
const overlay = overlays.get(node.id);
|
|
819
|
+
if (!overlay) {
|
|
820
|
+
return node;
|
|
821
|
+
}
|
|
822
|
+
const properties = isRecord(node.properties)
|
|
823
|
+
? node.properties
|
|
824
|
+
: isRecord(node.data)
|
|
825
|
+
? node.data
|
|
826
|
+
: {};
|
|
827
|
+
return { ...node, properties: { ...properties, ...overlay } };
|
|
828
|
+
})
|
|
829
|
+
};
|
|
830
|
+
await updateAppRunEstimate(userId, run.id, this.estimateRunCost(req));
|
|
831
|
+
}
|
|
832
|
+
if (!(await claimAppRun(userId, run.id, getInstanceId()))) {
|
|
833
|
+
return this.refuseRun(req, jobId, ApiErrorCode.ALREADY_EXISTS, "App run execution already started");
|
|
834
|
+
}
|
|
835
|
+
claimedRunId = run.id;
|
|
836
|
+
await setAppRunInputs(userId, run.id, req.params ?? {});
|
|
837
|
+
req.app_run_id = run.id;
|
|
838
|
+
req.instance_id = instance.id;
|
|
839
|
+
req.user_id = userId;
|
|
840
|
+
req.workflow_id = target.workflowId;
|
|
841
|
+
req.application_id = run.application_id;
|
|
842
|
+
req.application_version = run.version;
|
|
843
|
+
req.operation_id = run.operation_id;
|
|
844
|
+
return true;
|
|
845
|
+
}
|
|
846
|
+
catch (error) {
|
|
847
|
+
if (claimedRunId) {
|
|
848
|
+
try {
|
|
849
|
+
await settleAppRun(userId, claimedRunId, {
|
|
850
|
+
status: "failed",
|
|
851
|
+
actualUsd: 0,
|
|
852
|
+
knownLlmUsd: 0,
|
|
853
|
+
error: error instanceof Error
|
|
854
|
+
? error.message
|
|
855
|
+
: "App run admission failed"
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
catch (settlementError) {
|
|
859
|
+
if (!(settlementError instanceof AppRunError) ||
|
|
860
|
+
settlementError.code !== "not_found") {
|
|
861
|
+
this.session.logError("app run admission settlement failed", settlementError);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
this.session.logError("app run admission failed", error);
|
|
866
|
+
const code = error instanceof AppRunError && error.code === "budget_exceeded"
|
|
867
|
+
? ApiErrorCode.BUDGET_EXCEEDED
|
|
868
|
+
: ApiErrorCode.INVALID_INPUT;
|
|
869
|
+
return this.refuseRun(req, jobId, code, error instanceof Error ? error.message : "App run admission failed");
|
|
870
|
+
}
|
|
871
|
+
}
|
|
715
872
|
/**
|
|
716
873
|
* Gate a run on the user's credit balance — but only the part of the run
|
|
717
874
|
* that spends through NodeTool's managed provider. A graph with no
|
|
@@ -808,8 +965,15 @@ export class JobExecutionManager {
|
|
|
808
965
|
req._accepted_at_ms ??= performance.now();
|
|
809
966
|
if (!(await this.admitApplicationRun(req)))
|
|
810
967
|
return;
|
|
811
|
-
if (!(await this.admitCreditRun(req)))
|
|
968
|
+
if (!(await this.admitCreditRun(req))) {
|
|
969
|
+
if (req.app_run_id) {
|
|
970
|
+
await settleAppRun(this.session.requireUserId(), req.app_run_id, {
|
|
971
|
+
status: "failed",
|
|
972
|
+
error: "Run refused by spending limit"
|
|
973
|
+
});
|
|
974
|
+
}
|
|
812
975
|
return;
|
|
976
|
+
}
|
|
813
977
|
const max = await this.deps.getMaxConcurrentJobs();
|
|
814
978
|
const perWorkflowMax = await this.perWorkflowLimitFor(req);
|
|
815
979
|
// Queue the run when over the global cap, or when this workflow already has
|
|
@@ -841,7 +1005,7 @@ export class JobExecutionManager {
|
|
|
841
1005
|
await Job.create({
|
|
842
1006
|
id: jobId,
|
|
843
1007
|
workflow_id: req.workflow_id ?? "",
|
|
844
|
-
user_id:
|
|
1008
|
+
user_id: this.session.requireUserId(),
|
|
845
1009
|
status: "queued",
|
|
846
1010
|
name: req.job_name ?? "",
|
|
847
1011
|
params: req.params ?? {},
|
|
@@ -949,6 +1113,13 @@ export class JobExecutionManager {
|
|
|
949
1113
|
try {
|
|
950
1114
|
await this.startJobInner(req, releaseSlot);
|
|
951
1115
|
}
|
|
1116
|
+
catch (error) {
|
|
1117
|
+
if (req.app_run_id) {
|
|
1118
|
+
await this.emitBeforeRunFailure(req.job_id ?? "", req.workflow_id ?? null, error, true);
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
throw error;
|
|
1122
|
+
}
|
|
952
1123
|
finally {
|
|
953
1124
|
// Safety net: if startJobInner returned/threw without registering, the
|
|
954
1125
|
// slot is freed so it doesn't leak and permanently shrink the cap.
|
|
@@ -956,7 +1127,10 @@ export class JobExecutionManager {
|
|
|
956
1127
|
}
|
|
957
1128
|
}
|
|
958
1129
|
async startJobInner(req, releaseSlot) {
|
|
959
|
-
|
|
1130
|
+
// The connection's authenticated user. The request's `user_id` is
|
|
1131
|
+
// client-written, so it cannot choose whose secrets, workflows, and
|
|
1132
|
+
// assets the run uses.
|
|
1133
|
+
const userId = this.session.requireUserId();
|
|
960
1134
|
const workflowId = req.workflow_id ?? null;
|
|
961
1135
|
const jobId = req.job_id ?? randomUUID();
|
|
962
1136
|
let projectId = req.project_id ?? null;
|
|
@@ -1011,11 +1185,23 @@ export class JobExecutionManager {
|
|
|
1011
1185
|
const workspace = this.session.workspaceResolver
|
|
1012
1186
|
? await this.session.workspaceResolver(workflowId ?? null, userId)
|
|
1013
1187
|
: null;
|
|
1188
|
+
const appRun = req.app_run_id
|
|
1189
|
+
? await getAppRun(userId, req.app_run_id)
|
|
1190
|
+
: null;
|
|
1014
1191
|
const context = createRuntimeContext({
|
|
1015
1192
|
jobId,
|
|
1016
1193
|
workflowId,
|
|
1017
1194
|
projectId,
|
|
1018
1195
|
userId,
|
|
1196
|
+
...(appRun && {
|
|
1197
|
+
appRunContext: {
|
|
1198
|
+
userId,
|
|
1199
|
+
appRunId: appRun.id,
|
|
1200
|
+
instanceId: appRun.instance_id,
|
|
1201
|
+
traceId: appRun.trace_id,
|
|
1202
|
+
origin: appRun.origin
|
|
1203
|
+
}
|
|
1204
|
+
}),
|
|
1019
1205
|
workspace,
|
|
1020
1206
|
assetOutputMode: this.session.mode === "text" ? "data_uri" : "temp_url",
|
|
1021
1207
|
persistOutputAssets: executionOptions.assetPersistence === "auto"
|
|
@@ -1042,8 +1228,26 @@ export class JobExecutionManager {
|
|
|
1042
1228
|
if (executionOptions.persistence === "job") {
|
|
1043
1229
|
try {
|
|
1044
1230
|
const existing = await Job.get(jobId);
|
|
1231
|
+
if (existing && existing.user_id !== userId) {
|
|
1232
|
+
// The client chose this job_id. Another user's row under it must
|
|
1233
|
+
// not be flipped to running or written with this run's results.
|
|
1234
|
+
releaseSlot();
|
|
1235
|
+
this.drainQueue();
|
|
1236
|
+
this.session.sendDetached({
|
|
1237
|
+
type: "job_update",
|
|
1238
|
+
status: "failed",
|
|
1239
|
+
job_id: jobId,
|
|
1240
|
+
workflow_id: workflowId,
|
|
1241
|
+
error: "Job id already in use",
|
|
1242
|
+
error_code: ApiErrorCode.ALREADY_EXISTS
|
|
1243
|
+
});
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1045
1246
|
if (existing) {
|
|
1046
1247
|
if (existing.status === "cancelled") {
|
|
1248
|
+
if (appRun) {
|
|
1249
|
+
await settleAppRun(userId, appRun.id, { status: "cancelled" });
|
|
1250
|
+
}
|
|
1047
1251
|
log.info("Skipping start of cancelled job", { jobId });
|
|
1048
1252
|
// Nothing was registered in activeJobs yet — free the reserved
|
|
1049
1253
|
// slot and promote any queued run, matching every other slot
|
|
@@ -1079,7 +1283,10 @@ export class JobExecutionManager {
|
|
|
1079
1283
|
name: req.job_name ?? "",
|
|
1080
1284
|
started_at: new Date().toISOString(),
|
|
1081
1285
|
params: req.params ?? {},
|
|
1082
|
-
graph,
|
|
1286
|
+
// The graph as submitted, not the hydrated one: hydration drops
|
|
1287
|
+
// editor-only nodes (groups, comments), and "Open as it was when
|
|
1288
|
+
// made" reopens this graph in the editor.
|
|
1289
|
+
graph: rawGraph,
|
|
1083
1290
|
project_id: projectId ?? "default",
|
|
1084
1291
|
runner_instance: instanceId
|
|
1085
1292
|
});
|
|
@@ -1134,11 +1341,27 @@ export class JobExecutionManager {
|
|
|
1134
1341
|
// uses: a bare throw reaches handleCommand as a generic `invalid_command`
|
|
1135
1342
|
// the UI never associates with the job, so the run appears to spin
|
|
1136
1343
|
// forever instead of failing with the reason.
|
|
1344
|
+
let finishAppTrace;
|
|
1345
|
+
try {
|
|
1346
|
+
await ensureRunTraceTelemetry();
|
|
1347
|
+
const incomingParent = req.traceparent ? trace.getSpanContext(propagation.extract(ROOT_CONTEXT, { traceparent: req.traceparent })) : undefined;
|
|
1348
|
+
const acceptedParent = incomingParent && isSpanContextValid(incomingParent) && !this.session.appSession && appRun && incomingParent.traceId === appRun.trace_id && await getRegisteredRunTrace(userId, incomingParent.traceId, appRun.id) ? incomingParent : undefined;
|
|
1349
|
+
finishAppTrace = appRun ? await openAppRunTrace(context, appRun, acceptedParent) : undefined;
|
|
1350
|
+
if (executionOptions.persistence === "job") {
|
|
1351
|
+
await registerWorkflowRunTrace(context, { jobId, workflowId: workflowId ?? null, inlineGraph: Boolean(req.graph), origin: this.session.appSession ? "public" : "ui" });
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
catch (error) {
|
|
1355
|
+
await finishAppTrace?.("failed", error instanceof Error ? error.message : String(error));
|
|
1356
|
+
await this.emitBeforeRunFailure(jobId, workflowId, error, executionOptions.persistence === "job");
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1137
1359
|
let session;
|
|
1138
1360
|
try {
|
|
1139
1361
|
session = await ExecutionSession.create(sessionOptions);
|
|
1140
1362
|
}
|
|
1141
1363
|
catch (err) {
|
|
1364
|
+
await finishAppTrace?.("failed", err instanceof Error ? err.message : String(err));
|
|
1142
1365
|
if (!isExecutionPreflightError(err))
|
|
1143
1366
|
throw err;
|
|
1144
1367
|
await this.emitBeforeRunFailure(jobId, workflowId, err, executionOptions.persistence === "job");
|
|
@@ -1163,18 +1386,14 @@ export class JobExecutionManager {
|
|
|
1163
1386
|
persistenceMs,
|
|
1164
1387
|
kernelStartedAt: performance.now()
|
|
1165
1388
|
},
|
|
1166
|
-
applicationId: req.application_id ?? null
|
|
1389
|
+
applicationId: req.application_id ?? null,
|
|
1390
|
+
...(appRun && { appRunFold: createAppRunFold(appRun) }),
|
|
1391
|
+
...(finishAppTrace && { finishAppTrace })
|
|
1167
1392
|
};
|
|
1168
1393
|
// Decouple the run from this socket: from here on every frame carrying
|
|
1169
1394
|
// this job_id is stamped with `job_seq` and buffered, so a client that
|
|
1170
1395
|
// drops mid-run can `reconnect_job` from a fresh connection and replay
|
|
1171
1396
|
// the tail — including the terminal job_update.
|
|
1172
|
-
//
|
|
1173
|
-
// Keyed on the connection's identity, not `userId`: every lookup
|
|
1174
|
-
// (`reconnect_job`, `cancel_job`, the slot counts) reads
|
|
1175
|
-
// `this.session.requireUserId()`, and a run opened under an explicit differing
|
|
1176
|
-
// `req.user_id` would be unreachable — no replay, and a cancel that
|
|
1177
|
-
// reports the job as not found.
|
|
1178
1397
|
const runSession = jobRunRegistry.open(this.session.requireUserId(), jobId, workflowId, {
|
|
1179
1398
|
cancel: () => session.cancel(),
|
|
1180
1399
|
pushInput: (input, value, handle) => session.pushInput(input, value, handle),
|
|
@@ -1248,6 +1467,10 @@ export class JobExecutionManager {
|
|
|
1248
1467
|
// the client UI spinning, and the app ledger holding the estimate.
|
|
1249
1468
|
const message = error instanceof Error ? error.message : String(error);
|
|
1250
1469
|
this.session.logError("job message streaming failed", error);
|
|
1470
|
+
// The run is reported failed below, so stop the kernel too: otherwise
|
|
1471
|
+
// it keeps executing (and spending) with nobody reading its output,
|
|
1472
|
+
// and cancel_job can no longer reach it once the session finishes.
|
|
1473
|
+
active.session?.cancel();
|
|
1251
1474
|
active.finished = true;
|
|
1252
1475
|
active.status = "failed";
|
|
1253
1476
|
active.error = message;
|
|
@@ -1304,6 +1527,16 @@ export class JobExecutionManager {
|
|
|
1304
1527
|
}
|
|
1305
1528
|
else if (active.status === "failed") {
|
|
1306
1529
|
job.markFailed(active.error ?? "Unknown error");
|
|
1530
|
+
// The run's error is a string by now. A stack built here would
|
|
1531
|
+
// point at this method, not at the failure, so none is sent.
|
|
1532
|
+
captureError(active.error ?? "Unknown error", {
|
|
1533
|
+
source: "job",
|
|
1534
|
+
userId: job.user_id,
|
|
1535
|
+
context: {
|
|
1536
|
+
job_id: active.jobId,
|
|
1537
|
+
workflow_id: active.workflowId ?? ""
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1307
1540
|
}
|
|
1308
1541
|
else if (active.status === "cancelled") {
|
|
1309
1542
|
job.markCancelled();
|
|
@@ -1327,6 +1560,38 @@ export class JobExecutionManager {
|
|
|
1327
1560
|
* the estimate standing rather than handing the spend back. Never throws.
|
|
1328
1561
|
*/
|
|
1329
1562
|
async settleApplicationInvocation(active) {
|
|
1563
|
+
await active.finishAppTrace?.(active.status === "failed" ? "failed" : active.status === "cancelled" ? "cancelled" : "completed", active.error, this.runMeasuredCost(active));
|
|
1564
|
+
const identity = active.context.appRunContext;
|
|
1565
|
+
if (identity) {
|
|
1566
|
+
try {
|
|
1567
|
+
const settlement = {
|
|
1568
|
+
status: active.status === "failed"
|
|
1569
|
+
? "failed"
|
|
1570
|
+
: active.status === "cancelled"
|
|
1571
|
+
? "cancelled"
|
|
1572
|
+
: "completed",
|
|
1573
|
+
error: active.context.runTraceContext?.policy.contentSuppressed && active.error ? "Execution failed" : active.error ?? null,
|
|
1574
|
+
actualUsd: this.runMeasuredCost(active),
|
|
1575
|
+
outputs: active.appRunFold?.outputs() ?? {},
|
|
1576
|
+
documents: active.context.getAppRunDocuments(),
|
|
1577
|
+
contentSuppressed: active.context.runTraceContext?.policy.contentSuppressed,
|
|
1578
|
+
secretValues: [...active.context.getResolvedSecretValues()]
|
|
1579
|
+
};
|
|
1580
|
+
const llmCost = active.context.getAppRunLlmCost();
|
|
1581
|
+
if (llmCost !== null) {
|
|
1582
|
+
settlement.knownLlmUsd = llmCost;
|
|
1583
|
+
}
|
|
1584
|
+
await settleAppRun(identity.userId, identity.appRunId, settlement);
|
|
1585
|
+
await reconcileAppRunCost(identity.userId, identity.appRunId);
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1588
|
+
catch (error) {
|
|
1589
|
+
if (!(error instanceof AppRunError) || error.code !== "not_found") {
|
|
1590
|
+
this.session.logError("app run settlement failed", error);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1330
1595
|
if (!active.applicationId)
|
|
1331
1596
|
return;
|
|
1332
1597
|
try {
|
|
@@ -1587,18 +1852,25 @@ export class JobExecutionManager {
|
|
|
1587
1852
|
continue;
|
|
1588
1853
|
}
|
|
1589
1854
|
const status = outbound.type === "job_update" ? String(outbound.status ?? "") : "";
|
|
1590
|
-
const suppressProvisionalCompletion = active.
|
|
1591
|
-
status
|
|
1592
|
-
|
|
1855
|
+
const suppressProvisionalCompletion = (Boolean(active.context.appRunContext) &&
|
|
1856
|
+
TERMINAL_JOB_STATUSES.includes(status)) ||
|
|
1857
|
+
(active.requireTerminalResult &&
|
|
1858
|
+
status === "completed" &&
|
|
1859
|
+
outbound.result === undefined);
|
|
1593
1860
|
if (!suppressProvisionalCompletion) {
|
|
1594
1861
|
if (outbound.type === "job_update") {
|
|
1595
1862
|
if (status === "running") {
|
|
1596
1863
|
runningSeen = true;
|
|
1597
1864
|
}
|
|
1598
1865
|
else if (TERMINAL_JOB_STATUSES.includes(status)) {
|
|
1866
|
+
if (active.context.appRunContext) {
|
|
1867
|
+
await executionSettled;
|
|
1868
|
+
await this.settleApplicationInvocation(active);
|
|
1869
|
+
}
|
|
1599
1870
|
await ensureRunningFrame();
|
|
1600
1871
|
}
|
|
1601
1872
|
}
|
|
1873
|
+
active.appRunFold?.fold(outbound);
|
|
1602
1874
|
await this.session.send(outbound);
|
|
1603
1875
|
}
|
|
1604
1876
|
if (outbound.type === "job_update" && !suppressProvisionalCompletion) {
|
|
@@ -1620,12 +1892,30 @@ export class JobExecutionManager {
|
|
|
1620
1892
|
if (Object.keys(finalOutputs).length > 0) {
|
|
1621
1893
|
finalOutputs = await this.normalizeFinalOutputs(active, finalOutputs);
|
|
1622
1894
|
}
|
|
1895
|
+
if (active.appRunFold) {
|
|
1896
|
+
for (const [key, values] of Object.entries(finalOutputs)) {
|
|
1897
|
+
const nodeId = this.resolveOutputNodeForKey(active, key)?.id ?? key;
|
|
1898
|
+
for (const [index, value] of values.entries()) {
|
|
1899
|
+
active.appRunFold.fold({
|
|
1900
|
+
type: "output_update",
|
|
1901
|
+
job_id: active.jobId,
|
|
1902
|
+
node_id: nodeId,
|
|
1903
|
+
value,
|
|
1904
|
+
disposition: index === 0 ? "replace" : "append",
|
|
1905
|
+
done: true
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1623
1910
|
if (active.executionOptions.eventDetail !== "terminal" &&
|
|
1624
1911
|
!outputUpdateSeen &&
|
|
1625
1912
|
Object.keys(finalOutputs).length > 0) {
|
|
1626
1913
|
await this.sendOutputUpdates(active, finalOutputs);
|
|
1627
1914
|
}
|
|
1628
1915
|
const relayCompletedAt = performance.now();
|
|
1916
|
+
if (active.context.appRunContext) {
|
|
1917
|
+
await this.settleApplicationInvocation(active);
|
|
1918
|
+
}
|
|
1629
1919
|
if (!terminalSeen ||
|
|
1630
1920
|
(!terminalWithResultSeen && Object.keys(finalOutputs).length > 0)) {
|
|
1631
1921
|
await ensureRunningFrame();
|
|
@@ -1706,7 +1996,7 @@ export class JobExecutionManager {
|
|
|
1706
1996
|
// indistinguishable from a missing one — it must be neither reported
|
|
1707
1997
|
// nor settled below.
|
|
1708
1998
|
const row = (await Job.get(jobId));
|
|
1709
|
-
const job = row && row.user_id ===
|
|
1999
|
+
const job = row && row.user_id === this.session.requireUserId() ? row : null;
|
|
1710
2000
|
const settled = job != null &&
|
|
1711
2001
|
(job.status === "completed" ||
|
|
1712
2002
|
job.status === "failed" ||
|
|
@@ -1781,17 +2071,18 @@ export class JobExecutionManager {
|
|
|
1781
2071
|
// and tell the client it's cancelled before it ever starts.
|
|
1782
2072
|
const queued = this.jobQueue.remove(jobId);
|
|
1783
2073
|
if (queued) {
|
|
2074
|
+
if (queued.app_run_id) {
|
|
2075
|
+
await settleAppRun(this.session.requireUserId(), queued.app_run_id, {
|
|
2076
|
+
status: "cancelled"
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
1784
2079
|
releaseSpend(this.session.requireUserId(), jobId);
|
|
1785
2080
|
const cancelledWorkflowId = queued.workflow_id ?? workflowId ?? null;
|
|
1786
2081
|
// Mark the persisted queued row cancelled so it leaves the queue in
|
|
1787
2082
|
// jobs.list too (not just the in-memory queue).
|
|
1788
2083
|
if (resolveRunJobExecutionOptions(queued.execution_options, queued.require_terminal_result === true).persistence === "job") {
|
|
1789
2084
|
try {
|
|
1790
|
-
|
|
1791
|
-
if (job) {
|
|
1792
|
-
job.markCancelled();
|
|
1793
|
-
await job.save();
|
|
1794
|
-
}
|
|
2085
|
+
await Job.markCancelledIfActive(jobId, this.session.requireUserId());
|
|
1795
2086
|
}
|
|
1796
2087
|
catch (err) {
|
|
1797
2088
|
this.session.logError("cancel persistence failed", err);
|
|
@@ -1821,11 +2112,7 @@ export class JobExecutionManager {
|
|
|
1821
2112
|
if (registered && registered.status === "running") {
|
|
1822
2113
|
registered.cancel();
|
|
1823
2114
|
try {
|
|
1824
|
-
|
|
1825
|
-
if (job && job.status !== "cancelled") {
|
|
1826
|
-
job.markCancelled();
|
|
1827
|
-
await job.save();
|
|
1828
|
-
}
|
|
2115
|
+
await Job.markCancelledIfActive(jobId, this.session.requireUserId());
|
|
1829
2116
|
}
|
|
1830
2117
|
catch (err) {
|
|
1831
2118
|
this.session.logError("cancel persistence failed", err);
|
|
@@ -1875,11 +2162,7 @@ export class JobExecutionManager {
|
|
|
1875
2162
|
if ((active.executionOptions?.persistence ??
|
|
1876
2163
|
DEFAULT_RUN_JOB_EXECUTION_OPTIONS.persistence) === "job") {
|
|
1877
2164
|
try {
|
|
1878
|
-
|
|
1879
|
-
if (job && job.status !== "cancelled") {
|
|
1880
|
-
job.markCancelled();
|
|
1881
|
-
await job.save();
|
|
1882
|
-
}
|
|
2165
|
+
await Job.markCancelledIfActive(jobId, this.session.requireUserId());
|
|
1883
2166
|
}
|
|
1884
2167
|
catch (err) {
|
|
1885
2168
|
this.session.logError("cancel persistence failed", err);
|
|
@@ -2062,11 +2345,13 @@ export class JobExecutionManager {
|
|
|
2062
2345
|
if (!queuedId)
|
|
2063
2346
|
continue;
|
|
2064
2347
|
try {
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2348
|
+
if (queued.app_run_id) {
|
|
2349
|
+
await settleAppRun(this.session.requireUserId(), queued.app_run_id, {
|
|
2350
|
+
status: "cancelled"
|
|
2351
|
+
});
|
|
2069
2352
|
}
|
|
2353
|
+
releaseSpend(this.session.requireUserId(), queuedId);
|
|
2354
|
+
await Job.markCancelledIfActive(queuedId, this.session.requireUserId());
|
|
2070
2355
|
}
|
|
2071
2356
|
catch (err) {
|
|
2072
2357
|
this.session.logError("disconnect queue cancellation failed", err);
|
|
@@ -2074,11 +2359,13 @@ export class JobExecutionManager {
|
|
|
2074
2359
|
}
|
|
2075
2360
|
for (const dequeuedId of this.dequeuedJobs) {
|
|
2076
2361
|
try {
|
|
2077
|
-
const
|
|
2078
|
-
if (
|
|
2079
|
-
|
|
2080
|
-
|
|
2362
|
+
const run = await findAppRunByInvocation(this.session.requireUserId(), dequeuedId);
|
|
2363
|
+
if (run) {
|
|
2364
|
+
await settleAppRun(this.session.requireUserId(), run.id, {
|
|
2365
|
+
status: "cancelled"
|
|
2366
|
+
});
|
|
2081
2367
|
}
|
|
2368
|
+
await Job.markCancelledIfActive(dequeuedId, this.session.requireUserId());
|
|
2082
2369
|
}
|
|
2083
2370
|
catch (err) {
|
|
2084
2371
|
this.session.logError("disconnect dequeued-job cancellation failed", err);
|