@andreprado/agentkit 0.1.0-alpha.2 → 0.1.0-alpha.20
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 +67 -6
- package/docs/guides/add-channel.md +118 -7
- package/docs/guides/add-knowledge.md +144 -0
- package/docs/guides/add-managed-composio.md +163 -0
- package/docs/guides/add-tool.md +1 -1
- package/docs/guides/channel-security.md +97 -32
- package/docs/guides/connect-discord.md +178 -0
- package/docs/guides/connect-slack.md +126 -0
- package/docs/guides/connect-telegram.md +78 -1
- package/docs/guides/connect-whatsapp-zapster.md +112 -8
- package/docs/guides/create-agent.md +45 -4
- package/docs/guides/debug-channel.md +147 -0
- package/docs/guides/improve-from-production.md +151 -0
- package/docs/guides/prepare-deploy.md +47 -17
- package/docs/guides/replay-production-traces.md +72 -0
- package/docs/guides/run-evals.md +147 -20
- package/docs/guides/security-rules.md +7 -6
- package/docs/guides/send-feedback.md +135 -0
- package/docs/guides/use-provider.md +27 -3
- package/docs/llms-full.txt +303 -55
- package/docs/llms.txt +57 -7
- package/package.json +2 -5
- package/src/cli/args.ts +57 -0
- package/src/cli/cloud-client.ts +377 -0
- package/src/cli/commands/channels.ts +1315 -0
- package/src/cli/commands/feedback.ts +438 -0
- package/src/cli/commands/knowledge.ts +136 -0
- package/src/cli/commands/transcribe.ts +171 -0
- package/src/cli/constants.ts +4 -0
- package/src/cli/deploy-chat-ui.ts +535 -0
- package/src/cli/deploy-readiness.ts +481 -0
- package/src/cli/flags.ts +162 -0
- package/src/cli/help.ts +236 -0
- package/src/cli/index.ts +1167 -1005
- package/src/cli/process.ts +31 -0
- package/src/cloud/artifact.ts +139 -0
- package/src/cloud/client.ts +80 -0
- package/src/cloud/contracts.ts +63 -0
- package/src/cloud/index.ts +3 -0
- package/src/create-project.ts +21 -6
- package/src/index.ts +479 -7
- package/src/providers/pi.ts +70 -16
- package/src/providers/test.ts +88 -1
- package/src/providers/types.ts +7 -0
- package/src/runtime/channel-buffer.ts +30 -0
- package/src/runtime/channel-test-harness.ts +8 -1
- package/src/runtime/channels/discord.ts +896 -0
- package/src/runtime/channels/slack.ts +646 -0
- package/src/runtime/channels/telegram.ts +466 -23
- package/src/runtime/channels/whatsapp-meta.ts +9 -0
- package/src/runtime/channels/whatsapp-zapster.ts +677 -40
- package/src/runtime/channels.ts +86 -3
- package/src/runtime/chat.ts +130 -38
- package/src/runtime/config.ts +483 -18
- package/src/runtime/core/manifest.ts +103 -5
- package/src/runtime/core/targets.ts +5 -5
- package/src/runtime/database.ts +93 -2
- package/src/runtime/db-commands.ts +9 -0
- package/src/runtime/deploy-readiness.ts +46 -4
- package/src/runtime/deploy.ts +1 -1
- package/src/runtime/dev-server.ts +759 -41
- package/src/runtime/env.ts +8 -3
- package/src/runtime/evals.ts +589 -43
- package/src/runtime/improve.ts +868 -0
- package/src/runtime/inspect.ts +194 -4
- package/src/runtime/integrations/composio.ts +423 -0
- package/src/runtime/knowledge/chunk.ts +333 -0
- package/src/runtime/knowledge/config.ts +135 -0
- package/src/runtime/knowledge/embeddings.ts +133 -0
- package/src/runtime/knowledge/ingest.ts +521 -0
- package/src/runtime/knowledge/prompt-policy.ts +30 -0
- package/src/runtime/knowledge/retrieve.ts +303 -0
- package/src/runtime/knowledge/schema.ts +100 -0
- package/src/runtime/knowledge/tool.ts +64 -0
- package/src/runtime/knowledge/vector.ts +258 -0
- package/src/runtime/prompt-context.ts +141 -0
- package/src/runtime/runtime-contract.ts +86 -8
- package/src/runtime/skills.ts +95 -0
- package/src/runtime/spec.ts +152 -0
- package/src/runtime/sync.ts +144 -0
- package/src/runtime/targets/cloudflare/build.ts +1430 -185
- package/src/runtime/targets/container/server.ts +1 -1
- package/src/runtime/targets/vps/deploy.ts +26 -9
- package/src/runtime/tool-runner.ts +9 -1
- package/src/runtime/tools.ts +128 -2
- package/src/runtime/traces.ts +41 -0
- package/src/runtime/transcription.ts +483 -0
- package/src/storage/sqlite.ts +149 -3
- package/src/templates/blank.ts +76 -17
- package/src/templates/dentista.ts +1011 -0
- package/src/templates/index.ts +2 -0
- package/src/templates/skills/agentkit-build-agent/SKILL.md +52 -0
- package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +21 -0
- package/src/templates/skills/agentkit-build-agent/templates/sales-qualifier.instructions.md +17 -0
- package/src/templates/skills/agentkit-build-agent/templates/support-agent.instructions.md +16 -0
- package/src/templates/skills/agentkit-capsule/SKILL.md +70 -0
- package/src/templates/skills/agentkit-capsule/references/docs-router.md +15 -0
- package/src/templates/skills/agentkit-channels/SKILL.md +104 -0
- package/src/templates/skills/agentkit-channels/references/channel-buffering.md +65 -0
- package/src/templates/skills/agentkit-channels/references/channel-debugging.md +66 -0
- package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
- package/src/templates/skills/agentkit-channels/references/slack.md +56 -0
- package/src/templates/skills/agentkit-channels/references/telegram.md +72 -0
- package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +77 -0
- package/src/templates/skills/agentkit-database/SKILL.md +45 -0
- package/src/templates/skills/agentkit-database/templates/appointments.schema.sql +15 -0
- package/src/templates/skills/agentkit-database/templates/leads.schema.sql +17 -0
- package/src/templates/skills/agentkit-deploy/SKILL.md +50 -0
- package/src/templates/skills/agentkit-evals/SKILL.md +109 -0
- package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +29 -0
- package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +18 -0
- package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +18 -0
- package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +27 -0
- package/src/templates/skills/agentkit-improve/SKILL.md +86 -0
- package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
- package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
- package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
- package/src/templates/skills/agentkit-integrations/SKILL.md +76 -0
- package/src/templates/skills/agentkit-knowledge/SKILL.md +43 -0
- package/src/templates/skills/agentkit-knowledge/templates/faq.md +14 -0
- package/src/templates/skills/agentkit-knowledge/templates/policies.md +14 -0
- package/src/templates/skills/agentkit-knowledge/templates/prices.csv +3 -0
- package/src/templates/skills/agentkit-prompts/SKILL.md +47 -0
- package/src/templates/skills/agentkit-prompts/templates/knowledge-grounded-faq.instructions.md +11 -0
- package/src/templates/skills/agentkit-provider/SKILL.md +60 -0
- package/src/templates/skills/agentkit-security/SKILL.md +56 -0
- package/src/templates/skills/agentkit-tools/SKILL.md +37 -0
- package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +35 -0
- package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +37 -0
- package/src/templates/skills/agentkit-tools/examples/lookup-order.tool.md +46 -0
- package/src/templates/skills/agentkit-troubleshooting/SKILL.md +76 -0
- package/src/templates/support.ts +77 -18
- package/docs/guides/channels-production-handoff.md +0 -99
- package/docs/portable-deploy-release-checklist.md +0 -41
- package/src/runtime/targets/cloudflare/deploy.ts +0 -5475
|
@@ -12,7 +12,7 @@ export async function startContainerRuntime(options: ContainerRuntimeOptions = {
|
|
|
12
12
|
const capsuleRoot = resolve(options.capsuleRoot ?? process.env.AGENTKIT_CAPSULE_ROOT ?? process.cwd());
|
|
13
13
|
const hostname = options.hostname ?? process.env.HOST ?? "0.0.0.0";
|
|
14
14
|
const port = options.port ?? parsePort(process.env.PORT) ?? 4123;
|
|
15
|
-
return startAgentDevServer(capsuleRoot, { hostname, port });
|
|
15
|
+
return startAgentDevServer(capsuleRoot, { hostname, port, access: "enforce" });
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function parsePort(value: string | undefined): number | undefined {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
1
|
+
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
4
|
import type { LocalDeployState } from "../../core/deploy-state";
|
|
@@ -38,15 +38,19 @@ export async function prepareVpsDeploy(
|
|
|
38
38
|
const manifest = JSON.parse(await readFile(container.manifestPath, "utf8")) as {
|
|
39
39
|
name: string;
|
|
40
40
|
secrets: string[];
|
|
41
|
+
access: {
|
|
42
|
+
mode: "private" | "token" | "public";
|
|
43
|
+
};
|
|
41
44
|
};
|
|
42
45
|
|
|
43
46
|
await mkdir(buildDir, { recursive: true });
|
|
44
47
|
const envExample = renderEnvExample(manifest.secrets);
|
|
45
48
|
await writeFile(composePath, renderCompose(manifest.name));
|
|
46
49
|
await writeFile(envExamplePath, envExample);
|
|
47
|
-
await writeFile(envPath, envExample);
|
|
50
|
+
await writeFile(envPath, envExample, { mode: 0o600 });
|
|
51
|
+
await chmod(envPath, 0o600);
|
|
48
52
|
await writeFile(secretsPath, renderSecretsChecklist(manifest.secrets));
|
|
49
|
-
await writeFile(handoffPath, renderProductionHandoff(options.host, manifest.name));
|
|
53
|
+
await writeFile(handoffPath, renderProductionHandoff(options.host, manifest.name, manifest.access.mode));
|
|
50
54
|
|
|
51
55
|
const state: LocalDeployState = {
|
|
52
56
|
deploy_id: `vps_${slugify(manifest.name)}`,
|
|
@@ -71,7 +75,8 @@ export async function prepareVpsDeploy(
|
|
|
71
75
|
},
|
|
72
76
|
created_at: new Date().toISOString(),
|
|
73
77
|
};
|
|
74
|
-
await writeFile(statePath, `${JSON.stringify(state, null, 2)}\n
|
|
78
|
+
await writeFile(statePath, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
|
|
79
|
+
await chmod(statePath, 0o600);
|
|
75
80
|
|
|
76
81
|
return {
|
|
77
82
|
target: "vps",
|
|
@@ -88,7 +93,7 @@ export async function prepareVpsDeploy(
|
|
|
88
93
|
`docker compose -f ${composePath} --env-file ${envPath} config`,
|
|
89
94
|
`docker compose -f ${composePath} --env-file ${envPath} up -d --build`,
|
|
90
95
|
`curl -fsS https://${options.host}/health`,
|
|
91
|
-
`curl -fsS https://${options.host}/_agentkit`,
|
|
96
|
+
`curl -fsS -H "Authorization: Bearer $AGENTKIT_PRIVATE_TOKEN" https://${options.host}/_agentkit`,
|
|
92
97
|
],
|
|
93
98
|
};
|
|
94
99
|
}
|
|
@@ -113,7 +118,7 @@ function renderCompose(agentName: string): string {
|
|
|
113
118
|
- agentkit_data:/data
|
|
114
119
|
- agentkit_files:/capsule/.agentkit/files
|
|
115
120
|
healthcheck:
|
|
116
|
-
test: ["CMD", "
|
|
121
|
+
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:4123/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
|
117
122
|
interval: 30s
|
|
118
123
|
timeout: 5s
|
|
119
124
|
retries: 3
|
|
@@ -145,7 +150,7 @@ ${lines}
|
|
|
145
150
|
`;
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
function renderProductionHandoff(host: string, agentName: string): string {
|
|
153
|
+
function renderProductionHandoff(host: string, agentName: string, accessMode: "private" | "token" | "public"): string {
|
|
149
154
|
return `# VPS Production Handoff
|
|
150
155
|
|
|
151
156
|
## Deploy
|
|
@@ -169,12 +174,14 @@ docker compose -f .agentkit/build/vps/compose.yaml --env-file .agentkit/build/vp
|
|
|
169
174
|
|
|
170
175
|
\`\`\`sh
|
|
171
176
|
curl -fsS https://${host}/health
|
|
172
|
-
curl -fsS https://${host}/_agentkit
|
|
177
|
+
curl -fsS -H "Authorization: Bearer $AGENTKIT_PRIVATE_TOKEN" https://${host}/_agentkit
|
|
173
178
|
curl -fsS -X POST https://${host}/chat \\
|
|
174
|
-
-H 'content-type: application/json' \\
|
|
179
|
+
-H 'content-type: application/json'${renderChatAuthHeader(accessMode)} \\
|
|
175
180
|
-d '{"message":{"role":"user","content":"hello"}}'
|
|
176
181
|
\`\`\`
|
|
177
182
|
|
|
183
|
+
Set AGENTKIT_PRIVATE_TOKEN for privileged AgentKit endpoints. Chat access follows access.mode: ${accessMode}.
|
|
184
|
+
|
|
178
185
|
## Database
|
|
179
186
|
|
|
180
187
|
- Default database: SQLite at /data/agentkit.db in the agentkit_data volume.
|
|
@@ -195,6 +202,16 @@ docker compose -f .agentkit/build/vps/compose.yaml --env-file .agentkit/build/vp
|
|
|
195
202
|
`;
|
|
196
203
|
}
|
|
197
204
|
|
|
205
|
+
function renderChatAuthHeader(accessMode: "private" | "token" | "public"): string {
|
|
206
|
+
if (accessMode === "public") {
|
|
207
|
+
return "";
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const secretName = accessMode === "private" ? "AGENTKIT_PRIVATE_TOKEN" : "AGENTKIT_ACCESS_TOKEN";
|
|
211
|
+
return ` \\
|
|
212
|
+
-H "Authorization: Bearer $${secretName}"`;
|
|
213
|
+
}
|
|
214
|
+
|
|
198
215
|
function slugify(value: string): string {
|
|
199
216
|
const slug = value
|
|
200
217
|
.toLowerCase()
|
|
@@ -2,12 +2,15 @@ import { loadAgentCapsule } from "./config";
|
|
|
2
2
|
import { openPreparedCapsuleStore } from "./database";
|
|
3
3
|
import { loadCapsuleEnv } from "./env";
|
|
4
4
|
import { isAgentKitError } from "./errors";
|
|
5
|
+
import { createManagedComposioTools } from "./integrations/composio";
|
|
6
|
+
import { buildRuntimeClockContext } from "./prompt-context";
|
|
5
7
|
import { createToolRuntime, type ToolCallResult } from "./tools";
|
|
6
8
|
|
|
7
9
|
export type RunToolOptions = {
|
|
8
10
|
name: string;
|
|
9
11
|
input?: unknown;
|
|
10
12
|
signal?: AbortSignal;
|
|
13
|
+
now?: Date;
|
|
11
14
|
};
|
|
12
15
|
|
|
13
16
|
export async function runToolFromCwd(cwd: string, options: RunToolOptions): Promise<ToolCallResult> {
|
|
@@ -24,12 +27,17 @@ export async function runToolFromCwd(cwd: string, options: RunToolOptions): Prom
|
|
|
24
27
|
model: capsule.config.provider.model,
|
|
25
28
|
});
|
|
26
29
|
const toolRuntime = createToolRuntime({
|
|
27
|
-
tools: capsule.config.tools ?? [],
|
|
30
|
+
tools: [...createManagedComposioTools(capsule.config), ...(capsule.config.tools ?? [])],
|
|
28
31
|
store,
|
|
29
32
|
runId: run.id,
|
|
30
33
|
conversationId: conversation.id,
|
|
31
34
|
env,
|
|
32
35
|
signal: options.signal,
|
|
36
|
+
clock: buildRuntimeClockContext({
|
|
37
|
+
timeZone: capsule.config.timeZone,
|
|
38
|
+
env,
|
|
39
|
+
now: options.now,
|
|
40
|
+
}),
|
|
33
41
|
runtime: {
|
|
34
42
|
environment: "local",
|
|
35
43
|
invocation: "tool",
|
package/src/runtime/tools.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { AgentTool, JsonSchema, ToolContext, ToolRuntimeContext } from "../index";
|
|
1
|
+
import type { AgentTool, JsonSchema, ToolContext, ToolRenderResult, ToolRuntimeContext } from "../index";
|
|
2
2
|
import type { SqliteAgentKitStore } from "../storage/sqlite";
|
|
3
3
|
import { createLocalDatabaseRunner } from "./database";
|
|
4
4
|
import { AgentKitError } from "./errors";
|
|
5
|
+
import type { RuntimeClockContext } from "./prompt-context";
|
|
5
6
|
|
|
6
7
|
export type ToolCallRequest = {
|
|
7
8
|
name: string;
|
|
@@ -14,6 +15,7 @@ export type ToolCallResult = {
|
|
|
14
15
|
visibility: "user" | "internal";
|
|
15
16
|
input: unknown;
|
|
16
17
|
output: unknown;
|
|
18
|
+
rendered?: ToolRenderResult;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export type ToolRuntime = {
|
|
@@ -30,6 +32,7 @@ export type ToolRuntimeOptions = {
|
|
|
30
32
|
signal?: AbortSignal;
|
|
31
33
|
defaultTimeoutMs?: number;
|
|
32
34
|
runtime: ToolRuntimeContext;
|
|
35
|
+
clock: RuntimeClockContext;
|
|
33
36
|
};
|
|
34
37
|
|
|
35
38
|
const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
|
|
@@ -88,6 +91,7 @@ async function executeToolCall(
|
|
|
88
91
|
secrets,
|
|
89
92
|
database,
|
|
90
93
|
runtime: options.runtime,
|
|
94
|
+
clock: options.clock,
|
|
91
95
|
signal: options.signal,
|
|
92
96
|
},
|
|
93
97
|
tool.timeoutMs ?? options.defaultTimeoutMs ?? DEFAULT_TOOL_TIMEOUT_MS,
|
|
@@ -97,10 +101,13 @@ async function executeToolCall(
|
|
|
97
101
|
validateSchema(output, tool.outputSchema, `tool "${tool.name}" output`);
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
const rendered = renderToolOutput(tool, input, output, options.runtime, options.clock);
|
|
105
|
+
|
|
100
106
|
options.store.completeToolCall({
|
|
101
107
|
toolCallId: toolCall.id,
|
|
102
108
|
status: "completed",
|
|
103
109
|
output,
|
|
110
|
+
rendered,
|
|
104
111
|
secretValues,
|
|
105
112
|
});
|
|
106
113
|
|
|
@@ -110,6 +117,7 @@ async function executeToolCall(
|
|
|
110
117
|
visibility: tool.visibility ?? "user",
|
|
111
118
|
input,
|
|
112
119
|
output,
|
|
120
|
+
...(rendered ? { rendered } : {}),
|
|
113
121
|
};
|
|
114
122
|
} catch (error) {
|
|
115
123
|
const secretValues = collectConfiguredSecretValues(tool, options.env ?? process.env);
|
|
@@ -125,6 +133,123 @@ async function executeToolCall(
|
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
|
|
136
|
+
function renderToolOutput(
|
|
137
|
+
tool: AgentTool,
|
|
138
|
+
input: unknown,
|
|
139
|
+
output: unknown,
|
|
140
|
+
runtime: ToolRuntimeContext,
|
|
141
|
+
clock: RuntimeClockContext,
|
|
142
|
+
): ToolRenderResult | undefined {
|
|
143
|
+
if (!tool.render) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const rendered = tool.render(output, {
|
|
148
|
+
input,
|
|
149
|
+
runtime,
|
|
150
|
+
clock,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
if (typeof rendered === "string") {
|
|
154
|
+
return { text: rendered };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!isRecord(rendered) || typeof rendered.text !== "string" || rendered.text.trim().length === 0) {
|
|
158
|
+
throw new AgentKitError("tool_validation_error", `tool "${tool.name}" render must return a non-empty text string.`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (rendered.blocks !== undefined) {
|
|
162
|
+
if (!Array.isArray(rendered.blocks)) {
|
|
163
|
+
throw new AgentKitError("tool_validation_error", `tool "${tool.name}" render.blocks must be an array when provided.`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
for (const [index, block] of rendered.blocks.entries()) {
|
|
167
|
+
validateRenderBlock(block, `tool "${tool.name}" render.blocks[${index}]`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
text: rendered.text,
|
|
173
|
+
...(rendered.blocks ? { blocks: rendered.blocks } : {}),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function validateRenderBlock(block: unknown, label: string): void {
|
|
178
|
+
if (!isRecord(block)) {
|
|
179
|
+
throw new AgentKitError("tool_validation_error", `${label} must be an object.`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (block.type === "text") {
|
|
183
|
+
if (typeof block.text !== "string" || block.text.trim().length === 0) {
|
|
184
|
+
throw new AgentKitError("tool_validation_error", `${label}.text must be a non-empty string.`);
|
|
185
|
+
}
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (block.type === "card") {
|
|
190
|
+
if (typeof block.title !== "string" || block.title.trim().length === 0) {
|
|
191
|
+
throw new AgentKitError("tool_validation_error", `${label}.title must be a non-empty string.`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
validateOptionalString(block.subtitle, `${label}.subtitle`);
|
|
195
|
+
validateRenderFields(block.fields, `${label}.fields`);
|
|
196
|
+
validateRenderActions(block.actions, `${label}.actions`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
throw new AgentKitError("tool_validation_error", `${label}.type must be "text" or "card".`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function validateRenderFields(value: unknown, label: string): void {
|
|
204
|
+
if (value === undefined) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (!Array.isArray(value)) {
|
|
209
|
+
throw new AgentKitError("tool_validation_error", `${label} must be an array when provided.`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
for (const [index, field] of value.entries()) {
|
|
213
|
+
if (!isRecord(field)) {
|
|
214
|
+
throw new AgentKitError("tool_validation_error", `${label}[${index}] must be an object.`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
validateRequiredString(field.label, `${label}[${index}].label`);
|
|
218
|
+
validateRequiredString(field.value, `${label}[${index}].value`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function validateRenderActions(value: unknown, label: string): void {
|
|
223
|
+
if (value === undefined) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (!Array.isArray(value)) {
|
|
228
|
+
throw new AgentKitError("tool_validation_error", `${label} must be an array when provided.`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
for (const [index, action] of value.entries()) {
|
|
232
|
+
if (!isRecord(action)) {
|
|
233
|
+
throw new AgentKitError("tool_validation_error", `${label}[${index}] must be an object.`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
validateRequiredString(action.label, `${label}[${index}].label`);
|
|
237
|
+
validateOptionalString(action.href, `${label}[${index}].href`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function validateRequiredString(value: unknown, label: string): void {
|
|
242
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
243
|
+
throw new AgentKitError("tool_validation_error", `${label} must be a non-empty string.`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function validateOptionalString(value: unknown, label: string): void {
|
|
248
|
+
if (value !== undefined && typeof value !== "string") {
|
|
249
|
+
throw new AgentKitError("tool_validation_error", `${label} must be a string when provided.`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
128
253
|
function resolveToolSecrets(
|
|
129
254
|
tool: AgentTool,
|
|
130
255
|
env: Record<string, string | undefined>,
|
|
@@ -158,7 +283,7 @@ function collectConfiguredSecretValues(tool: AgentTool | undefined, env: Record<
|
|
|
158
283
|
async function runToolWithTimeout(
|
|
159
284
|
tool: AgentTool,
|
|
160
285
|
input: unknown,
|
|
161
|
-
context: Pick<ToolContext, "secrets" | "database" | "runtime"> & { signal?: AbortSignal },
|
|
286
|
+
context: Pick<ToolContext, "secrets" | "database" | "runtime" | "clock"> & { signal?: AbortSignal },
|
|
162
287
|
timeoutMs: number,
|
|
163
288
|
): Promise<unknown> {
|
|
164
289
|
const controller = new AbortController();
|
|
@@ -186,6 +311,7 @@ async function runToolWithTimeout(
|
|
|
186
311
|
secrets: context.secrets,
|
|
187
312
|
signal: controller.signal,
|
|
188
313
|
runtime: context.runtime,
|
|
314
|
+
clock: context.clock,
|
|
189
315
|
database: context.database,
|
|
190
316
|
db: context.database,
|
|
191
317
|
storage: {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ConversationRecord, StoredRun, StoredToolCall } from "../storage/sqlite";
|
|
2
|
+
import { openCapsuleStore } from "../storage/sqlite";
|
|
3
|
+
import { loadAgentCapsule } from "./config";
|
|
4
|
+
import { AgentKitError } from "./errors";
|
|
5
|
+
|
|
6
|
+
export type ConversationTrace = ConversationRecord & {
|
|
7
|
+
runs: ConversationTraceRun[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ConversationTraceRun = StoredRun & {
|
|
11
|
+
toolCalls: StoredToolCall[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export async function getConversationTraceFromCwd(cwd: string, conversationId: string): Promise<ConversationTrace> {
|
|
15
|
+
if (!conversationId) {
|
|
16
|
+
throw new AgentKitError("validation_error", "Missing conversation id.");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const capsule = await loadAgentCapsule(cwd);
|
|
20
|
+
const store = await openCapsuleStore(capsule);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const conversation = store.getConversation(conversationId);
|
|
24
|
+
|
|
25
|
+
if (!conversation) {
|
|
26
|
+
throw new AgentKitError("conversation_not_found", `Conversation "${conversationId}" was not found.`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const runs = store.listRunsForConversation(conversation.id).map((run) => ({
|
|
30
|
+
...run,
|
|
31
|
+
toolCalls: store.listToolCallsForRun(run.id),
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
...conversation,
|
|
36
|
+
runs,
|
|
37
|
+
};
|
|
38
|
+
} finally {
|
|
39
|
+
store.close();
|
|
40
|
+
}
|
|
41
|
+
}
|