@inneranimalmedia/agentsam-sdk 2.6.10 → 2.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/TRADEMARKS.md +22 -0
- package/apps/README.md +3 -0
- package/apps/cad-creator/LICENSE +21 -0
- package/apps/cad-creator/README.md +4 -1
- package/apps/cad-creator/shared/cad/package.json +1 -1
- package/apps/client-cms-editor/LICENSE +21 -0
- package/apps/client-cms-editor/README.md +3 -0
- package/apps/client-cms-editor/backend/package.json +2 -2
- package/apps/client-cms-editor/frontend/package.json +3 -3
- package/apps/client-cms-editor/package-lock.json +43 -43
- package/apps/client-cms-editor/package.json +3 -3
- package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +1 -1
- package/apps/client-cms-editor/reference/harvest/README.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +1 -1
- package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +1 -1
- package/apps/client-cms-editor/shared/cms/package.json +1 -1
- package/docs/MINI.md +4 -2
- package/docs/REPO_FILE_MAP.txt +0 -1
- package/docs/SOURCE_ARCHITECTURE.md +1 -1
- package/docs/architecture/DUAL_ANALYTICS_PRODUCT.md +140 -0
- package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
- package/docs/engineering/go-portability/01-product-project-deployment-authority.md +69 -0
- package/docs/engineering/provider-internal-renames/01-lane-initialization.md +20 -0
- package/docs/engineering/provider-internal-renames/01a-runtime-environment-contract.md +115 -0
- package/docs/engineering/provider-internal-renames/02-cfoa.md +57 -0
- package/docs/engineering/provider-internal-renames/03-gclioa.md +32 -0
- package/docs/engineering/provider-internal-renames/04-goaude.md +50 -0
- package/docs/engineering/provider-internal-renames/05-gdrv.md +33 -0
- package/docs/engineering/provider-internal-renames/06-verification.md +103 -0
- package/docs/engineering/provider-internal-renames/README.md +77 -0
- package/docs/engineering/provider-internal-renames/runtime-environment-contract.json +220 -0
- package/docs/engineering/test-diagnostics/go-cli-test-hang-20261003.md +49 -0
- package/docs/engineering/test-diagnostics/go-skip-deploy-docker-fix.md +90 -0
- package/docs/knowledge-service-verification.md +3 -3
- package/docs/plans/AGENTSAM-SUSPEND-QUEUE-KNOWLEDGE-RDP-2026-10-03.md +870 -0
- package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +9 -9
- package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +11 -11
- package/docs/plans/RECONCILIATION-2026-09-19.md +6 -6
- package/docs/plans/SAM_WORK_PROTOCOL.md +667 -0
- package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +2 -2
- package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +3 -3
- package/examples/hyperspace-demo/src/main.tsx +227 -110
- package/migrations/d1/0020_agentsam_receipt_catalog.sql +35 -0
- package/migrations/runtime/0006_agent_run_suspend_activity.sql +53 -0
- package/migrations/runtime/0007_queue_control.sql +40 -0
- package/migrations/runtime/0008_agent_run_dependencies.sql +24 -0
- package/migrations/runtime/0008_analytics_legacy_bootstrap.sql +43 -0
- package/migrations/runtime/0009_analytics_authority.sql +108 -0
- package/package.json +26 -11
- package/packages/agentsam-brand/README.md +3 -0
- package/packages/agentsam-brand/package.json +2 -2
- package/packages/agentsam-contracts/dist/adapter.d.ts +22 -0
- package/packages/agentsam-contracts/dist/adapter.js +0 -0
- package/packages/agentsam-contracts/dist/agent.d.ts +66 -0
- package/packages/agentsam-contracts/dist/agent.js +15 -0
- package/packages/agentsam-contracts/dist/artifacts.d.ts +70 -0
- package/packages/agentsam-contracts/dist/artifacts.js +0 -0
- package/packages/agentsam-contracts/dist/authority.d.ts +21 -0
- package/packages/agentsam-contracts/dist/authority.js +0 -0
- package/packages/agentsam-contracts/dist/context.d.ts +14 -0
- package/packages/agentsam-contracts/dist/context.js +0 -0
- package/packages/agentsam-contracts/dist/errors.d.ts +121 -0
- package/packages/agentsam-contracts/dist/errors.js +5 -0
- package/packages/agentsam-contracts/dist/events.d.ts +53 -0
- package/packages/agentsam-contracts/dist/events.js +0 -0
- package/packages/agentsam-contracts/dist/execution.d.ts +38 -0
- package/packages/agentsam-contracts/dist/execution.js +0 -0
- package/packages/agentsam-contracts/dist/hooks.d.ts +31 -0
- package/packages/agentsam-contracts/dist/hooks.js +0 -0
- package/packages/agentsam-contracts/dist/identity.d.ts +15 -0
- package/packages/agentsam-contracts/dist/identity.js +0 -0
- package/packages/agentsam-contracts/dist/index.d.ts +16 -0
- package/packages/agentsam-contracts/dist/index.js +164 -0
- package/packages/agentsam-contracts/dist/models.d.ts +9 -0
- package/packages/agentsam-contracts/dist/models.js +0 -0
- package/packages/agentsam-contracts/dist/providers.d.ts +27 -0
- package/packages/agentsam-contracts/dist/providers.js +0 -0
- package/packages/agentsam-contracts/dist/repository.d.ts +56 -0
- package/packages/agentsam-contracts/dist/repository.js +15 -0
- package/packages/agentsam-contracts/dist/run.d.ts +113 -0
- package/packages/agentsam-contracts/dist/run.js +132 -0
- package/packages/agentsam-contracts/dist/tools.d.ts +82 -0
- package/packages/agentsam-contracts/dist/tools.js +0 -0
- package/packages/agentsam-contracts/dist/widgets.d.ts +38 -0
- package/packages/agentsam-contracts/dist/widgets.js +0 -0
- package/packages/agentsam-contracts/package.json +9 -1
- package/packages/agentsam-contracts/scripts/build.mjs +1 -1
- package/packages/agentsam-contracts/src/agent.ts +78 -3
- package/packages/agentsam-contracts/src/index.ts +2 -0
- package/packages/agentsam-contracts/src/run.ts +320 -0
- package/packages/agentsam-contracts/src/widgets.ts +58 -0
- package/packages/agentsam-contracts/test/contracts.test.mjs +1 -1
- package/packages/agentsam-contracts/test/run-contract.test.mjs +94 -0
- package/packages/agentsam-errors/package.json +1 -1
- package/packages/agentsam-goap/README.md +3 -0
- package/packages/agentsam-goap/package.json +2 -2
- package/packages/agentsam-hooks/package.json +2 -2
- package/packages/agentsam-hooks/src/adapters/agents.js +48 -22
- package/packages/agentsam-hooks/src/index.d.ts +16 -0
- package/packages/agentsam-knowledge/package.json +1 -1
- package/packages/agentsam-knowledge/src/backends/index.js +1 -1
- package/packages/agentsam-merch/README.md +62 -0
- package/packages/agentsam-merch/bin/agentsam-merch.mjs +16 -0
- package/packages/agentsam-merch/package.json +65 -0
- package/packages/agentsam-merch/profiles/completeful/dtg-back-large.json +42 -0
- package/packages/agentsam-merch/profiles/completeful/laser-engraving.json +39 -0
- package/packages/agentsam-merch/profiles/generic/embroidery-digitization.json +22 -0
- package/packages/agentsam-merch/schemas/collection-candidate.schema.json +66 -0
- package/packages/agentsam-merch/schemas/manufacturing-profile.schema.json +221 -0
- package/packages/agentsam-merch/src/adapters-completeful.js +50 -0
- package/packages/agentsam-merch/src/cli.js +93 -0
- package/packages/agentsam-merch/src/collection-lab.js +60 -0
- package/packages/agentsam-merch/src/compatibility.js +501 -0
- package/packages/agentsam-merch/src/derivatives.js +112 -0
- package/packages/agentsam-merch/src/index.d.ts +316 -0
- package/packages/agentsam-merch/src/index.js +46 -0
- package/packages/agentsam-merch/src/node/index.d.ts +58 -0
- package/packages/agentsam-merch/src/node/index.js +6 -0
- package/packages/agentsam-merch/src/node/raster.js +142 -0
- package/packages/agentsam-merch/src/node/vector.js +239 -0
- package/packages/agentsam-merch/src/product-concepts.js +118 -0
- package/packages/agentsam-merch/src/profile-registry.js +104 -0
- package/packages/agentsam-merch/src/profile.js +158 -0
- package/packages/agentsam-merch/src/transforms.js +215 -0
- package/packages/agentsam-merch/test/merch.test.mjs +332 -0
- package/packages/agentsam-merch/test/node-transforms.test.mjs +149 -0
- package/packages/agentsam-nav/dist/browser.global.js +71 -34
- package/packages/agentsam-nav/dist/browser.js +3179 -781
- package/packages/agentsam-nav/dist/index.js +3171 -773
- package/packages/agentsam-nav/package.json +1 -1
- package/packages/agentsam-queue-control/README.md +4 -1
- package/packages/agentsam-queue-control/package.json +4 -3
- package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +111 -11
- package/packages/agentsam-queue-control/src/adapters/cloudflare.js +34 -6
- package/packages/agentsam-queue-control/src/adapters/memory.js +11 -2
- package/packages/agentsam-queue-control/src/adapters/sqlite.js +259 -0
- package/packages/agentsam-queue-control/src/contracts.js +207 -3
- package/packages/agentsam-queue-control/src/control-plane.js +62 -2
- package/packages/agentsam-queue-control/src/index.js +1 -0
- package/packages/agentsam-queue-control/test/queue-control.test.mjs +310 -0
- package/packages/agentsam-queue-control/test/sqlite-adapter.test.mjs +91 -0
- package/packages/agentsam-rapid-rust/README.md +3 -0
- package/packages/agentsam-repository/README.md +3 -0
- package/packages/agentsam-repository/package.json +1 -1
- package/packages/agentsam-vault/package.json +1 -1
- package/packages/agentsam-workbench/README.md +43 -0
- package/packages/agentsam-workbench/package.json +13 -3
- package/packages/agentsam-workbench/src/agent/AgentConversationSurface.tsx +108 -0
- package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +25 -8
- package/packages/agentsam-workbench/src/agent/AgentRuntimeField.tsx +152 -0
- package/packages/agentsam-workbench/src/agent/Composer.tsx +10 -1
- package/packages/agentsam-workbench/src/agent/RunMode.ts +26 -0
- package/packages/agentsam-workbench/src/agent/Thread.tsx +18 -3
- package/packages/agentsam-workbench/src/agent/index.ts +3 -0
- package/packages/agentsam-workbench/src/index.ts +4 -0
- package/packages/agentsam-workbench/src/manufacturing/PreflightIndicator.tsx +203 -0
- package/packages/agentsam-workbench/src/manufacturing/index.ts +2 -0
- package/packages/agentsam-workbench/src/manufacturing/loading.ts +147 -0
- package/packages/agentsam-workbench/src/widgets/BuiltinWidget.tsx +22 -0
- package/packages/agentsam-workbench/src/widgets/CountdownWidget.tsx +68 -0
- package/packages/agentsam-workbench/src/widgets/WidgetFrame.tsx +56 -0
- package/packages/agentsam-workbench/src/widgets/countdown.ts +25 -0
- package/packages/agentsam-workbench/src/widgets/index.ts +6 -0
- package/packages/agentsam-workbench/src/widgets/registry.ts +13 -0
- package/packages/agentsam-workbench/src/widgets/useCountdown.ts +128 -0
- package/packages/agentsam-workbench/src/widgets/widgets.css +102 -0
- package/packages/connectors/{cloudflare → cfoa}/package.json +3 -3
- package/packages/heuristic-theme/package.json +1 -1
- package/packages/identity/README.md +3 -0
- package/packages/identity/backend/README.md +3 -0
- package/packages/identity/package.json +1 -1
- package/packages/identity/src/frontend/auth-portal/README.md +3 -0
- package/packages/identity/src/index.js +1 -1
- package/packages/identity/src/oauth/README.md +4 -1
- package/packages/identity/src/oauth/credentials.js +1 -1
- package/packages/identity/src/server/worker-router.js +1 -1
- package/packages/identity/tests/google-desktop-identity-login.test.mjs +1 -1
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
- package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +1 -1
- package/packages/providers/completeful/package.json +1 -1
- package/packages/theme-church-site/package.json +1 -1
- package/packages/theme-companions-site/package.json +1 -1
- package/packages/theme-floors-site/package.json +1 -1
- package/packages/theme-fuelnfree-site/package.json +1 -1
- package/packages/theme-handyman-site/package.json +1 -1
- package/packages/theme-insurance-site/package.json +1 -1
- package/packages/theme-scenes/package.json +1 -1
- package/packages/theme-shinshu-site/package.json +1 -1
- package/packages/work-graph/package.json +1 -1
- package/protocol/models/README.md +3 -0
- package/protocol/receipts/agentsam.receipt.v1.json +95 -0
- package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +6 -6
- package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +6 -6
- package/skills/README.md +3 -0
- package/src/acp/agent-executor.js +106 -0
- package/src/acp/client.js +316 -0
- package/src/acp/dependencies.js +426 -0
- package/src/acp/http.js +207 -0
- package/src/acp/index.js +22 -0
- package/src/acp/runs.js +125 -0
- package/src/acp/runtime-selection.js +180 -0
- package/src/cli/command-catalog.js +3 -0
- package/src/cli.js +24 -0
- package/src/commands/cloudflare-login.js +1 -1
- package/src/commands/cloudflare.js +2 -2
- package/src/commands/connections.js +1 -1
- package/src/commands/go.js +76 -6
- package/src/commands/merch.js +5 -0
- package/src/commands/mini.js +1 -1
- package/src/commands/receipts.js +140 -0
- package/src/commands/run.js +253 -0
- package/src/go/container.js +1 -1
- package/src/go/contract.js +61 -18
- package/src/go/discover.js +0 -4
- package/src/go/index.js +13 -1
- package/src/go/probe.js +109 -0
- package/src/go/{cloudflare.js → providers/cloudflare.js} +36 -136
- package/src/go/verify.js +1 -1
- package/src/indexing/ingest/inventory.js +1 -1
- package/src/lib/deploy/local-studio.js +2 -2
- package/src/lib/mini/scaffold.js +1 -1
- package/src/lib/whoami-capabilities.js +1 -1
- package/src/local/runtime-store.js +8 -0
- package/src/mcp/cloudflare-bundles.js +1 -1
- package/src/plugins/index.js +1 -0
- package/src/plugins/registry.js +59 -6
- package/src/receipts/contract.js +68 -0
- package/src/receipts/index.js +20 -0
- package/src/receipts/prune.js +64 -0
- package/src/receipts/sinks.js +285 -0
- package/templates/mini/gadget/app.js +15 -40
- package/templates/mini/gadget/index.html +7 -7
- package/templates/mini/shared/style.css +1 -1
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
- /package/packages/connectors/{cloudflare → cfoa}/OAUTH_STORAGE_AUDIT.md +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/api-client.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/capabilities.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/credential.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/brand-protection.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/keyless.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/pages.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/scanner.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/snippets.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/tag-gateway.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/tags.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/token-validation.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/vectorize.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/families/workflows.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/index.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/oauth-persist.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/owner.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/permission-options.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/routes.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/scope-catalog.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/src/vault.js +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/capabilities.test.mjs +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/connector.test.mjs +0 -0
- /package/packages/connectors/{cloudflare → cfoa}/tests/oauth-persist.test.mjs +0 -0
- /package/packages/identity/src/oauth/{google-desktop-exchange.js → goaude.js} +0 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import {
|
|
3
|
+
QueueControl,
|
|
4
|
+
SqliteQueueAdapter,
|
|
5
|
+
buildQueueTopology,
|
|
6
|
+
} from '../../packages/agentsam-queue-control/src/index.js';
|
|
7
|
+
|
|
8
|
+
function clean(value) {
|
|
9
|
+
return value == null ? '' : String(value).trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createLocalQueueControl(database) {
|
|
13
|
+
return new QueueControl({
|
|
14
|
+
adapter: new SqliteQueueAdapter({
|
|
15
|
+
database,
|
|
16
|
+
leaseOwner: 'agentsam-acp-local',
|
|
17
|
+
}),
|
|
18
|
+
topology: buildQueueTopology({
|
|
19
|
+
namespace: 'agentsam',
|
|
20
|
+
environment: 'local',
|
|
21
|
+
mode: 'compact',
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function nextEventSeq(database, runId) {
|
|
27
|
+
const row = await database.prepare(
|
|
28
|
+
'SELECT COALESCE(MAX(seq), -1) + 1 AS next_seq FROM agentsam_agent_run_event WHERE run_id = ?'
|
|
29
|
+
).bind(runId).first();
|
|
30
|
+
return Number(row?.next_seq || 0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function appendAgentRunEvent(database, {
|
|
34
|
+
runId,
|
|
35
|
+
parentRunId = null,
|
|
36
|
+
eventType,
|
|
37
|
+
phase = null,
|
|
38
|
+
stepId = null,
|
|
39
|
+
label = '',
|
|
40
|
+
detail = null,
|
|
41
|
+
evidence = {},
|
|
42
|
+
dedupeKey = null,
|
|
43
|
+
sourceKind = 'sam',
|
|
44
|
+
sourceName = 'agent-control-plane',
|
|
45
|
+
createdAt = Math.floor(Date.now() / 1000),
|
|
46
|
+
} = {}) {
|
|
47
|
+
const id = clean(runId);
|
|
48
|
+
const type = clean(eventType);
|
|
49
|
+
if (!id) throw new TypeError('runId is required');
|
|
50
|
+
if (!type) throw new TypeError('eventType is required');
|
|
51
|
+
|
|
52
|
+
const eventId = `evt_${randomUUID()}`;
|
|
53
|
+
const seq = await nextEventSeq(database, id);
|
|
54
|
+
await database.prepare(`
|
|
55
|
+
INSERT OR IGNORE INTO agentsam_agent_run_event (
|
|
56
|
+
event_id, run_id, parent_run_id, seq, event_type, phase, step_id,
|
|
57
|
+
label, detail, source_kind, source_name, evidence_json, dedupe_key,
|
|
58
|
+
created_at_unix
|
|
59
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
60
|
+
`).bind(
|
|
61
|
+
eventId,
|
|
62
|
+
id,
|
|
63
|
+
clean(parentRunId) || null,
|
|
64
|
+
seq,
|
|
65
|
+
type,
|
|
66
|
+
clean(phase) || null,
|
|
67
|
+
clean(stepId) || null,
|
|
68
|
+
clean(label),
|
|
69
|
+
detail == null ? null : String(detail),
|
|
70
|
+
clean(sourceKind) || 'sam',
|
|
71
|
+
clean(sourceName) || null,
|
|
72
|
+
JSON.stringify(evidence && typeof evidence === 'object' ? evidence : {}),
|
|
73
|
+
clean(dedupeKey) || null,
|
|
74
|
+
createdAt,
|
|
75
|
+
).run();
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
event_id: eventId,
|
|
79
|
+
run_id: id,
|
|
80
|
+
seq,
|
|
81
|
+
event_type: type,
|
|
82
|
+
dedupe_key: clean(dedupeKey) || null,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function pendingChildIds(database, parentRunId) {
|
|
87
|
+
const result = await database.prepare(`
|
|
88
|
+
SELECT child_run_id
|
|
89
|
+
FROM agentsam_agent_run_dependency
|
|
90
|
+
WHERE parent_run_id = ? AND status = 'pending'
|
|
91
|
+
ORDER BY created_at_unix ASC, child_run_id ASC
|
|
92
|
+
`).bind(parentRunId).all();
|
|
93
|
+
return (result.results || []).map((row) => row.child_run_id);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export async function spawnChildRun(database, {
|
|
97
|
+
parentRunId,
|
|
98
|
+
childRunId = null,
|
|
99
|
+
accountId = null,
|
|
100
|
+
objective = '',
|
|
101
|
+
role = null,
|
|
102
|
+
workItemId = null,
|
|
103
|
+
stepId = null,
|
|
104
|
+
modelKey = null,
|
|
105
|
+
reasoningEffort = null,
|
|
106
|
+
serviceTier = null,
|
|
107
|
+
runtimeRequirements = {},
|
|
108
|
+
metadata = {},
|
|
109
|
+
priority = 'normal',
|
|
110
|
+
} = {}) {
|
|
111
|
+
const parentId = clean(parentRunId);
|
|
112
|
+
if (!parentId) throw new TypeError('parentRunId is required');
|
|
113
|
+
|
|
114
|
+
const parent = await database.prepare(
|
|
115
|
+
'SELECT * FROM agentsam_agent_run WHERE id = ? LIMIT 1'
|
|
116
|
+
).bind(parentId).first();
|
|
117
|
+
if (!parent) {
|
|
118
|
+
const error = new Error(`parent_run_not_found:${parentId}`);
|
|
119
|
+
error.code = 'parent_run_not_found';
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
if (['completed', 'failed', 'cancelled'].includes(parent.status)) {
|
|
123
|
+
const error = new Error(`parent_run_terminal:${parent.status}`);
|
|
124
|
+
error.code = 'parent_run_terminal';
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const currentSuspension = await database.prepare(
|
|
129
|
+
'SELECT state FROM agentsam_agent_run_suspension WHERE run_id = ? LIMIT 1'
|
|
130
|
+
).bind(parentId).first();
|
|
131
|
+
if (currentSuspension && currentSuspension.state !== 'waiting_child') {
|
|
132
|
+
const error = new Error(`parent_run_already_suspended:${currentSuspension.state}`);
|
|
133
|
+
error.code = 'parent_run_already_suspended';
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const childId = clean(childRunId) || `arun_${randomUUID()}`;
|
|
138
|
+
const resolvedAccount = clean(accountId) || clean(parent.account_id) || 'local';
|
|
139
|
+
const now = Math.floor(Date.now() / 1000);
|
|
140
|
+
|
|
141
|
+
await database.prepare(`
|
|
142
|
+
INSERT INTO agentsam_agent_run (
|
|
143
|
+
id, account_id, conversation_id, parent_run_id, source_client, surface,
|
|
144
|
+
mode, model_key, reasoning_effort, requested_service_tier, selected_by,
|
|
145
|
+
status, created_at_unix, updated_at_unix
|
|
146
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'agent', ?, ?, ?, 'automatic', 'queued', ?, ?)
|
|
147
|
+
`).bind(
|
|
148
|
+
childId,
|
|
149
|
+
resolvedAccount,
|
|
150
|
+
parent.conversation_id || null,
|
|
151
|
+
parentId,
|
|
152
|
+
parent.source_client || 'agentsam-acp',
|
|
153
|
+
parent.surface || 'control-plane',
|
|
154
|
+
clean(modelKey) || parent.model_key || null,
|
|
155
|
+
clean(reasoningEffort) || parent.reasoning_effort || null,
|
|
156
|
+
clean(serviceTier) || parent.requested_service_tier || null,
|
|
157
|
+
now,
|
|
158
|
+
now,
|
|
159
|
+
).run();
|
|
160
|
+
|
|
161
|
+
await database.prepare(`
|
|
162
|
+
INSERT INTO agentsam_agent_run_dependency (
|
|
163
|
+
parent_run_id, child_run_id, relation, work_item_id, step_id, status,
|
|
164
|
+
metadata_json, created_at_unix, updated_at_unix
|
|
165
|
+
) VALUES (?, ?, 'blocks', ?, ?, 'pending', ?, ?, ?)
|
|
166
|
+
`).bind(
|
|
167
|
+
parentId,
|
|
168
|
+
childId,
|
|
169
|
+
clean(workItemId) || null,
|
|
170
|
+
clean(stepId) || null,
|
|
171
|
+
JSON.stringify(metadata && typeof metadata === 'object' ? metadata : {}),
|
|
172
|
+
now,
|
|
173
|
+
now,
|
|
174
|
+
).run();
|
|
175
|
+
|
|
176
|
+
const pending = await pendingChildIds(database, parentId);
|
|
177
|
+
await database.prepare(`
|
|
178
|
+
UPDATE agentsam_agent_run
|
|
179
|
+
SET status = 'paused', updated_at_unix = ?
|
|
180
|
+
WHERE id = ?
|
|
181
|
+
`).bind(now, parentId).run();
|
|
182
|
+
|
|
183
|
+
await database.prepare(`
|
|
184
|
+
INSERT INTO agentsam_agent_run_suspension (
|
|
185
|
+
run_id, state, reason, dependency_run_ids_json, resume_step_id,
|
|
186
|
+
metadata_json, created_at_unix, updated_at_unix
|
|
187
|
+
) VALUES (?, 'waiting_child', 'child_run', ?, ?, ?, ?, ?)
|
|
188
|
+
ON CONFLICT(run_id) DO UPDATE SET
|
|
189
|
+
state = 'waiting_child',
|
|
190
|
+
reason = 'child_run',
|
|
191
|
+
dependency_run_ids_json = excluded.dependency_run_ids_json,
|
|
192
|
+
resume_step_id = COALESCE(excluded.resume_step_id, agentsam_agent_run_suspension.resume_step_id),
|
|
193
|
+
metadata_json = excluded.metadata_json,
|
|
194
|
+
updated_at_unix = excluded.updated_at_unix
|
|
195
|
+
`).bind(
|
|
196
|
+
parentId,
|
|
197
|
+
JSON.stringify(pending),
|
|
198
|
+
clean(stepId) || null,
|
|
199
|
+
JSON.stringify({
|
|
200
|
+
child_count: pending.length,
|
|
201
|
+
last_child_run_id: childId,
|
|
202
|
+
...(metadata && typeof metadata === 'object' ? metadata : {}),
|
|
203
|
+
}),
|
|
204
|
+
now,
|
|
205
|
+
now,
|
|
206
|
+
).run();
|
|
207
|
+
|
|
208
|
+
await appendAgentRunEvent(database, {
|
|
209
|
+
runId: childId,
|
|
210
|
+
parentRunId: parentId,
|
|
211
|
+
eventType: 'run.created',
|
|
212
|
+
phase: 'boot',
|
|
213
|
+
label: 'Child run created',
|
|
214
|
+
evidence: {
|
|
215
|
+
parent_run_id: parentId,
|
|
216
|
+
objective: clean(objective) || null,
|
|
217
|
+
role: clean(role) || null,
|
|
218
|
+
work_item_id: clean(workItemId) || null,
|
|
219
|
+
},
|
|
220
|
+
dedupeKey: `child:${childId}:created`,
|
|
221
|
+
createdAt: now,
|
|
222
|
+
});
|
|
223
|
+
await appendAgentRunEvent(database, {
|
|
224
|
+
runId: childId,
|
|
225
|
+
parentRunId: parentId,
|
|
226
|
+
eventType: 'run.queued',
|
|
227
|
+
phase: 'boot',
|
|
228
|
+
label: 'Child run queued',
|
|
229
|
+
evidence: { parent_run_id: parentId },
|
|
230
|
+
dedupeKey: `child:${childId}:queued`,
|
|
231
|
+
createdAt: now,
|
|
232
|
+
});
|
|
233
|
+
await appendAgentRunEvent(database, {
|
|
234
|
+
runId: parentId,
|
|
235
|
+
parentRunId: parent.parent_run_id || null,
|
|
236
|
+
eventType: 'run.suspended',
|
|
237
|
+
phase: 'waiting',
|
|
238
|
+
stepId: clean(stepId) || null,
|
|
239
|
+
label: 'Waiting for child run',
|
|
240
|
+
evidence: {
|
|
241
|
+
child_run_id: childId,
|
|
242
|
+
dependency_run_ids: pending,
|
|
243
|
+
work_item_id: clean(workItemId) || null,
|
|
244
|
+
},
|
|
245
|
+
dedupeKey: `wait-child:${childId}`,
|
|
246
|
+
createdAt: now,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const queueControl = createLocalQueueControl(database);
|
|
250
|
+
const queued = await queueControl.enqueue(
|
|
251
|
+
{
|
|
252
|
+
kind: 'agent.run',
|
|
253
|
+
account_id: resolvedAccount,
|
|
254
|
+
priority,
|
|
255
|
+
payload: {
|
|
256
|
+
run_id: childId,
|
|
257
|
+
parent_run_id: parentId,
|
|
258
|
+
objective: clean(objective) || null,
|
|
259
|
+
role: clean(role) || null,
|
|
260
|
+
work_item_id: clean(workItemId) || null,
|
|
261
|
+
step_id: clean(stepId) || null,
|
|
262
|
+
runtime_requirements: runtimeRequirements && typeof runtimeRequirements === 'object'
|
|
263
|
+
? runtimeRequirements
|
|
264
|
+
: {},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
id: `job_agent_run_${childId}`,
|
|
269
|
+
account_id: resolvedAccount,
|
|
270
|
+
source_run_id: childId,
|
|
271
|
+
step_id: clean(stepId) || null,
|
|
272
|
+
conversation_id: parent.conversation_id || null,
|
|
273
|
+
idempotency_key: `agent-run:${childId}`,
|
|
274
|
+
priority,
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
schema: 'agentsam.child-run-spawn.v1',
|
|
280
|
+
parent_run_id: parentId,
|
|
281
|
+
child_run_id: childId,
|
|
282
|
+
dependency_status: 'pending',
|
|
283
|
+
pending_child_run_ids: pending,
|
|
284
|
+
queue: queued.plan?.physical_queue || null,
|
|
285
|
+
queue_job: queued.job,
|
|
286
|
+
published: queued.published,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export async function reconcileParentAfterChildTerminal(database, {
|
|
291
|
+
runId,
|
|
292
|
+
status,
|
|
293
|
+
errorCode = null,
|
|
294
|
+
errorMessage = null,
|
|
295
|
+
} = {}) {
|
|
296
|
+
const childId = clean(runId);
|
|
297
|
+
const childStatus = clean(status);
|
|
298
|
+
if (!childId || !childStatus) return { reconciled: false, reason: 'missing_input' };
|
|
299
|
+
if (!['completed', 'failed', 'cancelled', 'partial'].includes(childStatus)) {
|
|
300
|
+
return { reconciled: false, reason: 'non_terminal_child_status' };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const child = await database.prepare(
|
|
304
|
+
'SELECT * FROM agentsam_agent_run WHERE id = ? LIMIT 1'
|
|
305
|
+
).bind(childId).first();
|
|
306
|
+
if (!child?.parent_run_id) return { reconciled: false, reason: 'no_parent' };
|
|
307
|
+
|
|
308
|
+
const parentId = child.parent_run_id;
|
|
309
|
+
const dependencyStatus = childStatus === 'completed'
|
|
310
|
+
? 'satisfied'
|
|
311
|
+
: childStatus === 'cancelled'
|
|
312
|
+
? 'cancelled'
|
|
313
|
+
: 'failed';
|
|
314
|
+
const now = Math.floor(Date.now() / 1000);
|
|
315
|
+
|
|
316
|
+
await database.prepare(`
|
|
317
|
+
UPDATE agentsam_agent_run_dependency
|
|
318
|
+
SET status = ?, completed_at_unix = ?, updated_at_unix = ?
|
|
319
|
+
WHERE child_run_id = ? AND parent_run_id = ? AND status = 'pending'
|
|
320
|
+
`).bind(dependencyStatus, now, now, childId, parentId).run();
|
|
321
|
+
|
|
322
|
+
const remaining = await pendingChildIds(database, parentId);
|
|
323
|
+
await appendAgentRunEvent(database, {
|
|
324
|
+
runId: parentId,
|
|
325
|
+
eventType: 'run.status',
|
|
326
|
+
phase: 'recover',
|
|
327
|
+
label: `Child run ${childStatus}`,
|
|
328
|
+
evidence: {
|
|
329
|
+
child_run_id: childId,
|
|
330
|
+
child_status: childStatus,
|
|
331
|
+
dependency_status: dependencyStatus,
|
|
332
|
+
remaining_child_run_ids: remaining,
|
|
333
|
+
error_code: clean(errorCode) || null,
|
|
334
|
+
error_message: clean(errorMessage) || null,
|
|
335
|
+
},
|
|
336
|
+
dedupeKey: `child-terminal:${childId}:${childStatus}`,
|
|
337
|
+
createdAt: now,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
if (remaining.length > 0) {
|
|
341
|
+
await database.prepare(`
|
|
342
|
+
UPDATE agentsam_agent_run_suspension
|
|
343
|
+
SET dependency_run_ids_json = ?, updated_at_unix = ?
|
|
344
|
+
WHERE run_id = ? AND state = 'waiting_child'
|
|
345
|
+
`).bind(JSON.stringify(remaining), now, parentId).run();
|
|
346
|
+
return {
|
|
347
|
+
reconciled: true,
|
|
348
|
+
parent_run_id: parentId,
|
|
349
|
+
woke_parent: false,
|
|
350
|
+
dependency_status: dependencyStatus,
|
|
351
|
+
remaining_child_run_ids: remaining,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const parent = await database.prepare(
|
|
356
|
+
'SELECT * FROM agentsam_agent_run WHERE id = ? LIMIT 1'
|
|
357
|
+
).bind(parentId).first();
|
|
358
|
+
if (!parent || ['completed', 'failed', 'cancelled'].includes(parent.status)) {
|
|
359
|
+
return {
|
|
360
|
+
reconciled: true,
|
|
361
|
+
parent_run_id: parentId,
|
|
362
|
+
woke_parent: false,
|
|
363
|
+
reason: 'parent_terminal',
|
|
364
|
+
dependency_status: dependencyStatus,
|
|
365
|
+
remaining_child_run_ids: [],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
await database.prepare(
|
|
370
|
+
"DELETE FROM agentsam_agent_run_suspension WHERE run_id = ? AND state = 'waiting_child'"
|
|
371
|
+
).bind(parentId).run();
|
|
372
|
+
await database.prepare(`
|
|
373
|
+
UPDATE agentsam_agent_run
|
|
374
|
+
SET status = 'queued', updated_at_unix = ?
|
|
375
|
+
WHERE id = ?
|
|
376
|
+
`).bind(now, parentId).run();
|
|
377
|
+
|
|
378
|
+
await appendAgentRunEvent(database, {
|
|
379
|
+
runId: parentId,
|
|
380
|
+
eventType: 'run.woken',
|
|
381
|
+
phase: 'recover',
|
|
382
|
+
label: 'Child dependencies resolved',
|
|
383
|
+
evidence: {
|
|
384
|
+
completed_child_run_id: childId,
|
|
385
|
+
completed_child_status: childStatus,
|
|
386
|
+
resume_reason: 'child_run',
|
|
387
|
+
cancel_requested: Boolean(parent.cancel_requested),
|
|
388
|
+
},
|
|
389
|
+
dedupeKey: `wake-child:${childId}`,
|
|
390
|
+
createdAt: now,
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const resolvedAccount = clean(parent.account_id) || clean(child.account_id) || 'local';
|
|
394
|
+
const queueControl = createLocalQueueControl(database);
|
|
395
|
+
const queued = await queueControl.enqueue(
|
|
396
|
+
{
|
|
397
|
+
kind: 'agent.resume',
|
|
398
|
+
account_id: resolvedAccount,
|
|
399
|
+
payload: {
|
|
400
|
+
run_id: parentId,
|
|
401
|
+
wake_reason: 'child_run',
|
|
402
|
+
completed_child_run_id: childId,
|
|
403
|
+
completed_child_status: childStatus,
|
|
404
|
+
cancel_requested: Boolean(parent.cancel_requested),
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
id: `job_agent_resume_${parentId}_${childId}`,
|
|
409
|
+
account_id: resolvedAccount,
|
|
410
|
+
source_run_id: parentId,
|
|
411
|
+
conversation_id: parent.conversation_id || null,
|
|
412
|
+
idempotency_key: `agent-resume:${parentId}:after:${childId}`,
|
|
413
|
+
priority: parent.cancel_requested ? 'high' : 'normal',
|
|
414
|
+
},
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
reconciled: true,
|
|
419
|
+
parent_run_id: parentId,
|
|
420
|
+
woke_parent: true,
|
|
421
|
+
dependency_status: dependencyStatus,
|
|
422
|
+
remaining_child_run_ids: [],
|
|
423
|
+
resume_job: queued.job,
|
|
424
|
+
queue: queued.plan?.physical_queue || null,
|
|
425
|
+
};
|
|
426
|
+
}
|
package/src/acp/http.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
function clean(value) {
|
|
2
|
+
return value == null ? '' : String(value).trim();
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function json(body, status = 200, headers = {}) {
|
|
6
|
+
return Response.json(body, {
|
|
7
|
+
status,
|
|
8
|
+
headers: {
|
|
9
|
+
'cache-control': 'no-store',
|
|
10
|
+
...headers,
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function errorBody(error, fallback = 'acp_request_failed') {
|
|
16
|
+
return {
|
|
17
|
+
error: {
|
|
18
|
+
code: clean(error?.code) || fallback,
|
|
19
|
+
message: clean(error?.message) || fallback,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function statusForError(error) {
|
|
25
|
+
const explicit = Number(error?.status || error?.statusCode);
|
|
26
|
+
if (Number.isInteger(explicit) && explicit >= 400 && explicit <= 599) return explicit;
|
|
27
|
+
const code = clean(error?.code);
|
|
28
|
+
if (code.endsWith('_not_found') || code === 'run_not_found') return 404;
|
|
29
|
+
if (code.includes('required') || code.includes('invalid') || code.startsWith('unknown_')) return 400;
|
|
30
|
+
if (code.includes('terminal') || code.includes('already_')) return 409;
|
|
31
|
+
if (code === 'unauthorized') return 401;
|
|
32
|
+
if (code === 'forbidden') return 403;
|
|
33
|
+
return 500;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function readJson(request) {
|
|
37
|
+
const text = await request.text();
|
|
38
|
+
if (!text) return {};
|
|
39
|
+
try {
|
|
40
|
+
const body = JSON.parse(text);
|
|
41
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
42
|
+
const error = new TypeError('request_body_must_be_object');
|
|
43
|
+
error.code = 'input_invalid';
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
return body;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error?.code === 'input_invalid') throw error;
|
|
49
|
+
const wrapped = new TypeError('invalid_json_body');
|
|
50
|
+
wrapped.code = 'input_invalid';
|
|
51
|
+
throw wrapped;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function segments(pathname) {
|
|
56
|
+
return pathname.split('/').filter(Boolean).map((part) => decodeURIComponent(part));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function requireMethod(request, allowed) {
|
|
60
|
+
if (allowed.includes(request.method)) return;
|
|
61
|
+
const error = new Error('method_not_allowed');
|
|
62
|
+
error.code = 'method_not_allowed';
|
|
63
|
+
error.status = 405;
|
|
64
|
+
error.allowed = allowed;
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function ensureControl(control) {
|
|
69
|
+
if (!control || typeof control !== 'object') throw new TypeError('control adapter is required');
|
|
70
|
+
for (const method of ['start', 'getRun', 'events', 'tree', 'spawn', 'cancel', 'receipt']) {
|
|
71
|
+
if (typeof control[method] !== 'function') throw new TypeError(`control.${method}() is required`);
|
|
72
|
+
}
|
|
73
|
+
return control;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Provider-neutral AgentSam Agent Control Plane HTTP contract.
|
|
78
|
+
*
|
|
79
|
+
* The request router contains no Cloudflare/GCP/Docker/VM assumptions. A host
|
|
80
|
+
* supplies a control adapter backed by its chosen persistence/queue/runtime
|
|
81
|
+
* implementation and may supply authorization separately.
|
|
82
|
+
*/
|
|
83
|
+
export function createAgentControlHttpHandler({
|
|
84
|
+
control,
|
|
85
|
+
authorize = null,
|
|
86
|
+
service = 'agentsam-control-plane',
|
|
87
|
+
} = {}) {
|
|
88
|
+
const adapter = ensureControl(control);
|
|
89
|
+
|
|
90
|
+
return async function handleAgentControlRequest(request, context = {}) {
|
|
91
|
+
try {
|
|
92
|
+
if (!(request instanceof Request)) throw new TypeError('Request is required');
|
|
93
|
+
|
|
94
|
+
if (typeof authorize === 'function') {
|
|
95
|
+
const auth = await authorize(request, context);
|
|
96
|
+
if (auth === false || auth?.ok === false) {
|
|
97
|
+
const error = new Error(auth?.message || 'unauthorized');
|
|
98
|
+
error.code = auth?.code || 'unauthorized';
|
|
99
|
+
error.status = auth?.status || 401;
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const url = new URL(request.url);
|
|
105
|
+
const parts = segments(url.pathname);
|
|
106
|
+
|
|
107
|
+
if (url.pathname === '/health' || url.pathname === '/v1/health') {
|
|
108
|
+
requireMethod(request, ['GET']);
|
|
109
|
+
return json({
|
|
110
|
+
ok: true,
|
|
111
|
+
service,
|
|
112
|
+
protocol: 'agentsam.control.v1',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (parts[0] !== 'v1' || parts[1] !== 'runs') {
|
|
117
|
+
return json(errorBody(Object.assign(new Error('route_not_found'), { code: 'route_not_found' })), 404);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// POST /v1/runs
|
|
121
|
+
if (parts.length === 2) {
|
|
122
|
+
requireMethod(request, ['POST']);
|
|
123
|
+
return json(await adapter.start(await readJson(request)), 202);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const runId = clean(parts[2]);
|
|
127
|
+
if (!runId) {
|
|
128
|
+
const error = new Error('run_id_required');
|
|
129
|
+
error.code = 'run_id_required';
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// GET /v1/runs/:id
|
|
134
|
+
if (parts.length === 3) {
|
|
135
|
+
requireMethod(request, ['GET']);
|
|
136
|
+
const run = await adapter.getRun(runId);
|
|
137
|
+
if (!run) {
|
|
138
|
+
const error = new Error(`run_not_found:${runId}`);
|
|
139
|
+
error.code = 'run_not_found';
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
return json(run);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const action = parts[3];
|
|
146
|
+
if (parts.length !== 4) {
|
|
147
|
+
return json(errorBody(Object.assign(new Error('route_not_found'), { code: 'route_not_found' })), 404);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (action === 'events') {
|
|
151
|
+
requireMethod(request, ['GET']);
|
|
152
|
+
const after = Number(url.searchParams.get('after') ?? -1);
|
|
153
|
+
const limit = Number(url.searchParams.get('limit') ?? 200);
|
|
154
|
+
return json(await adapter.events(runId, {
|
|
155
|
+
after: Number.isFinite(after) ? after : -1,
|
|
156
|
+
limit: Number.isFinite(limit) ? limit : 200,
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (action === 'tree') {
|
|
161
|
+
requireMethod(request, ['GET']);
|
|
162
|
+
const tree = await adapter.tree(runId);
|
|
163
|
+
if (!tree) {
|
|
164
|
+
const error = new Error(`run_not_found:${runId}`);
|
|
165
|
+
error.code = 'run_not_found';
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
return json(tree);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (action === 'spawn') {
|
|
172
|
+
requireMethod(request, ['POST']);
|
|
173
|
+
return json(await adapter.spawn(runId, await readJson(request)), 202);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (action === 'cancel') {
|
|
177
|
+
requireMethod(request, ['POST']);
|
|
178
|
+
const run = await adapter.cancel(runId);
|
|
179
|
+
if (!run) {
|
|
180
|
+
const error = new Error(`run_not_found:${runId}`);
|
|
181
|
+
error.code = 'run_not_found';
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
return json(run, 202);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (action === 'receipt') {
|
|
188
|
+
requireMethod(request, ['GET']);
|
|
189
|
+
const receipt = await adapter.receipt(runId);
|
|
190
|
+
if (!receipt) {
|
|
191
|
+
const error = new Error(`run_not_found:${runId}`);
|
|
192
|
+
error.code = 'run_not_found';
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
return json(receipt);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return json(errorBody(Object.assign(new Error('route_not_found'), { code: 'route_not_found' })), 404);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
const status = statusForError(error);
|
|
201
|
+
const headers = status === 405 && Array.isArray(error?.allowed)
|
|
202
|
+
? { allow: error.allowed.join(', ') }
|
|
203
|
+
: {};
|
|
204
|
+
return json(errorBody(error), status, headers);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
package/src/acp/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DatabaseAgentControlClient,
|
|
3
|
+
LocalAgentControlClient,
|
|
4
|
+
HttpAgentControlClient,
|
|
5
|
+
createAgentControlClient,
|
|
6
|
+
} from './client.js';
|
|
7
|
+
export { createAgentControlHttpHandler } from './http.js';
|
|
8
|
+
export { createRootRun } from './runs.js';
|
|
9
|
+
export {
|
|
10
|
+
appendAgentRunEvent,
|
|
11
|
+
createLocalQueueControl,
|
|
12
|
+
spawnChildRun,
|
|
13
|
+
reconcileParentAfterChildTerminal,
|
|
14
|
+
} from './dependencies.js';
|
|
15
|
+
export { createAgentRunJobHandler } from './agent-executor.js';
|
|
16
|
+
export {
|
|
17
|
+
normalizeRequiredCapabilities,
|
|
18
|
+
normalizeRuntimeRequirements,
|
|
19
|
+
matchRuntimeCandidate,
|
|
20
|
+
selectRuntimeCandidate,
|
|
21
|
+
createRuntimeSelector,
|
|
22
|
+
} from './runtime-selection.js';
|