@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.
Files changed (261) hide show
  1. package/README.md +3 -0
  2. package/TRADEMARKS.md +22 -0
  3. package/apps/README.md +3 -0
  4. package/apps/cad-creator/LICENSE +21 -0
  5. package/apps/cad-creator/README.md +4 -1
  6. package/apps/cad-creator/shared/cad/package.json +1 -1
  7. package/apps/client-cms-editor/LICENSE +21 -0
  8. package/apps/client-cms-editor/README.md +3 -0
  9. package/apps/client-cms-editor/backend/package.json +2 -2
  10. package/apps/client-cms-editor/frontend/package.json +3 -3
  11. package/apps/client-cms-editor/package-lock.json +43 -43
  12. package/apps/client-cms-editor/package.json +3 -3
  13. package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +1 -1
  14. package/apps/client-cms-editor/reference/harvest/README.md +1 -1
  15. package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +1 -1
  16. package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +1 -1
  17. package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +1 -1
  18. package/apps/client-cms-editor/shared/cms/package.json +1 -1
  19. package/docs/MINI.md +4 -2
  20. package/docs/REPO_FILE_MAP.txt +0 -1
  21. package/docs/SOURCE_ARCHITECTURE.md +1 -1
  22. package/docs/architecture/DUAL_ANALYTICS_PRODUCT.md +140 -0
  23. package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
  24. package/docs/engineering/go-portability/01-product-project-deployment-authority.md +69 -0
  25. package/docs/engineering/provider-internal-renames/01-lane-initialization.md +20 -0
  26. package/docs/engineering/provider-internal-renames/01a-runtime-environment-contract.md +115 -0
  27. package/docs/engineering/provider-internal-renames/02-cfoa.md +57 -0
  28. package/docs/engineering/provider-internal-renames/03-gclioa.md +32 -0
  29. package/docs/engineering/provider-internal-renames/04-goaude.md +50 -0
  30. package/docs/engineering/provider-internal-renames/05-gdrv.md +33 -0
  31. package/docs/engineering/provider-internal-renames/06-verification.md +103 -0
  32. package/docs/engineering/provider-internal-renames/README.md +77 -0
  33. package/docs/engineering/provider-internal-renames/runtime-environment-contract.json +220 -0
  34. package/docs/engineering/test-diagnostics/go-cli-test-hang-20261003.md +49 -0
  35. package/docs/engineering/test-diagnostics/go-skip-deploy-docker-fix.md +90 -0
  36. package/docs/knowledge-service-verification.md +3 -3
  37. package/docs/plans/AGENTSAM-SUSPEND-QUEUE-KNOWLEDGE-RDP-2026-10-03.md +870 -0
  38. package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +9 -9
  39. package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +11 -11
  40. package/docs/plans/RECONCILIATION-2026-09-19.md +6 -6
  41. package/docs/plans/SAM_WORK_PROTOCOL.md +667 -0
  42. package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +2 -2
  43. package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +3 -3
  44. package/examples/hyperspace-demo/src/main.tsx +227 -110
  45. package/migrations/d1/0020_agentsam_receipt_catalog.sql +35 -0
  46. package/migrations/runtime/0006_agent_run_suspend_activity.sql +53 -0
  47. package/migrations/runtime/0007_queue_control.sql +40 -0
  48. package/migrations/runtime/0008_agent_run_dependencies.sql +24 -0
  49. package/migrations/runtime/0008_analytics_legacy_bootstrap.sql +43 -0
  50. package/migrations/runtime/0009_analytics_authority.sql +108 -0
  51. package/package.json +26 -11
  52. package/packages/agentsam-brand/README.md +3 -0
  53. package/packages/agentsam-brand/package.json +2 -2
  54. package/packages/agentsam-contracts/dist/adapter.d.ts +22 -0
  55. package/packages/agentsam-contracts/dist/adapter.js +0 -0
  56. package/packages/agentsam-contracts/dist/agent.d.ts +66 -0
  57. package/packages/agentsam-contracts/dist/agent.js +15 -0
  58. package/packages/agentsam-contracts/dist/artifacts.d.ts +70 -0
  59. package/packages/agentsam-contracts/dist/artifacts.js +0 -0
  60. package/packages/agentsam-contracts/dist/authority.d.ts +21 -0
  61. package/packages/agentsam-contracts/dist/authority.js +0 -0
  62. package/packages/agentsam-contracts/dist/context.d.ts +14 -0
  63. package/packages/agentsam-contracts/dist/context.js +0 -0
  64. package/packages/agentsam-contracts/dist/errors.d.ts +121 -0
  65. package/packages/agentsam-contracts/dist/errors.js +5 -0
  66. package/packages/agentsam-contracts/dist/events.d.ts +53 -0
  67. package/packages/agentsam-contracts/dist/events.js +0 -0
  68. package/packages/agentsam-contracts/dist/execution.d.ts +38 -0
  69. package/packages/agentsam-contracts/dist/execution.js +0 -0
  70. package/packages/agentsam-contracts/dist/hooks.d.ts +31 -0
  71. package/packages/agentsam-contracts/dist/hooks.js +0 -0
  72. package/packages/agentsam-contracts/dist/identity.d.ts +15 -0
  73. package/packages/agentsam-contracts/dist/identity.js +0 -0
  74. package/packages/agentsam-contracts/dist/index.d.ts +16 -0
  75. package/packages/agentsam-contracts/dist/index.js +164 -0
  76. package/packages/agentsam-contracts/dist/models.d.ts +9 -0
  77. package/packages/agentsam-contracts/dist/models.js +0 -0
  78. package/packages/agentsam-contracts/dist/providers.d.ts +27 -0
  79. package/packages/agentsam-contracts/dist/providers.js +0 -0
  80. package/packages/agentsam-contracts/dist/repository.d.ts +56 -0
  81. package/packages/agentsam-contracts/dist/repository.js +15 -0
  82. package/packages/agentsam-contracts/dist/run.d.ts +113 -0
  83. package/packages/agentsam-contracts/dist/run.js +132 -0
  84. package/packages/agentsam-contracts/dist/tools.d.ts +82 -0
  85. package/packages/agentsam-contracts/dist/tools.js +0 -0
  86. package/packages/agentsam-contracts/dist/widgets.d.ts +38 -0
  87. package/packages/agentsam-contracts/dist/widgets.js +0 -0
  88. package/packages/agentsam-contracts/package.json +9 -1
  89. package/packages/agentsam-contracts/scripts/build.mjs +1 -1
  90. package/packages/agentsam-contracts/src/agent.ts +78 -3
  91. package/packages/agentsam-contracts/src/index.ts +2 -0
  92. package/packages/agentsam-contracts/src/run.ts +320 -0
  93. package/packages/agentsam-contracts/src/widgets.ts +58 -0
  94. package/packages/agentsam-contracts/test/contracts.test.mjs +1 -1
  95. package/packages/agentsam-contracts/test/run-contract.test.mjs +94 -0
  96. package/packages/agentsam-errors/package.json +1 -1
  97. package/packages/agentsam-goap/README.md +3 -0
  98. package/packages/agentsam-goap/package.json +2 -2
  99. package/packages/agentsam-hooks/package.json +2 -2
  100. package/packages/agentsam-hooks/src/adapters/agents.js +48 -22
  101. package/packages/agentsam-hooks/src/index.d.ts +16 -0
  102. package/packages/agentsam-knowledge/package.json +1 -1
  103. package/packages/agentsam-knowledge/src/backends/index.js +1 -1
  104. package/packages/agentsam-merch/README.md +62 -0
  105. package/packages/agentsam-merch/bin/agentsam-merch.mjs +16 -0
  106. package/packages/agentsam-merch/package.json +65 -0
  107. package/packages/agentsam-merch/profiles/completeful/dtg-back-large.json +42 -0
  108. package/packages/agentsam-merch/profiles/completeful/laser-engraving.json +39 -0
  109. package/packages/agentsam-merch/profiles/generic/embroidery-digitization.json +22 -0
  110. package/packages/agentsam-merch/schemas/collection-candidate.schema.json +66 -0
  111. package/packages/agentsam-merch/schemas/manufacturing-profile.schema.json +221 -0
  112. package/packages/agentsam-merch/src/adapters-completeful.js +50 -0
  113. package/packages/agentsam-merch/src/cli.js +93 -0
  114. package/packages/agentsam-merch/src/collection-lab.js +60 -0
  115. package/packages/agentsam-merch/src/compatibility.js +501 -0
  116. package/packages/agentsam-merch/src/derivatives.js +112 -0
  117. package/packages/agentsam-merch/src/index.d.ts +316 -0
  118. package/packages/agentsam-merch/src/index.js +46 -0
  119. package/packages/agentsam-merch/src/node/index.d.ts +58 -0
  120. package/packages/agentsam-merch/src/node/index.js +6 -0
  121. package/packages/agentsam-merch/src/node/raster.js +142 -0
  122. package/packages/agentsam-merch/src/node/vector.js +239 -0
  123. package/packages/agentsam-merch/src/product-concepts.js +118 -0
  124. package/packages/agentsam-merch/src/profile-registry.js +104 -0
  125. package/packages/agentsam-merch/src/profile.js +158 -0
  126. package/packages/agentsam-merch/src/transforms.js +215 -0
  127. package/packages/agentsam-merch/test/merch.test.mjs +332 -0
  128. package/packages/agentsam-merch/test/node-transforms.test.mjs +149 -0
  129. package/packages/agentsam-nav/dist/browser.global.js +71 -34
  130. package/packages/agentsam-nav/dist/browser.js +3179 -781
  131. package/packages/agentsam-nav/dist/index.js +3171 -773
  132. package/packages/agentsam-nav/package.json +1 -1
  133. package/packages/agentsam-queue-control/README.md +4 -1
  134. package/packages/agentsam-queue-control/package.json +4 -3
  135. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +111 -11
  136. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +34 -6
  137. package/packages/agentsam-queue-control/src/adapters/memory.js +11 -2
  138. package/packages/agentsam-queue-control/src/adapters/sqlite.js +259 -0
  139. package/packages/agentsam-queue-control/src/contracts.js +207 -3
  140. package/packages/agentsam-queue-control/src/control-plane.js +62 -2
  141. package/packages/agentsam-queue-control/src/index.js +1 -0
  142. package/packages/agentsam-queue-control/test/queue-control.test.mjs +310 -0
  143. package/packages/agentsam-queue-control/test/sqlite-adapter.test.mjs +91 -0
  144. package/packages/agentsam-rapid-rust/README.md +3 -0
  145. package/packages/agentsam-repository/README.md +3 -0
  146. package/packages/agentsam-repository/package.json +1 -1
  147. package/packages/agentsam-vault/package.json +1 -1
  148. package/packages/agentsam-workbench/README.md +43 -0
  149. package/packages/agentsam-workbench/package.json +13 -3
  150. package/packages/agentsam-workbench/src/agent/AgentConversationSurface.tsx +108 -0
  151. package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +25 -8
  152. package/packages/agentsam-workbench/src/agent/AgentRuntimeField.tsx +152 -0
  153. package/packages/agentsam-workbench/src/agent/Composer.tsx +10 -1
  154. package/packages/agentsam-workbench/src/agent/RunMode.ts +26 -0
  155. package/packages/agentsam-workbench/src/agent/Thread.tsx +18 -3
  156. package/packages/agentsam-workbench/src/agent/index.ts +3 -0
  157. package/packages/agentsam-workbench/src/index.ts +4 -0
  158. package/packages/agentsam-workbench/src/manufacturing/PreflightIndicator.tsx +203 -0
  159. package/packages/agentsam-workbench/src/manufacturing/index.ts +2 -0
  160. package/packages/agentsam-workbench/src/manufacturing/loading.ts +147 -0
  161. package/packages/agentsam-workbench/src/widgets/BuiltinWidget.tsx +22 -0
  162. package/packages/agentsam-workbench/src/widgets/CountdownWidget.tsx +68 -0
  163. package/packages/agentsam-workbench/src/widgets/WidgetFrame.tsx +56 -0
  164. package/packages/agentsam-workbench/src/widgets/countdown.ts +25 -0
  165. package/packages/agentsam-workbench/src/widgets/index.ts +6 -0
  166. package/packages/agentsam-workbench/src/widgets/registry.ts +13 -0
  167. package/packages/agentsam-workbench/src/widgets/useCountdown.ts +128 -0
  168. package/packages/agentsam-workbench/src/widgets/widgets.css +102 -0
  169. package/packages/connectors/{cloudflare → cfoa}/package.json +3 -3
  170. package/packages/heuristic-theme/package.json +1 -1
  171. package/packages/identity/README.md +3 -0
  172. package/packages/identity/backend/README.md +3 -0
  173. package/packages/identity/package.json +1 -1
  174. package/packages/identity/src/frontend/auth-portal/README.md +3 -0
  175. package/packages/identity/src/index.js +1 -1
  176. package/packages/identity/src/oauth/README.md +4 -1
  177. package/packages/identity/src/oauth/credentials.js +1 -1
  178. package/packages/identity/src/server/worker-router.js +1 -1
  179. package/packages/identity/tests/google-desktop-identity-login.test.mjs +1 -1
  180. package/packages/identity/tests/lane1-packed-consumer.test.mjs +1 -1
  181. package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +1 -1
  182. package/packages/providers/completeful/package.json +1 -1
  183. package/packages/theme-church-site/package.json +1 -1
  184. package/packages/theme-companions-site/package.json +1 -1
  185. package/packages/theme-floors-site/package.json +1 -1
  186. package/packages/theme-fuelnfree-site/package.json +1 -1
  187. package/packages/theme-handyman-site/package.json +1 -1
  188. package/packages/theme-insurance-site/package.json +1 -1
  189. package/packages/theme-scenes/package.json +1 -1
  190. package/packages/theme-shinshu-site/package.json +1 -1
  191. package/packages/work-graph/package.json +1 -1
  192. package/protocol/models/README.md +3 -0
  193. package/protocol/receipts/agentsam.receipt.v1.json +95 -0
  194. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +6 -6
  195. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +6 -6
  196. package/skills/README.md +3 -0
  197. package/src/acp/agent-executor.js +106 -0
  198. package/src/acp/client.js +316 -0
  199. package/src/acp/dependencies.js +426 -0
  200. package/src/acp/http.js +207 -0
  201. package/src/acp/index.js +22 -0
  202. package/src/acp/runs.js +125 -0
  203. package/src/acp/runtime-selection.js +180 -0
  204. package/src/cli/command-catalog.js +3 -0
  205. package/src/cli.js +24 -0
  206. package/src/commands/cloudflare-login.js +1 -1
  207. package/src/commands/cloudflare.js +2 -2
  208. package/src/commands/connections.js +1 -1
  209. package/src/commands/go.js +76 -6
  210. package/src/commands/merch.js +5 -0
  211. package/src/commands/mini.js +1 -1
  212. package/src/commands/receipts.js +140 -0
  213. package/src/commands/run.js +253 -0
  214. package/src/go/container.js +1 -1
  215. package/src/go/contract.js +61 -18
  216. package/src/go/discover.js +0 -4
  217. package/src/go/index.js +13 -1
  218. package/src/go/probe.js +109 -0
  219. package/src/go/{cloudflare.js → providers/cloudflare.js} +36 -136
  220. package/src/go/verify.js +1 -1
  221. package/src/indexing/ingest/inventory.js +1 -1
  222. package/src/lib/deploy/local-studio.js +2 -2
  223. package/src/lib/mini/scaffold.js +1 -1
  224. package/src/lib/whoami-capabilities.js +1 -1
  225. package/src/local/runtime-store.js +8 -0
  226. package/src/mcp/cloudflare-bundles.js +1 -1
  227. package/src/plugins/index.js +1 -0
  228. package/src/plugins/registry.js +59 -6
  229. package/src/receipts/contract.js +68 -0
  230. package/src/receipts/index.js +20 -0
  231. package/src/receipts/prune.js +64 -0
  232. package/src/receipts/sinks.js +285 -0
  233. package/templates/mini/gadget/app.js +15 -40
  234. package/templates/mini/gadget/index.html +7 -7
  235. package/templates/mini/shared/style.css +1 -1
  236. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
  237. /package/packages/connectors/{cloudflare → cfoa}/OAUTH_STORAGE_AUDIT.md +0 -0
  238. /package/packages/connectors/{cloudflare → cfoa}/src/api-client.js +0 -0
  239. /package/packages/connectors/{cloudflare → cfoa}/src/capabilities.js +0 -0
  240. /package/packages/connectors/{cloudflare → cfoa}/src/credential.js +0 -0
  241. /package/packages/connectors/{cloudflare → cfoa}/src/families/brand-protection.js +0 -0
  242. /package/packages/connectors/{cloudflare → cfoa}/src/families/keyless.js +0 -0
  243. /package/packages/connectors/{cloudflare → cfoa}/src/families/pages.js +0 -0
  244. /package/packages/connectors/{cloudflare → cfoa}/src/families/scanner.js +0 -0
  245. /package/packages/connectors/{cloudflare → cfoa}/src/families/snippets.js +0 -0
  246. /package/packages/connectors/{cloudflare → cfoa}/src/families/tag-gateway.js +0 -0
  247. /package/packages/connectors/{cloudflare → cfoa}/src/families/tags.js +0 -0
  248. /package/packages/connectors/{cloudflare → cfoa}/src/families/token-validation.js +0 -0
  249. /package/packages/connectors/{cloudflare → cfoa}/src/families/vectorize.js +0 -0
  250. /package/packages/connectors/{cloudflare → cfoa}/src/families/workflows.js +0 -0
  251. /package/packages/connectors/{cloudflare → cfoa}/src/index.js +0 -0
  252. /package/packages/connectors/{cloudflare → cfoa}/src/oauth-persist.js +0 -0
  253. /package/packages/connectors/{cloudflare → cfoa}/src/owner.js +0 -0
  254. /package/packages/connectors/{cloudflare → cfoa}/src/permission-options.js +0 -0
  255. /package/packages/connectors/{cloudflare → cfoa}/src/routes.js +0 -0
  256. /package/packages/connectors/{cloudflare → cfoa}/src/scope-catalog.js +0 -0
  257. /package/packages/connectors/{cloudflare → cfoa}/src/vault.js +0 -0
  258. /package/packages/connectors/{cloudflare → cfoa}/tests/capabilities.test.mjs +0 -0
  259. /package/packages/connectors/{cloudflare → cfoa}/tests/connector.test.mjs +0 -0
  260. /package/packages/connectors/{cloudflare → cfoa}/tests/oauth-persist.test.mjs +0 -0
  261. /package/packages/identity/src/oauth/{google-desktop-exchange.js → goaude.js} +0 -0
@@ -0,0 +1,106 @@
1
+ import { runWithSubagentHooks } from '../../packages/agentsam-hooks/src/adapters/agents.js';
2
+
3
+ function clean(value) {
4
+ return value == null ? '' : String(value).trim();
5
+ }
6
+
7
+ function object(value) {
8
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
9
+ }
10
+
11
+ /**
12
+ * Build the provider-neutral Queue Control handler for an `agent.run` job.
13
+ *
14
+ * ACP owns run/job identity and orchestration. The supplied `execute` function
15
+ * owns the actual model/runtime execution. AgentSam Hooks wrap the execution
16
+ * boundary for lifecycle policy/observability, but do not become run authority.
17
+ */
18
+ export function createAgentRunJobHandler({
19
+ execute,
20
+ hookRuntime = null,
21
+ cwd = process.cwd(),
22
+ source = 'agentsam-acp',
23
+ runtimeSelector = null,
24
+ } = {}) {
25
+ if (typeof execute !== 'function') throw new TypeError('agent_run_execute_required');
26
+
27
+ return async function handleAgentRun(job, context = {}) {
28
+ if (!job || job.kind !== 'agent.run') {
29
+ const error = new Error(`agent_run_job_required:${job?.kind || '<missing>'}`);
30
+ error.code = 'agent_run_job_required';
31
+ throw error;
32
+ }
33
+
34
+ const payload = object(job.payload);
35
+ const runId = clean(payload.run_id || job.source_run_id);
36
+ if (!runId) throw new TypeError('agent_run_id_required');
37
+
38
+ const parentRunId = clean(payload.parent_run_id);
39
+ const role = clean(payload.role) || 'agentsam-child';
40
+ const objective = clean(payload.objective) || `Run child AgentSam ${runId}`;
41
+ const runtimeRequirements = object(payload.runtime_requirements);
42
+ const executionContext = Object.freeze({
43
+ run_id: runId,
44
+ parent_run_id: parentRunId || null,
45
+ role,
46
+ objective,
47
+ work_item_id: clean(payload.work_item_id) || null,
48
+ step_id: clean(payload.step_id || job.step_id) || null,
49
+ runtime_requirements: runtimeRequirements,
50
+ job_id: clean(job.id) || null,
51
+ attempt: Number.isInteger(job.attempt) ? job.attempt : 0,
52
+ metadata: object(job.metadata),
53
+ });
54
+
55
+ const invocation = {
56
+ run_id: runId,
57
+ agent_id: role,
58
+ source: clean(context.source) || source,
59
+ metadata: {
60
+ parent_run_id: parentRunId || null,
61
+ job_id: clean(job.id) || null,
62
+ work_item_id: executionContext.work_item_id,
63
+ step_id: executionContext.step_id,
64
+ attempt: executionContext.attempt,
65
+ runtime_requirements: runtimeRequirements,
66
+ },
67
+ };
68
+
69
+ const selector = context.runtimeSelector || runtimeSelector;
70
+ const runtimeSelection = typeof selector === 'function'
71
+ ? await selector(runtimeRequirements, {
72
+ ...context,
73
+ account_id: job.account_id,
74
+ run_id: runId,
75
+ parent_run_id: parentRunId || null,
76
+ job_id: job.id,
77
+ })
78
+ : null;
79
+
80
+ const executeRun = () => execute({
81
+ job,
82
+ runId,
83
+ parentRunId: parentRunId || null,
84
+ role,
85
+ objective,
86
+ runtimeRequirements,
87
+ runtimeSelection,
88
+ executionContext,
89
+ invocation,
90
+ }, context);
91
+
92
+ // Only child AgentSam runs are subagents. Root agent.run jobs retain the
93
+ // normal session/model/tool hook lifecycle owned by the execution host.
94
+ if (!parentRunId) return executeRun();
95
+
96
+ return runWithSubagentHooks({
97
+ hookRuntime: context.hookRuntime || hookRuntime,
98
+ agentId: role,
99
+ task: objective,
100
+ context: executionContext,
101
+ invocation,
102
+ cwd: context.cwd || cwd,
103
+ run: executeRun,
104
+ });
105
+ };
106
+ }
@@ -0,0 +1,316 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { createLocalSqliteDatabase } from '../local/sqlite.js';
3
+ import { applyRuntimeMigrations } from '../local/migrations.js';
4
+ import { runtimeDatabasePath } from '../local/runtime-store.js';
5
+ import { spawnChildRun } from './dependencies.js';
6
+ import { createRootRun } from './runs.js';
7
+
8
+ function clean(value) { return value == null ? '' : String(value).trim(); }
9
+ function parseJson(value, fallback = null) {
10
+ if (value == null || value === '') return fallback;
11
+ try { return JSON.parse(value); } catch { return fallback; }
12
+ }
13
+ function isTerminal(status) {
14
+ return ['completed', 'failed', 'cancelled', 'timed_out'].includes(status);
15
+ }
16
+
17
+ const RUN_JOIN = `
18
+ SELECT r.*,
19
+ s.state AS suspension_state, s.reason AS suspension_reason,
20
+ s.wake_at_unix, s.wake_event, s.dependency_run_ids_json,
21
+ s.resume_step_id, s.checkpoint_ref, s.expires_at_unix,
22
+ s.attempt AS suspension_attempt, s.metadata_json AS suspension_metadata_json
23
+ FROM agentsam_agent_run r
24
+ LEFT JOIN agentsam_agent_run_suspension s ON s.run_id = r.id
25
+ `;
26
+
27
+ function mapSuspension(row) {
28
+ if (!row?.suspension_state) return null;
29
+ return {
30
+ runId: row.id, state: row.suspension_state, reason: row.suspension_reason,
31
+ wakeAt: row.wake_at_unix ?? undefined, wakeEvent: row.wake_event ?? undefined,
32
+ dependencyRunIds: parseJson(row.dependency_run_ids_json, []),
33
+ resumeStepId: row.resume_step_id ?? undefined,
34
+ checkpointRef: row.checkpoint_ref ?? undefined,
35
+ expiresAt: row.expires_at_unix ?? undefined,
36
+ attempt: Number(row.suspension_attempt || 0),
37
+ metadata: parseJson(row.suspension_metadata_json, {}),
38
+ };
39
+ }
40
+
41
+ function mapRun(row) {
42
+ if (!row) return null;
43
+ const suspension = mapSuspension(row);
44
+ return {
45
+ schema: 'agentsam.run.v1', id: row.id, accountId: row.account_id ?? undefined,
46
+ conversationId: row.conversation_id ?? undefined, parentRunId: row.parent_run_id ?? undefined,
47
+ externalAgentId: row.external_agent_id ?? undefined, externalRunId: row.external_run_id ?? undefined,
48
+ sourceClient: row.source_client ?? undefined, surface: row.surface ?? undefined, mode: row.mode ?? undefined,
49
+ modelKey: row.model_key ?? undefined, reasoningEffort: row.reasoning_effort ?? undefined,
50
+ requestedServiceTier: row.requested_service_tier ?? undefined, actualServiceTier: row.actual_service_tier ?? undefined,
51
+ selectedBy: row.selected_by ?? undefined, status: suspension?.state || row.status, storageStatus: row.status,
52
+ cancelRequested: Boolean(row.cancel_requested), errorCode: row.error_code ?? undefined, errorMessage: row.error_message ?? undefined,
53
+ modelCallCount: Number(row.model_call_count || 0), toolCallCount: Number(row.tool_call_count || 0),
54
+ inputTokens: Number(row.input_tokens || 0), cachedInputTokens: Number(row.cached_input_tokens || 0),
55
+ outputTokens: Number(row.output_tokens || 0), reasoningTokens: Number(row.reasoning_tokens || 0),
56
+ costUsd: Number(row.cost_usd || 0), planId: row.plan_id ?? undefined, todoId: row.todo_id ?? undefined,
57
+ createdAt: row.created_at_unix == null ? undefined : Number(row.created_at_unix) * 1000,
58
+ startedAt: row.started_at_unix == null ? undefined : Number(row.started_at_unix) * 1000,
59
+ completedAt: row.completed_at_unix == null ? undefined : Number(row.completed_at_unix) * 1000,
60
+ updatedAt: row.updated_at_unix == null ? undefined : Number(row.updated_at_unix) * 1000,
61
+ latencyMs: row.latency_ms == null ? undefined : Number(row.latency_ms), suspension,
62
+ };
63
+ }
64
+
65
+ function mapEvent(row) {
66
+ if (!row) return null;
67
+ const progress = row.progress_current == null && row.progress_total == null ? null : {
68
+ current: Number(row.progress_current || 0), total: Number(row.progress_total || 0),
69
+ };
70
+ return {
71
+ id: row.event_id, runId: row.run_id, parentRunId: row.parent_run_id ?? undefined, seq: Number(row.seq),
72
+ eventType: row.event_type, phase: row.phase ?? undefined, stepId: row.step_id ?? undefined,
73
+ label: row.label || '', detail: row.detail ?? null, progress,
74
+ source: row.source_kind || row.source_name ? { kind: row.source_kind || 'sam', name: row.source_name ?? null } : null,
75
+ evidence: parseJson(row.evidence_json, {}), createdAt: Number(row.created_at_unix) * 1000,
76
+ };
77
+ }
78
+
79
+ async function withLocalDb(cwd, fn) {
80
+ const db = await createLocalSqliteDatabase(runtimeDatabasePath(cwd));
81
+ try { await applyRuntimeMigrations(db); return await fn(db); } finally { db.close(); }
82
+ }
83
+
84
+ export class DatabaseAgentControlClient {
85
+ constructor({ database, kind = 'database' } = {}) {
86
+ if (!database || typeof database.prepare !== 'function') {
87
+ throw new TypeError('database with prepare() is required');
88
+ }
89
+ this.database = database;
90
+ this.kind = clean(kind) || 'database';
91
+ }
92
+
93
+ async getRun(id) {
94
+ return mapRun(await this.database.prepare(RUN_JOIN + ' WHERE r.id = ? LIMIT 1').bind(id).first());
95
+ }
96
+
97
+ async start(input = {}) {
98
+ return createRootRun(this.database, {
99
+ runId: input.run_id ?? input.runId ?? null,
100
+ accountId: input.account_id ?? input.accountId ?? null,
101
+ conversationId: input.conversation_id ?? input.conversationId ?? null,
102
+ objective: input.objective ?? '',
103
+ role: input.role ?? 'lead',
104
+ mode: input.mode ?? 'agent',
105
+ modelKey: input.model_key ?? input.modelKey ?? null,
106
+ reasoningEffort: input.reasoning_effort ?? input.reasoningEffort ?? null,
107
+ serviceTier: input.service_tier ?? input.serviceTier ?? null,
108
+ runtimeRequirements: input.runtime_requirements ?? input.runtimeRequirements ?? {},
109
+ metadata: input.metadata ?? {},
110
+ priority: input.priority ?? 'normal',
111
+ sourceClient: input.source_client ?? input.sourceClient ?? 'agentsam-acp',
112
+ surface: input.surface ?? 'control-plane',
113
+ });
114
+ }
115
+
116
+ async events(id, { after = -1, limit = 200 } = {}) {
117
+ const result = await this.database.prepare(`
118
+ SELECT * FROM agentsam_agent_run_event
119
+ WHERE run_id = ? AND seq > ?
120
+ ORDER BY seq ASC LIMIT ?
121
+ `).bind(id, Math.max(-1, Number(after)), Math.max(1, Math.min(1000, Number(limit)))).all();
122
+ return (result.results || []).map(mapEvent);
123
+ }
124
+
125
+ async tree(id) {
126
+ const result = await this.database.prepare(`
127
+ WITH RECURSIVE descendants(id, depth, path) AS (
128
+ SELECT id, 0, ',' || id || ',' FROM agentsam_agent_run WHERE id = ?
129
+ UNION ALL
130
+ SELECT child.id, descendants.depth + 1, descendants.path || child.id || ','
131
+ FROM agentsam_agent_run child
132
+ JOIN descendants ON child.parent_run_id = descendants.id
133
+ WHERE descendants.depth < 64
134
+ AND instr(descendants.path, ',' || child.id || ',') = 0
135
+ )
136
+ SELECT r.*, descendants.depth,
137
+ s.state AS suspension_state, s.reason AS suspension_reason,
138
+ s.wake_at_unix, s.wake_event, s.dependency_run_ids_json,
139
+ s.resume_step_id, s.checkpoint_ref, s.expires_at_unix,
140
+ s.attempt AS suspension_attempt, s.metadata_json AS suspension_metadata_json
141
+ FROM descendants
142
+ JOIN agentsam_agent_run r ON r.id = descendants.id
143
+ LEFT JOIN agentsam_agent_run_suspension s ON s.run_id = r.id
144
+ ORDER BY descendants.depth, r.created_at_unix, r.id
145
+ `).bind(id).all();
146
+ const rows = result.results || [];
147
+ if (!rows.length) return null;
148
+ const byId = new Map(rows.map((row) => [
149
+ row.id,
150
+ { ...mapRun(row), depth: Number(row.depth || 0), children: [] },
151
+ ]));
152
+ for (const node of byId.values()) {
153
+ if (node.parentRunId && byId.has(node.parentRunId)) {
154
+ byId.get(node.parentRunId).children.push(node);
155
+ }
156
+ }
157
+ return byId.get(id) || null;
158
+ }
159
+
160
+ async spawn(id, input = {}) {
161
+ return spawnChildRun(this.database, {
162
+ parentRunId: id,
163
+ childRunId: input.child_run_id ?? input.childRunId ?? null,
164
+ accountId: input.account_id ?? input.accountId ?? null,
165
+ objective: input.objective ?? '',
166
+ role: input.role ?? input.role_slug ?? null,
167
+ workItemId: input.work_item_id ?? input.workItemId ?? null,
168
+ stepId: input.step_id ?? input.stepId ?? null,
169
+ modelKey: input.model_key ?? input.modelKey ?? null,
170
+ reasoningEffort: input.reasoning_effort ?? input.reasoningEffort ?? null,
171
+ serviceTier: input.service_tier ?? input.serviceTier ?? null,
172
+ runtimeRequirements: input.runtime_requirements ?? input.runtimeRequirements ?? {},
173
+ metadata: input.metadata ?? {},
174
+ priority: input.priority ?? 'normal',
175
+ });
176
+ }
177
+
178
+ async cancel(id) {
179
+ const row = await this.database.prepare(RUN_JOIN + ' WHERE r.id = ? LIMIT 1').bind(id).first();
180
+ if (!row) return null;
181
+ const run = mapRun(row);
182
+ if (isTerminal(run.status)) return { ...run, cancelAccepted: false };
183
+
184
+ await this.database.prepare(
185
+ 'UPDATE agentsam_agent_run SET cancel_requested=1, updated_at_unix=unixepoch() WHERE id=?'
186
+ ).bind(id).run();
187
+ const seqRow = await this.database.prepare(
188
+ 'SELECT COALESCE(MAX(seq), -1) + 1 AS next_seq FROM agentsam_agent_run_event WHERE run_id=?'
189
+ ).bind(id).first();
190
+ await this.database.prepare(`
191
+ INSERT OR IGNORE INTO agentsam_agent_run_event (
192
+ event_id, run_id, parent_run_id, seq, event_type, phase, label,
193
+ source_kind, evidence_json, dedupe_key
194
+ ) VALUES (?, ?, ?, ?, 'run.cancel_requested', 'recover', ?, 'sam', ?, ?)
195
+ `).bind(
196
+ `evt_${randomUUID()}`,
197
+ id,
198
+ row.parent_run_id || null,
199
+ Number(seqRow?.next_seq || 0),
200
+ 'Cancellation requested',
201
+ JSON.stringify({ requested_by: 'user' }),
202
+ `cancel:${id}`,
203
+ ).run();
204
+
205
+ return { ...(await this.getRun(id)), cancelAccepted: true };
206
+ }
207
+
208
+ async receipt(id) {
209
+ const run = await this.getRun(id);
210
+ if (!run) return null;
211
+ const [events, tree] = await Promise.all([
212
+ this.events(id, { limit: 1000 }),
213
+ this.tree(id),
214
+ ]);
215
+ const lastEvent = events.length ? events[events.length - 1] : null;
216
+ return {
217
+ schema: 'agentsam.run-receipt.v1',
218
+ runId: id,
219
+ status: run.status,
220
+ terminal: isTerminal(run.status),
221
+ parentRunId: run.parentRunId ?? null,
222
+ planId: run.planId ?? null,
223
+ todoId: run.todoId ?? null,
224
+ usage: {
225
+ modelCalls: run.modelCallCount,
226
+ toolCalls: run.toolCallCount,
227
+ inputTokens: run.inputTokens,
228
+ cachedInputTokens: run.cachedInputTokens,
229
+ outputTokens: run.outputTokens,
230
+ reasoningTokens: run.reasoningTokens,
231
+ costUsd: run.costUsd,
232
+ },
233
+ timing: {
234
+ createdAt: run.createdAt ?? null,
235
+ startedAt: run.startedAt ?? null,
236
+ completedAt: run.completedAt ?? null,
237
+ latencyMs: run.latencyMs ?? null,
238
+ },
239
+ error: run.errorCode || run.errorMessage
240
+ ? { code: run.errorCode ?? null, message: run.errorMessage ?? null }
241
+ : null,
242
+ suspension: run.suspension,
243
+ eventCount: events.length,
244
+ childRunCount: tree?.children?.length || 0,
245
+ lastEvent,
246
+ };
247
+ }
248
+ }
249
+
250
+ export class LocalAgentControlClient {
251
+ constructor({ cwd = process.cwd() } = {}) {
252
+ this.cwd = cwd;
253
+ this.kind = 'local';
254
+ }
255
+
256
+ async #withClient(fn) {
257
+ return withLocalDb(this.cwd, (database) =>
258
+ fn(new DatabaseAgentControlClient({ database, kind: this.kind })));
259
+ }
260
+
261
+ getRun(id) { return this.#withClient((client) => client.getRun(id)); }
262
+ start(input = {}) { return this.#withClient((client) => client.start(input)); }
263
+ events(id, options = {}) { return this.#withClient((client) => client.events(id, options)); }
264
+ tree(id) { return this.#withClient((client) => client.tree(id)); }
265
+ spawn(id, input = {}) { return this.#withClient((client) => client.spawn(id, input)); }
266
+ cancel(id) { return this.#withClient((client) => client.cancel(id)); }
267
+ receipt(id) { return this.#withClient((client) => client.receipt(id)); }
268
+ }
269
+
270
+ export class HttpAgentControlClient {
271
+ constructor({ baseUrl, token = '', fetchImpl = globalThis.fetch } = {}) {
272
+ this.baseUrl = clean(baseUrl).replace(/\/+$/, '');
273
+ if (!this.baseUrl) throw new TypeError('Agent Control Plane base URL is required');
274
+ if (typeof fetchImpl !== 'function') throw new TypeError('fetch implementation is required');
275
+ this.token = clean(token); this.fetchImpl = fetchImpl; this.kind = 'http';
276
+ }
277
+ async request(path, init = {}) {
278
+ const headers = new Headers(init.headers || {});
279
+ headers.set('accept', 'application/json');
280
+ if (init.body != null) headers.set('content-type', 'application/json');
281
+ if (this.token) headers.set('authorization', `Bearer ${this.token}`);
282
+ const response = await this.fetchImpl(this.baseUrl + path, { ...init, headers });
283
+ const text = await response.text();
284
+ const body = text ? JSON.parse(text) : null;
285
+ if (!response.ok) {
286
+ const error = new Error(body?.error?.message || body?.message || `acp_http_${response.status}`);
287
+ error.code = body?.error?.code || `acp_http_${response.status}`; error.status = response.status; throw error;
288
+ }
289
+ return body;
290
+ }
291
+ start(input = {}) {
292
+ return this.request('/v1/runs', { method: 'POST', body: JSON.stringify(input) });
293
+ }
294
+ getRun(id) { return this.request(`/v1/runs/${encodeURIComponent(id)}`); }
295
+ events(id, { after = -1, limit = 200 } = {}) {
296
+ return this.request(`/v1/runs/${encodeURIComponent(id)}/events?after=${encodeURIComponent(after)}&limit=${encodeURIComponent(limit)}`);
297
+ }
298
+ tree(id) { return this.request(`/v1/runs/${encodeURIComponent(id)}/tree`); }
299
+ spawn(id, input = {}) {
300
+ return this.request(`/v1/runs/${encodeURIComponent(id)}/spawn`, { method: 'POST', body: JSON.stringify(input) });
301
+ }
302
+ cancel(id) { return this.request(`/v1/runs/${encodeURIComponent(id)}/cancel`, { method: 'POST', body: '{}' }); }
303
+ receipt(id) { return this.request(`/v1/runs/${encodeURIComponent(id)}/receipt`); }
304
+ }
305
+
306
+ export function createAgentControlClient({
307
+ cwd = process.cwd(),
308
+ url = process.env.AGENTSAM_CONTROL_PLANE_URL || '',
309
+ token = process.env.AGENTSAM_CONTROL_PLANE_TOKEN || '',
310
+ local = false,
311
+ fetchImpl = globalThis.fetch,
312
+ } = {}) {
313
+ return clean(url) && !local
314
+ ? new HttpAgentControlClient({ baseUrl: url, token, fetchImpl })
315
+ : new LocalAgentControlClient({ cwd });
316
+ }