@sschepis/oboto-agent 0.2.3 → 0.2.4

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/dist/index.d.ts CHANGED
@@ -74,7 +74,7 @@ interface ObotoAgentConfig {
74
74
  /** as-agent Wasm runtime for slash commands and utilities */
75
75
  agentRuntime?: AgentRuntime;
76
76
  }
77
- type AgentEventType = "user_input" | "agent_thought" | "token" | "phase" | "triage_result" | "tool_execution_start" | "tool_execution_complete" | "tool_round_complete" | "state_updated" | "interruption" | "error" | "cost_update" | "turn_complete" | "permission_denied" | "session_compacted" | "hook_denied" | "hook_message" | "router_event" | "slash_command" | "doom_loop" | "heartbeat";
77
+ type AgentEventType = "user_input" | "agent_thought" | "token" | "phase" | "triage_result" | "tool_execution_start" | "tool_execution_complete" | "tool_round_complete" | "state_updated" | "interruption" | "error" | "cost_update" | "turn_complete" | "permission_denied" | "session_compacted" | "hook_denied" | "hook_message" | "router_event" | "slash_command" | "doom_loop";
78
78
  /** Phase identifiers matching the unified provider's phase system. */
79
79
  type AgentPhase = "request" | "precheck" | "planning" | "thinking" | "tools" | "validation" | "memory" | "continuation" | "error" | "doom" | "cancel" | "complete";
80
80
  /** Payload for phase events. */
@@ -82,12 +82,6 @@ interface PhaseEvent {
82
82
  phase: AgentPhase;
83
83
  message: string;
84
84
  }
85
- /** Payload for heartbeat events. */
86
- interface HeartbeatEvent {
87
- phase: AgentPhase;
88
- elapsedMs: number;
89
- message: string;
90
- }
91
85
  /** Payload for doom loop events. */
92
86
  interface DoomLoopEvent {
93
87
  reason: string;
@@ -101,6 +95,7 @@ interface ToolRoundEvent {
101
95
  tools: Array<{
102
96
  command: string;
103
97
  success: boolean;
98
+ kwargs?: Record<string, unknown>;
104
99
  durationMs?: number;
105
100
  }>;
106
101
  totalToolCalls: number;
@@ -688,7 +683,7 @@ declare class ObotoAgent {
688
683
  private maxIterations;
689
684
  private config;
690
685
  private onToken?;
691
- private costTracker?;
686
+ private costTracker;
692
687
  private modelPricing?;
693
688
  private rateLimiter?;
694
689
  private middleware;
@@ -701,8 +696,6 @@ declare class ObotoAgent {
701
696
  private usageTracker;
702
697
  private usageBridge;
703
698
  private routerEventBridge;
704
- private heartbeatTimer;
705
- private heartbeatStart;
706
699
  private currentPhase;
707
700
  constructor(config: ObotoAgentConfig);
708
701
  /** Subscribe to agent events. Returns an unsubscribe function. */
@@ -767,13 +760,10 @@ declare class ObotoAgent {
767
760
  retrieveContext(query: string): Promise<string | undefined>;
768
761
  /** Emit a phase transition event with a human-readable message. */
769
762
  private emitPhase;
770
- /** Start a heartbeat that re-emits the current phase every intervalMs. */
771
- private startHeartbeat;
772
- /** Stop the heartbeat timer. */
773
- private stopHeartbeat;
774
763
  /**
775
764
  * Build a human-readable narrative for a batch of tool executions.
776
- * E.g. "Just read file data, and ran a command. Sending results back to AI for next steps…"
765
+ * Uses both command name and kwargs to produce accurate descriptions.
766
+ * E.g. "Just read file data, and edited files. Sending results back to AI for next steps…"
777
767
  */
778
768
  private buildToolRoundNarrative;
779
769
  /**
@@ -1212,4 +1202,4 @@ type TriageInput = {
1212
1202
  */
1213
1203
  declare function createTriageFunction(modelName: string): LScriptFunction<TriageInput, typeof TriageSchema>;
1214
1204
 
1215
- export { AgentDynamicTools, type AgentEvent, AgentEventBus, type AgentEventType, type AgentPhase, type AgentPipelineConfig, type AgentToolTreeConfig, AgentUsageTracker, ContextManager, ConversationRAG, type ConversationRAGConfig, type DoomLoopEvent, type DynamicToolEntry, type DynamicToolProvider, type ExecutionOutput, ExecutionSchema, type HeartbeatEvent, HookIntegration, ObotoAgent, type ObotoAgentConfig, PermissionGuard, type PhaseEvent, type PlanOutput, PlanSchema, type ProviderLike$1 as ProviderLike, type RAGRetrievalResult, RouterEventBridge, SessionCompactor, SlashCommandRegistry, type SummaryOutput, SummarySchema, type ToolExecutionEvent, type ToolRoundEvent, type TriagePipelineOutput, TriagePipelineSchema, type TriageResult, TriageSchema, type UnifiedCostSummary, UsageBridge, asTokenUsageToLmscript, createAgentToolTree, createAnalyzeRespondPipeline, createEmptySession, createExecutionStep, createFullPipeline, createPlanStep, createRouterTool, createSummaryStep, createToolAuditMiddleware, createToolTimeoutMiddleware, createToolTimingMiddleware, createTriageFunction, createTriagePlanExecutePipeline, createTriageStep, estimateCostFromAsAgent, fromChat, isLLMRouter, lmscriptToAsTokenUsage, runAgentPipeline, sessionToHistory, toChat, toLmscriptProvider };
1205
+ export { AgentDynamicTools, type AgentEvent, AgentEventBus, type AgentEventType, type AgentPhase, type AgentPipelineConfig, type AgentToolTreeConfig, AgentUsageTracker, ContextManager, ConversationRAG, type ConversationRAGConfig, type DoomLoopEvent, type DynamicToolEntry, type DynamicToolProvider, type ExecutionOutput, ExecutionSchema, HookIntegration, ObotoAgent, type ObotoAgentConfig, PermissionGuard, type PhaseEvent, type PlanOutput, PlanSchema, type ProviderLike$1 as ProviderLike, type RAGRetrievalResult, RouterEventBridge, SessionCompactor, SlashCommandRegistry, type SummaryOutput, SummarySchema, type ToolExecutionEvent, type ToolRoundEvent, type TriagePipelineOutput, TriagePipelineSchema, type TriageResult, TriageSchema, type UnifiedCostSummary, UsageBridge, asTokenUsageToLmscript, createAgentToolTree, createAnalyzeRespondPipeline, createEmptySession, createExecutionStep, createFullPipeline, createPlanStep, createRouterTool, createSummaryStep, createToolAuditMiddleware, createToolTimeoutMiddleware, createToolTimingMiddleware, createTriageFunction, createTriagePlanExecutePipeline, createTriageStep, estimateCostFromAsAgent, fromChat, isLLMRouter, lmscriptToAsTokenUsage, runAgentPipeline, sessionToHistory, toChat, toLmscriptProvider };
package/dist/index.js CHANGED
@@ -1163,8 +1163,6 @@ var ObotoAgent = class {
1163
1163
  usageTracker;
1164
1164
  usageBridge;
1165
1165
  routerEventBridge;
1166
- heartbeatTimer = null;
1167
- heartbeatStart = 0;
1168
1166
  currentPhase = "request";
1169
1167
  constructor(config) {
1170
1168
  this.config = config;
@@ -1178,10 +1176,8 @@ var ObotoAgent = class {
1178
1176
  this.middleware.use(hooks);
1179
1177
  }
1180
1178
  }
1181
- if (config.modelPricing) {
1182
- this.costTracker = new CostTracker();
1183
- this.modelPricing = config.modelPricing;
1184
- }
1179
+ this.costTracker = new CostTracker();
1180
+ this.modelPricing = config.modelPricing;
1185
1181
  const localCache = config.triageCacheTtlMs ? new ExecutionCache(new MemoryCacheBackend()) : void 0;
1186
1182
  this.localRuntime = new LScriptRuntime({
1187
1183
  provider: localLmscript,
@@ -1422,45 +1418,41 @@ var ObotoAgent = class {
1422
1418
  this.currentPhase = phase;
1423
1419
  this.bus.emit("phase", { phase, message });
1424
1420
  }
1425
- /** Start a heartbeat that re-emits the current phase every intervalMs. */
1426
- startHeartbeat(phase, intervalMs = 3e3) {
1427
- this.stopHeartbeat();
1428
- this.heartbeatStart = Date.now();
1429
- this.currentPhase = phase;
1430
- this.heartbeatTimer = setInterval(() => {
1431
- const elapsed = Date.now() - this.heartbeatStart;
1432
- const secs = Math.round(elapsed / 1e3);
1433
- const message = phase === "thinking" ? `Waiting for AI response\u2026 (${secs}s)` : `${phase}\u2026 (${secs}s)`;
1434
- this.bus.emit("heartbeat", { phase: this.currentPhase, elapsedMs: elapsed, message });
1435
- }, intervalMs);
1436
- }
1437
- /** Stop the heartbeat timer. */
1438
- stopHeartbeat() {
1439
- if (this.heartbeatTimer) {
1440
- clearInterval(this.heartbeatTimer);
1441
- this.heartbeatTimer = null;
1442
- }
1443
- }
1444
1421
  /**
1445
1422
  * Build a human-readable narrative for a batch of tool executions.
1446
- * E.g. "Just read file data, and ran a command. Sending results back to AI for next steps…"
1423
+ * Uses both command name and kwargs to produce accurate descriptions.
1424
+ * E.g. "Just read file data, and edited files. Sending results back to AI for next steps…"
1447
1425
  */
1448
1426
  buildToolRoundNarrative(tools) {
1449
1427
  if (tools.length === 0) return "No tools executed.";
1450
1428
  const verbs = /* @__PURE__ */ new Map();
1451
1429
  for (const t of tools) {
1452
1430
  const cmd = t.command.toLowerCase();
1431
+ const kw = t.kwargs || {};
1432
+ const kwStr = JSON.stringify(kw).toLowerCase();
1453
1433
  let verb;
1454
- if (cmd.includes("read") || cmd.includes("cat") || cmd.includes("get")) {
1434
+ if (kwStr.includes('"cmd"') && (kwStr.includes("cat ") || kwStr.includes("head ") || kwStr.includes("tail "))) {
1435
+ verb = "read file data";
1436
+ } else if (kwStr.includes('"cmd"') && (kwStr.includes("ls ") || kwStr.includes("find ") || kwStr.includes("tree "))) {
1437
+ verb = "listed files";
1438
+ } else if (kwStr.includes('"cmd"') && (kwStr.includes("grep ") || kwStr.includes("rg ") || kwStr.includes("ag "))) {
1439
+ verb = "searched for information";
1440
+ } else if (cmd.includes("read") || cmd.includes("get_file") || cmd.includes("view")) {
1455
1441
  verb = "read file data";
1456
- } else if (cmd.includes("write") || cmd.includes("edit") || cmd.includes("patch")) {
1442
+ } else if (cmd.includes("write") || cmd.includes("edit") || cmd.includes("patch") || cmd.includes("update")) {
1457
1443
  verb = "edited files";
1458
1444
  } else if (cmd.includes("search") || cmd.includes("grep") || cmd.includes("find") || cmd.includes("glob")) {
1459
1445
  verb = "searched for information";
1446
+ } else if (cmd.includes("list") || cmd.includes("ls")) {
1447
+ verb = "listed items";
1460
1448
  } else if (cmd.includes("run") || cmd.includes("exec") || cmd.includes("bash") || cmd.includes("shell")) {
1461
1449
  verb = "ran a command";
1462
1450
  } else if (cmd.includes("browse") || cmd.includes("web") || cmd.includes("fetch")) {
1463
1451
  verb = "browsed the web";
1452
+ } else if (cmd.includes("surface")) {
1453
+ verb = cmd.includes("read") ? "read surface data" : "accessed surfaces";
1454
+ } else if (cmd.includes("help")) {
1455
+ verb = "checked available tools";
1464
1456
  } else {
1465
1457
  verb = `used ${t.command}`;
1466
1458
  }
@@ -1537,9 +1529,7 @@ var ObotoAgent = class {
1537
1529
  }
1538
1530
  }
1539
1531
  this.emitPhase("precheck", "Checking if direct answer is possible\u2026");
1540
- this.startHeartbeat("precheck");
1541
1532
  const triageResult = await this.triage(userInput);
1542
- this.stopHeartbeat();
1543
1533
  this.bus.emit("triage_result", triageResult);
1544
1534
  if (this.interrupted) return;
1545
1535
  if (!triageResult.escalate && triageResult.directResponse) {
@@ -1556,12 +1546,7 @@ var ObotoAgent = class {
1556
1546
  return;
1557
1547
  }
1558
1548
  if (triageResult.escalate) {
1559
- this.emitPhase("thinking", `Escalating to remote model: ${triageResult.reasoning}`);
1560
- this.bus.emit("agent_thought", {
1561
- text: triageResult.reasoning,
1562
- model: "local",
1563
- escalating: true
1564
- });
1549
+ this.emitPhase("thinking", "Entering agent loop with remote model\u2026");
1565
1550
  } else {
1566
1551
  this.emitPhase("thinking", "This requires tools and deeper reasoning \u2014 entering agent loop.");
1567
1552
  }
@@ -1600,7 +1585,6 @@ var ObotoAgent = class {
1600
1585
  async executeWithAgentLoop(runtime, modelName, userInput) {
1601
1586
  const { z: z5 } = await import("zod");
1602
1587
  this.emitPhase("thinking", `Turn 1/${this.maxIterations}: Analyzing request\u2026`);
1603
- this.startHeartbeat("thinking");
1604
1588
  const agentFn = {
1605
1589
  name: "agent-task",
1606
1590
  model: modelName,
@@ -1635,12 +1619,11 @@ user: ${input}` : input;
1635
1619
  this.emitPhase("tools", `Running tool: ${String(command)}`);
1636
1620
  this.bus.emit("tool_execution_start", { command, kwargs });
1637
1621
  this.bus.emit("tool_execution_complete", { command, kwargs, result: resultStr });
1638
- iterationTools.push({ command: String(command), success: !isError });
1622
+ iterationTools.push({ command: String(command), success: !isError, kwargs });
1639
1623
  totalToolCalls++;
1640
1624
  this.recordToolResult(String(command), kwargs, resultStr);
1641
1625
  },
1642
1626
  onIteration: (iteration, response) => {
1643
- this.stopHeartbeat();
1644
1627
  if (iterationTools.length > 0) {
1645
1628
  const narrative = this.buildToolRoundNarrative(iterationTools);
1646
1629
  const roundEvent = {
@@ -1660,42 +1643,36 @@ user: ${input}` : input;
1660
1643
  });
1661
1644
  }
1662
1645
  this.emitPhase("thinking", `Turn ${iteration + 1}/${this.maxIterations}: Analyzing results\u2026`);
1663
- this.startHeartbeat("thinking");
1664
1646
  if (this.interrupted) return false;
1665
1647
  }
1666
1648
  };
1667
1649
  const agentLoop = new AgentLoop(runtime, agentConfig);
1668
- try {
1669
- const result = await agentLoop.run(agentFn, userInput);
1670
- this.stopHeartbeat();
1671
- if (iterationTools.length > 0) {
1672
- const narrative = this.buildToolRoundNarrative(iterationTools);
1673
- this.bus.emit("tool_round_complete", {
1674
- iteration: result.iterations,
1675
- tools: iterationTools,
1676
- totalToolCalls,
1677
- narrative
1678
- });
1679
- }
1680
- this.emitPhase("memory", "Recording interaction\u2026");
1681
- const responseText = result.data.response;
1682
- const assistantMsg = {
1683
- role: MessageRole4.Assistant,
1684
- blocks: [{ kind: "text", text: responseText }]
1685
- };
1686
- await this.recordMessage(assistantMsg);
1687
- this.bus.emit("state_updated", { reason: "assistant_response" });
1688
- this.emitPhase("complete", "Response ready.");
1689
- this.bus.emit("turn_complete", {
1690
- model: modelName,
1691
- escalated: true,
1692
- iterations: result.iterations,
1693
- toolCalls: result.toolCalls.length,
1694
- usage: result.usage
1650
+ const result = await agentLoop.run(agentFn, userInput);
1651
+ if (iterationTools.length > 0) {
1652
+ const narrative = this.buildToolRoundNarrative(iterationTools);
1653
+ this.bus.emit("tool_round_complete", {
1654
+ iteration: result.iterations,
1655
+ tools: iterationTools,
1656
+ totalToolCalls,
1657
+ narrative
1695
1658
  });
1696
- } finally {
1697
- this.stopHeartbeat();
1698
1659
  }
1660
+ this.emitPhase("memory", "Recording interaction\u2026");
1661
+ const responseText = result.data.response;
1662
+ const assistantMsg = {
1663
+ role: MessageRole4.Assistant,
1664
+ blocks: [{ kind: "text", text: responseText }]
1665
+ };
1666
+ await this.recordMessage(assistantMsg);
1667
+ this.bus.emit("state_updated", { reason: "assistant_response" });
1668
+ this.emitPhase("complete", "Response ready.");
1669
+ this.bus.emit("turn_complete", {
1670
+ model: modelName,
1671
+ escalated: true,
1672
+ iterations: result.iterations,
1673
+ toolCalls: result.toolCalls.length,
1674
+ usage: result.usage
1675
+ });
1699
1676
  }
1700
1677
  /**
1701
1678
  * Execute with streaming token emission.
@@ -1753,8 +1730,7 @@ user: ${input}` : input;
1753
1730
  "thinking",
1754
1731
  `Turn ${iteration}/${this.maxIterations}: ${iteration === 1 ? "Analyzing request\u2026" : "Analyzing results\u2026"}`
1755
1732
  );
1756
- this.startHeartbeat("thinking");
1757
- if (this.costTracker && this.budget) {
1733
+ if (this.budget) {
1758
1734
  this.costTracker.checkBudget(this.budget);
1759
1735
  }
1760
1736
  await this.rateLimiter?.acquire();
@@ -1776,7 +1752,6 @@ user: ${input}` : input;
1776
1752
  try {
1777
1753
  response = await this.streamAndAggregate(provider, params);
1778
1754
  } catch (err) {
1779
- this.stopHeartbeat();
1780
1755
  this.emitPhase("error", `LLM call failed: ${err instanceof Error ? err.message : String(err)}`);
1781
1756
  await this.middleware.runError(
1782
1757
  syntheticCtx,
@@ -1784,7 +1759,6 @@ user: ${input}` : input;
1784
1759
  );
1785
1760
  throw err;
1786
1761
  }
1787
- this.stopHeartbeat();
1788
1762
  const usage = response?.usage;
1789
1763
  if (usage) {
1790
1764
  const promptTokens = usage.prompt_tokens ?? 0;
@@ -1799,13 +1773,11 @@ user: ${input}` : input;
1799
1773
  completionTokens,
1800
1774
  totalTokens: usageTotal
1801
1775
  });
1802
- if (this.costTracker) {
1803
- this.bus.emit("cost_update", {
1804
- iteration,
1805
- totalTokens: this.costTracker.getTotalTokens(),
1806
- totalCost: this.costTracker.getTotalCost(this.modelPricing)
1807
- });
1808
- }
1776
+ this.bus.emit("cost_update", {
1777
+ iteration,
1778
+ totalTokens: this.costTracker.getTotalTokens(),
1779
+ totalCost: this.costTracker.getTotalCost(this.modelPricing)
1780
+ });
1809
1781
  }
1810
1782
  const choice = response?.choices?.[0];
1811
1783
  const content = choice?.message?.content ?? "";
@@ -1983,7 +1955,7 @@ user: ${input}` : input;
1983
1955
  }
1984
1956
  this.bus.emit("tool_execution_complete", { command, kwargs, result: truncated, error: isError ? truncated : void 0 });
1985
1957
  this.recordToolResult(command, kwargs, truncated);
1986
- roundTools.push({ command, success: !isError });
1958
+ roundTools.push({ command, success: !isError, kwargs });
1987
1959
  totalToolCalls++;
1988
1960
  messages.push({
1989
1961
  role: "tool",
@@ -2022,7 +1994,6 @@ user: ${input}` : input;
2022
1994
  usage: totalUsage
2023
1995
  });
2024
1996
  } catch (err) {
2025
- this.stopHeartbeat();
2026
1997
  this.emitPhase("error", `Error: ${err instanceof Error ? err.message : String(err)}`);
2027
1998
  if (!(err instanceof Error && err.message.includes("LLM call failed"))) {
2028
1999
  await this.middleware.runError(
@@ -2031,8 +2002,6 @@ user: ${input}` : input;
2031
2002
  );
2032
2003
  }
2033
2004
  throw err;
2034
- } finally {
2035
- this.stopHeartbeat();
2036
2005
  }
2037
2006
  }
2038
2007
  /**
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/oboto-agent.ts","../src/event-bus.ts","../src/context-manager.ts","../src/triage.ts","../src/adapters/tools.ts","../src/adapters/llm-wrapper.ts","../src/adapters/memory.ts","../src/adapters/rag-integration.ts","../src/adapters/as-agent-features.ts","../src/adapters/router-events.ts","../src/adapters/usage-bridge.ts","../src/adapters/tool-extensions.ts","../src/adapters/pipeline-workflows.ts"],"sourcesContent":["import {\n LScriptRuntime,\n MiddlewareManager,\n ExecutionCache,\n MemoryCacheBackend,\n CostTracker,\n RateLimiter,\n AgentLoop,\n type ToolDefinition,\n type ChatMessage,\n type AgentConfig,\n type ToolCall,\n type BudgetConfig,\n type ModelPricing,\n} from \"@sschepis/lmscript\";\nimport type {\n StandardChatChunk,\n StandardChatResponse,\n} from \"@sschepis/llm-wrapper\";\nimport { aggregateStream } from \"@sschepis/llm-wrapper\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type {\n ObotoAgentConfig, AgentEventType, AgentEvent, TriageResult, ProviderLike,\n AgentPhase, ToolRoundEvent,\n} from \"./types.js\";\nimport { AgentEventBus } from \"./event-bus.js\";\nimport { ContextManager } from \"./context-manager.js\";\nimport { createTriageFunction } from \"./triage.js\";\nimport { createRouterTool } from \"./adapters/tools.js\";\nimport { toLmscriptProvider } from \"./adapters/llm-wrapper.js\";\nimport { toChat, createEmptySession, sessionToHistory } from \"./adapters/memory.js\";\nimport { ConversationRAG } from \"./adapters/rag-integration.js\";\nimport {\n PermissionGuard,\n SessionCompactor,\n HookIntegration,\n SlashCommandRegistry,\n AgentUsageTracker,\n} from \"./adapters/as-agent-features.js\";\nimport { RouterEventBridge, isLLMRouter } from \"./adapters/router-events.js\";\nimport { UsageBridge, type UnifiedCostSummary } from \"./adapters/usage-bridge.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * ObotoAgent is the central orchestrator for dual-LLM agent execution.\n *\n * It binds together:\n * - llm-wrapper (LLM communication via local and remote providers / LLMRouter)\n * - lmscript (structured/schema-validated calls, agent loop, infrastructure)\n * - swiss-army-tool (tool execution via Router)\n * - as-agent (session state and conversation history)\n *\n * All interaction flows through an event-driven architecture.\n *\n * Key integration improvements (v0.2):\n * - Accepts LLMRouter for automatic failover and health tracking\n * - Uses lmscript's AgentLoop instead of a custom tool-calling loop\n * - Wires lmscript infrastructure: cache, cost tracking, rate limiting, middleware\n * - Bridges streaming via chatStream through the full lmscript stack\n */\nexport class ObotoAgent {\n private bus = new AgentEventBus();\n private localRuntime: LScriptRuntime;\n private remoteRuntime: LScriptRuntime;\n private localProvider: ProviderLike;\n private remoteProvider: ProviderLike;\n private contextManager: ContextManager;\n private routerTool: ToolDefinition<any, any>;\n private triageFn: ReturnType<typeof createTriageFunction>;\n private session: Session;\n private isProcessing = false;\n private interrupted = false;\n private systemPrompt: string;\n private maxIterations: number;\n private config: ObotoAgentConfig;\n private onToken?: (token: string) => void;\n private costTracker?: CostTracker;\n private modelPricing?: ModelPricing;\n private rateLimiter?: RateLimiter;\n private middleware!: MiddlewareManager;\n private budget?: BudgetConfig;\n private conversationRAG?: ConversationRAG;\n private permissionGuard?: PermissionGuard;\n private sessionCompactor?: SessionCompactor;\n private hookIntegration?: HookIntegration;\n private slashCommands: SlashCommandRegistry;\n private usageTracker: AgentUsageTracker;\n private usageBridge: UsageBridge;\n private routerEventBridge: RouterEventBridge;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private heartbeatStart = 0;\n private currentPhase: AgentPhase = \"request\";\n\n constructor(config: ObotoAgentConfig) {\n this.config = config;\n this.localProvider = config.localModel;\n this.remoteProvider = config.remoteModel;\n\n // ── Build lmscript providers from llm-wrapper providers ──────────\n const localLmscript = toLmscriptProvider(config.localModel, \"local\");\n const remoteLmscript = toLmscriptProvider(config.remoteModel, \"remote\");\n\n // ── Build middleware manager ─────────────────────────────────────\n this.middleware = new MiddlewareManager();\n if (config.middleware) {\n for (const hooks of config.middleware) {\n this.middleware.use(hooks);\n }\n }\n\n // ── Build cost tracker (shared across runtimes for unified reporting) ─\n // CostTracker takes no constructor args; pricing is passed to getTotalCost()\n if (config.modelPricing) {\n this.costTracker = new CostTracker();\n this.modelPricing = config.modelPricing;\n }\n\n // ── Build local runtime (lightweight: cache for triage, no rate limit) ─\n // ExecutionCache takes only a CacheBackend; TTL is handled per-entry\n // by the MemoryCacheBackend.set(key, value, ttlMs) call\n const localCache = config.triageCacheTtlMs\n ? new ExecutionCache(new MemoryCacheBackend())\n : undefined;\n\n this.localRuntime = new LScriptRuntime({\n provider: localLmscript,\n defaultTemperature: 0.1,\n cache: localCache,\n costTracker: this.costTracker,\n });\n\n // ── Build remote runtime (full infrastructure) ──────────────────\n const remoteCache = config.cacheTtlMs\n ? new ExecutionCache(new MemoryCacheBackend())\n : undefined;\n\n const rateLimiter = config.rateLimit\n ? new RateLimiter(config.rateLimit)\n : undefined;\n this.rateLimiter = rateLimiter;\n this.budget = config.budget;\n\n this.remoteRuntime = new LScriptRuntime({\n provider: remoteLmscript,\n middleware: this.middleware,\n cache: remoteCache,\n costTracker: this.costTracker,\n budget: config.budget,\n rateLimiter,\n });\n\n // ── Session and context ─────────────────────────────────────────\n this.session = config.session ?? createEmptySession();\n this.systemPrompt = config.systemPrompt ?? \"You are a helpful AI assistant with access to tools.\";\n this.maxIterations = config.maxIterations ?? 10;\n this.onToken = config.onToken;\n\n this.contextManager = new ContextManager(\n this.localRuntime,\n config.localModelName,\n config.maxContextTokens ?? 8192\n );\n\n // ── Tool layer ──────────────────────────────────────────────────\n // Apply swiss-army-tool middleware if configured\n if (config.toolMiddleware) {\n for (const mw of config.toolMiddleware) {\n config.router.use(mw);\n }\n }\n\n this.routerTool = createRouterTool(config.router);\n this.triageFn = createTriageFunction(config.localModelName);\n\n // ── RAG pipeline (optional) ─────────────────────────────────────\n if (config.embeddingProvider) {\n this.conversationRAG = new ConversationRAG(this.remoteRuntime, {\n embeddingProvider: config.embeddingProvider,\n vectorStore: config.vectorStore,\n topK: config.ragTopK,\n minScore: config.ragMinScore,\n embeddingModel: config.ragEmbeddingModel,\n autoIndex: config.ragAutoIndex,\n indexToolResults: config.ragIndexToolResults,\n formatContext: config.ragFormatContext,\n });\n }\n\n // ── as-agent features ───────────────────────────────────────────\n // Permission guard (optional)\n if (config.permissionPolicy) {\n this.permissionGuard = new PermissionGuard(\n config.permissionPolicy,\n config.permissionPrompter ?? null,\n this.bus,\n );\n }\n\n // Session compaction (optional)\n if (config.compactionConfig) {\n this.sessionCompactor = new SessionCompactor(this.bus, config.compactionConfig);\n }\n\n // Hook runner (optional)\n if (config.hookRunner) {\n this.hookIntegration = new HookIntegration(config.hookRunner, this.bus);\n }\n\n // Slash command registry (always available, Wasm runtime optional)\n this.slashCommands = new SlashCommandRegistry(config.agentRuntime);\n\n // Usage tracker (always available)\n this.usageTracker = new AgentUsageTracker();\n\n // Usage bridge: unifies as-agent UsageTracker and lmscript CostTracker\n this.usageBridge = new UsageBridge(this.usageTracker, this.costTracker);\n\n // ── Router event bridge (auto-attach LLMRouters) ────────────────\n this.routerEventBridge = new RouterEventBridge(this.bus);\n if (isLLMRouter(config.localModel)) {\n this.routerEventBridge.attach(config.localModel, \"local\");\n }\n if (isLLMRouter(config.remoteModel)) {\n this.routerEventBridge.attach(config.remoteModel, \"remote\");\n }\n\n // Push system prompt into context\n this.contextManager.push({\n role: \"system\",\n content: this.systemPrompt,\n });\n\n // Seed context manager from existing session messages so triage\n // and execution paths see the full conversation history.\n if (this.session.messages.length > 0) {\n this.contextManager.pushAll(sessionToHistory(this.session));\n }\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n /** Subscribe to agent events. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.on(type, handler);\n }\n\n /** Subscribe to an event for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.once(type, handler);\n }\n\n /** Submit user input to the agent. Triggers the execution loop. */\n async submitInput(text: string): Promise<void> {\n if (this.isProcessing) {\n this.interrupt(text);\n return;\n }\n\n // Check for slash commands first\n const parsedCmd = this.slashCommands.parseCommand(text);\n if (parsedCmd) {\n const result = await this.slashCommands.executeCustomCommand(parsedCmd.name, parsedCmd.args);\n if (result !== null) {\n this.bus.emit(\"slash_command\", {\n command: parsedCmd.name,\n args: parsedCmd.args,\n result,\n });\n return;\n }\n // If not a custom command, fall through to normal processing\n // (the Wasm runtime may handle it, or it's treated as regular input)\n }\n\n this.isProcessing = true;\n this.interrupted = false;\n\n try {\n await this.executionLoop(text);\n\n // End the usage tracker turn (via bridge)\n this.usageBridge.endTurn();\n\n // Auto-compact session if configured\n if (this.sessionCompactor) {\n const result = this.sessionCompactor.compactIfNeeded(this.session);\n if (result && result.removedMessageCount > 0) {\n this.session = result.compactedSession;\n }\n }\n } catch (err) {\n this.bus.emit(\"error\", {\n message: err instanceof Error ? err.message : String(err),\n error: err,\n });\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Interrupt the current execution loop.\n * Optionally inject new directives into the context.\n */\n async interrupt(newDirectives?: string): Promise<void> {\n this.interrupted = true;\n this.bus.emit(\"interruption\", { newDirectives });\n\n if (newDirectives) {\n const msg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: `[INTERRUPTION] ${newDirectives}` }],\n };\n await this.recordMessage(msg);\n this.bus.emit(\"state_updated\", { reason: \"interruption\" });\n }\n }\n\n /** Get the current session state. */\n getSession(): Session {\n return this.session;\n }\n\n /** Whether the agent is currently processing input. */\n get processing(): boolean {\n return this.isProcessing;\n }\n\n /** Get cost tracking summary (if cost tracking is enabled). */\n getCostSummary(): {\n totalCost: number;\n totalTokens: number;\n byFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }>;\n } | undefined {\n if (!this.costTracker) return undefined;\n\n const totalTokens = this.costTracker.getTotalTokens();\n const totalCost = this.costTracker.getTotalCost(this.modelPricing);\n\n // Convert Map to plain object for easier consumption\n const usageMap = this.costTracker.getUsageByFunction();\n const byFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }> = {};\n for (const [fnName, entry] of usageMap) {\n byFunction[fnName] = entry;\n }\n\n return { totalCost, totalTokens, byFunction };\n }\n\n /**\n * Get unified cost summary combining both as-agent and lmscript tracking.\n * Uses the UsageBridge to provide a single view of all token/cost data.\n */\n getUnifiedCostSummary(\n asPricing?: import(\"@sschepis/as-agent\").ModelPricing,\n ): UnifiedCostSummary {\n return this.usageBridge.getCostSummary(this.modelPricing, asPricing);\n }\n\n /** Get the usage bridge for direct access to unified tracking. */\n getUsageBridge(): UsageBridge {\n return this.usageBridge;\n }\n\n /** Remove all event listeners and detach router event subscriptions. */\n removeAllListeners(): void {\n this.bus.removeAllListeners();\n this.routerEventBridge.detachAll();\n }\n\n /** Sync session and repopulate context manager (for reuse across turns). */\n async syncSession(session: Session): Promise<void> {\n this.session = session;\n this.contextManager.clear();\n await this.contextManager.push({ role: \"system\", content: this.systemPrompt });\n if (session.messages.length > 0) {\n await this.contextManager.pushAll(sessionToHistory(session));\n }\n }\n\n /** Update the streaming token callback between turns. */\n setOnToken(callback: ((token: string) => void) | undefined): void {\n this.onToken = callback;\n }\n\n /** Get the ConversationRAG instance (if RAG is enabled). */\n getConversationRAG(): ConversationRAG | undefined {\n return this.conversationRAG;\n }\n\n /** Get the slash command registry. */\n getSlashCommands(): SlashCommandRegistry {\n return this.slashCommands;\n }\n\n /** Get the as-agent usage tracker. */\n getUsageTracker(): AgentUsageTracker {\n return this.usageTracker;\n }\n\n /** Get the permission guard (if permissions are configured). */\n getPermissionGuard(): PermissionGuard | undefined {\n return this.permissionGuard;\n }\n\n /** Get the session compactor (if compaction is configured). */\n getSessionCompactor(): SessionCompactor | undefined {\n return this.sessionCompactor;\n }\n\n /** Get the router event bridge for observability into LLMRouter health. */\n getRouterEventBridge(): RouterEventBridge {\n return this.routerEventBridge;\n }\n\n /**\n * Manually compact the session. Returns null if compaction is not configured.\n */\n compactSession(): import(\"@sschepis/as-agent\").CompactionResult | null {\n if (!this.sessionCompactor) return null;\n const result = this.sessionCompactor.compact(this.session);\n if (result.removedMessageCount > 0) {\n this.session = result.compactedSession;\n }\n return result;\n }\n\n /**\n * Retrieve relevant past context for a query via the RAG pipeline.\n * Returns undefined if RAG is not configured.\n */\n async retrieveContext(query: string): Promise<string | undefined> {\n if (!this.conversationRAG) return undefined;\n const { context } = await this.conversationRAG.retrieve(query);\n return context || undefined;\n }\n\n // ── Conversational helpers ──────────────────────────────────────────\n\n /** Emit a phase transition event with a human-readable message. */\n private emitPhase(phase: AgentPhase, message: string): void {\n this.currentPhase = phase;\n this.bus.emit(\"phase\", { phase, message });\n }\n\n /** Start a heartbeat that re-emits the current phase every intervalMs. */\n private startHeartbeat(phase: AgentPhase, intervalMs = 3000): void {\n this.stopHeartbeat();\n this.heartbeatStart = Date.now();\n this.currentPhase = phase;\n this.heartbeatTimer = setInterval(() => {\n const elapsed = Date.now() - this.heartbeatStart;\n const secs = Math.round(elapsed / 1000);\n const message = phase === \"thinking\"\n ? `Waiting for AI response… (${secs}s)`\n : `${phase}… (${secs}s)`;\n this.bus.emit(\"heartbeat\", { phase: this.currentPhase, elapsedMs: elapsed, message });\n }, intervalMs);\n }\n\n /** Stop the heartbeat timer. */\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n /**\n * Build a human-readable narrative for a batch of tool executions.\n * E.g. \"Just read file data, and ran a command. Sending results back to AI for next steps…\"\n */\n private buildToolRoundNarrative(\n tools: Array<{ command: string; success: boolean }>\n ): string {\n if (tools.length === 0) return \"No tools executed.\";\n\n // Group tools by action verb\n const verbs = new Map<string, string[]>();\n for (const t of tools) {\n const cmd = t.command.toLowerCase();\n let verb: string;\n if (cmd.includes(\"read\") || cmd.includes(\"cat\") || cmd.includes(\"get\")) {\n verb = \"read file data\";\n } else if (cmd.includes(\"write\") || cmd.includes(\"edit\") || cmd.includes(\"patch\")) {\n verb = \"edited files\";\n } else if (cmd.includes(\"search\") || cmd.includes(\"grep\") || cmd.includes(\"find\") || cmd.includes(\"glob\")) {\n verb = \"searched for information\";\n } else if (cmd.includes(\"run\") || cmd.includes(\"exec\") || cmd.includes(\"bash\") || cmd.includes(\"shell\")) {\n verb = \"ran a command\";\n } else if (cmd.includes(\"browse\") || cmd.includes(\"web\") || cmd.includes(\"fetch\")) {\n verb = \"browsed the web\";\n } else {\n verb = `used ${t.command}`;\n }\n if (!verbs.has(verb)) verbs.set(verb, []);\n verbs.get(verb)!.push(t.command);\n }\n\n const parts = Array.from(verbs.keys());\n let narrative: string;\n if (parts.length === 1) {\n narrative = `Just ${parts[0]}.`;\n } else if (parts.length === 2) {\n narrative = `Just ${parts[0]}, and ${parts[1]}.`;\n } else {\n const last = parts.pop()!;\n narrative = `Just ${parts.join(\", \")}, and ${last}.`;\n }\n\n const errors = tools.filter(t => !t.success);\n if (errors.length > 0) {\n const errNames = errors.map(e => e.command).join(\", \");\n narrative += ` (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}: ${errNames})`;\n }\n\n narrative += \" Sending results back to AI for next steps…\";\n return narrative;\n }\n\n // ── Internal ───────────────────────────────────────────────────────\n\n /**\n * Record a message in the session, context manager, and optionally RAG index.\n * Centralizes message recording to ensure RAG indexing stays in sync.\n */\n private async recordMessage(msg: ConversationMessage): Promise<void> {\n this.session.messages.push(msg);\n await this.contextManager.push(toChat(msg));\n\n // Auto-index for RAG if enabled\n if (this.conversationRAG) {\n // Fire and forget — RAG indexing should not block the main loop\n this.conversationRAG.indexMessage(msg, this.session.messages.length - 1).catch((err) => {\n console.warn(\"[ObotoAgent] RAG indexing failed:\", err instanceof Error ? err.message : err);\n });\n }\n }\n\n /**\n * Record a tool execution result in the RAG index.\n */\n private recordToolResult(command: string, kwargs: Record<string, unknown>, result: string): void {\n if (this.conversationRAG) {\n this.conversationRAG.indexToolResult(command, kwargs, result).catch((err) => {\n console.warn(\"[ObotoAgent] RAG tool indexing failed:\", err instanceof Error ? err.message : err);\n });\n }\n }\n\n private async executionLoop(userInput: string): Promise<void> {\n // ── Phase: Request ──\n this.emitPhase(\"request\", `Processing: ${userInput.substring(0, 80)}${userInput.length > 80 ? \"…\" : \"\"}`);\n\n // 1. Emit user_input and record in session + context + RAG\n this.bus.emit(\"user_input\", { text: userInput });\n\n const userMsg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: userInput }],\n };\n await this.recordMessage(userMsg);\n this.bus.emit(\"state_updated\", { reason: \"user_input\" });\n\n // ── Phase: Planning ──\n this.emitPhase(\"planning\", \"Building context and preparing tools…\");\n\n // 1b. Optionally augment context with RAG-retrieved past conversation\n if (this.conversationRAG) {\n try {\n const { context } = await this.conversationRAG.retrieve(userInput);\n if (context) {\n await this.contextManager.push({\n role: \"system\",\n content: context,\n });\n this.bus.emit(\"agent_thought\", {\n text: \"Retrieved relevant past context via RAG.\",\n model: \"system\",\n });\n }\n } catch (err) {\n console.warn(\"[ObotoAgent] RAG retrieval failed:\", err instanceof Error ? err.message : err);\n }\n }\n\n // ── Phase: Precheck (Triage) ──\n this.emitPhase(\"precheck\", \"Checking if direct answer is possible…\");\n this.startHeartbeat(\"precheck\");\n\n const triageResult = await this.triage(userInput);\n this.stopHeartbeat();\n this.bus.emit(\"triage_result\", triageResult);\n\n if (this.interrupted) return;\n\n // 3. If local can handle directly, emit and return\n if (!triageResult.escalate && triageResult.directResponse) {\n const response = triageResult.directResponse;\n this.emitPhase(\"complete\", \"Answered directly — no tools needed.\");\n this.bus.emit(\"agent_thought\", { text: response, model: \"local\" });\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: response }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", { model: \"local\", escalated: false });\n return;\n }\n\n // 4. Escalate to remote model with tool access\n if (triageResult.escalate) {\n this.emitPhase(\"thinking\", `Escalating to remote model: ${triageResult.reasoning}`);\n this.bus.emit(\"agent_thought\", {\n text: triageResult.reasoning,\n model: \"local\",\n escalating: true,\n });\n } else {\n this.emitPhase(\"thinking\", \"This requires tools and deeper reasoning — entering agent loop.\");\n }\n\n const modelName = triageResult.escalate\n ? this.config.remoteModelName\n : this.config.localModelName;\n\n const runtime = triageResult.escalate\n ? this.remoteRuntime\n : this.localRuntime;\n\n if (this.onToken) {\n await this.executeWithStreaming(runtime, modelName, userInput);\n } else {\n await this.executeWithAgentLoop(runtime, modelName, userInput);\n }\n }\n\n private async triage(userInput: string): Promise<TriageResult> {\n const recentMessages = this.contextManager.getMessages().slice(-5);\n const recentContext = recentMessages\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.triageFn, {\n userInput,\n recentContext,\n availableTools: this.routerTool.description,\n });\n\n return result.data;\n }\n\n /**\n * Execute using lmscript's AgentLoop for iterative tool calling.\n * This replaces the old custom tool loop with lmscript's battle-tested implementation.\n *\n * Benefits:\n * - Schema validation on final output\n * - Budget checking via CostTracker\n * - Rate limiting via RateLimiter\n * - Middleware lifecycle hooks\n * - Automatic retry with backoff\n */\n private async executeWithAgentLoop(\n runtime: LScriptRuntime,\n modelName: string,\n userInput: string\n ): Promise<void> {\n const { z } = await import(\"zod\");\n\n this.emitPhase(\"thinking\", `Turn 1/${this.maxIterations}: Analyzing request…`);\n this.startHeartbeat(\"thinking\");\n\n const agentFn = {\n name: \"agent-task\",\n model: modelName,\n system: this.systemPrompt,\n prompt: (input: string) => {\n const contextMessages = this.contextManager.getMessages();\n const contextStr = contextMessages\n .filter(m => m.role !== \"system\")\n .map(m => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n return contextStr ? `${contextStr}\\n\\nuser: ${input}` : input;\n },\n schema: z.object({\n response: z.string().describe(\"The assistant's response to the user\"),\n reasoning: z.string().optional().describe(\"Internal reasoning about the approach taken\"),\n }),\n tools: [this.routerTool],\n temperature: 0.7,\n maxRetries: 1,\n };\n\n // Track tool calls per iteration for narrative building\n let iterationTools: Array<{ command: string; success: boolean }> = [];\n let totalToolCalls = 0;\n\n const agentConfig: AgentConfig = {\n maxIterations: this.maxIterations,\n onToolCall: (tc: ToolCall) => {\n const command = typeof tc.arguments === \"object\" && tc.arguments !== null\n ? (tc.arguments as Record<string, unknown>).command ?? tc.name\n : tc.name;\n const kwargs = typeof tc.arguments === \"object\" && tc.arguments !== null\n ? (tc.arguments as Record<string, unknown>).kwargs ?? {}\n : {};\n\n const resultStr = typeof tc.result === \"string\" ? tc.result : JSON.stringify(tc.result);\n const isError = resultStr.startsWith(\"Error:\");\n\n this.emitPhase(\"tools\", `Running tool: ${String(command)}`);\n this.bus.emit(\"tool_execution_start\", { command, kwargs });\n this.bus.emit(\"tool_execution_complete\", { command, kwargs, result: resultStr });\n\n iterationTools.push({ command: String(command), success: !isError });\n totalToolCalls++;\n\n this.recordToolResult(String(command), kwargs as Record<string, unknown>, resultStr);\n },\n onIteration: (iteration: number, response: string) => {\n this.stopHeartbeat();\n\n // Emit tool round narrative if tools were called this iteration\n if (iterationTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(iterationTools);\n const roundEvent: ToolRoundEvent = {\n iteration,\n tools: iterationTools,\n totalToolCalls,\n narrative,\n };\n this.bus.emit(\"tool_round_complete\", roundEvent);\n iterationTools = [];\n }\n\n // Forward AI text\n if (response) {\n this.bus.emit(\"agent_thought\", {\n text: response,\n model: modelName,\n iteration,\n });\n }\n\n // Announce next iteration\n this.emitPhase(\"thinking\", `Turn ${iteration + 1}/${this.maxIterations}: Analyzing results…`);\n this.startHeartbeat(\"thinking\");\n\n if (this.interrupted) return false;\n },\n };\n\n const agentLoop = new AgentLoop(runtime, agentConfig);\n\n try {\n const result = await agentLoop.run(agentFn, userInput);\n this.stopHeartbeat();\n\n // Emit final tool round if pending\n if (iterationTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(iterationTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration: result.iterations,\n tools: iterationTools,\n totalToolCalls,\n narrative,\n });\n }\n\n // ── Phase: Memory ──\n this.emitPhase(\"memory\", \"Recording interaction…\");\n\n const responseText = result.data.response;\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: responseText }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n\n // ── Phase: Complete ──\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: result.iterations,\n toolCalls: result.toolCalls.length,\n usage: result.usage,\n });\n } finally {\n this.stopHeartbeat();\n }\n }\n\n /**\n * Execute with streaming token emission.\n * Uses the raw llm-wrapper provider for streaming, combined with\n * manual tool calling (since streaming + structured agent loops are complex).\n *\n * This preserves real-time token delivery while still leveraging\n * the lmscript infrastructure:\n * - Rate limiting (acquire/reportTokens per call)\n * - Cost tracking (trackUsage per call)\n * - Budget checking (checkBudget before each call)\n * - Middleware lifecycle hooks (onBeforeExecute/onComplete per turn)\n */\n private async executeWithStreaming(\n _runtime: LScriptRuntime,\n modelName: string,\n _userInput: string\n ): Promise<void> {\n const { zodToJsonSchema } = await import(\"zod-to-json-schema\");\n\n const provider = modelName === this.config.remoteModelName\n ? this.remoteProvider\n : this.localProvider;\n\n const contextMessages = this.contextManager.getMessages();\n\n const messages: import(\"@sschepis/llm-wrapper\").Message[] = contextMessages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : (m.content as Array<{ type: string; text?: string }>)\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\\n\"),\n }));\n\n const tool = this.routerTool;\n const parametersSchema = tool.parameters\n ? (zodToJsonSchema(tool.parameters, { target: \"openApi3\" }) as Record<string, unknown>)\n : { type: \"object\", properties: {} };\n const tools: import(\"@sschepis/llm-wrapper\").ToolDefinition[] = [\n {\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: parametersSchema,\n },\n },\n ];\n\n let totalToolCalls = 0;\n const callHistory: string[] = [];\n // Track consecutive duplicate patterns for doom loop detection\n const consecutiveDupes = new Map<string, number>();\n let doomLoopRedirected = false;\n const turnStartTime = Date.now();\n const totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };\n\n const syntheticCtx = {\n fn: { name: \"streaming-turn\", model: modelName, system: this.systemPrompt, prompt: () => \"\", schema: {} as any },\n input: _userInput,\n messages: messages as any,\n attempt: 1,\n startTime: turnStartTime,\n };\n await this.middleware.runBeforeExecute(syntheticCtx);\n\n try {\n for (let iteration = 1; iteration <= this.maxIterations; iteration++) {\n if (this.interrupted) {\n this.emitPhase(\"cancel\", \"Interrupted by user.\");\n break;\n }\n\n // ── Phase: Thinking with iteration context ──\n this.emitPhase(\n \"thinking\",\n `Turn ${iteration}/${this.maxIterations}: ${iteration === 1 ? \"Analyzing request…\" : \"Analyzing results…\"}`\n );\n this.startHeartbeat(\"thinking\");\n\n // ── Budget check ──\n if (this.costTracker && this.budget) {\n this.costTracker.checkBudget(this.budget);\n }\n\n await this.rateLimiter?.acquire();\n\n const isLastIteration = iteration === this.maxIterations;\n\n if (isLastIteration) {\n this.emitPhase(\"continuation\", \"Maximum iterations reached — synthesizing final response…\");\n messages.push({\n role: \"user\",\n content:\n \"You have used all available tool iterations. Please provide your final response now based on what you have gathered so far. Do not call any more tools.\",\n });\n }\n\n const params: import(\"@sschepis/llm-wrapper\").StandardChatParams = {\n model: modelName,\n messages: [...messages],\n temperature: 0.7,\n ...(isLastIteration\n ? {}\n : { tools, tool_choice: \"auto\" as const }),\n };\n\n let response: StandardChatResponse;\n try {\n response = await this.streamAndAggregate(provider, params);\n } catch (err) {\n this.stopHeartbeat();\n this.emitPhase(\"error\", `LLM call failed: ${err instanceof Error ? err.message : String(err)}`);\n await this.middleware.runError(\n syntheticCtx,\n err instanceof Error ? err : new Error(String(err))\n );\n throw err;\n }\n\n this.stopHeartbeat();\n\n // ── Usage tracking ──\n const usage = response?.usage;\n if (usage) {\n const promptTokens = usage.prompt_tokens ?? 0;\n const completionTokens = usage.completion_tokens ?? 0;\n const usageTotal = usage.total_tokens ?? (promptTokens + completionTokens);\n\n totalUsage.promptTokens += promptTokens;\n totalUsage.completionTokens += completionTokens;\n totalUsage.totalTokens += usageTotal;\n\n this.rateLimiter?.reportTokens(usageTotal);\n this.usageBridge.recordFromLmscript(modelName, {\n promptTokens,\n completionTokens,\n totalTokens: usageTotal,\n });\n\n if (this.costTracker) {\n this.bus.emit(\"cost_update\", {\n iteration,\n totalTokens: this.costTracker.getTotalTokens(),\n totalCost: this.costTracker.getTotalCost(this.modelPricing),\n });\n }\n }\n\n const choice = response?.choices?.[0];\n const content = (choice?.message?.content as string) ?? \"\";\n const toolCalls = choice?.message?.tool_calls;\n\n // Forward AI reasoning text\n if (content) {\n this.bus.emit(\"agent_thought\", {\n text: content,\n model: modelName,\n iteration,\n });\n }\n\n // ── No tool calls → final response ──\n if (!toolCalls || toolCalls.length === 0) {\n // Handle empty responses\n if (!content) {\n this.bus.emit(\"agent_thought\", {\n text: `Empty response from AI — iteration ${iteration}`,\n model: \"system\",\n });\n if (iteration < this.maxIterations) continue;\n }\n\n this.emitPhase(\"memory\", \"Recording interaction…\");\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: content }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: iteration,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n\n await this.middleware.runComplete(syntheticCtx, {\n data: content,\n raw: content,\n usage: totalUsage,\n } as any);\n return;\n }\n\n // ── Phase: Tools ──\n this.emitPhase(\"tools\", `Executing ${toolCalls.length} tool(s)…`);\n\n messages.push({\n role: \"assistant\",\n content: content || null,\n tool_calls: toolCalls,\n });\n\n // Track tools this round for narrative\n const roundTools: Array<{ command: string; success: boolean }> = [];\n\n for (let ti = 0; ti < toolCalls.length; ti++) {\n const tc = toolCalls[ti];\n if (this.interrupted) break;\n\n let args: Record<string, unknown>;\n try {\n args = JSON.parse(tc.function.arguments);\n } catch {\n args = {};\n }\n\n const command = (args.command as string) ?? tc.function.name;\n const kwargs = (args.kwargs as Record<string, unknown>) ?? {};\n const toolInputStr = JSON.stringify({ command, kwargs });\n\n // ── Permission check ──\n if (this.permissionGuard) {\n const outcome = this.permissionGuard.checkPermission(command, toolInputStr);\n if (outcome.kind === \"deny\") {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `Permission denied for tool \"${command}\": ${outcome.reason ?? \"denied by policy\"}`,\n });\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n }\n }\n\n // ── Pre-tool-use hooks ──\n if (this.hookIntegration) {\n const hookResult = this.hookIntegration.runPreToolUse(command, toolInputStr);\n if (hookResult.denied) {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `Tool \"${command}\" blocked by pre-use hook: ${hookResult.messages.join(\"; \")}`,\n });\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n }\n }\n\n // ── Duplicate detection + doom loop ──\n const callSig = JSON.stringify({ command, kwargs });\n const dupeCount = callHistory.filter((s) => s === callSig).length;\n callHistory.push(callSig);\n\n // Track consecutive dupes for doom loop detection\n const prevConsec = consecutiveDupes.get(command) ?? 0;\n consecutiveDupes.set(command, prevConsec + 1);\n\n if (dupeCount >= 2) {\n // ── Doom loop detection ──\n if (prevConsec >= 3 && !doomLoopRedirected) {\n doomLoopRedirected = true;\n this.emitPhase(\"doom\", `Doom loop detected: repeated calls to \"${command}\"`);\n this.bus.emit(\"doom_loop\", {\n reason: `Repeated calls to \"${command}\"`,\n command,\n count: prevConsec + 1,\n redirected: true,\n });\n // Inject a redirect message to break the pattern\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `STOP: You have been calling \"${command}\" repeatedly with the same arguments ${prevConsec + 1} times. `\n + `This is a doom loop. You MUST take a different approach. `\n + `Summarize what you know so far and either try a completely different strategy or provide your best answer.`,\n });\n } else if (doomLoopRedirected && prevConsec >= 5) {\n // Persistent doom loop — force termination\n this.emitPhase(\"doom\", `Persistent doom loop — terminating.`);\n this.bus.emit(\"doom_loop\", {\n reason: `Persistent doom loop on \"${command}\"`,\n command,\n count: prevConsec + 1,\n redirected: false,\n });\n // Break out of the tool loop and the iteration loop\n roundTools.push({ command, success: false });\n totalToolCalls++;\n\n // Emit tool round narrative before breaking\n if (roundTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(roundTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration,\n tools: roundTools,\n totalToolCalls,\n narrative,\n } as ToolRoundEvent);\n }\n\n // Force final response\n this.emitPhase(\"continuation\", \"Synthesizing response after doom loop…\");\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: content || \"I encountered a repeating pattern and am unable to make further progress. Here is what I have so far.\" }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"doom_loop\" });\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: iteration,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n await this.middleware.runComplete(syntheticCtx, {\n data: content || \"doom_loop_terminated\",\n raw: content,\n usage: totalUsage,\n } as any);\n return;\n } else {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `You already called \"${command}\" with these arguments ${dupeCount} time(s). Use the data you already have.`,\n });\n }\n\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n } else {\n // Reset consecutive counter for this command on a novel call\n consecutiveDupes.set(command, 0);\n }\n\n // ── Tool status: \"Running tool 1/3: read_file\" ──\n this.bus.emit(\"tool_execution_start\", { command, kwargs, index: ti, total: toolCalls.length });\n\n let result: string;\n let isError = false;\n try {\n result = await tool.execute(args);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n isError = true;\n }\n\n const resultStr = typeof result === \"string\" ? result : JSON.stringify(result);\n const truncated =\n resultStr.length > 8000\n ? resultStr.slice(0, 8000) +\n `\\n\\n[... truncated ${resultStr.length - 8000} characters.]`\n : resultStr;\n\n if (this.hookIntegration) {\n this.hookIntegration.runPostToolUse(command, toolInputStr, truncated, isError);\n }\n\n this.bus.emit(\"tool_execution_complete\", { command, kwargs, result: truncated, error: isError ? truncated : undefined });\n this.recordToolResult(command, kwargs, truncated);\n roundTools.push({ command, success: !isError });\n totalToolCalls++;\n\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: truncated,\n });\n }\n\n // ── Tool round narrative ──\n if (roundTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(roundTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration,\n tools: roundTools,\n totalToolCalls,\n narrative,\n } as ToolRoundEvent);\n }\n }\n\n // ── Exhausted iterations fallback ──\n this.emitPhase(\"continuation\", \"Maximum iterations reached — synthesizing response…\");\n\n const fallbackMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: \"I reached the maximum number of iterations. Here is what I have so far.\" }],\n };\n await this.recordMessage(fallbackMsg);\n this.bus.emit(\"state_updated\", { reason: \"max_iterations\" });\n\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: this.maxIterations,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n\n await this.middleware.runComplete(syntheticCtx, {\n data: \"max_iterations_reached\",\n raw: \"\",\n usage: totalUsage,\n } as any);\n\n } catch (err) {\n this.stopHeartbeat();\n this.emitPhase(\"error\", `Error: ${err instanceof Error ? err.message : String(err)}`);\n if (!(err instanceof Error && err.message.includes(\"LLM call failed\"))) {\n await this.middleware.runError(\n syntheticCtx,\n err instanceof Error ? err : new Error(String(err))\n );\n }\n throw err;\n } finally {\n this.stopHeartbeat();\n }\n }\n\n /**\n * Stream an LLM call, emitting tokens in real-time, then aggregate into\n * a full StandardChatResponse (including accumulated tool calls).\n */\n private async streamAndAggregate(\n provider: ProviderLike,\n params: import(\"@sschepis/llm-wrapper\").StandardChatParams\n ): Promise<StandardChatResponse> {\n const stream = provider.stream({ ...params, stream: true });\n\n const chunks: StandardChatChunk[] = [];\n for await (const chunk of stream) {\n chunks.push(chunk);\n\n const delta = chunk.choices?.[0]?.delta;\n if (delta?.content) {\n this.onToken!(delta.content);\n this.bus.emit(\"token\", { text: delta.content });\n }\n }\n\n async function* replay(): AsyncIterable<StandardChatChunk> {\n for (const c of chunks) yield c;\n }\n return aggregateStream(replay());\n }\n}\n","import type { AgentEventType, AgentEvent } from \"./types.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * Platform-agnostic typed event bus.\n * Uses a plain Map instead of Node.js EventEmitter for browser/Deno/Bun compatibility.\n */\nexport class AgentEventBus {\n private listeners = new Map<AgentEventType, Set<EventHandler>>();\n\n /** Subscribe to an event type. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n return () => this.off(type, handler);\n }\n\n /** Unsubscribe a handler from an event type. */\n off(type: AgentEventType, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n /** Subscribe to an event type for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n const wrapper: EventHandler = (event) => {\n this.off(type, wrapper);\n handler(event);\n };\n return this.on(type, wrapper);\n }\n\n /** Emit an event to all subscribers. */\n emit(type: AgentEventType, payload: unknown): void {\n const event: AgentEvent = {\n type,\n payload,\n timestamp: Date.now(),\n };\n const handlers = this.listeners.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n }\n\n /** Remove all listeners for all event types. */\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { z } from \"zod\";\nimport { ContextStack, type LScriptRuntime, type ChatMessage, type LScriptFunction } from \"@sschepis/lmscript\";\n\nconst SummarySchema = z.object({\n summary: z.string().describe(\"A dense summary of the conversation so far\"),\n});\n\ntype SummaryInput = { conversation: string };\n\n/**\n * Manages the sliding context window with automatic summarization.\n * Wraps lmscript's ContextStack and uses the local LLM for compression.\n */\nexport class ContextManager {\n private stack: ContextStack;\n private summarizeFn: LScriptFunction<SummaryInput, typeof SummarySchema>;\n\n constructor(\n private localRuntime: LScriptRuntime,\n localModelName: string,\n maxTokens: number\n ) {\n this.stack = new ContextStack({\n maxTokens,\n pruneStrategy: \"summarize\",\n });\n\n this.summarizeFn = {\n name: \"summarize_context\",\n model: localModelName,\n system:\n \"You are a summarization engine. Compress the given conversation into a dense, factual summary that preserves all key information, decisions, and context needed for continued operation. Be concise but thorough.\",\n prompt: ({ conversation }) => conversation,\n schema: SummarySchema,\n temperature: 0.2,\n maxRetries: 1,\n };\n\n this.stack.setSummarizer(async (messages: ChatMessage[]) => {\n const conversation = messages\n .map((m) => {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\" \");\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n try {\n const result = await this.localRuntime.execute(this.summarizeFn, {\n conversation,\n });\n return result.data.summary;\n } catch (err) {\n // If the local LLM fails (timeout, schema error, etc.), fall back\n // to a simple truncation so we don't crash the agent loop.\n console.warn(\n \"[ContextManager] Summarization failed, using truncation fallback:\",\n err instanceof Error ? err.message : err\n );\n // Keep last ~500 chars of each message as a crude summary\n return messages\n .slice(-3)\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex]\";\n return `${m.role}: ${text.slice(-500)}`;\n })\n .join(\"\\n\");\n }\n });\n }\n\n /** Append a message to the context. Triggers pruning if over budget. */\n async push(message: ChatMessage): Promise<void> {\n await this.stack.push(message);\n }\n\n /** Append multiple messages. */\n async pushAll(messages: ChatMessage[]): Promise<void> {\n await this.stack.pushAll(messages);\n }\n\n /** Get all messages in the current context window. */\n getMessages(): ChatMessage[] {\n return this.stack.getMessages();\n }\n\n /** Get estimated token count. */\n getTokenCount(): number {\n return this.stack.getTokenCount();\n }\n\n /** Clear all context. */\n clear(): void {\n this.stack.clear();\n }\n}\n","import { z } from \"zod\";\nimport type { LScriptFunction } from \"@sschepis/lmscript\";\n\n/** Zod schema for structured triage output. */\nexport const TriageSchema = z.object({\n escalate: z\n .boolean()\n .describe(\"True if the request needs a powerful model, false if answerable directly\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of the triage decision\"),\n directResponse: z\n .string()\n .nullish()\n .transform(v => v ?? undefined)\n .describe(\"Direct answer if the request can be handled without escalation\"),\n});\n\nexport type TriageInput = {\n userInput: string;\n recentContext: string;\n availableTools: string;\n};\n\nconst TRIAGE_SYSTEM = `You are a fast triage classifier for an AI agent system.\nYour job is to decide whether a user's request can be answered directly (simple queries,\ncasual chat, short lookups) or needs to be escalated to a more powerful model\n(complex reasoning, multi-step tool usage, code generation, analysis).\n\nRules:\n- Only respond directly for truly trivial exchanges: greetings, thanks, or very simple factual questions.\n- When responding directly, use a natural, warm, conversational tone. Do NOT list capabilities or describe what tools you have access to.\n- If the user's message could benefit from tool usage or detailed reasoning, always escalate.\n- If the request needs tool calls, code analysis, or multi-step reasoning: escalate.\n- If unsure, escalate. It's better to over-escalate than to give a poor direct answer.\n- Keep directResponse under 200 words when answering directly.\n- Pay attention to the recent context — if the user is continuing a conversation, your response should reflect that context.\n\nRespond with JSON matching the schema.`;\n\n/**\n * Create an LScriptFunction for local-LLM triage classification.\n * The local model evaluates whether input needs escalation to the remote model.\n */\nexport function createTriageFunction(\n modelName: string\n): LScriptFunction<TriageInput, typeof TriageSchema> {\n return {\n name: \"triage\",\n model: modelName,\n system: TRIAGE_SYSTEM,\n prompt: ({ userInput, recentContext, availableTools }) =>\n `Recent context:\\n${recentContext}\\n\\nAvailable tools: ${availableTools}\\n\\nUser: ${userInput}`,\n schema: TriageSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n","import { z } from \"zod\";\nimport type { Router } from \"@sschepis/swiss-army-tool\";\nimport { generateToolSchema } from \"@sschepis/swiss-army-tool\";\nimport type { ToolDefinition } from \"@sschepis/lmscript\";\nimport type { BranchNode } from \"@sschepis/swiss-army-tool\";\n\n/** Parameter schema for the omni-tool bridge. */\nconst RouterToolParams = z.object({\n command: z.string().describe(\n \"The command or menu path (e.g., 'help', 'filesystem read', 'db query')\"\n ),\n kwargs: z\n .record(z.unknown())\n .optional()\n .default({})\n .describe(\"Key-value arguments for the command\"),\n});\n\n/**\n * Bridge a swiss-army-tool Router into an lmscript ToolDefinition.\n *\n * The LLM sees a single tool (\"terminal_interface\") with `command` and `kwargs`\n * parameters. When called, it routes through the swiss-army-tool command tree.\n */\nexport function createRouterTool(\n router: Router,\n root?: BranchNode\n): ToolDefinition<typeof RouterToolParams, string> {\n const schema = generateToolSchema({ root });\n\n return {\n name: schema.name,\n description: schema.description,\n parameters: RouterToolParams,\n execute: async (params) => {\n return router.execute(params.command, params.kwargs ?? {});\n },\n };\n}\n","import type { LLMProvider, LLMRequest, LLMResponse } from \"@sschepis/lmscript\";\nimport type {\n BaseProvider,\n StandardChatParams,\n Message,\n ToolDefinition as WrapperToolDef,\n} from \"@sschepis/llm-wrapper\";\nimport type { LLMRouter } from \"@sschepis/llm-wrapper\";\n\n/**\n * A provider-like object that has `chat()` and `stream()` methods.\n * Both `BaseProvider` and `LLMRouter` implement this interface.\n */\ntype ProviderLike = {\n chat(params: StandardChatParams): Promise<import(\"@sschepis/llm-wrapper\").StandardChatResponse>;\n stream(params: StandardChatParams): AsyncIterable<import(\"@sschepis/llm-wrapper\").StandardChatChunk>;\n readonly providerName?: string;\n};\n\n/**\n * Convert lmscript messages to llm-wrapper messages.\n */\nfunction convertMessages(messages: LLMRequest[\"messages\"]): Message[] {\n return messages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { type: \"text\"; text: string }).text)\n .join(\"\\n\"),\n }));\n}\n\n/**\n * Convert lmscript tool format to llm-wrapper tool definitions.\n */\nfunction convertTools(tools?: LLMRequest[\"tools\"]): WrapperToolDef[] | undefined {\n if (!tools || tools.length === 0) return undefined;\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters as Record<string, unknown>,\n },\n }));\n}\n\n/**\n * Build llm-wrapper StandardChatParams from an lmscript LLMRequest.\n */\nfunction buildParams(request: LLMRequest, tools?: WrapperToolDef[]): StandardChatParams {\n return {\n model: request.model,\n messages: convertMessages(request.messages),\n temperature: request.temperature,\n ...(tools ? { tools } : {}),\n ...(request.jsonMode\n ? { response_format: { type: \"json_object\" as const } }\n : {}),\n };\n}\n\n/**\n * Adapt a llm-wrapper BaseProvider (or LLMRouter) into lmscript's LLMProvider interface.\n *\n * This allows lmscript's LScriptRuntime to use llm-wrapper providers for\n * structured calls (e.g. triage) that need schema validation.\n *\n * Bridges both `chat()` and `chatStream()` — enabling streaming through the\n * full lmscript stack (including `executeStream()`).\n */\nexport function toLmscriptProvider(\n provider: ProviderLike,\n name?: string\n): LLMProvider {\n return {\n name: name ?? (provider as BaseProvider).providerName ?? \"llm-wrapper\",\n\n async chat(request: LLMRequest): Promise<LLMResponse> {\n const tools = convertTools(request.tools);\n const params = buildParams(request, tools);\n\n const response = await provider.chat(params);\n const choice = response.choices[0];\n\n // Convert tool calls back to lmscript format\n let toolCalls: LLMResponse[\"toolCalls\"];\n if (choice?.message?.tool_calls) {\n toolCalls = choice.message.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }));\n }\n\n return {\n content: (choice?.message?.content as string) ?? \"\",\n usage: response.usage\n ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n }\n : undefined,\n toolCalls,\n };\n },\n\n async *chatStream(request: LLMRequest): AsyncIterable<string> {\n const tools = convertTools(request.tools);\n const params = buildParams(request, tools);\n\n for await (const chunk of provider.stream({ ...params, stream: true })) {\n const delta = chunk.choices?.[0]?.delta;\n if (delta?.content) {\n yield delta.content;\n }\n }\n },\n };\n}\n","import {\n MessageRole,\n type ConversationMessage,\n type ContentBlock as AsContentBlock,\n type Session,\n} from \"@sschepis/as-agent\";\nimport type { ChatMessage, Role } from \"@sschepis/lmscript\";\n\nconst ROLE_TO_STRING: Record<MessageRole, Role> = {\n [MessageRole.System]: \"system\",\n [MessageRole.User]: \"user\",\n [MessageRole.Assistant]: \"assistant\",\n [MessageRole.Tool]: \"user\",\n};\n\nconst STRING_TO_ROLE: Record<Role, MessageRole> = {\n system: MessageRole.System,\n user: MessageRole.User,\n assistant: MessageRole.Assistant,\n};\n\n/** Extract plain text from as-agent content blocks. */\nfunction blocksToText(blocks: AsContentBlock[]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool call: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Tool error (${b.toolName}): ${b.output}]`\n : `[Tool result (${b.toolName}): ${b.output}]`;\n }\n })\n .join(\"\\n\");\n}\n\n/** Convert an as-agent ConversationMessage to an lmscript ChatMessage. */\nexport function toChat(msg: ConversationMessage): ChatMessage {\n return {\n role: ROLE_TO_STRING[msg.role] ?? \"user\",\n content: blocksToText(msg.blocks),\n };\n}\n\n/** Convert an lmscript ChatMessage to an as-agent ConversationMessage. */\nexport function fromChat(msg: ChatMessage): ConversationMessage {\n const text = typeof msg.content === \"string\"\n ? msg.content\n : msg.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n\n return {\n role: STRING_TO_ROLE[msg.role] ?? MessageRole.User,\n blocks: [{ kind: \"text\", text }],\n };\n}\n\n/** Convert an entire as-agent Session to an array of lmscript ChatMessages. */\nexport function sessionToHistory(session: Session): ChatMessage[] {\n return session.messages.map(toChat);\n}\n\n/** Create an empty as-agent Session. */\nexport function createEmptySession(): Session {\n return { version: 1, messages: [] };\n}\n","/**\n * rag-integration.ts — RAG pipeline integration with oboto-agent conversation history.\n *\n * This module bridges lmscript's RAG pipeline, embedding provider, and vector store\n * with the agent's conversation history (as-agent Sessions) and tool execution results.\n *\n * Key capabilities:\n * - Index conversation messages and tool results into a vector store\n * - Retrieve relevant past context when processing new user input\n * - Provide a RAG-augmented execution path for the agent\n */\n\nimport {\n RAGPipeline,\n MemoryVectorStore,\n type EmbeddingProvider,\n type VectorStore,\n type VectorSearchResult,\n type LScriptRuntime,\n type LScriptFunction,\n type ExecutionResult,\n} from \"@sschepis/lmscript\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\n\n// ── Types ─────────────────────────────────────────────────────────────\n\nexport interface ConversationRAGConfig {\n /** The embedding provider (e.g. OpenAI, local model) */\n embeddingProvider: EmbeddingProvider;\n\n /** Optional custom vector store. Defaults to MemoryVectorStore. */\n vectorStore?: VectorStore;\n\n /** Number of past context chunks to retrieve. Default: 5 */\n topK?: number;\n\n /** Minimum similarity score (0-1). Default: 0.3 */\n minScore?: number;\n\n /** Embedding model identifier. Default: provider's default */\n embeddingModel?: string;\n\n /**\n * Whether to automatically index conversation messages as they're added.\n * Default: true\n */\n autoIndex?: boolean;\n\n /**\n * Whether to index tool execution results.\n * Default: true\n */\n indexToolResults?: boolean;\n\n /** Maximum characters per indexed chunk. Longer messages are split. Default: 2000 */\n maxChunkSize?: number;\n\n /**\n * Custom context formatter for retrieved documents.\n * Default: numbered list with scores.\n */\n formatContext?: (results: VectorSearchResult[]) => string;\n}\n\nexport interface RAGRetrievalResult {\n /** Retrieved context string ready for prompt injection */\n context: string;\n /** Raw search results */\n results: VectorSearchResult[];\n /** Number of documents in the store */\n totalDocuments: number;\n}\n\n// ── ConversationRAG ──────────────────────────────────────────────────\n\n/**\n * ConversationRAG bridges lmscript's RAG pipeline with the agent's\n * conversation history and tool results.\n *\n * It maintains a vector store of conversation chunks and can retrieve\n * relevant past context for new queries. This is useful for:\n * - Long-running agent sessions where early context is pruned\n * - Multi-topic conversations where relevant past decisions need retrieval\n * - Tool result recall without re-execution\n *\n * ```ts\n * const rag = new ConversationRAG(runtime, {\n * embeddingProvider: openaiEmbeddings,\n * topK: 5,\n * minScore: 0.3,\n * });\n *\n * // Index existing session history\n * await rag.indexSession(session);\n *\n * // Retrieve relevant context for a new query\n * const { context } = await rag.retrieve(\"What database schema did we discuss?\");\n *\n * // Or use RAG-augmented execution directly\n * const result = await rag.executeWithContext(myFn, input, \"search query\");\n * ```\n */\nexport class ConversationRAG {\n private vectorStore: VectorStore;\n private embeddingProvider: EmbeddingProvider;\n private ragPipeline: RAGPipeline;\n private config: Required<ConversationRAGConfig>;\n private indexedMessageCount = 0;\n private runtime: LScriptRuntime;\n\n constructor(runtime: LScriptRuntime, config: ConversationRAGConfig) {\n this.runtime = runtime;\n this.vectorStore = config.vectorStore ?? new MemoryVectorStore();\n this.embeddingProvider = config.embeddingProvider;\n\n this.config = {\n embeddingProvider: config.embeddingProvider,\n vectorStore: this.vectorStore,\n topK: config.topK ?? 5,\n minScore: config.minScore ?? 0.3,\n embeddingModel: config.embeddingModel ?? \"\",\n autoIndex: config.autoIndex ?? true,\n indexToolResults: config.indexToolResults ?? true,\n maxChunkSize: config.maxChunkSize ?? 2000,\n formatContext: config.formatContext ?? defaultConversationContextFormatter,\n };\n\n this.ragPipeline = new RAGPipeline(runtime, {\n embeddingProvider: this.embeddingProvider,\n vectorStore: this.vectorStore,\n topK: this.config.topK,\n minScore: this.config.minScore,\n embeddingModel: this.config.embeddingModel,\n formatContext: this.config.formatContext,\n });\n }\n\n // ── Indexing ──────────────────────────────────────────────────────\n\n /**\n * Index an entire as-agent Session into the vector store.\n * Each message becomes one or more chunks (split by maxChunkSize).\n */\n async indexSession(session: Session): Promise<number> {\n const documents: Array<{ id: string; content: string; metadata?: Record<string, unknown> }> = [];\n\n for (let i = 0; i < session.messages.length; i++) {\n const msg = session.messages[i];\n const chunks = this.messageToChunks(msg, i);\n documents.push(...chunks);\n }\n\n if (documents.length > 0) {\n await this.ragPipeline.ingest(documents);\n this.indexedMessageCount += session.messages.length;\n }\n\n return documents.length;\n }\n\n /**\n * Index a single conversation message.\n * Call this after adding a message to the session for real-time indexing.\n */\n async indexMessage(msg: ConversationMessage, messageIndex?: number): Promise<void> {\n const idx = messageIndex ?? this.indexedMessageCount;\n const chunks = this.messageToChunks(msg, idx);\n\n if (chunks.length > 0) {\n await this.ragPipeline.ingest(chunks);\n this.indexedMessageCount++;\n }\n }\n\n /**\n * Index a tool execution result for later retrieval.\n */\n async indexToolResult(\n command: string,\n kwargs: Record<string, unknown>,\n result: string\n ): Promise<void> {\n if (!this.config.indexToolResults) return;\n\n const content = `Tool: ${command}\\nArgs: ${JSON.stringify(kwargs)}\\nResult: ${result}`;\n const chunks = this.splitChunks(content, `tool:${command}:${Date.now()}`);\n\n if (chunks.length > 0) {\n const documents = chunks.map((chunk, i) => ({\n id: chunk.id,\n content: chunk.content,\n metadata: {\n type: \"tool_result\",\n command,\n kwargs,\n chunkIndex: i,\n timestamp: Date.now(),\n },\n }));\n\n await this.ragPipeline.ingest(documents);\n }\n }\n\n // ── Retrieval ─────────────────────────────────────────────────────\n\n /**\n * Retrieve relevant past context for a query.\n * Returns formatted context string and raw results.\n */\n async retrieve(query: string): Promise<RAGRetrievalResult> {\n const [queryVector] = await this.embeddingProvider.embed(\n [query],\n this.config.embeddingModel || undefined\n );\n\n const results = await this.vectorStore.search(queryVector, this.config.topK);\n const filtered = results.filter(r => r.score >= this.config.minScore);\n const context = this.config.formatContext(filtered);\n const totalDocuments = await this.vectorStore.count();\n\n return { context, results: filtered, totalDocuments };\n }\n\n /**\n * Execute an lmscript function with RAG-augmented context from the\n * conversation history.\n *\n * This is the primary integration point — it uses lmscript's RAGPipeline\n * to inject relevant past conversation into the function's system prompt.\n */\n async executeWithContext<I, O extends import(\"zod\").ZodType>(\n fn: LScriptFunction<I, O>,\n input: I,\n queryText?: string\n ): Promise<{ result: ExecutionResult<import(\"zod\").infer<O>>; retrievedDocuments: VectorSearchResult[]; context: string }> {\n const ragResult = await this.ragPipeline.query(fn, input, queryText);\n return {\n result: ragResult.result as ExecutionResult<O>,\n retrievedDocuments: ragResult.retrievedDocuments,\n context: ragResult.context,\n };\n }\n\n // ── Utility ───────────────────────────────────────────────────────\n\n /** Get the number of indexed messages. */\n get messageCount(): number {\n return this.indexedMessageCount;\n }\n\n /** Get the total number of document chunks in the vector store. */\n async documentCount(): Promise<number> {\n return this.vectorStore.count();\n }\n\n /** Clear the vector store and reset counters. */\n async clear(): Promise<void> {\n await this.vectorStore.clear();\n this.indexedMessageCount = 0;\n }\n\n /** Get the underlying vector store (for advanced usage). */\n getVectorStore(): VectorStore {\n return this.vectorStore;\n }\n\n /** Get the underlying RAG pipeline (for advanced usage). */\n getRagPipeline(): RAGPipeline {\n return this.ragPipeline;\n }\n\n // ── Private ───────────────────────────────────────────────────────\n\n private messageToChunks(\n msg: ConversationMessage,\n messageIndex: number\n ): Array<{ id: string; content: string; metadata?: Record<string, unknown> }> {\n const roleLabel = messageRoleToLabel(msg.role);\n const text = blocksToText(msg.blocks);\n\n if (!text.trim()) return [];\n\n const prefixed = `[${roleLabel}]: ${text}`;\n const baseId = `msg:${messageIndex}`;\n\n return this.splitChunks(prefixed, baseId).map((chunk, i) => ({\n id: chunk.id,\n content: chunk.content,\n metadata: {\n type: \"conversation\",\n role: roleLabel,\n messageIndex,\n chunkIndex: i,\n timestamp: Date.now(),\n },\n }));\n }\n\n private splitChunks(\n text: string,\n baseId: string\n ): Array<{ id: string; content: string }> {\n const maxSize = this.config.maxChunkSize;\n\n if (text.length <= maxSize) {\n return [{ id: baseId, content: text }];\n }\n\n // Split on paragraph boundaries first, then sentence boundaries\n const chunks: Array<{ id: string; content: string }> = [];\n let remaining = text;\n let chunkIdx = 0;\n\n while (remaining.length > 0) {\n let splitAt = maxSize;\n\n if (remaining.length > maxSize) {\n // Try to split at paragraph boundary\n const paraIdx = remaining.lastIndexOf(\"\\n\\n\", maxSize);\n if (paraIdx > maxSize * 0.3) {\n splitAt = paraIdx + 2;\n } else {\n // Try sentence boundary\n const sentIdx = remaining.lastIndexOf(\". \", maxSize);\n if (sentIdx > maxSize * 0.3) {\n splitAt = sentIdx + 2;\n }\n }\n } else {\n splitAt = remaining.length;\n }\n\n chunks.push({\n id: `${baseId}:${chunkIdx}`,\n content: remaining.slice(0, splitAt).trim(),\n });\n\n remaining = remaining.slice(splitAt);\n chunkIdx++;\n }\n\n return chunks;\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction messageRoleToLabel(role: MessageRole): string {\n switch (role) {\n case MessageRole.System: return \"system\";\n case MessageRole.User: return \"user\";\n case MessageRole.Assistant: return \"assistant\";\n case MessageRole.Tool: return \"tool\";\n default: return \"unknown\";\n }\n}\n\nfunction blocksToText(blocks: ConversationMessage[\"blocks\"]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Error: ${b.toolName}: ${b.output}]`\n : `[Result: ${b.toolName}: ${b.output}]`;\n default:\n return \"\";\n }\n })\n .join(\"\\n\");\n}\n\n/**\n * Default context formatter for conversation RAG results.\n * Shows role, score, and content for each retrieved chunk.\n */\nfunction defaultConversationContextFormatter(results: VectorSearchResult[]): string {\n if (results.length === 0) return \"\";\n\n return [\n \"## Relevant Past Context\",\n \"\",\n ...results.map((r, i) => {\n const meta = r.document.metadata as Record<string, unknown> | undefined;\n const type = meta?.type ?? \"unknown\";\n const score = r.score.toFixed(3);\n return `[${i + 1}] (${type}, score: ${score})\\n${r.document.content}`;\n }),\n ].join(\"\\n\");\n}\n","/**\n * as-agent-features.ts — Deep integration of @sschepis/as-agent's advanced features.\n *\n * This module bridges the following as-agent subsystems into oboto-agent:\n *\n * 1. **Permissions** — PermissionPolicy + PermissionPrompter for tool authorization\n * 2. **Session Compaction** — CompactionConfig for auto-compacting long sessions\n * 3. **Hooks** — HookRunner for pre/post tool-use shell hooks\n * 4. **Slash Commands** — AgentRuntime's slash command registry\n * 5. **Usage Tracking** — UsageTracker bridge (detailed impl in Task 11)\n */\n\nimport type {\n PermissionPolicy,\n PermissionPrompter,\n PermissionOutcome,\n PermissionMode,\n CompactionConfig,\n CompactionResult,\n HookRunner,\n HookRunResult,\n SlashCommandSpec,\n AgentRuntime,\n Session,\n ConversationMessage,\n TokenUsage as AsTokenUsage,\n UsageTracker,\n} from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n// ── Permission Guard ──────────────────────────────────────────────────\n\n/**\n * Wraps an as-agent PermissionPolicy to provide tool-call authorization\n * that integrates with the agent's event bus.\n *\n * Before each tool execution, `authorize()` is called. If the policy\n * denies the call, a `permission_denied` event is emitted and the tool\n * execution is skipped.\n *\n * ```ts\n * const guard = new PermissionGuard(policy, prompter, bus);\n * const outcome = guard.checkPermission(\"bash\", '{\"cmd\":\"rm -rf /\"}');\n * if (outcome.kind === \"deny\") { ... }\n * ```\n */\nexport class PermissionGuard {\n constructor(\n private policy: PermissionPolicy,\n private prompter: PermissionPrompter | null,\n private bus?: AgentEventBus,\n ) {}\n\n /**\n * Check whether a tool call is authorized.\n * Emits `permission_denied` on the event bus if denied.\n */\n checkPermission(toolName: string, toolInput: string): PermissionOutcome {\n const outcome = this.policy.authorize(toolName, toolInput, this.prompter);\n\n if (outcome.kind === \"deny\") {\n this.bus?.emit(\"permission_denied\", {\n toolName,\n toolInput,\n reason: outcome.reason ?? \"denied by policy\",\n activeMode: this.policy.activeMode,\n requiredMode: this.policy.requiredModeFor(toolName),\n });\n }\n\n return outcome;\n }\n\n /** Get the current active permission mode. */\n get activeMode(): PermissionMode {\n return this.policy.activeMode;\n }\n\n /** Get the required permission mode for a specific tool. */\n requiredModeFor(toolName: string): PermissionMode {\n return this.policy.requiredModeFor(toolName);\n }\n}\n\n// ── Session Compactor ─────────────────────────────────────────────────\n\n/**\n * Manages automatic and manual session compaction using as-agent's\n * CompactionConfig. Compaction summarizes older messages to stay within\n * token limits while preserving recent context.\n *\n * ```ts\n * const compactor = new SessionCompactor(bus, {\n * preserveRecentMessages: 10,\n * maxEstimatedTokens: 100_000,\n * });\n *\n * // Check and compact if needed\n * const result = compactor.compactIfNeeded(session, estimatedTokens);\n * ```\n */\nexport class SessionCompactor {\n private config: CompactionConfig;\n private bus?: AgentEventBus;\n private compactionCount = 0;\n private totalRemovedMessages = 0;\n\n constructor(bus: AgentEventBus | undefined, config: CompactionConfig) {\n this.bus = bus;\n this.config = config;\n }\n\n /**\n * Check if the session needs compaction and perform it if so.\n * Uses a simple heuristic: ~4 chars per token for estimation.\n *\n * Since the actual compaction logic lives in the Wasm runtime\n * (ConversationRuntime.compact()), this method provides a JS-side\n * implementation that creates a summary of older messages and\n * preserves recent ones.\n *\n * Returns null if compaction is not needed.\n */\n compactIfNeeded(\n session: Session,\n estimatedTokens?: number,\n ): CompactionResult | null {\n const tokenEstimate = estimatedTokens ?? this.estimateTokens(session);\n\n if (tokenEstimate <= this.config.maxEstimatedTokens) {\n return null;\n }\n\n return this.compact(session);\n }\n\n /**\n * Force compaction of the session regardless of token count.\n */\n compact(session: Session): CompactionResult {\n const preserve = this.config.preserveRecentMessages;\n const totalMessages = session.messages.length;\n\n if (totalMessages <= preserve) {\n // Nothing to compact\n return {\n summary: \"\",\n formattedSummary: \"\",\n compactedSession: session,\n removedMessageCount: 0,\n };\n }\n\n // Separate messages into \"to summarize\" and \"to preserve\"\n const toSummarize = session.messages.slice(0, totalMessages - preserve);\n const toPreserve = session.messages.slice(totalMessages - preserve);\n\n // Build a summary from the messages being removed\n const summaryParts: string[] = [];\n for (const msg of toSummarize) {\n const role = roleToString(msg.role);\n const text = blocksToText(msg.blocks);\n if (text.trim()) {\n summaryParts.push(`[${role}]: ${text}`);\n }\n }\n\n const summary = summaryParts.join(\"\\n\\n\");\n const formattedSummary = `[Session Compaction Summary — ${toSummarize.length} messages summarized]\\n\\n${summary}`;\n\n // Build the compacted session with a summary message + preserved messages\n const summaryMessage: ConversationMessage = {\n role: MessageRole.System,\n blocks: [{\n kind: \"text\",\n text: `[Previous conversation summary — ${toSummarize.length} messages compacted]\\n\\n${\n summary.length > 4000 ? summary.slice(0, 4000) + \"\\n\\n[... summary truncated]\" : summary\n }`,\n }],\n };\n\n const compactedSession: Session = {\n version: session.version,\n messages: [summaryMessage, ...toPreserve],\n };\n\n const result: CompactionResult = {\n summary,\n formattedSummary,\n compactedSession,\n removedMessageCount: toSummarize.length,\n };\n\n this.compactionCount++;\n this.totalRemovedMessages += toSummarize.length;\n\n this.bus?.emit(\"session_compacted\", {\n removedMessageCount: toSummarize.length,\n preservedMessageCount: toPreserve.length + 1, // +1 for summary msg\n estimatedTokensBefore: this.estimateTokens(session),\n estimatedTokensAfter: this.estimateTokens(compactedSession),\n compactionIndex: this.compactionCount,\n });\n\n return result;\n }\n\n /** Get compaction statistics. */\n get stats() {\n return {\n compactionCount: this.compactionCount,\n totalRemovedMessages: this.totalRemovedMessages,\n };\n }\n\n /** Update the compaction config at runtime. */\n updateConfig(config: Partial<CompactionConfig>): void {\n if (config.preserveRecentMessages !== undefined) {\n this.config.preserveRecentMessages = config.preserveRecentMessages;\n }\n if (config.maxEstimatedTokens !== undefined) {\n this.config.maxEstimatedTokens = config.maxEstimatedTokens;\n }\n }\n\n /** Estimate token count for a session (~4 chars per token). */\n private estimateTokens(session: Session): number {\n let charCount = 0;\n for (const msg of session.messages) {\n for (const block of msg.blocks) {\n if (block.kind === \"text\") {\n charCount += block.text.length;\n } else if (block.kind === \"tool_use\") {\n charCount += block.name.length + block.input.length;\n } else if (block.kind === \"tool_result\") {\n charCount += block.output.length;\n }\n }\n }\n return Math.ceil(charCount / 4);\n }\n}\n\n// ── Hook Integration ──────────────────────────────────────────────────\n\n/**\n * Wraps an as-agent HookRunner and integrates it with the agent's\n * event bus. Hooks are shell commands that run before and after\n * tool executions, allowing external validation/transformation.\n *\n * ```ts\n * const hooks = new HookIntegration(hookRunner, bus);\n * const pre = hooks.runPreToolUse(\"bash\", '{\"cmd\":\"ls\"}');\n * if (pre.denied) { /* skip tool call *\\/ }\n *\n * // After tool executes:\n * const post = hooks.runPostToolUse(\"bash\", '{\"cmd\":\"ls\"}', \"file1\\nfile2\", false);\n * ```\n */\nexport class HookIntegration {\n constructor(\n private runner: HookRunner,\n private bus?: AgentEventBus,\n ) {}\n\n /**\n * Run pre-tool-use hooks. If any hook denies the call,\n * the tool execution should be skipped.\n */\n runPreToolUse(toolName: string, toolInput: string): HookRunResult {\n const result = this.runner.runPreToolUse(toolName, toolInput);\n\n if (result.denied) {\n this.bus?.emit(\"hook_denied\", {\n phase: \"pre\",\n toolName,\n toolInput,\n messages: result.messages,\n });\n } else if (result.messages.length > 0) {\n this.bus?.emit(\"hook_message\", {\n phase: \"pre\",\n toolName,\n messages: result.messages,\n });\n }\n\n return result;\n }\n\n /**\n * Run post-tool-use hooks. These can log, transform, or audit\n * tool results but cannot retroactively deny execution.\n */\n runPostToolUse(\n toolName: string,\n toolInput: string,\n toolOutput: string,\n isError: boolean,\n ): HookRunResult {\n const result = this.runner.runPostToolUse(toolName, toolInput, toolOutput, isError);\n\n if (result.messages.length > 0) {\n this.bus?.emit(\"hook_message\", {\n phase: \"post\",\n toolName,\n messages: result.messages,\n });\n }\n\n return result;\n }\n}\n\n// ── Slash Command Registry ────────────────────────────────────────────\n\n/**\n * Bridges the as-agent Wasm runtime's slash command system with\n * oboto-agent. The Wasm runtime provides 21 built-in slash commands\n * (e.g. /help, /compact, /clear, /model, etc.).\n *\n * This class provides:\n * - Access to command specs and help text from the Wasm runtime\n * - An extensible registry for adding custom slash commands\n * - Parsing and dispatching of slash command input\n *\n * ```ts\n * const registry = new SlashCommandRegistry(agentRuntime);\n * const specs = registry.getCommandSpecs();\n * const help = registry.getHelpText();\n *\n * // Add custom commands\n * registry.registerCommand({\n * name: \"status\",\n * summary: \"Show agent status\",\n * argumentHint: \"\",\n * resumeSupported: false,\n * }, async (args) => \"Agent is running\");\n * ```\n */\nexport class SlashCommandRegistry {\n private customCommands = new Map<string, {\n spec: SlashCommandSpec;\n handler: (args: string) => string | Promise<string>;\n }>();\n private wasmRuntime?: AgentRuntime;\n\n constructor(wasmRuntime?: AgentRuntime) {\n this.wasmRuntime = wasmRuntime;\n }\n\n /**\n * Get all slash command specs (built-in from Wasm + custom).\n */\n getCommandSpecs(): SlashCommandSpec[] {\n const builtIn = this.wasmRuntime\n ? (this.wasmRuntime.slashCommandSpecs() as SlashCommandSpec[])\n : [];\n\n const custom = Array.from(this.customCommands.values()).map(c => c.spec);\n\n return [...builtIn, ...custom];\n }\n\n /**\n * Get the full help text for all commands.\n * Uses the Wasm runtime's formatted help if available.\n */\n getHelpText(): string {\n const parts: string[] = [];\n\n if (this.wasmRuntime) {\n parts.push(this.wasmRuntime.renderSlashCommandHelp());\n }\n\n if (this.customCommands.size > 0) {\n parts.push(\"\\n## Custom Commands\\n\");\n for (const [name, { spec }] of this.customCommands) {\n const hint = spec.argumentHint ? ` ${spec.argumentHint}` : \"\";\n parts.push(`/${name}${hint} — ${spec.summary}`);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Register a custom slash command.\n */\n registerCommand(\n spec: SlashCommandSpec,\n handler: (args: string) => string | Promise<string>,\n ): void {\n this.customCommands.set(spec.name, { spec, handler });\n }\n\n /**\n * Unregister a custom slash command.\n */\n unregisterCommand(name: string): boolean {\n return this.customCommands.delete(name);\n }\n\n /**\n * Parse a user input string to check if it's a slash command.\n * Returns the command name and arguments, or null if not a command.\n */\n parseCommand(input: string): { name: string; args: string } | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return null;\n\n const spaceIdx = trimmed.indexOf(\" \");\n const name = spaceIdx === -1\n ? trimmed.slice(1)\n : trimmed.slice(1, spaceIdx);\n const args = spaceIdx === -1\n ? \"\"\n : trimmed.slice(spaceIdx + 1).trim();\n\n return { name, args };\n }\n\n /**\n * Execute a custom slash command by name.\n * Returns the command output, or null if the command is not found\n * in the custom registry (it may be a built-in Wasm command).\n */\n async executeCustomCommand(name: string, args: string): Promise<string | null> {\n const entry = this.customCommands.get(name);\n if (!entry) return null;\n return entry.handler(args);\n }\n\n /**\n * Check if a command name exists (either built-in or custom).\n */\n hasCommand(name: string): boolean {\n if (this.customCommands.has(name)) return true;\n const specs = this.getCommandSpecs();\n return specs.some(s => s.name === name);\n }\n\n /**\n * Get only commands that support resume (useful for session restoration).\n */\n getResumeSupportedCommands(): SlashCommandSpec[] {\n const builtIn = this.wasmRuntime\n ? (this.wasmRuntime.resumeSupportedSlashCommands() as SlashCommandSpec[])\n : [];\n\n const custom = Array.from(this.customCommands.values())\n .filter(c => c.spec.resumeSupported)\n .map(c => c.spec);\n\n return [...builtIn, ...custom];\n }\n}\n\n// ── Usage Tracker Adapter ─────────────────────────────────────────────\n\n/**\n * A JS-side implementation of the as-agent UsageTracker interface.\n * This adapter accumulates token usage across turns, matching the\n * as-agent contract (inputTokens, outputTokens, cache tokens).\n *\n * The bridge to lmscript's CostTracker (which uses different field names)\n * is handled in Task 11.\n */\nexport class AgentUsageTracker implements UsageTracker {\n private turnUsages: AsTokenUsage[] = [];\n private currentTurn: AsTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n\n record(usage: AsTokenUsage): void {\n this.currentTurn = {\n inputTokens: this.currentTurn.inputTokens + usage.inputTokens,\n outputTokens: this.currentTurn.outputTokens + usage.outputTokens,\n cacheCreationInputTokens: this.currentTurn.cacheCreationInputTokens + usage.cacheCreationInputTokens,\n cacheReadInputTokens: this.currentTurn.cacheReadInputTokens + usage.cacheReadInputTokens,\n };\n }\n\n currentTurnUsage(): AsTokenUsage {\n return { ...this.currentTurn };\n }\n\n cumulativeUsage(): AsTokenUsage {\n const cumulative: AsTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n\n for (const usage of this.turnUsages) {\n cumulative.inputTokens += usage.inputTokens;\n cumulative.outputTokens += usage.outputTokens;\n cumulative.cacheCreationInputTokens += usage.cacheCreationInputTokens;\n cumulative.cacheReadInputTokens += usage.cacheReadInputTokens;\n }\n\n // Add current turn\n cumulative.inputTokens += this.currentTurn.inputTokens;\n cumulative.outputTokens += this.currentTurn.outputTokens;\n cumulative.cacheCreationInputTokens += this.currentTurn.cacheCreationInputTokens;\n cumulative.cacheReadInputTokens += this.currentTurn.cacheReadInputTokens;\n\n return cumulative;\n }\n\n turns(): number {\n return this.turnUsages.length + (this.hasTurnActivity() ? 1 : 0);\n }\n\n /**\n * Finalize the current turn and start a new one.\n * Call this at the end of each agent turn.\n */\n endTurn(): void {\n if (this.hasTurnActivity()) {\n this.turnUsages.push({ ...this.currentTurn });\n this.currentTurn = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n }\n }\n\n /** Reset all usage data. */\n reset(): void {\n this.turnUsages = [];\n this.currentTurn = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n }\n\n private hasTurnActivity(): boolean {\n return (\n this.currentTurn.inputTokens > 0 ||\n this.currentTurn.outputTokens > 0\n );\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────\n\nfunction roleToString(role: MessageRole): string {\n switch (role) {\n case MessageRole.System: return \"system\";\n case MessageRole.User: return \"user\";\n case MessageRole.Assistant: return \"assistant\";\n case MessageRole.Tool: return \"tool\";\n default: return \"unknown\";\n }\n}\n\nfunction blocksToText(blocks: ConversationMessage[\"blocks\"]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Error: ${b.toolName}: ${b.output}]`\n : `[Result: ${b.toolName}: ${b.output}]`;\n default:\n return \"\";\n }\n })\n .join(\"\\n\");\n}\n","/**\n * router-events.ts — Bridge LLMRouter health/failover events into the agent event bus.\n *\n * The LLMRouter (from @sschepis/llm-wrapper) exposes a `RouterEventEmitter` that\n * fires typed events for routing decisions, fallbacks, circuit breaker state changes,\n * and request completions/errors.\n *\n * This module:\n * 1. Subscribes to all LLMRouter events\n * 2. Forwards them to the agent's AgentEventBus as `router_event` events\n * 3. Provides a health snapshot method for observability\n */\n\nimport type {\n LLMRouter,\n RouterEventMap,\n HealthState,\n} from \"@sschepis/llm-wrapper\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n/** All LLMRouter event names we subscribe to. */\nconst ROUTER_EVENTS: (keyof RouterEventMap)[] = [\n \"route\",\n \"fallback\",\n \"circuit:open\",\n \"circuit:close\",\n \"circuit:half-open\",\n \"request:complete\",\n \"request:error\",\n];\n\n/**\n * Bridge that forwards LLMRouter events to the agent event bus.\n *\n * Usage:\n * ```ts\n * const bridge = new RouterEventBridge(bus);\n * bridge.attach(localRouter, \"local\");\n * bridge.attach(remoteRouter, \"remote\");\n *\n * // Later, get a health snapshot\n * const health = bridge.getHealthSnapshot();\n * ```\n */\nexport class RouterEventBridge {\n private bus: AgentEventBus;\n private attachedRouters = new Map<string, {\n router: LLMRouter;\n detachFns: Array<() => void>;\n }>();\n\n constructor(bus: AgentEventBus) {\n this.bus = bus;\n }\n\n /**\n * Attach an LLMRouter and forward all its events to the agent bus.\n *\n * @param router - The LLMRouter to monitor\n * @param label - A label to identify this router in events (e.g. \"local\", \"remote\")\n */\n attach(router: LLMRouter, label: string): void {\n // Detach if already attached with this label\n this.detach(label);\n\n const detachFns: Array<() => void> = [];\n\n for (const eventName of ROUTER_EVENTS) {\n const handler = (data: RouterEventMap[typeof eventName]) => {\n this.bus.emit(\"router_event\", {\n routerLabel: label,\n eventName,\n data,\n timestamp: Date.now(),\n });\n };\n\n router.events.on(eventName, handler as any);\n detachFns.push(() => {\n router.events.off(eventName, handler as any);\n });\n }\n\n this.attachedRouters.set(label, { router, detachFns });\n }\n\n /**\n * Detach a previously attached router.\n */\n detach(label: string): void {\n const entry = this.attachedRouters.get(label);\n if (entry) {\n for (const fn of entry.detachFns) {\n fn();\n }\n this.attachedRouters.delete(label);\n }\n }\n\n /**\n * Detach all attached routers.\n */\n detachAll(): void {\n for (const label of this.attachedRouters.keys()) {\n this.detach(label);\n }\n }\n\n /**\n * Get a health snapshot from all attached routers.\n * Returns a map of router label -> endpoint name -> HealthState.\n */\n getHealthSnapshot(): Map<string, Map<string, HealthState>> {\n const snapshot = new Map<string, Map<string, HealthState>>();\n\n for (const [label, { router }] of this.attachedRouters) {\n snapshot.set(label, router.getHealthState());\n }\n\n return snapshot;\n }\n\n /**\n * Check if any attached router has an endpoint in \"open\" (tripped) circuit state.\n */\n hasTrippedCircuits(): boolean {\n for (const [, { router }] of this.attachedRouters) {\n for (const [, health] of router.getHealthState()) {\n if (health.status === \"open\") return true;\n }\n }\n return false;\n }\n\n /**\n * Get the labels of all attached routers.\n */\n get labels(): string[] {\n return Array.from(this.attachedRouters.keys());\n }\n}\n\n/**\n * Helper to check if a ProviderLike is an LLMRouter (has `events` property).\n */\nexport function isLLMRouter(provider: unknown): provider is LLMRouter {\n return (\n typeof provider === \"object\" &&\n provider !== null &&\n \"events\" in provider &&\n \"getHealthState\" in provider\n );\n}\n","/**\n * usage-bridge.ts — Bidirectional bridge between as-agent's UsageTracker\n * and lmscript's CostTracker.\n *\n * Field mapping:\n * as-agent lmscript\n * ───────── ────────\n * inputTokens → promptTokens\n * outputTokens → completionTokens\n * cacheCreationInputTokens → (no equivalent, tracked separately)\n * cacheReadInputTokens → (no equivalent, tracked separately)\n * (sum of all) → totalTokens\n *\n * The bridge records every usage event into both systems, ensuring\n * unified cost accounting regardless of which subsystem reports usage.\n */\n\nimport type {\n TokenUsage as AsTokenUsage,\n UsageTracker,\n ModelPricing as AsModelPricing,\n UsageCostEstimate,\n} from \"@sschepis/as-agent\";\nimport type {\n CostTracker,\n ModelPricing as LmModelPricing,\n} from \"@sschepis/lmscript\";\nimport { AgentUsageTracker } from \"./as-agent-features.js\";\n\n// ── Type converters ──────────────────────────────────────────────────\n\n/**\n * Convert as-agent TokenUsage to lmscript usage format.\n */\nexport function asTokenUsageToLmscript(usage: AsTokenUsage): {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n} {\n const promptTokens = usage.inputTokens;\n const completionTokens = usage.outputTokens;\n // Total includes all token types (input + output + cache tokens)\n const totalTokens =\n usage.inputTokens +\n usage.outputTokens +\n usage.cacheCreationInputTokens +\n usage.cacheReadInputTokens;\n\n return { promptTokens, completionTokens, totalTokens };\n}\n\n/**\n * Convert lmscript usage format to as-agent TokenUsage.\n * Cache tokens default to 0 since lmscript doesn't track them separately.\n */\nexport function lmscriptToAsTokenUsage(usage: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}): AsTokenUsage {\n return {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n}\n\n// ── Cost estimation ──────────────────────────────────────────────────\n\n/**\n * Estimate costs using as-agent's ModelPricing (per-million-token pricing).\n */\nexport function estimateCostFromAsAgent(\n usage: AsTokenUsage,\n pricing: AsModelPricing,\n): UsageCostEstimate {\n const inputCostUsd = (usage.inputTokens / 1_000_000) * pricing.inputCostPerMillion;\n const outputCostUsd = (usage.outputTokens / 1_000_000) * pricing.outputCostPerMillion;\n const cacheCreationCostUsd = (usage.cacheCreationInputTokens / 1_000_000) * pricing.cacheCreationCostPerMillion;\n const cacheReadCostUsd = (usage.cacheReadInputTokens / 1_000_000) * pricing.cacheReadCostPerMillion;\n const totalCostUsd = inputCostUsd + outputCostUsd + cacheCreationCostUsd + cacheReadCostUsd;\n\n return {\n inputCostUsd,\n outputCostUsd,\n cacheCreationCostUsd,\n cacheReadCostUsd,\n totalCostUsd,\n };\n}\n\n// ── Usage Bridge ─────────────────────────────────────────────────────\n\n/**\n * Bidirectional bridge that keeps an as-agent UsageTracker and an\n * lmscript CostTracker in sync.\n *\n * When usage is reported from either side, the bridge records it in\n * both tracking systems.\n *\n * ```ts\n * const bridge = new UsageBridge(usageTracker, costTracker);\n *\n * // Record from LLM response (lmscript format)\n * bridge.recordFromLmscript(\"gpt-4\", { promptTokens: 100, completionTokens: 50, totalTokens: 150 });\n *\n * // Record from API response (as-agent format)\n * bridge.recordFromAsAgent({ inputTokens: 100, outputTokens: 50, cacheCreationInputTokens: 0, cacheReadInputTokens: 0 });\n *\n * // Get unified cost summary\n * const summary = bridge.getCostSummary(lmModelPricing, asModelPricing);\n * ```\n */\nexport class UsageBridge {\n constructor(\n private asTracker: AgentUsageTracker,\n private lmTracker?: CostTracker,\n ) {}\n\n /**\n * Record usage from an lmscript-format source (e.g. from the streaming path\n * or AgentLoop result).\n *\n * Converts to as-agent format and records in both trackers.\n */\n recordFromLmscript(\n functionName: string,\n usage: { promptTokens: number; completionTokens: number; totalTokens: number },\n ): void {\n // Record in lmscript CostTracker\n this.lmTracker?.trackUsage(functionName, usage);\n\n // Convert and record in as-agent tracker\n this.asTracker.record(lmscriptToAsTokenUsage(usage));\n }\n\n /**\n * Record usage from an as-agent-format source (e.g. from ConversationRuntime\n * or the Wasm runtime).\n *\n * Converts to lmscript format and records in both trackers.\n */\n recordFromAsAgent(\n usage: AsTokenUsage,\n functionName?: string,\n ): void {\n // Record in as-agent tracker\n this.asTracker.record(usage);\n\n // Convert and record in lmscript CostTracker\n if (this.lmTracker) {\n this.lmTracker.trackUsage(\n functionName ?? \"as-agent\",\n asTokenUsageToLmscript(usage),\n );\n }\n }\n\n /**\n * End the current turn in the as-agent tracker.\n */\n endTurn(): void {\n this.asTracker.endTurn();\n }\n\n /**\n * Get unified cost summary combining both tracking systems.\n */\n getCostSummary(\n lmPricing?: LmModelPricing,\n asPricing?: AsModelPricing,\n ): UnifiedCostSummary {\n const asUsage = this.asTracker.cumulativeUsage();\n const asTurns = this.asTracker.turns();\n\n // as-agent side cost estimation\n let asCostEstimate: UsageCostEstimate | undefined;\n if (asPricing) {\n asCostEstimate = estimateCostFromAsAgent(asUsage, asPricing);\n }\n\n // lmscript side totals\n let lmTotalTokens: number | undefined;\n let lmTotalCost: number | undefined;\n let lmByFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }> | undefined;\n\n if (this.lmTracker) {\n lmTotalTokens = this.lmTracker.getTotalTokens();\n lmTotalCost = this.lmTracker.getTotalCost(lmPricing);\n const usageMap = this.lmTracker.getUsageByFunction();\n lmByFunction = {};\n for (const [fnName, entry] of usageMap) {\n lmByFunction[fnName] = entry;\n }\n }\n\n return {\n // as-agent view\n asAgent: {\n usage: asUsage,\n turns: asTurns,\n costEstimate: asCostEstimate,\n },\n // lmscript view\n lmscript: this.lmTracker ? {\n totalTokens: lmTotalTokens!,\n totalCost: lmTotalCost!,\n byFunction: lmByFunction!,\n } : undefined,\n };\n }\n\n /**\n * Reset both tracking systems.\n */\n reset(): void {\n this.asTracker.reset();\n this.lmTracker?.reset();\n }\n\n /** Get the as-agent usage tracker. */\n getAsTracker(): AgentUsageTracker {\n return this.asTracker;\n }\n\n /** Get the lmscript cost tracker (if available). */\n getLmTracker(): CostTracker | undefined {\n return this.lmTracker;\n }\n}\n\n// ── Unified summary type ─────────────────────────────────────────────\n\nexport interface UnifiedCostSummary {\n /** as-agent's view: per-turn token counts and optional cost estimate. */\n asAgent: {\n usage: AsTokenUsage;\n turns: number;\n costEstimate?: UsageCostEstimate;\n };\n /** lmscript's view: total tokens, cost, and per-function breakdown. */\n lmscript?: {\n totalTokens: number;\n totalCost: number;\n byFunction: Record<string, {\n calls: number;\n totalTokens: number;\n promptTokens: number;\n completionTokens: number;\n }>;\n };\n}\n","/**\n * tool-extensions.ts — Swiss-army-tool integration extensions for oboto-agent.\n *\n * This module provides:\n * 1. AgentDynamicTools — A DynamicBranchNode subclass for runtime tool discovery\n * 2. createToolTimingMiddleware — Swiss-army-tool Middleware that emits timing events\n * 3. createAgentToolTree — Helper to build a pre-wired tool tree with memory + dynamic tools\n */\n\nimport {\n DynamicBranchNode,\n BranchNode,\n LeafNode,\n TreeBuilder,\n SessionManager,\n createMemoryModule,\n type Middleware,\n type ExecutionContext,\n} from \"@sschepis/swiss-army-tool\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n// ── Types ─────────────────────────────────────────────────────────────\n\nexport interface DynamicToolProvider {\n /**\n * Called when the branch needs refreshing.\n * Return an array of leaf node configs to populate the dynamic branch.\n */\n discover(): Promise<DynamicToolEntry[]> | DynamicToolEntry[];\n}\n\nexport interface DynamicToolEntry {\n name: string;\n description: string;\n requiredArgs?: string[] | Record<string, { type?: string; description?: string }>;\n optionalArgs?: string[] | Record<string, { type?: string; description?: string; default?: unknown }>;\n handler: (kwargs: Record<string, unknown>) => string | Promise<string>;\n}\n\nexport interface AgentToolTreeConfig {\n /** Session manager for the swiss-army-tool Router */\n session: SessionManager;\n /** Whether to include the memory module (set/get/list/pin). Default: true */\n includeMemory?: boolean;\n /** Additional static branches to add to the tree */\n staticBranches?: BranchNode[];\n /** Dynamic tool providers to register. Each entry becomes a DynamicBranchNode */\n dynamicProviders?: Array<{\n name: string;\n description: string;\n provider: DynamicToolProvider;\n /** TTL in ms before the provider is re-queried. Default: 60000 */\n ttlMs?: number;\n }>;\n}\n\n// ── AgentDynamicTools ─────────────────────────────────────────────────\n\n/**\n * A DynamicBranchNode that discovers tools at runtime from a provider.\n *\n * Use this to integrate external tool sources (MCP servers, plugin systems,\n * API discovery endpoints, etc.) into the swiss-army-tool command tree.\n *\n * The provider's `discover()` method is called when the TTL expires,\n * and the returned entries are registered as LeafNode children.\n *\n * ```ts\n * const mcpTools = new AgentDynamicTools({\n * name: \"mcp\",\n * description: \"Tools discovered from MCP servers\",\n * provider: myMcpProvider,\n * ttlMs: 30_000, // refresh every 30s\n * });\n * ```\n */\nexport class AgentDynamicTools extends DynamicBranchNode {\n private provider: DynamicToolProvider;\n\n constructor(config: {\n name: string;\n description: string;\n provider: DynamicToolProvider;\n ttlMs?: number;\n }) {\n super({\n name: config.name,\n description: config.description,\n ttlMs: config.ttlMs ?? 60_000,\n });\n this.provider = config.provider;\n }\n\n protected async refresh(): Promise<void> {\n const entries = await this.provider.discover();\n for (const entry of entries) {\n this.addChild(\n new LeafNode({\n name: entry.name,\n description: entry.description,\n requiredArgs: entry.requiredArgs as any,\n optionalArgs: entry.optionalArgs as any,\n handler: entry.handler,\n }),\n { overwrite: true }\n );\n }\n }\n\n /** Manually register a tool entry without waiting for refresh. */\n registerTool(entry: DynamicToolEntry): void {\n this.addChild(\n new LeafNode({\n name: entry.name,\n description: entry.description,\n requiredArgs: entry.requiredArgs as any,\n optionalArgs: entry.optionalArgs as any,\n handler: entry.handler,\n }),\n { overwrite: true }\n );\n }\n\n /** Remove a dynamically registered tool by name. */\n unregisterTool(name: string): boolean {\n return this.removeChild(name);\n }\n}\n\n// ── Middleware Factories ──────────────────────────────────────────────\n\n/**\n * Creates a swiss-army-tool Middleware that emits tool execution timing\n * and results through the agent's event bus.\n *\n * This bridges swiss-army-tool's execution context into oboto-agent's\n * event-driven architecture, enabling:\n * - Real-time tool execution duration monitoring\n * - Tool execution logging / tracing\n * - Performance analytics\n *\n * ```ts\n * const timingMw = createToolTimingMiddleware(agent.bus);\n * router.use(timingMw);\n * ```\n */\nexport function createToolTimingMiddleware(bus: AgentEventBus): Middleware {\n return async (ctx: ExecutionContext, next: () => Promise<string>) => {\n const startTime = Date.now();\n bus.emit(\"tool_execution_start\", {\n command: ctx.command,\n kwargs: ctx.kwargs,\n resolvedPath: ctx.resolvedPath,\n });\n\n try {\n const result = await next();\n const durationMs = Date.now() - startTime;\n\n bus.emit(\"tool_execution_complete\", {\n command: ctx.command,\n kwargs: ctx.kwargs,\n result: result.length > 500 ? result.slice(0, 500) + \"...\" : result,\n durationMs,\n });\n\n return result;\n } catch (err) {\n const durationMs = Date.now() - startTime;\n bus.emit(\"error\", {\n message: `Tool execution failed: ${ctx.command}`,\n error: err,\n durationMs,\n });\n throw err;\n }\n };\n}\n\n/**\n * Creates a swiss-army-tool Middleware that enforces a maximum execution\n * time for any tool call. Useful as a safety net.\n */\nexport function createToolTimeoutMiddleware(maxMs: number): Middleware {\n return async (_ctx: ExecutionContext, next: () => Promise<string>) => {\n const result = await Promise.race([\n next(),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(`Tool execution timed out after ${maxMs}ms`)),\n maxMs\n )\n ),\n ]);\n return result;\n };\n}\n\n/**\n * Creates a swiss-army-tool Middleware that logs all tool calls to the\n * session's KV store for later review. The agent can access these via\n * the memory module.\n */\nexport function createToolAuditMiddleware(session: SessionManager): Middleware {\n let callIndex = 0;\n\n return async (ctx: ExecutionContext, next: () => Promise<string>) => {\n const idx = ++callIndex;\n const startTime = Date.now();\n const result = await next();\n const durationMs = Date.now() - startTime;\n\n const entry = JSON.stringify({\n command: ctx.command,\n kwargs: ctx.kwargs,\n resultLength: result.length,\n durationMs,\n timestamp: new Date().toISOString(),\n });\n\n session.kvStore.set(`_audit:${idx}`, entry);\n return result;\n };\n}\n\n// ── Tool Tree Builder ────────────────────────────────────────────────\n\n/**\n * Build a pre-wired swiss-army-tool command tree that includes:\n * - Memory module (set/get/list/search/pin/unpin/delete/tag)\n * - Dynamic tool branches from providers\n * - Any additional static branches\n *\n * Returns the root BranchNode, ready to be passed to `new Router(root, session)`.\n *\n * ```ts\n * const root = createAgentToolTree({\n * session,\n * includeMemory: true,\n * dynamicProviders: [\n * { name: \"mcp\", description: \"MCP tools\", provider: mcpProvider },\n * ],\n * staticBranches: [myFilesystemBranch, myDatabaseBranch],\n * });\n * const router = new Router(root, session);\n * ```\n */\nexport function createAgentToolTree(config: AgentToolTreeConfig): BranchNode {\n const builder = TreeBuilder.create(\"root\", \"Agent command tree with integrated tools\");\n\n // Add memory module\n if (config.includeMemory !== false) {\n const memoryBranch = createMemoryModule(config.session);\n builder.addBranch(memoryBranch);\n }\n\n // Build the root first so we can add dynamic branches\n const root = builder.build();\n\n // Add dynamic tool providers\n if (config.dynamicProviders) {\n for (const dp of config.dynamicProviders) {\n const dynamicBranch = new AgentDynamicTools({\n name: dp.name,\n description: dp.description,\n provider: dp.provider,\n ttlMs: dp.ttlMs,\n });\n root.addChild(dynamicBranch);\n }\n }\n\n // Add additional static branches\n if (config.staticBranches) {\n for (const branch of config.staticBranches) {\n root.addChild(branch);\n }\n }\n\n return root;\n}\n","/**\n * pipeline-workflows.ts — Multi-step agent workflows using lmscript's Pipeline.\n *\n * This module provides pre-built and composable pipeline patterns for\n * chaining LLM calls where the typed output of one step feeds into the next.\n *\n * Key patterns:\n * 1. Triage → Execute → Summarize\n * 2. Analyze → Plan → Execute\n * 3. Custom pipeline builder for agent-specific workflows\n */\n\nimport { z } from \"zod\";\nimport {\n Pipeline,\n type LScriptRuntime,\n type LScriptFunction,\n type PipelineResult,\n} from \"@sschepis/lmscript\";\n\n// ── Schema definitions for pipeline steps ────────────────────────────\n\n/** Output of a triage step — determines routing and intent. */\nexport const TriagePipelineSchema = z.object({\n intent: z.string().describe(\"The classified intent of the user input\"),\n complexity: z.enum([\"simple\", \"moderate\", \"complex\"]).describe(\"Estimated task complexity\"),\n requiresTools: z.boolean().describe(\"Whether tools are needed\"),\n suggestedApproach: z.string().describe(\"Brief approach suggestion\"),\n escalate: z.boolean().describe(\"Whether to escalate to the remote model\"),\n});\nexport type TriagePipelineOutput = z.infer<typeof TriagePipelineSchema>;\n\n/** Output of a planning step — breaks work into steps. */\nexport const PlanSchema = z.object({\n steps: z.array(z.object({\n description: z.string(),\n toolRequired: z.string().optional(),\n expectedOutput: z.string().optional(),\n })).describe(\"Ordered list of steps to accomplish the task\"),\n estimatedComplexity: z.enum([\"low\", \"medium\", \"high\"]),\n reasoning: z.string().describe(\"Why this plan was chosen\"),\n});\nexport type PlanOutput = z.infer<typeof PlanSchema>;\n\n/** Output of an execution step — the actual work result. */\nexport const ExecutionSchema = z.object({\n response: z.string().describe(\"The response or result of executing the plan\"),\n stepsCompleted: z.number().describe(\"Number of plan steps completed\"),\n toolsUsed: z.array(z.string()).optional(),\n confidence: z.enum([\"low\", \"medium\", \"high\"]),\n});\nexport type ExecutionOutput = z.infer<typeof ExecutionSchema>;\n\n/** Output of a summarization step — condenses results. */\nexport const SummarySchema = z.object({\n summary: z.string().describe(\"Concise summary of what was accomplished\"),\n keyPoints: z.array(z.string()).describe(\"Key points from the execution\"),\n followUpSuggestions: z.array(z.string()).optional(),\n});\nexport type SummaryOutput = z.infer<typeof SummarySchema>;\n\n// ── Pipeline step factories ──────────────────────────────────────────\n\n/**\n * Create a triage step function for the pipeline.\n */\nexport function createTriageStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<string, typeof TriagePipelineSchema> {\n return {\n name: \"pipeline-triage\",\n model: modelName,\n system: systemPrompt ?? \"You are a task classifier. Analyze the input and determine its intent, complexity, and whether it requires tools or escalation.\",\n prompt: (input: string) => `Classify this request:\\n\\n${input}`,\n schema: TriagePipelineSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n\n/**\n * Create a planning step that takes triage output and produces a plan.\n */\nexport function createPlanStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<TriagePipelineOutput, typeof PlanSchema> {\n return {\n name: \"pipeline-plan\",\n model: modelName,\n system: systemPrompt ?? \"You are a task planner. Given the triage analysis, create a step-by-step plan to accomplish the task.\",\n prompt: (triage: TriagePipelineOutput) =>\n `Create an execution plan based on this analysis:\\n` +\n `Intent: ${triage.intent}\\n` +\n `Complexity: ${triage.complexity}\\n` +\n `Requires tools: ${triage.requiresTools}\\n` +\n `Suggested approach: ${triage.suggestedApproach}`,\n schema: PlanSchema,\n temperature: 0.3,\n maxRetries: 1,\n };\n}\n\n/**\n * Create an execution step that takes a plan and produces results.\n */\nexport function createExecutionStep(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n systemPrompt?: string,\n): LScriptFunction<PlanOutput, typeof ExecutionSchema> {\n return {\n name: \"pipeline-execute\",\n model: modelName,\n system: systemPrompt ?? \"You are a task executor. Follow the given plan step by step and produce the result.\",\n prompt: (plan: PlanOutput) => {\n const stepsStr = plan.steps\n .map((s, i) => `${i + 1}. ${s.description}${s.toolRequired ? ` (tool: ${s.toolRequired})` : \"\"}`)\n .join(\"\\n\");\n return `Execute this plan:\\n\\n${stepsStr}\\n\\nReasoning: ${plan.reasoning}`;\n },\n schema: ExecutionSchema,\n tools,\n temperature: 0.5,\n maxRetries: 1,\n };\n}\n\n/**\n * Create a summarization step that condenses execution results.\n */\nexport function createSummaryStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<ExecutionOutput, typeof SummarySchema> {\n return {\n name: \"pipeline-summarize\",\n model: modelName,\n system: systemPrompt ?? \"You are a summarizer. Condense the execution results into a clear, concise summary.\",\n prompt: (execution: ExecutionOutput) =>\n `Summarize these results:\\n` +\n `Response: ${execution.response}\\n` +\n `Steps completed: ${execution.stepsCompleted}\\n` +\n `Confidence: ${execution.confidence}\\n` +\n (execution.toolsUsed?.length ? `Tools used: ${execution.toolsUsed.join(\", \")}` : \"\"),\n schema: SummarySchema,\n temperature: 0.3,\n maxRetries: 1,\n };\n}\n\n// ── Pre-built pipeline constructors ──────────────────────────────────\n\n/**\n * Build a Triage → Plan → Execute pipeline.\n *\n * Takes raw user input, classifies it, plans the approach,\n * and executes the plan.\n *\n * ```ts\n * const pipeline = createTriagePlanExecutePipeline(\"gpt-4\");\n * const result = await pipeline.execute(runtime, \"Refactor the auth module\");\n * console.log(result.finalData.response);\n * ```\n */\nexport function createTriagePlanExecutePipeline(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n): Pipeline<string, ExecutionOutput> {\n return Pipeline\n .from(createTriageStep(modelName))\n .pipe(createPlanStep(modelName))\n .pipe(createExecutionStep(modelName, tools));\n}\n\n/**\n * Build a Triage → Plan → Execute → Summarize pipeline.\n *\n * Full end-to-end pipeline that classifies, plans, executes,\n * and then summarizes the results.\n *\n * ```ts\n * const pipeline = createFullPipeline(\"gpt-4\");\n * const result = await pipeline.execute(runtime, \"Build a REST API\");\n * console.log(result.finalData.summary);\n * console.log(`Total tokens: ${result.totalUsage.totalTokens}`);\n * ```\n */\nexport function createFullPipeline(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n): Pipeline<string, SummaryOutput> {\n return Pipeline\n .from(createTriageStep(modelName))\n .pipe(createPlanStep(modelName))\n .pipe(createExecutionStep(modelName, tools))\n .pipe(createSummaryStep(modelName));\n}\n\n/**\n * Build a simple Analyze → Respond pipeline.\n * Good for straightforward queries that don't need planning.\n */\nexport function createAnalyzeRespondPipeline(\n modelName: string,\n): Pipeline<string, ExecutionOutput> {\n const analyzeStep: LScriptFunction<string, typeof TriagePipelineSchema> = {\n name: \"pipeline-analyze\",\n model: modelName,\n system: \"You are an analyst. Understand the request and identify the best approach.\",\n prompt: (input: string) => `Analyze this request:\\n\\n${input}`,\n schema: TriagePipelineSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n\n const respondStep: LScriptFunction<TriagePipelineOutput, typeof ExecutionSchema> = {\n name: \"pipeline-respond\",\n model: modelName,\n system: \"You are a helpful assistant. Based on the analysis, provide a comprehensive response.\",\n prompt: (analysis: TriagePipelineOutput) =>\n `Respond to this request:\\n` +\n `Intent: ${analysis.intent}\\n` +\n `Approach: ${analysis.suggestedApproach}`,\n schema: ExecutionSchema,\n temperature: 0.7,\n maxRetries: 1,\n };\n\n return Pipeline.from(analyzeStep).pipe(respondStep);\n}\n\n// ── Pipeline runner helper ───────────────────────────────────────────\n\n/**\n * Configuration for running a pipeline within the agent context.\n */\nexport interface AgentPipelineConfig {\n /** The lmscript runtime to execute the pipeline on. */\n runtime: LScriptRuntime;\n /** The model name for all pipeline steps (can be overridden per-step). */\n modelName: string;\n /** Optional tools available to the execution step. */\n tools?: LScriptFunction<any, any>[\"tools\"];\n /** Callback for each pipeline step completion. */\n onStepComplete?: (stepName: string, data: unknown, usage: { promptTokens: number; completionTokens: number; totalTokens: number } | undefined) => void;\n}\n\n/**\n * Run a pipeline and emit step completion events.\n * This is a convenience wrapper that adds observability.\n */\nexport async function runAgentPipeline<I, O>(\n pipeline: Pipeline<I, O>,\n input: I,\n config: AgentPipelineConfig,\n): Promise<PipelineResult<O>> {\n const result = await pipeline.execute(config.runtime, input);\n\n if (config.onStepComplete) {\n for (const step of result.steps) {\n config.onStepComplete(step.name, step.data, step.usage);\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["MessageRole","z","z","MessageRole","blocksToText","MessageRole","blocksToText","MessageRole","z","z","SummarySchema"]}
1
+ {"version":3,"sources":["../src/oboto-agent.ts","../src/event-bus.ts","../src/context-manager.ts","../src/triage.ts","../src/adapters/tools.ts","../src/adapters/llm-wrapper.ts","../src/adapters/memory.ts","../src/adapters/rag-integration.ts","../src/adapters/as-agent-features.ts","../src/adapters/router-events.ts","../src/adapters/usage-bridge.ts","../src/adapters/tool-extensions.ts","../src/adapters/pipeline-workflows.ts"],"sourcesContent":["import {\n LScriptRuntime,\n MiddlewareManager,\n ExecutionCache,\n MemoryCacheBackend,\n CostTracker,\n RateLimiter,\n AgentLoop,\n type ToolDefinition,\n type ChatMessage,\n type AgentConfig,\n type ToolCall,\n type BudgetConfig,\n type ModelPricing,\n} from \"@sschepis/lmscript\";\nimport type {\n StandardChatChunk,\n StandardChatResponse,\n} from \"@sschepis/llm-wrapper\";\nimport { aggregateStream } from \"@sschepis/llm-wrapper\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type {\n ObotoAgentConfig, AgentEventType, AgentEvent, TriageResult, ProviderLike,\n AgentPhase, ToolRoundEvent,\n} from \"./types.js\";\nimport { AgentEventBus } from \"./event-bus.js\";\nimport { ContextManager } from \"./context-manager.js\";\nimport { createTriageFunction } from \"./triage.js\";\nimport { createRouterTool } from \"./adapters/tools.js\";\nimport { toLmscriptProvider } from \"./adapters/llm-wrapper.js\";\nimport { toChat, createEmptySession, sessionToHistory } from \"./adapters/memory.js\";\nimport { ConversationRAG } from \"./adapters/rag-integration.js\";\nimport {\n PermissionGuard,\n SessionCompactor,\n HookIntegration,\n SlashCommandRegistry,\n AgentUsageTracker,\n} from \"./adapters/as-agent-features.js\";\nimport { RouterEventBridge, isLLMRouter } from \"./adapters/router-events.js\";\nimport { UsageBridge, type UnifiedCostSummary } from \"./adapters/usage-bridge.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * ObotoAgent is the central orchestrator for dual-LLM agent execution.\n *\n * It binds together:\n * - llm-wrapper (LLM communication via local and remote providers / LLMRouter)\n * - lmscript (structured/schema-validated calls, agent loop, infrastructure)\n * - swiss-army-tool (tool execution via Router)\n * - as-agent (session state and conversation history)\n *\n * All interaction flows through an event-driven architecture.\n *\n * Key integration improvements (v0.2):\n * - Accepts LLMRouter for automatic failover and health tracking\n * - Uses lmscript's AgentLoop instead of a custom tool-calling loop\n * - Wires lmscript infrastructure: cache, cost tracking, rate limiting, middleware\n * - Bridges streaming via chatStream through the full lmscript stack\n */\nexport class ObotoAgent {\n private bus = new AgentEventBus();\n private localRuntime: LScriptRuntime;\n private remoteRuntime: LScriptRuntime;\n private localProvider: ProviderLike;\n private remoteProvider: ProviderLike;\n private contextManager: ContextManager;\n private routerTool: ToolDefinition<any, any>;\n private triageFn: ReturnType<typeof createTriageFunction>;\n private session: Session;\n private isProcessing = false;\n private interrupted = false;\n private systemPrompt: string;\n private maxIterations: number;\n private config: ObotoAgentConfig;\n private onToken?: (token: string) => void;\n private costTracker: CostTracker;\n private modelPricing?: ModelPricing;\n private rateLimiter?: RateLimiter;\n private middleware!: MiddlewareManager;\n private budget?: BudgetConfig;\n private conversationRAG?: ConversationRAG;\n private permissionGuard?: PermissionGuard;\n private sessionCompactor?: SessionCompactor;\n private hookIntegration?: HookIntegration;\n private slashCommands: SlashCommandRegistry;\n private usageTracker: AgentUsageTracker;\n private usageBridge: UsageBridge;\n private routerEventBridge: RouterEventBridge;\n private currentPhase: AgentPhase = \"request\";\n\n constructor(config: ObotoAgentConfig) {\n this.config = config;\n this.localProvider = config.localModel;\n this.remoteProvider = config.remoteModel;\n\n // ── Build lmscript providers from llm-wrapper providers ──────────\n const localLmscript = toLmscriptProvider(config.localModel, \"local\");\n const remoteLmscript = toLmscriptProvider(config.remoteModel, \"remote\");\n\n // ── Build middleware manager ─────────────────────────────────────\n this.middleware = new MiddlewareManager();\n if (config.middleware) {\n for (const hooks of config.middleware) {\n this.middleware.use(hooks);\n }\n }\n\n // ── Build cost tracker (shared across runtimes for unified reporting) ─\n // Always create a CostTracker so token counts are tracked even without pricing.\n // Pricing is passed to getTotalCost() when available.\n this.costTracker = new CostTracker();\n this.modelPricing = config.modelPricing;\n\n // ── Build local runtime (lightweight: cache for triage, no rate limit) ─\n // ExecutionCache takes only a CacheBackend; TTL is handled per-entry\n // by the MemoryCacheBackend.set(key, value, ttlMs) call\n const localCache = config.triageCacheTtlMs\n ? new ExecutionCache(new MemoryCacheBackend())\n : undefined;\n\n this.localRuntime = new LScriptRuntime({\n provider: localLmscript,\n defaultTemperature: 0.1,\n cache: localCache,\n costTracker: this.costTracker,\n });\n\n // ── Build remote runtime (full infrastructure) ──────────────────\n const remoteCache = config.cacheTtlMs\n ? new ExecutionCache(new MemoryCacheBackend())\n : undefined;\n\n const rateLimiter = config.rateLimit\n ? new RateLimiter(config.rateLimit)\n : undefined;\n this.rateLimiter = rateLimiter;\n this.budget = config.budget;\n\n this.remoteRuntime = new LScriptRuntime({\n provider: remoteLmscript,\n middleware: this.middleware,\n cache: remoteCache,\n costTracker: this.costTracker,\n budget: config.budget,\n rateLimiter,\n });\n\n // ── Session and context ─────────────────────────────────────────\n this.session = config.session ?? createEmptySession();\n this.systemPrompt = config.systemPrompt ?? \"You are a helpful AI assistant with access to tools.\";\n this.maxIterations = config.maxIterations ?? 10;\n this.onToken = config.onToken;\n\n this.contextManager = new ContextManager(\n this.localRuntime,\n config.localModelName,\n config.maxContextTokens ?? 8192\n );\n\n // ── Tool layer ──────────────────────────────────────────────────\n // Apply swiss-army-tool middleware if configured\n if (config.toolMiddleware) {\n for (const mw of config.toolMiddleware) {\n config.router.use(mw);\n }\n }\n\n this.routerTool = createRouterTool(config.router);\n this.triageFn = createTriageFunction(config.localModelName);\n\n // ── RAG pipeline (optional) ─────────────────────────────────────\n if (config.embeddingProvider) {\n this.conversationRAG = new ConversationRAG(this.remoteRuntime, {\n embeddingProvider: config.embeddingProvider,\n vectorStore: config.vectorStore,\n topK: config.ragTopK,\n minScore: config.ragMinScore,\n embeddingModel: config.ragEmbeddingModel,\n autoIndex: config.ragAutoIndex,\n indexToolResults: config.ragIndexToolResults,\n formatContext: config.ragFormatContext,\n });\n }\n\n // ── as-agent features ───────────────────────────────────────────\n // Permission guard (optional)\n if (config.permissionPolicy) {\n this.permissionGuard = new PermissionGuard(\n config.permissionPolicy,\n config.permissionPrompter ?? null,\n this.bus,\n );\n }\n\n // Session compaction (optional)\n if (config.compactionConfig) {\n this.sessionCompactor = new SessionCompactor(this.bus, config.compactionConfig);\n }\n\n // Hook runner (optional)\n if (config.hookRunner) {\n this.hookIntegration = new HookIntegration(config.hookRunner, this.bus);\n }\n\n // Slash command registry (always available, Wasm runtime optional)\n this.slashCommands = new SlashCommandRegistry(config.agentRuntime);\n\n // Usage tracker (always available)\n this.usageTracker = new AgentUsageTracker();\n\n // Usage bridge: unifies as-agent UsageTracker and lmscript CostTracker\n this.usageBridge = new UsageBridge(this.usageTracker, this.costTracker);\n\n // ── Router event bridge (auto-attach LLMRouters) ────────────────\n this.routerEventBridge = new RouterEventBridge(this.bus);\n if (isLLMRouter(config.localModel)) {\n this.routerEventBridge.attach(config.localModel, \"local\");\n }\n if (isLLMRouter(config.remoteModel)) {\n this.routerEventBridge.attach(config.remoteModel, \"remote\");\n }\n\n // Push system prompt into context\n this.contextManager.push({\n role: \"system\",\n content: this.systemPrompt,\n });\n\n // Seed context manager from existing session messages so triage\n // and execution paths see the full conversation history.\n if (this.session.messages.length > 0) {\n this.contextManager.pushAll(sessionToHistory(this.session));\n }\n }\n\n // ── Public API ─────────────────────────────────────────────────────\n\n /** Subscribe to agent events. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.on(type, handler);\n }\n\n /** Subscribe to an event for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n return this.bus.once(type, handler);\n }\n\n /** Submit user input to the agent. Triggers the execution loop. */\n async submitInput(text: string): Promise<void> {\n if (this.isProcessing) {\n this.interrupt(text);\n return;\n }\n\n // Check for slash commands first\n const parsedCmd = this.slashCommands.parseCommand(text);\n if (parsedCmd) {\n const result = await this.slashCommands.executeCustomCommand(parsedCmd.name, parsedCmd.args);\n if (result !== null) {\n this.bus.emit(\"slash_command\", {\n command: parsedCmd.name,\n args: parsedCmd.args,\n result,\n });\n return;\n }\n // If not a custom command, fall through to normal processing\n // (the Wasm runtime may handle it, or it's treated as regular input)\n }\n\n this.isProcessing = true;\n this.interrupted = false;\n\n try {\n await this.executionLoop(text);\n\n // End the usage tracker turn (via bridge)\n this.usageBridge.endTurn();\n\n // Auto-compact session if configured\n if (this.sessionCompactor) {\n const result = this.sessionCompactor.compactIfNeeded(this.session);\n if (result && result.removedMessageCount > 0) {\n this.session = result.compactedSession;\n }\n }\n } catch (err) {\n this.bus.emit(\"error\", {\n message: err instanceof Error ? err.message : String(err),\n error: err,\n });\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Interrupt the current execution loop.\n * Optionally inject new directives into the context.\n */\n async interrupt(newDirectives?: string): Promise<void> {\n this.interrupted = true;\n this.bus.emit(\"interruption\", { newDirectives });\n\n if (newDirectives) {\n const msg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: `[INTERRUPTION] ${newDirectives}` }],\n };\n await this.recordMessage(msg);\n this.bus.emit(\"state_updated\", { reason: \"interruption\" });\n }\n }\n\n /** Get the current session state. */\n getSession(): Session {\n return this.session;\n }\n\n /** Whether the agent is currently processing input. */\n get processing(): boolean {\n return this.isProcessing;\n }\n\n /** Get cost tracking summary (if cost tracking is enabled). */\n getCostSummary(): {\n totalCost: number;\n totalTokens: number;\n byFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }>;\n } | undefined {\n if (!this.costTracker) return undefined;\n\n const totalTokens = this.costTracker.getTotalTokens();\n const totalCost = this.costTracker.getTotalCost(this.modelPricing);\n\n // Convert Map to plain object for easier consumption\n const usageMap = this.costTracker.getUsageByFunction();\n const byFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }> = {};\n for (const [fnName, entry] of usageMap) {\n byFunction[fnName] = entry;\n }\n\n return { totalCost, totalTokens, byFunction };\n }\n\n /**\n * Get unified cost summary combining both as-agent and lmscript tracking.\n * Uses the UsageBridge to provide a single view of all token/cost data.\n */\n getUnifiedCostSummary(\n asPricing?: import(\"@sschepis/as-agent\").ModelPricing,\n ): UnifiedCostSummary {\n return this.usageBridge.getCostSummary(this.modelPricing, asPricing);\n }\n\n /** Get the usage bridge for direct access to unified tracking. */\n getUsageBridge(): UsageBridge {\n return this.usageBridge;\n }\n\n /** Remove all event listeners and detach router event subscriptions. */\n removeAllListeners(): void {\n this.bus.removeAllListeners();\n this.routerEventBridge.detachAll();\n }\n\n /** Sync session and repopulate context manager (for reuse across turns). */\n async syncSession(session: Session): Promise<void> {\n this.session = session;\n this.contextManager.clear();\n await this.contextManager.push({ role: \"system\", content: this.systemPrompt });\n if (session.messages.length > 0) {\n await this.contextManager.pushAll(sessionToHistory(session));\n }\n }\n\n /** Update the streaming token callback between turns. */\n setOnToken(callback: ((token: string) => void) | undefined): void {\n this.onToken = callback;\n }\n\n /** Get the ConversationRAG instance (if RAG is enabled). */\n getConversationRAG(): ConversationRAG | undefined {\n return this.conversationRAG;\n }\n\n /** Get the slash command registry. */\n getSlashCommands(): SlashCommandRegistry {\n return this.slashCommands;\n }\n\n /** Get the as-agent usage tracker. */\n getUsageTracker(): AgentUsageTracker {\n return this.usageTracker;\n }\n\n /** Get the permission guard (if permissions are configured). */\n getPermissionGuard(): PermissionGuard | undefined {\n return this.permissionGuard;\n }\n\n /** Get the session compactor (if compaction is configured). */\n getSessionCompactor(): SessionCompactor | undefined {\n return this.sessionCompactor;\n }\n\n /** Get the router event bridge for observability into LLMRouter health. */\n getRouterEventBridge(): RouterEventBridge {\n return this.routerEventBridge;\n }\n\n /**\n * Manually compact the session. Returns null if compaction is not configured.\n */\n compactSession(): import(\"@sschepis/as-agent\").CompactionResult | null {\n if (!this.sessionCompactor) return null;\n const result = this.sessionCompactor.compact(this.session);\n if (result.removedMessageCount > 0) {\n this.session = result.compactedSession;\n }\n return result;\n }\n\n /**\n * Retrieve relevant past context for a query via the RAG pipeline.\n * Returns undefined if RAG is not configured.\n */\n async retrieveContext(query: string): Promise<string | undefined> {\n if (!this.conversationRAG) return undefined;\n const { context } = await this.conversationRAG.retrieve(query);\n return context || undefined;\n }\n\n // ── Conversational helpers ──────────────────────────────────────────\n\n /** Emit a phase transition event with a human-readable message. */\n private emitPhase(phase: AgentPhase, message: string): void {\n this.currentPhase = phase;\n this.bus.emit(\"phase\", { phase, message });\n }\n\n /**\n * Build a human-readable narrative for a batch of tool executions.\n * Uses both command name and kwargs to produce accurate descriptions.\n * E.g. \"Just read file data, and edited files. Sending results back to AI for next steps…\"\n */\n private buildToolRoundNarrative(\n tools: Array<{ command: string; success: boolean; kwargs?: Record<string, unknown> }>\n ): string {\n if (tools.length === 0) return \"No tools executed.\";\n\n // Classify each tool call by examining both the command and its kwargs\n const verbs = new Map<string, string[]>();\n for (const t of tools) {\n const cmd = t.command.toLowerCase();\n const kw = t.kwargs || {};\n const kwStr = JSON.stringify(kw).toLowerCase();\n\n let verb: string;\n // Check kwargs for more specific classification\n if (kwStr.includes('\"cmd\"') && (kwStr.includes(\"cat \") || kwStr.includes(\"head \") || kwStr.includes(\"tail \"))) {\n verb = \"read file data\";\n } else if (kwStr.includes('\"cmd\"') && (kwStr.includes(\"ls \") || kwStr.includes(\"find \") || kwStr.includes(\"tree \"))) {\n verb = \"listed files\";\n } else if (kwStr.includes('\"cmd\"') && (kwStr.includes(\"grep \") || kwStr.includes(\"rg \") || kwStr.includes(\"ag \"))) {\n verb = \"searched for information\";\n } else if (cmd.includes(\"read\") || cmd.includes(\"get_file\") || cmd.includes(\"view\")) {\n verb = \"read file data\";\n } else if (cmd.includes(\"write\") || cmd.includes(\"edit\") || cmd.includes(\"patch\") || cmd.includes(\"update\")) {\n verb = \"edited files\";\n } else if (cmd.includes(\"search\") || cmd.includes(\"grep\") || cmd.includes(\"find\") || cmd.includes(\"glob\")) {\n verb = \"searched for information\";\n } else if (cmd.includes(\"list\") || cmd.includes(\"ls\")) {\n verb = \"listed items\";\n } else if (cmd.includes(\"run\") || cmd.includes(\"exec\") || cmd.includes(\"bash\") || cmd.includes(\"shell\")) {\n verb = \"ran a command\";\n } else if (cmd.includes(\"browse\") || cmd.includes(\"web\") || cmd.includes(\"fetch\")) {\n verb = \"browsed the web\";\n } else if (cmd.includes(\"surface\")) {\n verb = cmd.includes(\"read\") ? \"read surface data\" : \"accessed surfaces\";\n } else if (cmd.includes(\"help\")) {\n verb = \"checked available tools\";\n } else {\n verb = `used ${t.command}`;\n }\n if (!verbs.has(verb)) verbs.set(verb, []);\n verbs.get(verb)!.push(t.command);\n }\n\n const parts = Array.from(verbs.keys());\n let narrative: string;\n if (parts.length === 1) {\n narrative = `Just ${parts[0]}.`;\n } else if (parts.length === 2) {\n narrative = `Just ${parts[0]}, and ${parts[1]}.`;\n } else {\n const last = parts.pop()!;\n narrative = `Just ${parts.join(\", \")}, and ${last}.`;\n }\n\n const errors = tools.filter(t => !t.success);\n if (errors.length > 0) {\n const errNames = errors.map(e => e.command).join(\", \");\n narrative += ` (${errors.length} error${errors.length > 1 ? \"s\" : \"\"}: ${errNames})`;\n }\n\n narrative += \" Sending results back to AI for next steps…\";\n return narrative;\n }\n\n // ── Internal ───────────────────────────────────────────────────────\n\n /**\n * Record a message in the session, context manager, and optionally RAG index.\n * Centralizes message recording to ensure RAG indexing stays in sync.\n */\n private async recordMessage(msg: ConversationMessage): Promise<void> {\n this.session.messages.push(msg);\n await this.contextManager.push(toChat(msg));\n\n // Auto-index for RAG if enabled\n if (this.conversationRAG) {\n // Fire and forget — RAG indexing should not block the main loop\n this.conversationRAG.indexMessage(msg, this.session.messages.length - 1).catch((err) => {\n console.warn(\"[ObotoAgent] RAG indexing failed:\", err instanceof Error ? err.message : err);\n });\n }\n }\n\n /**\n * Record a tool execution result in the RAG index.\n */\n private recordToolResult(command: string, kwargs: Record<string, unknown>, result: string): void {\n if (this.conversationRAG) {\n this.conversationRAG.indexToolResult(command, kwargs, result).catch((err) => {\n console.warn(\"[ObotoAgent] RAG tool indexing failed:\", err instanceof Error ? err.message : err);\n });\n }\n }\n\n private async executionLoop(userInput: string): Promise<void> {\n // ── Phase: Request ──\n this.emitPhase(\"request\", `Processing: ${userInput.substring(0, 80)}${userInput.length > 80 ? \"…\" : \"\"}`);\n\n // 1. Emit user_input and record in session + context + RAG\n this.bus.emit(\"user_input\", { text: userInput });\n\n const userMsg: ConversationMessage = {\n role: MessageRole.User,\n blocks: [{ kind: \"text\", text: userInput }],\n };\n await this.recordMessage(userMsg);\n this.bus.emit(\"state_updated\", { reason: \"user_input\" });\n\n // ── Phase: Planning ──\n this.emitPhase(\"planning\", \"Building context and preparing tools…\");\n\n // 1b. Optionally augment context with RAG-retrieved past conversation\n if (this.conversationRAG) {\n try {\n const { context } = await this.conversationRAG.retrieve(userInput);\n if (context) {\n await this.contextManager.push({\n role: \"system\",\n content: context,\n });\n this.bus.emit(\"agent_thought\", {\n text: \"Retrieved relevant past context via RAG.\",\n model: \"system\",\n });\n }\n } catch (err) {\n console.warn(\"[ObotoAgent] RAG retrieval failed:\", err instanceof Error ? err.message : err);\n }\n }\n\n // ── Phase: Precheck (Triage) ──\n // StreamController's ActivityTracker handles heartbeat automatically\n // when phaseStart is called, so we don't need our own timer.\n this.emitPhase(\"precheck\", \"Checking if direct answer is possible…\");\n\n const triageResult = await this.triage(userInput);\n this.bus.emit(\"triage_result\", triageResult);\n\n if (this.interrupted) return;\n\n // 3. If local can handle directly, emit and return\n if (!triageResult.escalate && triageResult.directResponse) {\n const response = triageResult.directResponse;\n this.emitPhase(\"complete\", \"Answered directly — no tools needed.\");\n this.bus.emit(\"agent_thought\", { text: response, model: \"local\" });\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: response }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n this.bus.emit(\"turn_complete\", { model: \"local\", escalated: false });\n return;\n }\n\n // 4. Escalate to remote model with tool access\n // Note: triage_result event already carries the reasoning for the provider to display.\n // We only emit the phase transition here — no duplicate agent_thought.\n if (triageResult.escalate) {\n this.emitPhase(\"thinking\", \"Entering agent loop with remote model…\");\n } else {\n this.emitPhase(\"thinking\", \"This requires tools and deeper reasoning — entering agent loop.\");\n }\n\n const modelName = triageResult.escalate\n ? this.config.remoteModelName\n : this.config.localModelName;\n\n const runtime = triageResult.escalate\n ? this.remoteRuntime\n : this.localRuntime;\n\n if (this.onToken) {\n await this.executeWithStreaming(runtime, modelName, userInput);\n } else {\n await this.executeWithAgentLoop(runtime, modelName, userInput);\n }\n }\n\n private async triage(userInput: string): Promise<TriageResult> {\n const recentMessages = this.contextManager.getMessages().slice(-5);\n const recentContext = recentMessages\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n const result = await this.localRuntime.execute(this.triageFn, {\n userInput,\n recentContext,\n availableTools: this.routerTool.description,\n });\n\n return result.data;\n }\n\n /**\n * Execute using lmscript's AgentLoop for iterative tool calling.\n * This replaces the old custom tool loop with lmscript's battle-tested implementation.\n *\n * Benefits:\n * - Schema validation on final output\n * - Budget checking via CostTracker\n * - Rate limiting via RateLimiter\n * - Middleware lifecycle hooks\n * - Automatic retry with backoff\n */\n private async executeWithAgentLoop(\n runtime: LScriptRuntime,\n modelName: string,\n userInput: string\n ): Promise<void> {\n const { z } = await import(\"zod\");\n\n this.emitPhase(\"thinking\", `Turn 1/${this.maxIterations}: Analyzing request…`);\n\n const agentFn = {\n name: \"agent-task\",\n model: modelName,\n system: this.systemPrompt,\n prompt: (input: string) => {\n const contextMessages = this.contextManager.getMessages();\n const contextStr = contextMessages\n .filter(m => m.role !== \"system\")\n .map(m => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex content]\";\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n return contextStr ? `${contextStr}\\n\\nuser: ${input}` : input;\n },\n schema: z.object({\n response: z.string().describe(\"The assistant's response to the user\"),\n reasoning: z.string().optional().describe(\"Internal reasoning about the approach taken\"),\n }),\n tools: [this.routerTool],\n temperature: 0.7,\n maxRetries: 1,\n };\n\n // Track tool calls per iteration for narrative building\n let iterationTools: Array<{ command: string; success: boolean; kwargs?: Record<string, unknown> }> = [];\n let totalToolCalls = 0;\n\n const agentConfig: AgentConfig = {\n maxIterations: this.maxIterations,\n onToolCall: (tc: ToolCall) => {\n const command = typeof tc.arguments === \"object\" && tc.arguments !== null\n ? (tc.arguments as Record<string, unknown>).command ?? tc.name\n : tc.name;\n const kwargs = typeof tc.arguments === \"object\" && tc.arguments !== null\n ? (tc.arguments as Record<string, unknown>).kwargs ?? {}\n : {};\n\n const resultStr = typeof tc.result === \"string\" ? tc.result : JSON.stringify(tc.result);\n const isError = resultStr.startsWith(\"Error:\");\n\n this.emitPhase(\"tools\", `Running tool: ${String(command)}`);\n this.bus.emit(\"tool_execution_start\", { command, kwargs });\n this.bus.emit(\"tool_execution_complete\", { command, kwargs, result: resultStr });\n\n iterationTools.push({ command: String(command), success: !isError, kwargs: kwargs as Record<string, unknown> });\n totalToolCalls++;\n\n this.recordToolResult(String(command), kwargs as Record<string, unknown>, resultStr);\n },\n onIteration: (iteration: number, response: string) => {\n // Emit tool round narrative if tools were called this iteration\n if (iterationTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(iterationTools);\n const roundEvent: ToolRoundEvent = {\n iteration,\n tools: iterationTools,\n totalToolCalls,\n narrative,\n };\n this.bus.emit(\"tool_round_complete\", roundEvent);\n iterationTools = [];\n }\n\n // Forward AI text\n if (response) {\n this.bus.emit(\"agent_thought\", {\n text: response,\n model: modelName,\n iteration,\n });\n }\n\n // Announce next iteration\n this.emitPhase(\"thinking\", `Turn ${iteration + 1}/${this.maxIterations}: Analyzing results…`);\n\n if (this.interrupted) return false;\n },\n };\n\n const agentLoop = new AgentLoop(runtime, agentConfig);\n const result = await agentLoop.run(agentFn, userInput);\n\n // Emit final tool round if pending\n if (iterationTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(iterationTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration: result.iterations,\n tools: iterationTools,\n totalToolCalls,\n narrative,\n });\n }\n\n // ── Phase: Memory ──\n this.emitPhase(\"memory\", \"Recording interaction…\");\n\n const responseText = result.data.response;\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: responseText }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n\n // ── Phase: Complete ──\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: result.iterations,\n toolCalls: result.toolCalls.length,\n usage: result.usage,\n });\n }\n\n /**\n * Execute with streaming token emission.\n * Uses the raw llm-wrapper provider for streaming, combined with\n * manual tool calling (since streaming + structured agent loops are complex).\n *\n * This preserves real-time token delivery while still leveraging\n * the lmscript infrastructure:\n * - Rate limiting (acquire/reportTokens per call)\n * - Cost tracking (trackUsage per call)\n * - Budget checking (checkBudget before each call)\n * - Middleware lifecycle hooks (onBeforeExecute/onComplete per turn)\n */\n private async executeWithStreaming(\n _runtime: LScriptRuntime,\n modelName: string,\n _userInput: string\n ): Promise<void> {\n const { zodToJsonSchema } = await import(\"zod-to-json-schema\");\n\n const provider = modelName === this.config.remoteModelName\n ? this.remoteProvider\n : this.localProvider;\n\n const contextMessages = this.contextManager.getMessages();\n\n const messages: import(\"@sschepis/llm-wrapper\").Message[] = contextMessages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : (m.content as Array<{ type: string; text?: string }>)\n .filter((b) => b.type === \"text\")\n .map((b) => b.text ?? \"\")\n .join(\"\\n\"),\n }));\n\n const tool = this.routerTool;\n const parametersSchema = tool.parameters\n ? (zodToJsonSchema(tool.parameters, { target: \"openApi3\" }) as Record<string, unknown>)\n : { type: \"object\", properties: {} };\n const tools: import(\"@sschepis/llm-wrapper\").ToolDefinition[] = [\n {\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: parametersSchema,\n },\n },\n ];\n\n let totalToolCalls = 0;\n const callHistory: string[] = [];\n // Track consecutive duplicate patterns for doom loop detection\n const consecutiveDupes = new Map<string, number>();\n let doomLoopRedirected = false;\n const turnStartTime = Date.now();\n const totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };\n\n const syntheticCtx = {\n fn: { name: \"streaming-turn\", model: modelName, system: this.systemPrompt, prompt: () => \"\", schema: {} as any },\n input: _userInput,\n messages: messages as any,\n attempt: 1,\n startTime: turnStartTime,\n };\n await this.middleware.runBeforeExecute(syntheticCtx);\n\n try {\n for (let iteration = 1; iteration <= this.maxIterations; iteration++) {\n if (this.interrupted) {\n this.emitPhase(\"cancel\", \"Interrupted by user.\");\n break;\n }\n\n // ── Phase: Thinking with iteration context ──\n this.emitPhase(\n \"thinking\",\n `Turn ${iteration}/${this.maxIterations}: ${iteration === 1 ? \"Analyzing request…\" : \"Analyzing results…\"}`\n );\n\n // ── Budget check ──\n if (this.budget) {\n this.costTracker.checkBudget(this.budget);\n }\n\n await this.rateLimiter?.acquire();\n\n const isLastIteration = iteration === this.maxIterations;\n\n if (isLastIteration) {\n this.emitPhase(\"continuation\", \"Maximum iterations reached — synthesizing final response…\");\n messages.push({\n role: \"user\",\n content:\n \"You have used all available tool iterations. Please provide your final response now based on what you have gathered so far. Do not call any more tools.\",\n });\n }\n\n const params: import(\"@sschepis/llm-wrapper\").StandardChatParams = {\n model: modelName,\n messages: [...messages],\n temperature: 0.7,\n ...(isLastIteration\n ? {}\n : { tools, tool_choice: \"auto\" as const }),\n };\n\n let response: StandardChatResponse;\n try {\n response = await this.streamAndAggregate(provider, params);\n } catch (err) {\n this.emitPhase(\"error\", `LLM call failed: ${err instanceof Error ? err.message : String(err)}`);\n await this.middleware.runError(\n syntheticCtx,\n err instanceof Error ? err : new Error(String(err))\n );\n throw err;\n }\n\n // ── Usage tracking ──\n const usage = response?.usage;\n if (usage) {\n const promptTokens = usage.prompt_tokens ?? 0;\n const completionTokens = usage.completion_tokens ?? 0;\n const usageTotal = usage.total_tokens ?? (promptTokens + completionTokens);\n\n totalUsage.promptTokens += promptTokens;\n totalUsage.completionTokens += completionTokens;\n totalUsage.totalTokens += usageTotal;\n\n this.rateLimiter?.reportTokens(usageTotal);\n this.usageBridge.recordFromLmscript(modelName, {\n promptTokens,\n completionTokens,\n totalTokens: usageTotal,\n });\n\n this.bus.emit(\"cost_update\", {\n iteration,\n totalTokens: this.costTracker.getTotalTokens(),\n totalCost: this.costTracker.getTotalCost(this.modelPricing),\n });\n }\n\n const choice = response?.choices?.[0];\n const content = (choice?.message?.content as string) ?? \"\";\n const toolCalls = choice?.message?.tool_calls;\n\n // Forward AI reasoning text\n if (content) {\n this.bus.emit(\"agent_thought\", {\n text: content,\n model: modelName,\n iteration,\n });\n }\n\n // ── No tool calls → final response ──\n if (!toolCalls || toolCalls.length === 0) {\n // Handle empty responses\n if (!content) {\n this.bus.emit(\"agent_thought\", {\n text: `Empty response from AI — iteration ${iteration}`,\n model: \"system\",\n });\n if (iteration < this.maxIterations) continue;\n }\n\n this.emitPhase(\"memory\", \"Recording interaction…\");\n\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: content }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"assistant_response\" });\n\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: iteration,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n\n await this.middleware.runComplete(syntheticCtx, {\n data: content,\n raw: content,\n usage: totalUsage,\n } as any);\n return;\n }\n\n // ── Phase: Tools ──\n this.emitPhase(\"tools\", `Executing ${toolCalls.length} tool(s)…`);\n\n messages.push({\n role: \"assistant\",\n content: content || null,\n tool_calls: toolCalls,\n });\n\n // Track tools this round for narrative\n const roundTools: Array<{ command: string; success: boolean; kwargs?: Record<string, unknown> }> = [];\n\n for (let ti = 0; ti < toolCalls.length; ti++) {\n const tc = toolCalls[ti];\n if (this.interrupted) break;\n\n let args: Record<string, unknown>;\n try {\n args = JSON.parse(tc.function.arguments);\n } catch {\n args = {};\n }\n\n const command = (args.command as string) ?? tc.function.name;\n const kwargs = (args.kwargs as Record<string, unknown>) ?? {};\n const toolInputStr = JSON.stringify({ command, kwargs });\n\n // ── Permission check ──\n if (this.permissionGuard) {\n const outcome = this.permissionGuard.checkPermission(command, toolInputStr);\n if (outcome.kind === \"deny\") {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `Permission denied for tool \"${command}\": ${outcome.reason ?? \"denied by policy\"}`,\n });\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n }\n }\n\n // ── Pre-tool-use hooks ──\n if (this.hookIntegration) {\n const hookResult = this.hookIntegration.runPreToolUse(command, toolInputStr);\n if (hookResult.denied) {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `Tool \"${command}\" blocked by pre-use hook: ${hookResult.messages.join(\"; \")}`,\n });\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n }\n }\n\n // ── Duplicate detection + doom loop ──\n const callSig = JSON.stringify({ command, kwargs });\n const dupeCount = callHistory.filter((s) => s === callSig).length;\n callHistory.push(callSig);\n\n // Track consecutive dupes for doom loop detection\n const prevConsec = consecutiveDupes.get(command) ?? 0;\n consecutiveDupes.set(command, prevConsec + 1);\n\n if (dupeCount >= 2) {\n // ── Doom loop detection ──\n if (prevConsec >= 3 && !doomLoopRedirected) {\n doomLoopRedirected = true;\n this.emitPhase(\"doom\", `Doom loop detected: repeated calls to \"${command}\"`);\n this.bus.emit(\"doom_loop\", {\n reason: `Repeated calls to \"${command}\"`,\n command,\n count: prevConsec + 1,\n redirected: true,\n });\n // Inject a redirect message to break the pattern\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `STOP: You have been calling \"${command}\" repeatedly with the same arguments ${prevConsec + 1} times. `\n + `This is a doom loop. You MUST take a different approach. `\n + `Summarize what you know so far and either try a completely different strategy or provide your best answer.`,\n });\n } else if (doomLoopRedirected && prevConsec >= 5) {\n // Persistent doom loop — force termination\n this.emitPhase(\"doom\", `Persistent doom loop — terminating.`);\n this.bus.emit(\"doom_loop\", {\n reason: `Persistent doom loop on \"${command}\"`,\n command,\n count: prevConsec + 1,\n redirected: false,\n });\n // Break out of the tool loop and the iteration loop\n roundTools.push({ command, success: false });\n totalToolCalls++;\n\n // Emit tool round narrative before breaking\n if (roundTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(roundTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration,\n tools: roundTools,\n totalToolCalls,\n narrative,\n } as ToolRoundEvent);\n }\n\n // Force final response\n this.emitPhase(\"continuation\", \"Synthesizing response after doom loop…\");\n const assistantMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: content || \"I encountered a repeating pattern and am unable to make further progress. Here is what I have so far.\" }],\n };\n await this.recordMessage(assistantMsg);\n this.bus.emit(\"state_updated\", { reason: \"doom_loop\" });\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: iteration,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n await this.middleware.runComplete(syntheticCtx, {\n data: content || \"doom_loop_terminated\",\n raw: content,\n usage: totalUsage,\n } as any);\n return;\n } else {\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `You already called \"${command}\" with these arguments ${dupeCount} time(s). Use the data you already have.`,\n });\n }\n\n roundTools.push({ command, success: false });\n totalToolCalls++;\n continue;\n } else {\n // Reset consecutive counter for this command on a novel call\n consecutiveDupes.set(command, 0);\n }\n\n // ── Tool status: \"Running tool 1/3: read_file\" ──\n this.bus.emit(\"tool_execution_start\", { command, kwargs, index: ti, total: toolCalls.length });\n\n let result: string;\n let isError = false;\n try {\n result = await tool.execute(args);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n isError = true;\n }\n\n const resultStr = typeof result === \"string\" ? result : JSON.stringify(result);\n const truncated =\n resultStr.length > 8000\n ? resultStr.slice(0, 8000) +\n `\\n\\n[... truncated ${resultStr.length - 8000} characters.]`\n : resultStr;\n\n if (this.hookIntegration) {\n this.hookIntegration.runPostToolUse(command, toolInputStr, truncated, isError);\n }\n\n this.bus.emit(\"tool_execution_complete\", { command, kwargs, result: truncated, error: isError ? truncated : undefined });\n this.recordToolResult(command, kwargs, truncated);\n roundTools.push({ command, success: !isError, kwargs });\n totalToolCalls++;\n\n messages.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: truncated,\n });\n }\n\n // ── Tool round narrative ──\n if (roundTools.length > 0) {\n const narrative = this.buildToolRoundNarrative(roundTools);\n this.bus.emit(\"tool_round_complete\", {\n iteration,\n tools: roundTools,\n totalToolCalls,\n narrative,\n } as ToolRoundEvent);\n }\n }\n\n // ── Exhausted iterations fallback ──\n this.emitPhase(\"continuation\", \"Maximum iterations reached — synthesizing response…\");\n\n const fallbackMsg: ConversationMessage = {\n role: MessageRole.Assistant,\n blocks: [{ kind: \"text\", text: \"I reached the maximum number of iterations. Here is what I have so far.\" }],\n };\n await this.recordMessage(fallbackMsg);\n this.bus.emit(\"state_updated\", { reason: \"max_iterations\" });\n\n this.emitPhase(\"complete\", \"Response ready.\");\n this.bus.emit(\"turn_complete\", {\n model: modelName,\n escalated: true,\n iterations: this.maxIterations,\n toolCalls: totalToolCalls,\n usage: totalUsage,\n });\n\n await this.middleware.runComplete(syntheticCtx, {\n data: \"max_iterations_reached\",\n raw: \"\",\n usage: totalUsage,\n } as any);\n\n } catch (err) {\n this.emitPhase(\"error\", `Error: ${err instanceof Error ? err.message : String(err)}`);\n if (!(err instanceof Error && err.message.includes(\"LLM call failed\"))) {\n await this.middleware.runError(\n syntheticCtx,\n err instanceof Error ? err : new Error(String(err))\n );\n }\n throw err;\n }\n }\n\n /**\n * Stream an LLM call, emitting tokens in real-time, then aggregate into\n * a full StandardChatResponse (including accumulated tool calls).\n */\n private async streamAndAggregate(\n provider: ProviderLike,\n params: import(\"@sschepis/llm-wrapper\").StandardChatParams\n ): Promise<StandardChatResponse> {\n const stream = provider.stream({ ...params, stream: true });\n\n const chunks: StandardChatChunk[] = [];\n for await (const chunk of stream) {\n chunks.push(chunk);\n\n const delta = chunk.choices?.[0]?.delta;\n if (delta?.content) {\n this.onToken!(delta.content);\n this.bus.emit(\"token\", { text: delta.content });\n }\n }\n\n async function* replay(): AsyncIterable<StandardChatChunk> {\n for (const c of chunks) yield c;\n }\n return aggregateStream(replay());\n }\n}\n","import type { AgentEventType, AgentEvent } from \"./types.js\";\n\ntype EventHandler = (event: AgentEvent) => void;\n\n/**\n * Platform-agnostic typed event bus.\n * Uses a plain Map instead of Node.js EventEmitter for browser/Deno/Bun compatibility.\n */\nexport class AgentEventBus {\n private listeners = new Map<AgentEventType, Set<EventHandler>>();\n\n /** Subscribe to an event type. Returns an unsubscribe function. */\n on(type: AgentEventType, handler: EventHandler): () => void {\n if (!this.listeners.has(type)) {\n this.listeners.set(type, new Set());\n }\n this.listeners.get(type)!.add(handler);\n return () => this.off(type, handler);\n }\n\n /** Unsubscribe a handler from an event type. */\n off(type: AgentEventType, handler: EventHandler): void {\n this.listeners.get(type)?.delete(handler);\n }\n\n /** Subscribe to an event type for a single emission. */\n once(type: AgentEventType, handler: EventHandler): () => void {\n const wrapper: EventHandler = (event) => {\n this.off(type, wrapper);\n handler(event);\n };\n return this.on(type, wrapper);\n }\n\n /** Emit an event to all subscribers. */\n emit(type: AgentEventType, payload: unknown): void {\n const event: AgentEvent = {\n type,\n payload,\n timestamp: Date.now(),\n };\n const handlers = this.listeners.get(type);\n if (handlers) {\n for (const handler of handlers) {\n handler(event);\n }\n }\n }\n\n /** Remove all listeners for all event types. */\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import { z } from \"zod\";\nimport { ContextStack, type LScriptRuntime, type ChatMessage, type LScriptFunction } from \"@sschepis/lmscript\";\n\nconst SummarySchema = z.object({\n summary: z.string().describe(\"A dense summary of the conversation so far\"),\n});\n\ntype SummaryInput = { conversation: string };\n\n/**\n * Manages the sliding context window with automatic summarization.\n * Wraps lmscript's ContextStack and uses the local LLM for compression.\n */\nexport class ContextManager {\n private stack: ContextStack;\n private summarizeFn: LScriptFunction<SummaryInput, typeof SummarySchema>;\n\n constructor(\n private localRuntime: LScriptRuntime,\n localModelName: string,\n maxTokens: number\n ) {\n this.stack = new ContextStack({\n maxTokens,\n pruneStrategy: \"summarize\",\n });\n\n this.summarizeFn = {\n name: \"summarize_context\",\n model: localModelName,\n system:\n \"You are a summarization engine. Compress the given conversation into a dense, factual summary that preserves all key information, decisions, and context needed for continued operation. Be concise but thorough.\",\n prompt: ({ conversation }) => conversation,\n schema: SummarySchema,\n temperature: 0.2,\n maxRetries: 1,\n };\n\n this.stack.setSummarizer(async (messages: ChatMessage[]) => {\n const conversation = messages\n .map((m) => {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\" \");\n return `${m.role}: ${text}`;\n })\n .join(\"\\n\");\n\n try {\n const result = await this.localRuntime.execute(this.summarizeFn, {\n conversation,\n });\n return result.data.summary;\n } catch (err) {\n // If the local LLM fails (timeout, schema error, etc.), fall back\n // to a simple truncation so we don't crash the agent loop.\n console.warn(\n \"[ContextManager] Summarization failed, using truncation fallback:\",\n err instanceof Error ? err.message : err\n );\n // Keep last ~500 chars of each message as a crude summary\n return messages\n .slice(-3)\n .map((m) => {\n const text = typeof m.content === \"string\" ? m.content : \"[complex]\";\n return `${m.role}: ${text.slice(-500)}`;\n })\n .join(\"\\n\");\n }\n });\n }\n\n /** Append a message to the context. Triggers pruning if over budget. */\n async push(message: ChatMessage): Promise<void> {\n await this.stack.push(message);\n }\n\n /** Append multiple messages. */\n async pushAll(messages: ChatMessage[]): Promise<void> {\n await this.stack.pushAll(messages);\n }\n\n /** Get all messages in the current context window. */\n getMessages(): ChatMessage[] {\n return this.stack.getMessages();\n }\n\n /** Get estimated token count. */\n getTokenCount(): number {\n return this.stack.getTokenCount();\n }\n\n /** Clear all context. */\n clear(): void {\n this.stack.clear();\n }\n}\n","import { z } from \"zod\";\nimport type { LScriptFunction } from \"@sschepis/lmscript\";\n\n/** Zod schema for structured triage output. */\nexport const TriageSchema = z.object({\n escalate: z\n .boolean()\n .describe(\"True if the request needs a powerful model, false if answerable directly\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of the triage decision\"),\n directResponse: z\n .string()\n .nullish()\n .transform(v => v ?? undefined)\n .describe(\"Direct answer if the request can be handled without escalation\"),\n});\n\nexport type TriageInput = {\n userInput: string;\n recentContext: string;\n availableTools: string;\n};\n\nconst TRIAGE_SYSTEM = `You are a fast triage classifier for an AI agent system.\nYour job is to decide whether a user's request can be answered directly (simple queries,\ncasual chat, short lookups) or needs to be escalated to a more powerful model\n(complex reasoning, multi-step tool usage, code generation, analysis).\n\nRules:\n- Only respond directly for truly trivial exchanges: greetings, thanks, or very simple factual questions.\n- When responding directly, use a natural, warm, conversational tone. Do NOT list capabilities or describe what tools you have access to.\n- If the user's message could benefit from tool usage or detailed reasoning, always escalate.\n- If the request needs tool calls, code analysis, or multi-step reasoning: escalate.\n- If unsure, escalate. It's better to over-escalate than to give a poor direct answer.\n- Keep directResponse under 200 words when answering directly.\n- Pay attention to the recent context — if the user is continuing a conversation, your response should reflect that context.\n\nRespond with JSON matching the schema.`;\n\n/**\n * Create an LScriptFunction for local-LLM triage classification.\n * The local model evaluates whether input needs escalation to the remote model.\n */\nexport function createTriageFunction(\n modelName: string\n): LScriptFunction<TriageInput, typeof TriageSchema> {\n return {\n name: \"triage\",\n model: modelName,\n system: TRIAGE_SYSTEM,\n prompt: ({ userInput, recentContext, availableTools }) =>\n `Recent context:\\n${recentContext}\\n\\nAvailable tools: ${availableTools}\\n\\nUser: ${userInput}`,\n schema: TriageSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n","import { z } from \"zod\";\nimport type { Router } from \"@sschepis/swiss-army-tool\";\nimport { generateToolSchema } from \"@sschepis/swiss-army-tool\";\nimport type { ToolDefinition } from \"@sschepis/lmscript\";\nimport type { BranchNode } from \"@sschepis/swiss-army-tool\";\n\n/** Parameter schema for the omni-tool bridge. */\nconst RouterToolParams = z.object({\n command: z.string().describe(\n \"The command or menu path (e.g., 'help', 'filesystem read', 'db query')\"\n ),\n kwargs: z\n .record(z.unknown())\n .optional()\n .default({})\n .describe(\"Key-value arguments for the command\"),\n});\n\n/**\n * Bridge a swiss-army-tool Router into an lmscript ToolDefinition.\n *\n * The LLM sees a single tool (\"terminal_interface\") with `command` and `kwargs`\n * parameters. When called, it routes through the swiss-army-tool command tree.\n */\nexport function createRouterTool(\n router: Router,\n root?: BranchNode\n): ToolDefinition<typeof RouterToolParams, string> {\n const schema = generateToolSchema({ root });\n\n return {\n name: schema.name,\n description: schema.description,\n parameters: RouterToolParams,\n execute: async (params) => {\n return router.execute(params.command, params.kwargs ?? {});\n },\n };\n}\n","import type { LLMProvider, LLMRequest, LLMResponse } from \"@sschepis/lmscript\";\nimport type {\n BaseProvider,\n StandardChatParams,\n Message,\n ToolDefinition as WrapperToolDef,\n} from \"@sschepis/llm-wrapper\";\nimport type { LLMRouter } from \"@sschepis/llm-wrapper\";\n\n/**\n * A provider-like object that has `chat()` and `stream()` methods.\n * Both `BaseProvider` and `LLMRouter` implement this interface.\n */\ntype ProviderLike = {\n chat(params: StandardChatParams): Promise<import(\"@sschepis/llm-wrapper\").StandardChatResponse>;\n stream(params: StandardChatParams): AsyncIterable<import(\"@sschepis/llm-wrapper\").StandardChatChunk>;\n readonly providerName?: string;\n};\n\n/**\n * Convert lmscript messages to llm-wrapper messages.\n */\nfunction convertMessages(messages: LLMRequest[\"messages\"]): Message[] {\n return messages.map((m) => ({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { type: \"text\"; text: string }).text)\n .join(\"\\n\"),\n }));\n}\n\n/**\n * Convert lmscript tool format to llm-wrapper tool definitions.\n */\nfunction convertTools(tools?: LLMRequest[\"tools\"]): WrapperToolDef[] | undefined {\n if (!tools || tools.length === 0) return undefined;\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters as Record<string, unknown>,\n },\n }));\n}\n\n/**\n * Build llm-wrapper StandardChatParams from an lmscript LLMRequest.\n */\nfunction buildParams(request: LLMRequest, tools?: WrapperToolDef[]): StandardChatParams {\n return {\n model: request.model,\n messages: convertMessages(request.messages),\n temperature: request.temperature,\n ...(tools ? { tools } : {}),\n ...(request.jsonMode\n ? { response_format: { type: \"json_object\" as const } }\n : {}),\n };\n}\n\n/**\n * Adapt a llm-wrapper BaseProvider (or LLMRouter) into lmscript's LLMProvider interface.\n *\n * This allows lmscript's LScriptRuntime to use llm-wrapper providers for\n * structured calls (e.g. triage) that need schema validation.\n *\n * Bridges both `chat()` and `chatStream()` — enabling streaming through the\n * full lmscript stack (including `executeStream()`).\n */\nexport function toLmscriptProvider(\n provider: ProviderLike,\n name?: string\n): LLMProvider {\n return {\n name: name ?? (provider as BaseProvider).providerName ?? \"llm-wrapper\",\n\n async chat(request: LLMRequest): Promise<LLMResponse> {\n const tools = convertTools(request.tools);\n const params = buildParams(request, tools);\n\n const response = await provider.chat(params);\n const choice = response.choices[0];\n\n // Convert tool calls back to lmscript format\n let toolCalls: LLMResponse[\"toolCalls\"];\n if (choice?.message?.tool_calls) {\n toolCalls = choice.message.tool_calls.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }));\n }\n\n return {\n content: (choice?.message?.content as string) ?? \"\",\n usage: response.usage\n ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n }\n : undefined,\n toolCalls,\n };\n },\n\n async *chatStream(request: LLMRequest): AsyncIterable<string> {\n const tools = convertTools(request.tools);\n const params = buildParams(request, tools);\n\n for await (const chunk of provider.stream({ ...params, stream: true })) {\n const delta = chunk.choices?.[0]?.delta;\n if (delta?.content) {\n yield delta.content;\n }\n }\n },\n };\n}\n","import {\n MessageRole,\n type ConversationMessage,\n type ContentBlock as AsContentBlock,\n type Session,\n} from \"@sschepis/as-agent\";\nimport type { ChatMessage, Role } from \"@sschepis/lmscript\";\n\nconst ROLE_TO_STRING: Record<MessageRole, Role> = {\n [MessageRole.System]: \"system\",\n [MessageRole.User]: \"user\",\n [MessageRole.Assistant]: \"assistant\",\n [MessageRole.Tool]: \"user\",\n};\n\nconst STRING_TO_ROLE: Record<Role, MessageRole> = {\n system: MessageRole.System,\n user: MessageRole.User,\n assistant: MessageRole.Assistant,\n};\n\n/** Extract plain text from as-agent content blocks. */\nfunction blocksToText(blocks: AsContentBlock[]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool call: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Tool error (${b.toolName}): ${b.output}]`\n : `[Tool result (${b.toolName}): ${b.output}]`;\n }\n })\n .join(\"\\n\");\n}\n\n/** Convert an as-agent ConversationMessage to an lmscript ChatMessage. */\nexport function toChat(msg: ConversationMessage): ChatMessage {\n return {\n role: ROLE_TO_STRING[msg.role] ?? \"user\",\n content: blocksToText(msg.blocks),\n };\n}\n\n/** Convert an lmscript ChatMessage to an as-agent ConversationMessage. */\nexport function fromChat(msg: ChatMessage): ConversationMessage {\n const text = typeof msg.content === \"string\"\n ? msg.content\n : msg.content\n .filter((b) => b.type === \"text\")\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n\n return {\n role: STRING_TO_ROLE[msg.role] ?? MessageRole.User,\n blocks: [{ kind: \"text\", text }],\n };\n}\n\n/** Convert an entire as-agent Session to an array of lmscript ChatMessages. */\nexport function sessionToHistory(session: Session): ChatMessage[] {\n return session.messages.map(toChat);\n}\n\n/** Create an empty as-agent Session. */\nexport function createEmptySession(): Session {\n return { version: 1, messages: [] };\n}\n","/**\n * rag-integration.ts — RAG pipeline integration with oboto-agent conversation history.\n *\n * This module bridges lmscript's RAG pipeline, embedding provider, and vector store\n * with the agent's conversation history (as-agent Sessions) and tool execution results.\n *\n * Key capabilities:\n * - Index conversation messages and tool results into a vector store\n * - Retrieve relevant past context when processing new user input\n * - Provide a RAG-augmented execution path for the agent\n */\n\nimport {\n RAGPipeline,\n MemoryVectorStore,\n type EmbeddingProvider,\n type VectorStore,\n type VectorSearchResult,\n type LScriptRuntime,\n type LScriptFunction,\n type ExecutionResult,\n} from \"@sschepis/lmscript\";\nimport type { Session, ConversationMessage } from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\n\n// ── Types ─────────────────────────────────────────────────────────────\n\nexport interface ConversationRAGConfig {\n /** The embedding provider (e.g. OpenAI, local model) */\n embeddingProvider: EmbeddingProvider;\n\n /** Optional custom vector store. Defaults to MemoryVectorStore. */\n vectorStore?: VectorStore;\n\n /** Number of past context chunks to retrieve. Default: 5 */\n topK?: number;\n\n /** Minimum similarity score (0-1). Default: 0.3 */\n minScore?: number;\n\n /** Embedding model identifier. Default: provider's default */\n embeddingModel?: string;\n\n /**\n * Whether to automatically index conversation messages as they're added.\n * Default: true\n */\n autoIndex?: boolean;\n\n /**\n * Whether to index tool execution results.\n * Default: true\n */\n indexToolResults?: boolean;\n\n /** Maximum characters per indexed chunk. Longer messages are split. Default: 2000 */\n maxChunkSize?: number;\n\n /**\n * Custom context formatter for retrieved documents.\n * Default: numbered list with scores.\n */\n formatContext?: (results: VectorSearchResult[]) => string;\n}\n\nexport interface RAGRetrievalResult {\n /** Retrieved context string ready for prompt injection */\n context: string;\n /** Raw search results */\n results: VectorSearchResult[];\n /** Number of documents in the store */\n totalDocuments: number;\n}\n\n// ── ConversationRAG ──────────────────────────────────────────────────\n\n/**\n * ConversationRAG bridges lmscript's RAG pipeline with the agent's\n * conversation history and tool results.\n *\n * It maintains a vector store of conversation chunks and can retrieve\n * relevant past context for new queries. This is useful for:\n * - Long-running agent sessions where early context is pruned\n * - Multi-topic conversations where relevant past decisions need retrieval\n * - Tool result recall without re-execution\n *\n * ```ts\n * const rag = new ConversationRAG(runtime, {\n * embeddingProvider: openaiEmbeddings,\n * topK: 5,\n * minScore: 0.3,\n * });\n *\n * // Index existing session history\n * await rag.indexSession(session);\n *\n * // Retrieve relevant context for a new query\n * const { context } = await rag.retrieve(\"What database schema did we discuss?\");\n *\n * // Or use RAG-augmented execution directly\n * const result = await rag.executeWithContext(myFn, input, \"search query\");\n * ```\n */\nexport class ConversationRAG {\n private vectorStore: VectorStore;\n private embeddingProvider: EmbeddingProvider;\n private ragPipeline: RAGPipeline;\n private config: Required<ConversationRAGConfig>;\n private indexedMessageCount = 0;\n private runtime: LScriptRuntime;\n\n constructor(runtime: LScriptRuntime, config: ConversationRAGConfig) {\n this.runtime = runtime;\n this.vectorStore = config.vectorStore ?? new MemoryVectorStore();\n this.embeddingProvider = config.embeddingProvider;\n\n this.config = {\n embeddingProvider: config.embeddingProvider,\n vectorStore: this.vectorStore,\n topK: config.topK ?? 5,\n minScore: config.minScore ?? 0.3,\n embeddingModel: config.embeddingModel ?? \"\",\n autoIndex: config.autoIndex ?? true,\n indexToolResults: config.indexToolResults ?? true,\n maxChunkSize: config.maxChunkSize ?? 2000,\n formatContext: config.formatContext ?? defaultConversationContextFormatter,\n };\n\n this.ragPipeline = new RAGPipeline(runtime, {\n embeddingProvider: this.embeddingProvider,\n vectorStore: this.vectorStore,\n topK: this.config.topK,\n minScore: this.config.minScore,\n embeddingModel: this.config.embeddingModel,\n formatContext: this.config.formatContext,\n });\n }\n\n // ── Indexing ──────────────────────────────────────────────────────\n\n /**\n * Index an entire as-agent Session into the vector store.\n * Each message becomes one or more chunks (split by maxChunkSize).\n */\n async indexSession(session: Session): Promise<number> {\n const documents: Array<{ id: string; content: string; metadata?: Record<string, unknown> }> = [];\n\n for (let i = 0; i < session.messages.length; i++) {\n const msg = session.messages[i];\n const chunks = this.messageToChunks(msg, i);\n documents.push(...chunks);\n }\n\n if (documents.length > 0) {\n await this.ragPipeline.ingest(documents);\n this.indexedMessageCount += session.messages.length;\n }\n\n return documents.length;\n }\n\n /**\n * Index a single conversation message.\n * Call this after adding a message to the session for real-time indexing.\n */\n async indexMessage(msg: ConversationMessage, messageIndex?: number): Promise<void> {\n const idx = messageIndex ?? this.indexedMessageCount;\n const chunks = this.messageToChunks(msg, idx);\n\n if (chunks.length > 0) {\n await this.ragPipeline.ingest(chunks);\n this.indexedMessageCount++;\n }\n }\n\n /**\n * Index a tool execution result for later retrieval.\n */\n async indexToolResult(\n command: string,\n kwargs: Record<string, unknown>,\n result: string\n ): Promise<void> {\n if (!this.config.indexToolResults) return;\n\n const content = `Tool: ${command}\\nArgs: ${JSON.stringify(kwargs)}\\nResult: ${result}`;\n const chunks = this.splitChunks(content, `tool:${command}:${Date.now()}`);\n\n if (chunks.length > 0) {\n const documents = chunks.map((chunk, i) => ({\n id: chunk.id,\n content: chunk.content,\n metadata: {\n type: \"tool_result\",\n command,\n kwargs,\n chunkIndex: i,\n timestamp: Date.now(),\n },\n }));\n\n await this.ragPipeline.ingest(documents);\n }\n }\n\n // ── Retrieval ─────────────────────────────────────────────────────\n\n /**\n * Retrieve relevant past context for a query.\n * Returns formatted context string and raw results.\n */\n async retrieve(query: string): Promise<RAGRetrievalResult> {\n const [queryVector] = await this.embeddingProvider.embed(\n [query],\n this.config.embeddingModel || undefined\n );\n\n const results = await this.vectorStore.search(queryVector, this.config.topK);\n const filtered = results.filter(r => r.score >= this.config.minScore);\n const context = this.config.formatContext(filtered);\n const totalDocuments = await this.vectorStore.count();\n\n return { context, results: filtered, totalDocuments };\n }\n\n /**\n * Execute an lmscript function with RAG-augmented context from the\n * conversation history.\n *\n * This is the primary integration point — it uses lmscript's RAGPipeline\n * to inject relevant past conversation into the function's system prompt.\n */\n async executeWithContext<I, O extends import(\"zod\").ZodType>(\n fn: LScriptFunction<I, O>,\n input: I,\n queryText?: string\n ): Promise<{ result: ExecutionResult<import(\"zod\").infer<O>>; retrievedDocuments: VectorSearchResult[]; context: string }> {\n const ragResult = await this.ragPipeline.query(fn, input, queryText);\n return {\n result: ragResult.result as ExecutionResult<O>,\n retrievedDocuments: ragResult.retrievedDocuments,\n context: ragResult.context,\n };\n }\n\n // ── Utility ───────────────────────────────────────────────────────\n\n /** Get the number of indexed messages. */\n get messageCount(): number {\n return this.indexedMessageCount;\n }\n\n /** Get the total number of document chunks in the vector store. */\n async documentCount(): Promise<number> {\n return this.vectorStore.count();\n }\n\n /** Clear the vector store and reset counters. */\n async clear(): Promise<void> {\n await this.vectorStore.clear();\n this.indexedMessageCount = 0;\n }\n\n /** Get the underlying vector store (for advanced usage). */\n getVectorStore(): VectorStore {\n return this.vectorStore;\n }\n\n /** Get the underlying RAG pipeline (for advanced usage). */\n getRagPipeline(): RAGPipeline {\n return this.ragPipeline;\n }\n\n // ── Private ───────────────────────────────────────────────────────\n\n private messageToChunks(\n msg: ConversationMessage,\n messageIndex: number\n ): Array<{ id: string; content: string; metadata?: Record<string, unknown> }> {\n const roleLabel = messageRoleToLabel(msg.role);\n const text = blocksToText(msg.blocks);\n\n if (!text.trim()) return [];\n\n const prefixed = `[${roleLabel}]: ${text}`;\n const baseId = `msg:${messageIndex}`;\n\n return this.splitChunks(prefixed, baseId).map((chunk, i) => ({\n id: chunk.id,\n content: chunk.content,\n metadata: {\n type: \"conversation\",\n role: roleLabel,\n messageIndex,\n chunkIndex: i,\n timestamp: Date.now(),\n },\n }));\n }\n\n private splitChunks(\n text: string,\n baseId: string\n ): Array<{ id: string; content: string }> {\n const maxSize = this.config.maxChunkSize;\n\n if (text.length <= maxSize) {\n return [{ id: baseId, content: text }];\n }\n\n // Split on paragraph boundaries first, then sentence boundaries\n const chunks: Array<{ id: string; content: string }> = [];\n let remaining = text;\n let chunkIdx = 0;\n\n while (remaining.length > 0) {\n let splitAt = maxSize;\n\n if (remaining.length > maxSize) {\n // Try to split at paragraph boundary\n const paraIdx = remaining.lastIndexOf(\"\\n\\n\", maxSize);\n if (paraIdx > maxSize * 0.3) {\n splitAt = paraIdx + 2;\n } else {\n // Try sentence boundary\n const sentIdx = remaining.lastIndexOf(\". \", maxSize);\n if (sentIdx > maxSize * 0.3) {\n splitAt = sentIdx + 2;\n }\n }\n } else {\n splitAt = remaining.length;\n }\n\n chunks.push({\n id: `${baseId}:${chunkIdx}`,\n content: remaining.slice(0, splitAt).trim(),\n });\n\n remaining = remaining.slice(splitAt);\n chunkIdx++;\n }\n\n return chunks;\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction messageRoleToLabel(role: MessageRole): string {\n switch (role) {\n case MessageRole.System: return \"system\";\n case MessageRole.User: return \"user\";\n case MessageRole.Assistant: return \"assistant\";\n case MessageRole.Tool: return \"tool\";\n default: return \"unknown\";\n }\n}\n\nfunction blocksToText(blocks: ConversationMessage[\"blocks\"]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Error: ${b.toolName}: ${b.output}]`\n : `[Result: ${b.toolName}: ${b.output}]`;\n default:\n return \"\";\n }\n })\n .join(\"\\n\");\n}\n\n/**\n * Default context formatter for conversation RAG results.\n * Shows role, score, and content for each retrieved chunk.\n */\nfunction defaultConversationContextFormatter(results: VectorSearchResult[]): string {\n if (results.length === 0) return \"\";\n\n return [\n \"## Relevant Past Context\",\n \"\",\n ...results.map((r, i) => {\n const meta = r.document.metadata as Record<string, unknown> | undefined;\n const type = meta?.type ?? \"unknown\";\n const score = r.score.toFixed(3);\n return `[${i + 1}] (${type}, score: ${score})\\n${r.document.content}`;\n }),\n ].join(\"\\n\");\n}\n","/**\n * as-agent-features.ts — Deep integration of @sschepis/as-agent's advanced features.\n *\n * This module bridges the following as-agent subsystems into oboto-agent:\n *\n * 1. **Permissions** — PermissionPolicy + PermissionPrompter for tool authorization\n * 2. **Session Compaction** — CompactionConfig for auto-compacting long sessions\n * 3. **Hooks** — HookRunner for pre/post tool-use shell hooks\n * 4. **Slash Commands** — AgentRuntime's slash command registry\n * 5. **Usage Tracking** — UsageTracker bridge (detailed impl in Task 11)\n */\n\nimport type {\n PermissionPolicy,\n PermissionPrompter,\n PermissionOutcome,\n PermissionMode,\n CompactionConfig,\n CompactionResult,\n HookRunner,\n HookRunResult,\n SlashCommandSpec,\n AgentRuntime,\n Session,\n ConversationMessage,\n TokenUsage as AsTokenUsage,\n UsageTracker,\n} from \"@sschepis/as-agent\";\nimport { MessageRole } from \"@sschepis/as-agent\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n// ── Permission Guard ──────────────────────────────────────────────────\n\n/**\n * Wraps an as-agent PermissionPolicy to provide tool-call authorization\n * that integrates with the agent's event bus.\n *\n * Before each tool execution, `authorize()` is called. If the policy\n * denies the call, a `permission_denied` event is emitted and the tool\n * execution is skipped.\n *\n * ```ts\n * const guard = new PermissionGuard(policy, prompter, bus);\n * const outcome = guard.checkPermission(\"bash\", '{\"cmd\":\"rm -rf /\"}');\n * if (outcome.kind === \"deny\") { ... }\n * ```\n */\nexport class PermissionGuard {\n constructor(\n private policy: PermissionPolicy,\n private prompter: PermissionPrompter | null,\n private bus?: AgentEventBus,\n ) {}\n\n /**\n * Check whether a tool call is authorized.\n * Emits `permission_denied` on the event bus if denied.\n */\n checkPermission(toolName: string, toolInput: string): PermissionOutcome {\n const outcome = this.policy.authorize(toolName, toolInput, this.prompter);\n\n if (outcome.kind === \"deny\") {\n this.bus?.emit(\"permission_denied\", {\n toolName,\n toolInput,\n reason: outcome.reason ?? \"denied by policy\",\n activeMode: this.policy.activeMode,\n requiredMode: this.policy.requiredModeFor(toolName),\n });\n }\n\n return outcome;\n }\n\n /** Get the current active permission mode. */\n get activeMode(): PermissionMode {\n return this.policy.activeMode;\n }\n\n /** Get the required permission mode for a specific tool. */\n requiredModeFor(toolName: string): PermissionMode {\n return this.policy.requiredModeFor(toolName);\n }\n}\n\n// ── Session Compactor ─────────────────────────────────────────────────\n\n/**\n * Manages automatic and manual session compaction using as-agent's\n * CompactionConfig. Compaction summarizes older messages to stay within\n * token limits while preserving recent context.\n *\n * ```ts\n * const compactor = new SessionCompactor(bus, {\n * preserveRecentMessages: 10,\n * maxEstimatedTokens: 100_000,\n * });\n *\n * // Check and compact if needed\n * const result = compactor.compactIfNeeded(session, estimatedTokens);\n * ```\n */\nexport class SessionCompactor {\n private config: CompactionConfig;\n private bus?: AgentEventBus;\n private compactionCount = 0;\n private totalRemovedMessages = 0;\n\n constructor(bus: AgentEventBus | undefined, config: CompactionConfig) {\n this.bus = bus;\n this.config = config;\n }\n\n /**\n * Check if the session needs compaction and perform it if so.\n * Uses a simple heuristic: ~4 chars per token for estimation.\n *\n * Since the actual compaction logic lives in the Wasm runtime\n * (ConversationRuntime.compact()), this method provides a JS-side\n * implementation that creates a summary of older messages and\n * preserves recent ones.\n *\n * Returns null if compaction is not needed.\n */\n compactIfNeeded(\n session: Session,\n estimatedTokens?: number,\n ): CompactionResult | null {\n const tokenEstimate = estimatedTokens ?? this.estimateTokens(session);\n\n if (tokenEstimate <= this.config.maxEstimatedTokens) {\n return null;\n }\n\n return this.compact(session);\n }\n\n /**\n * Force compaction of the session regardless of token count.\n */\n compact(session: Session): CompactionResult {\n const preserve = this.config.preserveRecentMessages;\n const totalMessages = session.messages.length;\n\n if (totalMessages <= preserve) {\n // Nothing to compact\n return {\n summary: \"\",\n formattedSummary: \"\",\n compactedSession: session,\n removedMessageCount: 0,\n };\n }\n\n // Separate messages into \"to summarize\" and \"to preserve\"\n const toSummarize = session.messages.slice(0, totalMessages - preserve);\n const toPreserve = session.messages.slice(totalMessages - preserve);\n\n // Build a summary from the messages being removed\n const summaryParts: string[] = [];\n for (const msg of toSummarize) {\n const role = roleToString(msg.role);\n const text = blocksToText(msg.blocks);\n if (text.trim()) {\n summaryParts.push(`[${role}]: ${text}`);\n }\n }\n\n const summary = summaryParts.join(\"\\n\\n\");\n const formattedSummary = `[Session Compaction Summary — ${toSummarize.length} messages summarized]\\n\\n${summary}`;\n\n // Build the compacted session with a summary message + preserved messages\n const summaryMessage: ConversationMessage = {\n role: MessageRole.System,\n blocks: [{\n kind: \"text\",\n text: `[Previous conversation summary — ${toSummarize.length} messages compacted]\\n\\n${\n summary.length > 4000 ? summary.slice(0, 4000) + \"\\n\\n[... summary truncated]\" : summary\n }`,\n }],\n };\n\n const compactedSession: Session = {\n version: session.version,\n messages: [summaryMessage, ...toPreserve],\n };\n\n const result: CompactionResult = {\n summary,\n formattedSummary,\n compactedSession,\n removedMessageCount: toSummarize.length,\n };\n\n this.compactionCount++;\n this.totalRemovedMessages += toSummarize.length;\n\n this.bus?.emit(\"session_compacted\", {\n removedMessageCount: toSummarize.length,\n preservedMessageCount: toPreserve.length + 1, // +1 for summary msg\n estimatedTokensBefore: this.estimateTokens(session),\n estimatedTokensAfter: this.estimateTokens(compactedSession),\n compactionIndex: this.compactionCount,\n });\n\n return result;\n }\n\n /** Get compaction statistics. */\n get stats() {\n return {\n compactionCount: this.compactionCount,\n totalRemovedMessages: this.totalRemovedMessages,\n };\n }\n\n /** Update the compaction config at runtime. */\n updateConfig(config: Partial<CompactionConfig>): void {\n if (config.preserveRecentMessages !== undefined) {\n this.config.preserveRecentMessages = config.preserveRecentMessages;\n }\n if (config.maxEstimatedTokens !== undefined) {\n this.config.maxEstimatedTokens = config.maxEstimatedTokens;\n }\n }\n\n /** Estimate token count for a session (~4 chars per token). */\n private estimateTokens(session: Session): number {\n let charCount = 0;\n for (const msg of session.messages) {\n for (const block of msg.blocks) {\n if (block.kind === \"text\") {\n charCount += block.text.length;\n } else if (block.kind === \"tool_use\") {\n charCount += block.name.length + block.input.length;\n } else if (block.kind === \"tool_result\") {\n charCount += block.output.length;\n }\n }\n }\n return Math.ceil(charCount / 4);\n }\n}\n\n// ── Hook Integration ──────────────────────────────────────────────────\n\n/**\n * Wraps an as-agent HookRunner and integrates it with the agent's\n * event bus. Hooks are shell commands that run before and after\n * tool executions, allowing external validation/transformation.\n *\n * ```ts\n * const hooks = new HookIntegration(hookRunner, bus);\n * const pre = hooks.runPreToolUse(\"bash\", '{\"cmd\":\"ls\"}');\n * if (pre.denied) { /* skip tool call *\\/ }\n *\n * // After tool executes:\n * const post = hooks.runPostToolUse(\"bash\", '{\"cmd\":\"ls\"}', \"file1\\nfile2\", false);\n * ```\n */\nexport class HookIntegration {\n constructor(\n private runner: HookRunner,\n private bus?: AgentEventBus,\n ) {}\n\n /**\n * Run pre-tool-use hooks. If any hook denies the call,\n * the tool execution should be skipped.\n */\n runPreToolUse(toolName: string, toolInput: string): HookRunResult {\n const result = this.runner.runPreToolUse(toolName, toolInput);\n\n if (result.denied) {\n this.bus?.emit(\"hook_denied\", {\n phase: \"pre\",\n toolName,\n toolInput,\n messages: result.messages,\n });\n } else if (result.messages.length > 0) {\n this.bus?.emit(\"hook_message\", {\n phase: \"pre\",\n toolName,\n messages: result.messages,\n });\n }\n\n return result;\n }\n\n /**\n * Run post-tool-use hooks. These can log, transform, or audit\n * tool results but cannot retroactively deny execution.\n */\n runPostToolUse(\n toolName: string,\n toolInput: string,\n toolOutput: string,\n isError: boolean,\n ): HookRunResult {\n const result = this.runner.runPostToolUse(toolName, toolInput, toolOutput, isError);\n\n if (result.messages.length > 0) {\n this.bus?.emit(\"hook_message\", {\n phase: \"post\",\n toolName,\n messages: result.messages,\n });\n }\n\n return result;\n }\n}\n\n// ── Slash Command Registry ────────────────────────────────────────────\n\n/**\n * Bridges the as-agent Wasm runtime's slash command system with\n * oboto-agent. The Wasm runtime provides 21 built-in slash commands\n * (e.g. /help, /compact, /clear, /model, etc.).\n *\n * This class provides:\n * - Access to command specs and help text from the Wasm runtime\n * - An extensible registry for adding custom slash commands\n * - Parsing and dispatching of slash command input\n *\n * ```ts\n * const registry = new SlashCommandRegistry(agentRuntime);\n * const specs = registry.getCommandSpecs();\n * const help = registry.getHelpText();\n *\n * // Add custom commands\n * registry.registerCommand({\n * name: \"status\",\n * summary: \"Show agent status\",\n * argumentHint: \"\",\n * resumeSupported: false,\n * }, async (args) => \"Agent is running\");\n * ```\n */\nexport class SlashCommandRegistry {\n private customCommands = new Map<string, {\n spec: SlashCommandSpec;\n handler: (args: string) => string | Promise<string>;\n }>();\n private wasmRuntime?: AgentRuntime;\n\n constructor(wasmRuntime?: AgentRuntime) {\n this.wasmRuntime = wasmRuntime;\n }\n\n /**\n * Get all slash command specs (built-in from Wasm + custom).\n */\n getCommandSpecs(): SlashCommandSpec[] {\n const builtIn = this.wasmRuntime\n ? (this.wasmRuntime.slashCommandSpecs() as SlashCommandSpec[])\n : [];\n\n const custom = Array.from(this.customCommands.values()).map(c => c.spec);\n\n return [...builtIn, ...custom];\n }\n\n /**\n * Get the full help text for all commands.\n * Uses the Wasm runtime's formatted help if available.\n */\n getHelpText(): string {\n const parts: string[] = [];\n\n if (this.wasmRuntime) {\n parts.push(this.wasmRuntime.renderSlashCommandHelp());\n }\n\n if (this.customCommands.size > 0) {\n parts.push(\"\\n## Custom Commands\\n\");\n for (const [name, { spec }] of this.customCommands) {\n const hint = spec.argumentHint ? ` ${spec.argumentHint}` : \"\";\n parts.push(`/${name}${hint} — ${spec.summary}`);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Register a custom slash command.\n */\n registerCommand(\n spec: SlashCommandSpec,\n handler: (args: string) => string | Promise<string>,\n ): void {\n this.customCommands.set(spec.name, { spec, handler });\n }\n\n /**\n * Unregister a custom slash command.\n */\n unregisterCommand(name: string): boolean {\n return this.customCommands.delete(name);\n }\n\n /**\n * Parse a user input string to check if it's a slash command.\n * Returns the command name and arguments, or null if not a command.\n */\n parseCommand(input: string): { name: string; args: string } | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return null;\n\n const spaceIdx = trimmed.indexOf(\" \");\n const name = spaceIdx === -1\n ? trimmed.slice(1)\n : trimmed.slice(1, spaceIdx);\n const args = spaceIdx === -1\n ? \"\"\n : trimmed.slice(spaceIdx + 1).trim();\n\n return { name, args };\n }\n\n /**\n * Execute a custom slash command by name.\n * Returns the command output, or null if the command is not found\n * in the custom registry (it may be a built-in Wasm command).\n */\n async executeCustomCommand(name: string, args: string): Promise<string | null> {\n const entry = this.customCommands.get(name);\n if (!entry) return null;\n return entry.handler(args);\n }\n\n /**\n * Check if a command name exists (either built-in or custom).\n */\n hasCommand(name: string): boolean {\n if (this.customCommands.has(name)) return true;\n const specs = this.getCommandSpecs();\n return specs.some(s => s.name === name);\n }\n\n /**\n * Get only commands that support resume (useful for session restoration).\n */\n getResumeSupportedCommands(): SlashCommandSpec[] {\n const builtIn = this.wasmRuntime\n ? (this.wasmRuntime.resumeSupportedSlashCommands() as SlashCommandSpec[])\n : [];\n\n const custom = Array.from(this.customCommands.values())\n .filter(c => c.spec.resumeSupported)\n .map(c => c.spec);\n\n return [...builtIn, ...custom];\n }\n}\n\n// ── Usage Tracker Adapter ─────────────────────────────────────────────\n\n/**\n * A JS-side implementation of the as-agent UsageTracker interface.\n * This adapter accumulates token usage across turns, matching the\n * as-agent contract (inputTokens, outputTokens, cache tokens).\n *\n * The bridge to lmscript's CostTracker (which uses different field names)\n * is handled in Task 11.\n */\nexport class AgentUsageTracker implements UsageTracker {\n private turnUsages: AsTokenUsage[] = [];\n private currentTurn: AsTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n\n record(usage: AsTokenUsage): void {\n this.currentTurn = {\n inputTokens: this.currentTurn.inputTokens + usage.inputTokens,\n outputTokens: this.currentTurn.outputTokens + usage.outputTokens,\n cacheCreationInputTokens: this.currentTurn.cacheCreationInputTokens + usage.cacheCreationInputTokens,\n cacheReadInputTokens: this.currentTurn.cacheReadInputTokens + usage.cacheReadInputTokens,\n };\n }\n\n currentTurnUsage(): AsTokenUsage {\n return { ...this.currentTurn };\n }\n\n cumulativeUsage(): AsTokenUsage {\n const cumulative: AsTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n\n for (const usage of this.turnUsages) {\n cumulative.inputTokens += usage.inputTokens;\n cumulative.outputTokens += usage.outputTokens;\n cumulative.cacheCreationInputTokens += usage.cacheCreationInputTokens;\n cumulative.cacheReadInputTokens += usage.cacheReadInputTokens;\n }\n\n // Add current turn\n cumulative.inputTokens += this.currentTurn.inputTokens;\n cumulative.outputTokens += this.currentTurn.outputTokens;\n cumulative.cacheCreationInputTokens += this.currentTurn.cacheCreationInputTokens;\n cumulative.cacheReadInputTokens += this.currentTurn.cacheReadInputTokens;\n\n return cumulative;\n }\n\n turns(): number {\n return this.turnUsages.length + (this.hasTurnActivity() ? 1 : 0);\n }\n\n /**\n * Finalize the current turn and start a new one.\n * Call this at the end of each agent turn.\n */\n endTurn(): void {\n if (this.hasTurnActivity()) {\n this.turnUsages.push({ ...this.currentTurn });\n this.currentTurn = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n }\n }\n\n /** Reset all usage data. */\n reset(): void {\n this.turnUsages = [];\n this.currentTurn = {\n inputTokens: 0,\n outputTokens: 0,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n }\n\n private hasTurnActivity(): boolean {\n return (\n this.currentTurn.inputTokens > 0 ||\n this.currentTurn.outputTokens > 0\n );\n }\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────\n\nfunction roleToString(role: MessageRole): string {\n switch (role) {\n case MessageRole.System: return \"system\";\n case MessageRole.User: return \"user\";\n case MessageRole.Assistant: return \"assistant\";\n case MessageRole.Tool: return \"tool\";\n default: return \"unknown\";\n }\n}\n\nfunction blocksToText(blocks: ConversationMessage[\"blocks\"]): string {\n return blocks\n .map((b) => {\n switch (b.kind) {\n case \"text\":\n return b.text;\n case \"tool_use\":\n return `[Tool: ${b.name}(${b.input})]`;\n case \"tool_result\":\n return b.isError\n ? `[Error: ${b.toolName}: ${b.output}]`\n : `[Result: ${b.toolName}: ${b.output}]`;\n default:\n return \"\";\n }\n })\n .join(\"\\n\");\n}\n","/**\n * router-events.ts — Bridge LLMRouter health/failover events into the agent event bus.\n *\n * The LLMRouter (from @sschepis/llm-wrapper) exposes a `RouterEventEmitter` that\n * fires typed events for routing decisions, fallbacks, circuit breaker state changes,\n * and request completions/errors.\n *\n * This module:\n * 1. Subscribes to all LLMRouter events\n * 2. Forwards them to the agent's AgentEventBus as `router_event` events\n * 3. Provides a health snapshot method for observability\n */\n\nimport type {\n LLMRouter,\n RouterEventMap,\n HealthState,\n} from \"@sschepis/llm-wrapper\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n/** All LLMRouter event names we subscribe to. */\nconst ROUTER_EVENTS: (keyof RouterEventMap)[] = [\n \"route\",\n \"fallback\",\n \"circuit:open\",\n \"circuit:close\",\n \"circuit:half-open\",\n \"request:complete\",\n \"request:error\",\n];\n\n/**\n * Bridge that forwards LLMRouter events to the agent event bus.\n *\n * Usage:\n * ```ts\n * const bridge = new RouterEventBridge(bus);\n * bridge.attach(localRouter, \"local\");\n * bridge.attach(remoteRouter, \"remote\");\n *\n * // Later, get a health snapshot\n * const health = bridge.getHealthSnapshot();\n * ```\n */\nexport class RouterEventBridge {\n private bus: AgentEventBus;\n private attachedRouters = new Map<string, {\n router: LLMRouter;\n detachFns: Array<() => void>;\n }>();\n\n constructor(bus: AgentEventBus) {\n this.bus = bus;\n }\n\n /**\n * Attach an LLMRouter and forward all its events to the agent bus.\n *\n * @param router - The LLMRouter to monitor\n * @param label - A label to identify this router in events (e.g. \"local\", \"remote\")\n */\n attach(router: LLMRouter, label: string): void {\n // Detach if already attached with this label\n this.detach(label);\n\n const detachFns: Array<() => void> = [];\n\n for (const eventName of ROUTER_EVENTS) {\n const handler = (data: RouterEventMap[typeof eventName]) => {\n this.bus.emit(\"router_event\", {\n routerLabel: label,\n eventName,\n data,\n timestamp: Date.now(),\n });\n };\n\n router.events.on(eventName, handler as any);\n detachFns.push(() => {\n router.events.off(eventName, handler as any);\n });\n }\n\n this.attachedRouters.set(label, { router, detachFns });\n }\n\n /**\n * Detach a previously attached router.\n */\n detach(label: string): void {\n const entry = this.attachedRouters.get(label);\n if (entry) {\n for (const fn of entry.detachFns) {\n fn();\n }\n this.attachedRouters.delete(label);\n }\n }\n\n /**\n * Detach all attached routers.\n */\n detachAll(): void {\n for (const label of this.attachedRouters.keys()) {\n this.detach(label);\n }\n }\n\n /**\n * Get a health snapshot from all attached routers.\n * Returns a map of router label -> endpoint name -> HealthState.\n */\n getHealthSnapshot(): Map<string, Map<string, HealthState>> {\n const snapshot = new Map<string, Map<string, HealthState>>();\n\n for (const [label, { router }] of this.attachedRouters) {\n snapshot.set(label, router.getHealthState());\n }\n\n return snapshot;\n }\n\n /**\n * Check if any attached router has an endpoint in \"open\" (tripped) circuit state.\n */\n hasTrippedCircuits(): boolean {\n for (const [, { router }] of this.attachedRouters) {\n for (const [, health] of router.getHealthState()) {\n if (health.status === \"open\") return true;\n }\n }\n return false;\n }\n\n /**\n * Get the labels of all attached routers.\n */\n get labels(): string[] {\n return Array.from(this.attachedRouters.keys());\n }\n}\n\n/**\n * Helper to check if a ProviderLike is an LLMRouter (has `events` property).\n */\nexport function isLLMRouter(provider: unknown): provider is LLMRouter {\n return (\n typeof provider === \"object\" &&\n provider !== null &&\n \"events\" in provider &&\n \"getHealthState\" in provider\n );\n}\n","/**\n * usage-bridge.ts — Bidirectional bridge between as-agent's UsageTracker\n * and lmscript's CostTracker.\n *\n * Field mapping:\n * as-agent lmscript\n * ───────── ────────\n * inputTokens → promptTokens\n * outputTokens → completionTokens\n * cacheCreationInputTokens → (no equivalent, tracked separately)\n * cacheReadInputTokens → (no equivalent, tracked separately)\n * (sum of all) → totalTokens\n *\n * The bridge records every usage event into both systems, ensuring\n * unified cost accounting regardless of which subsystem reports usage.\n */\n\nimport type {\n TokenUsage as AsTokenUsage,\n UsageTracker,\n ModelPricing as AsModelPricing,\n UsageCostEstimate,\n} from \"@sschepis/as-agent\";\nimport type {\n CostTracker,\n ModelPricing as LmModelPricing,\n} from \"@sschepis/lmscript\";\nimport { AgentUsageTracker } from \"./as-agent-features.js\";\n\n// ── Type converters ──────────────────────────────────────────────────\n\n/**\n * Convert as-agent TokenUsage to lmscript usage format.\n */\nexport function asTokenUsageToLmscript(usage: AsTokenUsage): {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n} {\n const promptTokens = usage.inputTokens;\n const completionTokens = usage.outputTokens;\n // Total includes all token types (input + output + cache tokens)\n const totalTokens =\n usage.inputTokens +\n usage.outputTokens +\n usage.cacheCreationInputTokens +\n usage.cacheReadInputTokens;\n\n return { promptTokens, completionTokens, totalTokens };\n}\n\n/**\n * Convert lmscript usage format to as-agent TokenUsage.\n * Cache tokens default to 0 since lmscript doesn't track them separately.\n */\nexport function lmscriptToAsTokenUsage(usage: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}): AsTokenUsage {\n return {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n cacheCreationInputTokens: 0,\n cacheReadInputTokens: 0,\n };\n}\n\n// ── Cost estimation ──────────────────────────────────────────────────\n\n/**\n * Estimate costs using as-agent's ModelPricing (per-million-token pricing).\n */\nexport function estimateCostFromAsAgent(\n usage: AsTokenUsage,\n pricing: AsModelPricing,\n): UsageCostEstimate {\n const inputCostUsd = (usage.inputTokens / 1_000_000) * pricing.inputCostPerMillion;\n const outputCostUsd = (usage.outputTokens / 1_000_000) * pricing.outputCostPerMillion;\n const cacheCreationCostUsd = (usage.cacheCreationInputTokens / 1_000_000) * pricing.cacheCreationCostPerMillion;\n const cacheReadCostUsd = (usage.cacheReadInputTokens / 1_000_000) * pricing.cacheReadCostPerMillion;\n const totalCostUsd = inputCostUsd + outputCostUsd + cacheCreationCostUsd + cacheReadCostUsd;\n\n return {\n inputCostUsd,\n outputCostUsd,\n cacheCreationCostUsd,\n cacheReadCostUsd,\n totalCostUsd,\n };\n}\n\n// ── Usage Bridge ─────────────────────────────────────────────────────\n\n/**\n * Bidirectional bridge that keeps an as-agent UsageTracker and an\n * lmscript CostTracker in sync.\n *\n * When usage is reported from either side, the bridge records it in\n * both tracking systems.\n *\n * ```ts\n * const bridge = new UsageBridge(usageTracker, costTracker);\n *\n * // Record from LLM response (lmscript format)\n * bridge.recordFromLmscript(\"gpt-4\", { promptTokens: 100, completionTokens: 50, totalTokens: 150 });\n *\n * // Record from API response (as-agent format)\n * bridge.recordFromAsAgent({ inputTokens: 100, outputTokens: 50, cacheCreationInputTokens: 0, cacheReadInputTokens: 0 });\n *\n * // Get unified cost summary\n * const summary = bridge.getCostSummary(lmModelPricing, asModelPricing);\n * ```\n */\nexport class UsageBridge {\n constructor(\n private asTracker: AgentUsageTracker,\n private lmTracker?: CostTracker,\n ) {}\n\n /**\n * Record usage from an lmscript-format source (e.g. from the streaming path\n * or AgentLoop result).\n *\n * Converts to as-agent format and records in both trackers.\n */\n recordFromLmscript(\n functionName: string,\n usage: { promptTokens: number; completionTokens: number; totalTokens: number },\n ): void {\n // Record in lmscript CostTracker\n this.lmTracker?.trackUsage(functionName, usage);\n\n // Convert and record in as-agent tracker\n this.asTracker.record(lmscriptToAsTokenUsage(usage));\n }\n\n /**\n * Record usage from an as-agent-format source (e.g. from ConversationRuntime\n * or the Wasm runtime).\n *\n * Converts to lmscript format and records in both trackers.\n */\n recordFromAsAgent(\n usage: AsTokenUsage,\n functionName?: string,\n ): void {\n // Record in as-agent tracker\n this.asTracker.record(usage);\n\n // Convert and record in lmscript CostTracker\n if (this.lmTracker) {\n this.lmTracker.trackUsage(\n functionName ?? \"as-agent\",\n asTokenUsageToLmscript(usage),\n );\n }\n }\n\n /**\n * End the current turn in the as-agent tracker.\n */\n endTurn(): void {\n this.asTracker.endTurn();\n }\n\n /**\n * Get unified cost summary combining both tracking systems.\n */\n getCostSummary(\n lmPricing?: LmModelPricing,\n asPricing?: AsModelPricing,\n ): UnifiedCostSummary {\n const asUsage = this.asTracker.cumulativeUsage();\n const asTurns = this.asTracker.turns();\n\n // as-agent side cost estimation\n let asCostEstimate: UsageCostEstimate | undefined;\n if (asPricing) {\n asCostEstimate = estimateCostFromAsAgent(asUsage, asPricing);\n }\n\n // lmscript side totals\n let lmTotalTokens: number | undefined;\n let lmTotalCost: number | undefined;\n let lmByFunction: Record<string, { calls: number; totalTokens: number; promptTokens: number; completionTokens: number }> | undefined;\n\n if (this.lmTracker) {\n lmTotalTokens = this.lmTracker.getTotalTokens();\n lmTotalCost = this.lmTracker.getTotalCost(lmPricing);\n const usageMap = this.lmTracker.getUsageByFunction();\n lmByFunction = {};\n for (const [fnName, entry] of usageMap) {\n lmByFunction[fnName] = entry;\n }\n }\n\n return {\n // as-agent view\n asAgent: {\n usage: asUsage,\n turns: asTurns,\n costEstimate: asCostEstimate,\n },\n // lmscript view\n lmscript: this.lmTracker ? {\n totalTokens: lmTotalTokens!,\n totalCost: lmTotalCost!,\n byFunction: lmByFunction!,\n } : undefined,\n };\n }\n\n /**\n * Reset both tracking systems.\n */\n reset(): void {\n this.asTracker.reset();\n this.lmTracker?.reset();\n }\n\n /** Get the as-agent usage tracker. */\n getAsTracker(): AgentUsageTracker {\n return this.asTracker;\n }\n\n /** Get the lmscript cost tracker (if available). */\n getLmTracker(): CostTracker | undefined {\n return this.lmTracker;\n }\n}\n\n// ── Unified summary type ─────────────────────────────────────────────\n\nexport interface UnifiedCostSummary {\n /** as-agent's view: per-turn token counts and optional cost estimate. */\n asAgent: {\n usage: AsTokenUsage;\n turns: number;\n costEstimate?: UsageCostEstimate;\n };\n /** lmscript's view: total tokens, cost, and per-function breakdown. */\n lmscript?: {\n totalTokens: number;\n totalCost: number;\n byFunction: Record<string, {\n calls: number;\n totalTokens: number;\n promptTokens: number;\n completionTokens: number;\n }>;\n };\n}\n","/**\n * tool-extensions.ts — Swiss-army-tool integration extensions for oboto-agent.\n *\n * This module provides:\n * 1. AgentDynamicTools — A DynamicBranchNode subclass for runtime tool discovery\n * 2. createToolTimingMiddleware — Swiss-army-tool Middleware that emits timing events\n * 3. createAgentToolTree — Helper to build a pre-wired tool tree with memory + dynamic tools\n */\n\nimport {\n DynamicBranchNode,\n BranchNode,\n LeafNode,\n TreeBuilder,\n SessionManager,\n createMemoryModule,\n type Middleware,\n type ExecutionContext,\n} from \"@sschepis/swiss-army-tool\";\nimport type { AgentEventBus } from \"../event-bus.js\";\n\n// ── Types ─────────────────────────────────────────────────────────────\n\nexport interface DynamicToolProvider {\n /**\n * Called when the branch needs refreshing.\n * Return an array of leaf node configs to populate the dynamic branch.\n */\n discover(): Promise<DynamicToolEntry[]> | DynamicToolEntry[];\n}\n\nexport interface DynamicToolEntry {\n name: string;\n description: string;\n requiredArgs?: string[] | Record<string, { type?: string; description?: string }>;\n optionalArgs?: string[] | Record<string, { type?: string; description?: string; default?: unknown }>;\n handler: (kwargs: Record<string, unknown>) => string | Promise<string>;\n}\n\nexport interface AgentToolTreeConfig {\n /** Session manager for the swiss-army-tool Router */\n session: SessionManager;\n /** Whether to include the memory module (set/get/list/pin). Default: true */\n includeMemory?: boolean;\n /** Additional static branches to add to the tree */\n staticBranches?: BranchNode[];\n /** Dynamic tool providers to register. Each entry becomes a DynamicBranchNode */\n dynamicProviders?: Array<{\n name: string;\n description: string;\n provider: DynamicToolProvider;\n /** TTL in ms before the provider is re-queried. Default: 60000 */\n ttlMs?: number;\n }>;\n}\n\n// ── AgentDynamicTools ─────────────────────────────────────────────────\n\n/**\n * A DynamicBranchNode that discovers tools at runtime from a provider.\n *\n * Use this to integrate external tool sources (MCP servers, plugin systems,\n * API discovery endpoints, etc.) into the swiss-army-tool command tree.\n *\n * The provider's `discover()` method is called when the TTL expires,\n * and the returned entries are registered as LeafNode children.\n *\n * ```ts\n * const mcpTools = new AgentDynamicTools({\n * name: \"mcp\",\n * description: \"Tools discovered from MCP servers\",\n * provider: myMcpProvider,\n * ttlMs: 30_000, // refresh every 30s\n * });\n * ```\n */\nexport class AgentDynamicTools extends DynamicBranchNode {\n private provider: DynamicToolProvider;\n\n constructor(config: {\n name: string;\n description: string;\n provider: DynamicToolProvider;\n ttlMs?: number;\n }) {\n super({\n name: config.name,\n description: config.description,\n ttlMs: config.ttlMs ?? 60_000,\n });\n this.provider = config.provider;\n }\n\n protected async refresh(): Promise<void> {\n const entries = await this.provider.discover();\n for (const entry of entries) {\n this.addChild(\n new LeafNode({\n name: entry.name,\n description: entry.description,\n requiredArgs: entry.requiredArgs as any,\n optionalArgs: entry.optionalArgs as any,\n handler: entry.handler,\n }),\n { overwrite: true }\n );\n }\n }\n\n /** Manually register a tool entry without waiting for refresh. */\n registerTool(entry: DynamicToolEntry): void {\n this.addChild(\n new LeafNode({\n name: entry.name,\n description: entry.description,\n requiredArgs: entry.requiredArgs as any,\n optionalArgs: entry.optionalArgs as any,\n handler: entry.handler,\n }),\n { overwrite: true }\n );\n }\n\n /** Remove a dynamically registered tool by name. */\n unregisterTool(name: string): boolean {\n return this.removeChild(name);\n }\n}\n\n// ── Middleware Factories ──────────────────────────────────────────────\n\n/**\n * Creates a swiss-army-tool Middleware that emits tool execution timing\n * and results through the agent's event bus.\n *\n * This bridges swiss-army-tool's execution context into oboto-agent's\n * event-driven architecture, enabling:\n * - Real-time tool execution duration monitoring\n * - Tool execution logging / tracing\n * - Performance analytics\n *\n * ```ts\n * const timingMw = createToolTimingMiddleware(agent.bus);\n * router.use(timingMw);\n * ```\n */\nexport function createToolTimingMiddleware(bus: AgentEventBus): Middleware {\n return async (ctx: ExecutionContext, next: () => Promise<string>) => {\n const startTime = Date.now();\n bus.emit(\"tool_execution_start\", {\n command: ctx.command,\n kwargs: ctx.kwargs,\n resolvedPath: ctx.resolvedPath,\n });\n\n try {\n const result = await next();\n const durationMs = Date.now() - startTime;\n\n bus.emit(\"tool_execution_complete\", {\n command: ctx.command,\n kwargs: ctx.kwargs,\n result: result.length > 500 ? result.slice(0, 500) + \"...\" : result,\n durationMs,\n });\n\n return result;\n } catch (err) {\n const durationMs = Date.now() - startTime;\n bus.emit(\"error\", {\n message: `Tool execution failed: ${ctx.command}`,\n error: err,\n durationMs,\n });\n throw err;\n }\n };\n}\n\n/**\n * Creates a swiss-army-tool Middleware that enforces a maximum execution\n * time for any tool call. Useful as a safety net.\n */\nexport function createToolTimeoutMiddleware(maxMs: number): Middleware {\n return async (_ctx: ExecutionContext, next: () => Promise<string>) => {\n const result = await Promise.race([\n next(),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(`Tool execution timed out after ${maxMs}ms`)),\n maxMs\n )\n ),\n ]);\n return result;\n };\n}\n\n/**\n * Creates a swiss-army-tool Middleware that logs all tool calls to the\n * session's KV store for later review. The agent can access these via\n * the memory module.\n */\nexport function createToolAuditMiddleware(session: SessionManager): Middleware {\n let callIndex = 0;\n\n return async (ctx: ExecutionContext, next: () => Promise<string>) => {\n const idx = ++callIndex;\n const startTime = Date.now();\n const result = await next();\n const durationMs = Date.now() - startTime;\n\n const entry = JSON.stringify({\n command: ctx.command,\n kwargs: ctx.kwargs,\n resultLength: result.length,\n durationMs,\n timestamp: new Date().toISOString(),\n });\n\n session.kvStore.set(`_audit:${idx}`, entry);\n return result;\n };\n}\n\n// ── Tool Tree Builder ────────────────────────────────────────────────\n\n/**\n * Build a pre-wired swiss-army-tool command tree that includes:\n * - Memory module (set/get/list/search/pin/unpin/delete/tag)\n * - Dynamic tool branches from providers\n * - Any additional static branches\n *\n * Returns the root BranchNode, ready to be passed to `new Router(root, session)`.\n *\n * ```ts\n * const root = createAgentToolTree({\n * session,\n * includeMemory: true,\n * dynamicProviders: [\n * { name: \"mcp\", description: \"MCP tools\", provider: mcpProvider },\n * ],\n * staticBranches: [myFilesystemBranch, myDatabaseBranch],\n * });\n * const router = new Router(root, session);\n * ```\n */\nexport function createAgentToolTree(config: AgentToolTreeConfig): BranchNode {\n const builder = TreeBuilder.create(\"root\", \"Agent command tree with integrated tools\");\n\n // Add memory module\n if (config.includeMemory !== false) {\n const memoryBranch = createMemoryModule(config.session);\n builder.addBranch(memoryBranch);\n }\n\n // Build the root first so we can add dynamic branches\n const root = builder.build();\n\n // Add dynamic tool providers\n if (config.dynamicProviders) {\n for (const dp of config.dynamicProviders) {\n const dynamicBranch = new AgentDynamicTools({\n name: dp.name,\n description: dp.description,\n provider: dp.provider,\n ttlMs: dp.ttlMs,\n });\n root.addChild(dynamicBranch);\n }\n }\n\n // Add additional static branches\n if (config.staticBranches) {\n for (const branch of config.staticBranches) {\n root.addChild(branch);\n }\n }\n\n return root;\n}\n","/**\n * pipeline-workflows.ts — Multi-step agent workflows using lmscript's Pipeline.\n *\n * This module provides pre-built and composable pipeline patterns for\n * chaining LLM calls where the typed output of one step feeds into the next.\n *\n * Key patterns:\n * 1. Triage → Execute → Summarize\n * 2. Analyze → Plan → Execute\n * 3. Custom pipeline builder for agent-specific workflows\n */\n\nimport { z } from \"zod\";\nimport {\n Pipeline,\n type LScriptRuntime,\n type LScriptFunction,\n type PipelineResult,\n} from \"@sschepis/lmscript\";\n\n// ── Schema definitions for pipeline steps ────────────────────────────\n\n/** Output of a triage step — determines routing and intent. */\nexport const TriagePipelineSchema = z.object({\n intent: z.string().describe(\"The classified intent of the user input\"),\n complexity: z.enum([\"simple\", \"moderate\", \"complex\"]).describe(\"Estimated task complexity\"),\n requiresTools: z.boolean().describe(\"Whether tools are needed\"),\n suggestedApproach: z.string().describe(\"Brief approach suggestion\"),\n escalate: z.boolean().describe(\"Whether to escalate to the remote model\"),\n});\nexport type TriagePipelineOutput = z.infer<typeof TriagePipelineSchema>;\n\n/** Output of a planning step — breaks work into steps. */\nexport const PlanSchema = z.object({\n steps: z.array(z.object({\n description: z.string(),\n toolRequired: z.string().optional(),\n expectedOutput: z.string().optional(),\n })).describe(\"Ordered list of steps to accomplish the task\"),\n estimatedComplexity: z.enum([\"low\", \"medium\", \"high\"]),\n reasoning: z.string().describe(\"Why this plan was chosen\"),\n});\nexport type PlanOutput = z.infer<typeof PlanSchema>;\n\n/** Output of an execution step — the actual work result. */\nexport const ExecutionSchema = z.object({\n response: z.string().describe(\"The response or result of executing the plan\"),\n stepsCompleted: z.number().describe(\"Number of plan steps completed\"),\n toolsUsed: z.array(z.string()).optional(),\n confidence: z.enum([\"low\", \"medium\", \"high\"]),\n});\nexport type ExecutionOutput = z.infer<typeof ExecutionSchema>;\n\n/** Output of a summarization step — condenses results. */\nexport const SummarySchema = z.object({\n summary: z.string().describe(\"Concise summary of what was accomplished\"),\n keyPoints: z.array(z.string()).describe(\"Key points from the execution\"),\n followUpSuggestions: z.array(z.string()).optional(),\n});\nexport type SummaryOutput = z.infer<typeof SummarySchema>;\n\n// ── Pipeline step factories ──────────────────────────────────────────\n\n/**\n * Create a triage step function for the pipeline.\n */\nexport function createTriageStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<string, typeof TriagePipelineSchema> {\n return {\n name: \"pipeline-triage\",\n model: modelName,\n system: systemPrompt ?? \"You are a task classifier. Analyze the input and determine its intent, complexity, and whether it requires tools or escalation.\",\n prompt: (input: string) => `Classify this request:\\n\\n${input}`,\n schema: TriagePipelineSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n}\n\n/**\n * Create a planning step that takes triage output and produces a plan.\n */\nexport function createPlanStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<TriagePipelineOutput, typeof PlanSchema> {\n return {\n name: \"pipeline-plan\",\n model: modelName,\n system: systemPrompt ?? \"You are a task planner. Given the triage analysis, create a step-by-step plan to accomplish the task.\",\n prompt: (triage: TriagePipelineOutput) =>\n `Create an execution plan based on this analysis:\\n` +\n `Intent: ${triage.intent}\\n` +\n `Complexity: ${triage.complexity}\\n` +\n `Requires tools: ${triage.requiresTools}\\n` +\n `Suggested approach: ${triage.suggestedApproach}`,\n schema: PlanSchema,\n temperature: 0.3,\n maxRetries: 1,\n };\n}\n\n/**\n * Create an execution step that takes a plan and produces results.\n */\nexport function createExecutionStep(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n systemPrompt?: string,\n): LScriptFunction<PlanOutput, typeof ExecutionSchema> {\n return {\n name: \"pipeline-execute\",\n model: modelName,\n system: systemPrompt ?? \"You are a task executor. Follow the given plan step by step and produce the result.\",\n prompt: (plan: PlanOutput) => {\n const stepsStr = plan.steps\n .map((s, i) => `${i + 1}. ${s.description}${s.toolRequired ? ` (tool: ${s.toolRequired})` : \"\"}`)\n .join(\"\\n\");\n return `Execute this plan:\\n\\n${stepsStr}\\n\\nReasoning: ${plan.reasoning}`;\n },\n schema: ExecutionSchema,\n tools,\n temperature: 0.5,\n maxRetries: 1,\n };\n}\n\n/**\n * Create a summarization step that condenses execution results.\n */\nexport function createSummaryStep(\n modelName: string,\n systemPrompt?: string,\n): LScriptFunction<ExecutionOutput, typeof SummarySchema> {\n return {\n name: \"pipeline-summarize\",\n model: modelName,\n system: systemPrompt ?? \"You are a summarizer. Condense the execution results into a clear, concise summary.\",\n prompt: (execution: ExecutionOutput) =>\n `Summarize these results:\\n` +\n `Response: ${execution.response}\\n` +\n `Steps completed: ${execution.stepsCompleted}\\n` +\n `Confidence: ${execution.confidence}\\n` +\n (execution.toolsUsed?.length ? `Tools used: ${execution.toolsUsed.join(\", \")}` : \"\"),\n schema: SummarySchema,\n temperature: 0.3,\n maxRetries: 1,\n };\n}\n\n// ── Pre-built pipeline constructors ──────────────────────────────────\n\n/**\n * Build a Triage → Plan → Execute pipeline.\n *\n * Takes raw user input, classifies it, plans the approach,\n * and executes the plan.\n *\n * ```ts\n * const pipeline = createTriagePlanExecutePipeline(\"gpt-4\");\n * const result = await pipeline.execute(runtime, \"Refactor the auth module\");\n * console.log(result.finalData.response);\n * ```\n */\nexport function createTriagePlanExecutePipeline(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n): Pipeline<string, ExecutionOutput> {\n return Pipeline\n .from(createTriageStep(modelName))\n .pipe(createPlanStep(modelName))\n .pipe(createExecutionStep(modelName, tools));\n}\n\n/**\n * Build a Triage → Plan → Execute → Summarize pipeline.\n *\n * Full end-to-end pipeline that classifies, plans, executes,\n * and then summarizes the results.\n *\n * ```ts\n * const pipeline = createFullPipeline(\"gpt-4\");\n * const result = await pipeline.execute(runtime, \"Build a REST API\");\n * console.log(result.finalData.summary);\n * console.log(`Total tokens: ${result.totalUsage.totalTokens}`);\n * ```\n */\nexport function createFullPipeline(\n modelName: string,\n tools?: LScriptFunction<any, any>[\"tools\"],\n): Pipeline<string, SummaryOutput> {\n return Pipeline\n .from(createTriageStep(modelName))\n .pipe(createPlanStep(modelName))\n .pipe(createExecutionStep(modelName, tools))\n .pipe(createSummaryStep(modelName));\n}\n\n/**\n * Build a simple Analyze → Respond pipeline.\n * Good for straightforward queries that don't need planning.\n */\nexport function createAnalyzeRespondPipeline(\n modelName: string,\n): Pipeline<string, ExecutionOutput> {\n const analyzeStep: LScriptFunction<string, typeof TriagePipelineSchema> = {\n name: \"pipeline-analyze\",\n model: modelName,\n system: \"You are an analyst. Understand the request and identify the best approach.\",\n prompt: (input: string) => `Analyze this request:\\n\\n${input}`,\n schema: TriagePipelineSchema,\n temperature: 0.1,\n maxRetries: 1,\n };\n\n const respondStep: LScriptFunction<TriagePipelineOutput, typeof ExecutionSchema> = {\n name: \"pipeline-respond\",\n model: modelName,\n system: \"You are a helpful assistant. Based on the analysis, provide a comprehensive response.\",\n prompt: (analysis: TriagePipelineOutput) =>\n `Respond to this request:\\n` +\n `Intent: ${analysis.intent}\\n` +\n `Approach: ${analysis.suggestedApproach}`,\n schema: ExecutionSchema,\n temperature: 0.7,\n maxRetries: 1,\n };\n\n return Pipeline.from(analyzeStep).pipe(respondStep);\n}\n\n// ── Pipeline runner helper ───────────────────────────────────────────\n\n/**\n * Configuration for running a pipeline within the agent context.\n */\nexport interface AgentPipelineConfig {\n /** The lmscript runtime to execute the pipeline on. */\n runtime: LScriptRuntime;\n /** The model name for all pipeline steps (can be overridden per-step). */\n modelName: string;\n /** Optional tools available to the execution step. */\n tools?: LScriptFunction<any, any>[\"tools\"];\n /** Callback for each pipeline step completion. */\n onStepComplete?: (stepName: string, data: unknown, usage: { promptTokens: number; completionTokens: number; totalTokens: number } | undefined) => void;\n}\n\n/**\n * Run a pipeline and emit step completion events.\n * This is a convenience wrapper that adds observability.\n */\nexport async function runAgentPipeline<I, O>(\n pipeline: Pipeline<I, O>,\n input: I,\n config: AgentPipelineConfig,\n): Promise<PipelineResult<O>> {\n const result = await pipeline.execute(config.runtime, input);\n\n if (config.onStepComplete) {\n for (const step of result.steps) {\n config.onStepComplete(step.name, step.data, step.usage);\n }\n }\n\n return result;\n}\n"],"mappings":"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","names":["MessageRole","z","z","MessageRole","blocksToText","MessageRole","blocksToText","MessageRole","z","z","SummarySchema"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sschepis/oboto-agent",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Event-driven dual-LLM orchestration library for autonomous AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",