@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.
- package/README.md +59 -277
- package/dist/adapters/audio/openai.d.ts +36 -0
- package/dist/adapters/audio/openai.js +136 -0
- package/dist/adapters/bullmq/lock.d.ts +26 -2
- package/dist/adapters/embeddings/openai.d.ts +45 -0
- package/dist/adapters/embeddings/openai.js +109 -0
- package/dist/adapters/memory/connections.d.ts +10 -0
- package/dist/adapters/memory/connections.js +87 -0
- package/dist/adapters/memory/graph.d.ts +17 -0
- package/dist/adapters/memory/graph.js +267 -0
- package/dist/adapters/memory/index.d.ts +3 -0
- package/dist/adapters/memory/index.js +3 -0
- package/dist/adapters/memory/rate-limit.d.ts +14 -0
- package/dist/adapters/memory/rate-limit.js +28 -0
- package/dist/adapters/memory/runtime.js +0 -0
- package/dist/adapters/postgres/connections.d.ts +15 -0
- package/dist/adapters/postgres/connections.js +134 -0
- package/dist/adapters/postgres/graph.d.ts +24 -0
- package/dist/adapters/postgres/graph.js +325 -0
- package/dist/adapters/postgres/index.d.ts +2 -0
- package/dist/adapters/postgres/index.js +2 -0
- package/dist/adapters/postgres/migrations.js +198 -0
- package/dist/adapters/postgres/run-store.js +26 -2
- package/dist/adapters/postgres/schema.d.ts +61 -2
- package/dist/adapters/postgres/schema.js +95 -10
- package/dist/adapters/redis/index.d.ts +1 -0
- package/dist/adapters/redis/index.js +1 -0
- package/dist/adapters/redis/rate-limit.d.ts +46 -0
- package/dist/adapters/redis/rate-limit.js +55 -0
- package/dist/adapters/supabase/index.d.ts +15 -0
- package/dist/adapters/supabase/index.js +15 -0
- package/dist/adapters/supabase/rls.js +33 -0
- package/dist/agents/agent.d.ts +99 -1
- package/dist/agents/agent.js +215 -16
- package/dist/agents/define.js +24 -4
- package/dist/agents/engine.d.ts +48 -0
- package/dist/agents/engine.js +370 -13
- package/dist/audio/index.d.ts +151 -0
- package/dist/audio/index.js +183 -0
- package/dist/capabilities/index.d.ts +5 -1
- package/dist/capabilities/index.js +23 -0
- package/dist/capabilities/runtime.d.ts +8 -0
- package/dist/connections/cipher.d.ts +103 -0
- package/dist/connections/cipher.js +141 -0
- package/dist/connections/index.d.ts +156 -0
- package/dist/connections/index.js +72 -0
- package/dist/connections/oauth/client.d.ts +84 -0
- package/dist/connections/oauth/client.js +141 -0
- package/dist/connections/oauth/index.d.ts +166 -0
- package/dist/connections/oauth/index.js +226 -0
- package/dist/connections/oauth/service.d.ts +90 -0
- package/dist/connections/oauth/service.js +132 -0
- package/dist/connections/pause.d.ts +68 -0
- package/dist/connections/pause.js +97 -0
- package/dist/connections/resolver.d.ts +59 -0
- package/dist/connections/resolver.js +138 -0
- package/dist/connections/resume.d.ts +64 -0
- package/dist/connections/resume.js +99 -0
- package/dist/connections/vault-cipher.d.ts +95 -0
- package/dist/connections/vault-cipher.js +206 -0
- package/dist/core/budget.d.ts +55 -0
- package/dist/core/budget.js +56 -0
- package/dist/core/content-parts.d.ts +26 -2
- package/dist/core/content-parts.js +1 -0
- package/dist/core/context.d.ts +25 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.js +15 -0
- package/dist/core/events.d.ts +110 -2
- package/dist/core/events.js +33 -2
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/validation.js +19 -0
- package/dist/documents/index.d.ts +14 -0
- package/dist/documents/parsers/text.d.ts +16 -0
- package/dist/documents/parsers/text.js +54 -2
- package/dist/entries/connections.d.ts +10 -0
- package/dist/entries/connections.js +10 -0
- package/dist/entries/guardrails.d.ts +14 -0
- package/dist/entries/guardrails.js +14 -0
- package/dist/entries/knowledge.d.ts +17 -0
- package/dist/entries/knowledge.js +16 -0
- package/dist/entries/mcp-server.d.ts +9 -0
- package/dist/entries/mcp-server.js +9 -0
- package/dist/entries/runtime.d.ts +10 -0
- package/dist/entries/runtime.js +8 -0
- package/dist/entries/testing.d.ts +28 -0
- package/dist/entries/testing.js +28 -0
- package/dist/graphql/resolvers.d.ts +7 -1
- package/dist/graphql/resolvers.js +20 -0
- package/dist/graphql/schema.d.ts +1 -1
- package/dist/graphql/schema.js +44 -0
- package/dist/guardrails/index.d.ts +115 -0
- package/dist/guardrails/index.js +108 -0
- package/dist/guardrails/moderation.d.ts +53 -0
- package/dist/guardrails/moderation.js +75 -0
- package/dist/guardrails/pii.d.ts +75 -0
- package/dist/guardrails/pii.js +193 -0
- package/dist/knowledge/communities.d.ts +166 -0
- package/dist/knowledge/communities.js +377 -0
- package/dist/knowledge/graph-global.d.ts +153 -0
- package/dist/knowledge/graph-global.js +246 -0
- package/dist/knowledge/graph-retrieval.d.ts +150 -0
- package/dist/knowledge/graph-retrieval.js +303 -0
- package/dist/knowledge/graph.d.ts +223 -0
- package/dist/knowledge/graph.js +369 -0
- package/dist/knowledge/index.d.ts +25 -0
- package/dist/knowledge/index.js +37 -1
- package/dist/knowledge/navigate.d.ts +89 -0
- package/dist/knowledge/navigate.js +107 -0
- package/dist/knowledge/retrieval.d.ts +98 -5
- package/dist/knowledge/retrieval.js +158 -28
- package/dist/mcp-server/index.d.ts +168 -0
- package/dist/mcp-server/index.js +175 -0
- package/dist/models/extraction.d.ts +73 -0
- package/dist/models/extraction.js +118 -0
- package/dist/models/index.d.ts +40 -1
- package/dist/models/index.js +22 -1
- package/dist/models/pricing.d.ts +2 -0
- package/dist/models/pricing.js +17 -1
- package/dist/models/provider-factory.js +9 -7
- package/dist/models/streaming.d.ts +111 -1
- package/dist/models/streaming.js +184 -3
- package/dist/persistence/index.d.ts +230 -0
- package/dist/persistence/index.js +2 -0
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +12 -0
- package/dist/runtime/worker.d.ts +36 -1
- package/dist/runtime/worker.js +37 -4
- package/dist/security/checklist.js +55 -0
- package/dist/security/findings.js +18 -9
- package/dist/server/bin.d.ts +19 -0
- package/dist/server/bin.js +226 -0
- package/dist/server/boot.d.ts +20 -2
- package/dist/server/boot.js +29 -3
- package/dist/server/cli.d.ts +13 -0
- package/dist/server/cli.js +7 -4
- package/dist/server/doctor.d.ts +74 -0
- package/dist/server/doctor.js +280 -0
- package/dist/skills/catalogue.d.ts +49 -0
- package/dist/skills/catalogue.js +61 -0
- package/dist/skills/context.d.ts +61 -0
- package/dist/skills/context.js +107 -0
- package/dist/skills/index.d.ts +2 -0
- package/dist/skills/index.js +2 -0
- package/dist/telemetry/spans.js +17 -0
- package/dist/testing/conformance/artifact-exports.d.ts +20 -0
- package/dist/testing/conformance/artifact-exports.js +172 -0
- package/dist/testing/conformance/artifacts.d.ts +11 -0
- package/dist/testing/conformance/artifacts.js +316 -0
- package/dist/testing/conformance/audio.d.ts +38 -0
- package/dist/testing/conformance/audio.js +145 -0
- package/dist/testing/conformance/capability.d.ts +23 -0
- package/dist/testing/conformance/capability.js +27 -0
- package/dist/testing/conformance/checkpoint-store.d.ts +15 -0
- package/dist/testing/conformance/checkpoint-store.js +72 -0
- package/dist/testing/conformance/connections.d.ts +14 -0
- package/dist/testing/conformance/connections.js +171 -0
- package/dist/testing/conformance/conversation-store.d.ts +10 -0
- package/dist/testing/conformance/conversation-store.js +60 -0
- package/dist/testing/conformance/evaluation.d.ts +10 -0
- package/dist/testing/conformance/evaluation.js +295 -0
- package/dist/testing/conformance/files.d.ts +19 -0
- package/dist/testing/conformance/files.js +454 -0
- package/dist/testing/conformance/flows.d.ts +16 -0
- package/dist/testing/conformance/flows.js +193 -0
- package/dist/testing/conformance/graph.d.ts +22 -0
- package/dist/testing/conformance/graph.js +500 -0
- package/dist/testing/conformance/hitl.d.ts +25 -0
- package/dist/testing/conformance/hitl.js +523 -0
- package/dist/testing/conformance/index.d.ts +163 -0
- package/dist/testing/conformance/index.js +321 -0
- package/dist/testing/conformance/invariants.d.ts +23 -0
- package/dist/testing/conformance/invariants.js +80 -0
- package/dist/testing/conformance/knowledge.d.ts +41 -0
- package/dist/testing/conformance/knowledge.js +592 -0
- package/dist/testing/conformance/parents.d.ts +50 -0
- package/dist/testing/conformance/parents.js +39 -0
- package/dist/testing/conformance/rate-limit.d.ts +25 -0
- package/dist/testing/conformance/rate-limit.js +71 -0
- package/dist/testing/conformance/records.d.ts +36 -0
- package/dist/testing/conformance/records.js +400 -0
- package/dist/testing/conformance/rollups.d.ts +30 -0
- package/dist/testing/conformance/rollups.js +425 -0
- package/dist/testing/conformance/run-coordinator.d.ts +27 -0
- package/dist/testing/conformance/run-coordinator.js +150 -0
- package/dist/testing/conformance/run-event-log.d.ts +9 -0
- package/dist/testing/conformance/run-event-log.js +138 -0
- package/dist/testing/conformance/run-store.d.ts +12 -0
- package/dist/testing/conformance/run-store.js +294 -0
- package/dist/testing/conformance/session-state.d.ts +38 -0
- package/dist/testing/conformance/session-state.js +198 -0
- package/dist/testing/conformance/usage-limits.d.ts +10 -0
- package/dist/testing/conformance/usage-limits.js +309 -0
- package/dist/testing/conformance.d.ts +8 -0
- package/dist/testing/conformance.js +8 -0
- package/dist/testing/memory-backend.d.ts +39 -0
- package/dist/testing/memory-backend.js +41 -0
- package/dist/testing/pglite.d.ts +55 -0
- package/dist/testing/pglite.js +78 -0
- package/dist/testing/stub-model.d.ts +58 -0
- package/dist/testing/stub-model.js +71 -0
- package/dist/testing/supabase-storage-double.d.ts +35 -0
- package/dist/testing/supabase-storage-double.js +101 -0
- package/dist/toolkit/files.d.ts +125 -0
- package/dist/toolkit/files.js +320 -0
- package/dist/toolkit/http.d.ts +27 -0
- package/dist/toolkit/http.js +48 -0
- package/dist/toolkit/index.d.ts +31 -1
- package/dist/toolkit/index.js +26 -1
- package/dist/toolkit/mime.d.ts +97 -0
- package/dist/toolkit/mime.js +233 -0
- package/dist/toolkit/sandbox.d.ts +119 -0
- package/dist/toolkit/sandbox.js +239 -0
- package/dist/toolkit/ssrf.d.ts +139 -0
- package/dist/toolkit/ssrf.js +349 -0
- package/dist/toolkit/vendor.d.ts +91 -0
- package/dist/toolkit/vendor.js +153 -0
- package/dist/toolkit/web.d.ts +13 -0
- package/dist/toolkit/web.js +7 -1
- package/dist/tools/budget.d.ts +28 -0
- package/dist/tools/budget.js +35 -0
- package/dist/tools/credentials.d.ts +316 -0
- package/dist/tools/credentials.js +369 -0
- package/dist/tools/define.d.ts +45 -0
- package/dist/tools/define.js +26 -0
- package/dist/tools/find.d.ts +109 -0
- package/dist/tools/find.js +210 -0
- package/dist/tools/index.d.ts +35 -2
- package/dist/tools/index.js +11 -0
- package/dist/tools/library/audio.d.ts +63 -0
- package/dist/tools/library/audio.js +148 -0
- package/dist/tools/library/fs.d.ts +24 -0
- package/dist/tools/library/fs.js +102 -0
- package/dist/tools/library/index.d.ts +37 -2
- package/dist/tools/library/index.js +47 -0
- package/dist/tools/library/shell.d.ts +45 -0
- package/dist/tools/library/shell.js +70 -0
- package/dist/tools/meta-tools.js +8 -0
- package/dist/tools/registry.d.ts +146 -0
- package/dist/tools/registry.js +250 -4
- package/dist/usage/index.d.ts +21 -0
- package/dist/usage/index.js +1 -0
- package/dist/usage/rate-limit.d.ts +122 -0
- package/dist/usage/rate-limit.js +131 -0
- package/dist/usage/recorder.js +3 -0
- 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
|
package/dist/tools/meta-tools.js
CHANGED
|
@@ -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."),
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -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;
|