@agntk/agent-harness 0.1.6 → 0.1.8

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.
Files changed (113) hide show
  1. package/README.md +25 -0
  2. package/defaults/agents/summarizer.md +4 -0
  3. package/dist/{auto-processor-QIRUOGEI.js → auto-processor-KLEP2NMV.js} +3 -3
  4. package/dist/{chunk-UXCHAS3Z.js → chunk-2GPXPU6U.js} +4 -4
  5. package/dist/{chunk-PMFAYKBD.js → chunk-36W2VC3L.js} +2 -2
  6. package/dist/{chunk-EC42HQQH.js → chunk-44R2VV33.js} +2 -2
  7. package/dist/{chunk-AN6Y4MDD.js → chunk-5QME3GHF.js} +6 -6
  8. package/dist/{chunk-QMOIVORH.js → chunk-6DIHJF2A.js} +3 -3
  9. package/dist/{chunk-SEHAQTBO.js → chunk-CKLJTFMV.js} +6 -6
  10. package/dist/{chunk-5O5OGOOQ.js → chunk-CNOHSYI5.js} +2 -2
  11. package/dist/{chunk-D7AWV24Z.js → chunk-ESBLYOXU.js} +3 -3
  12. package/dist/{chunk-4TQQZILG.js → chunk-EXO47RET.js} +4 -2
  13. package/dist/chunk-EXO47RET.js.map +1 -0
  14. package/dist/{chunk-M6PDMK2O.js → chunk-MASZOYMQ.js} +4 -4
  15. package/dist/{chunk-UMXPOYZR.js → chunk-NGF7UZY5.js} +5 -5
  16. package/dist/{chunk-4P6TRFPZ.js → chunk-O2YV52TH.js} +4 -4
  17. package/dist/{chunk-7GZ4D6V6.js → chunk-P7EFJ7CN.js} +2 -2
  18. package/dist/{chunk-KLYMGWQJ.js → chunk-QILHQNSM.js} +5 -5
  19. package/dist/{chunk-IZ6UZ3ZL.js → chunk-WCYBFALM.js} +10 -3
  20. package/dist/chunk-WCYBFALM.js.map +1 -0
  21. package/dist/{chunk-NVC2WY4K.js → chunk-WHRYPI2T.js} +2 -2
  22. package/dist/{chunk-5CO5JTYT.js → chunk-X47HHTNV.js} +2 -2
  23. package/dist/{chunk-2UVWCTAY.js → chunk-XPEDVA35.js} +2 -2
  24. package/dist/{chunk-M62KLIEK.js → chunk-XTV7HH5M.js} +30 -6
  25. package/dist/chunk-XTV7HH5M.js.map +1 -0
  26. package/dist/cli/index.js +101 -101
  27. package/dist/{config-PYSS3QY6.js → config-KRGEWBPM.js} +3 -3
  28. package/dist/context-loader-GKLLIDVC.js +12 -0
  29. package/dist/{conversation-TBTFIJVU.js → conversation-EU47O5MU.js} +7 -7
  30. package/dist/{delegate-3KJAL4NZ.js → delegate-BPTJVYU3.js} +8 -8
  31. package/dist/{export-GYLWROMB.js → export-OPR3SVVJ.js} +3 -3
  32. package/dist/graph-VW5GH2FZ.js +13 -0
  33. package/dist/{harness-R5FKRICG.js → harness-FZR52COJ.js} +9 -9
  34. package/dist/{indexer-L5UC6J2V.js → indexer-SEALD6HO.js} +4 -4
  35. package/dist/instinct-learner-MNROY6L4.js +19 -0
  36. package/dist/{intake-SVJKFHTL.js → intake-BU2WHPWF.js} +5 -5
  37. package/dist/{intelligence-XPV3MC5U.js → intelligence-TUNH5ZMA.js} +11 -11
  38. package/dist/{journal-ITUMKT6U.js → journal-E2DJGCNS.js} +6 -6
  39. package/dist/{loader-27PLDCOJ.js → loader-NVVXVFBH.js} +3 -3
  40. package/dist/{mcp-installer-X2TJ2S2G.js → mcp-installer-4LOYB3PP.js} +3 -3
  41. package/dist/{primitive-registry-ZMGGXSO5.js → primitive-registry-KQOL7LNU.js} +3 -3
  42. package/dist/{provider-HQY6SPZI.js → provider-75AKTYGB.js} +2 -2
  43. package/dist/{rule-engine-DM26S77N.js → rule-engine-EPFMNBEG.js} +3 -3
  44. package/dist/{scaffold-2F36YVW6.js → scaffold-FBUNVFYQ.js} +5 -5
  45. package/dist/{scheduler-Q7GB2KCW.js → scheduler-UCFJU4BF.js} +12 -12
  46. package/dist/{search-6Y6NCOLQ.js → search-7RAQA6UV.js} +3 -3
  47. package/dist/{semantic-search-FN6FZIXI.js → semantic-search-OSRMCW2H.js} +3 -3
  48. package/dist/{serve-MXRTP2HE.js → serve-2QUR74CS.js} +10 -10
  49. package/dist/{telemetry-RS2JZUZP.js → telemetry-R34GXFVW.js} +4 -4
  50. package/dist/{tool-executor-6I5PHQDY.js → tool-executor-URY2ZB6G.js} +5 -5
  51. package/dist/{tools-NDFJNVHK.js → tools-2HWMJ5CJ.js} +4 -4
  52. package/dist/{types-NPJZAI72.js → types-KSGYUZZO.js} +2 -2
  53. package/dist/{universal-installer-LCAZHFZR.js → universal-installer-ZNA3HA2S.js} +6 -6
  54. package/dist/validator-JNIHKGWA.js +21 -0
  55. package/dist/{verification-gate-2O6DF2B7.js → verification-gate-FFKVJN5N.js} +3 -3
  56. package/dist/{watcher-GZWQSWZ6.js → watcher-L5SJGTZ2.js} +5 -5
  57. package/dist/{web-server-2Y4CHD2W.js → web-server-N3YIT47Z.js} +9 -9
  58. package/package.json +1 -1
  59. package/dist/chunk-4TQQZILG.js.map +0 -1
  60. package/dist/chunk-IZ6UZ3ZL.js.map +0 -1
  61. package/dist/chunk-M62KLIEK.js.map +0 -1
  62. package/dist/context-loader-RSXXFW5R.js +0 -12
  63. package/dist/graph-LEEO37L3.js +0 -13
  64. package/dist/instinct-learner-QGAMIS3X.js +0 -19
  65. package/dist/validator-LM7RZWSH.js +0 -21
  66. /package/dist/{auto-processor-QIRUOGEI.js.map → auto-processor-KLEP2NMV.js.map} +0 -0
  67. /package/dist/{chunk-UXCHAS3Z.js.map → chunk-2GPXPU6U.js.map} +0 -0
  68. /package/dist/{chunk-PMFAYKBD.js.map → chunk-36W2VC3L.js.map} +0 -0
  69. /package/dist/{chunk-EC42HQQH.js.map → chunk-44R2VV33.js.map} +0 -0
  70. /package/dist/{chunk-AN6Y4MDD.js.map → chunk-5QME3GHF.js.map} +0 -0
  71. /package/dist/{chunk-QMOIVORH.js.map → chunk-6DIHJF2A.js.map} +0 -0
  72. /package/dist/{chunk-SEHAQTBO.js.map → chunk-CKLJTFMV.js.map} +0 -0
  73. /package/dist/{chunk-5O5OGOOQ.js.map → chunk-CNOHSYI5.js.map} +0 -0
  74. /package/dist/{chunk-D7AWV24Z.js.map → chunk-ESBLYOXU.js.map} +0 -0
  75. /package/dist/{chunk-M6PDMK2O.js.map → chunk-MASZOYMQ.js.map} +0 -0
  76. /package/dist/{chunk-UMXPOYZR.js.map → chunk-NGF7UZY5.js.map} +0 -0
  77. /package/dist/{chunk-4P6TRFPZ.js.map → chunk-O2YV52TH.js.map} +0 -0
  78. /package/dist/{chunk-7GZ4D6V6.js.map → chunk-P7EFJ7CN.js.map} +0 -0
  79. /package/dist/{chunk-KLYMGWQJ.js.map → chunk-QILHQNSM.js.map} +0 -0
  80. /package/dist/{chunk-NVC2WY4K.js.map → chunk-WHRYPI2T.js.map} +0 -0
  81. /package/dist/{chunk-5CO5JTYT.js.map → chunk-X47HHTNV.js.map} +0 -0
  82. /package/dist/{chunk-2UVWCTAY.js.map → chunk-XPEDVA35.js.map} +0 -0
  83. /package/dist/{config-PYSS3QY6.js.map → config-KRGEWBPM.js.map} +0 -0
  84. /package/dist/{context-loader-RSXXFW5R.js.map → context-loader-GKLLIDVC.js.map} +0 -0
  85. /package/dist/{conversation-TBTFIJVU.js.map → conversation-EU47O5MU.js.map} +0 -0
  86. /package/dist/{delegate-3KJAL4NZ.js.map → delegate-BPTJVYU3.js.map} +0 -0
  87. /package/dist/{export-GYLWROMB.js.map → export-OPR3SVVJ.js.map} +0 -0
  88. /package/dist/{graph-LEEO37L3.js.map → graph-VW5GH2FZ.js.map} +0 -0
  89. /package/dist/{harness-R5FKRICG.js.map → harness-FZR52COJ.js.map} +0 -0
  90. /package/dist/{indexer-L5UC6J2V.js.map → indexer-SEALD6HO.js.map} +0 -0
  91. /package/dist/{instinct-learner-QGAMIS3X.js.map → instinct-learner-MNROY6L4.js.map} +0 -0
  92. /package/dist/{intake-SVJKFHTL.js.map → intake-BU2WHPWF.js.map} +0 -0
  93. /package/dist/{intelligence-XPV3MC5U.js.map → intelligence-TUNH5ZMA.js.map} +0 -0
  94. /package/dist/{journal-ITUMKT6U.js.map → journal-E2DJGCNS.js.map} +0 -0
  95. /package/dist/{loader-27PLDCOJ.js.map → loader-NVVXVFBH.js.map} +0 -0
  96. /package/dist/{mcp-installer-X2TJ2S2G.js.map → mcp-installer-4LOYB3PP.js.map} +0 -0
  97. /package/dist/{primitive-registry-ZMGGXSO5.js.map → primitive-registry-KQOL7LNU.js.map} +0 -0
  98. /package/dist/{provider-HQY6SPZI.js.map → provider-75AKTYGB.js.map} +0 -0
  99. /package/dist/{rule-engine-DM26S77N.js.map → rule-engine-EPFMNBEG.js.map} +0 -0
  100. /package/dist/{scaffold-2F36YVW6.js.map → scaffold-FBUNVFYQ.js.map} +0 -0
  101. /package/dist/{scheduler-Q7GB2KCW.js.map → scheduler-UCFJU4BF.js.map} +0 -0
  102. /package/dist/{search-6Y6NCOLQ.js.map → search-7RAQA6UV.js.map} +0 -0
  103. /package/dist/{semantic-search-FN6FZIXI.js.map → semantic-search-OSRMCW2H.js.map} +0 -0
  104. /package/dist/{serve-MXRTP2HE.js.map → serve-2QUR74CS.js.map} +0 -0
  105. /package/dist/{telemetry-RS2JZUZP.js.map → telemetry-R34GXFVW.js.map} +0 -0
  106. /package/dist/{tool-executor-6I5PHQDY.js.map → tool-executor-URY2ZB6G.js.map} +0 -0
  107. /package/dist/{tools-NDFJNVHK.js.map → tools-2HWMJ5CJ.js.map} +0 -0
  108. /package/dist/{types-NPJZAI72.js.map → types-KSGYUZZO.js.map} +0 -0
  109. /package/dist/{universal-installer-LCAZHFZR.js.map → universal-installer-ZNA3HA2S.js.map} +0 -0
  110. /package/dist/{validator-LM7RZWSH.js.map → validator-JNIHKGWA.js.map} +0 -0
  111. /package/dist/{verification-gate-2O6DF2B7.js.map → verification-gate-FFKVJN5N.js.map} +0 -0
  112. /package/dist/{watcher-GZWQSWZ6.js.map → watcher-L5SJGTZ2.js.map} +0 -0
  113. /package/dist/{web-server-2Y4CHD2W.js.map → web-server-N3YIT47Z.js.map} +0 -0
package/README.md CHANGED
@@ -459,6 +459,31 @@ memory:
459
459
  # enforce: true
460
460
  ```
461
461
 
462
+ ## Sub-agent model selection
463
+
464
+ Sub-agents in `agents/` can declare which config model to use for their delegated LLM call via an optional `model:` frontmatter field. This lets cheap tasks (summarizing, triage, classification) run on smaller/faster models while your primary agent uses a stronger one for reasoning.
465
+
466
+ ```yaml
467
+ ---
468
+ id: agent-summarizer
469
+ tags: [agent, utility]
470
+ model: fast # primary (default) | summary | fast
471
+ ---
472
+
473
+ # Agent: Summarizer
474
+ ...
475
+ ```
476
+
477
+ The three values map to existing `config.yaml` fields:
478
+
479
+ - **`primary`** (default) — uses `config.model.id`. Same as `harness run`.
480
+ - **`summary`** — uses `config.model.summary_model`, falling back to `primary` if unset.
481
+ - **`fast`** — uses `config.model.fast_model`, falling back to `summary` → `primary`.
482
+
483
+ All three resolve to a model on the **same provider** as your primary config. Multi-provider sub-agents (e.g. primary on OpenRouter with summarizer on local Ollama) aren't supported in this field — model ids are provider-specific and a portable abstraction leaks. If you need cross-provider routing, file an issue describing the use case.
484
+
485
+ The default `agents/summarizer.md` ships with `model: fast` as a canonical example. It's safe on fresh scaffolds: when `fast_model` isn't configured, the fallback chain lands on your primary model, so you get the same behavior as v0.1.7 until you opt in by setting `fast_model` in `config.yaml`.
486
+
462
487
  ## Environment Variables
463
488
 
464
489
  | Variable | Required | Description |
@@ -5,6 +5,10 @@ created: {{DATE}}
5
5
  updated: {{DATE}}
6
6
  author: human
7
7
  status: active
8
+ # Summarizing is cheap — use the `fast` model tier from config.yaml if set.
9
+ # Falls back to summary_model → primary model when fast_model isn't configured,
10
+ # so this works on a fresh scaffold with zero config changes.
11
+ model: fast
8
12
  related:
9
13
  - research
10
14
  ---
@@ -3,10 +3,10 @@
3
3
  import {
4
4
  autoProcessAll,
5
5
  autoProcessFile
6
- } from "./chunk-NVC2WY4K.js";
7
- import "./chunk-4TQQZILG.js";
6
+ } from "./chunk-WHRYPI2T.js";
7
+ import "./chunk-EXO47RET.js";
8
8
  export {
9
9
  autoProcessAll,
10
10
  autoProcessFile
11
11
  };
12
- //# sourceMappingURL=auto-processor-QIRUOGEI.js.map
12
+ //# sourceMappingURL=auto-processor-KLEP2NMV.js.map
@@ -2,14 +2,14 @@
2
2
 
3
3
  import {
4
4
  writeIndexFile
5
- } from "./chunk-D7AWV24Z.js";
5
+ } from "./chunk-ESBLYOXU.js";
6
6
  import {
7
7
  loadDirectory,
8
8
  parseHarnessDocument
9
- } from "./chunk-2UVWCTAY.js";
9
+ } from "./chunk-XPEDVA35.js";
10
10
  import {
11
11
  getPrimitiveDirs
12
- } from "./chunk-4TQQZILG.js";
12
+ } from "./chunk-EXO47RET.js";
13
13
 
14
14
  // src/runtime/intake.ts
15
15
  import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, readdirSync, copyFileSync } from "fs";
@@ -343,4 +343,4 @@ export {
343
343
  processIntake,
344
344
  downloadCapability
345
345
  };
346
- //# sourceMappingURL=chunk-UXCHAS3Z.js.map
346
+ //# sourceMappingURL=chunk-2GPXPU6U.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  loadDirectory
5
- } from "./chunk-2UVWCTAY.js";
5
+ } from "./chunk-XPEDVA35.js";
6
6
 
7
7
  // src/runtime/tools.ts
8
8
  import { existsSync } from "fs";
@@ -108,4 +108,4 @@ export {
108
108
  listToolSummaries,
109
109
  checkToolAuth
110
110
  };
111
- //# sourceMappingURL=chunk-PMFAYKBD.js.map
111
+ //# sourceMappingURL=chunk-36W2VC3L.js.map
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  CONFIG_DEFAULTS,
5
5
  HarnessConfigSchema
6
- } from "./chunk-4TQQZILG.js";
6
+ } from "./chunk-EXO47RET.js";
7
7
 
8
8
  // src/core/config.ts
9
9
  import { readFileSync, existsSync } from "fs";
@@ -97,4 +97,4 @@ export {
97
97
  loadConfig,
98
98
  writeDefaultConfig
99
99
  };
100
- //# sourceMappingURL=chunk-EC42HQQH.js.map
100
+ //# sourceMappingURL=chunk-44R2VV33.js.map
@@ -2,25 +2,25 @@
2
2
 
3
3
  import {
4
4
  fixCapability
5
- } from "./chunk-UXCHAS3Z.js";
5
+ } from "./chunk-2GPXPU6U.js";
6
6
  import {
7
7
  validateMcpConfig
8
8
  } from "./chunk-5H34JPMB.js";
9
9
  import {
10
10
  buildSystemPrompt
11
- } from "./chunk-7GZ4D6V6.js";
11
+ } from "./chunk-P7EFJ7CN.js";
12
12
  import {
13
13
  loadState
14
14
  } from "./chunk-UDZIS2AQ.js";
15
15
  import {
16
16
  loadDirectoryWithErrors
17
- } from "./chunk-2UVWCTAY.js";
17
+ } from "./chunk-XPEDVA35.js";
18
18
  import {
19
19
  loadConfig
20
- } from "./chunk-EC42HQQH.js";
20
+ } from "./chunk-44R2VV33.js";
21
21
  import {
22
22
  getPrimitiveDirs
23
- } from "./chunk-4TQQZILG.js";
23
+ } from "./chunk-EXO47RET.js";
24
24
 
25
25
  // src/runtime/validator.ts
26
26
  import { existsSync, readdirSync, mkdirSync } from "fs";
@@ -227,4 +227,4 @@ export {
227
227
  validateHarness,
228
228
  doctorHarness
229
229
  };
230
- //# sourceMappingURL=chunk-AN6Y4MDD.js.map
230
+ //# sourceMappingURL=chunk-5QME3GHF.js.map
@@ -2,10 +2,10 @@
2
2
 
3
3
  import {
4
4
  loadDirectoryWithErrors
5
- } from "./chunk-2UVWCTAY.js";
5
+ } from "./chunk-XPEDVA35.js";
6
6
  import {
7
7
  getPrimitiveDirs
8
- } from "./chunk-4TQQZILG.js";
8
+ } from "./chunk-EXO47RET.js";
9
9
 
10
10
  // src/runtime/graph.ts
11
11
  import { existsSync } from "fs";
@@ -159,4 +159,4 @@ export {
159
159
  buildDependencyGraph,
160
160
  getGraphStats
161
161
  };
162
- //# sourceMappingURL=chunk-QMOIVORH.js.map
162
+ //# sourceMappingURL=chunk-6DIHJF2A.js.map
@@ -2,13 +2,13 @@
2
2
 
3
3
  import {
4
4
  collectSnapshot
5
- } from "./chunk-5O5OGOOQ.js";
5
+ } from "./chunk-CNOHSYI5.js";
6
6
  import {
7
7
  validateMcpConfig
8
8
  } from "./chunk-5H34JPMB.js";
9
9
  import {
10
10
  Conversation
11
- } from "./chunk-UMXPOYZR.js";
11
+ } from "./chunk-NGF7UZY5.js";
12
12
  import {
13
13
  loadState,
14
14
  saveState
@@ -20,16 +20,16 @@ import {
20
20
  loadAllPrimitives,
21
21
  loadDirectory,
22
22
  parseHarnessDocument
23
- } from "./chunk-2UVWCTAY.js";
23
+ } from "./chunk-XPEDVA35.js";
24
24
  import {
25
25
  log
26
26
  } from "./chunk-BSKDOFRT.js";
27
27
  import {
28
28
  loadConfig
29
- } from "./chunk-EC42HQQH.js";
29
+ } from "./chunk-44R2VV33.js";
30
30
  import {
31
31
  CORE_PRIMITIVE_DIRS
32
- } from "./chunk-4TQQZILG.js";
32
+ } from "./chunk-EXO47RET.js";
33
33
 
34
34
  // node_modules/hono/dist/compose.js
35
35
  var compose = (middleware, onError, onNotFound) => {
@@ -3437,4 +3437,4 @@ export {
3437
3437
  createWebApp,
3438
3438
  startWebServer
3439
3439
  };
3440
- //# sourceMappingURL=chunk-SEHAQTBO.js.map
3440
+ //# sourceMappingURL=chunk-CKLJTFMV.js.map
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-JKMGYWXB.js";
22
22
  import {
23
23
  loadConfig
24
- } from "./chunk-EC42HQQH.js";
24
+ } from "./chunk-44R2VV33.js";
25
25
 
26
26
  // src/runtime/telemetry.ts
27
27
  import { existsSync, readdirSync } from "fs";
@@ -233,4 +233,4 @@ export {
233
233
  collectSnapshot,
234
234
  formatDashboard
235
235
  };
236
- //# sourceMappingURL=chunk-5O5OGOOQ.js.map
236
+ //# sourceMappingURL=chunk-CNOHSYI5.js.map
@@ -2,10 +2,10 @@
2
2
 
3
3
  import {
4
4
  loadDirectory
5
- } from "./chunk-2UVWCTAY.js";
5
+ } from "./chunk-XPEDVA35.js";
6
6
  import {
7
7
  CORE_PRIMITIVE_DIRS
8
- } from "./chunk-4TQQZILG.js";
8
+ } from "./chunk-EXO47RET.js";
9
9
 
10
10
  // src/runtime/indexer.ts
11
11
  import { writeFileSync, existsSync, mkdirSync } from "fs";
@@ -66,4 +66,4 @@ export {
66
66
  writeIndexFile,
67
67
  rebuildAllIndexes
68
68
  };
69
- //# sourceMappingURL=chunk-D7AWV24Z.js.map
69
+ //# sourceMappingURL=chunk-ESBLYOXU.js.map
@@ -16,7 +16,9 @@ var FrontmatterSchema = z.object({
16
16
  channel: z.string().optional(),
17
17
  duration_minutes: z.number().optional(),
18
18
  max_retries: z.number().int().nonnegative().optional(),
19
- retry_delay_ms: z.number().int().positive().optional()
19
+ retry_delay_ms: z.number().int().positive().optional(),
20
+ /** Sub-agent only: which config model tier to use. See AgentModelTier above. */
21
+ model: z.enum(["primary", "summary", "fast"]).optional()
20
22
  });
21
23
  var HarnessConfigSchema = z.object({
22
24
  agent: z.object({
@@ -235,4 +237,4 @@ export {
235
237
  CORE_PRIMITIVE_DIRS,
236
238
  getPrimitiveDirs
237
239
  };
238
- //# sourceMappingURL=chunk-4TQQZILG.js.map
240
+ //# sourceMappingURL=chunk-EXO47RET.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/types.ts"],"sourcesContent":["import { z } from 'zod';\n\n// --- Frontmatter ---\n/**\n * Which config.yaml model a sub-agent's LLM call should use when invoked\n * via `harness delegate`. Only meaningful on agent primitives.\n *\n * - 'primary' (default): config.model.id — same as `harness run`\n * - 'summary': config.model.summary_model (falls back to primary if unset)\n * - 'fast': config.model.fast_model (falls back to summary → primary)\n *\n * All three use the SAME provider as the primary config. Multi-provider\n * sub-agents are explicitly not supported in this field — model ids are\n * provider-specific and a portable tier abstraction leaks. If you need a\n * different provider, that's a separate feature (backlog).\n */\nexport type AgentModelTier = 'primary' | 'summary' | 'fast';\n\nexport const FrontmatterSchema = z.object({\n id: z.string(),\n tags: z.array(z.string()).default([]),\n created: z.string().optional(),\n updated: z.string().optional(),\n author: z.enum(['human', 'agent', 'infrastructure']).default('human'),\n status: z.enum(['active', 'archived', 'deprecated', 'draft']).default('active'),\n related: z.array(z.string()).default([]),\n schedule: z.string().optional(),\n with: z.string().optional(),\n channel: z.string().optional(),\n duration_minutes: z.number().optional(),\n max_retries: z.number().int().nonnegative().optional(),\n retry_delay_ms: z.number().int().positive().optional(),\n /** Sub-agent only: which config model tier to use. See AgentModelTier above. */\n model: z.enum(['primary', 'summary', 'fast']).optional(),\n});\n\nexport type Frontmatter = z.infer<typeof FrontmatterSchema>;\n\n// --- Primitive Document ---\nexport interface HarnessDocument {\n path: string;\n frontmatter: Frontmatter;\n l0: string;\n l1: string;\n body: string;\n raw: string;\n}\n\n// --- Primitive Types ---\nexport type PrimitiveType =\n | 'rule'\n | 'instinct'\n | 'skill'\n | 'playbook'\n | 'workflow'\n | 'tool'\n | 'agent'\n | 'session'\n | 'journal';\n\nexport interface Primitive {\n type: PrimitiveType;\n doc: HarnessDocument;\n}\n\n// --- Config ---\nexport const HarnessConfigSchema = z.object({\n agent: z.object({\n name: z.string().min(1),\n version: z.string().default('0.1.0'),\n }).passthrough(),\n model: z.object({\n provider: z.string().default('openrouter'),\n id: z.string().min(1),\n max_tokens: z.number().int().positive().default(200000),\n max_retries: z.number().int().nonnegative().default(2),\n timeout_ms: z.number().int().positive().optional(),\n /** Cheap model for auto-generating summaries, tags, frontmatter (e.g. 'google/gemini-flash-1.5') */\n summary_model: z.string().optional(),\n /** Fast model for validation, checks, and quick decisions (e.g. 'google/gemini-flash-1.5') */\n fast_model: z.string().optional(),\n }).passthrough(),\n runtime: z.object({\n scratchpad_budget: z.number().int().nonnegative().default(10000),\n /** Reserved: cron expression for periodic heartbeat check (not yet implemented) */\n heartbeat: z.string().optional(),\n /** Reserved: cron expression for daily summary generation (not yet implemented) */\n daily_summary: z.string().optional(),\n /** Auto-process primitives on save: generate frontmatter, L0/L1 summaries (default: true) */\n auto_process: z.boolean().default(true),\n quiet_hours: z.object({\n start: z.number().int().min(0).max(23).default(23),\n end: z.number().int().min(0).max(23).default(6),\n }).passthrough().default({ start: 23, end: 6 }),\n timezone: z.string().default('America/New_York'),\n }).passthrough(),\n memory: z.object({\n session_retention_days: z.number().int().positive().default(7),\n journal_retention_days: z.number().int().positive().default(365),\n }).passthrough(),\n channels: z.object({\n primary: z.string().default('cli'),\n }).passthrough(),\n extensions: z.object({\n directories: z.array(z.string()).default([]),\n }).passthrough().default({ directories: [] }),\n rate_limits: z.object({\n /** Max LLM calls per minute (default: unlimited) */\n per_minute: z.number().int().positive().optional(),\n /** Max LLM calls per hour (default: unlimited) */\n per_hour: z.number().int().positive().optional(),\n /** Max LLM calls per day (default: unlimited) */\n per_day: z.number().int().positive().optional(),\n }).passthrough().default({}),\n budget: z.object({\n /** Max daily spend in USD (default: unlimited) */\n daily_limit_usd: z.number().positive().optional(),\n /** Max monthly spend in USD (default: unlimited) */\n monthly_limit_usd: z.number().positive().optional(),\n /** Block runs when budget exceeded (default: true) */\n enforce: z.boolean().default(true),\n }).passthrough().default({ enforce: true }),\n mcp: z.object({\n /** MCP server definitions keyed by server name */\n servers: z.record(z.string(), z.object({\n /** Transport type: 'stdio' for local processes, 'http' for remote, 'sse' for SSE */\n transport: z.enum(['stdio', 'http', 'sse']),\n /** Command to spawn (stdio transport only) */\n command: z.string().optional(),\n /** Command arguments (stdio transport only) */\n args: z.array(z.string()).optional(),\n /** Environment variables for the spawned process (stdio transport only) */\n env: z.record(z.string(), z.string()).optional(),\n /** Working directory for the spawned process (stdio transport only) */\n cwd: z.string().optional(),\n /** URL endpoint (http/sse transport only) */\n url: z.string().optional(),\n /** Additional HTTP headers (http/sse transport only) */\n headers: z.record(z.string(), z.string()).optional(),\n /** Whether this server is enabled (default: true) */\n enabled: z.boolean().default(true),\n }).passthrough()).default({}),\n }).passthrough().default({ servers: {} }),\n /** Intelligence & continuous learning config */\n intelligence: z.object({\n /** Auto-run journal synthesis on a cron schedule (default: off). Set to cron string e.g. \"0 22 * * *\" or true for default \"0 22 * * *\". */\n auto_journal: z.union([z.boolean(), z.string()]).default(false),\n /** Auto-run instinct learning after journal synthesis (default: off) */\n auto_learn: z.boolean().default(false),\n }).passthrough().default({ auto_journal: false, auto_learn: false }),\n /** Proactive execution config (scheduler rate-limiting) */\n proactive: z.object({\n /** Enable proactive scheduled workflows (default: false) */\n enabled: z.boolean().default(false),\n /** Max proactive workflow executions per hour (default: 5) */\n max_per_hour: z.number().int().positive().default(5),\n /** Cooldown in minutes between proactive runs of the same workflow (default: 30) */\n cooldown_minutes: z.number().int().nonnegative().default(30),\n /** Override quiet hours for proactive execution (start/end hours, inherits runtime.quiet_hours if not set) */\n quiet_hours: z.object({\n start: z.number().int().min(0).max(23).optional(),\n end: z.number().int().min(0).max(23).optional(),\n }).passthrough().optional(),\n }).passthrough().default({ enabled: false, max_per_hour: 5, cooldown_minutes: 30 }),\n /** Primitive bundle registries for search/install */\n registries: z.array(z.object({\n /** Registry URL (HTTPS endpoint) */\n url: z.string().url(),\n /** Optional display name */\n name: z.string().optional(),\n /** Optional auth token for private registries */\n token: z.string().optional(),\n }).passthrough()).default([]),\n /**\n * License policy for `harness install <url>`. Controls how the universal\n * installer reacts to the license detected on a fetched primitive (Level 3\n * of task 12.14). Detection itself runs unconditionally — this only governs\n * what happens after the license is determined.\n */\n install: z.object({\n /**\n * SPDX ids the installer accepts without warning. Permissive defaults\n * cover the OSI-approved ecosystem most users care about. Add or remove\n * here to tighten or loosen the policy.\n */\n allowed_licenses: z.array(z.string()).default([\n 'MIT',\n 'Apache-2.0',\n 'BSD-2-Clause',\n 'BSD-3-Clause',\n 'ISC',\n 'MPL-2.0',\n 'CC-BY-4.0',\n 'CC0-1.0',\n 'Unlicense',\n ]),\n /**\n * What to do when the detected license is not in `allowed_licenses` and\n * is not classified as PROPRIETARY. Includes the UNKNOWN case (no LICENSE\n * file found anywhere) and any non-permissive SPDX id like GPL-3.0.\n *\n * - allow: install silently (legacy v0.1.3 behavior — safest for migration)\n * - warn: install with a stderr warning naming the license_source\n * - prompt: ask Y/n on TTY; treats non-TTY as `block`\n * - block: refuse the install with an error showing the override flag\n */\n on_unknown_license: z.enum(['allow', 'warn', 'prompt', 'block']).default('warn'),\n /**\n * What to do when the detected license is PROPRIETARY (text contains\n * \"all rights reserved\" or no permission grant). Defaults to `block`\n * because shipping proprietary content was the v0.1.0 yank cause.\n */\n on_proprietary: z.enum(['allow', 'warn', 'prompt', 'block']).default('block'),\n }).passthrough().default({\n allowed_licenses: [\n 'MIT',\n 'Apache-2.0',\n 'BSD-2-Clause',\n 'BSD-3-Clause',\n 'ISC',\n 'MPL-2.0',\n 'CC-BY-4.0',\n 'CC0-1.0',\n 'Unlicense',\n ],\n on_unknown_license: 'warn',\n on_proprietary: 'block',\n }),\n}).passthrough();\n\nexport type HarnessConfig = z.infer<typeof HarnessConfigSchema>;\n\nexport const CONFIG_DEFAULTS: HarnessConfig = {\n agent: { name: 'agent', version: '0.1.0' },\n model: { provider: 'openrouter', id: 'anthropic/claude-sonnet-4', max_tokens: 200000, max_retries: 2 },\n runtime: {\n scratchpad_budget: 10000,\n auto_process: true,\n quiet_hours: { start: 23, end: 6 },\n timezone: 'America/New_York',\n },\n memory: { session_retention_days: 7, journal_retention_days: 365 },\n channels: { primary: 'cli' },\n extensions: { directories: [] },\n rate_limits: {},\n budget: { enforce: true },\n intelligence: { auto_journal: false, auto_learn: false },\n proactive: { enabled: false, max_per_hour: 5, cooldown_minutes: 30 },\n mcp: { servers: {} },\n registries: [],\n install: {\n allowed_licenses: [\n 'MIT',\n 'Apache-2.0',\n 'BSD-2-Clause',\n 'BSD-3-Clause',\n 'ISC',\n 'MPL-2.0',\n 'CC-BY-4.0',\n 'CC0-1.0',\n 'Unlicense',\n ],\n on_unknown_license: 'warn',\n on_proprietary: 'block',\n },\n};\n\nexport const CORE_PRIMITIVE_DIRS = ['rules', 'instincts', 'skills', 'playbooks', 'workflows', 'tools', 'agents'] as const;\n\nexport function getPrimitiveDirs(config?: HarnessConfig): string[] {\n const dirs: string[] = [...CORE_PRIMITIVE_DIRS];\n if (config?.extensions?.directories) {\n for (const dir of config.extensions.directories) {\n if (!dirs.includes(dir)) {\n dirs.push(dir);\n }\n }\n }\n return dirs;\n}\n\n// --- Agent State ---\nexport interface AgentState {\n mode: string;\n goals: string[];\n active_workflows: string[];\n last_interaction: string;\n unfinished_business: string[];\n}\n\n// --- Context Budget ---\nexport interface ContextBudget {\n max_tokens: number;\n used_tokens: number;\n remaining: number;\n loaded_files: string[];\n}\n\n// --- Utility Types ---\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n// --- Lifecycle Hooks ---\nexport interface HarnessHooks {\n /** Called after boot completes (context loaded, state ready) */\n onBoot?: (context: { agent: HarnessAgent; config: HarnessConfig; state: AgentState }) => void | Promise<void>;\n /** Called after each session completes (run or stream) */\n onSessionEnd?: (context: { agent: HarnessAgent; sessionId: string; prompt: string; result: AgentRunResult }) => void | Promise<void>;\n /** Called when an error occurs during run/stream */\n onError?: (context: { agent: HarnessAgent; error: Error; prompt?: string }) => void | Promise<void>;\n /** Called when agent state changes (boot, shutdown, after run) */\n onStateChange?: (context: { agent: HarnessAgent; previous: string; current: string }) => void | Promise<void>;\n /** Called before shutdown completes */\n onShutdown?: (context: { agent: HarnessAgent; state: AgentState }) => void | Promise<void>;\n}\n\n// --- Tool Executor Config (inline to avoid circular deps) ---\nexport interface ToolExecutorOptions {\n /** Maximum tool calls per run (default: 5) */\n maxToolCalls?: number;\n /** Timeout per tool call in ms (default: 30000) */\n toolTimeoutMs?: number;\n /** Whether to allow HTTP tool execution (default: true) */\n allowHttpExecution?: boolean;\n}\n\n// --- Agent Options (programmatic API) ---\nexport interface CreateHarnessOptions {\n dir: string;\n /** Model ID override (e.g., \"claude-sonnet-4-20250514\" or \"gpt-4o\") */\n model?: string;\n /** Provider override (e.g., \"anthropic\", \"openai\", \"openrouter\") */\n provider?: string;\n apiKey?: string;\n config?: DeepPartial<HarnessConfig>;\n /** Lifecycle hooks for agent events */\n hooks?: HarnessHooks;\n /** Tool execution configuration */\n toolExecutor?: ToolExecutorOptions;\n}\n\n/** Record of a single tool call made during a run */\nexport interface ToolCallInfo {\n toolName: string;\n args: Record<string, unknown>;\n result: unknown;\n}\n\n// --- Agent Interface ---\nexport interface AgentRunResult {\n text: string;\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n session_id: string;\n steps: number;\n /** Tool calls made during the run (empty array if none) */\n toolCalls: ToolCallInfo[];\n}\n\nexport interface AgentStreamResult {\n /** Async iterable of text chunks — consume with for-await */\n textStream: AsyncIterable<string>;\n /** Resolves after the stream is fully consumed with session metadata */\n result: Promise<AgentRunResult>;\n}\n\nexport interface HarnessAgent {\n name: string;\n config: HarnessConfig;\n boot(): Promise<void>;\n run(prompt: string): Promise<AgentRunResult>;\n stream(prompt: string): AgentStreamResult;\n shutdown(): Promise<void>;\n getSystemPrompt(): string;\n getState(): AgentState;\n}\n\n// --- Index Entry ---\nexport interface IndexEntry {\n id: string;\n path: string;\n tags: string[];\n l0: string;\n created: string;\n status: string;\n}\n"],"mappings":"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","names":[]}
@@ -2,14 +2,14 @@
2
2
 
3
3
  import {
4
4
  loadDirectory
5
- } from "./chunk-2UVWCTAY.js";
5
+ } from "./chunk-XPEDVA35.js";
6
6
  import {
7
7
  generate,
8
8
  getModel
9
- } from "./chunk-IZ6UZ3ZL.js";
9
+ } from "./chunk-WCYBFALM.js";
10
10
  import {
11
11
  loadConfig
12
- } from "./chunk-EC42HQQH.js";
12
+ } from "./chunk-44R2VV33.js";
13
13
 
14
14
  // src/runtime/instinct-learner.ts
15
15
  import { writeFileSync, readdirSync, readFileSync, existsSync, mkdirSync } from "fs";
@@ -197,4 +197,4 @@ export {
197
197
  learnFromSessions,
198
198
  harvestInstincts
199
199
  };
200
- //# sourceMappingURL=chunk-M6PDMK2O.js.map
200
+ //# sourceMappingURL=chunk-MASZOYMQ.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  buildSystemPrompt
5
- } from "./chunk-7GZ4D6V6.js";
5
+ } from "./chunk-P7EFJ7CN.js";
6
6
  import {
7
7
  createSessionId,
8
8
  writeSession
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-Z2PUCXTZ.js";
13
13
  import {
14
14
  estimateTokens
15
- } from "./chunk-2UVWCTAY.js";
15
+ } from "./chunk-XPEDVA35.js";
16
16
  import {
17
17
  log
18
18
  } from "./chunk-BSKDOFRT.js";
@@ -20,10 +20,10 @@ import {
20
20
  generateWithMessages,
21
21
  getModel,
22
22
  streamWithMessages
23
- } from "./chunk-IZ6UZ3ZL.js";
23
+ } from "./chunk-WCYBFALM.js";
24
24
  import {
25
25
  loadConfig
26
- } from "./chunk-EC42HQQH.js";
26
+ } from "./chunk-44R2VV33.js";
27
27
 
28
28
  // src/runtime/conversation.ts
29
29
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -371,4 +371,4 @@ export {
371
371
  parseJsonlContext,
372
372
  parseLegacyContext
373
373
  };
374
- //# sourceMappingURL=chunk-UMXPOYZR.js.map
374
+ //# sourceMappingURL=chunk-NGF7UZY5.js.map
@@ -2,14 +2,14 @@
2
2
 
3
3
  import {
4
4
  parseHarnessDocument
5
- } from "./chunk-2UVWCTAY.js";
5
+ } from "./chunk-XPEDVA35.js";
6
6
  import {
7
7
  generate,
8
8
  getModel
9
- } from "./chunk-IZ6UZ3ZL.js";
9
+ } from "./chunk-WCYBFALM.js";
10
10
  import {
11
11
  loadConfig
12
- } from "./chunk-EC42HQQH.js";
12
+ } from "./chunk-44R2VV33.js";
13
13
 
14
14
  // src/runtime/journal.ts
15
15
  import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from "fs";
@@ -304,4 +304,4 @@ export {
304
304
  listJournals,
305
305
  compressJournals
306
306
  };
307
- //# sourceMappingURL=chunk-4P6TRFPZ.js.map
307
+ //# sourceMappingURL=chunk-O2YV52TH.js.map
@@ -4,7 +4,7 @@ import {
4
4
  estimateTokens,
5
5
  getAtLevel,
6
6
  loadAllPrimitivesWithErrors
7
- } from "./chunk-2UVWCTAY.js";
7
+ } from "./chunk-XPEDVA35.js";
8
8
  import {
9
9
  log
10
10
  } from "./chunk-BSKDOFRT.js";
@@ -151,4 +151,4 @@ ${scratch}`);
151
151
  export {
152
152
  buildSystemPrompt
153
153
  };
154
- //# sourceMappingURL=chunk-7GZ4D6V6.js.map
154
+ //# sourceMappingURL=chunk-P7EFJ7CN.js.map
@@ -8,10 +8,10 @@ import {
8
8
  } from "./chunk-5H34JPMB.js";
9
9
  import {
10
10
  buildToolSet
11
- } from "./chunk-5CO5JTYT.js";
11
+ } from "./chunk-X47HHTNV.js";
12
12
  import {
13
13
  buildSystemPrompt
14
- } from "./chunk-7GZ4D6V6.js";
14
+ } from "./chunk-P7EFJ7CN.js";
15
15
  import {
16
16
  loadState,
17
17
  saveState
@@ -35,10 +35,10 @@ import {
35
35
  generate,
36
36
  getModel,
37
37
  streamGenerateWithDetails
38
- } from "./chunk-IZ6UZ3ZL.js";
38
+ } from "./chunk-WCYBFALM.js";
39
39
  import {
40
40
  loadConfig
41
- } from "./chunk-EC42HQQH.js";
41
+ } from "./chunk-44R2VV33.js";
42
42
 
43
43
  // src/core/harness.ts
44
44
  import { existsSync } from "fs";
@@ -396,4 +396,4 @@ function createHarness(options) {
396
396
  export {
397
397
  createHarness
398
398
  };
399
- //# sourceMappingURL=chunk-KLYMGWQJ.js.map
399
+ //# sourceMappingURL=chunk-QILHQNSM.js.map
@@ -11,13 +11,14 @@ var ENV_KEYS = {
11
11
  anthropic: "ANTHROPIC_API_KEY",
12
12
  openai: "OPENAI_API_KEY"
13
13
  };
14
+ var OLLAMA_DEFAULT_BASE_URL = "http://localhost:11434/v1";
14
15
  var _providers = /* @__PURE__ */ new Map();
15
16
  function getOrCreateFactory(providerName, apiKey) {
16
17
  const cacheKey = `${providerName}:${apiKey ?? "env"}`;
17
18
  const cached = _providers.get(cacheKey);
18
19
  if (cached) return cached;
19
20
  const envKey = ENV_KEYS[providerName];
20
- const key = apiKey ?? process.env[envKey];
21
+ const key = apiKey ?? (envKey ? process.env[envKey] : void 0);
21
22
  let factory;
22
23
  switch (providerName) {
23
24
  case "openrouter": {
@@ -40,9 +41,15 @@ function getOrCreateFactory(providerName, apiKey) {
40
41
  factory = (modelId) => provider(modelId);
41
42
  break;
42
43
  }
44
+ case "ollama": {
45
+ const baseURL = process.env.OLLAMA_BASE_URL ?? OLLAMA_DEFAULT_BASE_URL;
46
+ const provider = createOpenAI({ baseURL, apiKey: "ollama" });
47
+ factory = (modelId) => provider(modelId);
48
+ break;
49
+ }
43
50
  default:
44
51
  throw new Error(
45
- `Unknown provider "${providerName}". Supported providers: ${Object.keys(ENV_KEYS).join(", ")}`
52
+ `Unknown provider "${providerName}". Supported providers: openrouter, anthropic, openai, ollama`
46
53
  );
47
54
  }
48
55
  _providers.set(cacheKey, factory);
@@ -204,4 +211,4 @@ export {
204
211
  streamWithMessages,
205
212
  streamGenerateWithDetails
206
213
  };
207
- //# sourceMappingURL=chunk-IZ6UZ3ZL.js.map
214
+ //# sourceMappingURL=chunk-WCYBFALM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/llm/provider.ts"],"sourcesContent":["import { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { generateText, streamText, stepCountIs, type LanguageModel } from 'ai';\nimport type { ModelMessage } from '@ai-sdk/provider-utils';\nimport type { HarnessConfig, ToolCallInfo } from '../core/types.js';\nimport type { AIToolSet } from '../runtime/tool-executor.js';\n\n/** Supported provider names for config.model.provider */\nexport type ProviderName = 'openrouter' | 'anthropic' | 'openai' | 'ollama';\n\n/** Provider factory — maps provider names to (apiKey) => LanguageModel functions */\ntype ProviderFactory = (modelId: string, apiKey?: string) => LanguageModel;\n\n/**\n * Environment variable each provider reads its API key from.\n * Ollama runs locally and needs no auth, so it has no env key.\n */\nconst ENV_KEYS: Partial<Record<ProviderName, string>> = {\n openrouter: 'OPENROUTER_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n openai: 'OPENAI_API_KEY',\n};\n\n/**\n * Default base URL for the local Ollama HTTP server. Ollama exposes an\n * OpenAI-compatible chat completions endpoint at /v1 on this port.\n * Override with the OLLAMA_BASE_URL env var when running on a non-default\n * host or port (e.g. in Docker, on a remote box, behind a proxy).\n */\nconst OLLAMA_DEFAULT_BASE_URL = 'http://localhost:11434/v1';\n\n/** Cached provider instances keyed by provider name */\nconst _providers: Map<string, ProviderFactory> = new Map();\n\nfunction getOrCreateFactory(providerName: ProviderName, apiKey?: string): ProviderFactory {\n const cacheKey = `${providerName}:${apiKey ?? 'env'}`;\n const cached = _providers.get(cacheKey);\n if (cached) return cached;\n\n const envKey = ENV_KEYS[providerName];\n const key = apiKey ?? (envKey ? process.env[envKey] : undefined);\n\n let factory: ProviderFactory;\n\n switch (providerName) {\n case 'openrouter': {\n if (!key) {\n throw new Error(\n `No API key found for provider \"${providerName}\". ` +\n `Set ${envKey} environment variable or pass apiKey option.`\n );\n }\n const provider = createOpenRouter({ apiKey: key });\n factory = (modelId) => provider(modelId);\n break;\n }\n case 'anthropic': {\n // createAnthropic reads ANTHROPIC_API_KEY from env by default\n const provider = createAnthropic(key ? { apiKey: key } : undefined);\n factory = (modelId) => provider(modelId);\n break;\n }\n case 'openai': {\n // createOpenAI reads OPENAI_API_KEY from env by default\n const provider = createOpenAI(key ? { apiKey: key } : undefined);\n factory = (modelId) => provider(modelId);\n break;\n }\n case 'ollama': {\n // Ollama exposes an OpenAI-compatible chat completions endpoint at\n // http://localhost:11434/v1 by default. Reuses @ai-sdk/openai with a\n // baseURL override and a dummy apiKey (Ollama doesn't authenticate but\n // the OpenAI SDK requires the field to be set to something).\n // Override the host with OLLAMA_BASE_URL env var when needed.\n const baseURL = process.env.OLLAMA_BASE_URL ?? OLLAMA_DEFAULT_BASE_URL;\n const provider = createOpenAI({ baseURL, apiKey: 'ollama' });\n factory = (modelId) => provider(modelId);\n break;\n }\n default:\n throw new Error(\n `Unknown provider \"${providerName}\". ` +\n `Supported providers: openrouter, anthropic, openai, ollama`\n );\n }\n\n _providers.set(cacheKey, factory);\n return factory;\n}\n\n/**\n * Get the OpenRouter provider (backward-compatible).\n * @deprecated Use getModel() with config.model.provider instead.\n */\nexport function getProvider(apiKey?: string): ReturnType<typeof createOpenRouter> {\n const key = apiKey ?? process.env.OPENROUTER_API_KEY;\n if (!key) {\n throw new Error(\n 'No OpenRouter API key found. Set OPENROUTER_API_KEY environment variable or pass apiKey option.'\n );\n }\n return createOpenRouter({ apiKey: key });\n}\n\nexport function resetProvider(): void {\n _providers.clear();\n}\n\n/**\n * Get a LanguageModel from config. Supports openrouter, anthropic, and openai providers.\n *\n * Provider is selected from config.model.provider (defaults to 'openrouter').\n * Model ID format depends on provider:\n * - openrouter: \"anthropic/claude-sonnet-4\" (vendor/model)\n * - anthropic: \"claude-sonnet-4-20250514\" (native model ID)\n * - openai: \"gpt-4o\" (native model ID)\n */\nexport function getModel(config: HarnessConfig, apiKey?: string): LanguageModel {\n const providerName = (config.model.provider ?? 'openrouter') as ProviderName;\n const factory = getOrCreateFactory(providerName, apiKey);\n return factory(config.model.id);\n}\n\n/**\n * Get the summary model for cheap auto-generation tasks (L0/L1 summaries, tags, frontmatter).\n * Falls back to the primary model if summary_model is not configured.\n *\n * Usage: set `model.summary_model` in config.yaml, e.g.:\n * summary_model: \"google/gemini-flash-1.5\"\n */\nexport function getSummaryModel(config: HarnessConfig, apiKey?: string): LanguageModel {\n const modelId = config.model.summary_model ?? config.model.id;\n const providerName = (config.model.provider ?? 'openrouter') as ProviderName;\n const factory = getOrCreateFactory(providerName, apiKey);\n return factory(modelId);\n}\n\n/**\n * Get the fast model for validation, checks, and quick decisions.\n * Falls back to summary_model, then primary model.\n *\n * Usage: set `model.fast_model` in config.yaml, e.g.:\n * fast_model: \"google/gemini-flash-1.5\"\n */\nexport function getFastModel(config: HarnessConfig, apiKey?: string): LanguageModel {\n const modelId = config.model.fast_model ?? config.model.summary_model ?? config.model.id;\n const providerName = (config.model.provider ?? 'openrouter') as ProviderName;\n const factory = getOrCreateFactory(providerName, apiKey);\n return factory(modelId);\n}\n\nexport interface CallOptions {\n maxRetries?: number;\n timeoutMs?: number;\n abortSignal?: AbortSignal;\n}\n\nexport interface GenerateOptions extends CallOptions {\n model: LanguageModel;\n system: string;\n prompt: string;\n maxOutputTokens?: number;\n /** AI SDK tools to make available for the LLM */\n tools?: AIToolSet;\n /** Max tool-use roundtrips (default: 1 if tools provided, 0 otherwise) */\n maxToolSteps?: number;\n}\n\nexport interface GenerateWithMessagesOptions extends CallOptions {\n model: LanguageModel;\n system: string;\n messages: ModelMessage[];\n maxOutputTokens?: number;\n /** AI SDK tools to make available for the LLM */\n tools?: AIToolSet;\n /** Max tool-use roundtrips (default: 1 if tools provided, 0 otherwise) */\n maxToolSteps?: number;\n}\n\nexport interface GenerateResult {\n text: string;\n usage: { inputTokens: number; outputTokens: number; totalTokens: number };\n /** Tool calls made during generation (empty if no tools used) */\n toolCalls: ToolCallInfo[];\n /** Number of steps taken (1 = no tool calls, >1 = tool roundtrips) */\n steps: number;\n}\n\nfunction extractUsage(usage: { inputTokens?: number; outputTokens?: number } | undefined) {\n return {\n inputTokens: usage?.inputTokens ?? 0,\n outputTokens: usage?.outputTokens ?? 0,\n totalTokens: (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0),\n };\n}\n\nfunction buildCallSettings(opts: CallOptions & { tools?: AIToolSet; maxToolSteps?: number }) {\n const hasTools = opts.tools && Object.keys(opts.tools).length > 0;\n return {\n ...(opts.maxRetries !== undefined ? { maxRetries: opts.maxRetries } : {}),\n ...(opts.timeoutMs !== undefined ? { timeout: opts.timeoutMs } : {}),\n ...(opts.abortSignal ? { abortSignal: opts.abortSignal } : {}),\n ...(hasTools ? { tools: opts.tools } : {}),\n ...(hasTools ? { stopWhen: stepCountIs(opts.maxToolSteps ?? 5) } : {}),\n };\n}\n\n/** Extract tool call info from AI SDK step results */\nfunction extractToolCalls(result: { steps?: Array<{ toolCalls?: Array<{ toolName: string; input: unknown }>; toolResults?: Array<{ toolName: string; output: unknown }> }> }): ToolCallInfo[] {\n const calls: ToolCallInfo[] = [];\n if (!result.steps) return calls;\n\n for (const step of result.steps) {\n if (!step.toolCalls) continue;\n for (let i = 0; i < step.toolCalls.length; i++) {\n const tc = step.toolCalls[i];\n const tr = step.toolResults?.[i];\n calls.push({\n toolName: tc.toolName,\n args: (tc.input ?? {}) as Record<string, unknown>,\n result: tr?.output ?? null,\n });\n }\n }\n return calls;\n}\n\nexport async function generate(opts: GenerateOptions): Promise<GenerateResult> {\n const result = await generateText({\n model: opts.model,\n system: opts.system,\n prompt: opts.prompt,\n maxOutputTokens: opts.maxOutputTokens,\n ...buildCallSettings(opts),\n });\n\n // Use totalUsage when available (multi-step) otherwise fall back to usage\n const usage = result.totalUsage ?? result.usage;\n\n return {\n text: result.text,\n usage: extractUsage(usage),\n toolCalls: extractToolCalls(result),\n steps: result.steps?.length ?? 1,\n };\n}\n\nexport async function generateWithMessages(opts: GenerateWithMessagesOptions): Promise<GenerateResult> {\n const result = await generateText({\n model: opts.model,\n system: opts.system,\n messages: opts.messages,\n maxOutputTokens: opts.maxOutputTokens,\n ...buildCallSettings(opts),\n });\n\n const usage = result.totalUsage ?? result.usage;\n\n return {\n text: result.text,\n usage: extractUsage(usage),\n toolCalls: extractToolCalls(result),\n steps: result.steps?.length ?? 1,\n };\n}\n\n/**\n * @deprecated Use `streamGenerateWithDetails()` instead — returns metadata (usage, toolCalls, steps).\n */\nexport async function* streamGenerate(opts: GenerateOptions): AsyncIterable<string> {\n const result = streamText({\n model: opts.model,\n system: opts.system,\n prompt: opts.prompt,\n maxOutputTokens: opts.maxOutputTokens,\n ...buildCallSettings(opts),\n });\n\n for await (const chunk of result.textStream) {\n yield chunk;\n }\n}\n\nexport interface StreamWithMessagesResult {\n textStream: AsyncIterable<string>;\n usage: Promise<GenerateResult['usage']>;\n /** Tool calls made across all steps (resolves after stream completes) */\n toolCalls: Promise<ToolCallInfo[]>;\n /** Number of steps (resolves after stream completes) */\n steps: Promise<number>;\n}\n\nexport function streamWithMessages(opts: GenerateWithMessagesOptions): StreamWithMessagesResult {\n const result = streamText({\n model: opts.model,\n system: opts.system,\n messages: opts.messages,\n maxOutputTokens: opts.maxOutputTokens,\n ...buildCallSettings(opts),\n });\n\n const totalUsage = Promise.resolve(result.totalUsage ?? result.usage).then((u) => extractUsage(u));\n const toolCalls = Promise.resolve(result.steps).then((s) => extractToolCalls({ steps: s }));\n const steps = Promise.resolve(result.steps).then((s) => s?.length ?? 1);\n\n return {\n textStream: result.textStream,\n usage: totalUsage,\n toolCalls,\n steps,\n };\n}\n\nexport interface StreamGenerateResult {\n textStream: AsyncIterable<string>;\n usage: Promise<GenerateResult['usage']>;\n toolCalls: Promise<ToolCallInfo[]>;\n steps: Promise<number>;\n}\n\nexport function streamGenerateWithDetails(opts: GenerateOptions): StreamGenerateResult {\n const result = streamText({\n model: opts.model,\n system: opts.system,\n prompt: opts.prompt,\n maxOutputTokens: opts.maxOutputTokens,\n ...buildCallSettings(opts),\n });\n\n const totalUsage = Promise.resolve(result.totalUsage ?? result.usage).then((u) => extractUsage(u));\n const toolCalls = Promise.resolve(result.steps).then((s) => extractToolCalls({ steps: s }));\n const steps = Promise.resolve(result.steps).then((s) => s?.length ?? 1);\n\n return {\n textStream: result.textStream,\n usage: totalUsage,\n toolCalls,\n steps,\n };\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  getPrimitiveDirs
5
- } from "./chunk-4TQQZILG.js";
5
+ } from "./chunk-EXO47RET.js";
6
6
 
7
7
  // src/runtime/auto-processor.ts
8
8
  import { readFileSync, writeFileSync, existsSync, readdirSync } from "fs";
@@ -196,4 +196,4 @@ export {
196
196
  autoProcessFile,
197
197
  autoProcessAll
198
198
  };
199
- //# sourceMappingURL=chunk-NVC2WY4K.js.map
199
+ //# sourceMappingURL=chunk-WHRYPI2T.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  loadTools
5
- } from "./chunk-PMFAYKBD.js";
5
+ } from "./chunk-36W2VC3L.js";
6
6
  import {
7
7
  log
8
8
  } from "./chunk-BSKDOFRT.js";
@@ -226,4 +226,4 @@ export {
226
226
  createToolCallTracker,
227
227
  getToolSetSummary
228
228
  };
229
- //# sourceMappingURL=chunk-5CO5JTYT.js.map
229
+ //# sourceMappingURL=chunk-X47HHTNV.js.map
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  CORE_PRIMITIVE_DIRS,
5
5
  FrontmatterSchema
6
- } from "./chunk-4TQQZILG.js";
6
+ } from "./chunk-EXO47RET.js";
7
7
 
8
8
  // src/primitives/loader.ts
9
9
  import { readFileSync, readdirSync, existsSync } from "fs";
@@ -112,4 +112,4 @@ export {
112
112
  estimateTokens,
113
113
  getAtLevel
114
114
  };
115
- //# sourceMappingURL=chunk-2UVWCTAY.js.map
115
+ //# sourceMappingURL=chunk-XPEDVA35.js.map
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  buildToolSet
5
- } from "./chunk-5CO5JTYT.js";
5
+ } from "./chunk-X47HHTNV.js";
6
6
  import {
7
7
  createSessionId,
8
8
  writeSession
@@ -11,18 +11,20 @@ import {
11
11
  estimateTokens,
12
12
  getAtLevel,
13
13
  loadDirectory
14
- } from "./chunk-2UVWCTAY.js";
14
+ } from "./chunk-XPEDVA35.js";
15
15
  import {
16
16
  log
17
17
  } from "./chunk-BSKDOFRT.js";
18
18
  import {
19
19
  generate,
20
+ getFastModel,
20
21
  getModel,
22
+ getSummaryModel,
21
23
  streamGenerateWithDetails
22
- } from "./chunk-IZ6UZ3ZL.js";
24
+ } from "./chunk-WCYBFALM.js";
23
25
  import {
24
26
  loadConfig
25
- } from "./chunk-EC42HQQH.js";
27
+ } from "./chunk-44R2VV33.js";
26
28
 
27
29
  // src/runtime/delegate.ts
28
30
  import { existsSync, readFileSync } from "fs";
@@ -125,7 +127,29 @@ ${agentList}`
125
127
  }
126
128
  const config = loadConfig(harnessDir, opts.modelOverride ? { model: { id: opts.modelOverride } } : void 0);
127
129
  const systemPrompt = buildAgentPrompt(harnessDir, agentDoc, config);
128
- const model = getModel(config, apiKey);
130
+ const modelTier = agentDoc.frontmatter.model ?? "primary";
131
+ let model;
132
+ switch (modelTier) {
133
+ case "primary":
134
+ model = getModel(config, apiKey);
135
+ break;
136
+ case "summary":
137
+ model = getSummaryModel(config, apiKey);
138
+ log.debug(
139
+ `[delegate] agent "${agentDoc.frontmatter.id}" using summary model tier`
140
+ );
141
+ break;
142
+ case "fast":
143
+ model = getFastModel(config, apiKey);
144
+ log.debug(
145
+ `[delegate] agent "${agentDoc.frontmatter.id}" using fast model tier`
146
+ );
147
+ break;
148
+ default:
149
+ throw new Error(
150
+ `Agent "${agentDoc.frontmatter.id}" declares model: "${modelTier}" which is not valid. Allowed values: primary, summary, fast.`
151
+ );
152
+ }
129
153
  const toolSet = buildToolSet(harnessDir);
130
154
  const hasTools = Object.keys(toolSet).length > 0;
131
155
  return { agentDoc, config, systemPrompt, model, toolSet, hasTools };
@@ -239,4 +263,4 @@ export {
239
263
  delegateTo,
240
264
  delegateStream
241
265
  };
242
- //# sourceMappingURL=chunk-M62KLIEK.js.map
266
+ //# sourceMappingURL=chunk-XTV7HH5M.js.map