@retinue/agentkit 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +59 -277
  2. package/dist/adapters/audio/openai.d.ts +36 -0
  3. package/dist/adapters/audio/openai.js +136 -0
  4. package/dist/adapters/bullmq/lock.d.ts +26 -2
  5. package/dist/adapters/embeddings/openai.d.ts +45 -0
  6. package/dist/adapters/embeddings/openai.js +109 -0
  7. package/dist/adapters/memory/connections.d.ts +10 -0
  8. package/dist/adapters/memory/connections.js +87 -0
  9. package/dist/adapters/memory/graph.d.ts +17 -0
  10. package/dist/adapters/memory/graph.js +267 -0
  11. package/dist/adapters/memory/index.d.ts +3 -0
  12. package/dist/adapters/memory/index.js +3 -0
  13. package/dist/adapters/memory/rate-limit.d.ts +14 -0
  14. package/dist/adapters/memory/rate-limit.js +28 -0
  15. package/dist/adapters/memory/runtime.js +0 -0
  16. package/dist/adapters/postgres/connections.d.ts +15 -0
  17. package/dist/adapters/postgres/connections.js +134 -0
  18. package/dist/adapters/postgres/graph.d.ts +24 -0
  19. package/dist/adapters/postgres/graph.js +325 -0
  20. package/dist/adapters/postgres/index.d.ts +2 -0
  21. package/dist/adapters/postgres/index.js +2 -0
  22. package/dist/adapters/postgres/migrations.js +198 -0
  23. package/dist/adapters/postgres/run-store.js +26 -2
  24. package/dist/adapters/postgres/schema.d.ts +61 -2
  25. package/dist/adapters/postgres/schema.js +95 -10
  26. package/dist/adapters/redis/index.d.ts +1 -0
  27. package/dist/adapters/redis/index.js +1 -0
  28. package/dist/adapters/redis/rate-limit.d.ts +46 -0
  29. package/dist/adapters/redis/rate-limit.js +55 -0
  30. package/dist/adapters/supabase/index.d.ts +15 -0
  31. package/dist/adapters/supabase/index.js +15 -0
  32. package/dist/adapters/supabase/rls.js +33 -0
  33. package/dist/agents/agent.d.ts +99 -1
  34. package/dist/agents/agent.js +215 -16
  35. package/dist/agents/define.js +24 -4
  36. package/dist/agents/engine.d.ts +48 -0
  37. package/dist/agents/engine.js +370 -13
  38. package/dist/audio/index.d.ts +151 -0
  39. package/dist/audio/index.js +183 -0
  40. package/dist/capabilities/index.d.ts +5 -1
  41. package/dist/capabilities/index.js +23 -0
  42. package/dist/capabilities/runtime.d.ts +8 -0
  43. package/dist/connections/cipher.d.ts +103 -0
  44. package/dist/connections/cipher.js +141 -0
  45. package/dist/connections/index.d.ts +156 -0
  46. package/dist/connections/index.js +72 -0
  47. package/dist/connections/oauth/client.d.ts +84 -0
  48. package/dist/connections/oauth/client.js +141 -0
  49. package/dist/connections/oauth/index.d.ts +166 -0
  50. package/dist/connections/oauth/index.js +226 -0
  51. package/dist/connections/oauth/service.d.ts +90 -0
  52. package/dist/connections/oauth/service.js +132 -0
  53. package/dist/connections/pause.d.ts +68 -0
  54. package/dist/connections/pause.js +97 -0
  55. package/dist/connections/resolver.d.ts +59 -0
  56. package/dist/connections/resolver.js +138 -0
  57. package/dist/connections/resume.d.ts +64 -0
  58. package/dist/connections/resume.js +99 -0
  59. package/dist/connections/vault-cipher.d.ts +95 -0
  60. package/dist/connections/vault-cipher.js +206 -0
  61. package/dist/core/budget.d.ts +55 -0
  62. package/dist/core/budget.js +56 -0
  63. package/dist/core/content-parts.d.ts +26 -2
  64. package/dist/core/content-parts.js +1 -0
  65. package/dist/core/context.d.ts +25 -0
  66. package/dist/core/errors.d.ts +1 -1
  67. package/dist/core/errors.js +15 -0
  68. package/dist/core/events.d.ts +110 -2
  69. package/dist/core/events.js +33 -2
  70. package/dist/core/index.d.ts +1 -0
  71. package/dist/core/index.js +1 -0
  72. package/dist/core/validation.js +19 -0
  73. package/dist/documents/index.d.ts +14 -0
  74. package/dist/documents/parsers/text.d.ts +16 -0
  75. package/dist/documents/parsers/text.js +54 -2
  76. package/dist/entries/connections.d.ts +10 -0
  77. package/dist/entries/connections.js +10 -0
  78. package/dist/entries/guardrails.d.ts +14 -0
  79. package/dist/entries/guardrails.js +14 -0
  80. package/dist/entries/knowledge.d.ts +17 -0
  81. package/dist/entries/knowledge.js +16 -0
  82. package/dist/entries/mcp-server.d.ts +9 -0
  83. package/dist/entries/mcp-server.js +9 -0
  84. package/dist/entries/runtime.d.ts +10 -0
  85. package/dist/entries/runtime.js +8 -0
  86. package/dist/entries/testing.d.ts +28 -0
  87. package/dist/entries/testing.js +28 -0
  88. package/dist/graphql/resolvers.d.ts +7 -1
  89. package/dist/graphql/resolvers.js +20 -0
  90. package/dist/graphql/schema.d.ts +1 -1
  91. package/dist/graphql/schema.js +44 -0
  92. package/dist/guardrails/index.d.ts +115 -0
  93. package/dist/guardrails/index.js +108 -0
  94. package/dist/guardrails/moderation.d.ts +53 -0
  95. package/dist/guardrails/moderation.js +75 -0
  96. package/dist/guardrails/pii.d.ts +75 -0
  97. package/dist/guardrails/pii.js +193 -0
  98. package/dist/knowledge/communities.d.ts +166 -0
  99. package/dist/knowledge/communities.js +377 -0
  100. package/dist/knowledge/graph-global.d.ts +153 -0
  101. package/dist/knowledge/graph-global.js +246 -0
  102. package/dist/knowledge/graph-retrieval.d.ts +150 -0
  103. package/dist/knowledge/graph-retrieval.js +303 -0
  104. package/dist/knowledge/graph.d.ts +223 -0
  105. package/dist/knowledge/graph.js +369 -0
  106. package/dist/knowledge/index.d.ts +25 -0
  107. package/dist/knowledge/index.js +37 -1
  108. package/dist/knowledge/navigate.d.ts +89 -0
  109. package/dist/knowledge/navigate.js +107 -0
  110. package/dist/knowledge/retrieval.d.ts +98 -5
  111. package/dist/knowledge/retrieval.js +158 -28
  112. package/dist/mcp-server/index.d.ts +168 -0
  113. package/dist/mcp-server/index.js +175 -0
  114. package/dist/models/extraction.d.ts +73 -0
  115. package/dist/models/extraction.js +118 -0
  116. package/dist/models/index.d.ts +40 -1
  117. package/dist/models/index.js +22 -1
  118. package/dist/models/pricing.d.ts +2 -0
  119. package/dist/models/pricing.js +17 -1
  120. package/dist/models/provider-factory.js +9 -7
  121. package/dist/models/streaming.d.ts +111 -1
  122. package/dist/models/streaming.js +184 -3
  123. package/dist/persistence/index.d.ts +230 -0
  124. package/dist/persistence/index.js +2 -0
  125. package/dist/runtime/index.d.ts +1 -1
  126. package/dist/runtime/index.js +12 -0
  127. package/dist/runtime/worker.d.ts +36 -1
  128. package/dist/runtime/worker.js +37 -4
  129. package/dist/security/checklist.js +55 -0
  130. package/dist/security/findings.js +18 -9
  131. package/dist/server/bin.d.ts +19 -0
  132. package/dist/server/bin.js +226 -0
  133. package/dist/server/boot.d.ts +20 -2
  134. package/dist/server/boot.js +29 -3
  135. package/dist/server/cli.d.ts +13 -0
  136. package/dist/server/cli.js +7 -4
  137. package/dist/server/doctor.d.ts +74 -0
  138. package/dist/server/doctor.js +280 -0
  139. package/dist/skills/catalogue.d.ts +49 -0
  140. package/dist/skills/catalogue.js +61 -0
  141. package/dist/skills/context.d.ts +61 -0
  142. package/dist/skills/context.js +107 -0
  143. package/dist/skills/index.d.ts +2 -0
  144. package/dist/skills/index.js +2 -0
  145. package/dist/telemetry/spans.js +17 -0
  146. package/dist/testing/conformance/artifact-exports.d.ts +20 -0
  147. package/dist/testing/conformance/artifact-exports.js +172 -0
  148. package/dist/testing/conformance/artifacts.d.ts +11 -0
  149. package/dist/testing/conformance/artifacts.js +316 -0
  150. package/dist/testing/conformance/audio.d.ts +38 -0
  151. package/dist/testing/conformance/audio.js +145 -0
  152. package/dist/testing/conformance/capability.d.ts +23 -0
  153. package/dist/testing/conformance/capability.js +27 -0
  154. package/dist/testing/conformance/checkpoint-store.d.ts +15 -0
  155. package/dist/testing/conformance/checkpoint-store.js +72 -0
  156. package/dist/testing/conformance/connections.d.ts +14 -0
  157. package/dist/testing/conformance/connections.js +171 -0
  158. package/dist/testing/conformance/conversation-store.d.ts +10 -0
  159. package/dist/testing/conformance/conversation-store.js +60 -0
  160. package/dist/testing/conformance/evaluation.d.ts +10 -0
  161. package/dist/testing/conformance/evaluation.js +295 -0
  162. package/dist/testing/conformance/files.d.ts +19 -0
  163. package/dist/testing/conformance/files.js +454 -0
  164. package/dist/testing/conformance/flows.d.ts +16 -0
  165. package/dist/testing/conformance/flows.js +193 -0
  166. package/dist/testing/conformance/graph.d.ts +22 -0
  167. package/dist/testing/conformance/graph.js +500 -0
  168. package/dist/testing/conformance/hitl.d.ts +25 -0
  169. package/dist/testing/conformance/hitl.js +523 -0
  170. package/dist/testing/conformance/index.d.ts +163 -0
  171. package/dist/testing/conformance/index.js +321 -0
  172. package/dist/testing/conformance/invariants.d.ts +23 -0
  173. package/dist/testing/conformance/invariants.js +80 -0
  174. package/dist/testing/conformance/knowledge.d.ts +41 -0
  175. package/dist/testing/conformance/knowledge.js +592 -0
  176. package/dist/testing/conformance/parents.d.ts +50 -0
  177. package/dist/testing/conformance/parents.js +39 -0
  178. package/dist/testing/conformance/rate-limit.d.ts +25 -0
  179. package/dist/testing/conformance/rate-limit.js +71 -0
  180. package/dist/testing/conformance/records.d.ts +36 -0
  181. package/dist/testing/conformance/records.js +400 -0
  182. package/dist/testing/conformance/rollups.d.ts +30 -0
  183. package/dist/testing/conformance/rollups.js +425 -0
  184. package/dist/testing/conformance/run-coordinator.d.ts +27 -0
  185. package/dist/testing/conformance/run-coordinator.js +150 -0
  186. package/dist/testing/conformance/run-event-log.d.ts +9 -0
  187. package/dist/testing/conformance/run-event-log.js +138 -0
  188. package/dist/testing/conformance/run-store.d.ts +12 -0
  189. package/dist/testing/conformance/run-store.js +294 -0
  190. package/dist/testing/conformance/session-state.d.ts +38 -0
  191. package/dist/testing/conformance/session-state.js +198 -0
  192. package/dist/testing/conformance/usage-limits.d.ts +10 -0
  193. package/dist/testing/conformance/usage-limits.js +309 -0
  194. package/dist/testing/conformance.d.ts +8 -0
  195. package/dist/testing/conformance.js +8 -0
  196. package/dist/testing/memory-backend.d.ts +39 -0
  197. package/dist/testing/memory-backend.js +41 -0
  198. package/dist/testing/pglite.d.ts +55 -0
  199. package/dist/testing/pglite.js +78 -0
  200. package/dist/testing/stub-model.d.ts +58 -0
  201. package/dist/testing/stub-model.js +71 -0
  202. package/dist/testing/supabase-storage-double.d.ts +35 -0
  203. package/dist/testing/supabase-storage-double.js +101 -0
  204. package/dist/toolkit/files.d.ts +125 -0
  205. package/dist/toolkit/files.js +320 -0
  206. package/dist/toolkit/http.d.ts +27 -0
  207. package/dist/toolkit/http.js +48 -0
  208. package/dist/toolkit/index.d.ts +31 -1
  209. package/dist/toolkit/index.js +26 -1
  210. package/dist/toolkit/mime.d.ts +97 -0
  211. package/dist/toolkit/mime.js +233 -0
  212. package/dist/toolkit/sandbox.d.ts +119 -0
  213. package/dist/toolkit/sandbox.js +239 -0
  214. package/dist/toolkit/ssrf.d.ts +139 -0
  215. package/dist/toolkit/ssrf.js +349 -0
  216. package/dist/toolkit/vendor.d.ts +91 -0
  217. package/dist/toolkit/vendor.js +153 -0
  218. package/dist/toolkit/web.d.ts +13 -0
  219. package/dist/toolkit/web.js +7 -1
  220. package/dist/tools/budget.d.ts +28 -0
  221. package/dist/tools/budget.js +35 -0
  222. package/dist/tools/credentials.d.ts +316 -0
  223. package/dist/tools/credentials.js +369 -0
  224. package/dist/tools/define.d.ts +45 -0
  225. package/dist/tools/define.js +26 -0
  226. package/dist/tools/find.d.ts +109 -0
  227. package/dist/tools/find.js +210 -0
  228. package/dist/tools/index.d.ts +35 -2
  229. package/dist/tools/index.js +11 -0
  230. package/dist/tools/library/audio.d.ts +63 -0
  231. package/dist/tools/library/audio.js +148 -0
  232. package/dist/tools/library/fs.d.ts +24 -0
  233. package/dist/tools/library/fs.js +102 -0
  234. package/dist/tools/library/index.d.ts +37 -2
  235. package/dist/tools/library/index.js +47 -0
  236. package/dist/tools/library/shell.d.ts +45 -0
  237. package/dist/tools/library/shell.js +70 -0
  238. package/dist/tools/meta-tools.js +8 -0
  239. package/dist/tools/registry.d.ts +146 -0
  240. package/dist/tools/registry.js +250 -4
  241. package/dist/usage/index.d.ts +21 -0
  242. package/dist/usage/index.js +1 -0
  243. package/dist/usage/rate-limit.d.ts +122 -0
  244. package/dist/usage/rate-limit.js +131 -0
  245. package/dist/usage/recorder.js +3 -0
  246. package/package.json +33 -2
@@ -20,12 +20,15 @@
20
20
  * replay protection is the failure this envelope exists to prevent, and a deployment should hear about it the
21
21
  * first time rather than after.
22
22
  */
23
+ export { createFsListTool, createFsReadTool, createFsSearchTool, createFsWriteTool } from "./fs.js";
24
+ export { createShellExecTool, shellDisabled } from "./shell.js";
25
+ export type { ShellToolConfig } from "./shell.js";
23
26
  import type { DelegatingToolDeps } from "../delegating.js";
24
27
  import type { ToolProvider } from "../index.js";
25
28
  import type { ExecutionContext } from "../../core/context.js";
26
29
  import type { ExtractionService } from "../../documents/extraction.js";
27
30
  import type { FileService } from "../../files/index.js";
28
- import type { HttpClient, HttpClientConfig, ReadOnlyQuery, SearchProvider } from "../../toolkit/index.js";
31
+ import type { FileReader, FileScope, HttpClient, HttpClientConfig, ReadOnlyQuery, Sandbox, SearchProvider } from "../../toolkit/index.js";
29
32
  import type { KnowledgeRetriever } from "./knowledge.js";
30
33
  import type { RetrievalMode } from "../../knowledge/retrieval.js";
31
34
  /**
@@ -34,7 +37,7 @@ import type { RetrievalMode } from "../../knowledge/retrieval.js";
34
37
  * A closed list so `exclude` is checked against it: a typo in an exclusion is otherwise a tool that stays enabled
35
38
  * and a deployment that believes it is off.
36
39
  */
37
- export declare const STANDARD_TOOL_NAMES: readonly ["fetch_url", "fetch_json", "web_search", "http_request", "http_write", "parse_csv", "query_json", "sql_query", "sql_schema", "search_knowledge", "read_attachment", "list_attachments", "read_document", "now", "calculate"];
40
+ export declare const STANDARD_TOOL_NAMES: readonly ["fetch_url", "fetch_json", "web_search", "http_request", "http_write", "parse_csv", "query_json", "sql_query", "sql_schema", "search_knowledge", "read_attachment", "list_attachments", "read_document", "now", "calculate", "fs_read", "fs_list", "fs_search", "fs_write", "shell_exec"];
38
41
  export type StandardToolName = (typeof STANDARD_TOOL_NAMES)[number];
39
42
  /**
40
43
  * The categories these tools use.
@@ -82,6 +85,30 @@ export type StandardToolsConfig = {
82
85
  readonly files?: FileService;
83
86
  /** Enables `read_document`. */
84
87
  readonly documents?: ExtractionService;
88
+ /**
89
+ * A path-scoped filesystem — REQ-047 (#206), task #215.
90
+ *
91
+ * Supplying a `root` enables `fs_read`, `fs_list` and `fs_search`. `fs_write` needs a `writableRoot` as well,
92
+ * and it must be a *different* directory: pointing both at the same place lets a model edit the material it
93
+ * also reads, which is how a corpus a model cites becomes a corpus a model wrote.
94
+ */
95
+ readonly filesystem?: FileScope | {
96
+ readonly reader: FileReader;
97
+ readonly writable: boolean;
98
+ };
99
+ /**
100
+ * A sandbox, which is what makes `shell_exec` exist — task #215.
101
+ *
102
+ * Two switches, deliberately, and the only tool in the library with two: a sandbox wired *and* the `shell`
103
+ * capability declared. Everywhere else wiring is the toggle, because a second switch is usually how a
104
+ * deployment ends up with something switched on and wired to nothing. Here the failure mode runs the other
105
+ * way — "somebody wired a sandbox for a test and forgot" must not silently mean the agent can run commands on
106
+ * a machine.
107
+ *
108
+ * `shellEnabled` is a function, so the declaration is read at the call rather than captured at construction.
109
+ */
110
+ readonly sandbox?: Sandbox;
111
+ readonly shellEnabled?: () => boolean;
85
112
  /** Injected so a test can pin `now`. */
86
113
  readonly clock?: () => Date;
87
114
  readonly exclude?: readonly StandardToolName[];
@@ -94,4 +121,12 @@ export { createHttpRequestTool, createHttpWriteTool } from "./http.js";
94
121
  export { createSearchKnowledgeTool } from "./knowledge.js";
95
122
  export type { KnowledgeRetriever } from "./knowledge.js";
96
123
  export { createFetchJsonTool, createFetchUrlTool, createWebSearchTool } from "./web.js";
124
+ /**
125
+ * Audio — REQ-062 (#257), task #258.
126
+ *
127
+ * Library tools rather than a `tools-media` package, and the reason is argued in `audio.ts`: they take ports,
128
+ * not a vendor, exactly as `createWebSearchTool` does.
129
+ */
130
+ export { createSpeechGenerateTool, createTranscribeTool } from "./audio.js";
131
+ export type { AudioToolDeps } from "./audio.js";
97
132
  //# sourceMappingURL=index.d.ts.map
@@ -25,9 +25,14 @@ import { createParseCsvTool, createQueryJsonTool, createSqlQueryTool, createSqlS
25
25
  import { createHttpRequestTool, createHttpWriteTool } from "./http.js";
26
26
  import { createSearchKnowledgeTool } from "./knowledge.js";
27
27
  import { createFetchJsonTool, createFetchUrlTool, createWebSearchTool } from "./web.js";
28
+ import { createFsListTool, createFsReadTool, createFsSearchTool, createFsWriteTool } from "./fs.js";
29
+ import { createShellExecTool } from "./shell.js";
30
+ export { createFsListTool, createFsReadTool, createFsSearchTool, createFsWriteTool } from "./fs.js";
31
+ export { createShellExecTool, shellDisabled } from "./shell.js";
28
32
  import { createHttpClient } from "../../toolkit/http.js";
29
33
  import { createFetchJson, createFetchPage, createWebSearch } from "../../toolkit/web.js";
30
34
  import { createSqlQuery, createSqlSchema } from "../../toolkit/data.js";
35
+ import { createFileReader } from "../../toolkit/files.js";
31
36
  import { createReadAttachmentTool, createListAttachmentsTool } from "../../files/read-tool.js";
32
37
  import { createReadDocumentTool } from "../../documents/read-tool.js";
33
38
  /**
@@ -52,6 +57,11 @@ export const STANDARD_TOOL_NAMES = [
52
57
  "read_document",
53
58
  "now",
54
59
  "calculate",
60
+ "fs_read",
61
+ "fs_list",
62
+ "fs_search",
63
+ "fs_write",
64
+ "shell_exec",
55
65
  ];
56
66
  /**
57
67
  * The categories these tools use.
@@ -81,6 +91,17 @@ export const createStandardToolProvider = (config) => {
81
91
  ? undefined
82
92
  : createSqlQuery({ query: config.sql.query, readOnly: config.sql.readOnly, ...(config.sql.maxRows === undefined ? {} : { maxRows: config.sql.maxRows }) });
83
93
  const describeSql = config.sql?.schemas === undefined ? undefined : createSqlSchema({ query: config.sql.query, schemas: config.sql.schemas });
94
+ /**
95
+ * The file reader, built once.
96
+ *
97
+ * A caller may hand over a `FileReader` it already has instead of a scope — the same shape the HTTP config
98
+ * takes a `client` for, and the same reason: one place decides what is readable.
99
+ */
100
+ const filesystem = config.filesystem === undefined
101
+ ? undefined
102
+ : "reader" in config.filesystem
103
+ ? { reader: config.filesystem.reader, writable: config.filesystem.writable }
104
+ : { reader: createFileReader(config.filesystem), writable: config.filesystem.writableRoot !== undefined };
84
105
  const fixed = [
85
106
  ["fetch_url", () => createFetchUrlTool(deps, fetchPage)],
86
107
  ["fetch_json", () => createFetchJsonTool(deps, fetchJson)],
@@ -96,6 +117,19 @@ export const createStandardToolProvider = (config) => {
96
117
  ["read_document", () => createReadDocumentTool({ extraction: config.documents })],
97
118
  ["now", () => createNowTool(deps, config.clock)],
98
119
  ["calculate", () => createCalculateTool(deps)],
120
+ ["fs_read", () => createFsReadTool(deps, filesystem.reader)],
121
+ ["fs_list", () => createFsListTool(deps, filesystem.reader)],
122
+ ["fs_search", () => createFsSearchTool(deps, filesystem.reader)],
123
+ ["fs_write", () => createFsWriteTool(deps, filesystem.reader)],
124
+ [
125
+ "shell_exec",
126
+ () => createShellExecTool(deps, {
127
+ sandbox: config.sandbox,
128
+ // Absent means not declared. The uncomfortable direction on purpose: a forgotten declaration turns the
129
+ // tool off rather than on.
130
+ enabled: config.shellEnabled ?? (() => false),
131
+ }),
132
+ ],
99
133
  ];
100
134
  /** What each tool needs before it can exist. A tool with no entry needs nothing. */
101
135
  const wired = {
@@ -109,6 +143,12 @@ export const createStandardToolProvider = (config) => {
109
143
  search_knowledge: config.knowledge !== undefined,
110
144
  read_attachment: config.files !== undefined,
111
145
  read_document: config.documents !== undefined,
146
+ fs_read: filesystem !== undefined,
147
+ fs_list: filesystem !== undefined,
148
+ fs_search: filesystem !== undefined,
149
+ // A writable root, separately: the three reads are useful on their own, and most deployments want only those.
150
+ fs_write: filesystem?.writable === true,
151
+ shell_exec: config.sandbox !== undefined,
112
152
  };
113
153
  const tools = fixed
114
154
  .filter(([name]) => !excluded.has(name) && (wired[name] ?? true))
@@ -131,4 +171,11 @@ export { createParseCsvTool, createQueryJsonTool, createSqlQueryTool, createSqlS
131
171
  export { createHttpRequestTool, createHttpWriteTool } from "./http.js";
132
172
  export { createSearchKnowledgeTool } from "./knowledge.js";
133
173
  export { createFetchJsonTool, createFetchUrlTool, createWebSearchTool } from "./web.js";
174
+ /**
175
+ * Audio — REQ-062 (#257), task #258.
176
+ *
177
+ * Library tools rather than a `tools-media` package, and the reason is argued in `audio.ts`: they take ports,
178
+ * not a vendor, exactly as `createWebSearchTool` does.
179
+ */
180
+ export { createSpeechGenerateTool, createTranscribeTool } from "./audio.js";
134
181
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Running a command — REQ-047 (#206), task #215.
3
+ *
4
+ * An envelope over `toolkit/sandbox.ts`, and the most consequential tool in the package. Read the note at the top
5
+ * of that module before wiring this: the tool is only defensible because of what the sandbox guarantees, and the
6
+ * local adapter guarantees almost none of it.
7
+ *
8
+ * ## Three things this envelope does, and one it deliberately does not
9
+ *
10
+ * **`destructive`, so the approval gate always fires.** Not because every command is destructive — `ls` is not —
11
+ * but because the classification is what the gate reads, and a tool whose worst case is "anything" has to be
12
+ * classified by its worst case.
13
+ *
14
+ * **An idempotency key is required.** A retried `shell_exec` must not run twice: the first result is returned
15
+ * instead. A command that appended a line to a file would otherwise append two on a network hiccup.
16
+ *
17
+ * **The capability must be declared.** Wiring a sandbox is not enough; `shell: "on"` has to be in the runtime's
18
+ * capability declaration, and this is checked at the *call*. Two switches for one decision is usually a smell —
19
+ * see `web_search`, where wiring alone is the toggle — and here it is deliberate: this is the one tool where
20
+ * "somebody wired a sandbox for a test and forgot" must not silently mean the agent can run commands.
21
+ *
22
+ * **What it does not do is read the command.** No refusing `rm -rf`, no allow-list of binaries. That is a losing
23
+ * game — `find . -delete`, `dd`, `python -c`, a base64 pipeline — and worse, it *feels* like protection while
24
+ * being a list somebody gets around. The classification cannot be evaded by rephrasing.
25
+ */
26
+ import type { DelegatingToolDeps } from "../delegating.js";
27
+ import type { Tool } from "../index.js";
28
+ import type { Sandbox, SandboxResult } from "../../toolkit/index.js";
29
+ export type ShellToolConfig = {
30
+ readonly sandbox: Sandbox;
31
+ /**
32
+ * Whether the runtime declared the `shell` capability.
33
+ *
34
+ * A function rather than a boolean, so the answer is read at the call. A capability map captured at
35
+ * construction is a capability map that cannot be turned off without a restart, and this is the one tool where
36
+ * that matters.
37
+ */
38
+ readonly enabled: () => boolean;
39
+ };
40
+ /** What a refused call returns. Shaped like a result, because the model can act on a reason and not on a throw. */
41
+ export declare const shellDisabled: () => SandboxResult & {
42
+ readonly refused: string;
43
+ };
44
+ export declare const createShellExecTool: (deps: DelegatingToolDeps, config: ShellToolConfig) => Tool;
45
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Running a command — REQ-047 (#206), task #215.
3
+ *
4
+ * An envelope over `toolkit/sandbox.ts`, and the most consequential tool in the package. Read the note at the top
5
+ * of that module before wiring this: the tool is only defensible because of what the sandbox guarantees, and the
6
+ * local adapter guarantees almost none of it.
7
+ *
8
+ * ## Three things this envelope does, and one it deliberately does not
9
+ *
10
+ * **`destructive`, so the approval gate always fires.** Not because every command is destructive — `ls` is not —
11
+ * but because the classification is what the gate reads, and a tool whose worst case is "anything" has to be
12
+ * classified by its worst case.
13
+ *
14
+ * **An idempotency key is required.** A retried `shell_exec` must not run twice: the first result is returned
15
+ * instead. A command that appended a line to a file would otherwise append two on a network hiccup.
16
+ *
17
+ * **The capability must be declared.** Wiring a sandbox is not enough; `shell: "on"` has to be in the runtime's
18
+ * capability declaration, and this is checked at the *call*. Two switches for one decision is usually a smell —
19
+ * see `web_search`, where wiring alone is the toggle — and here it is deliberate: this is the one tool where
20
+ * "somebody wired a sandbox for a test and forgot" must not silently mean the agent can run commands.
21
+ *
22
+ * **What it does not do is read the command.** No refusing `rm -rf`, no allow-list of binaries. That is a losing
23
+ * game — `find . -delete`, `dd`, `python -c`, a base64 pipeline — and worse, it *feels* like protection while
24
+ * being a list somebody gets around. The classification cannot be evaded by rephrasing.
25
+ */
26
+ import { z } from "zod";
27
+ import { defineDelegatingTool } from "../delegating.js";
28
+ const shellSchema = z
29
+ .object({
30
+ command: z
31
+ .string()
32
+ .min(1)
33
+ .max(4_000)
34
+ .describe("A shell command. It runs in an isolated sandbox with no network and a writable /scratch only."),
35
+ timeoutMs: z.number().int().min(100).max(120_000).optional(),
36
+ })
37
+ .strict();
38
+ /** What a refused call returns. Shaped like a result, because the model can act on a reason and not on a throw. */
39
+ export const shellDisabled = () => ({
40
+ ok: false,
41
+ exitCode: null,
42
+ stdout: "",
43
+ stderr: "",
44
+ truncated: false,
45
+ durationMs: 0,
46
+ refused: "shell_exec is wired but the `shell` capability is not declared for this runtime, so no command will run. " +
47
+ "This is a deliberate second switch on the one tool whose blast radius is the machine.",
48
+ });
49
+ export const createShellExecTool = (deps, config) => defineDelegatingTool(deps, {
50
+ name: "shell_exec",
51
+ label: "Run a command",
52
+ description: "Run a shell command inside an isolated sandbox: no network, a read-only filesystem apart from /scratch, a " +
53
+ "memory cap and a wall-clock timeout. Returns stdout, stderr and the exit code. This always requires a " +
54
+ "human's approval before it runs, whatever the command is. Output is truncated when long, and says so.",
55
+ category: "code",
56
+ effect: "destructive",
57
+ approvalPolicy: "always",
58
+ requiresIdempotencyKey: true,
59
+ inputSchema: shellSchema,
60
+ delegatesTo: "toolkit/sandbox.run",
61
+ delegate: async (input) => {
62
+ if (!config.enabled())
63
+ return shellDisabled();
64
+ return config.sandbox.run({
65
+ command: input.command,
66
+ ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
67
+ });
68
+ },
69
+ });
70
+ //# sourceMappingURL=shell.js.map
@@ -26,6 +26,14 @@ const meta = (name, label, description) => ({
26
26
  });
27
27
  export const META_TOOL_DESCRIPTORS = {
28
28
  learn_tools: meta("learn_tools", "Learn tools", "Fetch the full input/output schemas for named tools before using them."),
29
+ /**
30
+ * REQ-045 (#204), task #210.
31
+ *
32
+ * The description says "not all of them are listed", and that sentence is doing real work: a model that
33
+ * believes the catalogue it can see is complete will not search, and a budget that dropped fourteen tools
34
+ * would then behave exactly like fourteen tools that do not exist.
35
+ */
36
+ find_tools: meta("find_tools", "Find tools", "Search for a tool by describing what you need to do. Not all available tools are listed in the catalogue, so search before concluding that something cannot be done. Returns names and descriptions; use learn_tools for a schema."),
29
37
  execute_tool: meta("execute_tool", "Execute tool", "Run a tool by name with validated input; authorization is rechecked at execution."),
30
38
  load_skill: meta("load_skill", "Load skill", "Load a named skill's instructions into context on demand."),
31
39
  ask_questions: meta("ask_questions", "Ask questions", "Ask the user consequential questions that cannot be resolved from context or tools."),
@@ -16,10 +16,13 @@
16
16
  * result instead of firing the side effect twice.
17
17
  */
18
18
  import type { ExecutionContext } from "../core/context.js";
19
+ import type { PlatformError } from "../core/errors.js";
19
20
  import type { BlobRef } from "../core/ids.js";
20
21
  import { type AuthorizationPolicy } from "../authorization/index.js";
21
22
  import { type IdempotencyStore } from "../idempotency/index.js";
22
23
  import type { BlobStore } from "../persistence/index.js";
24
+ import { type TokenBudget } from "../core/budget.js";
25
+ import type { ToolSearch, ToolSearchOutcome } from "./find.js";
23
26
  import type { OneTimeApprovalRef, ShadowRecorder, ToolCatalogEntry, ToolDescriptor, ToolProvider, ToolResult } from "./index.js";
24
27
  /** Validates a tool input against its (opaque) `inputSchema`. Default duck-types a zod schema. */
25
28
  export interface SchemaValidator {
@@ -33,6 +36,55 @@ export interface SchemaValidator {
33
36
  }
34
37
  /** Default validator: run a zod-like schema's `safeParse`; pass through anything else (tool self-validates). */
35
38
  export declare const zodishValidator: SchemaValidator;
39
+ /**
40
+ * `execute_tool({ name, input })` → the call it names. Anything else passes through untouched.
41
+ *
42
+ * Refuses to target another meta-tool: `execute_tool` calling itself is an unbounded recursion a model can start
43
+ * with one call, and the others have their own entry points. One level of indirection is the feature; a stack of
44
+ * it is a way to hide what a call actually was from every log that records the outer name.
45
+ */
46
+ export type ExecuteToolRequest = {
47
+ name: string;
48
+ input: unknown;
49
+ idempotencyKey?: string;
50
+ toolCallId?: string;
51
+ approval?: OneTimeApprovalRef;
52
+ };
53
+ export declare const unwrapExecuteTool: (request: ExecuteToolRequest) => ExecuteToolRequest | {
54
+ readonly error: PlatformError;
55
+ };
56
+ /**
57
+ * What a tenant has switched on — REQ-045 (#204), task #210, AC-4.
58
+ *
59
+ * Authorization answers *may this principal use this tool*. Nothing answered *does this tenant want it at all*,
60
+ * and without the second question a catalogue is only ever as small as its largest customer: every tenant pays
61
+ * the context cost of every integration anybody wired.
62
+ *
63
+ * Categories rather than names, deliberately. A tenant switching off `communication` should not have to name
64
+ * five Slack tools and then miss the sixth when it ships.
65
+ */
66
+ export type TenantToolset = {
67
+ /** An allow-list. Present means *only* these categories, which is the safer shape for a tenant opting in. */
68
+ readonly enabledCategories?: readonly string[];
69
+ /** A deny-list, applied after any allow-list. */
70
+ readonly disabledCategories?: readonly string[];
71
+ };
72
+ /**
73
+ * Resolves a tenant's toolset. A port, because where this lives is a deployment's decision — a column, a
74
+ * settings service, a static map.
75
+ */
76
+ export interface ToolsetResolver {
77
+ resolve(context: ExecutionContext): Promise<TenantToolset>;
78
+ }
79
+ /**
80
+ * Categories a tenant may not switch off.
81
+ *
82
+ * `meta` is the model's route back to everything else. A tenant that disabled it would have an agent that cannot
83
+ * learn a schema or search the catalogue — which is not a smaller toolset, it is a broken one.
84
+ */
85
+ export declare const UNDISABLEABLE_CATEGORIES: readonly string[];
86
+ /** Whether a category survives a tenant's toolset. Exported because the filtering is worth testing directly. */
87
+ export declare const categoryEnabled: (toolset: TenantToolset, category: string) => boolean;
36
88
  export type ToolPolicyView = {
37
89
  readonly preloaded: readonly string[];
38
90
  readonly categories: readonly string[];
@@ -45,7 +97,49 @@ export type ToolCatalog = {
45
97
  readonly discoverable: readonly ToolCatalogEntry[];
46
98
  /** Always-present meta-tools. */
47
99
  readonly meta: readonly ToolCatalogEntry[];
100
+ /**
101
+ * Present only when a budget bound — REQ-045 (#204), task #210, AC-3.
102
+ *
103
+ * On the catalogue as well as in the run event log, because the two have different readers: the event is for
104
+ * whoever reviews the run afterwards, and this is for the client rendering the catalogue *now*. A UI showing
105
+ * a shortened list with no indication it was shortened is the same invisible failure in a different place.
106
+ */
107
+ readonly truncation?: {
108
+ readonly budgetTokens: number;
109
+ readonly residentTokens: number;
110
+ readonly dropped: readonly string[];
111
+ readonly findable: boolean;
112
+ readonly overBudget: boolean;
113
+ };
114
+ /**
115
+ * The tenant's toolset as it was applied — AC-4's "visible in the capability declaration".
116
+ *
117
+ * This catalogue *is* the declaration a client reads: it is the only place the platform states what an agent
118
+ * can do. A tenant setting that silently narrowed it, with nothing in the answer saying so, would be
119
+ * indistinguishable from tools that were never built.
120
+ */
121
+ readonly toolset?: TenantToolset;
48
122
  };
123
+ /**
124
+ * Loads a skill body by name — the execution half of `load_skill`.
125
+ *
126
+ * Kept structural (no `skills` import) so `tools` does not depend on `skills`. Returns `null` for a name the
127
+ * tenant does not have, so an unknown skill is a message rather than a throw.
128
+ */
129
+ export interface SkillBodyLoader {
130
+ load(context: ExecutionContext, name: string): Promise<{
131
+ readonly name: string;
132
+ readonly version: number;
133
+ readonly instructions: string;
134
+ } | null>;
135
+ }
136
+ /**
137
+ * How many distinct skills one run may pull into context.
138
+ *
139
+ * Mirrors `SKILL_LIMITS.maxLoadedPerRun`, duplicated rather than imported for the same layering reason as
140
+ * `SkillBodyLoader`. A test asserts the two agree, so the copy cannot drift silently.
141
+ */
142
+ export declare const MAX_SKILLS_LOADED_PER_RUN = 5;
49
143
  /** Structural approval check (satisfied by the HITL `ApprovalGate`) — kept structural to avoid a
50
144
  * tools→hitl dependency. Returns false when the tool needs approval and the call carries neither a
51
145
  * standing grant nor a valid one-time approval. */
@@ -127,9 +221,61 @@ export type ToolRegistryConfig = {
127
221
  * than performed, the same fail-closed rule as the envelope's.
128
222
  */
129
223
  readonly shadow?: ShadowRecorder;
224
+ /**
225
+ * Search over the catalogue, which is what makes `find_tools` exist — AC-1.
226
+ *
227
+ * Absent means no `find_tools` in the catalogue at all, rather than one that always answers "not configured".
228
+ * Wiring is the toggle, the same rule the tool library already follows for `web_search`.
229
+ */
230
+ readonly search?: ToolSearch;
231
+ /**
232
+ * Loads a named skill's body, when the deployment has skills — task #244.
233
+ *
234
+ * Structural rather than importing `SkillResolver`, for the reason `ApprovalCheck` is structural: `tools` must
235
+ * not depend on `skills`. `createSkillBodyLoader` in `skills/` adapts a resolver to this shape.
236
+ *
237
+ * Wiring is the toggle. `load_skill` has been in `META_TOOLS` since the registry was written with **nothing
238
+ * implementing it** — the third instance of that exact pattern after `execute_tool` and `learn_tools` (#210).
239
+ * A model handed the descriptor would call it, get "Unknown tool load_skill", and a transcript reader would
240
+ * see a broken platform. So the descriptor is now advertised only when this is wired, which is the rule
241
+ * `find_tools` already follows.
242
+ */
243
+ readonly skills?: SkillBodyLoader;
244
+ /** A tenant's category switches, applied *before* authorization filtering — AC-4. */
245
+ readonly toolsets?: ToolsetResolver;
246
+ /**
247
+ * A ceiling in tokens on the discoverable catalogue — AC-3.
248
+ *
249
+ * Applies to the compact entries only. Preloaded tools are an explicit instruction from the host and are not
250
+ * silently withdrawn; a host that preloads more than its own budget is told so through `overBudget` rather
251
+ * than having its instruction quietly reversed.
252
+ */
253
+ readonly catalogBudget?: TokenBudget;
130
254
  };
131
255
  export interface ToolRegistry {
132
256
  catalog(context: ExecutionContext, policy: ToolPolicyView): Promise<ToolCatalog>;
257
+ /**
258
+ * Search the catalogue — AC-1.
259
+ *
260
+ * Filtered by the same authorization policy as discovery, which is not a nicety: an unfiltered search is an
261
+ * enumeration oracle. A principal who cannot see `github_merge_pull_request` in the catalogue but can confirm
262
+ * it exists by searching for "merge" has learned what the deployment does, and hiding a tool from discovery
263
+ * while making it findable is worse than not hiding it, because it looks like it was hidden.
264
+ */
265
+ find(context: ExecutionContext, input: {
266
+ readonly query: string;
267
+ readonly limit?: number;
268
+ }): Promise<ToolSearchOutcome>;
269
+ /**
270
+ * Every tool this caller may use, with schemas — the list `buildTools` should hand a model.
271
+ *
272
+ * Exists because the embedded facade was doing this itself: gathering providers, flattening, and filtering by
273
+ * authorization, in its own copy of the four lines this registry already owns. The copy had no duplicate-name
274
+ * check and no tenant toolset, so a category a tenant had switched off was invisible in the catalogue, absent
275
+ * from `find_tools`, refused at execution — and *still handed to the model*, which would then call it and be
276
+ * refused. One implementation, and this is it.
277
+ */
278
+ listAuthorized(context: ExecutionContext): Promise<readonly ToolDescriptor[]>;
133
279
  learn(context: ExecutionContext, names: readonly string[]): Promise<readonly ToolDescriptor[]>;
134
280
  execute(context: ExecutionContext, input: {
135
281
  name: string;