@fungi.computer/truffle 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +282 -34
  2. package/dist/auth-cli.d.ts +10 -0
  3. package/dist/auth-cli.js +36 -14
  4. package/dist/fungi-account-command.d.ts +1 -1
  5. package/dist/fungi-account-command.js +6 -3
  6. package/dist/index.d.ts +10 -2
  7. package/dist/index.js +8 -2
  8. package/dist/internal/image-fit-metafile.json +106 -0
  9. package/dist/internal/local-image-fit-worker.mjs +960 -0
  10. package/dist/internal/private-workerd-sandbox-worker.mjs +11 -12
  11. package/dist/internal/sandbox-metafile.json +7 -7
  12. package/dist/local-archive-handoff.d.ts +12 -0
  13. package/dist/local-archive-handoff.js +21 -0
  14. package/dist/local-extensions.d.ts +58 -12
  15. package/dist/local-extensions.js +195 -55
  16. package/dist/local-image-fit.d.ts +30 -0
  17. package/dist/local-image-fit.js +105 -0
  18. package/dist/local-models.d.ts +4 -2
  19. package/dist/local-models.js +11 -6
  20. package/dist/local-session-archives.d.ts +8 -0
  21. package/dist/local-session-archives.js +152 -0
  22. package/dist/local-skill-source.d.ts +18 -3
  23. package/dist/local-skill-source.js +216 -140
  24. package/dist/log-event.d.ts +7 -0
  25. package/dist/log-event.js +8 -4
  26. package/dist/private-bounded-response.d.ts +2 -0
  27. package/dist/private-bounded-response.js +41 -0
  28. package/dist/private-file-credential-store.d.ts +28 -3
  29. package/dist/private-file-credential-store.js +57 -9
  30. package/dist/private-files-patch.d.ts +2 -1
  31. package/dist/private-files-patch.js +21 -3
  32. package/dist/private-fungi-account.d.ts +40 -23
  33. package/dist/private-fungi-account.js +201 -21
  34. package/dist/private-fungi-mcp-connection.d.ts +4 -0
  35. package/dist/private-fungi-mcp-connection.js +25 -6
  36. package/dist/private-fungi-mcp-selection-schema.d.ts +7 -0
  37. package/dist/private-fungi-mcp-selection-schema.js +15 -0
  38. package/dist/private-fungi-mcp-selection.d.ts +6 -6
  39. package/dist/private-fungi-mcp-selection.js +29 -16
  40. package/dist/private-fungi-model-api.js +4 -4
  41. package/dist/private-fungi-model-catalog.d.ts +10 -0
  42. package/dist/private-fungi-model-catalog.js +10 -2
  43. package/dist/private-fungi-model-provider.d.ts +1 -1
  44. package/dist/private-fungi-model-provider.js +6 -1
  45. package/dist/private-fungi-pending-logouts.d.ts +1 -1
  46. package/dist/private-fungi-pending-logouts.js +1 -2
  47. package/dist/private-fungi-service-logout.d.ts +44 -0
  48. package/dist/private-fungi-service-logout.js +59 -0
  49. package/dist/private-invocation-computer.d.ts +24 -3
  50. package/dist/private-invocation-computer.js +101 -62
  51. package/dist/private-invocation-files.d.ts +16 -1
  52. package/dist/private-invocation-files.js +154 -83
  53. package/dist/private-local-acp-stdio.js +3 -0
  54. package/dist/private-local-admission-gate.d.ts +14 -0
  55. package/dist/private-local-admission-gate.js +52 -0
  56. package/dist/private-local-agent-control.d.ts +101 -0
  57. package/dist/private-local-agent-control.js +30 -0
  58. package/dist/private-local-agent-default-model.d.ts +12 -0
  59. package/dist/private-local-agent-default-model.js +31 -0
  60. package/dist/private-local-auth-rpc.d.ts +67 -7
  61. package/dist/private-local-auth-rpc.js +140 -17
  62. package/dist/private-local-bwrap.d.ts +13 -0
  63. package/dist/private-local-bwrap.js +70 -0
  64. package/dist/private-local-client-version.d.ts +5 -0
  65. package/dist/private-local-client-version.js +43 -0
  66. package/dist/private-local-computer-attach.d.ts +3 -3
  67. package/dist/private-local-computer-attach.js +17 -3
  68. package/dist/private-local-computer-processes.d.ts +6 -3
  69. package/dist/private-local-computer-processes.js +55 -31
  70. package/dist/private-local-config-root.d.ts +21 -0
  71. package/dist/private-local-config-root.js +19 -0
  72. package/dist/private-local-containment.d.ts +51 -0
  73. package/dist/private-local-containment.js +161 -0
  74. package/dist/private-local-delegation.d.ts +10 -3
  75. package/dist/private-local-delegation.js +70 -15
  76. package/dist/private-local-effective-model.d.ts +9 -1
  77. package/dist/private-local-effective-model.js +3 -0
  78. package/dist/private-local-exec-environment.d.ts +16 -0
  79. package/dist/private-local-exec-environment.js +11 -0
  80. package/dist/private-local-linux-sandbox.d.ts +8 -0
  81. package/dist/private-local-linux-sandbox.js +67 -0
  82. package/dist/private-local-mail.d.ts +4 -2
  83. package/dist/private-local-mail.js +41 -33
  84. package/dist/private-local-mesh-enrollment.d.ts +34 -0
  85. package/dist/private-local-mesh-enrollment.js +188 -0
  86. package/dist/private-local-mesh-links.d.ts +21 -0
  87. package/dist/private-local-mesh-links.js +229 -0
  88. package/dist/private-local-mesh-record.d.ts +120 -0
  89. package/dist/private-local-mesh-record.js +55 -0
  90. package/dist/private-local-process-identity.d.ts +20 -0
  91. package/dist/private-local-process-identity.js +40 -0
  92. package/dist/private-local-runtime-host.d.ts +64 -13
  93. package/dist/private-local-runtime-host.js +361 -172
  94. package/dist/private-local-sandbox-policy.d.ts +21 -0
  95. package/dist/private-local-sandbox-policy.js +121 -0
  96. package/dist/private-local-sandbox.d.ts +37 -0
  97. package/dist/private-local-sandbox.js +114 -0
  98. package/dist/private-local-seatbelt.d.ts +24 -0
  99. package/dist/private-local-seatbelt.js +68 -0
  100. package/dist/private-local-service-contract.d.ts +91 -11
  101. package/dist/private-local-service-discovery.d.ts +129 -13
  102. package/dist/private-local-service-discovery.js +148 -47
  103. package/dist/private-local-service-lease.d.ts +16 -0
  104. package/dist/private-local-service-lease.js +105 -0
  105. package/dist/private-local-service-listener.d.ts +9 -2
  106. package/dist/private-local-service-listener.js +260 -64
  107. package/dist/private-local-service-log.d.ts +128 -0
  108. package/dist/private-local-service-log.js +321 -0
  109. package/dist/private-local-service-owner.d.ts +87 -1519
  110. package/dist/private-local-service-owner.js +1069 -71
  111. package/dist/private-local-service-process.js +3 -1
  112. package/dist/private-local-service-termination.d.ts +7 -0
  113. package/dist/private-local-service-termination.js +67 -0
  114. package/dist/private-local-service.d.ts +31 -2
  115. package/dist/private-local-service.js +402 -126
  116. package/dist/private-local-session-discovery.d.ts +52 -5
  117. package/dist/private-local-session-discovery.js +132 -11
  118. package/dist/private-local-shiitake-host.js +2 -2
  119. package/dist/private-local-startup-model.d.ts +51 -0
  120. package/dist/private-local-startup-model.js +86 -0
  121. package/dist/private-local-stop-all.d.ts +27 -0
  122. package/dist/private-local-stop-all.js +26 -0
  123. package/dist/private-local-ui-attachment.d.ts +19 -0
  124. package/dist/private-local-ui-attachment.js +71 -0
  125. package/dist/private-local-worker-server.d.ts +1 -0
  126. package/dist/private-local-worker-server.js +13 -5
  127. package/dist/private-mcp-form-contract.d.ts +186 -0
  128. package/dist/private-mcp-form-contract.js +53 -0
  129. package/dist/private-mcp-form-elicitation.d.ts +18 -0
  130. package/dist/private-mcp-form-elicitation.js +97 -0
  131. package/dist/private-mcp-form-session.d.ts +172 -0
  132. package/dist/private-mcp-form-session.js +148 -0
  133. package/dist/private-openai-claims.d.ts +30 -0
  134. package/dist/private-openai-claims.js +69 -0
  135. package/dist/private-oyster-mcp-auth.d.ts +13 -0
  136. package/dist/private-oyster-mcp-auth.js +57 -0
  137. package/dist/private-provider-rejection.d.ts +15 -0
  138. package/dist/private-provider-rejection.js +24 -0
  139. package/dist/private-sqlite-owner.d.ts +34 -2
  140. package/dist/private-sqlite-owner.js +103 -37
  141. package/dist/private-team-computers.d.ts +4 -4
  142. package/dist/private-team-computers.js +11 -2
  143. package/dist/seatbelt/safe-base.sbpl +79 -0
  144. package/dist/subscription-activation.d.ts +9 -0
  145. package/dist/subscription-activation.js +62 -0
  146. package/dist/subscription-identity.d.ts +23 -0
  147. package/dist/subscription-identity.js +124 -0
  148. package/dist/subscription-turn.d.ts +17 -0
  149. package/dist/subscription-turn.js +143 -0
  150. package/dist/team-apps.d.ts +2 -2
  151. package/dist/team-apps.js +7 -2
  152. package/native/bin/LICENSE.bubblewrap +502 -0
  153. package/native/bin/LICENSE.libcap +112 -0
  154. package/native/bin/LICENSE.sandbox-runtime +201 -0
  155. package/native/bin/SOURCE.bubblewrap.tar.xz +0 -0
  156. package/native/bin/bwrap-build-source/Dockerfile +48 -0
  157. package/native/bin/bwrap-build-source/README.md +96 -0
  158. package/native/bin/bwrap-build-source/build.mjs +52 -0
  159. package/native/bin/bwrap-build-source/linux-arm64.ini +14 -0
  160. package/native/bin/bwrap-build-source/pin.mjs +21 -0
  161. package/native/bin/bwrap-build-source/record.mjs +74 -0
  162. package/native/bin/bwrap-build-source/vendor/LICENSE.sandbox-runtime +201 -0
  163. package/native/bin/bwrap-build-source/vendor/README.md +23 -0
  164. package/native/bin/bwrap-build-source/vendor/seccomp-unix-block.c +280 -0
  165. package/native/bin/bwrap-build.json +44 -0
  166. package/native/bin/fungi-bwrap +0 -0
  167. package/native/bin/fungi-bwrap.sha256 +1 -0
  168. package/native/bin/fungi-seccomp.bpf +0 -0
  169. package/native/bin/fungi-seccomp.bpf.sha256 +1 -0
  170. package/package.json +44 -31
  171. package/dist/private-local-model-settings.d.ts +0 -5
  172. package/dist/private-local-model-settings.js +0 -31
  173. package/dist/private-local-subagents.d.ts +0 -27
  174. package/dist/private-local-subagents.js +0 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/truffle",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "description": "Truffle: Fungi's local Agent runtime, bundled into the fungi command",
6
6
  "type": "module",
@@ -58,49 +58,55 @@
58
58
  ],
59
59
  "dependencies": {
60
60
  "@agentclientprotocol/sdk": "1.7.0",
61
- "@earendil-works/pi-ai": "0.99.2",
61
+ "@cf-wasm/photon": "0.4.0",
62
+ "@earendil-works/pi-ai": "1.3.0",
62
63
  "@effect/platform-node": "4.0.2",
63
- "@fungi.computer/graft": "0.0.1",
64
- "@fungi.computer/agar": "0.2.0",
65
- "@fungi.computer/bird-dog": "0.0.1",
66
- "@fungi.computer/cairn": "0.0.1",
67
- "@fungi.computer/cordyceps": "0.2.2",
68
- "@fungi.computer/knapsack": "0.1.0",
69
- "@fungi.computer/mycelium": "0.1.0",
70
- "@fungi.computer/shiitake": "0.2.0",
71
- "@fungi.computer/shiitake-extensions": "0.0.2",
72
- "@fungi.computer/veil": "0.1.0",
73
- "@fungi.computer/whistle": "0.0.2",
74
- "@modelcontextprotocol/client": "2.0.0",
64
+ "@fungi.computer/agar": "0.3.0",
65
+ "@fungi.computer/approvals": "0.0.2",
66
+ "@fungi.computer/bird-dog": "0.1.0",
67
+ "@fungi.computer/cairn": "0.1.0",
75
68
  "@fungi.computer/capnweb": "0.12.0",
69
+ "@fungi.computer/carrier": "0.1.0",
70
+ "@fungi.computer/cordyceps": "0.3.1",
71
+ "@fungi.computer/gills": "0.2.0",
72
+ "@fungi.computer/graft": "0.1.0",
73
+ "@fungi.computer/knapsack": "0.2.0",
74
+ "@fungi.computer/lantern": "0.3.0",
75
+ "@fungi.computer/mycelium": "0.2.0",
76
+ "@fungi.computer/nacre": "0.0.1",
77
+ "@fungi.computer/seam": "0.1.0",
78
+ "@fungi.computer/shiitake": "0.3.0",
79
+ "@fungi.computer/shiitake-extensions": "0.1.0",
80
+ "@fungi.computer/veil": "0.2.0",
81
+ "@fungi.computer/watchdog": "0.1.0",
82
+ "@fungi.computer/whistle": "0.1.0",
83
+ "@fungi.computer/zookeeper": "0.0.1",
84
+ "@modelcontextprotocol/client": "2.0.0",
76
85
  "diff": "8.0.4",
77
86
  "effect": "4.0.2",
78
87
  "eventsource": "5.1.1",
79
88
  "hono": "4.13.5",
89
+ "image-size": "2.0.4",
90
+ "jose": "6.2.11",
80
91
  "miniflare": "5.20260828.0-alpha",
81
92
  "proper-lockfile": "4.1.2",
82
93
  "re2js": "1.3.3",
83
94
  "write-file-atomic": "8.0.0",
84
95
  "yaml": "2.9.0",
85
- "zod": "4.4.3",
86
- "@fungi.computer/lantern": "0.2.0",
87
- "jose": "6.2.11",
88
- "@fungi.computer/oyster": "0.2.0",
89
- "@fungi.computer/seam": "0.0.1",
90
- "@fungi.computer/gills": "0.1.0"
96
+ "zod": "4.4.3"
91
97
  },
92
98
  "devDependencies": {
93
99
  "@cloudflare/codemode": "0.5.1",
100
+ "@fungi.computer/mule": "0.1.0",
94
101
  "@modelcontextprotocol/server": "2.0.0",
95
102
  "@types/node": "24.13.3",
96
- "bun-types": "1.4.1",
97
103
  "@types/proper-lockfile": "4.1.4",
98
104
  "@types/write-file-atomic": "4.0.3",
105
+ "bun": "1.4.2",
106
+ "bun-types": "1.4.1",
99
107
  "esbuild": "0.28.2",
100
108
  "typescript": "5.9.3",
101
- "vitest": "4.1.11",
102
- "bun": "1.4.2",
103
- "@fungi.computer/mule": "0.0.2"
109
+ "vitest": "4.1.11"
104
110
  },
105
111
  "botanical": {
106
112
  "role": "runtime",
@@ -134,18 +140,25 @@
134
140
  "scripts": {
135
141
  "lint": "../../node_modules/.bin/eslint src scripts test --max-warnings=0 && ../../node_modules/.bin/oxlint --config ../../oxlint.config.ts --deny-warnings src scripts test",
136
142
  "typecheck": "tsc -p tsconfig.json --noEmit",
137
- "build": "pnpm run clean && tsc -p tsconfig.build.json && esbuild src/internal/private-workerd-sandbox-worker.mjs --outfile=dist/internal/private-workerd-sandbox-worker.mjs --bundle --format=esm --platform=neutral --conditions=workerd,browser --target=es2024 --external:cloudflare:workers --metafile=dist/internal/sandbox-metafile.json --log-level=warning",
143
+ "build": "pnpm run clean && tsc -p tsconfig.build.json && node scripts/copy-seatbelt.mjs && esbuild src/internal/private-workerd-sandbox-worker.mjs --outfile=dist/internal/private-workerd-sandbox-worker.mjs --bundle --format=esm --platform=neutral --conditions=workerd,browser --target=es2024 --external:cloudflare:workers --metafile=dist/internal/sandbox-metafile.json --log-level=warning && esbuild src/internal/local-image-fit-worker.mjs --outfile=dist/internal/local-image-fit-worker.mjs --bundle --format=esm --platform=node --target=es2024 --metafile=dist/internal/image-fit-metafile.json --log-level=warning",
138
144
  "clean": "node --input-type=module --eval \"import { rm } from 'node:fs/promises'; await rm('dist', { recursive: true, force: true });\"",
139
- "test": "pnpm run test:node && pnpm run test:patch",
145
+ "test": "pnpm run test:node && pnpm run test:merge && pnpm run test:stop-all",
146
+ "test:stop-all": "bun test ./test/private-local-stop-all.bun.test.ts",
140
147
  "test:full": "pnpm run test && pnpm run test:bun",
141
148
  "test:node": "../../node_modules/.bin/vitest run",
142
- "test:bun": "bun test ./test/private-local-service-discovery.bun.test.ts ./test/private-local-service-listener.bun.test.ts ./test/private-local-service-manager.bun.test.ts ./test/private-local-auth-rpc.bun.test.ts ./test/private-workerd-deadline.bun.test.ts ./test/private-workerd-forage.bun.test.ts ./test/local-extensions.bun.test.ts",
143
- "build:native": "fungi-apply-patch-build --out native/bin",
149
+ "test:bun": "pnpm run test:mesh-link && pnpm run test:bun:batch && bun test ./test/private-workerd-deadline.bun.test.ts",
150
+ "test:mesh-link": "bun test ./test/private-local-mesh-links.bun.test.ts",
151
+ "test:bun:batch": "bun test ./test/private-sqlite-approval-driver.bun.test.ts ./test/mcp-form-service.bun.test.ts ./test/private-local-service-discovery.bun.test.ts ./test/private-local-service-listener.bun.test.ts ./test/private-local-service-manager.bun.test.ts ./test/private-local-service-rebind.bun.test.ts ./test/private-local-service-stop.bun.test.ts ./test/private-local-service-ensure.bun.test.ts ./test/private-local-service-identity.bun.test.ts ./test/private-local-service-kill-resume.bun.test.ts ./test/private-local-service-idle-owners.bun.test.ts ./test/private-local-service-idle-delegation.bun.test.ts ./test/private-local-mail-retry.bun.test.ts ./test/private-local-service-log-native.bun.test.ts ./test/private-local-service-log.bun.test.ts ./test/private-local-sqlite-lifetime.bun.test.ts ./test/private-sqlite-driver.bun.test.ts ./test/private-local-reload.bun.test.ts ./test/private-local-auth-rpc.bun.test.ts ./test/private-workerd-forage.bun.test.ts ./test/local-extensions.bun.test.ts ./test/local-zookeeper-slot.bun.test.ts ./test/local-extension-skills.bun.test.ts ./test/private-local-sandbox-service.bun.test.ts",
152
+ "build:native": "fungi-apply-patch-build --out native/bin && node scripts/build-bwrap.mjs --out native/bin",
144
153
  "test:patch": "node --test --test-timeout=30000 test/apply-patch.native.mjs",
154
+ "test:sandbox:linux": "node --import tsx test/fixtures/local-sandbox-proof.mts",
155
+ "test:sandbox:macos": "scratch=$(mktemp -d /tmp/fungi-seatbelt.XXXXXX) && scratch=$(cd \"$scratch\" && pwd -P) && mkdir \"$scratch/home\" && HOME=\"$scratch/home\" node --import tsx scripts/seatbelt-mac-proof.mjs \"$scratch\"",
145
156
  "format:check": "node ../../tooling/repository/scripts/format-package-check.mjs",
146
157
  "lint:anti-slop": "node ../../tooling/repository/scripts/lint-package-anti-slop.mjs",
147
- "test:unit": "node ../../tooling/repository/scripts/test-file-pool.mjs pnpm run test:node",
148
- "test:merge": "pnpm run test:patch",
149
- "proof:goal-loop-sol": "bun scripts/goal-loop-model-proof.mjs"
158
+ "test:unit": "node ../../tooling/repository/scripts/test-file-pool.mjs pnpm run test:node && pnpm run test:mesh-link && pnpm run test:bun:batch && pnpm run test:stop-all",
159
+ "test:merge": "pnpm run test:patch && case \"$(uname -s)\" in Darwin) pnpm run test:sandbox:macos ;; *) pnpm run test:sandbox:linux ;; esac",
160
+ "proof:goal-loop-sol": "bun scripts/goal-loop-model-proof.mjs",
161
+ "proof:unpatched-login": "node scripts/prove-unpatched-login.mjs",
162
+ "proof:sqlite-close": "bun test ./test/private-local-sqlite-close.bun.test.ts"
150
163
  }
151
164
  }
@@ -1,5 +0,0 @@
1
- import { type ModelPreference } from "@fungi.computer/shiitake/model-preference";
2
- /** Reads Local's per-person remembered model; a Session switch never writes it. */
3
- export declare function createLocalModelSettings(path?: string): {
4
- read: () => Promise<ModelPreference | null>;
5
- };
@@ -1,31 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
- import * as Schema from "effect/Schema";
5
- import { ModelPreferenceSchema, } from "@fungi.computer/shiitake/model-preference";
6
- const settingsSchema = Schema.Struct({
7
- lastManualModel: ModelPreferenceSchema,
8
- });
9
- const decodeSettings = Schema.decodeUnknownSync(Schema.fromJsonString(settingsSchema), { onExcessProperty: "error" });
10
- /** Reads Local's per-person remembered model; a Session switch never writes it. */
11
- export function createLocalModelSettings(path = join(homedir(), ".config", "fungi", "shiitake.json")) {
12
- return {
13
- read: async () => {
14
- try {
15
- const text = await readFile(path, "utf8");
16
- if (text.length > 4096)
17
- throw new Error("Local model settings exceed their bound");
18
- return decodeSettings(text).lastManualModel;
19
- }
20
- catch (cause) {
21
- if (cause instanceof Error &&
22
- "code" in cause &&
23
- cause.code === "ENOENT")
24
- return null;
25
- throw new Error("Local model settings are invalid or unreadable", {
26
- cause,
27
- });
28
- }
29
- },
30
- };
31
- }
@@ -1,27 +0,0 @@
1
- import { type AgentControlDirectory } from "@fungi.computer/shiitake/agent-control";
2
- import type { DatabaseSync } from "node:sqlite";
3
- /**
4
- * One Local Agent's own record of the Agents each of its Sessions created or
5
- * sent work to. This host writes it as its Agent-control directory accepts a
6
- * create or a send. It feeds the read-only sub-agent view and is not a managed
7
- * parent/child relationship.
8
- */
9
- export declare function createPrivateLocalSubagents(input: Readonly<{
10
- database: DatabaseSync;
11
- directory: AgentControlDirectory;
12
- }>): {
13
- control: Readonly<{
14
- id: string;
15
- acquire: (context: import("@fungi.computer/mycelium").CapabilitySourceContext) => Promise<import("@fungi.computer/mycelium").CapabilitySourceAcquisition>;
16
- }>;
17
- source: Readonly<{
18
- read: (sessionId: string, limit: number) => Promise<Readonly<{
19
- agents: readonly import("@fungi.computer/shiitake-extensions/subagents/host").SubagentRecord[];
20
- more: number;
21
- }>>;
22
- open: (agentId: string, signal: AbortSignal) => Promise<Readonly<{
23
- agent: import("@fungi.computer/shiitake-extensions/subagents/host").SubagentAgent;
24
- release: () => Promise<void>;
25
- }>>;
26
- }>;
27
- };
@@ -1,77 +0,0 @@
1
- import { createAgentControlSource, } from "@fungi.computer/shiitake/agent-control";
2
- import { z } from "zod";
3
- const subagentRow = z.lazy(() => z.strictObject({
4
- agent_id: z.string().min(1).max(256),
5
- session_id: z.string().min(1).max(256).nullable(),
6
- total: z.number().int().nonnegative(),
7
- }));
8
- /**
9
- * One Local Agent's own record of the Agents each of its Sessions created or
10
- * sent work to. This host writes it as its Agent-control directory accepts a
11
- * create or a send. It feeds the read-only sub-agent view and is not a managed
12
- * parent/child relationship.
13
- */
14
- export function createPrivateLocalSubagents(input) {
15
- input.database.exec(`CREATE TABLE IF NOT EXISTS private_local_subagents (
16
- parent_session_id TEXT NOT NULL,
17
- agent_id TEXT NOT NULL,
18
- session_id TEXT,
19
- at INTEGER NOT NULL,
20
- PRIMARY KEY (parent_session_id, agent_id)
21
- ) STRICT`);
22
- input.database.exec("CREATE INDEX IF NOT EXISTS idx_private_local_subagents_parent ON private_local_subagents(parent_session_id, at)");
23
- // A retried create keeps its first row.
24
- const created = input.database.prepare("INSERT OR IGNORE INTO private_local_subagents(parent_session_id, agent_id, session_id, at) VALUES (?, ?, NULL, ?)");
25
- // A send names the conversation to open and moves the row to the front.
26
- const sent = input.database.prepare("INSERT INTO private_local_subagents(parent_session_id, agent_id, session_id, at) VALUES (?, ?, ?, ?) ON CONFLICT(parent_session_id, agent_id) DO UPDATE SET session_id = excluded.session_id, at = excluded.at");
27
- const page = input.database.prepare("SELECT agent_id, session_id, COUNT(*) OVER () AS total FROM private_local_subagents WHERE parent_session_id = ? ORDER BY at DESC, agent_id LIMIT ?");
28
- /** One Session's directory: its accepted creates and sends are recorded. */
29
- function recording(parentSessionId) {
30
- const { create, send } = input.directory;
31
- let directory = input.directory;
32
- if (create !== undefined && parentSessionId !== undefined)
33
- directory = {
34
- ...directory,
35
- create: async (request, signal) => {
36
- const agent = await create(request, signal);
37
- created.run(parentSessionId, agent.agentId, Date.now());
38
- return agent;
39
- },
40
- };
41
- if (send !== undefined)
42
- directory = {
43
- ...directory,
44
- send: async (task, sourceSessionId, signal, invocation) => {
45
- const accepted = await send(task, sourceSessionId, signal, invocation);
46
- sent.run(sourceSessionId, task.agentId, task.sessionId, Date.now());
47
- return accepted;
48
- },
49
- };
50
- return directory;
51
- }
52
- /**
53
- * The ordinary Agent-control tools, bound to the Session that acquires them
54
- * for one run, so a create is recorded against that Session.
55
- */
56
- const control = {
57
- id: createAgentControlSource(input.directory).id,
58
- acquire: (context) => createAgentControlSource(recording(context.session?.sessionId)).acquire(context),
59
- };
60
- const source = {
61
- read: (sessionId, limit) => {
62
- const rows = page
63
- .all(sessionId, limit)
64
- .map((row) => subagentRow.parse(row));
65
- return Promise.resolve({
66
- agents: rows.map((row) => ({
67
- agentId: row.agent_id,
68
- name: row.agent_id,
69
- sessionId: row.session_id,
70
- })),
71
- more: Math.max(0, (rows[0]?.total ?? 0) - rows.length),
72
- });
73
- },
74
- open: input.directory.open,
75
- };
76
- return { control, source };
77
- }