@intentface/latch-agent-builder 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,559 @@
1
+ import { tool } from "ai";
2
+ import { z } from "zod";
3
+ import { defineAgent } from "@intentface/latch-core";
4
+ import { AgentRecordSchema, AgentScopeSchema, normalizeAgentName, normalizeAgentRecord } from "./record";
5
+ import { sharedReadTools } from "./shared-read-tools";
6
+ /**
7
+ * The Agent Builder — a meta-agent that designs, creates, and updates other
8
+ * agents on behalf of the user it's talking to. Its tools are host functions
9
+ * bound to that user's principal (via `toolSources.open`), so everything it
10
+ * writes lands at the user's own scope through the host-supplied store.
11
+ * Reads connections/models/history to make grounded proposals.
12
+ *
13
+ * Mutations (save/delete) are gated with `user-approval`, so the user sees and
14
+ * confirms the exact spec before it persists.
15
+ *
16
+ * The core is host-agnostic: models, connections, storage, and the runtime
17
+ * arrive through `AgentBuilderConfig.deps`; optional feature sets (evals,
18
+ * tool authoring) arrive as `extensions`.
19
+ */
20
+ const SCOPE = AgentScopeSchema;
21
+ /**
22
+ * save_agent's input IS the record schema (`./record`) — the model, a host
23
+ * editor, and a host validator all speak one shape. Capability flags live
24
+ * under `exec.*`; host-only rules (reserved names, which flags exist here) are
25
+ * checked in the tool below.
26
+ */
27
+ const SAVE_INPUT = AgentRecordSchema;
28
+ /** The `exec` bullet, built from what the host actually supports. */
29
+ function capabilitiesBullet(support) {
30
+ const offered = [];
31
+ if (support.sandbox !== false)
32
+ offered.push("sandbox (workspace + file/shell tools)");
33
+ if (support.providerWebTools !== false)
34
+ offered.push("providerWebTools (native web search/fetch)");
35
+ if (support.renderTools !== false)
36
+ offered.push("renderTools (headless-browser page render/fetch)");
37
+ const dt = support.defaultTools;
38
+ if (dt !== false) {
39
+ offered.push(typeof dt === "object" ? `defaultTools (${dt.description})` : "defaultTools (web_fetch + askUser)");
40
+ }
41
+ // Opt-IN (unlike the rest): only hosts that gate writes and honor the
42
+ // waiver should offer it — a host with ungated writes would save a no-op.
43
+ const paw = support.preApprovedWrites;
44
+ if (paw) {
45
+ offered.push(typeof paw === "object"
46
+ ? `preApprovedWrites (${paw.description})`
47
+ : "preApprovedWrites (writes skip the per-call approval pause — the save approval is the consent; only for unattended/scheduled agents, requires defaultTools)");
48
+ }
49
+ // Opt-in too: needs a memory provider composed into the host runtime.
50
+ const mem = support.memory;
51
+ if (mem) {
52
+ offered.push(typeof mem === "object"
53
+ ? `memory (${mem.description})`
54
+ : "memory ({ scope, connection, extractTo?, schemas? } — persistent cross-session memory in one of the agent's connections; 'agent-org' needs an org-scoped agent)");
55
+ }
56
+ const effort = "effort (\"minimal\" | \"low\" | \"medium\" | \"high\" — ONLY for a model where list_models shows reasoning=true; lower = faster/cheaper, higher = deeper; omit for the provider default)";
57
+ return offered.length
58
+ ? `- exec: capability flags, all optional — ${offered.join(", ")}, ${effort}. These are the ONLY capabilities that exist here — never promise behavior outside them (agents run as request-scoped turns; there are no persistent/background processes).`
59
+ : `- exec: only ${effort}. No other capabilities exist in this host — never promise behavior outside the fields above.`;
60
+ }
61
+ const SCHEDULING_PROMPT = `SCHEDULING (schedule_agent / list_schedules / unschedule_agent):
62
+ An agent runs as one TURN per trigger — it cannot loop in the background. For "do X every …" or "do X at …", save the agent to do X ONCE per run, then put it on a schedule.
63
+ - schedule_agent takes the agent name, a prompt (the message each fire sends it), and a cron expression — croner syntax, 5 fields (minute-level) or 6 with leading seconds — interpreted in the given IANA timezone (default UTC). Omit cron for a ONE-SHOT that fires on the next tick. It pauses for the user's approval (a schedule spends money unattended).
64
+ - Design scheduled agents to complete in one self-contained turn from the schedule's prompt alone. NOTE: a scheduled run has no user watching — if it hits an approval-gated (write) tool it PAUSES until the user reviews that chat, so warn the user when scheduling a write-capable agent.
65
+ - list_schedules shows the user's schedules; unschedule_agent (approval-gated) removes one by id.`;
66
+ function buildBaseInstructions(support, scheduling) {
67
+ return `You are the Agent Builder. You design, CREATE, and update agents on behalf of the user you're talking to. Everything you make belongs to that user, at their personal or org scope.
68
+
69
+ WHAT AN AGENT IS — the fields you set with save_agent:
70
+ - name: unique kebab-case id (e.g. "support-triage"). Reusing a name UPDATES that agent.
71
+ - title / description: short labels for the picker.
72
+ - modelId: MUST be one returned by list_models — never invent one.
73
+ - instructions: the system prompt, the heart of the agent. Spend most of your effort here: role, scope, tone, which tools to use and when, and edge cases. A great agent is mostly a great prompt.
74
+ - connections: integration names from list_connections. Only wire ones that exist; prefer authorized ones. Use list_connection_tools to see what a connection offers.
75
+ ${capabilitiesBullet(support)}
76
+ - subagents: names of other agents this one may delegate to.
77
+ - scope: "user" (personal) or "org" (shared with the whole org).
78
+ ${scheduling ? `\n${SCHEDULING_PROMPT}\n` : ""}
79
+ WORKFLOW:
80
+ 1. Understand the goal. If it's vague, ask a few sharp questions first (purpose, behavior, integrations, tone).
81
+ 2. Discover before proposing: call list_models and list_connections (and list_connection_tools for any you'll wire).
82
+ 3. ALWAYS ask whether the agent should be personal (user) or org-shared before saving — scope is required and you must not guess it.
83
+ 4. Propose: summarize the agent in plain language (name, model, connections, key instruction points) and get a quick confirmation.
84
+ 5. Call save_agent. It pauses for the user's approval — they'll see the full spec; that's expected.
85
+ 6. TEST IT: after saving, offer to test_agent with a realistic message. Read the answer + tool calls it returns, and tell the user how it did. If it's off (wrong tone, missed a tool, weak reasoning), refine the instructions and save_agent again, then re-test — iterate until it's good. test_agent blocks mutating tools by default (no real side effects); only pass live=true if the user explicitly wants a real end-to-end run.
86
+ 7. Confirm it's ready and that they can pick it from the agent list.
87
+
88
+ MODIFYING an existing agent: call get_agent first, change only what's needed, then save_agent with the SAME name and scope. Re-test with test_agent to confirm the change had the intended effect.
89
+
90
+ USING HISTORY: when the user refers to past work ("make an agent like in that chat"), use list_chats + read_chat to read the relevant conversation and ground the prompt/connections in what actually happened.
91
+
92
+ RULES:
93
+ - You can only create/edit the user's own agents (those from list_agents → yourAgents). Built-in agents are read-only references — inspect for inspiration, don't overwrite their names.
94
+ - Never invent a modelId or connection name. Only use values from list_models / list_connections.
95
+ - NEVER promise behavior the fields above can't express. No background loops, no timers inside an agent${scheduling ? " — recurring behavior is a SCHEDULE (see SCHEDULING)" : ""}.
96
+ - delete_agent is destructive and pauses for approval; only call it when the user clearly asks.`;
97
+ }
98
+ /**
99
+ * Chain a result through every extension's decorator of the given kind.
100
+ * A throwing hook is isolated: decoration runs AFTER the mutation persisted,
101
+ * so a decorator failure must not turn a successful save/test into a reported
102
+ * error — keep the last good result and log the hook failure.
103
+ */
104
+ async function decorate(extensions, kind, principal, agentName, result) {
105
+ let out = result;
106
+ for (const ext of extensions) {
107
+ const hook = ext[kind];
108
+ if (!hook)
109
+ continue;
110
+ try {
111
+ out = await hook(principal, agentName, out);
112
+ }
113
+ catch (error) {
114
+ console.warn(`agent-builder: extension "${ext.name}" ${kind} failed; keeping undecorated result:`, error);
115
+ }
116
+ }
117
+ return out;
118
+ }
119
+ /** Build the management toolset bound to one principal + the live host services. */
120
+ async function builderTools(principal, config) {
121
+ const deps = await config.deps(principal);
122
+ const { runtime, store, models, listConnections, connectionTools } = deps;
123
+ const extensions = config.extensions ?? [];
124
+ const support = config.capabilities ?? {};
125
+ const scheduling = config.scheduling !== false;
126
+ const reserved = new Set([
127
+ ...(config.reservedNames ?? []),
128
+ ...extensions.flatMap((e) => e.reservedNames ?? []),
129
+ ]);
130
+ const authoredToolsSupported = extensions.some((e) => e.handlesAuthoredTools);
131
+ /** Reject capability flags this host never wired (silent no-ops otherwise). */
132
+ const unsupportedCapabilities = (exec) => {
133
+ const asked = [
134
+ ["sandbox", exec?.sandbox, support.sandbox !== false],
135
+ ["providerWebTools", exec?.providerWebTools, support.providerWebTools !== false],
136
+ ["renderTools", exec?.renderTools, support.renderTools !== false],
137
+ ["defaultTools", exec?.defaultTools, support.defaultTools !== false],
138
+ // Opt-in (see capabilitiesBullet): unsupported unless declared.
139
+ ["preApprovedWrites", exec?.preApprovedWrites, !!support.preApprovedWrites],
140
+ ["memory", exec?.memory, !!support.memory],
141
+ ];
142
+ return asked.filter(([, on, ok]) => on && !ok).map(([name]) => name);
143
+ };
144
+ const extensionTools = {};
145
+ for (const ext of extensions) {
146
+ if (ext.tools)
147
+ Object.assign(extensionTools, await ext.tools(principal));
148
+ }
149
+ return {
150
+ // get_agent / list_connection_tools — shared with delegate agents (e.g.
151
+ // an eval author) so the implementations can't drift.
152
+ ...sharedReadTools(principal, { store, connectionTools }),
153
+ list_agents: tool({
154
+ description: "List the user's own (editable) agents plus the names of all available agents.",
155
+ inputSchema: z.object({}),
156
+ execute: async () => {
157
+ const records = await store.listRecords(principal);
158
+ const all = await runtime.listAgents(principal);
159
+ return {
160
+ yourAgents: records.map((r) => ({
161
+ name: r.name,
162
+ scope: r.scope,
163
+ title: r.title,
164
+ description: r.description,
165
+ modelId: r.modelId,
166
+ connections: r.connections,
167
+ exec: r.exec,
168
+ })),
169
+ allAgentNames: all.map((a) => a.name),
170
+ note: "Only 'yourAgents' can be edited. Other names are built-in, read-only references.",
171
+ };
172
+ },
173
+ }),
174
+ list_models: tool({
175
+ description: "Available model ids to choose from (use one of these for modelId).",
176
+ inputSchema: z.object({}),
177
+ execute: async () => models.map((m) => ({ id: m.id, label: m.label, provider: m.provider, reasoning: !!m.reasoning })),
178
+ }),
179
+ list_connections: tool({
180
+ description: "Connections the user can wire to an agent, with whether they're authorized. Prefer authorized ones.",
181
+ inputSchema: z.object({}),
182
+ execute: async () => listConnections(principal),
183
+ }),
184
+ list_chats: tool({
185
+ description: "The user's recent chats (to read history and base an agent on past work).",
186
+ inputSchema: z.object({ limit: z.number().optional() }),
187
+ execute: async ({ limit }) => {
188
+ const chats = await runtime.listChats({ principal, limit: limit ?? 20 });
189
+ return chats
190
+ .filter((c) => !c.id.startsWith("sub_"))
191
+ .map((c) => ({ id: c.id, title: c.title ?? null, agent: c.agent, updatedAt: c.updatedAt }));
192
+ },
193
+ }),
194
+ read_chat: tool({
195
+ description: "Read one chat's messages (role + text) to inform prompts or connection choices.",
196
+ inputSchema: z.object({ chatId: z.string() }),
197
+ execute: async ({ chatId }) => {
198
+ const messages = await runtime.loadHistory({ chatId, principal });
199
+ return messages.map((m) => ({
200
+ role: m.role ?? "unknown",
201
+ text: (m.parts ?? [])
202
+ .filter((p) => p.type === "text" && p.text)
203
+ .map((p) => p.text)
204
+ .join("\n")
205
+ .slice(0, 4000),
206
+ }));
207
+ },
208
+ }),
209
+ save_agent: tool({
210
+ description: "Create a new agent or update an existing one (upsert by name). Pauses for the user's approval.",
211
+ inputSchema: SAVE_INPUT,
212
+ execute: async (raw) => {
213
+ // Re-validate here as well as at the SDK boundary: it applies the
214
+ // schema's defaults and the host-independent invariants (memory
215
+ // connection wired, agent-org ⇒ org scope, index outlines) even when a
216
+ // host calls the tool directly, and reports violations as a tool
217
+ // error the model can act on instead of a thrown ZodError.
218
+ const parsed = SAVE_INPUT.safeParse(raw);
219
+ if (!parsed.success) {
220
+ return {
221
+ error: `Invalid agent: ${parsed.error.issues.map((i) => `${i.path.join(".") || "record"}: ${i.message}`).join("; ")}`,
222
+ };
223
+ }
224
+ // Canonicalize, then apply THIS host's policy.
225
+ const rec = normalizeAgentRecord(parsed.data);
226
+ const name = rec.name;
227
+ if (!name)
228
+ return { error: "invalid name" };
229
+ if (reserved.has(name)) {
230
+ return { error: `"${name}" is a built-in agent and can't be overwritten — pick another name.` };
231
+ }
232
+ if (!models.some((m) => m.id === rec.modelId)) {
233
+ return { error: `Unknown modelId "${rec.modelId}". Call list_models and use one of those.` };
234
+ }
235
+ // `effort` is a no-op on non-reasoning models — reject like the
236
+ // capability flags instead of persisting a setting that does nothing.
237
+ if (rec.exec?.effort && !models.find((m) => m.id === rec.modelId)?.reasoning) {
238
+ return {
239
+ error: `Model "${rec.modelId}" is not reasoning-capable (list_models shows reasoning=false) — omit exec.effort or pick a reasoning model.`,
240
+ };
241
+ }
242
+ // Reject hallucinated references — only names the discovery tools return.
243
+ const knownConnections = new Set((await listConnections(principal)).map((c) => c.name));
244
+ const badConn = rec.connections.filter((n) => !knownConnections.has(n));
245
+ if (badConn.length) {
246
+ return { error: `Unknown connection(s): ${badConn.join(", ")}. Use list_connections.` };
247
+ }
248
+ const knownAgents = new Set((await runtime.listAgents(principal)).map((a) => a.name));
249
+ const badSub = (rec.subagents ?? []).filter((n) => !knownAgents.has(n) && n !== name);
250
+ if (badSub.length) {
251
+ return { error: `Unknown subagent(s): ${badSub.join(", ")}. Use list_agents.` };
252
+ }
253
+ // Authored tools only exist where an extension provides them — a clear
254
+ // rejection beats silently dropping a capability the model asked for.
255
+ if (rec.exec?.authoredTools?.length && !authoredToolsSupported) {
256
+ return { error: "Tool authoring is not available here — omit exec.authoredTools." };
257
+ }
258
+ // Same for capability flags the host never wired: rejecting beats
259
+ // persisting a silent no-op the user believes in.
260
+ const unsupported = unsupportedCapabilities(rec.exec);
261
+ if (unsupported.length) {
262
+ return {
263
+ error: `Not available in this host: ${unsupported.join(", ")}. Omit ${unsupported.length > 1 ? "them" : "it"} — and don't promise the user that behavior.`,
264
+ };
265
+ }
266
+ // The write waiver without write tools is meaningless — likely a
267
+ // misunderstanding worth surfacing rather than persisting.
268
+ if (rec.exec?.preApprovedWrites && !rec.exec?.defaultTools) {
269
+ return {
270
+ error: "exec.preApprovedWrites requires exec.defaultTools (the write capability) — there are no writes to waive without it.",
271
+ };
272
+ }
273
+ // The builder speaks the record's model-facing fields. Per-tool
274
+ // selections (`tools`) and attached evals are managed by other
275
+ // surfaces (an editor, an evals feature) — carry them over when the
276
+ // input doesn't mention them, so a save never silently detaches them.
277
+ // Pinned to the record's own scope: a same-named agent in the other
278
+ // scope must not donate its state.
279
+ const existing = await store.getRecord(principal, `${rec.scope}:${name}`);
280
+ const merged = {
281
+ ...rec,
282
+ tools: rec.tools ?? existing?.tools,
283
+ attachedEvals: rec.attachedEvals ?? existing?.attachedEvals,
284
+ };
285
+ // Extension vetoes (e.g. tool-authoring existence + org-scope rules).
286
+ for (const ext of extensions) {
287
+ const veto = await ext.validateSave?.(principal, merged);
288
+ if (veto)
289
+ return { error: veto };
290
+ }
291
+ await store.upsert(principal, merged);
292
+ return decorate(extensions, "decorateSaveResult", principal, name, {
293
+ saved: true,
294
+ name,
295
+ scope: rec.scope,
296
+ note: "Available now in the agent picker.",
297
+ });
298
+ },
299
+ }),
300
+ delete_agent: tool({
301
+ description: "Delete one of the user's agents, along with the user's schedules that fire it (an orphaned schedule would error on every tick). Destructive — pauses for the user's approval.",
302
+ inputSchema: z.object({ name: z.string(), scope: SCOPE }),
303
+ execute: async ({ name, scope }) => {
304
+ const target = normalizeAgentName(name);
305
+ await store.remove(principal, scope, target);
306
+ // Cascade: the CALLER's schedules for this agent — regardless of
307
+ // whether THIS builder offers schedule tools (`scheduling`): schedules
308
+ // can exist from other surfaces, and an orphan errors on every tick.
309
+ // Schedules are per-principal, so an org-shared agent may still have
310
+ // other members' schedules — surface that instead of pretending. The
311
+ // agent is already deleted at this point, so a failing unschedule must
312
+ // not reject the tool (the model would report a failed delete) —
313
+ // collect and report partial failures instead.
314
+ let removedSchedules = 0;
315
+ const scheduleCleanupFailures = [];
316
+ let mine = [];
317
+ let listFailed = false;
318
+ try {
319
+ mine = (await runtime.listSchedules({ principal })).filter((s) => s.agent === target);
320
+ }
321
+ catch (error) {
322
+ listFailed = true;
323
+ console.warn(`agent-builder: delete_agent could not list schedules for ${target}:`, error);
324
+ }
325
+ for (const s of mine) {
326
+ try {
327
+ await runtime.unschedule({ principal, id: s.id });
328
+ removedSchedules++;
329
+ }
330
+ catch (error) {
331
+ scheduleCleanupFailures.push(s.id);
332
+ console.warn(`agent-builder: delete_agent cascade failed to unschedule ${s.id}:`, error);
333
+ }
334
+ }
335
+ return {
336
+ deleted: target,
337
+ scope,
338
+ removedSchedules,
339
+ ...(listFailed
340
+ ? {
341
+ warning: "The agent is deleted, but its schedules could not be listed — check list_schedules and remove any that still name it.",
342
+ }
343
+ : {}),
344
+ ...(scheduleCleanupFailures.length
345
+ ? {
346
+ scheduleCleanupFailures,
347
+ warning: `The agent is deleted, but ${scheduleCleanupFailures.length} schedule(s) could not be removed and will error on fire — retry with unschedule_agent: ${scheduleCleanupFailures.join(", ")}.`,
348
+ }
349
+ : {}),
350
+ ...(scope === "org"
351
+ ? {
352
+ note: "Org-shared agent: other members' schedules for it (if any) are not visible here — they will error on fire until those members unschedule them.",
353
+ }
354
+ : {}),
355
+ };
356
+ },
357
+ }),
358
+ ...(scheduling
359
+ ? {
360
+ schedule_agent: tool({
361
+ description: "Put an agent on a schedule: each fire sends it the prompt as a fresh, self-contained turn. Recurring via a cron expression, or one-shot (omit cron) on the next tick. Pauses for the user's approval — a schedule runs unattended and spends money.",
362
+ inputSchema: z.object({
363
+ agent: z.string().describe("Agent name (from list_agents)."),
364
+ prompt: z.string().describe("The message each fire sends the agent. Self-contained — no conversation context exists at fire time."),
365
+ cron: z
366
+ .string()
367
+ .optional()
368
+ .describe('Croner expression, 5 fields or 6 with leading seconds (e.g. "0 9 * * *" = daily 9am, "*/30 * * * * *" = every 30s). Omit for a one-shot.'),
369
+ timezone: z.string().optional().describe('IANA timezone the cron is interpreted in (e.g. "Europe/Helsinki"). Default UTC.'),
370
+ }),
371
+ execute: async ({ agent, prompt, cron, timezone }) => {
372
+ try {
373
+ const rec = await runtime.schedule({
374
+ principal,
375
+ agent: normalizeAgentName(agent),
376
+ prompt,
377
+ cron: cron ?? null,
378
+ timezone,
379
+ });
380
+ return {
381
+ scheduled: true,
382
+ id: rec.id,
383
+ agent: rec.agent,
384
+ cron: rec.cron ?? "one-shot",
385
+ nextRunAt: new Date(rec.nextRunAt).toISOString(),
386
+ note: "Manage it with list_schedules / unschedule_agent.",
387
+ };
388
+ }
389
+ catch (e) {
390
+ return { error: `Could not schedule: ${e instanceof Error ? e.message : String(e)}` };
391
+ }
392
+ },
393
+ }),
394
+ list_schedules: tool({
395
+ description: "The user's scheduled agent runs (id, agent, cadence, next fire).",
396
+ inputSchema: z.object({}),
397
+ execute: async () => {
398
+ const schedules = await runtime.listSchedules({ principal });
399
+ return schedules.map((s) => ({
400
+ id: s.id,
401
+ agent: s.agent,
402
+ cron: s.cron ?? "one-shot",
403
+ timezone: s.timezone ?? "UTC",
404
+ prompt: s.prompt,
405
+ enabled: s.enabled,
406
+ nextRunAt: s.enabled ? new Date(s.nextRunAt).toISOString() : null,
407
+ lastRunAt: s.lastRunAt ? new Date(s.lastRunAt).toISOString() : null,
408
+ }));
409
+ },
410
+ }),
411
+ unschedule_agent: tool({
412
+ description: "Remove one of the user's schedules by id (from list_schedules). Pauses for the user's approval.",
413
+ inputSchema: z.object({ id: z.string() }),
414
+ execute: async ({ id }) => {
415
+ // `unschedule` returns void and silently ignores unknown ids —
416
+ // pre-check so the result is truthful. (Lookup + delete isn't
417
+ // atomic; the worst case of the race is a stale success for an
418
+ // id that was concurrently deleted anyway.)
419
+ const exists = (await runtime.listSchedules({ principal })).some((s) => s.id === id);
420
+ if (!exists) {
421
+ return { error: `No schedule "${id}" — check list_schedules.` };
422
+ }
423
+ await runtime.unschedule({ principal, id });
424
+ return { unscheduled: id };
425
+ },
426
+ }),
427
+ }
428
+ : {}),
429
+ test_agent: tool({
430
+ description: "Run one of the user's agents once with a test message and get its answer plus which tools it called — so you can verify behavior and refine the prompt. In the default safe mode, APPROVAL-GATED tools are blocked (return a 'blocked' marker). NOTE: tools that are NOT approval-gated still execute for real — they may perform real fetch side effects (e.g. a POST). Set live=true only when the user explicitly wants a full real run. A web-heavy agent's test can take MINUTES (each fetch is a full page read) — warn the user before testing one.",
431
+ inputSchema: z.object({
432
+ name: z.string().describe("Agent name to test."),
433
+ message: z.string().describe("The test user message to send it."),
434
+ live: z
435
+ .boolean()
436
+ .optional()
437
+ .describe("true → real run (mutating tools execute). Default false → safe (mutations blocked)."),
438
+ }),
439
+ execute: async ({ name, message, live }, options) => {
440
+ // Normalize like every other tool — stored names are normalized.
441
+ const target = normalizeAgentName(name);
442
+ // The nested run is one long, otherwise-SILENT await inside this
443
+ // turn — minutes for a web-heavy agent. Emit a small heartbeat data
444
+ // part on an interval: it keeps idle-timeout proxies from killing
445
+ // the chat stream, and gives the user live progress instead of dead
446
+ // air. Reconciled in place by id (one part, updated), like
447
+ // latch-platform's eval progress card.
448
+ const env = (options ?? {});
449
+ const startedAt = Date.now();
450
+ const writeHeartbeat = () => {
451
+ env.context?.writer?.write({
452
+ type: "data-test-agent-progress",
453
+ id: `testprog_${env.toolCallId ?? "run"}`,
454
+ data: {
455
+ toolCallId: env.toolCallId,
456
+ agent: target,
457
+ elapsedSec: Math.round((Date.now() - startedAt) / 1000),
458
+ },
459
+ });
460
+ };
461
+ // Guard the configured cadence: 0/negative/NaN would spin the writer.
462
+ const cadence = Number.isFinite(config.testHeartbeatMs) && config.testHeartbeatMs >= 10
463
+ ? config.testHeartbeatMs
464
+ : 10_000;
465
+ const heartbeat = setInterval(writeHeartbeat, cadence);
466
+ let threadId;
467
+ let answer;
468
+ try {
469
+ writeHeartbeat();
470
+ ({ threadId, answer } = await runtime.runAgent({
471
+ principal,
472
+ agent: target,
473
+ prompt: message,
474
+ blockGated: !live,
475
+ }));
476
+ }
477
+ catch (error) {
478
+ // Surface the REAL failure — a generic tool error invites the
479
+ // model to confabulate reassuring explanations.
480
+ return {
481
+ error: `test run of "${target}" failed: ${error instanceof Error ? error.message : String(error)}`,
482
+ };
483
+ }
484
+ finally {
485
+ clearInterval(heartbeat);
486
+ }
487
+ const history = await runtime.loadHistory({ chatId: threadId, principal });
488
+ const toolCalls = [];
489
+ for (const m of history) {
490
+ for (const p of (m.parts ?? [])) {
491
+ const type = p.type;
492
+ if (!type)
493
+ continue;
494
+ if (type === "dynamic-tool" || type.startsWith("tool-")) {
495
+ const toolName = typeof p.toolName === "string"
496
+ ? p.toolName
497
+ : type.startsWith("tool-")
498
+ ? type.slice(5)
499
+ : "unknown";
500
+ const blocked = p.output?.__blocked;
501
+ toolCalls.push({ tool: toolName, blocked: blocked || undefined });
502
+ }
503
+ }
504
+ }
505
+ return decorate(extensions, "decorateTestResult", principal, target, {
506
+ answer,
507
+ toolCalls,
508
+ mode: live ? "live" : "safe (mutating tools blocked)",
509
+ });
510
+ },
511
+ }),
512
+ ...extensionTools,
513
+ };
514
+ }
515
+ /**
516
+ * Create the Agent Builder as a standard agent factory for the host's
517
+ * registry: `agents: { "agent-builder": createAgentBuilder({...}) }`.
518
+ */
519
+ export function createAgentBuilder(config) {
520
+ const extensions = config.extensions ?? [];
521
+ const scheduling = config.scheduling !== false;
522
+ const instructions = [
523
+ buildBaseInstructions(config.capabilities ?? {}, scheduling),
524
+ ...extensions.flatMap((e) => e.promptSections ?? []),
525
+ ].join("\n\n");
526
+ const subagents = [...new Set(extensions.flatMap((e) => e.subagents ?? []))];
527
+ const toolApproval = {
528
+ // Approve every persisting mutation: the user sees and confirms the exact spec.
529
+ save_agent: "user-approval",
530
+ delete_agent: "user-approval",
531
+ // A schedule runs unattended and spends money; removal is destructive.
532
+ ...(scheduling
533
+ ? { schedule_agent: "user-approval", unschedule_agent: "user-approval" }
534
+ : {}),
535
+ };
536
+ for (const ext of extensions)
537
+ Object.assign(toolApproval, ext.toolApproval ?? {});
538
+ return defineAgent(async ({ context, principal }) => ({
539
+ model: typeof config.model === "function"
540
+ ? await config.model({ context, principal })
541
+ : config.model,
542
+ instructions,
543
+ ...(subagents.length ? { subagents } : {}),
544
+ // Host tools bound to the chatting user's principal.
545
+ toolSources: [
546
+ {
547
+ async open(p) {
548
+ return { tools: await builderTools(p, config), close: async () => { } };
549
+ },
550
+ },
551
+ ],
552
+ toolApproval,
553
+ smoothStream: true,
554
+ }), config.meta ?? {
555
+ title: "Agent Builder",
556
+ description: "Designs, creates, and updates your agents from a conversation.",
557
+ });
558
+ }
559
+ //# sourceMappingURL=agent-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-builder.js","sourceRoot":"","sources":["../src/agent-builder.ts"],"names":[],"mappings":"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"}