@directive-run/ai 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { M as Message$1, e as RunResult, A as AgentLike, G as GuardrailFn, O as OutputGuardrailData, aX as StreamingCallbackRunner, D as DebugEvent, a1 as DebugEventType, b as AgentRunner, aw as OrchestratorState, aq as NamedGuardrail, I as InputGuardrailData, C as Checkpoint, u as BreakpointModifications, v as BreakpointRequest, ar as OrchestratorConstraint, au as OrchestratorResolver, af as GuardrailsConfig, o as ApprovalRequest, as as OrchestratorDebugConfig, k as AgentRetryConfig, at as OrchestratorLifecycleHooks, aU as SelfHealingConfig, L as CheckpointStore, r as BreakpointConfig, ai as HealthMonitorConfig, R as RunOptions, T as ToolCallGuardrailData, ay as PatternCheckpointConfig, Z as DagPattern, a7 as GoalPattern, a6 as GoalNode, m as AgentSelectionStrategy, aL as RelaxationTier, f as GoalResult, a4 as GoalCheckpointState, aV as SequentialCheckpointState, aY as SupervisorCheckpointState, aF as ReflectCheckpointState, _ as DebateCheckpointState, U as DagCheckpointState, aS as Scratchpad, ao as MultiAgentLifecycleHooks, ap as MultiAgentSelfHealingConfig, am as MultiAgentBreakpointType, P as CrossAgentDerivationFn, W as DagNode, V as DagExecutionContext, az as PatternCheckpointState, E as CheckpointDiff, H as CheckpointProgress, a5 as GoalMetrics } from './types-Co4BzMiH.js';
1
+ import { M as Message$1, e as RunResult, A as AgentLike, G as GuardrailFn, O as OutputGuardrailData, aX as StreamingCallbackRunner, D as DebugEvent, a1 as DebugEventType, b as AgentRunner, aw as OrchestratorState, aq as NamedGuardrail, I as InputGuardrailData, C as Checkpoint, u as BreakpointModifications, v as BreakpointRequest, ar as OrchestratorConstraint, au as OrchestratorResolver, af as GuardrailsConfig, o as ApprovalRequest, as as OrchestratorDebugConfig, k as AgentRetryConfig, at as OrchestratorLifecycleHooks, aU as SelfHealingConfig, L as CheckpointStore, r as BreakpointConfig, ai as HealthMonitorConfig, R as RunOptions, T as ToolCallGuardrailData, ay as PatternCheckpointConfig, Z as DagPattern, a7 as GoalPattern, a6 as GoalNode, m as AgentSelectionStrategy, aL as RelaxationTier, f as GoalResult, a4 as GoalCheckpointState, aV as SequentialCheckpointState, aY as SupervisorCheckpointState, aF as ReflectCheckpointState, _ as DebateCheckpointState, U as DagCheckpointState, aS as Scratchpad, ao as MultiAgentLifecycleHooks, ap as MultiAgentSelfHealingConfig, am as MultiAgentBreakpointType, P as CrossAgentDerivationFn, W as DagNode, V as DagExecutionContext, az as PatternCheckpointState, E as CheckpointDiff, H as CheckpointProgress, a5 as GoalMetrics } from './types-D5veI9su.cjs';
2
2
  import { Plugin, System, Requirement } from '@directive-run/core';
3
3
  import { CircuitBreaker } from '@directive-run/core/plugins';
4
4
 
@@ -998,6 +998,58 @@ interface AgentOrchestrator<F extends Record<string, unknown>> {
998
998
  */
999
999
  declare function createAgentOrchestrator<F extends Record<string, unknown> = Record<string, never>>(options: OrchestratorOptions<F>): AgentOrchestrator<F>;
1000
1000
 
1001
+ /**
1002
+ * Health Monitor — tracks per-agent health metrics for self-healing networks.
1003
+ *
1004
+ * Pure computation module with zero Directive dependency.
1005
+ * Maintains a rolling window of success/failure events and computes a health
1006
+ * score from 0-100 based on configurable weights.
1007
+ *
1008
+ * @module
1009
+ */
1010
+
1011
+ /** Circuit state values */
1012
+ type HealthCircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
1013
+ /** Per-agent health metrics */
1014
+ interface AgentHealthMetrics {
1015
+ agentId: string;
1016
+ circuitState: HealthCircuitState;
1017
+ successRate: number;
1018
+ avgLatencyMs: number;
1019
+ recentFailures: number;
1020
+ recentSuccesses: number;
1021
+ healthScore: number;
1022
+ /** Last N error messages (most recent last) */
1023
+ lastErrors: string[];
1024
+ }
1025
+ /** Health monitor instance */
1026
+ interface HealthMonitor {
1027
+ recordSuccess(agentId: string, latencyMs: number): void;
1028
+ recordFailure(agentId: string, latencyMs: number, error?: Error): void;
1029
+ getMetrics(agentId: string): AgentHealthMetrics;
1030
+ getAllMetrics(): Record<string, AgentHealthMetrics>;
1031
+ /** Returns a 0-100 health score. Returns 50 (neutral) when no data is available for the agent. */
1032
+ getHealthScore(agentId: string): number;
1033
+ updateCircuitState(agentId: string, state: HealthCircuitState): void;
1034
+ /** Reset all metrics. Useful for testing. */
1035
+ reset(): void;
1036
+ }
1037
+ /**
1038
+ * Create a health monitor that tracks per-agent metrics.
1039
+ *
1040
+ * @example
1041
+ * ```typescript
1042
+ * const monitor = createHealthMonitor({ windowMs: 30000 });
1043
+ *
1044
+ * monitor.recordSuccess("agent-a", 120);
1045
+ * monitor.recordFailure("agent-a", 5000, new Error("timeout"));
1046
+ *
1047
+ * const score = monitor.getHealthScore("agent-a");
1048
+ * console.log(score); // 0-100
1049
+ * ```
1050
+ */
1051
+ declare function createHealthMonitor(config?: HealthMonitorConfig): HealthMonitor;
1052
+
1001
1053
  /**
1002
1054
  * Agent Reflection / Self-Improvement
1003
1055
  *
@@ -1098,58 +1150,6 @@ declare class ReflectionExhaustedError extends Error {
1098
1150
  */
1099
1151
  declare function withReflection<T = unknown>(runner: AgentRunner, config: ReflectionConfig<T>): AgentRunner;
1100
1152
 
1101
- /**
1102
- * Health Monitor — tracks per-agent health metrics for self-healing networks.
1103
- *
1104
- * Pure computation module with zero Directive dependency.
1105
- * Maintains a rolling window of success/failure events and computes a health
1106
- * score from 0-100 based on configurable weights.
1107
- *
1108
- * @module
1109
- */
1110
-
1111
- /** Circuit state values */
1112
- type HealthCircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
1113
- /** Per-agent health metrics */
1114
- interface AgentHealthMetrics {
1115
- agentId: string;
1116
- circuitState: HealthCircuitState;
1117
- successRate: number;
1118
- avgLatencyMs: number;
1119
- recentFailures: number;
1120
- recentSuccesses: number;
1121
- healthScore: number;
1122
- /** Last N error messages (most recent last) */
1123
- lastErrors: string[];
1124
- }
1125
- /** Health monitor instance */
1126
- interface HealthMonitor {
1127
- recordSuccess(agentId: string, latencyMs: number): void;
1128
- recordFailure(agentId: string, latencyMs: number, error?: Error): void;
1129
- getMetrics(agentId: string): AgentHealthMetrics;
1130
- getAllMetrics(): Record<string, AgentHealthMetrics>;
1131
- /** Returns a 0-100 health score. Returns 50 (neutral) when no data is available for the agent. */
1132
- getHealthScore(agentId: string): number;
1133
- updateCircuitState(agentId: string, state: HealthCircuitState): void;
1134
- /** Reset all metrics. Useful for testing. */
1135
- reset(): void;
1136
- }
1137
- /**
1138
- * Create a health monitor that tracks per-agent metrics.
1139
- *
1140
- * @example
1141
- * ```typescript
1142
- * const monitor = createHealthMonitor({ windowMs: 30000 });
1143
- *
1144
- * monitor.recordSuccess("agent-a", 120);
1145
- * monitor.recordFailure("agent-a", 5000, new Error("timeout"));
1146
- *
1147
- * const score = monitor.getHealthScore("agent-a");
1148
- * console.log(score); // 0-100
1149
- * ```
1150
- */
1151
- declare function createHealthMonitor(config?: HealthMonitorConfig): HealthMonitor;
1152
-
1153
1153
  /** Get the current step/round/iteration count from a pattern checkpoint state */
1154
1154
  declare function getPatternStep(state: PatternCheckpointState): number;
1155
1155
  /** Compute progress from a pattern checkpoint state */
@@ -1256,25 +1256,25 @@ interface AgentRegistration {
1256
1256
  interface AgentRegistry {
1257
1257
  [agentId: string]: AgentRegistration;
1258
1258
  }
1259
- /** Parallel execution pattern - run agents concurrently and merge results */
1259
+ /** Parallel execution pattern - run handlers concurrently and merge results */
1260
1260
  interface ParallelPattern<T = unknown> {
1261
1261
  type: "parallel";
1262
- /** Agent IDs to run in parallel (can repeat for multiple instances) */
1263
- agents: string[];
1264
- /** Function to merge results from all agents */
1262
+ /** Handler IDs (agents or tasks) to run in parallel (can repeat for multiple instances) */
1263
+ handlers: string[];
1264
+ /** Function to merge results from all handlers */
1265
1265
  merge: (results: RunResult<unknown>[]) => T | Promise<T>;
1266
- /** Minimum successful results required. @default agents.length */
1266
+ /** Minimum successful results required. @default handlers.length */
1267
1267
  minSuccess?: number;
1268
1268
  /** Overall timeout (ms) */
1269
1269
  timeout?: number;
1270
1270
  }
1271
- /** Sequential execution pattern - pipeline of agents */
1271
+ /** Sequential execution pattern - pipeline of handlers */
1272
1272
  interface SequentialPattern<T = unknown> {
1273
1273
  type: "sequential";
1274
- /** Agent IDs in execution order */
1275
- agents: string[];
1274
+ /** Handler IDs (agents or tasks) in execution order */
1275
+ handlers: string[];
1276
1276
  /** Transform output to next input. @default JSON.stringify */
1277
- transform?: (output: unknown, agentId: string, index: number) => string;
1277
+ transform?: (output: unknown, handlerId: string, index: number) => string;
1278
1278
  /** Final result extractor */
1279
1279
  extract?: (output: unknown) => T;
1280
1280
  /** Continue on error. @default false */
@@ -1313,8 +1313,8 @@ interface ReflectIterationRecord {
1313
1313
  */
1314
1314
  interface ReflectPattern<T = unknown> {
1315
1315
  type: "reflect";
1316
- /** Producer agent ID */
1317
- agent: string;
1316
+ /** Producer handler ID (agent or task) */
1317
+ handler: string;
1318
1318
  /** Evaluator agent ID (receives output as input) */
1319
1319
  evaluator: string;
1320
1320
  /** Maximum iterations. @default 2 */
@@ -1345,8 +1345,8 @@ interface ReflectPattern<T = unknown> {
1345
1345
  */
1346
1346
  interface RacePattern<T = unknown> {
1347
1347
  type: "race";
1348
- /** Agent IDs to race */
1349
- agents: string[];
1348
+ /** Handler IDs (agents or tasks) to race */
1349
+ handlers: string[];
1350
1350
  /** Extract result from winning RunResult (receives full RunResult for access to tokens/metadata). @default output field */
1351
1351
  extract?: (result: RunResult<unknown>) => T;
1352
1352
  /** Overall timeout (ms) */
@@ -1391,8 +1391,8 @@ interface RaceResult<T = unknown> {
1391
1391
  */
1392
1392
  interface DebatePattern<T = unknown> {
1393
1393
  type: "debate";
1394
- /** Agent IDs that will generate competing proposals */
1395
- agents: string[];
1394
+ /** Handler IDs (agents or tasks) that will generate competing proposals */
1395
+ handlers: string[];
1396
1396
  /** Evaluator agent ID that judges proposals */
1397
1397
  evaluator: string;
1398
1398
  /** Maximum rounds of debate. @default 2 */
@@ -1437,12 +1437,57 @@ interface RunAgentRequirement extends Requirement {
1437
1437
  input: string;
1438
1438
  context?: Record<string, unknown>;
1439
1439
  }
1440
+ /** Read-only context passed to task functions */
1441
+ interface TaskContext {
1442
+ /** The ID of this task */
1443
+ taskId: string;
1444
+ /** Conversation history from orchestrator memory (read-only deep copy) */
1445
+ memory: ReadonlyArray<{
1446
+ role: string;
1447
+ content: string;
1448
+ }>;
1449
+ /** Current scratchpad state (read-only deep copy) */
1450
+ scratchpad: Readonly<Record<string, unknown>>;
1451
+ /** Read the state of any registered agent or task (status, lastOutput, lastError, totalTokens) */
1452
+ readAgentState: (nodeId: string) => Readonly<{
1453
+ status: string;
1454
+ lastOutput?: string;
1455
+ lastError?: string;
1456
+ totalTokens: number;
1457
+ }> | undefined;
1458
+ /** Report intermediate progress (0-100) for DevTools timeline */
1459
+ reportProgress: (percent: number, message?: string) => void;
1460
+ }
1461
+ /** Configuration for a registered task (imperative code) */
1462
+ interface TaskRegistration {
1463
+ /** The function to execute. Receives input, abort signal, and context. */
1464
+ run: (input: string, signal: AbortSignal, context: TaskContext) => unknown | Promise<unknown>;
1465
+ /** Display label for DevTools graph. Defaults to task ID. */
1466
+ label?: string;
1467
+ /** Description for DevTools tooltip/detail panel. */
1468
+ description?: string;
1469
+ /** Timeout (ms) */
1470
+ timeout?: number;
1471
+ /** Max concurrent executions of this task. @default 1 */
1472
+ maxConcurrent?: number;
1473
+ /** Optional retry configuration for transient failures */
1474
+ retry?: {
1475
+ /** Max number of attempts (including the first try) */
1476
+ attempts: number;
1477
+ /** Backoff strategy between retries. @default 'fixed' */
1478
+ backoff?: "fixed" | "exponential";
1479
+ /** Base delay between retries (ms). @default 1000 */
1480
+ delayMs?: number;
1481
+ };
1482
+ }
1440
1483
  /** Multi-agent orchestrator options */
1441
1484
  interface MultiAgentOrchestratorOptions {
1442
1485
  /** Base run function */
1443
1486
  runner: AgentRunner;
1444
1487
  /** Registered agents */
1445
1488
  agents: AgentRegistry;
1489
+ /** Imperative code tasks, referenced by ID in patterns (same namespace as agents) */
1490
+ tasks?: Record<string, TaskRegistration>;
1446
1491
  /** Execution patterns */
1447
1492
  patterns?: Record<string, ExecutionPattern>;
1448
1493
  /** Handoff callbacks */
@@ -1524,6 +1569,8 @@ interface MultiAgentRunCallOptions extends RunOptions {
1524
1569
  outputSchema?: SafeParseable<unknown> | null;
1525
1570
  /** Override max schema retries for this call. */
1526
1571
  maxSchemaRetries?: number;
1572
+ /** Pattern ID that initiated this run (for lifecycle hooks). Set internally by pattern executors. */
1573
+ patternId?: string;
1527
1574
  }
1528
1575
  /** Multi-agent orchestrator instance */
1529
1576
  interface MultiAgentOrchestrator {
@@ -1579,6 +1626,35 @@ interface MultiAgentOrchestrator {
1579
1626
  unregisterAgent(agentId: string): void;
1580
1627
  /** Get registered agent IDs */
1581
1628
  getAgentIds(): string[];
1629
+ /** Register a new task dynamically */
1630
+ registerTask(taskId: string, registration: TaskRegistration): void;
1631
+ /** Unregister a task */
1632
+ unregisterTask(taskId: string): void;
1633
+ /** Get registered task IDs */
1634
+ getTaskIds(): string[];
1635
+ /** Get task registry info (labels + descriptions) */
1636
+ getTaskRegistry(): Record<string, {
1637
+ label?: string;
1638
+ description?: string;
1639
+ }>;
1640
+ /** Get task state */
1641
+ getTaskState(taskId: string): {
1642
+ status: string;
1643
+ lastOutput?: unknown;
1644
+ lastError?: string;
1645
+ startTime?: number;
1646
+ durationMs?: number;
1647
+ } | undefined;
1648
+ /** Get all task states */
1649
+ getAllTaskStates(): Record<string, {
1650
+ status: string;
1651
+ lastOutput?: unknown;
1652
+ lastError?: string;
1653
+ startTime?: number;
1654
+ durationMs?: number;
1655
+ }>;
1656
+ /** Get all handler IDs (agents + tasks combined) */
1657
+ getNodeIds(): string[];
1582
1658
  /** Get agent state */
1583
1659
  getAgentState(agentId: string): MultiAgentState["__agents"][string] | undefined;
1584
1660
  /** Get all agent states */
@@ -1684,7 +1760,6 @@ interface MultiAgentOrchestrator {
1684
1760
  }): Promise<T>;
1685
1761
  /**
1686
1762
  * Get reflection iteration history from last runReflectPattern call.
1687
- * @deprecated Use the `history` field on the return value from `runReflect()` instead.
1688
1763
  */
1689
1764
  getLastReflectionHistory(): ReflectIterationRecord[] | null;
1690
1765
  /** Cross-agent derived values (frozen snapshot). Empty when derive not configured. */
@@ -1740,9 +1815,8 @@ declare function createMultiAgentOrchestrator(options: MultiAgentOrchestratorOpt
1740
1815
  /**
1741
1816
  * Create a parallel pattern configuration.
1742
1817
  *
1743
- * @param agents - Agent IDs to run concurrently
1744
- * @param merge - Combine all agent results into a single output
1745
- * @param config.merge - Receives all successful RunResults (array may be shorter than agents.length when minSuccess is set). Returns the merged result.
1818
+ * @param handlers - Handler IDs (agents or tasks) to run concurrently
1819
+ * @param merge - Combine all handler results into a single output. Receives all successful RunResults (array may be shorter than handlers.length when minSuccess is set).
1746
1820
  * @param options - Optional `minSuccess` and `timeout` overrides
1747
1821
  *
1748
1822
  * @example
@@ -1753,14 +1827,14 @@ declare function createMultiAgentOrchestrator(options: MultiAgentOrchestratorOpt
1753
1827
  * );
1754
1828
  * ```
1755
1829
  */
1756
- declare function parallel<T>(agents: string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
1830
+ declare function parallel<T>(handlers: string[], merge: (results: RunResult<unknown>[]) => T | Promise<T>, options?: {
1757
1831
  minSuccess?: number;
1758
1832
  timeout?: number;
1759
1833
  }): ParallelPattern<T>;
1760
1834
  /**
1761
1835
  * Create a sequential pattern configuration.
1762
1836
  *
1763
- * @param agents - Agent IDs to run in order (output of each feeds into the next)
1837
+ * @param handlers - Handler IDs (agents or tasks) to run in order (output of each feeds into the next)
1764
1838
  * @param options - Optional `transform`, `extract`, `continueOnError`
1765
1839
  *
1766
1840
  * @example
@@ -1771,8 +1845,8 @@ declare function parallel<T>(agents: string[], merge: (results: RunResult<unknow
1771
1845
  * );
1772
1846
  * ```
1773
1847
  */
1774
- declare function sequential<T>(agents: string[], options?: {
1775
- transform?: (output: unknown, agentId: string, index: number) => string;
1848
+ declare function sequential<T>(handlers: string[], options?: {
1849
+ transform?: (output: unknown, handlerId: string, index: number) => string;
1776
1850
  extract?: (output: unknown) => T;
1777
1851
  continueOnError?: boolean;
1778
1852
  }): SequentialPattern<T>;
@@ -1799,7 +1873,7 @@ declare function supervisor<T>(supervisorAgent: string, workers: string[], optio
1799
1873
  /**
1800
1874
  * Create a DAG execution pattern.
1801
1875
  *
1802
- * @param nodes - Node definitions keyed by ID, each with `agent` and optional `deps`
1876
+ * @param nodes - Node definitions keyed by ID, each with `handler` and optional `deps`
1803
1877
  * @param merge - Combine DAG outputs into a single result (defaults to `context.outputs`)
1804
1878
  * @param options - Optional `timeout`, `maxConcurrent`, `onNodeError`
1805
1879
  *
@@ -1807,9 +1881,9 @@ declare function supervisor<T>(supervisorAgent: string, workers: string[], optio
1807
1881
  * ```typescript
1808
1882
  * const researchPipeline = dag(
1809
1883
  * {
1810
- * fetch: { agent: 'fetcher' },
1811
- * analyze: { agent: 'analyzer', deps: ['fetch'] },
1812
- * summarize: { agent: 'summarizer', deps: ['analyze'] },
1884
+ * fetch: { handler: 'fetcher' },
1885
+ * analyze: { handler: 'analyzer', deps: ['fetch'] },
1886
+ * summarize: { handler: 'summarizer', deps: ['analyze'] },
1813
1887
  * },
1814
1888
  * (context) => context.outputs.summarize,
1815
1889
  * );
@@ -1831,8 +1905,8 @@ declare function dag<T = Record<string, unknown>>(nodes: Record<string, DagNode>
1831
1905
  /**
1832
1906
  * Create a reflect pattern configuration.
1833
1907
  *
1834
- * @param agent - Producer agent ID that generates output
1835
- * @param evaluator - Evaluator agent ID that judges quality
1908
+ * @param handler - Producer handler ID (agent or task) that generates output
1909
+ * @param evaluator - Evaluator handler ID that judges quality
1836
1910
  * @param options - Optional iteration, parsing, signal, and threshold config
1837
1911
  *
1838
1912
  * @example
@@ -1840,7 +1914,7 @@ declare function dag<T = Record<string, unknown>>(nodes: Record<string, DagNode>
1840
1914
  * const reviewPattern = reflect('writer', 'reviewer', { maxIterations: 2 });
1841
1915
  * ```
1842
1916
  */
1843
- declare function reflect<T>(agent: string, evaluator: string, options?: {
1917
+ declare function reflect<T>(handler: string, evaluator: string, options?: {
1844
1918
  maxIterations?: number;
1845
1919
  parseEvaluation?: (output: unknown) => ReflectionEvaluation;
1846
1920
  buildRetryInput?: (input: string, feedback: string, iteration: number) => string;
@@ -1854,7 +1928,7 @@ declare function reflect<T>(agent: string, evaluator: string, options?: {
1854
1928
  /**
1855
1929
  * Create a race pattern configuration.
1856
1930
  *
1857
- * @param agents - Agent IDs to race concurrently
1931
+ * @param handlers - Handler IDs (agents or tasks) to race concurrently
1858
1932
  * @param options - Optional `extract`, `timeout`, `minSuccess`, `signal`
1859
1933
  *
1860
1934
  * @example
@@ -1862,7 +1936,7 @@ declare function reflect<T>(agent: string, evaluator: string, options?: {
1862
1936
  * const fastest = race(['fast-model', 'smart-model'], { timeout: 5000 });
1863
1937
  * ```
1864
1938
  */
1865
- declare function race<T>(agents: string[], options?: {
1939
+ declare function race<T>(handlers: string[], options?: {
1866
1940
  extract?: (result: RunResult<unknown>) => T;
1867
1941
  timeout?: number;
1868
1942
  minSuccess?: number;
@@ -1880,13 +1954,13 @@ declare function race<T>(agents: string[], options?: {
1880
1954
  * const pipeline = goal(
1881
1955
  * {
1882
1956
  * researcher: {
1883
- * agent: "researcher",
1957
+ * handler: "researcher",
1884
1958
  * produces: ["research.findings"],
1885
1959
  * requires: ["research.topic"],
1886
1960
  * extractOutput: (r) => ({ "research.findings": r.output }),
1887
1961
  * },
1888
1962
  * writer: {
1889
- * agent: "writer",
1963
+ * handler: "writer",
1890
1964
  * produces: ["article.draft"],
1891
1965
  * requires: ["research.findings"],
1892
1966
  * extractOutput: (r) => ({ "article.draft": r.output }),
@@ -2066,7 +2140,6 @@ declare function spawnOnCondition(config: {
2066
2140
  priority?: number;
2067
2141
  /** Additional context passed to the agent */
2068
2142
  context?: Record<string, unknown>;
2069
- /** @deprecated Use top-level `priority` and `context` instead */
2070
2143
  options?: SpawnOnConditionOptions;
2071
2144
  }): OrchestratorConstraint<Record<string, unknown>>;
2072
2145
  /** Configuration for the debate() factory and runDebate() imperative API. @see DebatePattern */
@@ -2079,7 +2152,7 @@ type DebateConfig<T = unknown> = Omit<DebatePattern<T>, "type">;
2079
2152
  * 2. Evaluator receives all proposals and picks a winner
2080
2153
  * 3. Optionally repeat with evaluator feedback for refinement
2081
2154
  *
2082
- * @param config - Debate configuration with `agents`, `evaluator`, and optional settings
2155
+ * @param config - Debate configuration with `handlers`, `evaluator`, and optional settings
2083
2156
  * @see runDebate for the imperative API
2084
2157
  *
2085
2158
  * @example
@@ -2092,7 +2165,7 @@ type DebateConfig<T = unknown> = Omit<DebatePattern<T>, "type">;
2092
2165
  * },
2093
2166
  * patterns: {
2094
2167
  * debate: debate({
2095
- * agents: ['optimist', 'pessimist'],
2168
+ * handlers: ['optimist', 'pessimist'],
2096
2169
  * evaluator: 'judge',
2097
2170
  * maxRounds: 2,
2098
2171
  * }),
@@ -2185,7 +2258,8 @@ interface SpawnPoolConfig {
2185
2258
  declare function spawnPool(when: (facts: Record<string, unknown>) => boolean, config: SpawnPoolConfig): OrchestratorConstraint<Record<string, unknown>>;
2186
2259
  /** Serialized DAG node (functions stripped) */
2187
2260
  interface SerializedDagNode {
2188
- agent: string;
2261
+ handler: string;
2262
+ agent?: string;
2189
2263
  deps?: string[];
2190
2264
  timeout?: number;
2191
2265
  priority?: number;
@@ -2193,12 +2267,12 @@ interface SerializedDagNode {
2193
2267
  /** JSON-safe representation of any execution pattern (all functions stripped) */
2194
2268
  type SerializedPattern = {
2195
2269
  type: "parallel";
2196
- agents: string[];
2270
+ handlers: string[];
2197
2271
  minSuccess?: number;
2198
2272
  timeout?: number;
2199
2273
  } | {
2200
2274
  type: "sequential";
2201
- agents: string[];
2275
+ handlers: string[];
2202
2276
  continueOnError?: boolean;
2203
2277
  } | {
2204
2278
  type: "supervisor";
@@ -2213,7 +2287,7 @@ type SerializedPattern = {
2213
2287
  onNodeError?: "fail" | "skip-downstream" | "continue";
2214
2288
  } | {
2215
2289
  type: "reflect";
2216
- agent: string;
2290
+ handler: string;
2217
2291
  evaluator: string;
2218
2292
  maxIterations?: number;
2219
2293
  onExhausted?: "accept-last" | "accept-best" | "throw";
@@ -2221,12 +2295,12 @@ type SerializedPattern = {
2221
2295
  threshold?: number;
2222
2296
  } | {
2223
2297
  type: "race";
2224
- agents: string[];
2298
+ handlers: string[];
2225
2299
  timeout?: number;
2226
2300
  minSuccess?: number;
2227
2301
  } | {
2228
2302
  type: "debate";
2229
- agents: string[];
2303
+ handlers: string[];
2230
2304
  evaluator: string;
2231
2305
  maxRounds?: number;
2232
2306
  timeout?: number;
@@ -2238,7 +2312,8 @@ type SerializedPattern = {
2238
2312
  };
2239
2313
  /** Serialized goal node (functions stripped) */
2240
2314
  interface SerializedGoalNode {
2241
- agent: string;
2315
+ handler: string;
2316
+ agent?: string;
2242
2317
  produces: string[];
2243
2318
  requires?: string[];
2244
2319
  allowRerun?: boolean;
@@ -2259,9 +2334,9 @@ interface SerializedGoalNode {
2259
2334
  *
2260
2335
  * @example
2261
2336
  * ```typescript
2262
- * const p = parallel({ agents: ["a", "b"], merge: (r) => r });
2337
+ * const p = parallel({ handlers: ["a", "b"], merge: (r) => r });
2263
2338
  * const json = patternToJSON(p);
2264
- * // { type: "parallel", agents: ["a", "b"] }
2339
+ * // { type: "parallel", handlers: ["a", "b"] }
2265
2340
  * localStorage.setItem("plan", JSON.stringify(json));
2266
2341
  * ```
2267
2342
  */
@@ -2281,10 +2356,10 @@ declare function patternToJSON(pattern: ExecutionPattern<unknown>): SerializedPa
2281
2356
  * });
2282
2357
  * // Use the imperative API — runPattern takes a registered pattern ID, not an object
2283
2358
  * if (pattern.type === "parallel") {
2284
- * const result = await orchestrator.runParallel(pattern.agents, input, pattern.merge);
2359
+ * const result = await orchestrator.runParallel(pattern.handlers, input, pattern.merge);
2285
2360
  * }
2286
2361
  * ```
2287
2362
  */
2288
2363
  declare function patternFromJSON<T = unknown>(json: SerializedPattern, overrides?: Partial<ExecutionPattern<T>>): ExecutionPattern<T>;
2289
2364
 
2290
- export { type SafeParseResult as $, type AgentHealthMetrics as A, type BackpressureStrategy as B, type MultiplexedStreamChunk as C, type DebugTimeline as D, type ExecutionPattern as E, type MultiplexedStreamResult as F, type GuardrailTriggeredChunk as G, type HealthMonitor as H, type OrchestratorStreamChunk as I, type OrchestratorStreamResult as J, type ProgressChunk as K, type RaceResult as L, type MemoryManageResult as M, type RaceSuccessEntry as N, type OrchestratorOptions as O, type ParallelPattern as P, type ReflectIterationRecord as Q, type RacePattern as R, type SerializedPattern as S, type ReflectPattern as T, type ReflectionConfig as U, type ReflectionContext as V, type ReflectionEvaluation as W, type ReflectionEvaluator as X, ReflectionExhaustedError as Y, type RunAgentRequirement as Z, type RunCallOptions as _, type AgentMemory as a, race as a$, type SafeParseable as a0, Semaphore as a1, type SequentialPattern as a2, type SerializedDagNode as a3, type SerializedGoalNode as a4, type SpawnOnConditionOptions as a5, type SpawnPoolConfig as a6, type StreamChunk as a7, type StreamRunOptions as a8, type StreamRunner as a9, createLLMSummarizer as aA, createLengthStreamingGuardrail as aB, createMultiAgentOrchestrator as aC, createPatternStreamingGuardrail as aD, createSlidingWindowStrategy as aE, createStreamingRunner as aF, createTokenBasedStrategy as aG, createToxicityStreamingGuardrail as aH, createTruncationSummarizer as aI, dag as aJ, debate as aK, derivedConstraint as aL, diffCheckpoints as aM, extractJsonFromOutput as aN, filterStream as aO, findAgentsByCapability as aP, forkFromCheckpoint as aQ, getCheckpointProgress as aR, getPatternStep as aS, goal as aT, highestImpactStrategy as aU, mapStream as aV, mergeTaggedStreams as aW, parallel as aX, patternFromJSON as aY, patternToJSON as aZ, pickBestResult as a_, type StreamingGuardrail as aa, type StreamingGuardrailResult as ab, type StreamingRunResult as ac, type StructuredOutputConfig as ad, StructuredOutputError as ae, type SupervisorPattern as af, type TokenChunk as ag, type ToolEndChunk as ah, type ToolStartChunk as ai, adaptOutputGuardrail as aj, aggregateTokens as ak, allReadyStrategy as al, capabilityRoute as am, collectOutputs as an, collectTokens as ao, combineStreamingGuardrails as ap, composePatterns as aq, concatResults as ar, costEfficientStrategy as as, createAgentMemory as at, createAgentOrchestrator as au, createDebugTimeline as av, createDebugTimelinePlugin as aw, createHealthMonitor as ax, createHybridStrategy as ay, createKeyPointsSummarizer as az, type AgentMemoryConfig as b, reflect as b0, runAgentRequirement as b1, runDebate as b2, selectAgent as b3, sequential as b4, spawnOnCondition as b5, spawnPool as b6, supervisor as b7, tapStream as b8, withReflection as b9, withStructuredOutput as ba, type AgentOrchestrator as c, type AgentRegistration as d, type AgentRegistry as e, type DebateConfig as f, type DebatePattern as g, type DebateResult as h, type DebugTimelineListener as i, type DebugTimelineOptions as j, type DoneChunk as k, type ErrorChunk as l, type HandoffRequest as m, type HandoffResult as n, type HealthCircuitState as o, type MemoryState as p, type MemoryStrategy as q, type MemoryStrategyConfig as r, type MemoryStrategyResult as s, type MergedTaggedStreamResult as t, type MessageChunk as u, type MessageSummarizer as v, type MultiAgentOrchestrator as w, type MultiAgentOrchestratorOptions as x, type MultiAgentRunCallOptions as y, type MultiAgentState as z };
2365
+ export { type SafeParseResult as $, type AgentHealthMetrics as A, type BackpressureStrategy as B, type MultiplexedStreamChunk as C, type DebugTimeline as D, type ExecutionPattern as E, type MultiplexedStreamResult as F, type GuardrailTriggeredChunk as G, type HealthMonitor as H, type OrchestratorStreamChunk as I, type OrchestratorStreamResult as J, type ProgressChunk as K, type RaceResult as L, type MemoryManageResult as M, type RaceSuccessEntry as N, type OrchestratorOptions as O, type ParallelPattern as P, type ReflectIterationRecord as Q, type RacePattern as R, type SerializedPattern as S, type ReflectPattern as T, type ReflectionConfig as U, type ReflectionContext as V, type ReflectionEvaluation as W, type ReflectionEvaluator as X, ReflectionExhaustedError as Y, type RunAgentRequirement as Z, type RunCallOptions as _, type AgentMemory as a, patternToJSON as a$, type SafeParseable as a0, Semaphore as a1, type SequentialPattern as a2, type SerializedDagNode as a3, type SerializedGoalNode as a4, type SpawnOnConditionOptions as a5, type SpawnPoolConfig as a6, type StreamChunk as a7, type StreamRunOptions as a8, type StreamRunner as a9, createHybridStrategy as aA, createKeyPointsSummarizer as aB, createLLMSummarizer as aC, createLengthStreamingGuardrail as aD, createMultiAgentOrchestrator as aE, createPatternStreamingGuardrail as aF, createSlidingWindowStrategy as aG, createStreamingRunner as aH, createTokenBasedStrategy as aI, createToxicityStreamingGuardrail as aJ, createTruncationSummarizer as aK, dag as aL, debate as aM, derivedConstraint as aN, diffCheckpoints as aO, extractJsonFromOutput as aP, filterStream as aQ, findAgentsByCapability as aR, forkFromCheckpoint as aS, getCheckpointProgress as aT, getPatternStep as aU, goal as aV, highestImpactStrategy as aW, mapStream as aX, mergeTaggedStreams as aY, parallel as aZ, patternFromJSON as a_, type StreamingGuardrail as aa, type StreamingGuardrailResult as ab, type StreamingRunResult as ac, type StructuredOutputConfig as ad, StructuredOutputError as ae, type SupervisorPattern as af, type TaskContext as ag, type TaskRegistration as ah, type TokenChunk as ai, type ToolEndChunk as aj, type ToolStartChunk as ak, adaptOutputGuardrail as al, aggregateTokens as am, allReadyStrategy as an, capabilityRoute as ao, collectOutputs as ap, collectTokens as aq, combineStreamingGuardrails as ar, composePatterns as as, concatResults as at, costEfficientStrategy as au, createAgentMemory as av, createAgentOrchestrator as aw, createDebugTimeline as ax, createDebugTimelinePlugin as ay, createHealthMonitor as az, type AgentMemoryConfig as b, pickBestResult as b0, race as b1, reflect as b2, runAgentRequirement as b3, runDebate as b4, selectAgent as b5, sequential as b6, spawnOnCondition as b7, spawnPool as b8, supervisor as b9, tapStream as ba, withReflection as bb, withStructuredOutput as bc, type AgentOrchestrator as c, type AgentRegistration as d, type AgentRegistry as e, type DebateConfig as f, type DebatePattern as g, type DebateResult as h, type DebugTimelineListener as i, type DebugTimelineOptions as j, type DoneChunk as k, type ErrorChunk as l, type HandoffRequest as m, type HandoffResult as n, type HealthCircuitState as o, type MemoryState as p, type MemoryStrategy as q, type MemoryStrategyConfig as r, type MemoryStrategyResult as s, type MergedTaggedStreamResult as t, type MessageChunk as u, type MessageSummarizer as v, type MultiAgentOrchestrator as w, type MultiAgentOrchestratorOptions as x, type MultiAgentRunCallOptions as y, type MultiAgentState as z };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent-utils.ts","../src/adapters/ollama.ts"],"names":["ALLOWED_PROTOCOLS","validateBaseURL","baseURL","url","err","createRunner","options","fetchFn","buildRequest","parseResponse","parseOutput","hooks","parse","text","agent","input","runOptions","startTime","messages","init","fetchInit","response","errBody","parsed","tokenUsage","assistantMessage","allMessages","durationMs","createOllamaRunner","model","timeoutMs","_input","m","res","data","inputTokens","outputTokens"],"mappings":"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","file":"ollama.cjs","sourcesContent":["/**\n * Agent utilities — createRunner, estimateCost, state queries, URL validation.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n AgentRunner,\n RunResult,\n RunOptions,\n Message,\n TokenUsage,\n AgentState,\n ApprovalState,\n} from \"./types.js\";\n\n// ============================================================================\n// State Query Helpers\n// ============================================================================\n\n/** Check if agent is currently running. */\nexport function isAgentRunning(state: AgentState): boolean {\n return state.status === \"running\";\n}\n\n/** Check if there are pending approvals. */\nexport function hasPendingApprovals(state: ApprovalState): boolean {\n return state.pending.length > 0;\n}\n\n// ============================================================================\n// Cost Estimation\n// ============================================================================\n\n/**\n * Get total cost estimate based on token usage.\n *\n * @param tokenUsage - Total token count\n * @param ratePerMillionTokens - Cost per million tokens (required, no default to avoid stale pricing)\n * @returns Estimated cost in dollars\n */\nexport function estimateCost(\n tokenUsage: number,\n ratePerMillionTokens: number\n): number {\n return (tokenUsage / 1_000_000) * ratePerMillionTokens;\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\"]);\n\n/**\n * Validate that a baseURL uses http or https.\n * Throws immediately at adapter creation time (not at call time) to catch config errors early.\n */\nexport function validateBaseURL(baseURL: string): void {\n try {\n const url = new URL(baseURL);\n if (!ALLOWED_PROTOCOLS.has(url.protocol)) {\n throw new Error(\n `[Directive] Invalid baseURL protocol \"${url.protocol}\" – only http: and https: are allowed`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith(\"[Directive]\")) {\n throw err;\n }\n\n throw new Error(\n `[Directive] Invalid baseURL \"${baseURL}\" – must be a valid URL (e.g. \"https://api.openai.com/v1\")`,\n );\n }\n}\n\n// ============================================================================\n// createRunner Helper\n// ============================================================================\n\n/** Parsed response from an LLM provider */\nexport interface ParsedResponse {\n text: string;\n totalTokens: number;\n /** Input token count, when available from the provider */\n inputTokens?: number;\n /** Output token count, when available from the provider */\n outputTokens?: number;\n}\n\n/** Options for creating an AgentRunner from buildRequest/parseResponse */\nexport interface CreateRunnerOptions {\n fetch?: typeof globalThis.fetch;\n buildRequest: (\n agent: AgentLike,\n input: string,\n messages: Message[]\n ) => { url: string; init: RequestInit };\n parseResponse: (\n response: Response,\n messages: Message[]\n ) => Promise<ParsedResponse>;\n parseOutput?: <T>(text: string) => T;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n}\n\n/**\n * Create an AgentRunner from buildRequest/parseResponse helpers.\n * Reduces ~50 lines of fetch boilerplate to ~20 lines of configuration.\n *\n * Supports lifecycle hooks for observability:\n * - `onBeforeCall` fires before each API request\n * - `onAfterCall` fires after a successful response (includes token breakdown)\n * - `onError` fires when the request fails\n *\n * @example\n * ```typescript\n * const runClaude = createRunner({\n * buildRequest: (agent, input) => ({\n * url: \"/api/claude\",\n * init: {\n * method: \"POST\",\n * headers: { \"Content-Type\": \"application/json\" },\n * body: JSON.stringify({\n * model: agent.model ?? \"claude-haiku-4-5-20251001\",\n * system: agent.instructions ?? \"\",\n * messages: [{ role: \"user\", content: input }],\n * }),\n * },\n * }),\n * parseResponse: async (res) => {\n * const data = await res.json();\n * const inputTokens = data.usage?.input_tokens ?? 0;\n * const outputTokens = data.usage?.output_tokens ?? 0;\n * return {\n * text: data.content?.[0]?.text ?? \"\",\n * totalTokens: inputTokens + outputTokens,\n * inputTokens,\n * outputTokens,\n * };\n * },\n * hooks: {\n * onAfterCall: ({ durationMs, tokenUsage }) => {\n * console.log(`LLM call: ${durationMs}ms, ${tokenUsage.inputTokens}in/${tokenUsage.outputTokens}out`);\n * },\n * },\n * });\n * ```\n */\nexport function createRunner(options: CreateRunnerOptions): AgentRunner {\n const {\n fetch: fetchFn = globalThis.fetch,\n buildRequest,\n parseResponse,\n parseOutput,\n hooks,\n } = options;\n\n const defaultParseOutput = <T>(text: string): T => {\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n };\n\n const parse = parseOutput ?? defaultParseOutput;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions\n ): Promise<RunResult<T>> => {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n const messages: Message[] = [{ role: \"user\", content: input }];\n\n try {\n const { url, init } = buildRequest(agent, input, messages);\n\n const fetchInit: RequestInit = runOptions?.signal\n ? { ...init, signal: runOptions.signal }\n : init;\n\n const response = await fetchFn(url, fetchInit);\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] AgentRunner request failed: ${response.status} ${response.statusText}${errBody ? ` – ${errBody.slice(0, 300)}` : \"\"}`,\n );\n }\n\n const parsed = await parseResponse(response, messages);\n const tokenUsage: TokenUsage = {\n inputTokens: parsed.inputTokens ?? 0,\n outputTokens: parsed.outputTokens ?? 0,\n };\n\n const assistantMessage: Message = { role: \"assistant\", content: parsed.text };\n const allMessages: Message[] = [...messages, assistantMessage];\n\n runOptions?.onMessage?.(assistantMessage);\n\n const durationMs = Date.now() - startTime;\n hooks?.onAfterCall?.({\n agent,\n input,\n output: parsed.text,\n totalTokens: parsed.totalTokens,\n tokenUsage,\n durationMs,\n timestamp: Date.now(),\n });\n\n return {\n output: parse<T>(parsed.text),\n messages: allMessages,\n toolCalls: [],\n totalTokens: parsed.totalTokens,\n tokenUsage,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs,\n timestamp: Date.now(),\n });\n }\n\n throw err;\n }\n };\n}\n","/**\n * @directive-run/ai/ollama\n *\n * Ollama adapter for Directive AI. Provides runners for local\n * Ollama inference. No API key required.\n *\n * Requires Ollama to be running locally. Start it with: `ollama serve`\n *\n * @example\n * ```typescript\n * import { createOllamaRunner } from '@directive-run/ai/ollama';\n *\n * const runner = createOllamaRunner({ model: 'llama3' });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { AdapterHooks, AgentRunner } from \"../types.js\";\n\n// ============================================================================\n// Ollama Runner\n// ============================================================================\n\n/** Options for createOllamaRunner */\nexport interface OllamaRunnerOptions {\n\tmodel?: string;\n\tbaseURL?: string;\n\tfetch?: typeof globalThis.fetch;\n\t/** @default undefined */\n\ttimeoutMs?: number;\n\t/** Lifecycle hooks for tracing, logging, and metrics */\n\thooks?: AdapterHooks;\n}\n\n/**\n * Create an AgentRunner for local Ollama inference.\n *\n * Ollama runs locally – no API key or cloud service needed. Default model\n * is `llama3`, default base URL is `http://localhost:11434`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking\n * (useful for monitoring local resource usage).\n *\n * @example\n * ```typescript\n * const runner = createOllamaRunner({ model: \"llama3\" });\n * const orchestrator = createAgentOrchestrator({ runner });\n * const result = await orchestrator.run(agent, input);\n * ```\n */\nexport function createOllamaRunner(\n\toptions: OllamaRunnerOptions = {},\n): AgentRunner {\n\tconst {\n\t\tmodel = \"llama3\",\n\t\tbaseURL = \"http://localhost:11434\",\n\t\tfetch: fetchFn = globalThis.fetch,\n\t\ttimeoutMs,\n\t\thooks,\n\t} = options;\n\n\tvalidateBaseURL(baseURL);\n\n\treturn createRunner({\n\t\tfetch: fetchFn,\n\t\thooks,\n\t\tbuildRequest: (agent, _input, messages) => ({\n\t\t\turl: `${baseURL}/api/chat`,\n\t\t\tinit: {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tmodel: agent.model ?? model,\n\t\t\t\t\tmessages: [\n\t\t\t\t\t\t...(agent.instructions\n\t\t\t\t\t\t\t? [{ role: \"system\", content: agent.instructions }]\n\t\t\t\t\t\t\t: []),\n\t\t\t\t\t\t...messages.map((m) => ({ role: m.role, content: m.content })),\n\t\t\t\t\t],\n\t\t\t\t\tstream: false,\n\t\t\t\t}),\n\t\t\t\t...(timeoutMs != null ? { signal: AbortSignal.timeout(timeoutMs) } : {}),\n\t\t\t},\n\t\t}),\n\t\tparseResponse: async (res) => {\n\t\t\tlet data: Record<string, unknown>;\n\t\t\ttry {\n\t\t\t\tdata = await res.json();\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`[Directive] Ollama returned non-JSON response. Is Ollama running at ${baseURL}? Start it with: ollama serve`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst text = (data.message as Record<string, unknown>)?.content as string ?? \"\";\n\t\t\tconst inputTokens = (data.prompt_eval_count as number) ?? 0;\n\t\t\tconst outputTokens = (data.eval_count as number) ?? 0;\n\n\t\t\treturn {\n\t\t\t\ttext,\n\t\t\t\ttotalTokens: inputTokens + outputTokens,\n\t\t\t\tinputTokens,\n\t\t\t\toutputTokens,\n\t\t\t};\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"sources":["../src/agent-utils.ts","../src/adapters/ollama.ts"],"names":["ALLOWED_PROTOCOLS","validateBaseURL","baseURL","url","err","createRunner","options","fetchFn","buildRequest","parseResponse","parseOutput","hooks","parse","text","agent","input","runOptions","startTime","messages","init","fetchInit","response","errBody","parsed","tokenUsage","assistantMessage","allMessages","durationMs","createOllamaRunner","model","timeoutMs","_input","m","res","data","inputTokens","outputTokens"],"mappings":"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","file":"ollama.cjs","sourcesContent":["/**\n * Agent utilities — createRunner, estimateCost, state queries, URL validation.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n AgentRunner,\n AgentState,\n ApprovalState,\n Message,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// State Query Helpers\n// ============================================================================\n\n/** Check if agent is currently running. */\nexport function isAgentRunning(state: AgentState): boolean {\n return state.status === \"running\";\n}\n\n/** Check if there are pending approvals. */\nexport function hasPendingApprovals(state: ApprovalState): boolean {\n return state.pending.length > 0;\n}\n\n// ============================================================================\n// Cost Estimation\n// ============================================================================\n\n/**\n * Get total cost estimate based on token usage.\n *\n * @param tokenUsage - Total token count\n * @param ratePerMillionTokens - Cost per million tokens (required, no default to avoid stale pricing)\n * @returns Estimated cost in dollars\n */\nexport function estimateCost(\n tokenUsage: number,\n ratePerMillionTokens: number,\n): number {\n return (tokenUsage / 1_000_000) * ratePerMillionTokens;\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\"]);\n\n/**\n * Validate that a baseURL uses http or https.\n * Throws immediately at adapter creation time (not at call time) to catch config errors early.\n */\nexport function validateBaseURL(baseURL: string): void {\n try {\n const url = new URL(baseURL);\n if (!ALLOWED_PROTOCOLS.has(url.protocol)) {\n throw new Error(\n `[Directive] Invalid baseURL protocol \"${url.protocol}\" – only http: and https: are allowed`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith(\"[Directive]\")) {\n throw err;\n }\n\n throw new Error(\n `[Directive] Invalid baseURL \"${baseURL}\" – must be a valid URL (e.g. \"https://api.openai.com/v1\")`,\n );\n }\n}\n\n// ============================================================================\n// createRunner Helper\n// ============================================================================\n\n/** Parsed response from an LLM provider */\nexport interface ParsedResponse {\n text: string;\n totalTokens: number;\n /** Input token count, when available from the provider */\n inputTokens?: number;\n /** Output token count, when available from the provider */\n outputTokens?: number;\n}\n\n/** Options for creating an AgentRunner from buildRequest/parseResponse */\nexport interface CreateRunnerOptions {\n fetch?: typeof globalThis.fetch;\n buildRequest: (\n agent: AgentLike,\n input: string,\n messages: Message[],\n ) => { url: string; init: RequestInit };\n parseResponse: (\n response: Response,\n messages: Message[],\n ) => Promise<ParsedResponse>;\n parseOutput?: <T>(text: string) => T;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n}\n\n/**\n * Create an AgentRunner from buildRequest/parseResponse helpers.\n * Reduces ~50 lines of fetch boilerplate to ~20 lines of configuration.\n *\n * Supports lifecycle hooks for observability:\n * - `onBeforeCall` fires before each API request\n * - `onAfterCall` fires after a successful response (includes token breakdown)\n * - `onError` fires when the request fails\n *\n * @example\n * ```typescript\n * const runClaude = createRunner({\n * buildRequest: (agent, input) => ({\n * url: \"/api/claude\",\n * init: {\n * method: \"POST\",\n * headers: { \"Content-Type\": \"application/json\" },\n * body: JSON.stringify({\n * model: agent.model ?? \"claude-haiku-4-5-20251001\",\n * system: agent.instructions ?? \"\",\n * messages: [{ role: \"user\", content: input }],\n * }),\n * },\n * }),\n * parseResponse: async (res) => {\n * const data = await res.json();\n * const inputTokens = data.usage?.input_tokens ?? 0;\n * const outputTokens = data.usage?.output_tokens ?? 0;\n * return {\n * text: data.content?.[0]?.text ?? \"\",\n * totalTokens: inputTokens + outputTokens,\n * inputTokens,\n * outputTokens,\n * };\n * },\n * hooks: {\n * onAfterCall: ({ durationMs, tokenUsage }) => {\n * console.log(`LLM call: ${durationMs}ms, ${tokenUsage.inputTokens}in/${tokenUsage.outputTokens}out`);\n * },\n * },\n * });\n * ```\n */\nexport function createRunner(options: CreateRunnerOptions): AgentRunner {\n const {\n fetch: fetchFn = globalThis.fetch,\n buildRequest,\n parseResponse,\n parseOutput,\n hooks,\n } = options;\n\n const defaultParseOutput = <T>(text: string): T => {\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n };\n\n const parse = parseOutput ?? defaultParseOutput;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n const messages: Message[] = [{ role: \"user\", content: input }];\n\n try {\n const { url, init } = buildRequest(agent, input, messages);\n\n const fetchInit: RequestInit = runOptions?.signal\n ? { ...init, signal: runOptions.signal }\n : init;\n\n const response = await fetchFn(url, fetchInit);\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] AgentRunner request failed: ${response.status} ${response.statusText}${errBody ? ` – ${errBody.slice(0, 300)}` : \"\"}`,\n );\n }\n\n const parsed = await parseResponse(response, messages);\n const tokenUsage: TokenUsage = {\n inputTokens: parsed.inputTokens ?? 0,\n outputTokens: parsed.outputTokens ?? 0,\n };\n\n const assistantMessage: Message = {\n role: \"assistant\",\n content: parsed.text,\n };\n const allMessages: Message[] = [...messages, assistantMessage];\n\n runOptions?.onMessage?.(assistantMessage);\n\n const durationMs = Date.now() - startTime;\n hooks?.onAfterCall?.({\n agent,\n input,\n output: parsed.text,\n totalTokens: parsed.totalTokens,\n tokenUsage,\n durationMs,\n timestamp: Date.now(),\n });\n\n return {\n output: parse<T>(parsed.text),\n messages: allMessages,\n toolCalls: [],\n totalTokens: parsed.totalTokens,\n tokenUsage,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs,\n timestamp: Date.now(),\n });\n }\n\n throw err;\n }\n };\n}\n","/**\n * @directive-run/ai/ollama\n *\n * Ollama adapter for Directive AI. Provides runners for local\n * Ollama inference. No API key required.\n *\n * Requires Ollama to be running locally. Start it with: `ollama serve`\n *\n * @example\n * ```typescript\n * import { createOllamaRunner } from '@directive-run/ai/ollama';\n *\n * const runner = createOllamaRunner({ model: 'llama3' });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { AdapterHooks, AgentRunner } from \"../types.js\";\n\n// ============================================================================\n// Ollama Runner\n// ============================================================================\n\n/** Options for createOllamaRunner */\nexport interface OllamaRunnerOptions {\n model?: string;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default undefined */\n timeoutMs?: number;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n}\n\n/**\n * Create an AgentRunner for local Ollama inference.\n *\n * Ollama runs locally – no API key or cloud service needed. Default model\n * is `llama3`, default base URL is `http://localhost:11434`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking\n * (useful for monitoring local resource usage).\n *\n * @example\n * ```typescript\n * const runner = createOllamaRunner({ model: \"llama3\" });\n * const orchestrator = createAgentOrchestrator({ runner });\n * const result = await orchestrator.run(agent, input);\n * ```\n */\nexport function createOllamaRunner(\n options: OllamaRunnerOptions = {},\n): AgentRunner {\n const {\n model = \"llama3\",\n baseURL = \"http://localhost:11434\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n hooks,\n } = options;\n\n validateBaseURL(baseURL);\n\n return createRunner({\n fetch: fetchFn,\n hooks,\n buildRequest: (agent, _input, messages) => ({\n url: `${baseURL}/api/chat`,\n init: {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n model: agent.model ?? model,\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n ...messages.map((m) => ({ role: m.role, content: m.content })),\n ],\n stream: false,\n }),\n ...(timeoutMs != null\n ? { signal: AbortSignal.timeout(timeoutMs) }\n : {}),\n },\n }),\n parseResponse: async (res) => {\n let data: Record<string, unknown>;\n try {\n data = await res.json();\n } catch {\n throw new Error(\n `[Directive] Ollama returned non-JSON response. Is Ollama running at ${baseURL}? Start it with: ollama serve`,\n );\n }\n const text =\n ((data.message as Record<string, unknown>)?.content as string) ?? \"\";\n const inputTokens = (data.prompt_eval_count as number) ?? 0;\n const outputTokens = (data.eval_count as number) ?? 0;\n\n return {\n text,\n totalTokens: inputTokens + outputTokens,\n inputTokens,\n outputTokens,\n };\n },\n });\n}\n"]}
package/dist/ollama.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as AdapterHooks, b as AgentRunner } from './types-Co4BzMiH.cjs';
1
+ import { a as AdapterHooks, b as AgentRunner } from './types-D5veI9su.cjs';
2
2
  import '@directive-run/core';
3
3
 
4
4
  /**
package/dist/ollama.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as AdapterHooks, b as AgentRunner } from './types-Co4BzMiH.js';
1
+ import { a as AdapterHooks, b as AgentRunner } from './types-D5veI9su.js';
2
2
  import '@directive-run/core';
3
3
 
4
4
  /**