@nodetool-ai/execution 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/app-debug/app-spec.d.ts +94 -0
- package/dist/app-debug/app-spec.d.ts.map +1 -0
- package/dist/app-debug/app-spec.js +710 -0
- package/dist/app-debug/app-spec.js.map +1 -0
- package/dist/app-debug/application-target.d.ts +53 -0
- package/dist/app-debug/application-target.d.ts.map +1 -0
- package/dist/app-debug/application-target.js +126 -0
- package/dist/app-debug/application-target.js.map +1 -0
- package/dist/app-debug/bundle-target.d.ts +21 -0
- package/dist/app-debug/bundle-target.d.ts.map +1 -0
- package/dist/app-debug/bundle-target.js +51 -0
- package/dist/app-debug/bundle-target.js.map +1 -0
- package/dist/app-debug/graph-shape.d.ts +14 -0
- package/dist/app-debug/graph-shape.d.ts.map +1 -0
- package/dist/app-debug/graph-shape.js +23 -0
- package/dist/app-debug/graph-shape.js.map +1 -0
- package/dist/app-debug/index.d.ts +26 -0
- package/dist/app-debug/index.d.ts.map +1 -0
- package/dist/app-debug/index.js +19 -0
- package/dist/app-debug/index.js.map +1 -0
- package/dist/app-debug/markdown.d.ts +6 -0
- package/dist/app-debug/markdown.d.ts.map +1 -0
- package/dist/app-debug/markdown.js +133 -0
- package/dist/app-debug/markdown.js.map +1 -0
- package/dist/app-debug/runtime.d.ts +267 -0
- package/dist/app-debug/runtime.d.ts.map +1 -0
- package/dist/app-debug/runtime.js +633 -0
- package/dist/app-debug/runtime.js.map +1 -0
- package/dist/app-debug/script-operation.d.ts +58 -0
- package/dist/app-debug/script-operation.d.ts.map +1 -0
- package/dist/app-debug/script-operation.js +44 -0
- package/dist/app-debug/script-operation.js.map +1 -0
- package/dist/app-debug/simulate.d.ts +85 -0
- package/dist/app-debug/simulate.d.ts.map +1 -0
- package/dist/app-debug/simulate.js +991 -0
- package/dist/app-debug/simulate.js.map +1 -0
- package/dist/app-debug/summarize.d.ts +64 -0
- package/dist/app-debug/summarize.d.ts.map +1 -0
- package/dist/app-debug/summarize.js +65 -0
- package/dist/app-debug/summarize.js.map +1 -0
- package/dist/app-debug/types.d.ts +343 -0
- package/dist/app-debug/types.d.ts.map +1 -0
- package/dist/app-debug/types.js +2 -0
- package/dist/app-debug/types.js.map +1 -0
- package/dist/cost-ledger.d.ts +147 -0
- package/dist/cost-ledger.d.ts.map +1 -0
- package/dist/cost-ledger.js +288 -0
- package/dist/cost-ledger.js.map +1 -0
- package/dist/debug/collector.d.ts +28 -0
- package/dist/debug/collector.d.ts.map +1 -0
- package/dist/debug/collector.js +284 -0
- package/dist/debug/collector.js.map +1 -0
- package/dist/debug/index.d.ts +15 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +16 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/debug/types.d.ts +179 -0
- package/dist/debug/types.d.ts.map +1 -0
- package/dist/debug/types.js +11 -0
- package/dist/debug/types.js.map +1 -0
- package/dist/debug/verdict.d.ts +27 -0
- package/dist/debug/verdict.d.ts.map +1 -0
- package/dist/debug/verdict.js +51 -0
- package/dist/debug/verdict.js.map +1 -0
- package/dist/executor-resolver.d.ts +13 -0
- package/dist/executor-resolver.d.ts.map +1 -0
- package/dist/executor-resolver.js +13 -0
- package/dist/executor-resolver.js.map +1 -0
- package/dist/fal-output-decoder.d.ts +36 -0
- package/dist/fal-output-decoder.d.ts.map +1 -0
- package/dist/fal-output-decoder.js +129 -0
- package/dist/fal-output-decoder.js.map +1 -0
- package/dist/generation-lifecycle.d.ts +54 -0
- package/dist/generation-lifecycle.d.ts.map +1 -0
- package/dist/generation-lifecycle.js +431 -0
- package/dist/generation-lifecycle.js.map +1 -0
- package/dist/generation-recovery-worker.d.ts +100 -0
- package/dist/generation-recovery-worker.d.ts.map +1 -0
- package/dist/generation-recovery-worker.js +995 -0
- package/dist/generation-recovery-worker.js.map +1 -0
- package/dist/generation-tracker.d.ts +83 -0
- package/dist/generation-tracker.d.ts.map +1 -0
- package/dist/generation-tracker.js +436 -0
- package/dist/generation-tracker.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/js-script-debug/index.d.ts +13 -0
- package/dist/js-script-debug/index.d.ts.map +1 -0
- package/dist/js-script-debug/index.js +12 -0
- package/dist/js-script-debug/index.js.map +1 -0
- package/dist/js-script-debug/markdown.d.ts +6 -0
- package/dist/js-script-debug/markdown.d.ts.map +1 -0
- package/dist/js-script-debug/markdown.js +62 -0
- package/dist/js-script-debug/markdown.js.map +1 -0
- package/dist/js-script-debug/outputs.d.ts +20 -0
- package/dist/js-script-debug/outputs.d.ts.map +1 -0
- package/dist/js-script-debug/outputs.js +30 -0
- package/dist/js-script-debug/outputs.js.map +1 -0
- package/dist/js-script-debug/report.d.ts +15 -0
- package/dist/js-script-debug/report.d.ts.map +1 -0
- package/dist/js-script-debug/report.js +90 -0
- package/dist/js-script-debug/report.js.map +1 -0
- package/dist/js-script-debug/types.d.ts +63 -0
- package/dist/js-script-debug/types.d.ts.map +1 -0
- package/dist/js-script-debug/types.js +10 -0
- package/dist/js-script-debug/types.js.map +1 -0
- package/dist/js-script-debug/validate.d.ts +38 -0
- package/dist/js-script-debug/validate.d.ts.map +1 -0
- package/dist/js-script-debug/validate.js +137 -0
- package/dist/js-script-debug/validate.js.map +1 -0
- package/dist/message-stream.d.ts +33 -0
- package/dist/message-stream.d.ts.map +1 -0
- package/dist/message-stream.js +58 -0
- package/dist/message-stream.js.map +1 -0
- package/dist/normalize-graph.d.ts +13 -0
- package/dist/normalize-graph.d.ts.map +1 -0
- package/dist/normalize-graph.js +63 -0
- package/dist/normalize-graph.js.map +1 -0
- package/dist/output-names.d.ts +13 -0
- package/dist/output-names.d.ts.map +1 -0
- package/dist/output-names.js +13 -0
- package/dist/output-names.js.map +1 -0
- package/dist/predicates.d.ts +6 -0
- package/dist/predicates.d.ts.map +1 -0
- package/dist/predicates.js +6 -0
- package/dist/predicates.js.map +1 -0
- package/dist/preflight.d.ts +87 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +139 -0
- package/dist/preflight.js.map +1 -0
- package/dist/provider-secret-key.d.ts +3 -0
- package/dist/provider-secret-key.d.ts.map +1 -0
- package/dist/provider-secret-key.js +7 -0
- package/dist/provider-secret-key.js.map +1 -0
- package/dist/service/app-debug-service.d.ts +78 -0
- package/dist/service/app-debug-service.d.ts.map +1 -0
- package/dist/service/app-debug-service.js +201 -0
- package/dist/service/app-debug-service.js.map +1 -0
- package/dist/service/app-run-server.d.ts +28 -0
- package/dist/service/app-run-server.d.ts.map +1 -0
- package/dist/service/app-run-server.js +104 -0
- package/dist/service/app-run-server.js.map +1 -0
- package/dist/service/debug-sessions.d.ts +158 -0
- package/dist/service/debug-sessions.d.ts.map +1 -0
- package/dist/service/debug-sessions.js +358 -0
- package/dist/service/debug-sessions.js.map +1 -0
- package/dist/service/index.d.ts +22 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/index.js +17 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/job-progress.d.ts +40 -0
- package/dist/service/job-progress.d.ts.map +1 -0
- package/dist/service/job-progress.js +53 -0
- package/dist/service/job-progress.js.map +1 -0
- package/dist/service/workflow-run.d.ts +279 -0
- package/dist/service/workflow-run.d.ts.map +1 -0
- package/dist/service/workflow-run.js +598 -0
- package/dist/service/workflow-run.js.map +1 -0
- package/dist/service/workflow-workspace.d.ts +89 -0
- package/dist/service/workflow-workspace.d.ts.map +1 -0
- package/dist/service/workflow-workspace.js +160 -0
- package/dist/service/workflow-workspace.js.map +1 -0
- package/dist/session.d.ts +62 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +353 -0
- package/dist/session.js.map +1 -0
- package/dist/sketch-debug/index.d.ts +11 -0
- package/dist/sketch-debug/index.d.ts.map +1 -0
- package/dist/sketch-debug/index.js +10 -0
- package/dist/sketch-debug/index.js.map +1 -0
- package/dist/sketch-debug/markdown.d.ts +6 -0
- package/dist/sketch-debug/markdown.d.ts.map +1 -0
- package/dist/sketch-debug/markdown.js +93 -0
- package/dist/sketch-debug/markdown.js.map +1 -0
- package/dist/sketch-debug/report.d.ts +15 -0
- package/dist/sketch-debug/report.d.ts.map +1 -0
- package/dist/sketch-debug/report.js +98 -0
- package/dist/sketch-debug/report.js.map +1 -0
- package/dist/sketch-debug/types.d.ts +62 -0
- package/dist/sketch-debug/types.d.ts.map +1 -0
- package/dist/sketch-debug/types.js +10 -0
- package/dist/sketch-debug/types.js.map +1 -0
- package/dist/sketch-debug/validate.d.ts +14 -0
- package/dist/sketch-debug/validate.d.ts.map +1 -0
- package/dist/sketch-debug/validate.js +478 -0
- package/dist/sketch-debug/validate.js.map +1 -0
- package/dist/supervisor.d.ts +45 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +97 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/timeline-debug/index.d.ts +11 -0
- package/dist/timeline-debug/index.d.ts.map +1 -0
- package/dist/timeline-debug/index.js +10 -0
- package/dist/timeline-debug/index.js.map +1 -0
- package/dist/timeline-debug/legibility.d.ts +23 -0
- package/dist/timeline-debug/legibility.d.ts.map +1 -0
- package/dist/timeline-debug/legibility.js +240 -0
- package/dist/timeline-debug/legibility.js.map +1 -0
- package/dist/timeline-debug/markdown.d.ts +6 -0
- package/dist/timeline-debug/markdown.d.ts.map +1 -0
- package/dist/timeline-debug/markdown.js +103 -0
- package/dist/timeline-debug/markdown.js.map +1 -0
- package/dist/timeline-debug/motion.d.ts +20 -0
- package/dist/timeline-debug/motion.d.ts.map +1 -0
- package/dist/timeline-debug/motion.js +362 -0
- package/dist/timeline-debug/motion.js.map +1 -0
- package/dist/timeline-debug/report.d.ts +16 -0
- package/dist/timeline-debug/report.d.ts.map +1 -0
- package/dist/timeline-debug/report.js +100 -0
- package/dist/timeline-debug/report.js.map +1 -0
- package/dist/timeline-debug/showcase.d.ts +7 -0
- package/dist/timeline-debug/showcase.d.ts.map +1 -0
- package/dist/timeline-debug/showcase.js +347 -0
- package/dist/timeline-debug/showcase.js.map +1 -0
- package/dist/timeline-debug/types.d.ts +64 -0
- package/dist/timeline-debug/types.d.ts.map +1 -0
- package/dist/timeline-debug/types.js +10 -0
- package/dist/timeline-debug/types.js.map +1 -0
- package/dist/timeline-debug/validate.d.ts +24 -0
- package/dist/timeline-debug/validate.d.ts.map +1 -0
- package/dist/timeline-debug/validate.js +1432 -0
- package/dist/timeline-debug/validate.js.map +1 -0
- package/dist/types.d.ts +211 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Workspace as WorkspaceRow } from "@nodetool-ai/models";
|
|
2
|
+
import { ProcessingContext, type StorageAdapter, type Workspace, type WorkspaceChange } from "@nodetool-ai/runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The host name the kernel's headless gate reports a denial under. Shared by
|
|
5
|
+
* the context built here and by `ExecutionSession.create`, which gates a
|
|
6
|
+
* caller's own context the same way when that caller set no gate.
|
|
7
|
+
*/
|
|
8
|
+
export declare const WORKFLOW_RUN_HOST = "kernel workflow run";
|
|
9
|
+
/** Called once at startup by a host that serves cloud workspaces. */
|
|
10
|
+
export declare function setWorkspaceCloudStorage(storage: StorageAdapter | null): void;
|
|
11
|
+
/** What a host is told when a run writes in a workspace. */
|
|
12
|
+
export interface WorkspaceFileChange extends WorkspaceChange {
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
userId: string;
|
|
15
|
+
}
|
|
16
|
+
/** Called once at startup by a host that pushes workspace changes to clients. */
|
|
17
|
+
export declare function setWorkspaceChangeNotifier(notify: ((change: WorkspaceFileChange) => void) | null): void;
|
|
18
|
+
/** Build the {@link Workspace} a workspace row describes. */
|
|
19
|
+
export declare function workspaceFromRow(row: WorkspaceRow): Workspace | null;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the workspace a run reads and writes in.
|
|
22
|
+
*
|
|
23
|
+
* Selection is stored on the workflow (`workflow.workspace_id`); this maps it
|
|
24
|
+
* to a {@link Workspace}, gated on ownership and the workspace still being
|
|
25
|
+
* usable. When the workflow names none — or there is no workflow at all, which
|
|
26
|
+
* is every chat turn — the run falls back to the user's default workspace,
|
|
27
|
+
* created on first use.
|
|
28
|
+
*
|
|
29
|
+
* What comes back is an interface, not a directory: a local install gets one
|
|
30
|
+
* over a real folder and a cloud deployment one over its object storage, and
|
|
31
|
+
* nothing downstream can tell which. It answers null only when the database or
|
|
32
|
+
* the storage refused, and a caller that gets null must report that rather than
|
|
33
|
+
* writing somewhere else.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveWorkflowWorkspace(workflowId: string | null, userId: string): Promise<Workspace | null>;
|
|
36
|
+
/**
|
|
37
|
+
* The directory a run's workspace lives in, or null when it is virtual.
|
|
38
|
+
*
|
|
39
|
+
* Only for the few callers that still need a real path (host binaries). Prefer
|
|
40
|
+
* {@link resolveWorkflowWorkspace} and the {@link Workspace} interface, which
|
|
41
|
+
* work on both deployments.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveWorkflowWorkspaceDir(workflowId: string | null, userId: string): Promise<string | null>;
|
|
44
|
+
/** True when this deployment keeps workspaces in object storage. */
|
|
45
|
+
export declare function usesCloudWorkspaces(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Build a minimal execution context carrying the resolved workspace, for run
|
|
48
|
+
* paths (REST / tRPC / MCP) that otherwise run without a ProcessingContext.
|
|
49
|
+
* The streaming WebSocket runner builds a richer context of its own; this keeps
|
|
50
|
+
* the workspace available everywhere else with the same resolution rules.
|
|
51
|
+
*
|
|
52
|
+
* The run's secrets come with it. Without a resolver `context.getSecret`
|
|
53
|
+
* answers `null` for every key and providers see only the process environment,
|
|
54
|
+
* so a key stored in the secret DB is invisible: an agent could generate an
|
|
55
|
+
* image in a chat turn and get a 401 from the same provider when it ran the
|
|
56
|
+
* workflow it had just built. The resolver is scoped to the run's own user,
|
|
57
|
+
* which is the only account whose secrets this run may read.
|
|
58
|
+
*
|
|
59
|
+
* So do the storage adapters. A context with none resolves no `asset://` ref
|
|
60
|
+
* at all — every uploaded image wired into a graph reached its node empty, and
|
|
61
|
+
* the node reported "The input image is empty". The host passes the same two
|
|
62
|
+
* adapters the streaming WebSocket runner uses; a host that passes neither
|
|
63
|
+
* keeps the old read-nothing behaviour rather than guessing at a backend.
|
|
64
|
+
*
|
|
65
|
+
* The context carries the headless permission gate, set here on purpose: a
|
|
66
|
+
* workflow run is consent — the user pressed Run on a graph whose nodes list
|
|
67
|
+
* their tools — so an agent loop inside it gates in `auto` with no human to
|
|
68
|
+
* ask, and every escalation the ladder raises is denied. Setting it
|
|
69
|
+
* explicitly is what lets `gateFromContext` in `@nodetool-ai/agents` treat a
|
|
70
|
+
* context with no gate as a bug and fail closed. A host that does have a
|
|
71
|
+
* user to ask — a chat turn — puts its own gate on the context it hands in
|
|
72
|
+
* and never comes through here.
|
|
73
|
+
*/
|
|
74
|
+
export declare function buildWorkspaceExecutionContext(opts: {
|
|
75
|
+
jobId: string;
|
|
76
|
+
workflowId?: string | null;
|
|
77
|
+
projectId?: string | null;
|
|
78
|
+
userId: string;
|
|
79
|
+
workspace: Workspace | null;
|
|
80
|
+
/** Overrides the per-user DB lookup (tests, a host with its own store). */
|
|
81
|
+
secretResolver?: (key: string, userId: string) => Promise<string | null | undefined> | string | null | undefined;
|
|
82
|
+
/** Temp store for runtime-materialized refs. */
|
|
83
|
+
storage?: StorageAdapter | null;
|
|
84
|
+
/** Asset store `asset://<id>` references resolve through. */
|
|
85
|
+
assetStorage?: StorageAdapter | null;
|
|
86
|
+
/** Enable the execution-owned FAL durable lifecycle for this host. */
|
|
87
|
+
durableFalGenerations?: boolean;
|
|
88
|
+
}): ProcessingContext;
|
|
89
|
+
//# sourceMappingURL=workflow-workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-workspace.d.ts","sourceRoot":"","sources":["../../src/service/workflow-workspace.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,IAAI,YAAY,EAE1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,iBAAiB,EAKjB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,sBAAsB,CAAC;AAK9B;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAWvD,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAE7E;AAED,4DAA4D;AAC5D,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAaD,iFAAiF;AACjF,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC,GAAG,IAAI,GACrD,IAAI,CAEN;AAED,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAkBpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAsB3B;AAED;;;;;;GAMG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExB;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,CACf,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpE,gDAAgD;IAChD,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,sEAAsE;IACtE,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,GAAG,iBAAiB,CAwBpB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { createLogger, workspaceStorageKind } from "@nodetool-ai/config";
|
|
2
|
+
import { Workflow, Workspace as WorkspaceRow, getSecret } from "@nodetool-ai/models";
|
|
3
|
+
import { PERMISSION_GATE_CONTEXT_KEY, ProcessingContext, createLocalWorkspace, createWorkspace, headlessGate, observeWorkspace } from "@nodetool-ai/runtime";
|
|
4
|
+
import { createFalGenerationLifecycleHooks } from "../generation-lifecycle.js";
|
|
5
|
+
const log = createLogger("nodetool.execution.workspace");
|
|
6
|
+
/**
|
|
7
|
+
* The host name the kernel's headless gate reports a denial under. Shared by
|
|
8
|
+
* the context built here and by `ExecutionSession.create`, which gates a
|
|
9
|
+
* caller's own context the same way when that caller set no gate.
|
|
10
|
+
*/
|
|
11
|
+
export const WORKFLOW_RUN_HOST = "kernel workflow run";
|
|
12
|
+
/**
|
|
13
|
+
* The object store a cloud deployment keeps workspaces in.
|
|
14
|
+
*
|
|
15
|
+
* Injected by the host rather than constructed here: `@nodetool-ai/execution`
|
|
16
|
+
* has no storage dependency, and the server already builds exactly one asset
|
|
17
|
+
* adapter it wants reused (connection pools, credentials).
|
|
18
|
+
*/
|
|
19
|
+
let cloudStorage = null;
|
|
20
|
+
/** Called once at startup by a host that serves cloud workspaces. */
|
|
21
|
+
export function setWorkspaceCloudStorage(storage) {
|
|
22
|
+
cloudStorage = storage;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Told about every file a run writes, so a host can push the change to a
|
|
26
|
+
* client watching that workspace.
|
|
27
|
+
*
|
|
28
|
+
* Injected the way {@link setWorkspaceCloudStorage} is: `@nodetool-ai/execution`
|
|
29
|
+
* has no websocket to broadcast on, and the workspace row id — which the
|
|
30
|
+
* {@link Workspace} interface deliberately does not carry — is known only here,
|
|
31
|
+
* where the row is read.
|
|
32
|
+
*/
|
|
33
|
+
let changeNotifier = null;
|
|
34
|
+
/** Called once at startup by a host that pushes workspace changes to clients. */
|
|
35
|
+
export function setWorkspaceChangeNotifier(notify) {
|
|
36
|
+
changeNotifier = notify;
|
|
37
|
+
}
|
|
38
|
+
/** Build the {@link Workspace} a workspace row describes. */
|
|
39
|
+
export function workspaceFromRow(row) {
|
|
40
|
+
const workspace = !row.isVirtual()
|
|
41
|
+
? createLocalWorkspace(row.path)
|
|
42
|
+
: cloudStorage
|
|
43
|
+
? createWorkspace(cloudStorage, { prefix: row.path })
|
|
44
|
+
: null;
|
|
45
|
+
if (!workspace) {
|
|
46
|
+
log.warn("A virtual workspace was requested but no cloud storage is configured", { workspaceId: row.id });
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const notify = changeNotifier;
|
|
50
|
+
if (!notify)
|
|
51
|
+
return workspace;
|
|
52
|
+
return observeWorkspace(workspace, (change) => notify({ ...change, workspaceId: row.id, userId: row.user_id }));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the workspace a run reads and writes in.
|
|
56
|
+
*
|
|
57
|
+
* Selection is stored on the workflow (`workflow.workspace_id`); this maps it
|
|
58
|
+
* to a {@link Workspace}, gated on ownership and the workspace still being
|
|
59
|
+
* usable. When the workflow names none — or there is no workflow at all, which
|
|
60
|
+
* is every chat turn — the run falls back to the user's default workspace,
|
|
61
|
+
* created on first use.
|
|
62
|
+
*
|
|
63
|
+
* What comes back is an interface, not a directory: a local install gets one
|
|
64
|
+
* over a real folder and a cloud deployment one over its object storage, and
|
|
65
|
+
* nothing downstream can tell which. It answers null only when the database or
|
|
66
|
+
* the storage refused, and a caller that gets null must report that rather than
|
|
67
|
+
* writing somewhere else.
|
|
68
|
+
*/
|
|
69
|
+
export async function resolveWorkflowWorkspace(workflowId, userId) {
|
|
70
|
+
try {
|
|
71
|
+
if (workflowId) {
|
|
72
|
+
const workflow = await Workflow.find(userId, workflowId);
|
|
73
|
+
if (workflow?.workspace_id) {
|
|
74
|
+
const row = await WorkspaceRow.find(userId, workflow.workspace_id);
|
|
75
|
+
if (row?.isAccessible() && row.project_id === workflow.project_id) {
|
|
76
|
+
const workspace = workspaceFromRow(row);
|
|
77
|
+
if (workspace)
|
|
78
|
+
return workspace;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const fallback = await WorkspaceRow.ensureDefault(userId);
|
|
83
|
+
return fallback.isAccessible() ? workspaceFromRow(fallback) : null;
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
log.warn("Failed to resolve run workspace", {
|
|
87
|
+
workflowId,
|
|
88
|
+
userId,
|
|
89
|
+
error: err instanceof Error ? err.message : String(err)
|
|
90
|
+
});
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The directory a run's workspace lives in, or null when it is virtual.
|
|
96
|
+
*
|
|
97
|
+
* Only for the few callers that still need a real path (host binaries). Prefer
|
|
98
|
+
* {@link resolveWorkflowWorkspace} and the {@link Workspace} interface, which
|
|
99
|
+
* work on both deployments.
|
|
100
|
+
*/
|
|
101
|
+
export async function resolveWorkflowWorkspaceDir(workflowId, userId) {
|
|
102
|
+
return (await resolveWorkflowWorkspace(workflowId, userId))?.localDir ?? null;
|
|
103
|
+
}
|
|
104
|
+
/** True when this deployment keeps workspaces in object storage. */
|
|
105
|
+
export function usesCloudWorkspaces() {
|
|
106
|
+
return workspaceStorageKind() === "cloud";
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build a minimal execution context carrying the resolved workspace, for run
|
|
110
|
+
* paths (REST / tRPC / MCP) that otherwise run without a ProcessingContext.
|
|
111
|
+
* The streaming WebSocket runner builds a richer context of its own; this keeps
|
|
112
|
+
* the workspace available everywhere else with the same resolution rules.
|
|
113
|
+
*
|
|
114
|
+
* The run's secrets come with it. Without a resolver `context.getSecret`
|
|
115
|
+
* answers `null` for every key and providers see only the process environment,
|
|
116
|
+
* so a key stored in the secret DB is invisible: an agent could generate an
|
|
117
|
+
* image in a chat turn and get a 401 from the same provider when it ran the
|
|
118
|
+
* workflow it had just built. The resolver is scoped to the run's own user,
|
|
119
|
+
* which is the only account whose secrets this run may read.
|
|
120
|
+
*
|
|
121
|
+
* So do the storage adapters. A context with none resolves no `asset://` ref
|
|
122
|
+
* at all — every uploaded image wired into a graph reached its node empty, and
|
|
123
|
+
* the node reported "The input image is empty". The host passes the same two
|
|
124
|
+
* adapters the streaming WebSocket runner uses; a host that passes neither
|
|
125
|
+
* keeps the old read-nothing behaviour rather than guessing at a backend.
|
|
126
|
+
*
|
|
127
|
+
* The context carries the headless permission gate, set here on purpose: a
|
|
128
|
+
* workflow run is consent — the user pressed Run on a graph whose nodes list
|
|
129
|
+
* their tools — so an agent loop inside it gates in `auto` with no human to
|
|
130
|
+
* ask, and every escalation the ladder raises is denied. Setting it
|
|
131
|
+
* explicitly is what lets `gateFromContext` in `@nodetool-ai/agents` treat a
|
|
132
|
+
* context with no gate as a bug and fail closed. A host that does have a
|
|
133
|
+
* user to ask — a chat turn — puts its own gate on the context it hands in
|
|
134
|
+
* and never comes through here.
|
|
135
|
+
*/
|
|
136
|
+
export function buildWorkspaceExecutionContext(opts) {
|
|
137
|
+
const generationLifecycle = opts.durableFalGenerations
|
|
138
|
+
? createFalGenerationLifecycleHooks({
|
|
139
|
+
userId: opts.userId,
|
|
140
|
+
jobId: opts.jobId,
|
|
141
|
+
projectId: opts.projectId,
|
|
142
|
+
publicUrl: process.env["NODETOOL_PUBLIC_URL"] ?? null
|
|
143
|
+
})
|
|
144
|
+
: undefined;
|
|
145
|
+
const context = new ProcessingContext({
|
|
146
|
+
jobId: opts.jobId,
|
|
147
|
+
workflowId: opts.workflowId ?? null,
|
|
148
|
+
projectId: opts.projectId ?? null,
|
|
149
|
+
userId: opts.userId,
|
|
150
|
+
workspace: opts.workspace,
|
|
151
|
+
storage: opts.storage ?? null,
|
|
152
|
+
assetStorage: opts.assetStorage ?? null,
|
|
153
|
+
secretResolver: opts.secretResolver ??
|
|
154
|
+
((key, userId) => getSecret(key, userId)),
|
|
155
|
+
generationLifecycle
|
|
156
|
+
});
|
|
157
|
+
context.set(PERMISSION_GATE_CONTEXT_KEY, headlessGate(WORKFLOW_RUN_HOST));
|
|
158
|
+
return context;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=workflow-workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-workspace.js","sourceRoot":"","sources":["../../src/service/workflow-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type RunResult } from "@nodetool-ai/kernel";
|
|
2
|
+
import type { HydratedGraphData, ProcessingMessage } from "@nodetool-ai/protocol";
|
|
3
|
+
import type { ExecutionSessionOptions } from "./types.js";
|
|
4
|
+
export declare class ExecutionSession {
|
|
5
|
+
readonly jobId: string;
|
|
6
|
+
readonly workflowId: string | null;
|
|
7
|
+
readonly graph: HydratedGraphData;
|
|
8
|
+
private readonly runner;
|
|
9
|
+
/** Null unless the caller opted into `captureMessages` (see options). */
|
|
10
|
+
private readonly stream;
|
|
11
|
+
private readonly persistence;
|
|
12
|
+
private readonly bridge;
|
|
13
|
+
private readonly resultPromise;
|
|
14
|
+
private runTimeoutHandle;
|
|
15
|
+
private _cancelReason;
|
|
16
|
+
private constructor();
|
|
17
|
+
/** Map a kernel run status onto the `job.end` reason. */
|
|
18
|
+
private endReason;
|
|
19
|
+
static create(options: ExecutionSessionOptions): Promise<ExecutionSession>;
|
|
20
|
+
/**
|
|
21
|
+
* Live message stream — closes once the run reaches a terminal state.
|
|
22
|
+
* Requires `captureMessages: true` at `create()`; without it nothing is
|
|
23
|
+
* queued (see that option) and reading this throws rather than handing back
|
|
24
|
+
* a stream that would silently yield nothing.
|
|
25
|
+
*/
|
|
26
|
+
get messages(): AsyncIterable<ProcessingMessage>;
|
|
27
|
+
/** The run's terminal result. Never rejects — kernel failures resolve as `status: "failed"`. */
|
|
28
|
+
get result(): Promise<RunResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Live resource counts, for leak accounting: after a terminal result every
|
|
31
|
+
* one of these must be back to zero. Measured, not inferred — the
|
|
32
|
+
* reliability harness's `cleanup-leaks` invariant asserts against these
|
|
33
|
+
* numbers and reports a violation when a driver can't produce them.
|
|
34
|
+
*/
|
|
35
|
+
resourceCounters(): {
|
|
36
|
+
liveActors: number;
|
|
37
|
+
pendingControlResponses: number;
|
|
38
|
+
pendingTimers: number;
|
|
39
|
+
pythonBridgePendingRequests: number;
|
|
40
|
+
};
|
|
41
|
+
/** The reason passed to the most recent `cancel()` call, if any. */
|
|
42
|
+
get cancelReason(): string | null;
|
|
43
|
+
/** Stream one more value into a live input node (mirrors the WS `stream_input` command). */
|
|
44
|
+
pushInput(inputName: string, value: unknown, sourceHandle?: string): Promise<void>;
|
|
45
|
+
/** Signal end-of-stream for a live input node (mirrors `end_input_stream`). */
|
|
46
|
+
finishInputStream(inputName: string, sourceHandle?: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Push property updates into a running node's executor instance (live
|
|
49
|
+
* parameter changes, e.g. a synth knob while a patch plays — mirrors the
|
|
50
|
+
* WS runner's `update_node_properties` command). Returns `true` when the
|
|
51
|
+
* node's executor exists and supports live updates; `false` is not an
|
|
52
|
+
* error — the caller's own state already holds the new value for the next
|
|
53
|
+
* run.
|
|
54
|
+
*/
|
|
55
|
+
updateNodeProperties(nodeId: string, properties: Record<string, unknown>): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* The only cancel path. `runTimeoutMs` is implemented as
|
|
58
|
+
* `cancel("timeout")` — there is no separate timeout code path.
|
|
59
|
+
*/
|
|
60
|
+
cancel(reason?: string): void;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAI1D,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,eAiIN;IAED,yDAAyD;IACzD,OAAO,CAAC,SAAS;IAQjB,OAAa,MAAM,CACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAsK3B;IAED;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,aAAa,CAAC,iBAAiB,CAAC,CAS/C;IAED,gGAAgG;IAChG,IAAI,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC,CAE/B;IAED;;;;;OAKG;IACH,gBAAgB;;;;;MASf;IAED,oEAAoE;IACpE,IAAI,YAAY,IAAI,MAAM,GAAG,IAAI,CAEhC;IAED,4FAA4F;IAC5F,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAEf;IAED,+EAA+E;IAC/E,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAEhE;IAED;;;;;;;OAOG;IACH,oBAAoB,CAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAET;IAED;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAG5B;CACF"}
|