@bastani/atomic 0.9.25-alpha.2 → 0.9.25-alpha.4
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/CHANGELOG.md +55 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +43 -0
- package/dist/builtin/mcp/OAUTH.md +59 -269
- package/dist/builtin/mcp/README.md +58 -345
- package/dist/builtin/mcp/index.bundle.mjs +4 -27792
- package/dist/builtin/mcp/native-client-licenses/LICENSES/modelcontextprotocol-typescript-sdk.txt +21 -0
- package/dist/builtin/mcp/native-client-licenses/NOTICE +30 -0
- package/dist/builtin/mcp/package.json +4 -25
- package/dist/builtin/subagents/package.json +3 -3
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/builtin/{chunk-e1254zvd.js → chunk-kfsnh3w7.js} +40 -12
- package/dist/builtin/workflows/builtin/{chunk-cpw5gtzg.js → chunk-rqmasd3d.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-qy6g0baf.js → chunk-wz783pvd.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +472 -88
- package/dist/builtin/workflows/src/index.js +65 -28
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-accessors.d.ts.map +1 -1
- package/dist/core/agent-session-accessors.js +7 -0
- package/dist/core/agent-session-accessors.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +103 -7
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +7 -1
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-state.d.ts.map +1 -1
- package/dist/core/agent-session-state.js +3 -2
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +6 -3
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +1 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/api-types.d.ts +3 -0
- package/dist/core/extensions/api-types.d.ts.map +1 -1
- package/dist/core/extensions/api-types.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +3 -1
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -0
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -0
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-api.d.ts.map +1 -1
- package/dist/core/extensions/loader-api.js +15 -0
- package/dist/core/extensions/loader-api.js.map +1 -1
- package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
- package/dist/core/extensions/loader-runtime.js +3 -0
- package/dist/core/extensions/loader-runtime.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +3 -0
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/mcp-server-registry.d.ts.map +1 -1
- package/dist/core/extensions/mcp-server-registry.js +4 -0
- package/dist/core/extensions/mcp-server-registry.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +4 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +3 -0
- package/dist/core/extensions/runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/runtime-types.js.map +1 -1
- package/dist/core/extensions/tool-types.d.ts +1 -0
- package/dist/core/extensions/tool-types.d.ts.map +1 -1
- package/dist/core/extensions/tool-types.js.map +1 -1
- package/dist/core/extensions/workflow-run-control-hub.d.ts +23 -0
- package/dist/core/extensions/workflow-run-control-hub.d.ts.map +1 -0
- package/dist/core/extensions/workflow-run-control-hub.js +57 -0
- package/dist/core/extensions/workflow-run-control-hub.js.map +1 -0
- package/dist/core/extensions/workflow-run-control.d.ts +163 -0
- package/dist/core/extensions/workflow-run-control.d.ts.map +1 -0
- package/dist/core/extensions/workflow-run-control.js +73 -0
- package/dist/core/extensions/workflow-run-control.js.map +1 -0
- package/dist/core/mcp-child-policy.d.ts +11 -0
- package/dist/core/mcp-child-policy.d.ts.map +1 -0
- package/dist/core/mcp-child-policy.js +31 -0
- package/dist/core/mcp-child-policy.js.map +1 -0
- package/dist/core/mcp-servers.d.ts +34 -25
- package/dist/core/mcp-servers.d.ts.map +1 -1
- package/dist/core/mcp-servers.js +148 -1
- package/dist/core/mcp-servers.js.map +1 -1
- package/dist/core/package-manager-manifest.js.map +1 -1
- package/dist/core/package-manager-mcp-servers.js +1 -1
- package/dist/core/package-manager-mcp-servers.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +4 -9
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/tool-loadout.d.ts +1 -0
- package/dist/core/tool-loadout.d.ts.map +1 -1
- package/dist/core/tool-loadout.js +3 -0
- package/dist/core/tool-loadout.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -30
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +8 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +24 -0
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +26 -0
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/renderer.d.ts.map +1 -1
- package/dist/extensions/codemode/renderer.js +38 -23
- package/dist/extensions/codemode/renderer.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +22 -10
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts +21 -0
- package/dist/extensions/mcp/cli.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.js +500 -0
- package/dist/extensions/mcp/cli.js.map +1 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.lazy.js +3 -0
- package/dist/extensions/mcp/cli.lazy.js.map +1 -0
- package/dist/extensions/mcp/client/auth-provider.d.ts +15 -0
- package/dist/extensions/mcp/client/auth-provider.d.ts.map +1 -0
- package/dist/extensions/mcp/client/auth-provider.js +2 -0
- package/dist/extensions/mcp/client/auth-provider.js.map +1 -0
- package/dist/extensions/mcp/client/client.d.ts +89 -0
- package/dist/extensions/mcp/client/client.d.ts.map +1 -0
- package/dist/extensions/mcp/client/client.js +457 -0
- package/dist/extensions/mcp/client/client.js.map +1 -0
- package/dist/extensions/mcp/client/index.d.ts +9 -0
- package/dist/extensions/mcp/client/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/index.js +7 -0
- package/dist/extensions/mcp/client/index.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/callback.d.ts +42 -0
- package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/callback.js +106 -0
- package/dist/extensions/mcp/client/oauth/callback.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/discovery.d.ts +27 -0
- package/dist/extensions/mcp/client/oauth/discovery.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/discovery.js +153 -0
- package/dist/extensions/mcp/client/oauth/discovery.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/errors.d.ts +24 -0
- package/dist/extensions/mcp/client/oauth/errors.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/errors.js +46 -0
- package/dist/extensions/mcp/client/oauth/errors.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/flow.d.ts +82 -0
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/flow.js +292 -0
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/index.d.ts +7 -0
- package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/index.js +6 -0
- package/dist/extensions/mcp/client/oauth/index.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/provider.d.ts +59 -0
- package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/provider.js +116 -0
- package/dist/extensions/mcp/client/oauth/provider.js.map +1 -0
- package/dist/extensions/mcp/client/oauth/types.d.ts +77 -0
- package/dist/extensions/mcp/client/oauth/types.d.ts.map +1 -0
- package/dist/extensions/mcp/client/oauth/types.js +109 -0
- package/dist/extensions/mcp/client/oauth/types.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/content.d.ts +82 -0
- package/dist/extensions/mcp/client/protocol/content.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/content.js +41 -0
- package/dist/extensions/mcp/client/protocol/content.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts +59 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.js +67 -0
- package/dist/extensions/mcp/client/protocol/jsonrpc.js.map +1 -0
- package/dist/extensions/mcp/client/protocol/types.d.ts +123 -0
- package/dist/extensions/mcp/client/protocol/types.d.ts.map +1 -0
- package/dist/extensions/mcp/client/protocol/types.js +7 -0
- package/dist/extensions/mcp/client/protocol/types.js.map +1 -0
- package/dist/extensions/mcp/client/testing/index.d.ts +2 -0
- package/dist/extensions/mcp/client/testing/index.d.ts.map +1 -0
- package/dist/extensions/mcp/client/testing/index.js +2 -0
- package/dist/extensions/mcp/client/testing/index.js.map +1 -0
- package/dist/extensions/mcp/client/transports/in-memory.d.ts +19 -0
- package/dist/extensions/mcp/client/transports/in-memory.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/in-memory.js +50 -0
- package/dist/extensions/mcp/client/transports/in-memory.js.map +1 -0
- package/dist/extensions/mcp/client/transports/stdio.d.ts +32 -0
- package/dist/extensions/mcp/client/transports/stdio.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/stdio.js +201 -0
- package/dist/extensions/mcp/client/transports/stdio.js.map +1 -0
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts +96 -0
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/streamable-http.js +456 -0
- package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -0
- package/dist/extensions/mcp/client/transports/transport.d.ts +28 -0
- package/dist/extensions/mcp/client/transports/transport.d.ts.map +1 -0
- package/dist/extensions/mcp/client/transports/transport.js +38 -0
- package/dist/extensions/mcp/client/transports/transport.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +72 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +158 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +76 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +1119 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/extensions/mcp/log.d.ts +16 -0
- package/dist/extensions/mcp/log.d.ts.map +1 -0
- package/dist/extensions/mcp/log.js +66 -0
- package/dist/extensions/mcp/log.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +103 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +382 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/resources.d.ts +43 -0
- package/dist/extensions/mcp/resources.d.ts.map +1 -0
- package/dist/extensions/mcp/resources.js +262 -0
- package/dist/extensions/mcp/resources.js.map +1 -0
- package/dist/extensions/mcp/runtime.d.ts +104 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.js +546 -0
- package/dist/extensions/mcp/runtime.js.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.js +3 -0
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +84 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.js +251 -0
- package/dist/extensions/mcp/tools.js.map +1 -0
- package/dist/extensions/mcp/ui.d.ts +60 -0
- package/dist/extensions/mcp/ui.d.ts.map +1 -0
- package/dist/extensions/mcp/ui.js +175 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +1 -1
- package/dist/extensions/tool-search/tool.d.ts.map +1 -1
- package/dist/extensions/tool-search/tool.js +3 -13
- package/dist/extensions/tool-search/tool.js.map +1 -1
- package/dist/index-extensions.d.ts +2 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +7 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +39 -6
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/docs/extensions/api-reference.md +3 -3
- package/docs/extensions/events.md +2 -0
- package/docs/extensions.md +8 -8
- package/docs/mcp-servers.md +171 -50
- package/docs/packages/authoring.md +2 -2
- package/docs/providers.md +8 -0
- package/docs/sdk/reference.md +16 -0
- package/docs/sdk.md +67 -1
- package/docs/settings.md +2 -0
- package/docs/tools.md +6 -0
- package/docs/workflows/operations.md +3 -1
- package/examples/extensions/built-in-tool-renderer.ts +16 -40
- package/examples/extensions/minimal-mode.ts +28 -108
- package/npm-shrinkwrap.json +69 -69
- package/package.json +8 -8
- package/dist/builtin/mcp/app-bridge.bundle.js +0 -67
- package/dist/builtin/mcp/xdg-open +0 -1267
|
@@ -30558,7 +30558,7 @@ function createRecoverablePostgresPool(initialUrl, options = {}) {
|
|
|
30558
30558
|
release(true);
|
|
30559
30559
|
for (const { client } of held) {
|
|
30560
30560
|
if (client.listenerCount("error") > 0) {
|
|
30561
|
-
client.emit("error", new
|
|
30561
|
+
client.emit("error", new DbosDependencyError("Postgres dependency invalidated"));
|
|
30562
30562
|
}
|
|
30563
30563
|
}
|
|
30564
30564
|
}
|
|
@@ -30674,6 +30674,7 @@ function createRecoverablePostgresPool(initialUrl, options = {}) {
|
|
|
30674
30674
|
var import_datasource;
|
|
30675
30675
|
var init_dbos_recoverable_pool = __esm(() => {
|
|
30676
30676
|
init_esm();
|
|
30677
|
+
init_dbos_admission();
|
|
30677
30678
|
import_datasource = __toESM(require_datasource(), 1);
|
|
30678
30679
|
});
|
|
30679
30680
|
|
|
@@ -87745,6 +87746,9 @@ function isMonitoringConnectionFailure(error) {
|
|
|
87745
87746
|
return ["ECONNREFUSED", "ECONNRESET", "EPIPE", "ETIMEDOUT", "57P01", "57P02", "57P03"].includes(String(error.code));
|
|
87746
87747
|
return error.message === "timeout expired" || error.message === "Connection terminated due to connection timeout";
|
|
87747
87748
|
}
|
|
87749
|
+
function isQueryReadTimeout(error) {
|
|
87750
|
+
return error instanceof Error && error.message === "Query read timeout";
|
|
87751
|
+
}
|
|
87748
87752
|
|
|
87749
87753
|
class PostgresHealth {
|
|
87750
87754
|
operations;
|
|
@@ -87777,11 +87781,20 @@ class PostgresHealth {
|
|
|
87777
87781
|
try {
|
|
87778
87782
|
if (this.stopped)
|
|
87779
87783
|
throw new DbosDependencyError;
|
|
87780
|
-
|
|
87784
|
+
try {
|
|
87785
|
+
await this.operations.validate?.(client);
|
|
87786
|
+
} catch (error) {
|
|
87787
|
+
if (!isQueryReadTimeout(error) || this.stopped)
|
|
87788
|
+
throw error;
|
|
87789
|
+
await this.operations.validate?.(client);
|
|
87790
|
+
}
|
|
87781
87791
|
} catch (error) {
|
|
87782
87792
|
this.failure = error instanceof Error ? error : new Error(String(error));
|
|
87783
|
-
|
|
87784
|
-
|
|
87793
|
+
if (!isQueryReadTimeout(error)) {
|
|
87794
|
+
this.invalidate();
|
|
87795
|
+
throw error;
|
|
87796
|
+
}
|
|
87797
|
+
throw new DbosDependencyError("Managed PostgreSQL did not answer a connection identity check in time.");
|
|
87785
87798
|
}
|
|
87786
87799
|
}
|
|
87787
87800
|
check() {
|
|
@@ -87815,7 +87828,7 @@ class PostgresHealth {
|
|
|
87815
87828
|
try {
|
|
87816
87829
|
identity = await this.operations.probe();
|
|
87817
87830
|
} catch (error) {
|
|
87818
|
-
if (!isMonitoringConnectionFailure(error) || this.stopped)
|
|
87831
|
+
if (!(isMonitoringConnectionFailure(error) || isQueryReadTimeout(error)) || this.stopped)
|
|
87819
87832
|
throw error;
|
|
87820
87833
|
try {
|
|
87821
87834
|
identity = await this.operations.probe();
|
|
@@ -87845,6 +87858,10 @@ class PostgresHealth {
|
|
|
87845
87858
|
if (ready !== undefined)
|
|
87846
87859
|
return ready;
|
|
87847
87860
|
} catch (error) {
|
|
87861
|
+
if (isQueryReadTimeout(error)) {
|
|
87862
|
+
this.failure = new DbosDependencyError("Managed PostgreSQL did not answer a health check in time.");
|
|
87863
|
+
throw this.failure;
|
|
87864
|
+
}
|
|
87848
87865
|
this.failure = error instanceof Error ? error : new Error(String(error));
|
|
87849
87866
|
if (!(error instanceof Error && ("code" in error) && error.code === "53300"))
|
|
87850
87867
|
this.invalidate();
|
|
@@ -88108,6 +88125,7 @@ var POSTGRES_IDENTITY_SQL = `SELECT current_setting('data_directory') AS data_di
|
|
|
88108
88125
|
split_part(pg_read_file('postmaster.pid'), E'\\n', 3) AS started,
|
|
88109
88126
|
system_identifier::text, current_setting('server_version') AS server_version FROM pg_control_system()`;
|
|
88110
88127
|
var POSTGRES_TIMEZONE_SQL = "SELECT set_config('timezone_abbreviations', 'Default', true)";
|
|
88128
|
+
var POSTGRES_HEALTH_QUERY_TIMEOUT_MS = 3000;
|
|
88111
88129
|
async function probePostgresTimezoneData(port) {
|
|
88112
88130
|
const client = new Client({
|
|
88113
88131
|
host: "127.0.0.1",
|
|
@@ -88117,8 +88135,8 @@ async function probePostgresTimezoneData(port) {
|
|
|
88117
88135
|
database: "postgres",
|
|
88118
88136
|
ssl: false,
|
|
88119
88137
|
connectionTimeoutMillis: 1000,
|
|
88120
|
-
query_timeout:
|
|
88121
|
-
statement_timeout:
|
|
88138
|
+
query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS,
|
|
88139
|
+
statement_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS
|
|
88122
88140
|
});
|
|
88123
88141
|
client.on("error", () => {});
|
|
88124
88142
|
try {
|
|
@@ -88137,8 +88155,8 @@ async function probePostgresIdentity(port) {
|
|
|
88137
88155
|
database: "postgres",
|
|
88138
88156
|
ssl: false,
|
|
88139
88157
|
connectionTimeoutMillis: 1000,
|
|
88140
|
-
query_timeout:
|
|
88141
|
-
statement_timeout:
|
|
88158
|
+
query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS,
|
|
88159
|
+
statement_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS
|
|
88142
88160
|
});
|
|
88143
88161
|
client.on("error", () => {});
|
|
88144
88162
|
try {
|
|
@@ -88146,6 +88164,8 @@ async function probePostgresIdentity(port) {
|
|
|
88146
88164
|
const result = await client.query(POSTGRES_IDENTITY_SQL);
|
|
88147
88165
|
return result.rows[0];
|
|
88148
88166
|
} catch (error) {
|
|
88167
|
+
if (isQueryReadTimeout(error))
|
|
88168
|
+
throw error;
|
|
88149
88169
|
const code = error instanceof Error && "code" in error ? error.code : undefined;
|
|
88150
88170
|
if (code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "57P01" || code === "57P02" || code === "57P03" || error instanceof Error && /timeout|timed out|connection terminated/i.test(error.message))
|
|
88151
88171
|
return;
|
|
@@ -88313,6 +88333,15 @@ async function ensureCluster(options = {}) {
|
|
|
88313
88333
|
}
|
|
88314
88334
|
let verified;
|
|
88315
88335
|
const existingServerProbe = () => options.probeIdentity ?? probePostgresIdentity;
|
|
88336
|
+
const startupServerProbe = async (probePort) => {
|
|
88337
|
+
try {
|
|
88338
|
+
return await existingServerProbe()(probePort);
|
|
88339
|
+
} catch (error) {
|
|
88340
|
+
if (isQueryReadTimeout(error))
|
|
88341
|
+
return;
|
|
88342
|
+
throw error;
|
|
88343
|
+
}
|
|
88344
|
+
};
|
|
88316
88345
|
let prepared = options.prepared ? options.binaries : undefined;
|
|
88317
88346
|
let selectedIdentity = options.runtimeIdentity;
|
|
88318
88347
|
let reservedLiveGeneration;
|
|
@@ -88433,7 +88462,7 @@ async function ensureCluster(options = {}) {
|
|
|
88433
88462
|
}
|
|
88434
88463
|
} else if (existing) {
|
|
88435
88464
|
await waitForClusterReadiness(logFile, undefined, async () => {
|
|
88436
|
-
verified = await verifyPostgresIdentity(metadata, port, existing.pid,
|
|
88465
|
+
verified = await verifyPostgresIdentity(metadata, port, existing.pid, startupServerProbe);
|
|
88437
88466
|
return verified !== undefined || managedPostmaster(metadata) === undefined;
|
|
88438
88467
|
}, READY_ATTEMPTS, delay, port, dataDir);
|
|
88439
88468
|
}
|
|
@@ -88465,7 +88494,7 @@ async function ensureCluster(options = {}) {
|
|
|
88465
88494
|
startedCluster = { lease };
|
|
88466
88495
|
activeCluster = startedCluster;
|
|
88467
88496
|
await waitForClusterReadiness(logFile, startedCluster, async () => {
|
|
88468
|
-
verified = await verifyPostgresIdentity(metadata, port, lease.pid,
|
|
88497
|
+
verified = await verifyPostgresIdentity(metadata, port, lease.pid, startupServerProbe);
|
|
88469
88498
|
return verified !== undefined;
|
|
88470
88499
|
}, READY_ATTEMPTS, delay, port, dataDir);
|
|
88471
88500
|
break;
|
|
@@ -88534,14 +88563,14 @@ async function ensureCluster(options = {}) {
|
|
|
88534
88563
|
probe: () => inspect(),
|
|
88535
88564
|
validate: async (client) => {
|
|
88536
88565
|
const identity = await inspect(async () => {
|
|
88537
|
-
const query = { text: POSTGRES_IDENTITY_SQL, query_timeout:
|
|
88566
|
+
const query = { text: POSTGRES_IDENTITY_SQL, query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS };
|
|
88538
88567
|
const result = await client.query(query);
|
|
88539
88568
|
return result.rows[0];
|
|
88540
88569
|
});
|
|
88541
88570
|
if (!identity)
|
|
88542
88571
|
throw new DbosDependencyError;
|
|
88543
88572
|
if (options.probeIdentity === undefined) {
|
|
88544
|
-
const query = { text: POSTGRES_TIMEZONE_SQL, query_timeout:
|
|
88573
|
+
const query = { text: POSTGRES_TIMEZONE_SQL, query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS };
|
|
88545
88574
|
await client.query(query);
|
|
88546
88575
|
}
|
|
88547
88576
|
},
|
|
@@ -92489,6 +92518,11 @@ async function resumeRun(runId, opts) {
|
|
|
92489
92518
|
...acknowledgementMessage !== undefined ? { message: acknowledgementMessage } : {}
|
|
92490
92519
|
};
|
|
92491
92520
|
}
|
|
92521
|
+
function isRunFullyPaused(activeStore, runId, controlRunIds) {
|
|
92522
|
+
const runs = activeStore.runs();
|
|
92523
|
+
const hasLiveStage = controlRunIds.some((controlRunId) => runs.find((candidate) => candidate.id === controlRunId)?.stages.some((stage) => stage.status === "running" || stage.status === "pending") === true);
|
|
92524
|
+
return !hasLiveStage && runs.find((candidate) => candidate.id === runId)?.status === "paused";
|
|
92525
|
+
}
|
|
92492
92526
|
async function pauseRunWithAction(runId, opts, action = "pause") {
|
|
92493
92527
|
const activeStore = opts?.store ?? store;
|
|
92494
92528
|
const registry = opts?.stageControlRegistry ?? stageControlRegistry;
|
|
@@ -92531,7 +92565,11 @@ async function pauseRunWithAction(runId, opts, action = "pause") {
|
|
|
92531
92565
|
message: `Run ${runId} paused (${run.controlPersistence ?? "observed"}). ${run.controlPersistence === "durable" ? "Database persistence confirmed." : "Pause observed locally, not confirmed persisted."} Resume with /workflow resume on this live process; untracked initialization or workflow code may still finish, but further workflow steps and completion wait for resume. Cross-process resume requires durable checkpoint or pending prompt progress.`
|
|
92532
92566
|
};
|
|
92533
92567
|
}
|
|
92534
|
-
return {
|
|
92568
|
+
return {
|
|
92569
|
+
ok: false,
|
|
92570
|
+
runId,
|
|
92571
|
+
reason: isRunFullyPaused(activeStore, runId, controlRunIds) ? "already_paused" : "no_active_stages"
|
|
92572
|
+
};
|
|
92535
92573
|
}
|
|
92536
92574
|
const paused = [];
|
|
92537
92575
|
const pausedRunIds = new Set;
|
|
@@ -92574,12 +92612,22 @@ async function pauseRun(runId, opts) {
|
|
|
92574
92612
|
async function pauseAllRuns(opts) {
|
|
92575
92613
|
const activeStore = opts?.store ?? store;
|
|
92576
92614
|
const inFlight = topLevelWorkflowRuns(activeStore.runs()).filter((run) => run.endedAt === undefined);
|
|
92577
|
-
|
|
92615
|
+
const settled = await Promise.allSettled(inFlight.map((run) => pauseRun(run.id, {
|
|
92578
92616
|
store: activeStore,
|
|
92579
92617
|
stageControlRegistry: opts?.stageControlRegistry,
|
|
92580
92618
|
toolControlRegistry: opts?.toolControlRegistry,
|
|
92581
92619
|
jobs: opts?.jobs
|
|
92582
92620
|
})));
|
|
92621
|
+
return settled.map((result, index) => {
|
|
92622
|
+
if (result.status === "fulfilled")
|
|
92623
|
+
return result.value;
|
|
92624
|
+
return {
|
|
92625
|
+
ok: false,
|
|
92626
|
+
runId: inFlight[index].id,
|
|
92627
|
+
reason: "pause_failed",
|
|
92628
|
+
message: result.reason instanceof Error ? result.reason.message : String(result.reason)
|
|
92629
|
+
};
|
|
92630
|
+
});
|
|
92583
92631
|
}
|
|
92584
92632
|
|
|
92585
92633
|
// dist/builtin/workflows/src/shared/persistence-compaction-policy.ts
|
|
@@ -93598,6 +93646,8 @@ function stageFailureMessage(runId, resultReason, action) {
|
|
|
93598
93646
|
return `Run not found: ${runId}`;
|
|
93599
93647
|
case "already_ended":
|
|
93600
93648
|
return `Run already ended: ${runId}`;
|
|
93649
|
+
case "already_paused":
|
|
93650
|
+
return `Run ${runId} is already paused.`;
|
|
93601
93651
|
case "stage_not_found":
|
|
93602
93652
|
return `Stage not found for run: ${runId}`;
|
|
93603
93653
|
default:
|
|
@@ -93688,7 +93738,7 @@ function resolveStageTarget(runId, stageTarget, activeStore = store) {
|
|
|
93688
93738
|
return ambiguousUuidStageTarget(target, uuidMatches);
|
|
93689
93739
|
const matches = graph.stages.filter((stage) => stageMatchesExpandedIdentifier(stage, target));
|
|
93690
93740
|
if (matches.length === 0)
|
|
93691
|
-
return { ok: false, message: `Stage not found in run ${runId}: ${target}
|
|
93741
|
+
return { ok: false, message: `Stage not found in run ${runId}: ${target}`, code: "stage_not_found" };
|
|
93692
93742
|
if (matches.length > 1)
|
|
93693
93743
|
return ambiguousStageTarget(target, matches);
|
|
93694
93744
|
return resolvedStageTarget(matches[0]);
|
|
@@ -93711,12 +93761,14 @@ function matchingUuidStages(stages, target) {
|
|
|
93711
93761
|
function ambiguousUuidStageTarget(target, stages) {
|
|
93712
93762
|
return {
|
|
93713
93763
|
ok: false,
|
|
93764
|
+
code: "stage_ambiguous",
|
|
93714
93765
|
message: `Ambiguous stage UUID prefix "${target}" matches: ${stages.map((stage) => stage.workflowGraphTarget.stageId).join(", ")}. Use the full 36-character UUID.`
|
|
93715
93766
|
};
|
|
93716
93767
|
}
|
|
93717
93768
|
function ambiguousStageTarget(target, stages) {
|
|
93718
93769
|
return {
|
|
93719
93770
|
ok: false,
|
|
93771
|
+
code: "stage_ambiguous",
|
|
93720
93772
|
message: `Ambiguous stage identifier "${target}" matches: ${stages.map(expandedStageLabel).join(", ")}`
|
|
93721
93773
|
};
|
|
93722
93774
|
}
|
|
@@ -93742,10 +93794,11 @@ function resolveControlNodeTarget(runId, stageTarget, activeStore = store) {
|
|
|
93742
93794
|
if (matches.length > 1)
|
|
93743
93795
|
return {
|
|
93744
93796
|
ok: false,
|
|
93797
|
+
code: "stage_ambiguous",
|
|
93745
93798
|
message: `Ambiguous stage identifier "${target}" matches: ${matches.map(expandedStageLabel).join(", ")}`
|
|
93746
93799
|
};
|
|
93747
93800
|
}
|
|
93748
|
-
return { ok: false, message: `Stage not found in run ${runId}: ${target}
|
|
93801
|
+
return { ok: false, message: `Stage not found in run ${runId}: ${target}`, code: "stage_not_found" };
|
|
93749
93802
|
}
|
|
93750
93803
|
function resolvedControlNodeTarget(node) {
|
|
93751
93804
|
const graphTarget = node.workflowGraphTarget;
|
|
@@ -106960,7 +107013,7 @@ async function resumeDurableWorkflowClaimed(workflowId, deps, catalog) {
|
|
|
106960
107013
|
function foreignRunningResult(name, workflowId) {
|
|
106961
107014
|
return {
|
|
106962
107015
|
ok: false,
|
|
106963
|
-
reason: "
|
|
107016
|
+
reason: "owned_elsewhere",
|
|
106964
107017
|
message: `Workflow "${name}" (${workflowId}) is actively running in another Atomic session. ` + "Control it from that session; it becomes resumable here only after that session pauses, quits, or crashes."
|
|
106965
107018
|
};
|
|
106966
107019
|
}
|
|
@@ -114012,7 +114065,8 @@ async function run(def, inputs, opts = {}) {
|
|
|
114012
114065
|
let admissionControlError;
|
|
114013
114066
|
let pausePersistence;
|
|
114014
114067
|
let resumePersistence;
|
|
114015
|
-
let
|
|
114068
|
+
let controlSettlements = Promise.resolve();
|
|
114069
|
+
let latestControl = 0;
|
|
114016
114070
|
let pauseGeneration = 0;
|
|
114017
114071
|
const persistRunControl = async (status) => {
|
|
114018
114072
|
ownController.signal.throwIfAborted();
|
|
@@ -114026,27 +114080,30 @@ async function run(def, inputs, opts = {}) {
|
|
|
114026
114080
|
}
|
|
114027
114081
|
if (durableBackend.getWorkflow(runId) === undefined)
|
|
114028
114082
|
return;
|
|
114029
|
-
|
|
114030
|
-
const
|
|
114031
|
-
controlAttempt = attempt;
|
|
114083
|
+
const previous = controlSettlements;
|
|
114084
|
+
const control = ++latestControl;
|
|
114032
114085
|
const settlement = (async () => {
|
|
114033
114086
|
try {
|
|
114034
|
-
await boundedAdmission(
|
|
114035
|
-
|
|
114036
|
-
|
|
114037
|
-
|
|
114038
|
-
|
|
114039
|
-
|
|
114040
|
-
|
|
114041
|
-
|
|
114042
|
-
|
|
114087
|
+
await boundedAdmission(async (signal) => {
|
|
114088
|
+
await raceAbort(previous, signal);
|
|
114089
|
+
await dbosAdmissionContext.run(signal, async () => {
|
|
114090
|
+
if (!await transitionDurableWorkflowStatus(durableBackend, runId, ["running", "paused"], status, undefined, true)) {
|
|
114091
|
+
throw new Error(`Workflow ${runId} refused the durable ${status} transition`);
|
|
114092
|
+
}
|
|
114093
|
+
signal.throwIfAborted();
|
|
114094
|
+
recordRunTimingCheckpoint(durableBackend, runSnapshot);
|
|
114095
|
+
await durableBackend.flush(runId);
|
|
114096
|
+
});
|
|
114097
|
+
}, ownController.signal, DBOS_ADMISSION_TIMEOUT_MS);
|
|
114043
114098
|
ownController.signal.throwIfAborted();
|
|
114099
|
+
if (control !== latestControl)
|
|
114100
|
+
return;
|
|
114044
114101
|
activeStore.recordRunExecutionState(runId, {
|
|
114045
114102
|
controlPersistence: durableBackend.persistent ? "durable" : "observed",
|
|
114046
114103
|
...durableRootAdmitted ? { phase: "executing", dependencyError: undefined } : {}
|
|
114047
114104
|
});
|
|
114048
114105
|
} catch (error) {
|
|
114049
|
-
if (
|
|
114106
|
+
if (control === latestControl && !ownController.signal.aborted && isDbosDependencyError(error)) {
|
|
114050
114107
|
activeStore.recordRunExecutionState(runId, {
|
|
114051
114108
|
phase: "blocked_dependency",
|
|
114052
114109
|
dependencyError: `Workflow database unavailable during ${status === "paused" ? "pause" : "resume"}; persistence not confirmed.`
|
|
@@ -114057,6 +114114,11 @@ async function run(def, inputs, opts = {}) {
|
|
|
114057
114114
|
throw error;
|
|
114058
114115
|
}
|
|
114059
114116
|
})();
|
|
114117
|
+
controlSettlements = settlement.then(() => {
|
|
114118
|
+
return;
|
|
114119
|
+
}, () => {
|
|
114120
|
+
return;
|
|
114121
|
+
});
|
|
114060
114122
|
if (status === "running")
|
|
114061
114123
|
return settlement;
|
|
114062
114124
|
let acknowledgementTimer;
|
|
@@ -114085,7 +114147,6 @@ async function run(def, inputs, opts = {}) {
|
|
|
114085
114147
|
pause: () => {
|
|
114086
114148
|
ownController.signal.throwIfAborted();
|
|
114087
114149
|
pauseGeneration++;
|
|
114088
|
-
controlAttempt?.abort(new Error("Workflow control superseded by pause"));
|
|
114089
114150
|
scheduler.pauseRun();
|
|
114090
114151
|
activeStore.recordRunPaused(runId, undefined, { resumable: true });
|
|
114091
114152
|
pausePersistence = persistRunControl("paused");
|
|
@@ -115625,7 +115686,7 @@ function createExtensionRuntime(opts = {}) {
|
|
|
115625
115686
|
if (!resumed.ok)
|
|
115626
115687
|
return {
|
|
115627
115688
|
ok: false,
|
|
115628
|
-
reason: resumed.reason === "workflow_not_found" ? "workflow_not_found" : resumed.reason === "not_resumable" || resumed.reason === "stale" ? "not_resumable" : "insufficient_state",
|
|
115689
|
+
reason: resumed.reason === "workflow_not_found" ? "workflow_not_found" : resumed.reason === "owned_elsewhere" ? "owned_elsewhere" : resumed.reason === "not_resumable" || resumed.reason === "stale" ? "not_resumable" : "insufficient_state",
|
|
115629
115690
|
message: resumed.message
|
|
115630
115691
|
};
|
|
115631
115692
|
return {
|
|
@@ -119459,6 +119520,33 @@ function openWorkflowResumeSelector(ui, liveRuns, hydrate, options = {}) {
|
|
|
119459
119520
|
});
|
|
119460
119521
|
}
|
|
119461
119522
|
|
|
119523
|
+
// dist/builtin/workflows/src/extension/workflow-bulk-control.ts
|
|
119524
|
+
function isAlreadyPaused(result) {
|
|
119525
|
+
return !result.ok && result.reason === "already_paused";
|
|
119526
|
+
}
|
|
119527
|
+
function leavesRunActive(result) {
|
|
119528
|
+
return !result.ok && result.reason !== "already_paused" && result.reason !== "already_ended";
|
|
119529
|
+
}
|
|
119530
|
+
function bulkFailedRuns(results) {
|
|
119531
|
+
return results.filter(leavesRunActive).map((result) => ({
|
|
119532
|
+
runId: result.runId,
|
|
119533
|
+
reason: result.reason,
|
|
119534
|
+
...result.message === undefined ? {} : { message: result.message }
|
|
119535
|
+
}));
|
|
119536
|
+
}
|
|
119537
|
+
function bulkAlreadyPausedCount(results) {
|
|
119538
|
+
return results.filter(isAlreadyPaused).length;
|
|
119539
|
+
}
|
|
119540
|
+
function bulkUnstoppedStatus(results) {
|
|
119541
|
+
return results.some((result) => result.ok) ? { status: "partial" } : { status: "noop", code: "control_failed" };
|
|
119542
|
+
}
|
|
119543
|
+
function bulkFailureMessage(verb, action, results, describeSuccess) {
|
|
119544
|
+
const successes = results.filter((result) => result.ok).length;
|
|
119545
|
+
const failures = results.filter(leavesRunActive).length;
|
|
119546
|
+
const outcomes = results.map((result) => result.ok ? describeSuccess(result) : `${result.runId}: ${result.reason}${result.message === undefined ? "" : ` (${result.message})`}`).join(", ");
|
|
119547
|
+
return `${successes > 0 ? `${verb} ${successes} run(s); ` : ""}failed to ${action} ${failures} run(s); outcomes: ${outcomes}.`;
|
|
119548
|
+
}
|
|
119549
|
+
|
|
119462
119550
|
// dist/builtin/workflows/src/durable/resume-catalog.ts
|
|
119463
119551
|
function formatResumableWorkflowList(entries) {
|
|
119464
119552
|
if (entries.length === 0)
|
|
@@ -119819,12 +119907,11 @@ ${renderSessionList(store.runs(), { theme, includeAll: true })}`);
|
|
|
119819
119907
|
}
|
|
119820
119908
|
}
|
|
119821
119909
|
const results = action === "quit" ? await quitAllRuns({ ...owner, actor: "user" }) : await pauseAllRuns(owner);
|
|
119822
|
-
const successes = results.
|
|
119910
|
+
const successes = results.flatMap((result) => result.ok ? [result] : []);
|
|
119823
119911
|
const changed = successes.length;
|
|
119824
|
-
const
|
|
119825
|
-
if (
|
|
119826
|
-
const
|
|
119827
|
-
const message = `${changed > 0 ? `Quit ${changed} run(s); ` : ""}failed to quit ${failures.length} run(s); outcomes: ${outcomes}.`;
|
|
119912
|
+
const alreadyPaused = bulkAlreadyPausedCount(results);
|
|
119913
|
+
if (bulkFailedRuns(results).length > 0) {
|
|
119914
|
+
const message = bulkFailureMessage(action === "quit" ? "Quit" : "Paused", action, results, (result) => result.message ?? `${result.runId}: ${action === "quit" ? "quit" : "paused"}`);
|
|
119828
119915
|
if (changed > 0)
|
|
119829
119916
|
print(message);
|
|
119830
119917
|
else
|
|
@@ -119832,6 +119919,8 @@ ${renderSessionList(store.runs(), { theme, includeAll: true })}`);
|
|
|
119832
119919
|
} else if (changed > 0) {
|
|
119833
119920
|
print(successes.some((result) => result.message !== undefined) ? successes.map((result) => result.message ?? `Run ${result.runId} stopped.`).join(`
|
|
119834
119921
|
`) : action === "quit" ? `Quit ${changed} run(s); resume with /workflow resume.` : `Paused ${changed} run(s).`);
|
|
119922
|
+
} else if (alreadyPaused > 0) {
|
|
119923
|
+
print(`${alreadyPaused} in-flight run(s) already paused.`);
|
|
119835
119924
|
} else {
|
|
119836
119925
|
fail(`No in-flight runs to ${action}.`);
|
|
119837
119926
|
}
|
|
@@ -119878,6 +119967,8 @@ ${renderSessionList(store.runs(), { theme, includeAll: true })}`);
|
|
|
119878
119967
|
const result = await pauseRun(resolved.runId, owner);
|
|
119879
119968
|
if (result.ok)
|
|
119880
119969
|
print(result.message ?? `Run ${result.runId} paused and can be resumed.`);
|
|
119970
|
+
else if (result.reason === "already_paused")
|
|
119971
|
+
print(`Run ${result.runId} is already paused.`);
|
|
119881
119972
|
else
|
|
119882
119973
|
fail(result.reason === "not_found" ? `Run not found: ${target}` : result.reason === "already_ended" ? `Run already ended: ${target}` : result.reason === "stage_not_found" ? `Stage not found for run ${resolved.runId}.` : `No active stages to pause on run ${resolved.runId}.`);
|
|
119883
119974
|
} catch (error) {
|
|
@@ -120401,11 +120492,31 @@ function createWorkflowObservation(store, publisher, ownerSessionId) {
|
|
|
120401
120492
|
};
|
|
120402
120493
|
}
|
|
120403
120494
|
|
|
120404
|
-
// dist/builtin/workflows/src/extension/workflow-
|
|
120405
|
-
import {
|
|
120495
|
+
// dist/builtin/workflows/src/extension/workflow-session-run-control.ts
|
|
120496
|
+
import {
|
|
120497
|
+
WorkflowRunControlError,
|
|
120498
|
+
WorkflowRunControlUnavailableError,
|
|
120499
|
+
WorkflowRunDatabaseError,
|
|
120500
|
+
WorkflowRunNotFoundError,
|
|
120501
|
+
WorkflowRunNotResumableError,
|
|
120502
|
+
WorkflowRunOwnershipError,
|
|
120503
|
+
WorkflowStageAmbiguousError,
|
|
120504
|
+
WorkflowStageNotFoundError,
|
|
120505
|
+
WorkflowStageResumeUnsupportedError
|
|
120506
|
+
} from "@bastani/atomic";
|
|
120507
|
+
|
|
120508
|
+
// dist/builtin/workflows/src/extension/workflow-control-failure.ts
|
|
120509
|
+
init_dbos_admission();
|
|
120406
120510
|
|
|
120407
120511
|
// dist/builtin/workflows/src/extension/workflow-instance-owner.ts
|
|
120408
120512
|
var anonymousCallers = new WeakMap;
|
|
120513
|
+
|
|
120514
|
+
class WorkflowInstanceOwnershipError extends Error {
|
|
120515
|
+
constructor(message) {
|
|
120516
|
+
super(message);
|
|
120517
|
+
this.name = "WorkflowInstanceOwnershipError";
|
|
120518
|
+
}
|
|
120519
|
+
}
|
|
120409
120520
|
function workflowCaller(ctx) {
|
|
120410
120521
|
const sessionId = ctx.sessionId ?? ctx.sessionManager?.getSessionId?.();
|
|
120411
120522
|
if (sessionId)
|
|
@@ -120431,9 +120542,9 @@ function assertWorkflowInstanceOwner(id, ctx, store) {
|
|
|
120431
120542
|
const modelOwner = durable?.modelOwner ?? local?.modelOwner;
|
|
120432
120543
|
if (modelOwner !== undefined) {
|
|
120433
120544
|
if (modelOwner !== workflowCaller(ctx))
|
|
120434
|
-
throw new
|
|
120545
|
+
throw new WorkflowInstanceOwnershipError("Workflow instance belongs to another caller/session.");
|
|
120435
120546
|
} else if ((durable?.origin ?? local?.origin) === "agent") {
|
|
120436
|
-
throw new
|
|
120547
|
+
throw new WorkflowInstanceOwnershipError("Workflow instance ownership is unavailable; another caller cannot assume authority.");
|
|
120437
120548
|
}
|
|
120438
120549
|
const parentId = durable?.rootWorkflowId ?? local?.parentRunId;
|
|
120439
120550
|
if (parentId !== undefined)
|
|
@@ -120451,6 +120562,176 @@ function assertWorkflowInstanceOwner(id, ctx, store) {
|
|
|
120451
120562
|
}
|
|
120452
120563
|
}
|
|
120453
120564
|
|
|
120565
|
+
// dist/builtin/workflows/src/extension/workflow-control-failure.ts
|
|
120566
|
+
function classifyControlError(error) {
|
|
120567
|
+
if (error instanceof WorkflowInstanceOwnershipError)
|
|
120568
|
+
return "owned_elsewhere";
|
|
120569
|
+
if (error instanceof DbosDurabilityError || isDbosDependencyError(error))
|
|
120570
|
+
return "database_unavailable";
|
|
120571
|
+
return "control_failed";
|
|
120572
|
+
}
|
|
120573
|
+
function resumeFailureCode(reason) {
|
|
120574
|
+
switch (reason) {
|
|
120575
|
+
case "not_resumable":
|
|
120576
|
+
case "stale":
|
|
120577
|
+
return "not_resumable";
|
|
120578
|
+
case "owned_elsewhere":
|
|
120579
|
+
return "owned_elsewhere";
|
|
120580
|
+
case "not_registered":
|
|
120581
|
+
case "run_not_found":
|
|
120582
|
+
return "run_not_found";
|
|
120583
|
+
case "workflow_not_found":
|
|
120584
|
+
case "invalid_inputs":
|
|
120585
|
+
case "startup_failed":
|
|
120586
|
+
case "insufficient_state":
|
|
120587
|
+
return "control_failed";
|
|
120588
|
+
}
|
|
120589
|
+
}
|
|
120590
|
+
|
|
120591
|
+
// dist/builtin/workflows/src/extension/workflow-session-run-control.ts
|
|
120592
|
+
function executeContext(ctx) {
|
|
120593
|
+
if (ctx === undefined)
|
|
120594
|
+
throw new WorkflowRunControlUnavailableError;
|
|
120595
|
+
return {
|
|
120596
|
+
sessionId: ctx.sessionManager?.getSessionId?.(),
|
|
120597
|
+
sessionManager: ctx.sessionManager,
|
|
120598
|
+
ui: ctx.ui,
|
|
120599
|
+
hasUI: ctx.hasUI,
|
|
120600
|
+
hasHumanInput: ctx.hasHumanInput,
|
|
120601
|
+
model: ctx.model,
|
|
120602
|
+
modelRegistry: ctx.modelRegistry,
|
|
120603
|
+
cwd: ctx.cwd
|
|
120604
|
+
};
|
|
120605
|
+
}
|
|
120606
|
+
function errorOptions(runId, cause, failedRuns) {
|
|
120607
|
+
return {
|
|
120608
|
+
...runId === undefined || runId === "--all" ? {} : { runId },
|
|
120609
|
+
...cause === undefined ? {} : { cause },
|
|
120610
|
+
...failedRuns === undefined ? {} : { failedRuns }
|
|
120611
|
+
};
|
|
120612
|
+
}
|
|
120613
|
+
function failure3(code, message, runId, cause, failedRuns) {
|
|
120614
|
+
const options = errorOptions(runId, cause, failedRuns);
|
|
120615
|
+
switch (code) {
|
|
120616
|
+
case "run_not_found":
|
|
120617
|
+
return new WorkflowRunNotFoundError(message, options);
|
|
120618
|
+
case "not_resumable":
|
|
120619
|
+
return new WorkflowRunNotResumableError(message, options);
|
|
120620
|
+
case "owned_elsewhere":
|
|
120621
|
+
return new WorkflowRunOwnershipError(message, options);
|
|
120622
|
+
case "stage_not_found":
|
|
120623
|
+
return new WorkflowStageNotFoundError(message, options);
|
|
120624
|
+
case "stage_ambiguous":
|
|
120625
|
+
return new WorkflowStageAmbiguousError(message, options);
|
|
120626
|
+
case "stage_resume_unsupported":
|
|
120627
|
+
return new WorkflowStageResumeUnsupportedError(message, options);
|
|
120628
|
+
case "database_unavailable":
|
|
120629
|
+
return new WorkflowRunDatabaseError(message, options);
|
|
120630
|
+
case "control_failed":
|
|
120631
|
+
return new WorkflowRunControlError("WORKFLOW_RUN_CONTROL_FAILED", message, options);
|
|
120632
|
+
}
|
|
120633
|
+
}
|
|
120634
|
+
function translateThrown(error, runId) {
|
|
120635
|
+
const code = classifyControlError(error);
|
|
120636
|
+
return code === "owned_elsewhere" || code === "database_unavailable" ? failure3(code, error.message, runId, error) : error;
|
|
120637
|
+
}
|
|
120638
|
+
function controlStatus(status, runId) {
|
|
120639
|
+
switch (status) {
|
|
120640
|
+
case "ok":
|
|
120641
|
+
case "running":
|
|
120642
|
+
case "paused":
|
|
120643
|
+
case "partial":
|
|
120644
|
+
case "noop":
|
|
120645
|
+
case "cancelled":
|
|
120646
|
+
return status;
|
|
120647
|
+
default:
|
|
120648
|
+
throw failure3("control_failed", `Unexpected workflow control status: ${status}`, runId);
|
|
120649
|
+
}
|
|
120650
|
+
}
|
|
120651
|
+
function controlOutcome(result) {
|
|
120652
|
+
if (result.action !== "pause" && result.action !== "quit" && result.action !== "resume") {
|
|
120653
|
+
throw failure3("control_failed", `Unexpected workflow result: ${result.action}`, undefined);
|
|
120654
|
+
}
|
|
120655
|
+
if ("code" in result && result.code !== undefined) {
|
|
120656
|
+
throw failure3(result.code, result.message, result.runId, undefined, "failedRuns" in result ? result.failedRuns : undefined);
|
|
120657
|
+
}
|
|
120658
|
+
return { ...result, status: controlStatus(result.status, result.runId) };
|
|
120659
|
+
}
|
|
120660
|
+
function rejectUnknownRunPrefix(store, runId) {
|
|
120661
|
+
const target = runId.trim();
|
|
120662
|
+
if (!isRunIdPrefix(target))
|
|
120663
|
+
return;
|
|
120664
|
+
const resolution = resolveRunIdTarget(target, store.runs().map((run) => run.id));
|
|
120665
|
+
if (resolution.kind === "not_found") {
|
|
120666
|
+
throw failure3("run_not_found", `Run not found: ${target} (no run in this session has that prefix; pass the full run id for a run recorded elsewhere).`, runId);
|
|
120667
|
+
}
|
|
120668
|
+
}
|
|
120669
|
+
function createSessionRunControl(host) {
|
|
120670
|
+
const request = async (args) => {
|
|
120671
|
+
try {
|
|
120672
|
+
const ctx = executeContext(host.context());
|
|
120673
|
+
if (args.runId !== undefined && (args.action === "status" || args.action === "stages"))
|
|
120674
|
+
rejectUnknownRunPrefix(host.store, args.runId);
|
|
120675
|
+
return await host.execute(args, ctx);
|
|
120676
|
+
} catch (error) {
|
|
120677
|
+
throw error instanceof Error ? translateThrown(error, args.runId) : error;
|
|
120678
|
+
}
|
|
120679
|
+
};
|
|
120680
|
+
const target = (runId) => typeof runId === "string" ? { runId } : { all: true };
|
|
120681
|
+
return {
|
|
120682
|
+
async listRuns(filter) {
|
|
120683
|
+
const result = await request({
|
|
120684
|
+
action: "status",
|
|
120685
|
+
...filter?.status === undefined ? {} : { statusFilter: filter.status }
|
|
120686
|
+
});
|
|
120687
|
+
if (result.action !== "status")
|
|
120688
|
+
throw failure3("control_failed", `Unexpected workflow result: ${result.action}`, undefined);
|
|
120689
|
+
return result.runs;
|
|
120690
|
+
},
|
|
120691
|
+
async getRun(runId) {
|
|
120692
|
+
const result = await request({ action: "status", runId });
|
|
120693
|
+
if (result.action !== "statusDetail")
|
|
120694
|
+
throw failure3("control_failed", `Unexpected workflow result: ${result.action}`, runId);
|
|
120695
|
+
if ("error" in result)
|
|
120696
|
+
throw failure3("run_not_found", result.error, runId);
|
|
120697
|
+
return result.detail;
|
|
120698
|
+
},
|
|
120699
|
+
async getStages(runId, filter) {
|
|
120700
|
+
const result = await request({
|
|
120701
|
+
action: "stages",
|
|
120702
|
+
runId,
|
|
120703
|
+
...filter?.status === undefined ? {} : { statusFilter: filter.status }
|
|
120704
|
+
});
|
|
120705
|
+
if (result.action !== "stages")
|
|
120706
|
+
throw failure3("control_failed", `Unexpected workflow result: ${result.action}`, runId);
|
|
120707
|
+
if (result.error !== undefined)
|
|
120708
|
+
throw failure3("run_not_found", result.error, runId);
|
|
120709
|
+
return result.stages;
|
|
120710
|
+
},
|
|
120711
|
+
async pause(runId, options) {
|
|
120712
|
+
return controlOutcome(await request({
|
|
120713
|
+
action: "pause",
|
|
120714
|
+
...target(runId),
|
|
120715
|
+
...options?.stageId === undefined ? {} : { stageId: options.stageId }
|
|
120716
|
+
}));
|
|
120717
|
+
},
|
|
120718
|
+
async quit(runId) {
|
|
120719
|
+
return controlOutcome(await request({ action: "quit", ...target(runId) }));
|
|
120720
|
+
},
|
|
120721
|
+
async resume(runId, options) {
|
|
120722
|
+
return controlOutcome(await request({
|
|
120723
|
+
action: "resume",
|
|
120724
|
+
runId,
|
|
120725
|
+
...options?.stageId === undefined ? {} : { stageId: options.stageId },
|
|
120726
|
+
...options?.message === undefined ? {} : { message: options.message }
|
|
120727
|
+
}));
|
|
120728
|
+
}
|
|
120729
|
+
};
|
|
120730
|
+
}
|
|
120731
|
+
|
|
120732
|
+
// dist/builtin/workflows/src/extension/workflow-tool.ts
|
|
120733
|
+
import { getSupportedThinkingLevels } from "@bastani/pi-ai/compat";
|
|
120734
|
+
|
|
120454
120735
|
// dist/builtin/workflows/src/extension/workflow-status-summary.ts
|
|
120455
120736
|
var workflowStatusRenderRuns = new WeakMap;
|
|
120456
120737
|
function setWorkflowStatusRenderRuns(result, runs) {
|
|
@@ -121054,12 +121335,41 @@ async function abortToolNode(runId, nodeId, opts) {
|
|
|
121054
121335
|
}
|
|
121055
121336
|
|
|
121056
121337
|
// dist/builtin/workflows/src/extension/workflow-tool-control.ts
|
|
121057
|
-
function
|
|
121338
|
+
async function foreignRunFailure(action, target, guard) {
|
|
121339
|
+
if (guard === undefined || !isFullRunId(target))
|
|
121340
|
+
return;
|
|
121341
|
+
let durable;
|
|
121342
|
+
try {
|
|
121343
|
+
durable = await guard.getRuntime().inspectDurableWorkflow(target);
|
|
121344
|
+
} catch (error) {
|
|
121345
|
+
return controlFailure(action, target, error, "database_unavailable");
|
|
121346
|
+
}
|
|
121347
|
+
if (durable.kind !== "found")
|
|
121348
|
+
return;
|
|
121349
|
+
const runId = durable.detail.runId;
|
|
121350
|
+
const foreign = (message) => ({
|
|
121351
|
+
action,
|
|
121352
|
+
runId,
|
|
121353
|
+
status: "noop",
|
|
121354
|
+
message,
|
|
121355
|
+
code: "owned_elsewhere"
|
|
121356
|
+
});
|
|
121357
|
+
try {
|
|
121358
|
+
guard.authorize?.(runId);
|
|
121359
|
+
} catch (error) {
|
|
121360
|
+
if (error instanceof WorkflowInstanceOwnershipError)
|
|
121361
|
+
return foreign(error.message);
|
|
121362
|
+
throw error;
|
|
121363
|
+
}
|
|
121364
|
+
return durable.detail.ownerActiveElsewhere === true ? foreign(`Workflow ${runId} is actively running in another Atomic session. Control it from that session; it can be ${action === "pause" ? "paused" : "quit"} only by its owner.`) : undefined;
|
|
121365
|
+
}
|
|
121366
|
+
function controlFailure(action, runId, error, code = classifyControlError(error)) {
|
|
121058
121367
|
return {
|
|
121059
121368
|
action,
|
|
121060
121369
|
runId,
|
|
121061
121370
|
status: "noop",
|
|
121062
|
-
message: `Failed to ${action} run ${runId}: ${error instanceof Error ? error.message : String(error)}
|
|
121371
|
+
message: `Failed to ${action} run ${runId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
121372
|
+
code
|
|
121063
121373
|
};
|
|
121064
121374
|
}
|
|
121065
121375
|
function resumeControlFailure(runId, error, store) {
|
|
@@ -121070,7 +121380,8 @@ function resumeControlFailure(runId, error, store) {
|
|
|
121070
121380
|
action: "resume",
|
|
121071
121381
|
runId,
|
|
121072
121382
|
status: visiblyRunning ? "partial" : "noop",
|
|
121073
|
-
message: `Failed to resume run ${runId}: ${detail}
|
|
121383
|
+
message: `Failed to resume run ${runId}: ${detail}`,
|
|
121384
|
+
...visiblyRunning ? {} : { code: classifyControlError(error) }
|
|
121074
121385
|
};
|
|
121075
121386
|
}
|
|
121076
121387
|
async function workflowReloadAction(args, deps) {
|
|
@@ -121096,12 +121407,6 @@ async function workflowReloadAction(args, deps) {
|
|
|
121096
121407
|
};
|
|
121097
121408
|
}
|
|
121098
121409
|
}
|
|
121099
|
-
function bulkQuitFailureMessage(results) {
|
|
121100
|
-
const successes = results.filter((result) => result.ok).length;
|
|
121101
|
-
const failures = results.length - successes;
|
|
121102
|
-
const outcomes = results.map((result) => result.ok ? result.message ?? `${result.runId}: quit${abandonedToolSuffix(result.abandonedTools)}` : `${result.runId}: ${result.reason}${"message" in result ? ` (${result.message})` : ""}`).join(", ");
|
|
121103
|
-
return `${successes > 0 ? `Quit ${successes} run(s); ` : ""}failed to quit ${failures} run(s); outcomes: ${outcomes}.`;
|
|
121104
|
-
}
|
|
121105
121410
|
function abandonedToolSuffix(abandonedTools) {
|
|
121106
121411
|
return abandonedTools.length === 0 ? "" : ` (abandoned tool node(s): ${abandonedTools.map(formatToolNodeIdentity).join(", ")})`;
|
|
121107
121412
|
}
|
|
@@ -121140,7 +121445,7 @@ async function quitToolNodeAction(runId, nodeId, action, owner) {
|
|
|
121140
121445
|
message: `Cancelled ctx.tool ${aborted.name} (${nodeId}) on run ${runId}.${abandonedNote}` + ` Sibling work was not aborted. Current workflow status: ${workflowStatus}.` + " If workflow code awaited this call without catching cancellation, the workflow may fail." + " A later resume re-runs this call."
|
|
121141
121446
|
};
|
|
121142
121447
|
}
|
|
121143
|
-
async function workflowQuitAction(args, owner = captureWorkflowOwnerResources()) {
|
|
121448
|
+
async function workflowQuitAction(args, owner = captureWorkflowOwnerResources(), guard) {
|
|
121144
121449
|
const { store } = owner;
|
|
121145
121450
|
const target = resolveToolRunTarget(args, "No in-flight runs to quit.", store);
|
|
121146
121451
|
const action = "quit";
|
|
@@ -121151,21 +121456,32 @@ async function workflowQuitAction(args, owner = captureWorkflowOwnerResources())
|
|
|
121151
121456
|
const results = await quitAllRuns({ ...owner, actor: "agent" });
|
|
121152
121457
|
const successes = results.filter((result) => result.ok);
|
|
121153
121458
|
const quitCount = successes.length;
|
|
121154
|
-
const
|
|
121459
|
+
const failedRuns = bulkFailedRuns(results);
|
|
121460
|
+
if (failedRuns.length > 0) {
|
|
121461
|
+
return {
|
|
121462
|
+
action,
|
|
121463
|
+
runId: "--all",
|
|
121464
|
+
...bulkUnstoppedStatus(results),
|
|
121465
|
+
message: bulkFailureMessage("Quit", action, results, (result) => result.message ?? `${result.runId}: quit${abandonedToolSuffix(result.abandonedTools)}`),
|
|
121466
|
+
failedRuns
|
|
121467
|
+
};
|
|
121468
|
+
}
|
|
121155
121469
|
return {
|
|
121156
121470
|
action,
|
|
121157
121471
|
runId: "--all",
|
|
121158
|
-
status:
|
|
121159
|
-
message:
|
|
121472
|
+
status: quitCount > 0 ? "paused" : "noop",
|
|
121473
|
+
message: quitCount > 0 ? successes.some((result) => result.message !== undefined) ? successes.map((result) => result.message ?? `Run ${result.runId} quit.`).join(`
|
|
121160
121474
|
`) : `Quit ${quitCount} run(s); resume with /workflow resume.` : "No in-flight runs to quit."
|
|
121161
121475
|
};
|
|
121162
121476
|
}
|
|
121163
121477
|
if (target.kind === "malformed" || target.kind === "not_found") {
|
|
121164
|
-
|
|
121478
|
+
const foreign = target.kind === "not_found" ? await foreignRunFailure(action, target.target, guard) : undefined;
|
|
121479
|
+
return foreign ?? { action, runId: target.target, status: "noop", message: target.message, code: "run_not_found" };
|
|
121165
121480
|
}
|
|
121166
121481
|
const controlNode = resolveControlNodeTarget(target.runId, args.stageId, store);
|
|
121167
|
-
if (!controlNode.ok)
|
|
121168
|
-
return { action, runId: target.runId, status: "noop", message: controlNode.message };
|
|
121482
|
+
if (!controlNode.ok) {
|
|
121483
|
+
return { action, runId: target.runId, status: "noop", message: controlNode.message, code: controlNode.code };
|
|
121484
|
+
}
|
|
121169
121485
|
if (controlNode.kind === "tool")
|
|
121170
121486
|
return quitToolNodeAction(controlNode.runId, controlNode.nodeId, action, owner);
|
|
121171
121487
|
try {
|
|
@@ -121178,17 +121494,19 @@ async function workflowQuitAction(args, owner = captureWorkflowOwnerResources())
|
|
|
121178
121494
|
message: result.message ?? `Run ${result.runId} quit and can be resumed with /workflow resume.${cancelledToolSummary(result)}`
|
|
121179
121495
|
};
|
|
121180
121496
|
}
|
|
121497
|
+
const benign = result.reason === "already_ended" || result.reason === "no_active_stages";
|
|
121181
121498
|
return {
|
|
121182
121499
|
action,
|
|
121183
121500
|
runId: target.runId,
|
|
121184
121501
|
status: "noop",
|
|
121185
|
-
message: result.reason === "already_ended" ? `Run ${target.runId} already ended.` : result.reason === "no_active_stages" ? `No controllable stages on run ${target.runId}; the run remains active.` : `Run not found: ${target.runId}
|
|
121502
|
+
message: result.reason === "already_ended" ? `Run ${target.runId} already ended.` : result.reason === "no_active_stages" ? `No controllable stages on run ${target.runId}; the run remains active.` : `Run not found: ${target.runId}`,
|
|
121503
|
+
...benign ? {} : { code: "run_not_found" }
|
|
121186
121504
|
};
|
|
121187
121505
|
} catch (error) {
|
|
121188
121506
|
return controlFailure(action, target.runId, error);
|
|
121189
121507
|
}
|
|
121190
121508
|
}
|
|
121191
|
-
async function workflowPauseAction(args, owner = captureWorkflowOwnerResources()) {
|
|
121509
|
+
async function workflowPauseAction(args, owner = captureWorkflowOwnerResources(), guard) {
|
|
121192
121510
|
const { store } = owner;
|
|
121193
121511
|
const target = resolveToolRunTarget(args, "No in-flight runs to pause.", store);
|
|
121194
121512
|
const action = "pause";
|
|
@@ -121199,12 +121517,24 @@ async function workflowPauseAction(args, owner = captureWorkflowOwnerResources()
|
|
|
121199
121517
|
try {
|
|
121200
121518
|
const results = await pauseAllRuns(owner);
|
|
121201
121519
|
const paused = results.filter((result) => result.ok).length;
|
|
121520
|
+
const failedRuns = bulkFailedRuns(results);
|
|
121521
|
+
if (failedRuns.length > 0) {
|
|
121522
|
+
return {
|
|
121523
|
+
action,
|
|
121524
|
+
runId: "--all",
|
|
121525
|
+
...bulkUnstoppedStatus(results),
|
|
121526
|
+
message: bulkFailureMessage("Paused", action, results, (result) => result.message ?? `${result.runId}: paused`),
|
|
121527
|
+
failedRuns
|
|
121528
|
+
};
|
|
121529
|
+
}
|
|
121530
|
+
const alreadyPaused = bulkAlreadyPausedCount(results);
|
|
121531
|
+
const summary = paused > 0 ? `Paused ${paused} run(s)${alreadyPaused > 0 ? `; ${alreadyPaused} already paused` : ""}.` : alreadyPaused > 0 ? `${alreadyPaused} in-flight run(s) already paused.` : "No in-flight runs to pause.";
|
|
121202
121532
|
return {
|
|
121203
121533
|
action,
|
|
121204
121534
|
runId: "--all",
|
|
121205
121535
|
status: paused > 0 ? "paused" : "noop",
|
|
121206
121536
|
message: [
|
|
121207
|
-
|
|
121537
|
+
summary,
|
|
121208
121538
|
...results.flatMap((result) => result.ok && result.message !== undefined ? [result.message] : [])
|
|
121209
121539
|
].join(`
|
|
121210
121540
|
`)
|
|
@@ -121213,16 +121543,19 @@ async function workflowPauseAction(args, owner = captureWorkflowOwnerResources()
|
|
|
121213
121543
|
return controlFailure(action, "--all", error);
|
|
121214
121544
|
}
|
|
121215
121545
|
}
|
|
121216
|
-
if (target.kind === "malformed" || target.kind === "not_found")
|
|
121217
|
-
|
|
121546
|
+
if (target.kind === "malformed" || target.kind === "not_found") {
|
|
121547
|
+
const foreign = target.kind === "not_found" ? await foreignRunFailure(action, target.target, guard) : undefined;
|
|
121548
|
+
return foreign ?? { action, runId: target.target, status: "noop", message: target.message, code: "run_not_found" };
|
|
121549
|
+
}
|
|
121218
121550
|
const controlNode = resolveControlNodeTarget(target.runId, args.stageId, store);
|
|
121219
|
-
if (!controlNode.ok)
|
|
121220
|
-
return { action, runId: target.runId, status: "noop", message: controlNode.message };
|
|
121551
|
+
if (!controlNode.ok) {
|
|
121552
|
+
return { action, runId: target.runId, status: "noop", message: controlNode.message, code: controlNode.code };
|
|
121553
|
+
}
|
|
121221
121554
|
if (controlNode.kind === "tool")
|
|
121222
121555
|
return quitToolNodeAction(controlNode.runId, controlNode.nodeId, action, owner);
|
|
121223
121556
|
const stage = resolveToolStageTarget(target.runId, args.stageId, store);
|
|
121224
121557
|
if (!stage.ok)
|
|
121225
|
-
return { action, runId: target.runId, status: "noop", message: stage.message };
|
|
121558
|
+
return { action, runId: target.runId, status: "noop", message: stage.message, code: stage.code };
|
|
121226
121559
|
const stageRunId = stage.runId ?? target.runId;
|
|
121227
121560
|
try {
|
|
121228
121561
|
const result = await pauseRun(stageRunId, { ...owner, stageId: stage.stageId });
|
|
@@ -121238,7 +121571,9 @@ async function workflowPauseAction(args, owner = captureWorkflowOwnerResources()
|
|
|
121238
121571
|
action,
|
|
121239
121572
|
runId: stageRunId,
|
|
121240
121573
|
status: "noop",
|
|
121241
|
-
message: stageFailureMessage(stageRunId, result.reason, "pause")
|
|
121574
|
+
message: stageFailureMessage(stageRunId, result.reason, "pause"),
|
|
121575
|
+
...result.reason === "not_found" ? { code: "run_not_found" } : {},
|
|
121576
|
+
...result.reason === "stage_not_found" ? { code: "stage_not_found" } : {}
|
|
121242
121577
|
};
|
|
121243
121578
|
} catch (error) {
|
|
121244
121579
|
return controlFailure(action, stageRunId, error);
|
|
@@ -121273,7 +121608,8 @@ ${resumed.message}`;
|
|
|
121273
121608
|
action: "resume",
|
|
121274
121609
|
runId: resumed.ok ? resumed.runId : runId,
|
|
121275
121610
|
status: resumed.ok ? "running" : "noop",
|
|
121276
|
-
message
|
|
121611
|
+
message,
|
|
121612
|
+
...resumed.ok ? {} : { code: resumeFailureCode(resumed.reason) }
|
|
121277
121613
|
};
|
|
121278
121614
|
}
|
|
121279
121615
|
async function resumePreparedDurableTarget(runId, deps, budget) {
|
|
@@ -121291,7 +121627,8 @@ async function resumePreparedDurableTarget(runId, deps, budget) {
|
|
|
121291
121627
|
action: "resume",
|
|
121292
121628
|
runId: resumed.ok ? resumed.runId : runId,
|
|
121293
121629
|
status: resumed.ok ? "running" : "noop",
|
|
121294
|
-
message: resumed.message
|
|
121630
|
+
message: resumed.message,
|
|
121631
|
+
...resumed.ok ? {} : { code: resumeFailureCode(resumed.reason) }
|
|
121295
121632
|
};
|
|
121296
121633
|
} catch (error) {
|
|
121297
121634
|
return controlFailure("resume", runId, error);
|
|
@@ -121305,7 +121642,8 @@ function refuseStageScopedDurableResume(runId, args) {
|
|
|
121305
121642
|
action: "resume",
|
|
121306
121643
|
runId,
|
|
121307
121644
|
status: "noop",
|
|
121308
|
-
message: stageScopedDurableResumeMessage(runId)
|
|
121645
|
+
message: stageScopedDurableResumeMessage(runId),
|
|
121646
|
+
code: "stage_resume_unsupported"
|
|
121309
121647
|
};
|
|
121310
121648
|
}
|
|
121311
121649
|
async function resolveExplicitDurableTarget(target, args, deps, liveRuns = []) {
|
|
@@ -121331,7 +121669,7 @@ async function resolveExplicitDurableTarget(target, args, deps, liveRuns = []) {
|
|
|
121331
121669
|
deps.signal?.throwIfAborted();
|
|
121332
121670
|
const resolved = resolveWorkflowResumeTarget(target, liveRuns, durable, completed);
|
|
121333
121671
|
if (resolved.kind === "malformed" || resolved.kind === "ambiguous") {
|
|
121334
|
-
return { action: "resume", runId: target, status: "noop", message: resolved.message };
|
|
121672
|
+
return { action: "resume", runId: target, status: "noop", message: resolved.message, code: "run_not_found" };
|
|
121335
121673
|
}
|
|
121336
121674
|
if (resolved.kind === "durable" || resolved.kind === "live" || resolved.kind === "completed")
|
|
121337
121675
|
deps.authorize?.(resolved.workflowId);
|
|
@@ -121349,7 +121687,8 @@ async function resolveExplicitDurableTarget(target, args, deps, liveRuns = []) {
|
|
|
121349
121687
|
action: "resume",
|
|
121350
121688
|
runId: resolved.workflowId,
|
|
121351
121689
|
status: "noop",
|
|
121352
|
-
message: `Workflow ${resolved.workflowId} is completed, not resumable
|
|
121690
|
+
message: `Workflow ${resolved.workflowId} is completed, not resumable.`,
|
|
121691
|
+
code: "not_resumable"
|
|
121353
121692
|
};
|
|
121354
121693
|
}
|
|
121355
121694
|
const durableHandle = getDurableBackend().getWorkflow(target);
|
|
@@ -121361,7 +121700,8 @@ async function resolveExplicitDurableTarget(target, args, deps, liveRuns = []) {
|
|
|
121361
121700
|
action: "resume",
|
|
121362
121701
|
runId: target,
|
|
121363
121702
|
status: "noop",
|
|
121364
|
-
message: `Workflow ${target} has no durable checkpoint or pending prompt progress and is not resumable
|
|
121703
|
+
message: `Workflow ${target} has no durable checkpoint or pending prompt progress and is not resumable.`,
|
|
121704
|
+
code: "not_resumable"
|
|
121365
121705
|
};
|
|
121366
121706
|
}
|
|
121367
121707
|
if (durableHandle !== undefined) {
|
|
@@ -121370,7 +121710,13 @@ async function resolveExplicitDurableTarget(target, args, deps, liveRuns = []) {
|
|
|
121370
121710
|
return refusal;
|
|
121371
121711
|
return resumePreparedDurableTarget(target, deps, args.budget);
|
|
121372
121712
|
}
|
|
121373
|
-
return {
|
|
121713
|
+
return {
|
|
121714
|
+
action: "resume",
|
|
121715
|
+
runId: target,
|
|
121716
|
+
status: "noop",
|
|
121717
|
+
message: `Run not found: ${target}`,
|
|
121718
|
+
code: "run_not_found"
|
|
121719
|
+
};
|
|
121374
121720
|
}
|
|
121375
121721
|
async function workflowResumeAction(args, deps) {
|
|
121376
121722
|
const owner = deps.owner ?? captureWorkflowOwnerResources();
|
|
@@ -121385,18 +121731,25 @@ async function workflowResumeAction(args, deps) {
|
|
|
121385
121731
|
if (target.kind === "all")
|
|
121386
121732
|
return { action: "resume", runId: "--all", status: "noop", message: "Resume does not support --all." };
|
|
121387
121733
|
if (target.kind === "malformed") {
|
|
121388
|
-
return { action: "resume", runId: target.target, status: "noop", message: target.message };
|
|
121734
|
+
return { action: "resume", runId: target.target, status: "noop", message: target.message, code: "run_not_found" };
|
|
121389
121735
|
}
|
|
121390
121736
|
if (target.kind === "not_found") {
|
|
121391
121737
|
if (explicitTarget !== undefined && explicitTarget.length > 0) {
|
|
121392
121738
|
return resolveExplicitDurableTarget(explicitTarget, args, deps);
|
|
121393
121739
|
}
|
|
121394
|
-
return { action: "resume", runId: target.target, status: "noop", message: target.message };
|
|
121740
|
+
return { action: "resume", runId: target.target, status: "noop", message: target.message, code: "run_not_found" };
|
|
121395
121741
|
}
|
|
121396
121742
|
deps.authorize?.(target.runId);
|
|
121397
121743
|
const requestedStage = resolveToolStageTarget(target.runId, args.stageId, store);
|
|
121398
|
-
if (!requestedStage.ok)
|
|
121399
|
-
return {
|
|
121744
|
+
if (!requestedStage.ok) {
|
|
121745
|
+
return {
|
|
121746
|
+
action: "resume",
|
|
121747
|
+
runId: target.runId,
|
|
121748
|
+
status: "noop",
|
|
121749
|
+
message: requestedStage.message,
|
|
121750
|
+
code: requestedStage.code
|
|
121751
|
+
};
|
|
121752
|
+
}
|
|
121400
121753
|
const backend = getDurableBackend();
|
|
121401
121754
|
const exact = store.runs().find((run) => run.id === target.runId);
|
|
121402
121755
|
const shadow = exact === undefined ? "not_shadow" : classifyDurableResumeShadow(exact, store, {
|
|
@@ -121416,7 +121769,8 @@ async function workflowResumeAction(args, deps) {
|
|
|
121416
121769
|
action: "resume",
|
|
121417
121770
|
runId: target.runId,
|
|
121418
121771
|
status: "noop",
|
|
121419
|
-
message: `Workflow ${target.runId} has no durable checkpoint or pending prompt progress and is not resumable
|
|
121772
|
+
message: `Workflow ${target.runId} has no durable checkpoint or pending prompt progress and is not resumable.`,
|
|
121773
|
+
code: "not_resumable"
|
|
121420
121774
|
};
|
|
121421
121775
|
}
|
|
121422
121776
|
if (toolControlRegistry.runControl(target.runId) === undefined && !backend.isWorkflowLoadable(target.runId)) {
|
|
@@ -121432,16 +121786,24 @@ async function workflowResumeAction(args, deps) {
|
|
|
121432
121786
|
deps.signal?.throwIfAborted();
|
|
121433
121787
|
if (!backend.isWorkflowLoadable(target.runId)) {
|
|
121434
121788
|
store.removeRun(target.runId);
|
|
121435
|
-
return {
|
|
121789
|
+
return {
|
|
121790
|
+
action: "resume",
|
|
121791
|
+
runId: target.runId,
|
|
121792
|
+
status: "noop",
|
|
121793
|
+
message: `Run not found: ${target.runId}`,
|
|
121794
|
+
code: "run_not_found"
|
|
121795
|
+
};
|
|
121436
121796
|
}
|
|
121437
121797
|
}
|
|
121438
121798
|
let warning;
|
|
121439
121799
|
const stage = resolveToolStageTarget(target.runId, args.stageId, store);
|
|
121440
|
-
if (!stage.ok)
|
|
121441
|
-
return { action: "resume", runId: target.runId, status: "noop", message: stage.message };
|
|
121800
|
+
if (!stage.ok) {
|
|
121801
|
+
return { action: "resume", runId: target.runId, status: "noop", message: stage.message, code: stage.code };
|
|
121802
|
+
}
|
|
121442
121803
|
const stageRunId = stage.runId ?? target.runId;
|
|
121443
121804
|
const run = store.runs().find((candidate) => candidate.id === stageRunId);
|
|
121444
121805
|
const hadPausedRunState = run?.status === "paused";
|
|
121806
|
+
const endedBeforeResume = run?.endedAt !== undefined;
|
|
121445
121807
|
const hadPausedStageState = run !== undefined && workflowHasPausedStages(store, stageRunId);
|
|
121446
121808
|
const isPaused = run !== undefined && workflowHasPausedState(store, stageRunId);
|
|
121447
121809
|
const isDurableAuthorExit = run?.exited === true && run.status === "failed" && run.resumable === true;
|
|
@@ -121473,7 +121835,8 @@ ${continuation.message}`;
|
|
|
121473
121835
|
action: "resume",
|
|
121474
121836
|
runId: continuation.ok ? continuation.runId : stageRunId,
|
|
121475
121837
|
status: continuation.ok ? "running" : "noop",
|
|
121476
|
-
message
|
|
121838
|
+
message,
|
|
121839
|
+
...continuation.ok ? {} : { code: resumeFailureCode(continuation.reason) }
|
|
121477
121840
|
};
|
|
121478
121841
|
}
|
|
121479
121842
|
try {
|
|
@@ -121489,9 +121852,22 @@ ${continuation.message}`;
|
|
|
121489
121852
|
const message = result.message ?? (isPaused ? result.resumed.length === 0 ? runLevelResumed ? `Resumed run ${result.runId}.` : `No paused stages on run ${result.runId}.` : `Resumed ${result.resumed.length} stage(s) on run ${result.runId}${args.message ? ` with message: "${args.message}"` : ""}.` : `Snapshot available: run ${result.runId} (${result.snapshot.name}) — status: ${result.snapshot.status}, stages: ${result.snapshot.stages.length}`);
|
|
121490
121853
|
const noContinuation = result.mode === "not_resumable" || result.mode === "snapshot" && result.snapshot.status === "blocked";
|
|
121491
121854
|
const status = result.mode === "partial" ? "partial" : noContinuation || noPausedProgress ? "noop" : "ok";
|
|
121492
|
-
|
|
121855
|
+
const notResumable = result.mode === "not_resumable" || endedBeforeResume && result.mode === "snapshot" && result.snapshot.resumable !== true;
|
|
121856
|
+
return {
|
|
121857
|
+
action: "resume",
|
|
121858
|
+
runId: result.runId,
|
|
121859
|
+
status,
|
|
121860
|
+
message,
|
|
121861
|
+
...notResumable ? { code: "not_resumable" } : {}
|
|
121862
|
+
};
|
|
121493
121863
|
}
|
|
121494
|
-
return {
|
|
121864
|
+
return {
|
|
121865
|
+
action: "resume",
|
|
121866
|
+
runId: stageRunId,
|
|
121867
|
+
status: "noop",
|
|
121868
|
+
message: `Run not found: ${stageRunId}`,
|
|
121869
|
+
code: "run_not_found"
|
|
121870
|
+
};
|
|
121495
121871
|
} catch (error) {
|
|
121496
121872
|
return resumeControlFailure(stageRunId, error, store);
|
|
121497
121873
|
}
|
|
@@ -121957,11 +122333,11 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
|
|
|
121957
122333
|
case "answer":
|
|
121958
122334
|
return awaitRequest(workflowAnswerAction(args, owner));
|
|
121959
122335
|
case "pause":
|
|
121960
|
-
return awaitRequest(workflowPauseAction(args, owner));
|
|
122336
|
+
return awaitRequest(workflowPauseAction(args, owner, { getRuntime, authorize }));
|
|
121961
122337
|
case "reload":
|
|
121962
122338
|
return awaitRequest(workflowReloadAction(args, { reloadWorkflowResources }));
|
|
121963
122339
|
case "quit":
|
|
121964
|
-
return awaitRequest(workflowQuitAction(args, owner));
|
|
122340
|
+
return awaitRequest(workflowQuitAction(args, owner, { getRuntime, authorize }));
|
|
121965
122341
|
case "resume":
|
|
121966
122342
|
return awaitRequest(workflowResumeAction(args, {
|
|
121967
122343
|
getRuntime,
|
|
@@ -122587,6 +122963,14 @@ function factory(pi) {
|
|
|
122587
122963
|
const storeWidgetRef = { current: null };
|
|
122588
122964
|
const intercomControlRef = { current: null };
|
|
122589
122965
|
const executeWorkflowTool = makeExecuteWorkflowTool((ctx) => runtimeState.runtimeForContext(ctx), runtimeState.reloadWorkflowResources, runtimeState.ensureWorkflowResourcesLoaded, owner);
|
|
122966
|
+
let sessionContext;
|
|
122967
|
+
pi.on?.("session_start", (_event, ctx) => {
|
|
122968
|
+
sessionContext = ctx;
|
|
122969
|
+
});
|
|
122970
|
+
pi.on?.("session_shutdown", () => {
|
|
122971
|
+
sessionContext = undefined;
|
|
122972
|
+
});
|
|
122973
|
+
pi.registerWorkflowRunControl?.(createSessionRunControl({ execute: executeWorkflowTool, context: () => sessionContext, store: owner.store }));
|
|
122590
122974
|
const executeWorkflowToolWithAutoAttach = async (args, ctx, signal, onRunAccepted) => {
|
|
122591
122975
|
const result = await executeWorkflowTool(args, ctx, signal, onRunAccepted);
|
|
122592
122976
|
if (workflowPolicyFromContext(ctx).allowInputPicker && result.action === "run" && result.status === "running" && result.runId.length > 0 && result.name !== undefined && runtimeState.runtimeProxy.registry.get(result.name)?.autoAttach === true) {
|