@desplega.ai/agent-swarm 1.167.0 → 1.169.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-adapter-zpvy6321.js → acp-adapter-m47zfx4a.js} +2 -2
- package/dist/{actions-fq2zrwtf.js → actions-ws7k3tvq.js} +25 -19
- package/dist/{amp-adapter-5gbk7501.js → amp-adapter-nvv8k8j5.js} +1 -1
- package/dist/{app-nctetn1e.js → app-80w6qspx.js} +5 -5
- package/dist/{assistant-0aq8gjvj.js → assistant-jtq439kw.js} +29 -20
- package/dist/{boot-reembed-1ze5853n.js → boot-reembed-3nc0aaed.js} +4 -4
- package/dist/{boot-reembed-fmp5ww69.js → boot-reembed-feda8wn8.js} +4 -4
- package/dist/{boot-scrub-sweep-cbp8xd4e.js → boot-scrub-sweep-grsa2er0.js} +5 -5
- package/dist/{boot-seeds-22tx8a53.js → boot-seeds-gcfgq44f.js} +7 -7
- package/dist/{claude-adapter-0jhgeh1d.js → claude-adapter-pjv2q7t8.js} +7 -7
- package/dist/{claude-managed-adapter-tzwxy803.js → claude-managed-adapter-0wa8se82.js} +2 -2
- package/dist/{claude-managed-setup-nrhfx5b0.js → claude-managed-setup-zxa9p9tx.js} +1 -1
- package/dist/{claude-sdk-session-wh77rh83.js → claude-sdk-session-c9j6k9kx.js} +8772 -8663
- package/dist/{cli-c2tpw9ck.js → cli-3ry5gx4f.js} +1 -1
- package/dist/{cli-wydz3feg.js → cli-61tbnjpf.js} +214 -2472
- package/dist/{cli-cexctgn5.js → cli-7vz49g7h.js} +101 -34
- package/dist/{cli-6qxmjpem.js → cli-8xjst8q2.js} +34 -22
- package/dist/{cli-tx2zvn23.js → cli-91r17hb1.js} +3 -3
- package/dist/{cli-577bxkf6.js → cli-a8vps458.js} +182 -2208
- package/dist/{cli-tc5zec7v.js → cli-b7y8113e.js} +1 -1
- package/dist/{cli-69egj654.js → cli-bqrs5ycj.js} +1 -1
- package/dist/{cli-cf2vgn9d.js → cli-dv76vq5d.js} +30 -28
- package/dist/{cli-g5erf0zt.js → cli-e2prcx5m.js} +31 -0
- package/dist/{cli-c8r99akr.js → cli-e5qk3m2a.js} +209 -31
- package/dist/{cli-z1dqhc9y.js → cli-eqfbsxsn.js} +3 -3
- package/dist/{cli-kw0jcfje.js → cli-fyeft04q.js} +1 -1
- package/dist/{cli-5qkcdv8c.js → cli-gmdajfw5.js} +3 -3
- package/dist/{cli-ypgba1a8.js → cli-jkfxpg1b.js} +1 -1
- package/dist/{cli-mxvnnv5q.js → cli-jv36y8wz.js} +1 -1
- package/dist/{cli-m7vmeepg.js → cli-km8559dm.js} +6 -6
- package/dist/{cli-ykt8f7va.js → cli-kp3vfknv.js} +1 -1
- package/dist/{cli-ymmc1zxg.js → cli-m23r88re.js} +8 -5
- package/dist/{cli-v1pwxreq.js → cli-n4z21pt8.js} +1 -1
- package/dist/{cli-mxry91sa.js → cli-qg2zhjfc.js} +73 -4
- package/dist/{cli-1yrcfa5s.js → cli-rbr91whd.js} +4 -4
- package/dist/{cli-mkdsy1nq.js → cli-rg1c8ccw.js} +93 -7
- package/dist/cli-rh44xx46.js +2659 -0
- package/dist/cli-s0k2j7q9.js +2084 -0
- package/dist/{cli-ty4bzkqr.js → cli-sajr098b.js} +1 -1
- package/dist/{cli-6vfz44sr.js → cli-swrz3mj8.js} +1 -1
- package/dist/{cli-p8rt8spp.js → cli-vejds37t.js} +2 -2
- package/dist/{cli-jbzbr36n.js → cli-w6xa5nf5.js} +1 -1
- package/dist/{cli-9q3wt23f.js → cli-x6z90nq9.js} +1 -1
- package/dist/{cli-qzmzwegq.js → cli-ysnkvdx6.js} +102 -9
- package/dist/{cli-y0kjpfm9.js → cli-yvxfaem2.js} +2 -2
- package/dist/{cli-pkj1w46r.js → cli-z48ggfyq.js} +1 -1
- package/dist/{cli-6bpvv8h4.js → cli-zzev32jw.js} +1 -1
- package/dist/cli.js +20 -17
- package/dist/{codex-adapter-cgesnjkr.js → codex-adapter-0kpg09ca.js} +3 -3
- package/dist/{codex-hook-15dgc4cb.js → codex-hook-295jpbfa.js} +2 -2
- package/dist/{codex-session-runner-8kd7ddhr.js → codex-session-runner-8n672hxh.js} +3 -3
- package/dist/{commands-h6zaaxym.js → commands-mhmg5n0x.js} +4 -4
- package/dist/{cursor-adapter-v8mm6bp5.js → cursor-adapter-wn8n5zzk.js} +2 -2
- package/dist/{db-qg3myn53.js → db-wa6s1mwv.js} +4 -4
- package/dist/{dispatcher-7vnwj9qw.js → dispatcher-nhs2pkr8.js} +16 -14
- package/dist/{dsh-adapter-tz6hfp5r.js → dsh-adapter-5423p70m.js} +1 -1
- package/dist/{grok-adapter-jdt2dz2s.js → grok-adapter-28pkdt80.js} +3 -3
- package/dist/{handlers-2qtkpncr.js → handlers-5rtf9nng.js} +19 -17
- package/dist/{hook-51yfcgsv.js → hook-krjfkpzy.js} +4 -4
- package/dist/{hook-qnbdgwvd.js → hook-qkm73zk6.js} +5 -5
- package/dist/{http-jsmtag08.js → http-a397xcn4.js} +4845 -3484
- package/dist/{index-2t9kesn1.js → index-ac0v8v9d.js} +4 -4
- package/dist/{index-ekywyv2v.js → index-kqre45fr.js} +16 -14
- package/dist/{index-bt8wkv1w.js → index-rtxg15ah.js} +17 -15
- package/dist/{index-t4g06w93.js → index-vvsq7v45.js} +26 -23
- package/dist/{index-cx1sb9bq.js → index-ytdhtdry.js} +50 -11
- package/dist/{keepalive-4aezx4bj.js → keepalive-psfh8ysx.js} +6 -6
- package/dist/{lead-r44bkpm5.js → lead-m6rppjn7.js} +29 -27
- package/dist/{maintenance-grz5jrzh.js → maintenance-41f837ke.js} +4 -4
- package/dist/{node-qm9eb6z0.js → node-fkajaq96.js} +1 -1
- package/dist/{oauth-refresh-sweep-wm4ctjfj.js → oauth-refresh-sweep-6hr55hm8.js} +5 -5
- package/dist/{onboard-v60zgqf0.js → onboard-ktrtd7cz.js} +2 -2
- package/dist/{otel-impl-ghh4dyf8.js → otel-impl-dq4f2k3m.js} +1 -1
- package/dist/{pi-mono-adapter-0eg8kw2c.js → pi-mono-adapter-e5v9w0hv.js} +3 -2
- package/dist/{pricing-refresh-mjrqvnvw.js → pricing-refresh-kmk7j1ra.js} +6 -6
- package/dist/{rbac-roles-fd5tskj9.js → rbac-roles-9w1dkkxd.js} +4 -4
- package/dist/{rbac-roles-axv4d74x.js → rbac-roles-9ykx9tc5.js} +5 -5
- package/dist/{render-v2-k50j33qd.js → render-v2-ycqm53np.js} +5 -5
- package/dist/resume-cq2pkp8q.js +70 -0
- package/dist/{setup-4syh0pd2.js → setup-0dcmdvbn.js} +2 -2
- package/dist/{virtual-modules-ftr9kwe8.js → virtual-modules-1x9k4jcs.js} +1 -1
- package/dist/{work-objects-jcdbg8rr.js → work-objects-x01x2fh8.js} +19 -17
- package/dist/{worker-x8j8c9sx.js → worker-py1ssb1h.js} +29 -27
- package/openapi.json +15622 -15042
- package/package.json +8 -5
- package/src/apps/store.ts +1 -0
- package/src/artifact-sdk/feedback-overlay.ts +528 -0
- package/src/be/db/workflow-runs.ts +95 -0
- package/src/be/db-queries/slack-inbound.ts +489 -0
- package/src/be/db.ts +9 -2
- package/src/be/extensions/assets.ts +1 -1
- package/src/be/migrations/203_workflow_run_parent_step.sql +10 -0
- package/src/be/migrations/204_slack_inbound_receipts.sql +51 -0
- package/src/be/script-connections.ts +41 -7
- package/src/be/scripts/run-saved.ts +40 -20
- package/src/be/swarm-config-guard.ts +4 -0
- package/src/extensions/catalog.generated.json +17 -0
- package/src/extensions/catalog.ts +1 -1
- package/src/extensions/dispatcher.ts +3 -3
- package/src/heartbeat/heartbeat.ts +152 -2
- package/src/heartbeat/templates.ts +16 -0
- package/src/http/all-routes.ts +1 -0
- package/src/http/index.ts +2 -0
- package/src/http/integrations.ts +3 -1
- package/src/http/mcp-bridge.ts +1 -0
- package/src/http/pages-public.ts +7 -2
- package/src/http/pages.ts +178 -0
- package/src/http/script-connections.ts +35 -0
- package/src/http/slack-inbound.ts +107 -0
- package/src/http/tasks.ts +45 -27
- package/src/http/users.ts +1 -1
- package/src/http/webhooks.ts +20 -20
- package/src/prompts/session-templates.ts +32 -0
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +2 -2
- package/src/providers/claude-adapter.ts +6 -0
- package/src/providers/claude-background-keepalive.ts +100 -0
- package/src/providers/claude-managed-adapter.ts +2 -11
- package/src/providers/claude-sdk-session.ts +7 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/opencode-adapter.ts +1 -2
- package/src/providers/pi-mono-adapter.ts +3 -3
- package/src/realtime/browser.generated.txt +8 -8
- package/src/realtime/browser.ts +3 -3
- package/src/scheduler/scheduler.ts +82 -13
- package/src/scripts-runtime/executors/quickjs-pool-config.ts +26 -0
- package/src/scripts-runtime/executors/quickjs.ts +9 -2
- package/src/scripts-runtime/executors/registry.ts +1 -1
- package/src/server.ts +1 -0
- package/src/slack/actions.ts +6 -2
- package/src/slack/app.ts +5 -0
- package/src/slack/assistant.ts +15 -5
- package/src/slack/egress-scrub.ts +3 -2
- package/src/slack/handlers.ts +36 -18
- package/src/slack/inbound-dispatch.ts +549 -0
- package/src/slack/inbound-files.ts +2 -0
- package/src/telemetry-context.ts +1 -0
- package/src/tests/claude-background-keepalive-wiring.test.ts +220 -0
- package/src/tests/claude-background-keepalive.fixture.ts +162 -0
- package/src/tests/claude-background-keepalive.test.ts +139 -0
- package/src/tests/codex-oauth-device.test.ts +1 -1
- package/src/tests/connection-embedded-auth.test.ts +51 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/extensions-catalog.test.ts +1 -0
- package/src/tests/extensions-example-slack-reply-gate.test.ts +756 -0
- package/src/tests/heartbeat-checklist.test.ts +243 -0
- package/src/tests/pages-feedback.test.ts +218 -0
- package/src/tests/schedule-target-type.test.ts +136 -0
- package/src/tests/script-connections-http.test.ts +45 -0
- package/src/tests/script-connections-mcp.test.ts +41 -0
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/script-executor-quickjs-pool.test.ts +106 -0
- package/src/tests/script-executor-registry.test.ts +56 -0
- package/src/tests/send-task-self-send.test.ts +107 -0
- package/src/tests/slack-inbound-diagnostics-auth.test.ts +93 -0
- package/src/tests/slack-inbound-receipts.test.ts +684 -0
- package/src/tests/slack-session-status.test.ts +4 -2
- package/src/tests/ui-e2e-ingest-payload.test.ts +5 -1
- package/src/tests/user-token-routes.test.ts +1 -1
- package/src/tests/workflow-executors.test.ts +3 -2
- package/src/tests/workflow-sub-workflow.test.ts +363 -0
- package/src/tools/script-connections/tool.ts +35 -3
- package/src/tools/send-task.ts +9 -1
- package/src/utils/internal-ai/complete-structured.ts +6 -3
- package/src/utils/runtime-model-catalog.ts +1 -1
- package/src/workflows/engine.ts +17 -1
- package/src/workflows/executors/agent-task.ts +2 -2
- package/src/workflows/executors/human-in-the-loop.ts +3 -3
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/script.ts +1 -1
- package/src/workflows/executors/sub-workflow.ts +135 -0
- package/src/workflows/executors/wait.ts +3 -3
- package/src/workflows/recovery.ts +11 -1
- package/src/workflows/resume.ts +77 -0
- package/src/workflows/wait-filter.ts +5 -7
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/slack-reply-gate/README.md +98 -0
- package/templates/extensions/slack-reply-gate/hooks.ts +582 -0
- package/templates/extensions/slack-reply-gate/manifest.json +8 -0
- package/templates/skills/heartbeat-runbook/content.md +3 -1
- package/templates/skills/pages/content.md +25 -0
- package/templates/skills/swarm-scripts/SKILL.md +10 -0
- package/templates/skills/swarm-scripts/content.md +10 -0
|
@@ -44,7 +44,7 @@ import type {
|
|
|
44
44
|
* default; the image installs exactly this version and the per-task settings
|
|
45
45
|
* set `amp.updates.mode: "disabled"`. Bump it deliberately, with a live run.
|
|
46
46
|
*/
|
|
47
|
-
export const AMP_PACKAGE = "@ampcode/cli@0.0.
|
|
47
|
+
export const AMP_PACKAGE = "@ampcode/cli@0.0.1791633643-g895a91";
|
|
48
48
|
|
|
49
49
|
/** MCP server name. Amp exposes its tools as `agent_swarm` / `store_progress` (dashes become underscores). */
|
|
50
50
|
const AMP_MCP_SERVER_NAME = "agent-swarm";
|
|
@@ -537,7 +537,7 @@ class AmpSession implements ProviderSession {
|
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
private get stdin(): AmpStdin {
|
|
540
|
-
return this.proc.stdin as
|
|
540
|
+
return this.proc.stdin as AmpStdin;
|
|
541
541
|
}
|
|
542
542
|
|
|
543
543
|
private async writeInput(text: string): Promise<void> {
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
terminateProcessGroup,
|
|
42
42
|
} from "../utils/process-group";
|
|
43
43
|
import { scrubSecrets } from "../utils/secret-scrubber";
|
|
44
|
+
import { ClaudeBackgroundKeepalive } from "./claude-background-keepalive";
|
|
44
45
|
import { normalizeClaudeMessage } from "./claude-session-events";
|
|
45
46
|
import { resolveSlashSkillPrompt } from "./codex-skill-resolver";
|
|
46
47
|
import { CTX_MODE_NUDGE_EVERY } from "./ctx-mode-env";
|
|
@@ -904,6 +905,8 @@ class ClaudeSession implements ProviderSession {
|
|
|
904
905
|
private lastAssistantText = "";
|
|
905
906
|
/** Per-session stream-json transcript used by the parent-owned session summarizer. */
|
|
906
907
|
private transcript: string[];
|
|
908
|
+
/** Keeps the session heartbeat fresh while Claude idles on background tasks. */
|
|
909
|
+
private backgroundKeepalive: ClaudeBackgroundKeepalive;
|
|
907
910
|
readonly deliverSteering?: (delivery: SteerDelivery) => Promise<SteerDeliveryResult>;
|
|
908
911
|
|
|
909
912
|
constructor(
|
|
@@ -925,6 +928,7 @@ class ClaudeSession implements ProviderSession {
|
|
|
925
928
|
this.contextWindowSize = getContextWindowSize(model);
|
|
926
929
|
this.systemPromptFile = systemPromptFile;
|
|
927
930
|
this.transcript = [`User: ${scrubSecrets(config.prompt)}`];
|
|
931
|
+
this.backgroundKeepalive = new ClaudeBackgroundKeepalive(config);
|
|
928
932
|
const cmd = this.buildCommand();
|
|
929
933
|
|
|
930
934
|
console.log(
|
|
@@ -1158,6 +1162,7 @@ class ClaudeSession implements ProviderSession {
|
|
|
1158
1162
|
try {
|
|
1159
1163
|
await Promise.all([stdoutPromise, stderrPromise]);
|
|
1160
1164
|
} finally {
|
|
1165
|
+
this.backgroundKeepalive.stop();
|
|
1161
1166
|
this.closeStdin();
|
|
1162
1167
|
}
|
|
1163
1168
|
await logFileHandle.end();
|
|
@@ -1226,6 +1231,7 @@ class ClaudeSession implements ProviderSession {
|
|
|
1226
1231
|
if (json.type === "result") {
|
|
1227
1232
|
this.closeStdin();
|
|
1228
1233
|
}
|
|
1234
|
+
this.backgroundKeepalive.observe(json);
|
|
1229
1235
|
|
|
1230
1236
|
const normalized = normalizeClaudeMessage(json, {
|
|
1231
1237
|
taskId: this.config.taskId,
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps a Claude session's heartbeat fresh while it waits on background work.
|
|
3
|
+
*
|
|
4
|
+
* A Claude session that starts a `run_in_background` Bash job (or backgrounds a
|
|
5
|
+
* subagent) can end its turn and sit idle until the job's task_notification
|
|
6
|
+
* wakes it. During that wait it makes no tool calls and streams no output, so
|
|
7
|
+
* neither liveness input (the PostToolUse heartbeat and session-log ingestion)
|
|
8
|
+
* moves `active_sessions.lastHeartbeatAt`, and the stalled-task sweep classifies
|
|
9
|
+
* the live session as stale after `HEARTBEAT_STALL_STALE_HB_MIN`.
|
|
10
|
+
*
|
|
11
|
+
* Claude Code emits `system/background_tasks_changed` with the full set of live
|
|
12
|
+
* background tasks on every membership change (REPLACE semantics). While that
|
|
13
|
+
* set holds at least one non-ambient task, this pings the session heartbeat on
|
|
14
|
+
* an interval. With no background work the timer never runs, so a hung session
|
|
15
|
+
* still goes stale. A background job that never settles is bounded too: the
|
|
16
|
+
* keepalive stops once the session has emitted nothing for
|
|
17
|
+
* `BACKGROUND_KEEPALIVE_MAX_IDLE_MS`.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Ping interval; well inside the 15-minute stale-session threshold. */
|
|
21
|
+
export const BACKGROUND_KEEPALIVE_INTERVAL_MS = 60_000;
|
|
22
|
+
/** Longest silent wait on background work that the keepalive will cover. */
|
|
23
|
+
export const BACKGROUND_KEEPALIVE_MAX_IDLE_MS = 2 * 60 * 60_000;
|
|
24
|
+
|
|
25
|
+
type BackgroundTaskEntry = { task_id?: unknown; ambient?: unknown };
|
|
26
|
+
|
|
27
|
+
export interface ClaudeBackgroundKeepaliveOptions {
|
|
28
|
+
apiUrl: string;
|
|
29
|
+
apiKey: string;
|
|
30
|
+
agentId: string;
|
|
31
|
+
taskId: string;
|
|
32
|
+
intervalMs?: number;
|
|
33
|
+
maxIdleMs?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class ClaudeBackgroundKeepalive {
|
|
37
|
+
private liveTaskIds: string[] = [];
|
|
38
|
+
private timer: ReturnType<typeof setInterval> | undefined;
|
|
39
|
+
private lastMessageAt = Date.now();
|
|
40
|
+
private stopped = false;
|
|
41
|
+
private readonly intervalMs: number;
|
|
42
|
+
private readonly maxIdleMs: number;
|
|
43
|
+
|
|
44
|
+
constructor(private readonly options: ClaudeBackgroundKeepaliveOptions) {
|
|
45
|
+
this.intervalMs = options.intervalMs ?? BACKGROUND_KEEPALIVE_INTERVAL_MS;
|
|
46
|
+
this.maxIdleMs = options.maxIdleMs ?? BACKGROUND_KEEPALIVE_MAX_IDLE_MS;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Feed every protocol message the Claude process emits. */
|
|
50
|
+
observe(message: { type?: string; subtype?: string; tasks?: unknown }): void {
|
|
51
|
+
if (this.stopped) return;
|
|
52
|
+
this.lastMessageAt = Date.now();
|
|
53
|
+
if (message.type === "system" && message.subtype === "background_tasks_changed") {
|
|
54
|
+
const tasks = Array.isArray(message.tasks) ? (message.tasks as BackgroundTaskEntry[]) : [];
|
|
55
|
+
// Ambient tasks (live-update watchers, skip_transcript tasks) are not
|
|
56
|
+
// activity; Claude Code asks hosts to leave them out of activity signals.
|
|
57
|
+
this.liveTaskIds = tasks
|
|
58
|
+
.filter((task) => task && task.ambient !== true && typeof task.task_id === "string")
|
|
59
|
+
.map((task) => task.task_id as string);
|
|
60
|
+
}
|
|
61
|
+
// Any message restarts a keepalive the idle cap stopped, while work is live.
|
|
62
|
+
if (this.liveTaskIds.length > 0) this.start();
|
|
63
|
+
else this.clearTimer();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Stop pinging for good; call when the session ends. */
|
|
67
|
+
stop(): void {
|
|
68
|
+
this.stopped = true;
|
|
69
|
+
this.liveTaskIds = [];
|
|
70
|
+
this.clearTimer();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private start(): void {
|
|
74
|
+
if (this.timer !== undefined) return;
|
|
75
|
+
if (!this.options.apiUrl || !this.options.taskId) return;
|
|
76
|
+
this.timer = setInterval(() => this.tick(), this.intervalMs);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private tick(): void {
|
|
80
|
+
if (Date.now() - this.lastMessageAt > this.maxIdleMs) {
|
|
81
|
+
this.clearTimer();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const { apiUrl, apiKey, agentId, taskId } = this.options;
|
|
85
|
+
void fetch(`${apiUrl}/api/active-sessions/heartbeat/${encodeURIComponent(taskId)}`, {
|
|
86
|
+
method: "PUT",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
Authorization: `Bearer ${apiKey}`,
|
|
90
|
+
"X-Agent-ID": agentId,
|
|
91
|
+
},
|
|
92
|
+
}).catch(() => {});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private clearTimer(): void {
|
|
96
|
+
if (this.timer === undefined) return;
|
|
97
|
+
clearInterval(this.timer);
|
|
98
|
+
this.timer = undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -37,8 +37,6 @@
|
|
|
37
37
|
|
|
38
38
|
import Anthropic from "@anthropic-ai/sdk";
|
|
39
39
|
// Real type usages (the Phase 1 imports become non-decorative as of this phase).
|
|
40
|
-
import type { BetaManagedAgentsAgent as Agent } from "@anthropic-ai/sdk/resources/beta/agents";
|
|
41
|
-
import type { BetaEnvironment as Environment } from "@anthropic-ai/sdk/resources/beta/environments";
|
|
42
40
|
import type {
|
|
43
41
|
BetaManagedAgentsAgentMCPToolResultEvent,
|
|
44
42
|
BetaManagedAgentsAgentMCPToolUseEvent,
|
|
@@ -57,7 +55,6 @@ import type {
|
|
|
57
55
|
BetaManagedAgentsSession as Session,
|
|
58
56
|
BetaManagedAgentsSessionEvent as SessionEvent,
|
|
59
57
|
} from "@anthropic-ai/sdk/resources/beta/sessions";
|
|
60
|
-
import type { BetaSkill as Skill } from "@anthropic-ai/sdk/resources/beta/skills";
|
|
61
58
|
|
|
62
59
|
import { checkToolLoop } from "../hooks/tool-loop-detection";
|
|
63
60
|
import {
|
|
@@ -107,13 +104,6 @@ export function checkClaudeManagedCredentials(env: Record<string, string | undef
|
|
|
107
104
|
};
|
|
108
105
|
}
|
|
109
106
|
|
|
110
|
-
// Re-export the type aliases at module level so adjacent files / tests can use
|
|
111
|
-
// the short names without re-discovering the long Beta-prefixed ones. Kept on
|
|
112
|
-
// `void` lines so unused-import lints stay quiet for the type imports above.
|
|
113
|
-
void (null as unknown as Agent);
|
|
114
|
-
void (null as unknown as Environment);
|
|
115
|
-
void (null as unknown as Skill);
|
|
116
|
-
|
|
117
107
|
/**
|
|
118
108
|
* Required env vars validated at construction time. Listing them in one place
|
|
119
109
|
* keeps the error messages consistent and makes it easy for Phase 2 (worker
|
|
@@ -677,7 +667,7 @@ class ClaudeManagedSession implements ProviderSession {
|
|
|
677
667
|
events: [
|
|
678
668
|
{
|
|
679
669
|
type: "user.message",
|
|
680
|
-
content: this.userMessageContent
|
|
670
|
+
content: this.userMessageContent,
|
|
681
671
|
},
|
|
682
672
|
],
|
|
683
673
|
});
|
|
@@ -857,6 +847,7 @@ export class ClaudeManagedAdapter implements ProviderAdapter {
|
|
|
857
847
|
// our narrower `ManagedAgentsClient` interface (which exists for
|
|
858
848
|
// testability) but TypeScript can't infer that without us spelling out
|
|
859
849
|
// every method signature on both sides.
|
|
850
|
+
// oxlint-disable-next-line anti-slop/no-chained-type-assertions -- see the comment above.
|
|
860
851
|
this.client = new Anthropic({ apiKey: this.apiKey }) as unknown as ManagedAgentsClient;
|
|
861
852
|
}
|
|
862
853
|
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
cleanupTaskFile,
|
|
30
30
|
runClaudeSessionSummary,
|
|
31
31
|
} from "./claude-adapter";
|
|
32
|
+
import { ClaudeBackgroundKeepalive } from "./claude-background-keepalive";
|
|
32
33
|
import type { ClaudeProtocolMessage } from "./claude-session-events";
|
|
33
34
|
import { normalizeClaudeMessage } from "./claude-session-events";
|
|
34
35
|
import type {
|
|
@@ -317,8 +318,11 @@ class ClaudeSdkSession implements ProviderSession {
|
|
|
317
318
|
private acceptingInput = true;
|
|
318
319
|
private errorTracker = new SessionErrorTracker();
|
|
319
320
|
private shutdownPromise: Promise<void> | undefined;
|
|
321
|
+
/** Keeps the session heartbeat fresh while Claude idles on background tasks. */
|
|
322
|
+
private backgroundKeepalive: ClaudeBackgroundKeepalive;
|
|
320
323
|
|
|
321
324
|
constructor(private options: CreateClaudeSdkSessionOptions) {
|
|
325
|
+
this.backgroundKeepalive = new ClaudeBackgroundKeepalive(options.config);
|
|
322
326
|
this.model = options.model;
|
|
323
327
|
this.contextWindowSize = getContextWindowSize(options.model);
|
|
324
328
|
this.transcript = [`User: ${scrubSecrets(options.config.prompt)}`];
|
|
@@ -405,7 +409,8 @@ class ClaudeSdkSession implements ProviderSession {
|
|
|
405
409
|
}
|
|
406
410
|
|
|
407
411
|
private handleMessage(message: SDKMessage): boolean {
|
|
408
|
-
const json = message as
|
|
412
|
+
const json = message as ClaudeProtocolMessage;
|
|
413
|
+
this.backgroundKeepalive.observe(json);
|
|
409
414
|
const normalized = normalizeClaudeMessage(json, {
|
|
410
415
|
taskId: this.options.config.taskId,
|
|
411
416
|
agentId: this.options.config.agentId,
|
|
@@ -514,6 +519,7 @@ class ClaudeSdkSession implements ProviderSession {
|
|
|
514
519
|
this.emit({ type: "error", message, category: "sdk_transport" });
|
|
515
520
|
}
|
|
516
521
|
} finally {
|
|
522
|
+
this.backgroundKeepalive.stop();
|
|
517
523
|
this.acceptingInput = false;
|
|
518
524
|
this.input.close();
|
|
519
525
|
if (this.aborted) {
|
|
@@ -37,7 +37,7 @@ import type {
|
|
|
37
37
|
} from "./types";
|
|
38
38
|
|
|
39
39
|
// npm's `latest` is older and lacks the JSON/stdin contract used here.
|
|
40
|
-
export const DSH_PACKAGE = "@deepseek-ai/dsh@0.2.1-alpha.
|
|
40
|
+
export const DSH_PACKAGE = "@deepseek-ai/dsh@0.2.1-alpha.2";
|
|
41
41
|
|
|
42
42
|
export function checkDshCredentials(env: Record<string, string | undefined>): CredStatus {
|
|
43
43
|
return env.DEEPSEEK_API_KEY?.trim() || env.OPENROUTER_API_KEY?.trim()
|
|
@@ -559,8 +559,7 @@ export class OpencodeSession implements ProviderSession {
|
|
|
559
559
|
// so the dashboard's Activity timeline mirrors what other providers
|
|
560
560
|
// emit. We fire tool_start the first time we see a tool part (any
|
|
561
561
|
// status); tool_end fires once when state transitions to "completed".
|
|
562
|
-
const props = (ev as
|
|
563
|
-
.properties;
|
|
562
|
+
const props = (ev as { properties: { sessionID?: string; part?: unknown } }).properties;
|
|
564
563
|
if (props.sessionID !== this._sessionId) break;
|
|
565
564
|
const part = props.part as
|
|
566
565
|
| {
|
|
@@ -1692,9 +1692,9 @@ export class PiMonoAdapter implements ProviderAdapter {
|
|
|
1692
1692
|
try {
|
|
1693
1693
|
const sessionManager = SessionManager.create(this.lastCwd);
|
|
1694
1694
|
// SessionManager stores sessions as files — check if the session exists
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1695
|
+
// oxlint-disable-next-line anti-slop/no-chained-type-assertions -- pi declares list() as static, so this optional call finds nothing.
|
|
1696
|
+
const listable = sessionManager as unknown as { list?(): Promise<Array<{ id: string }>> };
|
|
1697
|
+
const sessions = await listable.list?.();
|
|
1698
1698
|
return sessions?.some((s) => s.id === sessionId) ?? false;
|
|
1699
1699
|
} catch {
|
|
1700
1700
|
return false;
|