@bastani/atomic 0.9.41-alpha.3 → 0.9.42-alpha.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/CHANGELOG.md +122 -0
- package/dist/builtin/intercom/CHANGELOG.md +25 -0
- package/dist/builtin/intercom/README.md +7 -3
- package/dist/builtin/intercom/broker/broker-status.ts +48 -0
- package/dist/builtin/intercom/broker/broker.ts +90 -9
- package/dist/builtin/intercom/broker/client.ts +112 -12
- package/dist/builtin/intercom/broker/control.ts +225 -0
- package/dist/builtin/intercom/broker/multinode-router.ts +32 -39
- package/dist/builtin/intercom/broker/paths.ts +4 -0
- package/dist/builtin/intercom/broker/pending-send-registry.ts +27 -5
- package/dist/builtin/intercom/broker/shared-storage-setting.ts +60 -0
- package/dist/builtin/intercom/broker/spawn.ts +13 -4
- package/dist/builtin/intercom/broker/sql-lease-store.ts +23 -0
- package/dist/builtin/intercom/broker/watchdog.ts +105 -0
- package/dist/builtin/intercom/index.bundle.mjs +200 -22
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/types.ts +34 -2
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +14 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +1 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +40 -0
- package/dist/builtin/workflows/README.md +10 -0
- package/dist/builtin/workflows/builtin/{chunk-txbc93t6.js → chunk-3s95f7ry.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-n2gkzkty.js → chunk-edhf30ef.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-8x61e0s7.js → chunk-frqxd4d1.js} +18 -9
- 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 +6 -1
- package/dist/builtin/workflows/src/authoring.d.ts +3 -1
- package/dist/builtin/workflows/src/durable/journal/internal.d.ts +13 -0
- package/dist/builtin/workflows/src/durable/journal/resolution.d.ts +2 -0
- package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +1 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +88554 -82820
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +72635 -0
- package/dist/builtin/workflows/src/index.js +53824 -5907
- package/dist/builtin/workflows/src/local-worker-entry.mjs +72635 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +7 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +2 -0
- package/dist/builtin/workflows/src/workers/public-options.d.ts +31 -0
- package/dist/bun/app-host-modules.d.ts +9 -0
- package/dist/bun/app-host-modules.d.ts.map +1 -0
- package/dist/bun/app-host-modules.js +10 -0
- package/dist/bun/app-host-modules.js.map +1 -0
- package/dist/bun/cli.d.ts +3 -1
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +15 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/internal-intercom-broker.d.ts +17 -0
- package/dist/bun/internal-intercom-broker.d.ts.map +1 -1
- package/dist/bun/internal-intercom-broker.js +29 -0
- package/dist/bun/internal-intercom-broker.js.map +1 -1
- package/dist/bun/internal-workflow-worker.d.ts +4 -0
- package/dist/bun/internal-workflow-worker.d.ts.map +1 -0
- package/dist/bun/internal-workflow-worker.js +37 -0
- package/dist/bun/internal-workflow-worker.js.map +1 -0
- package/dist/bun/split-loader.js +10 -2
- package/dist/bun/split-loader.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +3 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/intercom-command.d.ts +15 -0
- package/dist/cli/intercom-command.d.ts.map +1 -0
- package/dist/cli/intercom-command.js +87 -0
- package/dist/cli/intercom-command.js.map +1 -0
- package/dist/cli/storage-command.d.ts +39 -0
- package/dist/cli/storage-command.d.ts.map +1 -0
- package/dist/cli/storage-command.js +367 -0
- package/dist/cli/storage-command.js.map +1 -0
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +5 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +1 -0
- 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-tasks.d.ts.map +1 -1
- package/dist/core/agent-session-tasks.js +1 -0
- package/dist/core/agent-session-tasks.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 +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/builtin-install-layout.d.ts +6 -0
- package/dist/core/builtin-install-layout.d.ts.map +1 -1
- package/dist/core/builtin-install-layout.js +9 -0
- package/dist/core/builtin-install-layout.js.map +1 -1
- package/dist/core/child-session-options.d.ts.map +1 -1
- package/dist/core/child-session-options.js +3 -0
- package/dist/core/child-session-options.js.map +1 -1
- package/dist/core/exec.js +2 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/template.css +9 -0
- package/dist/core/export-html/template.js +165 -45
- package/dist/core/extensions/loader-host-modules.d.ts +6 -0
- package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-host-modules.js +12 -1
- package/dist/core/extensions/loader-host-modules.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +6 -0
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +18 -0
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/message-types.d.ts +4 -0
- package/dist/core/extensions/message-types.d.ts.map +1 -1
- package/dist/core/extensions/message-types.js.map +1 -1
- package/dist/core/fast-model-routing-transport.d.ts.map +1 -1
- package/dist/core/fast-model-routing-transport.js +5 -1
- package/dist/core/fast-model-routing-transport.js.map +1 -1
- package/dist/core/intercom-broker-control.d.ts +67 -0
- package/dist/core/intercom-broker-control.d.ts.map +1 -0
- package/dist/core/intercom-broker-control.js +17 -0
- package/dist/core/intercom-broker-control.js.map +1 -0
- package/dist/core/model-runtime-streaming.d.ts.map +1 -1
- package/dist/core/model-runtime-streaming.js +38 -1
- package/dist/core/model-runtime-streaming.js.map +1 -1
- package/dist/core/package-manager-git.d.ts +2 -2
- package/dist/core/package-manager-git.d.ts.map +1 -1
- package/dist/core/package-manager-git.js.map +1 -1
- package/dist/core/package-manager-manifest.d.ts.map +1 -1
- package/dist/core/package-manager-manifest.js +9 -1
- package/dist/core/package-manager-manifest.js.map +1 -1
- package/dist/core/package-manager-npm.d.ts +2 -2
- package/dist/core/package-manager-npm.d.ts.map +1 -1
- package/dist/core/package-manager-npm.js.map +1 -1
- package/dist/core/package-manager-paths.d.ts +7 -7
- package/dist/core/package-manager-paths.d.ts.map +1 -1
- package/dist/core/package-manager-paths.js.map +1 -1
- package/dist/core/package-manager-storage-adapters.d.ts +7 -0
- package/dist/core/package-manager-storage-adapters.d.ts.map +1 -0
- package/dist/core/package-manager-storage-adapters.js +76 -0
- package/dist/core/package-manager-storage-adapters.js.map +1 -0
- package/dist/core/package-manager-types.d.ts +4 -0
- package/dist/core/package-manager-types.d.ts.map +1 -1
- package/dist/core/package-manager-types.js.map +1 -1
- package/dist/core/provider-rate-limits.d.ts +23 -0
- package/dist/core/provider-rate-limits.d.ts.map +1 -0
- package/dist/core/provider-rate-limits.js +113 -0
- package/dist/core/provider-rate-limits.js.map +1 -0
- package/dist/core/provider-request-admission.d.ts +7 -0
- package/dist/core/provider-request-admission.d.ts.map +1 -0
- package/dist/core/provider-request-admission.js +91 -0
- package/dist/core/provider-request-admission.js.map +1 -0
- package/dist/core/resource-admission-scope.d.ts +4 -0
- package/dist/core/resource-admission-scope.d.ts.map +1 -0
- package/dist/core/resource-admission-scope.js +9 -0
- package/dist/core/resource-admission-scope.js.map +1 -0
- package/dist/core/sdk-types.d.ts +16 -0
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +18 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-lifecycle-work.d.ts +1 -0
- package/dist/core/session-lifecycle-work.d.ts.map +1 -1
- package/dist/core/session-lifecycle-work.js +1 -0
- package/dist/core/session-lifecycle-work.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +3 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +6 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-schema.d.ts +22 -0
- package/dist/core/settings-schema.d.ts.map +1 -1
- package/dist/core/settings-schema.js +18 -1
- package/dist/core/settings-schema.js.map +1 -1
- package/dist/core/storage/index.d.ts +1 -0
- package/dist/core/storage/index.d.ts.map +1 -1
- package/dist/core/storage/index.js +1 -0
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/node-sqlite.d.ts +2 -1
- package/dist/core/storage/node-sqlite.d.ts.map +1 -1
- package/dist/core/storage/node-sqlite.js +5 -4
- package/dist/core/storage/node-sqlite.js.map +1 -1
- package/dist/core/storage/provider.d.ts +6 -0
- package/dist/core/storage/provider.d.ts.map +1 -1
- package/dist/core/storage/provider.js +27 -7
- package/dist/core/storage/provider.js.map +1 -1
- package/dist/core/storage/sqlite-facade.d.ts +49 -0
- package/dist/core/storage/sqlite-facade.d.ts.map +1 -0
- package/dist/core/storage/sqlite-facade.js +180 -0
- package/dist/core/storage/sqlite-facade.js.map +1 -0
- package/dist/core/storage/storage-status.d.ts +81 -0
- package/dist/core/storage/storage-status.d.ts.map +1 -0
- package/dist/core/storage/storage-status.js +409 -0
- package/dist/core/storage/storage-status.js.map +1 -0
- package/dist/core/tasks/supervisor.d.ts +2 -1
- package/dist/core/tasks/supervisor.d.ts.map +1 -1
- package/dist/core/tasks/supervisor.js +105 -4
- package/dist/core/tasks/supervisor.js.map +1 -1
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +1 -1
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +28 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +7 -3
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +9 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +16 -8
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +69 -2
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js +2 -2
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +80 -22
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +6 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +6 -2
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive-engine/engine-health.d.ts +8 -4
- package/dist/modes/interactive-engine/engine-health.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-health.js +41 -6
- package/dist/modes/interactive-engine/engine-health.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +19 -17
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.js +1 -1
- package/dist/modes/interactive-engine/remote-queue-pause.js.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.d.ts +1 -0
- package/dist/modes/rpc/rpc-input-scheduler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-scheduler.js +4 -1
- package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
- package/dist/modes/rpc/rpc-input.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input.js +29 -7
- package/dist/modes/rpc/rpc-input.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +14 -0
- package/dist/utils/shell.js.map +1 -1
- package/docs/custom-provider/oauth.md +8 -1
- package/docs/extensions/api-reference.md +2 -0
- package/docs/intercom/operations.md +17 -8
- package/docs/intercom/reference.md +1 -1
- package/docs/keybindings.md +1 -1
- package/docs/packages/authoring.md +15 -0
- package/docs/packages.md +3 -2
- package/docs/providers.md +2 -0
- package/docs/reference/cli.md +17 -0
- package/docs/sdk.md +37 -0
- package/docs/settings.md +33 -2
- package/docs/storage.md +191 -219
- package/docs/usage.md +1 -1
- package/docs/workflows/api-reference.md +50 -0
- package/docs/workflows/operations.md +44 -1
- package/docs/workflows.md +25 -0
- package/examples/extensions/gondolin/package-lock.json +14 -24
- package/examples/extensions/gondolin/package.json +1 -1
- package/npm-shrinkwrap.json +35 -35
- package/package.json +4 -4
- package/schemas/settings.schema.json +87 -1
|
@@ -585,6 +585,32 @@ function createMessageReader(onMessage, onError) {
|
|
|
585
585
|
};
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
+
// dist/builtin/intercom/broker/broker-status.ts
|
|
589
|
+
function isObject(value) {
|
|
590
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
591
|
+
}
|
|
592
|
+
function isOptionalString(value) {
|
|
593
|
+
return value === undefined || typeof value === "string";
|
|
594
|
+
}
|
|
595
|
+
function isBrokerStatusReport(value) {
|
|
596
|
+
if (!isObject(value) || typeof value.pid !== "number" || typeof value.sessions !== "number")
|
|
597
|
+
return false;
|
|
598
|
+
const { storage, multiNode } = value;
|
|
599
|
+
if (storage !== undefined && (!isObject(storage) || typeof storage.digest !== "string" || storage.source !== "env" && storage.source !== "settings"))
|
|
600
|
+
return false;
|
|
601
|
+
return isObject(multiNode) && (multiNode.status === "off" || multiNode.status === "starting" || multiNode.status === "on" || multiNode.status === "unavailable") && isOptionalString(multiNode.reason) && isOptionalString(multiNode.adapter) && isOptionalString(multiNode.prefix) && (multiNode.peers === undefined || Array.isArray(multiNode.peers) && multiNode.peers.every((peer) => typeof peer === "string"));
|
|
602
|
+
}
|
|
603
|
+
function describeMultiNodeStatus(multiNode) {
|
|
604
|
+
const storage = multiNode.adapter === undefined ? "" : ` (adapter ${multiNode.adapter}, prefix ${multiNode.prefix ?? "none"})`;
|
|
605
|
+
if (multiNode.status === "off" || multiNode.status === "unavailable") {
|
|
606
|
+
return `${multiNode.status}${storage}${multiNode.reason === undefined ? "" : `: ${multiNode.reason}`}`;
|
|
607
|
+
}
|
|
608
|
+
if (multiNode.status === "starting" || multiNode.peers === undefined)
|
|
609
|
+
return `${multiNode.status}${storage}`;
|
|
610
|
+
const count = `${multiNode.peers.length} peer broker${multiNode.peers.length === 1 ? "" : "s"} live`;
|
|
611
|
+
return `on${storage}, ${count}${multiNode.peers.length === 0 ? "" : ` (${[...new Set(multiNode.peers)].join(", ")})`}`;
|
|
612
|
+
}
|
|
613
|
+
|
|
588
614
|
// dist/builtin/intercom/broker/paths.ts
|
|
589
615
|
import { homedir } from "os";
|
|
590
616
|
import { join } from "path";
|
|
@@ -730,14 +756,14 @@ class PendingSendRegistry {
|
|
|
730
756
|
generation
|
|
731
757
|
};
|
|
732
758
|
attempt.timer = setTimeout(() => {
|
|
733
|
-
this.
|
|
759
|
+
this.expire(attempt);
|
|
734
760
|
}, timeoutMs);
|
|
735
761
|
this.attempts.set(messageId, attempt);
|
|
736
762
|
return { attempt, owner: true };
|
|
737
763
|
}
|
|
738
764
|
resolve(messageId, attemptId, result) {
|
|
739
765
|
const attempt = this.attempts.get(messageId);
|
|
740
|
-
if (!attempt || attempt.attemptId !== attemptId)
|
|
766
|
+
if (!attempt || attempt.timedOut || attempt.attemptId !== attemptId)
|
|
741
767
|
return false;
|
|
742
768
|
this.attempts.delete(messageId);
|
|
743
769
|
if (attempt.timer)
|
|
@@ -748,21 +774,36 @@ class PendingSendRegistry {
|
|
|
748
774
|
}
|
|
749
775
|
extend(messageId, attemptId, timeoutMs) {
|
|
750
776
|
const attempt = this.attempts.get(messageId);
|
|
751
|
-
if (!attempt || (attemptId === undefined ? !attempt.legacyEligible : attempt.attemptId !== attemptId))
|
|
777
|
+
if (!attempt || attempt.timedOut || (attemptId === undefined ? !attempt.legacyEligible : attempt.attemptId !== attemptId))
|
|
752
778
|
return false;
|
|
753
779
|
if (attempt.timer)
|
|
754
780
|
clearTimeout(attempt.timer);
|
|
755
781
|
attempt.timer = setTimeout(() => {
|
|
756
|
-
this.
|
|
782
|
+
this.expire(attempt);
|
|
757
783
|
}, timeoutMs);
|
|
758
784
|
return true;
|
|
759
785
|
}
|
|
760
786
|
resolveLegacy(messageId, result) {
|
|
761
787
|
const attempt = this.attempts.get(messageId);
|
|
762
|
-
if (!attempt?.legacyEligible)
|
|
788
|
+
if (!attempt?.legacyEligible || attempt.timedOut)
|
|
763
789
|
return false;
|
|
764
790
|
return this.resolve(messageId, attempt.attemptId, result);
|
|
765
791
|
}
|
|
792
|
+
expire(attempt) {
|
|
793
|
+
if (this.attempts.get(attempt.messageId) !== attempt)
|
|
794
|
+
return;
|
|
795
|
+
attempt.timedOut = true;
|
|
796
|
+
attempt.timer = undefined;
|
|
797
|
+
attempt.reject(new PendingSendTimeoutError);
|
|
798
|
+
}
|
|
799
|
+
release(attempt) {
|
|
800
|
+
const current = this.attempts.get(attempt.messageId);
|
|
801
|
+
if (current !== attempt || !current.timedOut)
|
|
802
|
+
return false;
|
|
803
|
+
this.attempts.delete(attempt.messageId);
|
|
804
|
+
this.touchGeneration(current);
|
|
805
|
+
return true;
|
|
806
|
+
}
|
|
766
807
|
reject(attempt, error) {
|
|
767
808
|
const current = this.attempts.get(attempt.messageId);
|
|
768
809
|
if (current !== attempt)
|
|
@@ -779,9 +820,14 @@ class PendingSendRegistry {
|
|
|
779
820
|
this.reject(attempt, error);
|
|
780
821
|
}
|
|
781
822
|
}
|
|
782
|
-
var DEFAULT_GENERATION_TTL_MS, DEFAULT_MAX_GENERATIONS = 1e4;
|
|
823
|
+
var DEFAULT_GENERATION_TTL_MS, DEFAULT_MAX_GENERATIONS = 1e4, PendingSendTimeoutError;
|
|
783
824
|
var init_pending_send_registry = __esm(() => {
|
|
784
825
|
DEFAULT_GENERATION_TTL_MS = 10 * 60 * 1000;
|
|
826
|
+
PendingSendTimeoutError = class PendingSendTimeoutError extends Error {
|
|
827
|
+
constructor() {
|
|
828
|
+
super("Send timeout");
|
|
829
|
+
}
|
|
830
|
+
};
|
|
785
831
|
});
|
|
786
832
|
|
|
787
833
|
// dist/builtin/intercom/source-ownership.ts
|
|
@@ -878,16 +924,19 @@ var init_client = __esm(() => {
|
|
|
878
924
|
connectTimeoutMs;
|
|
879
925
|
brokerAcknowledgesReceipt = false;
|
|
880
926
|
brokerAcknowledgesPendingStageRoutes = false;
|
|
927
|
+
brokerAnswersStatus = false;
|
|
881
928
|
socket = null;
|
|
882
929
|
_sessionId = null;
|
|
883
930
|
_supervisorSessionId = null;
|
|
884
931
|
_messageSource;
|
|
885
932
|
pendingSends = new PendingSendRegistry;
|
|
933
|
+
sendResults = new WeakMap;
|
|
886
934
|
pendingReplyTargets = new Map;
|
|
887
935
|
pendingGroupLists = new Map;
|
|
888
936
|
pendingLists = new Map;
|
|
889
937
|
pendingPresence = new Map;
|
|
890
938
|
pendingMemberships = new Map;
|
|
939
|
+
pendingBrokerStatus = new Map;
|
|
891
940
|
_groups = normalizeGroups();
|
|
892
941
|
pendingLiveWorkflowStageRoutes = new Map;
|
|
893
942
|
pendingStageRouteRegistrations = new Map;
|
|
@@ -895,6 +944,43 @@ var init_client = __esm(() => {
|
|
|
895
944
|
pendingRestoringRecipientRequests = new Map;
|
|
896
945
|
disconnecting = false;
|
|
897
946
|
disconnectError = null;
|
|
947
|
+
healthCheck;
|
|
948
|
+
async requestTimeout(socket, error) {
|
|
949
|
+
if (this.socket !== socket || socket.destroyed)
|
|
950
|
+
return this.disconnectError ?? new IntercomClientDisconnectedError;
|
|
951
|
+
if (this.healthCheck?.socket !== socket) {
|
|
952
|
+
const requestId = randomUUID2();
|
|
953
|
+
const result = new Promise((resolve) => {
|
|
954
|
+
const finish = (failure) => {
|
|
955
|
+
clearTimeout(timer);
|
|
956
|
+
this.pendingGroupLists.delete(requestId);
|
|
957
|
+
resolve(failure);
|
|
958
|
+
};
|
|
959
|
+
const timer = setTimeout(() => finish(new IntercomBrokerTimeoutError("Broker health check timed out")), GROUP_REQUEST_TIMEOUT_MS);
|
|
960
|
+
this.pendingGroupLists.set(requestId, { resolve: () => finish(), reject: finish });
|
|
961
|
+
try {
|
|
962
|
+
writeMessage(socket, { type: "list_groups", requestId });
|
|
963
|
+
} catch (cause) {
|
|
964
|
+
finish(new IntercomClientDisconnectedError({ cause }));
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
this.healthCheck = { socket, result };
|
|
968
|
+
}
|
|
969
|
+
const check = this.healthCheck;
|
|
970
|
+
const failure = await check.result;
|
|
971
|
+
if (this.healthCheck === check)
|
|
972
|
+
this.healthCheck = undefined;
|
|
973
|
+
if (failure === undefined)
|
|
974
|
+
return error;
|
|
975
|
+
const reported = failure instanceof IntercomBrokerTimeoutError ? new IntercomBrokerTimeoutError(error.message, { cause: failure }) : failure;
|
|
976
|
+
if (this.socket === socket && !this.disconnecting) {
|
|
977
|
+
this.disconnectError ??= reported;
|
|
978
|
+
this.failPending(this.disconnectError);
|
|
979
|
+
socket.destroy();
|
|
980
|
+
return this.disconnectError;
|
|
981
|
+
}
|
|
982
|
+
return reported;
|
|
983
|
+
}
|
|
898
984
|
constructor(returnAddress = randomUUID2(), options = {}) {
|
|
899
985
|
super();
|
|
900
986
|
if (returnAddress.length === 0)
|
|
@@ -922,6 +1008,8 @@ var init_client = __esm(() => {
|
|
|
922
1008
|
pending.reject(error);
|
|
923
1009
|
for (const pending of this.pendingStageRouteRegistrations.values())
|
|
924
1010
|
pending.reject(error);
|
|
1011
|
+
for (const pending of this.pendingBrokerStatus.values())
|
|
1012
|
+
pending.reject(error);
|
|
925
1013
|
this.pendingLists.clear();
|
|
926
1014
|
this.pendingGroupLists.clear();
|
|
927
1015
|
this.pendingSupervisorAuthorizations.clear();
|
|
@@ -930,6 +1018,7 @@ var init_client = __esm(() => {
|
|
|
930
1018
|
this.pendingMemberships.clear();
|
|
931
1019
|
this.pendingLiveWorkflowStageRoutes.clear();
|
|
932
1020
|
this.pendingStageRouteRegistrations.clear();
|
|
1021
|
+
this.pendingBrokerStatus.clear();
|
|
933
1022
|
}
|
|
934
1023
|
get sessionId() {
|
|
935
1024
|
return this._sessionId;
|
|
@@ -1012,6 +1101,7 @@ var init_client = __esm(() => {
|
|
|
1012
1101
|
this._supervisorSessionId = null;
|
|
1013
1102
|
this.brokerAcknowledgesReceipt = false;
|
|
1014
1103
|
this.brokerAcknowledgesPendingStageRoutes = false;
|
|
1104
|
+
this.brokerAnswersStatus = false;
|
|
1015
1105
|
this._messageSource = undefined;
|
|
1016
1106
|
this.disconnectError = null;
|
|
1017
1107
|
if (connectionEstablished && !wasDisconnecting) {
|
|
@@ -1089,7 +1179,7 @@ var init_client = __esm(() => {
|
|
|
1089
1179
|
}
|
|
1090
1180
|
switch (brokerMessage.type) {
|
|
1091
1181
|
case "registered": {
|
|
1092
|
-
if (typeof brokerMessage.sessionId !== "string" || brokerMessage.supervisorSessionId !== undefined && typeof brokerMessage.supervisorSessionId !== "string" || brokerMessage.acknowledgesReceipt !== undefined && brokerMessage.acknowledgesReceipt !== true || brokerMessage.acknowledgesPendingStageRoutes !== undefined && brokerMessage.acknowledgesPendingStageRoutes !== true) {
|
|
1182
|
+
if (typeof brokerMessage.sessionId !== "string" || brokerMessage.supervisorSessionId !== undefined && typeof brokerMessage.supervisorSessionId !== "string" || brokerMessage.acknowledgesReceipt !== undefined && brokerMessage.acknowledgesReceipt !== true || brokerMessage.acknowledgesPendingStageRoutes !== undefined && brokerMessage.acknowledgesPendingStageRoutes !== true || brokerMessage.brokerStatus !== undefined && brokerMessage.brokerStatus !== true) {
|
|
1093
1183
|
throw new Error("Invalid registered message");
|
|
1094
1184
|
}
|
|
1095
1185
|
if (this._sessionId !== null) {
|
|
@@ -1099,6 +1189,7 @@ var init_client = __esm(() => {
|
|
|
1099
1189
|
this._supervisorSessionId = typeof brokerMessage.supervisorSessionId === "string" ? brokerMessage.supervisorSessionId : null;
|
|
1100
1190
|
this.brokerAcknowledgesReceipt = this.acknowledgesReceipt && brokerMessage.acknowledgesReceipt === true;
|
|
1101
1191
|
this.brokerAcknowledgesPendingStageRoutes = brokerMessage.acknowledgesPendingStageRoutes === true;
|
|
1192
|
+
this.brokerAnswersStatus = brokerMessage.brokerStatus === true;
|
|
1102
1193
|
this.emit("_registered", { type: "registered", sessionId: brokerMessage.sessionId });
|
|
1103
1194
|
break;
|
|
1104
1195
|
}
|
|
@@ -1154,6 +1245,18 @@ var init_client = __esm(() => {
|
|
|
1154
1245
|
pending.resolve(groups);
|
|
1155
1246
|
break;
|
|
1156
1247
|
}
|
|
1248
|
+
case "broker_status": {
|
|
1249
|
+
const { requestId } = brokerMessage;
|
|
1250
|
+
const report = brokerMessage.report;
|
|
1251
|
+
if (typeof requestId !== "string" || !isBrokerStatusReport(report))
|
|
1252
|
+
throw new Error("Invalid broker_status message");
|
|
1253
|
+
const pending = this.pendingBrokerStatus.get(requestId);
|
|
1254
|
+
if (!pending)
|
|
1255
|
+
return;
|
|
1256
|
+
this.pendingBrokerStatus.delete(requestId);
|
|
1257
|
+
pending.resolve(report);
|
|
1258
|
+
break;
|
|
1259
|
+
}
|
|
1157
1260
|
case "supervisor_authorized": {
|
|
1158
1261
|
const { requestId, capability, supervisorSessionId, childName } = brokerMessage;
|
|
1159
1262
|
if (typeof requestId !== "string" || typeof capability !== "string" || typeof supervisorSessionId !== "string" || typeof childName !== "string") {
|
|
@@ -1455,7 +1558,7 @@ var init_client = __esm(() => {
|
|
|
1455
1558
|
const timeout = setTimeout(() => {
|
|
1456
1559
|
if (!this.pendingLists.delete(requestId))
|
|
1457
1560
|
return;
|
|
1458
|
-
|
|
1561
|
+
this.requestTimeout(socket, new Error("List sessions timeout")).then(reject);
|
|
1459
1562
|
}, 5000);
|
|
1460
1563
|
this.pendingLists.set(requestId, {
|
|
1461
1564
|
resolve: (directory) => {
|
|
@@ -1488,7 +1591,7 @@ var init_client = __esm(() => {
|
|
|
1488
1591
|
const timeout = setTimeout(() => {
|
|
1489
1592
|
if (!this.pendingGroupLists.delete(requestId))
|
|
1490
1593
|
return;
|
|
1491
|
-
|
|
1594
|
+
this.requestTimeout(socket, new Error("List groups timeout")).then(reject);
|
|
1492
1595
|
}, GROUP_REQUEST_TIMEOUT_MS);
|
|
1493
1596
|
this.pendingGroupLists.set(requestId, {
|
|
1494
1597
|
resolve: (groups) => {
|
|
@@ -1509,6 +1612,41 @@ var init_client = __esm(() => {
|
|
|
1509
1612
|
}
|
|
1510
1613
|
});
|
|
1511
1614
|
}
|
|
1615
|
+
brokerStatus() {
|
|
1616
|
+
let socket;
|
|
1617
|
+
try {
|
|
1618
|
+
socket = this.requireActiveSocket();
|
|
1619
|
+
} catch (error) {
|
|
1620
|
+
return Promise.reject(toError(error));
|
|
1621
|
+
}
|
|
1622
|
+
if (!this.brokerAnswersStatus)
|
|
1623
|
+
return Promise.resolve(undefined);
|
|
1624
|
+
const requestId = randomUUID2();
|
|
1625
|
+
return new Promise((resolve, reject) => {
|
|
1626
|
+
const timeout = setTimeout(() => {
|
|
1627
|
+
if (!this.pendingBrokerStatus.delete(requestId))
|
|
1628
|
+
return;
|
|
1629
|
+
reject(new Error("Broker status timeout"));
|
|
1630
|
+
}, GROUP_REQUEST_TIMEOUT_MS);
|
|
1631
|
+
this.pendingBrokerStatus.set(requestId, {
|
|
1632
|
+
resolve: (report) => {
|
|
1633
|
+
clearTimeout(timeout);
|
|
1634
|
+
resolve(report);
|
|
1635
|
+
},
|
|
1636
|
+
reject: (error) => {
|
|
1637
|
+
clearTimeout(timeout);
|
|
1638
|
+
reject(error);
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
try {
|
|
1642
|
+
writeMessage(socket, { type: "broker_status", requestId });
|
|
1643
|
+
} catch (error) {
|
|
1644
|
+
clearTimeout(timeout);
|
|
1645
|
+
this.pendingBrokerStatus.delete(requestId);
|
|
1646
|
+
reject(toError(error));
|
|
1647
|
+
}
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1512
1650
|
joinGroup(group) {
|
|
1513
1651
|
return this.updateMembership("join_group", group);
|
|
1514
1652
|
}
|
|
@@ -1527,7 +1665,7 @@ var init_client = __esm(() => {
|
|
|
1527
1665
|
const timeout = setTimeout(() => {
|
|
1528
1666
|
if (!this.pendingMemberships.delete(requestId))
|
|
1529
1667
|
return;
|
|
1530
|
-
|
|
1668
|
+
this.requestTimeout(socket, new Error("Membership update timeout")).then(reject);
|
|
1531
1669
|
}, GROUP_REQUEST_TIMEOUT_MS);
|
|
1532
1670
|
this.pendingMemberships.set(requestId, {
|
|
1533
1671
|
resolve: (groups) => {
|
|
@@ -1563,7 +1701,7 @@ var init_client = __esm(() => {
|
|
|
1563
1701
|
const timeout = setTimeout(() => {
|
|
1564
1702
|
if (!this.pendingSupervisorAuthorizations.delete(requestId))
|
|
1565
1703
|
return;
|
|
1566
|
-
|
|
1704
|
+
this.requestTimeout(socket, new Error("Supervisor authorization timeout")).then(reject);
|
|
1567
1705
|
}, 5000);
|
|
1568
1706
|
this.pendingSupervisorAuthorizations.set(requestId, {
|
|
1569
1707
|
resolve: (authorization) => {
|
|
@@ -1614,7 +1752,7 @@ var init_client = __esm(() => {
|
|
|
1614
1752
|
const timeout = setTimeout(() => {
|
|
1615
1753
|
if (!this.pendingRestoringRecipientRequests.delete(requestId))
|
|
1616
1754
|
return;
|
|
1617
|
-
|
|
1755
|
+
this.requestTimeout(socket, new Error("Restoring-recipient request timeout")).then(reject);
|
|
1618
1756
|
}, RESTORING_RECIPIENT_REQUEST_TIMEOUT_MS);
|
|
1619
1757
|
this.pendingRestoringRecipientRequests.set(requestId, {
|
|
1620
1758
|
resolve: () => {
|
|
@@ -1669,7 +1807,7 @@ var init_client = __esm(() => {
|
|
|
1669
1807
|
const timeout = setTimeout(() => {
|
|
1670
1808
|
if (!this.pendingStageRouteRegistrations.delete(requestId))
|
|
1671
1809
|
return;
|
|
1672
|
-
|
|
1810
|
+
this.requestTimeout(socket, new IntercomBrokerTimeoutError("Pending-stage route registration timeout")).then(reject);
|
|
1673
1811
|
}, PENDING_STAGE_ROUTE_ACK_TIMEOUT_MS);
|
|
1674
1812
|
this.pendingStageRouteRegistrations.set(requestId, {
|
|
1675
1813
|
resolve: () => {
|
|
@@ -1783,8 +1921,22 @@ var init_client = __esm(() => {
|
|
|
1783
1921
|
} catch (error) {
|
|
1784
1922
|
return Promise.reject(toError(error));
|
|
1785
1923
|
}
|
|
1924
|
+
let result = this.sendResults.get(acquired.attempt.promise);
|
|
1925
|
+
if (result === undefined) {
|
|
1926
|
+
result = acquired.attempt.promise.catch(async (error) => {
|
|
1927
|
+
if (error instanceof PendingSendTimeoutError) {
|
|
1928
|
+
try {
|
|
1929
|
+
throw await this.requestTimeout(socket, error);
|
|
1930
|
+
} finally {
|
|
1931
|
+
this.pendingSends.release(acquired.attempt);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
throw error;
|
|
1935
|
+
});
|
|
1936
|
+
this.sendResults.set(acquired.attempt.promise, result);
|
|
1937
|
+
}
|
|
1786
1938
|
if (!acquired.owner)
|
|
1787
|
-
return
|
|
1939
|
+
return result;
|
|
1788
1940
|
const message = {
|
|
1789
1941
|
id: messageId,
|
|
1790
1942
|
timestamp: Date.now(),
|
|
@@ -1817,7 +1969,7 @@ var init_client = __esm(() => {
|
|
|
1817
1969
|
this.pendingReplyTargets.delete(acquired.attempt.attemptId);
|
|
1818
1970
|
};
|
|
1819
1971
|
acquired.attempt.promise.then(clearReplyTarget, clearReplyTarget);
|
|
1820
|
-
return
|
|
1972
|
+
return result;
|
|
1821
1973
|
}
|
|
1822
1974
|
updatePresence(updates) {
|
|
1823
1975
|
if (this.disconnecting) {
|
|
@@ -1854,7 +2006,7 @@ var init_client = __esm(() => {
|
|
|
1854
2006
|
const timeout = setTimeout(() => {
|
|
1855
2007
|
if (!this.pendingPresence.delete(requestId))
|
|
1856
2008
|
return;
|
|
1857
|
-
|
|
2009
|
+
this.requestTimeout(socket, new Error("Presence update timeout")).then(reject);
|
|
1858
2010
|
}, PRESENCE_ACK_TIMEOUT_MS);
|
|
1859
2011
|
this.pendingPresence.set(requestId, {
|
|
1860
2012
|
resolve: wrappedResolve,
|
|
@@ -2039,7 +2191,16 @@ function getBrokerSpawnOptions(extensionDir = EXTENSION_DIR, stderr = "ignore")
|
|
|
2039
2191
|
function resetBrokerLog(logPath = BROKER_LOG) {
|
|
2040
2192
|
ensurePrivateDirectory(dirname(logPath));
|
|
2041
2193
|
try {
|
|
2194
|
+
const previous = readBrokerLogTail(logPath);
|
|
2042
2195
|
closeSync(openSync(logPath, "w"));
|
|
2196
|
+
if (previous.length > 0) {
|
|
2197
|
+
try {
|
|
2198
|
+
const previousPath = `${logPath}.previous`;
|
|
2199
|
+
writeFileSync(previousPath, Buffer.from(previous).subarray(-BROKER_LOG_TAIL_BYTES), { mode: 384 });
|
|
2200
|
+
if (process.platform !== "win32")
|
|
2201
|
+
chmodSync(previousPath, 384);
|
|
2202
|
+
} catch {}
|
|
2203
|
+
}
|
|
2043
2204
|
return true;
|
|
2044
2205
|
} catch (error) {
|
|
2045
2206
|
const code = error.code;
|
|
@@ -2080,7 +2241,7 @@ ${tail}`;
|
|
|
2080
2241
|
function toError2(error) {
|
|
2081
2242
|
return error instanceof Error ? error : new Error(String(error));
|
|
2082
2243
|
}
|
|
2083
|
-
async function spawnBrokerIfNeeded(brokerCommand, brokerArgs, readyTimeoutMs = BROKER_READY_TIMEOUT_MS) {
|
|
2244
|
+
async function spawnBrokerIfNeeded(brokerCommand, brokerArgs, readyTimeoutMs = BROKER_READY_TIMEOUT_MS, extensionDir = EXTENSION_DIR) {
|
|
2084
2245
|
ensurePrivateDirectory(INTERCOM_DIR);
|
|
2085
2246
|
if (await isBrokerRunning()) {
|
|
2086
2247
|
return;
|
|
@@ -2095,8 +2256,8 @@ async function spawnBrokerIfNeeded(brokerCommand, brokerArgs, readyTimeoutMs = B
|
|
|
2095
2256
|
if (await isBrokerRunning()) {
|
|
2096
2257
|
return;
|
|
2097
2258
|
}
|
|
2098
|
-
const brokerPath = resolveBrokerEntrypoint(
|
|
2099
|
-
const launch = getBrokerLaunchSpec(brokerPath, brokerCommand, brokerArgs);
|
|
2259
|
+
const brokerPath = resolveBrokerEntrypoint(extensionDir);
|
|
2260
|
+
const launch = getBrokerLaunchSpec(brokerPath, brokerCommand, brokerArgs, extensionDir);
|
|
2100
2261
|
if (launch.kind === "windows-launcher") {
|
|
2101
2262
|
writeWindowsHiddenLauncher(launch.launcherCommandLine, launch.launcherPath);
|
|
2102
2263
|
}
|
|
@@ -2107,7 +2268,7 @@ async function spawnBrokerIfNeeded(brokerCommand, brokerArgs, readyTimeoutMs = B
|
|
|
2107
2268
|
const logFd = launch.kind === "direct" ? openSync(BROKER_LOG, "a") : undefined;
|
|
2108
2269
|
let child;
|
|
2109
2270
|
try {
|
|
2110
|
-
child = spawn(launch.command, launch.args, getBrokerSpawnOptions(
|
|
2271
|
+
child = spawn(launch.command, launch.args, getBrokerSpawnOptions(extensionDir, logFd ?? "ignore"));
|
|
2111
2272
|
} finally {
|
|
2112
2273
|
if (logFd !== undefined)
|
|
2113
2274
|
closeSync(logFd);
|
|
@@ -3753,6 +3914,19 @@ function retainInconclusiveRetry(reservations, attempt) {
|
|
|
3753
3914
|
remainingRetries: reservations.remainingRetries(attempt)
|
|
3754
3915
|
};
|
|
3755
3916
|
}
|
|
3917
|
+
async function multiNodeStatus(client) {
|
|
3918
|
+
if (typeof client.brokerStatus !== "function")
|
|
3919
|
+
return;
|
|
3920
|
+
try {
|
|
3921
|
+
const report = await client.brokerStatus();
|
|
3922
|
+
if (report === undefined) {
|
|
3923
|
+
return { line: "unknown (the running broker predates status reporting; `atomic intercom restart` replaces it)" };
|
|
3924
|
+
}
|
|
3925
|
+
return { line: describeMultiNodeStatus(report.multiNode), multiNode: report.multiNode };
|
|
3926
|
+
} catch (error) {
|
|
3927
|
+
return { line: `unknown (${getErrorMessage(error)})` };
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3756
3930
|
async function listDirectory(client, group) {
|
|
3757
3931
|
if (typeof client.listDirectory === "function")
|
|
3758
3932
|
return client.listDirectory(group);
|
|
@@ -4750,6 +4924,9 @@ ${lines.join(`
|
|
|
4750
4924
|
const selectedGroupSessions = selectedGroup === undefined ? undefined : await connectedClient.listSessions(selectedGroup);
|
|
4751
4925
|
const selectedSection = selectedGroupSessions === undefined ? "" : `
|
|
4752
4926
|
Selected group [${selectedGroup}]: ${selectedGroupSessions.length} session(s)`;
|
|
4927
|
+
const multiNode = await multiNodeStatus(connectedClient);
|
|
4928
|
+
const multiNodeSection = multiNode === undefined ? "" : `
|
|
4929
|
+
Multi-node routing: ${multiNode.line}`;
|
|
4753
4930
|
return {
|
|
4754
4931
|
content: [{
|
|
4755
4932
|
type: "text",
|
|
@@ -4757,13 +4934,14 @@ Selected group [${selectedGroup}]: ${selectedGroupSessions.length} session(s)`;
|
|
|
4757
4934
|
Connected: Yes
|
|
4758
4935
|
Session ID: ${mySessionId}
|
|
4759
4936
|
Groups: ${ownGroups.join(", ")}
|
|
4760
|
-
Active visible sessions: ${sessions.length}${selectedSection}`
|
|
4937
|
+
Active visible sessions: ${sessions.length}${selectedSection}${multiNodeSection}`
|
|
4761
4938
|
}],
|
|
4762
4939
|
isError: false,
|
|
4763
4940
|
details: {
|
|
4764
4941
|
group: ownGroups.at(-1),
|
|
4765
4942
|
groups: ownGroups,
|
|
4766
|
-
...selectedGroup === undefined ? {} : { selectedGroup, selectedGroupSessionCount: selectedGroupSessions?.length ?? 0 }
|
|
4943
|
+
...selectedGroup === undefined ? {} : { selectedGroup, selectedGroupSessionCount: selectedGroupSessions?.length ?? 0 },
|
|
4944
|
+
...multiNode?.multiNode === undefined ? {} : { multiNode: multiNode.multiNode }
|
|
4767
4945
|
}
|
|
4768
4946
|
};
|
|
4769
4947
|
} catch (error) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.42-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -93,6 +93,28 @@ export interface GroupSummary {
|
|
|
93
93
|
member: boolean;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/** A broker's multi-node routing state, as `broker_status` reports it. */
|
|
97
|
+
export interface BrokerMultiNodeStatus {
|
|
98
|
+
status: "off" | "starting" | "on" | "unavailable";
|
|
99
|
+
/** Why routing is off or unavailable. */
|
|
100
|
+
reason?: string;
|
|
101
|
+
/** The shared selection's adapter module, or `sqlite` for a `path` selection. */
|
|
102
|
+
adapter?: string;
|
|
103
|
+
prefix?: string;
|
|
104
|
+
/** Host names of the other brokers whose membership lease is live, while routing is on. */
|
|
105
|
+
peers?: string[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** What a broker reports about itself; read before registering by `atomic intercom restart` and `atomic storage status`. */
|
|
109
|
+
export interface BrokerStatusReport {
|
|
110
|
+
pid: number;
|
|
111
|
+
/** Sessions connected to this broker. */
|
|
112
|
+
sessions: number;
|
|
113
|
+
/** The shared storage selection the broker read, as a digest of its JSON, and where it read it; absent without one. */
|
|
114
|
+
storage?: { digest: string; source: "env" | "settings" };
|
|
115
|
+
multiNode: BrokerMultiNodeStatus;
|
|
116
|
+
}
|
|
117
|
+
|
|
96
118
|
export interface Message {
|
|
97
119
|
id: string;
|
|
98
120
|
timestamp: number;
|
|
@@ -125,6 +147,7 @@ export interface SupervisorRegistration {
|
|
|
125
147
|
|
|
126
148
|
|
|
127
149
|
export type ClientMessage =
|
|
150
|
+
| { type: "health"; requestId: string }
|
|
128
151
|
| {
|
|
129
152
|
type: "register";
|
|
130
153
|
session: Omit<SessionInfo, "id">;
|
|
@@ -225,9 +248,14 @@ export type ClientMessage =
|
|
|
225
248
|
/** Legacy single-group membership; accepted alongside `groups` for compatibility. */
|
|
226
249
|
group?: string;
|
|
227
250
|
requestId?: string;
|
|
228
|
-
}
|
|
251
|
+
}
|
|
252
|
+
/** Allowed before `register`: the broker's own status. */
|
|
253
|
+
| { type: "broker_status"; requestId: string }
|
|
254
|
+
/** Allowed before `register`: shut the broker down; its sessions reconnect to a new broker. */
|
|
255
|
+
| { type: "shutdown"; requestId: string };
|
|
229
256
|
|
|
230
257
|
export type BrokerMessage =
|
|
258
|
+
| { type: "health"; requestId: string; instanceId: string }
|
|
231
259
|
| {
|
|
232
260
|
type: "registered";
|
|
233
261
|
sessionId: string;
|
|
@@ -236,6 +264,8 @@ export type BrokerMessage =
|
|
|
236
264
|
acknowledgesReceipt?: true;
|
|
237
265
|
/** This broker acknowledges a `register_pending_stage_route` that carries a `requestId`; absent on older brokers. */
|
|
238
266
|
acknowledgesPendingStageRoutes?: true;
|
|
267
|
+
/** This broker answers `broker_status`; absent on older brokers, which drop a client that sends it. */
|
|
268
|
+
brokerStatus?: true;
|
|
239
269
|
}
|
|
240
270
|
| { type: "registration_failed"; reason: string; code?: LiveWorkflowStageRouteRefusalCode }
|
|
241
271
|
| { type: "question_target"; messageId: string; attemptId: string; sessionId: string }
|
|
@@ -272,4 +302,6 @@ export type BrokerMessage =
|
|
|
272
302
|
/** #3760: the send is held for a subagent that is being restored; wait up to `timeoutMs` for its outcome. */
|
|
273
303
|
| { type: "send_held"; messageId: string; attemptId?: string; timeoutMs: number }
|
|
274
304
|
| { type: "restoring_recipient_ack"; requestId: string; error?: string }
|
|
275
|
-
| { type: "delivery_failed"; messageId: string; reason: string; reasonCode?: "message_id_conflict" | "session_not_found"; attemptId?: string }
|
|
305
|
+
| { type: "delivery_failed"; messageId: string; reason: string; reasonCode?: "message_id_conflict" | "session_not_found"; attemptId?: string }
|
|
306
|
+
| { type: "broker_status"; requestId: string; report: BrokerStatusReport }
|
|
307
|
+
| { type: "shutdown_ack"; requestId: string };
|
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.41] - 2026-10-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added a `resumeInFlight` subagent setting (`"never"`, `"ask"`, or `"auto"`, default `"never"`) for recovery of paused and quit subagents that are awaiting resume. `ask` confirms once, listing each subagent, and `auto` resumes each from its own session, with its completion reaching the session that launched it; `never` leaves them for a manual `resume`. It applies when Atomic starts or a session is resumed, to that session's own subagents, never to workflow-stage children, and an invalid value is reported and treated as `never` ([#3827](https://github.com/bastani-inc/atomic/issues/3827)).
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Quitting a subagent now behaves like quitting a workflow. The `quit` and `pause` results say the child is paused · awaiting resume and name `{ action: "resume", id: "<child-id>" }`; the parent's completion notice says the same, with the typed `quit` or `pause` stop reason instead of `parent-handoff` and without "This execution has ended". `{ action: "status", id }` reports a paused or quit child as paused · awaiting resume with its resume call, and `{ action: "status" }` lists every such child, including after Atomic restarts. Launch cards of such children show `‖ Paused · awaiting resume` (or `‖ Quit · paused · awaiting resume`) instead of `(resumable)`.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- A subagent with `model: "auto"` no longer waits indefinitely on a slow routing model. Each routing inference now stops after the `httpIdleTimeoutMs` deadline (10 minutes by default), and the subagent runs on the current chat model when it satisfies the routing constraints ([#3806](https://github.com/bastani-inc/atomic/issues/3806))
|
|
18
|
+
|
|
5
19
|
## [0.9.41-alpha.1] - 2026-10-21
|
|
6
20
|
|
|
7
21
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.42-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with parallel execution. Fork of: https://github.com/nicobailon/pi-subagents",
|
|
6
6
|
"contributors": [
|
|
@@ -13205,6 +13205,7 @@ class SubagentControlRuntime {
|
|
|
13205
13205
|
...inherited,
|
|
13206
13206
|
customTools: admitted.policy.customTools ?? inherited.customTools,
|
|
13207
13207
|
resourceLoader,
|
|
13208
|
+
resourceAdmissionSignal: AbortSignal.any([signals.abort, signals.interrupt]),
|
|
13208
13209
|
subagentPolicy: {
|
|
13209
13210
|
...admitted.policy,
|
|
13210
13211
|
executionEnded: executionEnded.signal,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.42-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,46 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.42-alpha.1] - 2026-10-23
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Local workflow pools can be enabled per run through SDK options or workflow settings, with root and optional user-wide admission limits. A root stays local while registered child workflow subtrees run in local worker processes; unsupported process containment and incompatible worker definitions fail closed ([#3869](https://github.com/bastani-inc/atomic/issues/3869)).
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Workflow model chains now share provider-account cooldowns after rate limits, honor `Retry-After`, and wait for the earliest eligible account instead of exhausting a cooling chain. Retries remain bounded, including retries within each session; waits can be paused or cancelled, and workflow status and task results report provider counts and cooldown deadlines. Retrying a follow-up on the same model preserves its conversation history. Follow-ups keep each model's retry allowance across account switches and can return to an earlier account when its cooldown expires ([#3864](https://github.com/bastani-inc/atomic/issues/3864)).
|
|
18
|
+
- Workflow stages now reload resources up to four at a time per Atomic process instead of one at a time, so a slow reload no longer blocks every other stage at startup. Cancelling a stage waiting for a reload slot removes it from the queue immediately; an active reload retains its slot until it finishes ([#3861](https://github.com/bastani-inc/atomic/issues/3861)).
|
|
19
|
+
- Standalone `run()` now owns Intercom routes for eligible workflow stages until the run settles, so stages can use Intercom without an interactive workflow host. An installed SDK reuses an Intercom owner the extension bundle already registered for the store instead of starting a second one. When a route-update acknowledgement times out, the update retries without disconnecting a healthy owner ([#3863](https://github.com/bastani-inc/atomic/issues/3863))
|
|
20
|
+
|
|
21
|
+
## [0.9.41] - 2026-10-22
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Added `schemaTimeoutMs` to workflow stage, task, chain, and parallel options: the wall-clock limit in milliseconds for each `structured_output` decision of a schema-backed item, covering its repair attempts, retries, and model fallbacks together. It defaults to the `httpIdleTimeoutMs` setting ([#3806](https://github.com/bastani-inc/atomic/issues/3806))
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Reopening `/workflow resume` is faster: the run list is kept between opens and rereads only the runs whose journal changed since the last open, including changes made by other Atomic processes. Whether another session still owns a run is checked when you select it.
|
|
30
|
+
- `/workflow connect` and `/workflow status` now list runs the way `/tasks` does. Active runs come before ended ones, with runs waiting for your input or blocked first, then running, then paused; ended runs follow with failed, cancelled, then completed. Within each group the newest run comes first, where before the `/workflow connect` list showed the oldest running run first ([#3824](https://github.com/bastani-inc/atomic/issues/3824)).
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- A rejection that workflow code leaves unhandled no longer ends the whole Atomic process. This covers a rejected `ctx.tool`, `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` prompt (`input`, `confirm`, `select`, `editor` or `custom`) or stage method call (`prompt`, `complete`, `steer`, `sendUserMessage`, `setModel`, `compact` and the other promise-returning stage methods), including one that is started and never awaited (`void ctx.task(...)` used to leave the run `completed` with no sign of the failure), a `ctx.tool` call made after its run has stopped (`ctx.tool admission is closed for this run`), a string, number or `undefined` thrown from a `ctx.tool` callback, and an error the workflow file throws or receives from `fs` itself, for example in a rolling pool that keeps `branch.finally(...)` as a separate promise. It also covers `ctx.exit()` called inside such a branch, which ends the run as exited with the status and outputs it asked for (on Bun the process used to end right after the run reported `completed`), and a child workflow's own branch that uses `ctx` after its parent exited. Stopping a run no longer ends the process either: a branch that keeps running after `/workflow quit`, a kill, or an abort signal from the code that started the run, and then calls `ctx.stage`, `ctx.task`, `ctx.workflow` or `ctx.exit()`, or that was waiting on a `ctx.ui` prompt when the run was killed, could end it with `workflow killed` (a kill), the quit error (`/workflow quit`), an `AbortError` or `atomic-workflows: HIL aborted` right after the run reported `killed` or `paused`, and the run keeps that status. `ctx.exit()` called in such a branch while the run is paused ends the run as exited once the run resumes, and a kill of the paused run still ends it as `killed` (on Node it used to end as `failed` with `Workflow exit is waiting for explicit resume`, and on Bun the process ended). The rejection fails its own run when it surfaces before that run decides its final status, so other runs, stages, and the interactive engine keep going; a `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` or stage method rejection that the workflow awaits or catches reaches that code unchanged and does not fail the run. Once the run has ended, an error that a `ctx` call rejected with, what `ctx.exit()` threw and the reason the run was stopped with are ignored (the reason of a kill is the string `workflow killed`, which is ignored by value for the rest of the process, so a branch that wakes up long after the run ended is covered too), and so is an error thrown by the workflow file for the next 30 seconds, so the remaining branches of a failing pool cannot end the process; a later one ends it as before. On Node the owning run is identified exactly; on Bun a `ctx` call's rejection, what `ctx.exit()` threw and the reason the run was stopped with are matched by identity (a `ctx` call's string, number or `undefined` only within the event-loop turn in which the call rejected, and the string a kill uses by value), and an error thrown by the workflow file itself is matched through its stack to the run of the file that calls `workflow()`, but only when no other run of that file is running or has run at the same time (a child workflow defined in the same file does not count), so a primitive thrown outside a `ctx` call on Bun is still fatal, and an error that either of two overlapping runs of one file could have thrown ends the process as before instead of failing a run that may be healthy. This works the same in the bundled install as in a source checkout. A rejection that belongs to no workflow run, including one raised by Atomic's own code, ends the process as before, with its original error and stack, and `--unhandled-rejections=warn|none|warn-with-error-code` are honored ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
|
|
35
|
+
- A workflow that omits `name` is now named after the file that defines it when Atomic runs from the bundled install, as it already was in a source checkout, instead of after the bundled extension file (`index.bundle`) ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
|
|
36
|
+
- `/workflow status <runId>` no longer reports `durable checkpoint topology is malformed or incomplete` for a running or crashed run whose child `ctx.workflow` calls have started but not yet recorded a stage or tool of their own, such as a pool of concurrent children when the process was killed. The children now show as running, and a crashed run can be inspected and resumed. A run that fails while such children are still starting now cancels them first, so its status can be inspected as well ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
|
|
37
|
+
- A workflow stage no longer stays stuck selecting its model when many workflows run at once. A stage with `model: "auto"` now waits at most five minutes for model selection, counting any wait for one of eight routing slots shared by every stage, so a burst of stages queues instead of overloading the router provider. When the wait ends, the stage runs on the current chat model if that model satisfies every routing constraint; otherwise it fails with an error that names the stage and the `model-resolution` startup phase, and its startup status reads `failed` instead of staying active. A failed selection is no longer remembered, so the next prompt on the same stage selects a model again, without launching a replacement workflow.
|
|
38
|
+
- After a blocked workflow run is resumed, Intercom sends to `workflow:<rootRunId>/**`, to stage patterns, and to stages that have not started yet are accepted and delivered again instead of failing with `Workflow execution for <runId> is retired`.
|
|
39
|
+
- In a long-running session, starting a workflow from a turn that an Intercom message started no longer fails with `Workflow execution for <runId> is retired; startup cleanup failed: …` after an earlier workflow run in the session has ended or been quit. The session's Intercom connection is now opened outside the workflow run that first needed it. The `is retired` error now names the run whose execution actually ended, not the run being started.
|
|
40
|
+
- A workflow stage whose fallback session fails to start because an extension's `session_start` failed under load, for example Intercom's `Broker failed to start within timeout` or `connect ECONNREFUSED`, now retries that session with the same-model retry budget and then moves on to its next fallback model, instead of failing the stage and letting fail-fast skip its sibling stages. Any other extension startup error still fails the stage at once. The stage error, model attempts, and fallback warnings now name each failing extension and its error rather than only `Extension startup failed`.
|
|
41
|
+
- When a workflow stage falls back to another model and that fallback session cannot start, the stage now closes the session it was replacing. Before, that session kept its session database open after the stage failed, and on Windows the file could not be deleted until the process exited.
|
|
42
|
+
- Workflow stage sessions now provide `ctx.ui.theme` and the other default UI members, so extensions that read `ctx.ui.theme.fg(...)` in `session_start`, such as `examples/extensions/status-line.ts`, no longer fail stage startup with `Extension startup failed` ([#3801](https://github.com/bastani-inc/atomic/issues/3801))
|
|
43
|
+
- Workflow inputs now reject integer and number values outside the `minimum`/`maximum` declared in the input schema, such as `count: 0` for `Type.Integer({ minimum: 1, maximum: 8 })`, when the run is started, instead of passing them to the workflow body. The error names the input and the violated bound ([#3812](https://github.com/bastani-inc/atomic/issues/3812)).
|
|
44
|
+
- A `ctx.parallel(..., { failFast: false })` call that has a failing step no longer loses the results of the steps that succeeded. The `AggregateError` it rejects with now carries `partialResults`, one entry per step in step order, holding each completed step's result and `undefined` for a step that failed. The `WorkflowParallelFailure` type describes it ([#3809](https://github.com/bastani-inc/atomic/issues/3809))
|
|
45
|
+
- A workflow stage's corrective prompt after a rejected `structured_output` result now names the failing paths and expected types, or reports that the tool arguments were not valid JSON, instead of only saying the response does not match the decision schema ([#3802](https://github.com/bastani-inc/atomic/issues/3802))
|
|
46
|
+
- Disposing a session right after a workflow run reports that it ended no longer leaves the run `running` in the workflow journal, with its lease released, for readers to report as crashed. `session.dispose()` now waits up to 10 seconds for runs that have ended but are still recording their ending, before it closes the journal, and it rejects naming the run when that ending still cannot be recorded. A run whose journal rejects the write of its `completed` status now retries it once, and reports it with an error notice and a rejected `waitForSettled` when it still fails, instead of failing in silence ([#3811](https://github.com/bastani-inc/atomic/issues/3811))
|
|
47
|
+
- A schema-backed workflow stage no longer stays `running` for hours inside one `structured_output` call when a slow model keeps generating without calling the tool. The decision now stops after the `httpIdleTimeoutMs` deadline (10 minutes by default) or the stage's `schemaTimeoutMs`, and the error that names the deadline and each attempt's duration reaches the model and the failed stage unchanged instead of being treated as a structured-output contract failure ([#3806](https://github.com/bastani-inc/atomic/issues/3806))
|
|
48
|
+
|
|
9
49
|
## [0.9.41-alpha.2] - 2026-10-22
|
|
10
50
|
|
|
11
51
|
### Fixed
|