@poncho-ai/harness 0.37.2 → 0.39.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/harness",
3
- "version": "0.37.2",
3
+ "version": "0.39.0",
4
4
  "description": "Agent execution runtime - conversation loop, tool dispatch, streaming",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "mustache": "^4.2.0",
35
35
  "yaml": "^2.4.0",
36
36
  "zod": "^3.22.0",
37
- "@poncho-ai/sdk": "1.8.1"
37
+ "@poncho-ai/sdk": "1.9.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "esbuild": ">=0.17.0",
package/src/harness.ts CHANGED
@@ -12,7 +12,13 @@ import type {
12
12
  ToolContext,
13
13
  ToolDefinition,
14
14
  } from "@poncho-ai/sdk";
15
- import { defineTool, getTextContent } from "@poncho-ai/sdk";
15
+ import { defineTool, getTextContent, createLogger, formatError as fmtErr, url as urlColor } from "@poncho-ai/sdk";
16
+
17
+ const harnessLog = createLogger("harness");
18
+ const telemetryLog = createLogger("telemetry");
19
+ const costLog = createLogger("cost");
20
+ const mcpLog = createLogger("mcp");
21
+ const modelLog = createLogger("model");
16
22
  import type { UploadStore } from "./upload-store.js";
17
23
  import { PONCHO_UPLOAD_SCHEME, VFS_SCHEME, deriveUploadKey } from "./upload-store.js";
18
24
  import type { StorageEngine } from "./storage/engine.js";
@@ -812,8 +818,8 @@ export class AgentHarness {
812
818
  const toolResultId = typeof input.toolResultId === "string" ? input.toolResultId : "";
813
819
  const record = archive[toolResultId];
814
820
  if (!record) {
815
- console.info(
816
- `[poncho][cost] Archived tool result lookup miss: id="${toolResultId}" conversation="${conversationId}"`,
821
+ costLog.debug(
822
+ `archived tool result miss: id="${toolResultId}" conv=${conversationId.slice(0, 8)}`,
817
823
  );
818
824
  return {
819
825
  error: `No archived tool result found for id "${toolResultId}" in this conversation.`,
@@ -823,8 +829,8 @@ export class AgentHarness {
823
829
  const limit = Math.min(Math.max(Number(input.limit) || 6000, 1), 20_000);
824
830
  const end = Math.min(record.payload.length, offset + limit);
825
831
  const chunk = record.payload.slice(offset, end);
826
- console.info(
827
- `[poncho][cost] Archived tool result lookup hit: id="${toolResultId}" conversation="${conversationId}" ` +
832
+ costLog.debug(
833
+ `archived tool result hit: id="${toolResultId}" conv=${conversationId.slice(0, 8)} ` +
828
834
  `offset=${offset} returned=${chunk.length} total=${record.payload.length}`,
829
835
  );
830
836
  return {
@@ -1267,9 +1273,7 @@ export class AgentHarness {
1267
1273
  this.dispatcher.unregisterMany(this.registeredMcpToolNames);
1268
1274
  this.registeredMcpToolNames.clear();
1269
1275
  if (requestedPatterns.length === 0) {
1270
- console.info(
1271
- `[poncho][mcp] ${JSON.stringify({ event: "tools.cleared", reason, requestedPatterns })}`,
1272
- );
1276
+ mcpLog.debug(`tools cleared (reason=${reason})`);
1273
1277
  return;
1274
1278
  }
1275
1279
  const tools = await this.mcpBridge.loadTools(requestedPatterns);
@@ -1277,14 +1281,8 @@ export class AgentHarness {
1277
1281
  for (const tool of tools) {
1278
1282
  this.registeredMcpToolNames.add(tool.name);
1279
1283
  }
1280
- console.info(
1281
- `[poncho][mcp] ${JSON.stringify({
1282
- event: "tools.refreshed",
1283
- reason,
1284
- requestedPatterns,
1285
- registeredCount: tools.length,
1286
- activeSkills: this.listActiveSkills(),
1287
- })}`,
1284
+ mcpLog.debug(
1285
+ `tools refreshed (reason=${reason}, registered=${tools.length}, patterns=${requestedPatterns.length})`,
1288
1286
  );
1289
1287
  }
1290
1288
 
@@ -1358,11 +1356,7 @@ export class AgentHarness {
1358
1356
  this.agentFileFingerprint = rawContent;
1359
1357
  return true;
1360
1358
  } catch (error) {
1361
- console.warn(
1362
- `[poncho][agent] Failed to refresh AGENT.md in development mode: ${
1363
- error instanceof Error ? error.message : String(error)
1364
- }`,
1365
- );
1359
+ createLogger("agent").warn(`failed to refresh AGENT.md in dev: ${fmtErr(error)}`);
1366
1360
  return false;
1367
1361
  }
1368
1362
  }
@@ -1417,11 +1411,7 @@ export class AgentHarness {
1417
1411
  await this.refreshMcpTools("skills:changed");
1418
1412
  return true;
1419
1413
  } catch (error) {
1420
- console.warn(
1421
- `[poncho][skills] Failed to refresh skills in development mode: ${
1422
- error instanceof Error ? error.message : String(error)
1423
- }`,
1424
- );
1414
+ createLogger("skills").warn(`failed to refresh skills in dev: ${fmtErr(error)}`);
1425
1415
  return false;
1426
1416
  }
1427
1417
  }
@@ -1477,9 +1467,10 @@ export class AgentHarness {
1477
1467
  );
1478
1468
  // Register VFS tools
1479
1469
  this.registerIfMissing(createBashTool(this.bashManager));
1480
- this.registerIfMissing(createReadFileTool(engine));
1481
- this.registerIfMissing(createEditFileTool(engine));
1482
- this.registerIfMissing(createWriteFileTool(engine));
1470
+ const getFs = (tenantId: string) => this.bashManager!.getFs(tenantId);
1471
+ this.registerIfMissing(createReadFileTool(getFs));
1472
+ this.registerIfMissing(createEditFileTool(getFs));
1473
+ this.registerIfMissing(createWriteFileTool(getFs));
1483
1474
 
1484
1475
  // --- Isolate (V8 sandboxed code execution) ---
1485
1476
  if (config?.isolate) {
@@ -1531,9 +1522,7 @@ export class AgentHarness {
1531
1522
  if (config?.browser) {
1532
1523
  await this.initBrowserTools(config)
1533
1524
  .catch((e) => {
1534
- console.warn(
1535
- `[poncho][browser] Failed to load browser tools: ${e instanceof Error ? e.message : String(e)}`,
1536
- );
1525
+ createLogger("browser").warn(`failed to load browser tools: ${fmtErr(e)}`);
1537
1526
  });
1538
1527
  }
1539
1528
 
@@ -1568,7 +1557,7 @@ export class AgentHarness {
1568
1557
  provider.register();
1569
1558
  this.otlpTracerProvider = provider;
1570
1559
  this.hasOtlpExporter = true;
1571
- console.info(`[poncho][telemetry] OTLP trace exporter active → ${otlpConfig.url}`);
1560
+ telemetryLog.item(`OTLP trace exporter active → ${urlColor(otlpConfig.url)}`);
1572
1561
  }
1573
1562
  }
1574
1563
 
@@ -1695,13 +1684,13 @@ export class AgentHarness {
1695
1684
  await this.mcpBridge?.stopLocalServers();
1696
1685
  if (this.otlpSpanProcessor) {
1697
1686
  await this.otlpSpanProcessor.shutdown().catch((err) => {
1698
- console.warn(`[poncho][telemetry] OTLP span processor shutdown error: ${formatOtlpError(err)}`);
1687
+ telemetryLog.warn(`OTLP span processor shutdown error: ${formatOtlpError(err)}`);
1699
1688
  });
1700
1689
  this.otlpSpanProcessor = undefined;
1701
1690
  }
1702
1691
  if (this.otlpTracerProvider) {
1703
1692
  await this.otlpTracerProvider.shutdown().catch((err) => {
1704
- console.warn(`[poncho][telemetry] OTLP tracer provider shutdown error: ${formatOtlpError(err)}`);
1693
+ telemetryLog.warn(`OTLP tracer provider shutdown error: ${formatOtlpError(err)}`);
1705
1694
  });
1706
1695
  this.otlpTracerProvider = undefined;
1707
1696
  }
@@ -1761,7 +1750,7 @@ export class AgentHarness {
1761
1750
  await this.otlpSpanProcessor?.forceFlush();
1762
1751
  } catch (err: unknown) {
1763
1752
  const detail = formatOtlpError(err);
1764
- console.warn(`[poncho][telemetry] OTLP span flush failed: ${detail}`);
1753
+ telemetryLog.warn(`OTLP span flush failed: ${detail}`);
1765
1754
  }
1766
1755
  }
1767
1756
  } else {
@@ -1825,23 +1814,17 @@ export class AgentHarness {
1825
1814
  this.seedToolResultArchive(conversationId, input.parameters);
1826
1815
  const truncationSummary = this.truncateHistoricalToolResults(messages, conversationId);
1827
1816
  if (truncationSummary.changed) {
1828
- console.info(
1829
- `[poncho][cost] Truncated ${truncationSummary.truncatedCount} historical tool result(s) ` +
1830
- `(archived_new=${truncationSummary.archivedCount}, omitted_chars=${truncationSummary.omittedChars}) ` +
1831
- `for conversation="${conversationId}"`,
1817
+ costLog.debug(
1818
+ `truncated ${truncationSummary.truncatedCount} historical tool result(s) ` +
1819
+ `(archived=${truncationSummary.archivedCount}, omitted=${truncationSummary.omittedChars} chars) ` +
1820
+ `conv=${conversationId.slice(0, 8)}`,
1832
1821
  );
1833
1822
  }
1834
1823
  const hasFullToolResults = hasUntruncatedToolResults(messages);
1835
1824
  if (hasFullToolResults) {
1836
- console.info(
1837
- `[poncho][cost] Prompt cache breakpoint will be placed before untruncated ` +
1838
- `tool results for run "${runId}" (stable prefix only).`,
1839
- );
1825
+ costLog.debug(`cache breakpoint before untruncated tool results (run=${runId.slice(0, 12)})`);
1840
1826
  } else {
1841
- console.info(
1842
- `[poncho][cost] Prompt cache breakpoint will be placed at history tail ` +
1843
- `for run "${runId}" (no untruncated tool results).`,
1844
- );
1827
+ costLog.debug(`cache breakpoint at history tail (run=${runId.slice(0, 12)})`);
1845
1828
  }
1846
1829
  const inputMessageCount = messages.length;
1847
1830
  const events: AgentEvent[] = [];
@@ -2422,7 +2405,7 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2422
2405
 
2423
2406
  const modelName = agent.frontmatter.model?.name ?? "claude-opus-4-5";
2424
2407
  if (step === 1) {
2425
- console.info(`[poncho] model="${modelName}" provider="${agent.frontmatter.model?.provider ?? "anthropic"}"`);
2408
+ modelLog.item(`${modelName} (provider=${agent.frontmatter.model?.provider ?? "anthropic"})`);
2426
2409
  }
2427
2410
  const modelInstance = this.modelProvider(modelName);
2428
2411
 
@@ -2550,8 +2533,8 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2550
2533
  message: `Model "${modelName}" did not respond within the ${Math.floor(timeoutMs / 1000)}s run timeout.`,
2551
2534
  },
2552
2535
  });
2553
- console.error(
2554
- `[poncho][harness] Stream timeout: model="${modelName}", step=${step}, elapsed=${now() - start}ms`,
2536
+ harnessLog.error(
2537
+ `stream timeout: model=${modelName} step=${step} elapsed=${now() - start}ms`,
2555
2538
  );
2556
2539
  return;
2557
2540
  }
@@ -2587,8 +2570,8 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2587
2570
  break;
2588
2571
  }
2589
2572
  const isFirstChunk = chunkCount === 0;
2590
- console.error(
2591
- `[poncho][harness] Stream timeout waiting for ${isFirstChunk ? "first" : "next"} chunk: model="${modelName}", step=${step}, chunks=${chunkCount}, elapsed=${now() - start}ms`,
2573
+ harnessLog.error(
2574
+ `stream timeout waiting for ${isFirstChunk ? "first" : "next"} chunk: model=${modelName} step=${step} chunks=${chunkCount} elapsed=${now() - start}ms`,
2592
2575
  );
2593
2576
  if (isFirstChunk) {
2594
2577
  throw new FirstChunkTimeoutError(modelName, FIRST_CHUNK_TIMEOUT_MS);
@@ -2645,7 +2628,7 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2645
2628
  contextTokens: latestContextTokens + toolOutputEstimateSinceModel,
2646
2629
  contextWindow,
2647
2630
  };
2648
- console.info(`[poncho][harness] Soft deadline fired mid-stream at step ${step} (${(now() - start).toFixed(0)}ms). Checkpointing with ${fullText.length} chars of partial text.`);
2631
+ harnessLog.info(`soft deadline fired mid-stream at step ${step} (${(now() - start).toFixed(0)}ms); checkpointing with ${fullText.length} chars of partial text`);
2649
2632
  yield pushEvent({ type: "run:completed", runId, result: result_ });
2650
2633
  return;
2651
2634
  }
@@ -2698,9 +2681,7 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2698
2681
  message: `Model "${modelName}" returned an error. This may indicate the model is not supported by the current provider SDK version, or the API returned an error response.`,
2699
2682
  },
2700
2683
  });
2701
- console.error(
2702
- `[poncho][harness] Model error: finishReason="error", model="${modelName}", step=${step}`,
2703
- );
2684
+ harnessLog.error(`model error: finishReason="error" model=${modelName} step=${step}`);
2704
2685
  return;
2705
2686
  }
2706
2687
 
@@ -2749,11 +2730,10 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2749
2730
  cacheWrite: stepCacheWriteTokens,
2750
2731
  },
2751
2732
  });
2752
- console.info(
2753
- `[poncho][cost] model="${modelName}" step=${step} ` +
2754
- `input=${stepInputTokens} output=${usage.outputTokens ?? 0} ` +
2755
- `cached=${stepCachedTokens} cacheWrite=${stepCacheWriteTokens} ` +
2756
- `totals(input=${totalInputTokens}, output=${totalOutputTokens}, cached=${totalCachedTokens}, cacheWrite=${totalCacheWriteTokens})`,
2733
+ costLog.debug(
2734
+ `step=${step} in=${stepInputTokens} out=${usage.outputTokens ?? 0} ` +
2735
+ `cached=${stepCachedTokens} cw=${stepCacheWriteTokens} ` +
2736
+ `totals(in=${totalInputTokens} out=${totalOutputTokens} cached=${totalCachedTokens} cw=${totalCacheWriteTokens})`,
2757
2737
  );
2758
2738
 
2759
2739
  // Extract tool calls
@@ -2778,14 +2758,10 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
2778
2758
  message: `Model "${modelName}" returned no content (finish reason: ${finishReason}). The model may not be supported by the current provider SDK version.`,
2779
2759
  },
2780
2760
  });
2781
- console.error(
2782
- `[poncho][harness] Empty response: finishReason="${finishReason}", model="${modelName}", step=${step}`,
2783
- );
2761
+ harnessLog.error(`empty response: finishReason="${finishReason}" model=${modelName} step=${step}`);
2784
2762
  return;
2785
2763
  }
2786
- console.warn(
2787
- `[poncho][harness] Model "${modelName}" returned an empty response with finishReason="stop" on step ${step}.`,
2788
- );
2764
+ harnessLog.warn(`model "${modelName}" returned empty response with finishReason="stop" on step ${step}`);
2789
2765
  }
2790
2766
  if (fullText.length > 0) {
2791
2767
  messages.push({
@@ -3217,10 +3193,10 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
3217
3193
  if (isRetryableModelError(error) && transientStepRetryCount < MAX_TRANSIENT_STEP_RETRIES) {
3218
3194
  transientStepRetryCount += 1;
3219
3195
  const statusCode = getErrorStatusCode(error);
3220
- console.warn(
3221
- `[poncho][harness] Retrying step ${step} after transient model error (attempt ${transientStepRetryCount}/${MAX_TRANSIENT_STEP_RETRIES})${
3196
+ harnessLog.warn(
3197
+ `retrying step ${step} after transient model error (attempt ${transientStepRetryCount}/${MAX_TRANSIENT_STEP_RETRIES})${
3222
3198
  typeof statusCode === "number" ? ` status=${statusCode}` : ""
3223
- }: ${error instanceof Error ? error.message : String(error)}`,
3199
+ }: ${fmtErr(error)}`,
3224
3200
  );
3225
3201
  step -= 1;
3226
3202
  continue;
@@ -3231,7 +3207,7 @@ Code is wrapped in an async IIFE — use \`return\` to return a value to the too
3231
3207
  runId,
3232
3208
  error: runError,
3233
3209
  });
3234
- console.error(`[poncho][harness] Step ${step} error:`, error);
3210
+ harnessLog.error(`step ${step} error: ${fmtErr(error)}`);
3235
3211
  return;
3236
3212
  }
3237
3213
  }
package/src/index.ts CHANGED
@@ -27,5 +27,6 @@ export * from "./tenant-token.js";
27
27
  export * from "./tool-dispatcher.js";
28
28
  export * from "./subagent-manager.js";
29
29
  export * from "./subagent-tools.js";
30
+ export * from "./orchestrator/index.js";
30
31
  export { defineTool } from "@poncho-ai/sdk";
31
32
  export type { ToolDefinition } from "@poncho-ai/sdk";
@@ -3,8 +3,11 @@ import { resolve } from "node:path";
3
3
  import { pathToFileURL } from "node:url";
4
4
  import { createJiti } from "jiti";
5
5
  import type { ToolDefinition } from "@poncho-ai/sdk";
6
+ import { createLogger } from "@poncho-ai/sdk";
6
7
  import { resolveSkillDirs } from "./skill-context.js";
7
8
 
9
+ const toolsLog = createLogger("tools");
10
+
8
11
  const TOOL_FILE_PATTERN = /\.(?:[cm]?js|[cm]?ts)$/i;
9
12
 
10
13
  const collectToolFiles = async (directory: string): Promise<string[]> => {
@@ -94,9 +97,7 @@ export const loadLocalSkillTools = async (
94
97
  tools.push(...normalizeToolExports(loaded));
95
98
  } catch (error) {
96
99
  const message = error instanceof Error ? error.message : String(error);
97
- process.stderr.write(
98
- `[poncho] Skipping skill tool module ${filePath}: ${message}\n`,
99
- );
100
+ toolsLog.warn(`skipping skill tool module ${filePath}: ${message}`);
100
101
  }
101
102
  }
102
103
 
package/src/mcp.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import type { ToolDefinition } from "@poncho-ai/sdk";
2
+ import { createLogger } from "@poncho-ai/sdk";
2
3
  import {
3
4
  matchesSlashPattern,
4
5
  validateMcpPattern,
5
6
  } from "./tool-policy.js";
6
7
 
8
+ const mcpLog = createLogger("mcp");
9
+
7
10
  export interface RemoteMcpServerConfig {
8
11
  name?: string;
9
12
  url: string;
@@ -317,12 +320,12 @@ export class LocalMcpBridge {
317
320
  }
318
321
 
319
322
  private log(level: "info" | "warn", event: string, payload: Record<string, unknown>): void {
320
- const line = JSON.stringify({ event, ...payload });
321
- if (level === "warn") {
322
- console.warn(`[poncho][mcp] ${line}`);
323
- return;
324
- }
325
- console.info(`[poncho][mcp] ${line}`);
323
+ const summary = Object.entries(payload)
324
+ .map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`)
325
+ .join(" ");
326
+ const msg = summary ? `${event} ${summary}` : event;
327
+ if (level === "warn") mcpLog.warn(msg);
328
+ else mcpLog.debug(msg);
326
329
  }
327
330
 
328
331
  /** Set of servers where discovery was deferred (no default token, has env resolver). */
@@ -0,0 +1,13 @@
1
+ import type { Conversation } from "../state.js";
2
+
3
+ export const TOOL_RESULT_ARCHIVE_PARAM = "__toolResultArchive";
4
+
5
+ export const withToolResultArchiveParam = (
6
+ parameters: Record<string, unknown> | undefined,
7
+ conversation: Conversation,
8
+ ): Record<string, unknown> => ({
9
+ ...(parameters ?? {}),
10
+ [TOOL_RESULT_ARCHIVE_PARAM]: conversation._toolResultArchive ?? {},
11
+ });
12
+
13
+ export const MAX_CONTINUATION_COUNT = 20;
@@ -0,0 +1,69 @@
1
+ import type { Message } from "@poncho-ai/sdk";
2
+ import type { Conversation } from "../state.js";
3
+
4
+ export type HistorySource = "harness" | "continuation" | "messages";
5
+
6
+ export type RunRequest = {
7
+ conversationId: string;
8
+ messages: Message[];
9
+ preferContinuation?: boolean;
10
+ };
11
+
12
+ export type RunOutcome = {
13
+ source: HistorySource;
14
+ shouldRebuildCanonical: boolean;
15
+ messages: Message[];
16
+ };
17
+
18
+ export const isMessageArray = (value: unknown): value is Message[] =>
19
+ Array.isArray(value) &&
20
+ value.every((entry) => {
21
+ if (!entry || typeof entry !== "object") return false;
22
+ const row = entry as Record<string, unknown>;
23
+ const role = row.role;
24
+ const content = row.content;
25
+ const roleOk = role === "system" || role === "user" || role === "assistant" || role === "tool";
26
+ const contentOk = typeof content === "string" || Array.isArray(content);
27
+ return roleOk && contentOk;
28
+ });
29
+
30
+ export const loadCanonicalHistory = (
31
+ conversation: Conversation,
32
+ ): { messages: Message[]; source: HistorySource } => {
33
+ if (isMessageArray(conversation._harnessMessages) && conversation._harnessMessages.length > 0) {
34
+ return { messages: [...conversation._harnessMessages], source: "harness" };
35
+ }
36
+ return { messages: [...conversation.messages], source: "messages" };
37
+ };
38
+
39
+ export const loadRunHistory = (
40
+ conversation: Conversation,
41
+ options?: { preferContinuation?: boolean },
42
+ ): { messages: Message[]; source: HistorySource; shouldRebuildCanonical: boolean } => {
43
+ if (options?.preferContinuation && isMessageArray(conversation._continuationMessages) && conversation._continuationMessages.length > 0) {
44
+ return {
45
+ messages: [...conversation._continuationMessages],
46
+ source: "continuation",
47
+ shouldRebuildCanonical: !isMessageArray(conversation._harnessMessages) || conversation._harnessMessages.length === 0,
48
+ };
49
+ }
50
+ const canonical = loadCanonicalHistory(conversation);
51
+ return {
52
+ ...canonical,
53
+ shouldRebuildCanonical: canonical.source !== "harness",
54
+ };
55
+ };
56
+
57
+ export const resolveRunRequest = (
58
+ conversation: Conversation,
59
+ request: RunRequest,
60
+ ): RunOutcome => {
61
+ const resolved = loadRunHistory(conversation, {
62
+ preferContinuation: request.preferContinuation,
63
+ });
64
+ return {
65
+ source: resolved.source,
66
+ shouldRebuildCanonical: resolved.shouldRebuildCanonical,
67
+ messages: resolved.messages.length > 0 ? resolved.messages : request.messages,
68
+ };
69
+ };
@@ -0,0 +1,54 @@
1
+ export {
2
+ isMessageArray,
3
+ loadCanonicalHistory,
4
+ loadRunHistory,
5
+ resolveRunRequest,
6
+ type HistorySource,
7
+ type RunRequest,
8
+ type RunOutcome,
9
+ } from "./history.js";
10
+
11
+ export {
12
+ createTurnDraftState,
13
+ cloneSections,
14
+ flushTurnDraft,
15
+ buildToolCompletedText,
16
+ recordStandardTurnEvent,
17
+ buildAssistantMetadata,
18
+ executeConversationTurn,
19
+ normalizeApprovalCheckpoint,
20
+ buildApprovalCheckpoints,
21
+ applyTurnMetadata,
22
+ type StoredApproval,
23
+ type PendingToolCall,
24
+ type ApprovalEventItem,
25
+ type TurnSection,
26
+ type TurnDraftState,
27
+ type ExecuteTurnResult,
28
+ type TurnResultMetadata,
29
+ } from "./turn.js";
30
+
31
+ export {
32
+ TOOL_RESULT_ARCHIVE_PARAM,
33
+ withToolResultArchiveParam,
34
+ MAX_CONTINUATION_COUNT,
35
+ } from "./continuation.js";
36
+
37
+ export {
38
+ type ActiveSubagentRun,
39
+ type PendingSubagentApproval,
40
+ MAX_SUBAGENT_NESTING,
41
+ MAX_CONCURRENT_SUBAGENTS,
42
+ MAX_SUBAGENT_CALLBACK_COUNT,
43
+ CALLBACK_LOCK_STALE_MS,
44
+ STALE_SUBAGENT_THRESHOLD_MS,
45
+ } from "./subagents.js";
46
+
47
+ export {
48
+ AgentOrchestrator,
49
+ type ActiveConversationRun,
50
+ type EventSink,
51
+ type OrchestratorHooks,
52
+ type ContinuationHooks,
53
+ type OrchestratorOptions,
54
+ } from "./orchestrator.js";