@agntk/agent-harness 0.1.4 → 0.1.6

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 (178) hide show
  1. package/README.md +104 -43
  2. package/dist/{analytics-RPT73WNM.js → analytics-L24W3B7U.js} +1 -2
  3. package/dist/auto-processor-QIRUOGEI.js +12 -0
  4. package/dist/{chunk-UPLBF4RZ.js → chunk-2UVWCTAY.js} +2 -2
  5. package/dist/{chunk-CSL3ERUI.js → chunk-4P6TRFPZ.js} +3 -3
  6. package/dist/chunk-4P6TRFPZ.js.map +1 -0
  7. package/dist/{chunk-4CWAGBNS.js → chunk-4TQQZILG.js} +73 -3
  8. package/dist/chunk-4TQQZILG.js.map +1 -0
  9. package/dist/{chunk-DA7IKHC4.js → chunk-5CO5JTYT.js} +2 -2
  10. package/dist/chunk-5CO5JTYT.js.map +1 -0
  11. package/dist/{chunk-A7BJPQQ6.js → chunk-5O5OGOOQ.js} +2 -2
  12. package/dist/{chunk-UWQTZMNI.js → chunk-7GZ4D6V6.js} +2 -2
  13. package/dist/{chunk-FLZU44SV.js → chunk-AN6Y4MDD.js} +6 -6
  14. package/dist/{chunk-4FDUOGSZ.js → chunk-D7AWV24Z.js} +3 -3
  15. package/dist/{chunk-CHJ5GNZC.js → chunk-EC42HQQH.js} +2 -2
  16. package/dist/{chunk-YIJY5DBV.js → chunk-KLYMGWQJ.js} +4 -4
  17. package/dist/chunk-KLYMGWQJ.js.map +1 -0
  18. package/dist/{chunk-YUFNYN2H.js → chunk-M62KLIEK.js} +4 -4
  19. package/dist/chunk-M62KLIEK.js.map +1 -0
  20. package/dist/{chunk-GJNNR2RA.js → chunk-M6PDMK2O.js} +3 -3
  21. package/dist/{chunk-M7NXUK55.js → chunk-NVC2WY4K.js} +2 -2
  22. package/dist/{chunk-XTBKL5BI.js → chunk-PMFAYKBD.js} +2 -2
  23. package/dist/chunk-PMFAYKBD.js.map +1 -0
  24. package/dist/{chunk-274RV3YO.js → chunk-QMOIVORH.js} +3 -3
  25. package/dist/chunk-QMOIVORH.js.map +1 -0
  26. package/dist/{chunk-RY3ZFII7.js → chunk-SEHAQTBO.js} +6 -6
  27. package/dist/{chunk-MPZ3BPUI.js → chunk-UMXPOYZR.js} +4 -4
  28. package/dist/{chunk-W4T7PGI2.js → chunk-UXCHAS3Z.js} +4 -4
  29. package/dist/cli/index.js +153 -167
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/config-PYSS3QY6.js +12 -0
  32. package/dist/context-loader-RSXXFW5R.js +12 -0
  33. package/dist/{conversation-QDEIDQPH.js → conversation-TBTFIJVU.js} +6 -7
  34. package/dist/{cost-tracker-RS3W7SVY.js → cost-tracker-NZRZEHVA.js} +1 -2
  35. package/dist/{delegate-VJCJLYEK.js → delegate-3KJAL4NZ.js} +7 -8
  36. package/dist/{emotional-state-VQVRA6ED.js → emotional-state-IN4ZUL2Q.js} +1 -2
  37. package/dist/{emotional-state-VQVRA6ED.js.map → emotional-state-IN4ZUL2Q.js.map} +1 -1
  38. package/dist/{env-discovery-2BLVMAIM.js → env-discovery-PXBRE5FX.js} +1 -2
  39. package/dist/{env-discovery-2BLVMAIM.js.map → env-discovery-PXBRE5FX.js.map} +1 -1
  40. package/dist/{export-6GCYHEHQ.js → export-GYLWROMB.js} +3 -4
  41. package/dist/{export-6GCYHEHQ.js.map → export-GYLWROMB.js.map} +1 -1
  42. package/dist/graph-LEEO37L3.js +13 -0
  43. package/dist/{harness-WE4SLCML.js → harness-R5FKRICG.js} +8 -9
  44. package/dist/{health-NZ6WNIMV.js → health-HL2JYHIY.js} +1 -2
  45. package/dist/indexer-L5UC6J2V.js +15 -0
  46. package/dist/{instinct-learner-SRM72DHF.js → instinct-learner-QGAMIS3X.js} +5 -6
  47. package/dist/{intake-4M3HNU43.js → intake-SVJKFHTL.js} +5 -6
  48. package/dist/{intelligence-HJOCA4SJ.js → intelligence-XPV3MC5U.js} +10 -13
  49. package/dist/intelligence-XPV3MC5U.js.map +1 -0
  50. package/dist/{journal-WANJL3MI.js → journal-ITUMKT6U.js} +5 -6
  51. package/dist/{loader-C3TKIKZR.js → loader-27PLDCOJ.js} +3 -4
  52. package/dist/{mcp-WTQJJZAO.js → mcp-JSIUJJZV.js} +1 -2
  53. package/dist/{mcp-discovery-WPAQFL6S.js → mcp-discovery-DG3RQYLM.js} +1 -2
  54. package/dist/{mcp-discovery-WPAQFL6S.js.map → mcp-discovery-DG3RQYLM.js.map} +1 -1
  55. package/dist/{mcp-installer-6O2XXD3V.js → mcp-installer-X2TJ2S2G.js} +3 -4
  56. package/dist/{mcp-installer-6O2XXD3V.js.map → mcp-installer-X2TJ2S2G.js.map} +1 -1
  57. package/dist/{metrics-KXGNFAAB.js → metrics-2MNINXNQ.js} +1 -2
  58. package/dist/{primitive-registry-I6VTIR4W.js → primitive-registry-ZMGGXSO5.js} +3 -4
  59. package/dist/{primitive-registry-I6VTIR4W.js.map → primitive-registry-ZMGGXSO5.js.map} +1 -1
  60. package/dist/{project-discovery-C4UMD7JI.js → project-discovery-FQLAZKEM.js} +1 -2
  61. package/dist/project-discovery-FQLAZKEM.js.map +1 -0
  62. package/dist/{provider-SXPQZ74H.js → provider-HQY6SPZI.js} +1 -2
  63. package/dist/{rate-limiter-RLRVM325.js → rate-limiter-PH5DCVU4.js} +1 -2
  64. package/dist/{rule-engine-YGQ3RYZM.js → rule-engine-DM26S77N.js} +3 -4
  65. package/dist/{rule-engine-YGQ3RYZM.js.map → rule-engine-DM26S77N.js.map} +1 -1
  66. package/dist/{scaffold-A3VRRCBV.js → scaffold-2F36YVW6.js} +5 -6
  67. package/dist/{scaffold-A3VRRCBV.js.map → scaffold-2F36YVW6.js.map} +1 -1
  68. package/dist/{scheduler-XHHIVHRI.js → scheduler-Q7GB2KCW.js} +11 -12
  69. package/dist/{scheduler-XHHIVHRI.js.map → scheduler-Q7GB2KCW.js.map} +1 -1
  70. package/dist/{search-V3W5JMJG.js → search-6Y6NCOLQ.js} +3 -4
  71. package/dist/search-6Y6NCOLQ.js.map +1 -0
  72. package/dist/{semantic-search-2DTOO5UX.js → semantic-search-FN6FZIXI.js} +3 -4
  73. package/dist/semantic-search-FN6FZIXI.js.map +1 -0
  74. package/dist/{serve-DTQ3HENY.js → serve-MXRTP2HE.js} +10 -11
  75. package/dist/serve-MXRTP2HE.js.map +1 -0
  76. package/dist/{sessions-CZGVXKQE.js → sessions-G6SZZXWS.js} +1 -2
  77. package/dist/{sources-RW5DT56F.js → sources-7LDYO5GK.js} +1 -2
  78. package/dist/{starter-packs-76YUVHEU.js → starter-packs-OR7NI5NA.js} +1 -2
  79. package/dist/{starter-packs-76YUVHEU.js.map → starter-packs-OR7NI5NA.js.map} +1 -1
  80. package/dist/{state-GMXILIHW.js → state-25IQEC5C.js} +1 -2
  81. package/dist/{state-merge-NKO5FRBA.js → state-merge-E333OEIQ.js} +1 -2
  82. package/dist/{state-merge-NKO5FRBA.js.map → state-merge-E333OEIQ.js.map} +1 -1
  83. package/dist/{telemetry-UC6PBXC7.js → telemetry-RS2JZUZP.js} +4 -5
  84. package/dist/{tool-executor-MJ7IG7PQ.js → tool-executor-6I5PHQDY.js} +5 -6
  85. package/dist/{tools-DZ4KETET.js → tools-NDFJNVHK.js} +4 -5
  86. package/dist/{types-EW7AIB3R.js → types-NPJZAI72.js} +2 -3
  87. package/dist/{universal-installer-AAXXYM5A.js → universal-installer-LCAZHFZR.js} +91 -7
  88. package/dist/universal-installer-LCAZHFZR.js.map +1 -0
  89. package/dist/validator-LM7RZWSH.js +21 -0
  90. package/dist/{verification-gate-FYXUX6LH.js → verification-gate-2O6DF2B7.js} +3 -4
  91. package/dist/verification-gate-2O6DF2B7.js.map +1 -0
  92. package/dist/{versioning-Z3XNE2Q2.js → versioning-WEGF6KJG.js} +1 -2
  93. package/dist/versioning-WEGF6KJG.js.map +1 -0
  94. package/dist/{watcher-ISJC7YKL.js → watcher-GZWQSWZ6.js} +5 -6
  95. package/dist/{watcher-ISJC7YKL.js.map → watcher-GZWQSWZ6.js.map} +1 -1
  96. package/dist/{web-server-DD7ZOP46.js → web-server-2Y4CHD2W.js} +8 -9
  97. package/package.json +1 -9
  98. package/dist/agent-framework-K4GUIICH.js +0 -344
  99. package/dist/agent-framework-K4GUIICH.js.map +0 -1
  100. package/dist/auto-processor-OLE45UI3.js +0 -13
  101. package/dist/chunk-274RV3YO.js.map +0 -1
  102. package/dist/chunk-4CWAGBNS.js.map +0 -1
  103. package/dist/chunk-CSL3ERUI.js.map +0 -1
  104. package/dist/chunk-DA7IKHC4.js.map +0 -1
  105. package/dist/chunk-DGUM43GV.js +0 -11
  106. package/dist/chunk-FD55B3IO.js +0 -204
  107. package/dist/chunk-FD55B3IO.js.map +0 -1
  108. package/dist/chunk-GUJTBGVS.js +0 -2212
  109. package/dist/chunk-GUJTBGVS.js.map +0 -1
  110. package/dist/chunk-KFX54TQM.js +0 -165
  111. package/dist/chunk-KFX54TQM.js.map +0 -1
  112. package/dist/chunk-XTBKL5BI.js.map +0 -1
  113. package/dist/chunk-YIJY5DBV.js.map +0 -1
  114. package/dist/chunk-YUFNYN2H.js.map +0 -1
  115. package/dist/chunk-ZZJOFKAT.js +0 -13
  116. package/dist/config-WVMRUOCA.js +0 -13
  117. package/dist/context-loader-3ORBPMHJ.js +0 -13
  118. package/dist/graph-YUIPOSOO.js +0 -14
  119. package/dist/harness-LCHA3DWP.js +0 -10
  120. package/dist/index.d.ts +0 -3612
  121. package/dist/index.js +0 -13713
  122. package/dist/index.js.map +0 -1
  123. package/dist/indexer-LONANRRM.js +0 -16
  124. package/dist/intelligence-HJOCA4SJ.js.map +0 -1
  125. package/dist/project-discovery-C4UMD7JI.js.map +0 -1
  126. package/dist/provider-LQHQX7Z7.js +0 -26
  127. package/dist/search-V3W5JMJG.js.map +0 -1
  128. package/dist/semantic-search-2DTOO5UX.js.map +0 -1
  129. package/dist/serve-DTQ3HENY.js.map +0 -1
  130. package/dist/tools-DZ4KETET.js.map +0 -1
  131. package/dist/types-EW7AIB3R.js.map +0 -1
  132. package/dist/types-WGDLSPO6.js +0 -16
  133. package/dist/types-WGDLSPO6.js.map +0 -1
  134. package/dist/universal-installer-AAXXYM5A.js.map +0 -1
  135. package/dist/validator-7WXMDIHH.js +0 -22
  136. package/dist/validator-7WXMDIHH.js.map +0 -1
  137. package/dist/verification-gate-FYXUX6LH.js.map +0 -1
  138. package/dist/versioning-Z3XNE2Q2.js.map +0 -1
  139. package/dist/web-server-DD7ZOP46.js.map +0 -1
  140. /package/dist/{analytics-RPT73WNM.js.map → analytics-L24W3B7U.js.map} +0 -0
  141. /package/dist/{auto-processor-OLE45UI3.js.map → auto-processor-QIRUOGEI.js.map} +0 -0
  142. /package/dist/{chunk-UPLBF4RZ.js.map → chunk-2UVWCTAY.js.map} +0 -0
  143. /package/dist/{chunk-A7BJPQQ6.js.map → chunk-5O5OGOOQ.js.map} +0 -0
  144. /package/dist/{chunk-UWQTZMNI.js.map → chunk-7GZ4D6V6.js.map} +0 -0
  145. /package/dist/{chunk-FLZU44SV.js.map → chunk-AN6Y4MDD.js.map} +0 -0
  146. /package/dist/{chunk-4FDUOGSZ.js.map → chunk-D7AWV24Z.js.map} +0 -0
  147. /package/dist/{chunk-CHJ5GNZC.js.map → chunk-EC42HQQH.js.map} +0 -0
  148. /package/dist/{chunk-GJNNR2RA.js.map → chunk-M6PDMK2O.js.map} +0 -0
  149. /package/dist/{chunk-M7NXUK55.js.map → chunk-NVC2WY4K.js.map} +0 -0
  150. /package/dist/{chunk-RY3ZFII7.js.map → chunk-SEHAQTBO.js.map} +0 -0
  151. /package/dist/{chunk-MPZ3BPUI.js.map → chunk-UMXPOYZR.js.map} +0 -0
  152. /package/dist/{chunk-W4T7PGI2.js.map → chunk-UXCHAS3Z.js.map} +0 -0
  153. /package/dist/{chunk-DGUM43GV.js.map → config-PYSS3QY6.js.map} +0 -0
  154. /package/dist/{chunk-ZZJOFKAT.js.map → context-loader-RSXXFW5R.js.map} +0 -0
  155. /package/dist/{config-WVMRUOCA.js.map → conversation-TBTFIJVU.js.map} +0 -0
  156. /package/dist/{context-loader-3ORBPMHJ.js.map → cost-tracker-NZRZEHVA.js.map} +0 -0
  157. /package/dist/{conversation-QDEIDQPH.js.map → delegate-3KJAL4NZ.js.map} +0 -0
  158. /package/dist/{cost-tracker-RS3W7SVY.js.map → graph-LEEO37L3.js.map} +0 -0
  159. /package/dist/{delegate-VJCJLYEK.js.map → harness-R5FKRICG.js.map} +0 -0
  160. /package/dist/{graph-YUIPOSOO.js.map → health-HL2JYHIY.js.map} +0 -0
  161. /package/dist/{harness-LCHA3DWP.js.map → indexer-L5UC6J2V.js.map} +0 -0
  162. /package/dist/{harness-WE4SLCML.js.map → instinct-learner-QGAMIS3X.js.map} +0 -0
  163. /package/dist/{health-NZ6WNIMV.js.map → intake-SVJKFHTL.js.map} +0 -0
  164. /package/dist/{indexer-LONANRRM.js.map → journal-ITUMKT6U.js.map} +0 -0
  165. /package/dist/{instinct-learner-SRM72DHF.js.map → loader-27PLDCOJ.js.map} +0 -0
  166. /package/dist/{intake-4M3HNU43.js.map → mcp-JSIUJJZV.js.map} +0 -0
  167. /package/dist/{journal-WANJL3MI.js.map → metrics-2MNINXNQ.js.map} +0 -0
  168. /package/dist/{loader-C3TKIKZR.js.map → provider-HQY6SPZI.js.map} +0 -0
  169. /package/dist/{mcp-WTQJJZAO.js.map → rate-limiter-PH5DCVU4.js.map} +0 -0
  170. /package/dist/{metrics-KXGNFAAB.js.map → sessions-G6SZZXWS.js.map} +0 -0
  171. /package/dist/{provider-LQHQX7Z7.js.map → sources-7LDYO5GK.js.map} +0 -0
  172. /package/dist/{provider-SXPQZ74H.js.map → state-25IQEC5C.js.map} +0 -0
  173. /package/dist/{rate-limiter-RLRVM325.js.map → telemetry-RS2JZUZP.js.map} +0 -0
  174. /package/dist/{sessions-CZGVXKQE.js.map → tool-executor-6I5PHQDY.js.map} +0 -0
  175. /package/dist/{sources-RW5DT56F.js.map → tools-NDFJNVHK.js.map} +0 -0
  176. /package/dist/{state-GMXILIHW.js.map → types-NPJZAI72.js.map} +0 -0
  177. /package/dist/{telemetry-UC6PBXC7.js.map → validator-LM7RZWSH.js.map} +0 -0
  178. /package/dist/{tool-executor-MJ7IG7PQ.js.map → web-server-2Y4CHD2W.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/types.ts"],"sourcesContent":["import { z } from 'zod';\n\n// --- Frontmatter ---\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});\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}).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};\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":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/journal.ts"],"sourcesContent":["import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { parseHarnessDocument } from '../primitives/loader.js';\nimport { getModel, generate } from '../llm/provider.js';\nimport { loadConfig } from '../core/config.js';\nimport type { HarnessConfig, HarnessDocument } from '../core/types.js';\n\nexport interface JournalSynthesis {\n summary: string;\n insights: string[];\n instinct_candidates: string[];\n knowledge_updates: string[];\n}\n\nexport interface JournalEntry {\n date: string;\n sessions: HarnessDocument[];\n synthesis: string;\n structured: JournalSynthesis;\n instinct_candidates: string[];\n tokens_used: number;\n}\n\nexport async function synthesizeJournal(\n harnessDir: string,\n date?: string,\n apiKey?: string,\n): Promise<JournalEntry> {\n const targetDate = date || new Date().toISOString().split('T')[0];\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n const journalDir = join(harnessDir, 'memory', 'journal');\n\n if (!existsSync(journalDir)) {\n mkdirSync(journalDir, { recursive: true });\n }\n\n // Load sessions for this date\n const sessions: HarnessDocument[] = [];\n if (existsSync(sessionsDir)) {\n const files = readdirSync(sessionsDir).filter(\n (f) => f.endsWith('.md') && f.startsWith(targetDate),\n );\n\n for (const file of files) {\n try {\n const doc = parseHarnessDocument(join(sessionsDir, file));\n sessions.push(doc);\n } catch {\n // Skip unparseable\n }\n }\n }\n\n if (sessions.length === 0) {\n return {\n date: targetDate,\n sessions: [],\n synthesis: 'No sessions recorded today.',\n structured: {\n summary: 'No sessions recorded today.',\n insights: [],\n instinct_candidates: [],\n knowledge_updates: [],\n },\n instinct_candidates: [],\n tokens_used: 0,\n };\n }\n\n // Build synthesis prompt\n const sessionSummaries = sessions\n .map((s, i) => {\n const prompt = s.body.match(/## Prompt\\n([\\s\\S]*?)(?=\\n## |$)/)?.[1]?.trim() || '';\n const summary = s.body.match(/## Summary\\n([\\s\\S]*?)(?=\\n## |$)/)?.[1]?.trim() || '';\n return `Session ${i + 1}:\\n Prompt: ${prompt}\\n Summary: ${summary}`;\n })\n .join('\\n\\n');\n\n const synthesisPrompt = `You are synthesizing today's agent sessions into a structured journal entry.\n\nSessions from ${targetDate}:\n\n${sessionSummaries}\n\nWrite a journal entry with these EXACT sections (use the exact headers shown):\n\n## Summary\n2-3 sentence synthesis of what happened today.\n\n## Insights\nBullet points (starting with \"- \") of patterns, recurring themes, or notable observations.\n\n## Instinct Candidates\nBullet points (starting with \"- INSTINCT: \") of behaviors that should become reflexive rules.\n\n## Knowledge Updates\nBullet points (starting with \"- \") of new facts, corrections, or learnings that should be remembered.`;\n\n const config = loadConfig(harnessDir);\n const model = getModel(config, apiKey);\n\n const result = await generate({\n model,\n system: 'You are a reflective journal synthesizer. Be concise and insightful. Follow the output format exactly.',\n prompt: synthesisPrompt,\n });\n\n // Parse structured sections from the response\n const structured = parseJournalSynthesis(result.text);\n\n // Write journal entry\n const journalPath = join(journalDir, `${targetDate}.md`);\n const journalContent = `---\nid: journal-${targetDate}\ntags: [journal, daily]\ncreated: ${targetDate}\nupdated: ${new Date().toISOString().split('T')[0]}\nauthor: infrastructure\nstatus: active\n---\n\n<!-- L0: Journal for ${targetDate} — ${sessions.length} sessions synthesized. -->\n<!-- L1: ${structured.summary.slice(0, 200)} -->\n\n# Journal: ${targetDate}\n\n**Sessions:** ${sessions.length}\n**Tokens used:** ${result.usage.totalTokens}\n\n${result.text}\n`;\n\n writeFileSync(journalPath, journalContent, 'utf-8');\n\n return {\n date: targetDate,\n sessions,\n synthesis: result.text,\n structured,\n instinct_candidates: structured.instinct_candidates,\n tokens_used: result.usage.totalTokens,\n };\n}\n\n/**\n * Parse a journal synthesis response into structured sections.\n * Resilient to missing sections — returns empty arrays/strings for missing parts.\n */\nexport function parseJournalSynthesis(text: string): JournalSynthesis {\n const sectionRegex = /## (Summary|Insights|Instinct Candidates|Knowledge Updates|Patterns)\\n([\\s\\S]*?)(?=\\n## |\\n*$)/g;\n const sections = new Map<string, string>();\n\n for (const match of text.matchAll(sectionRegex)) {\n sections.set(match[1].toLowerCase(), match[2].trim());\n }\n\n const extractBullets = (content: string | undefined): string[] => {\n if (!content) return [];\n return content\n .split('\\n')\n .filter((line) => line.startsWith('- '))\n .map((line) => line.slice(2).trim())\n .filter(Boolean);\n };\n\n const summary = sections.get('summary') ?? '';\n\n // \"Insights\" or legacy \"Patterns\" section\n const insightsRaw = sections.get('insights') ?? sections.get('patterns') ?? '';\n const insights = extractBullets(insightsRaw);\n\n // Extract instinct candidates, stripping \"INSTINCT:\" prefix\n const instinctRaw = sections.get('instinct candidates') ?? '';\n const instinct_candidates = extractBullets(instinctRaw).map((line) =>\n line.replace(/^INSTINCT:\\s*/i, ''),\n );\n\n const knowledgeRaw = sections.get('knowledge updates') ?? '';\n const knowledge_updates = extractBullets(knowledgeRaw);\n\n return { summary, insights, instinct_candidates, knowledge_updates };\n}\n\n/**\n * Synthesize journals for a date range.\n * Processes each date that has sessions, skipping dates already journaled unless force is set.\n */\nexport async function synthesizeJournalRange(\n harnessDir: string,\n options: { from?: string; to?: string; all?: boolean; force?: boolean; apiKey?: string },\n): Promise<JournalEntry[]> {\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (!existsSync(sessionsDir)) return [];\n\n // Collect all unique dates from session filenames\n const files = readdirSync(sessionsDir).filter(\n (f) => f.endsWith('.md') && !f.startsWith('.') && !f.startsWith('_'),\n );\n const dateSet = new Set<string>();\n for (const file of files) {\n const match = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (match) dateSet.add(match[1]);\n }\n\n let dates = [...dateSet].sort();\n\n // Apply range filters\n if (!options.all) {\n const from = options.from;\n const to = options.to || new Date().toISOString().split('T')[0];\n if (from) {\n dates = dates.filter((d) => d >= from && d <= to);\n }\n }\n\n if (dates.length === 0) return [];\n\n // Check which dates already have journals\n const journalDir = join(harnessDir, 'memory', 'journal');\n const existingJournals = new Set<string>();\n if (existsSync(journalDir)) {\n for (const jf of readdirSync(journalDir)) {\n const match = jf.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (match) existingJournals.add(match[1]);\n }\n }\n\n const entries: JournalEntry[] = [];\n for (const date of dates) {\n if (!options.force && existingJournals.has(date)) continue;\n\n const entry = await synthesizeJournal(harnessDir, date, options.apiKey);\n entries.push(entry);\n }\n\n return entries;\n}\n\n/**\n * List dates that have sessions but no journal entry.\n */\nexport function listUnjournaled(harnessDir: string): string[] {\n const sessionsDir = join(harnessDir, 'memory', 'sessions');\n if (!existsSync(sessionsDir)) return [];\n\n const sessionDates = new Set<string>();\n for (const file of readdirSync(sessionsDir)) {\n if (!file.endsWith('.md') || file.startsWith('.')) continue;\n const match = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (match) sessionDates.add(match[1]);\n }\n\n const journalDir = join(harnessDir, 'memory', 'journal');\n const journalDates = new Set<string>();\n if (existsSync(journalDir)) {\n for (const file of readdirSync(journalDir)) {\n const match = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (match) journalDates.add(match[1]);\n }\n }\n\n return [...sessionDates].filter((d) => !journalDates.has(d)).sort();\n}\n\nexport function listJournals(harnessDir: string): string[] {\n const journalDir = join(harnessDir, 'memory', 'journal');\n if (!existsSync(journalDir)) return [];\n\n return readdirSync(journalDir)\n .filter((f) => f.endsWith('.md') && !f.startsWith('.'))\n .sort()\n .reverse();\n}\n\nexport interface WeekSummary {\n weekStart: string;\n weekEnd: string;\n journalDates: string[];\n summary: string;\n allInsights: string[];\n allInstinctCandidates: string[];\n allKnowledgeUpdates: string[];\n filePath: string;\n}\n\n/**\n * Get the Monday of the ISO week for a given date string (YYYY-MM-DD).\n */\nfunction getWeekStart(dateStr: string): string {\n const date = new Date(dateStr + 'T12:00:00Z');\n const day = date.getUTCDay();\n const diff = day === 0 ? 6 : day - 1;\n date.setUTCDate(date.getUTCDate() - diff);\n return date.toISOString().split('T')[0];\n}\n\n/**\n * Get the Sunday of the ISO week for a given date string.\n */\nfunction getWeekEnd(dateStr: string): string {\n const start = new Date(getWeekStart(dateStr) + 'T12:00:00Z');\n start.setUTCDate(start.getUTCDate() + 6);\n return start.toISOString().split('T')[0];\n}\n\n/**\n * Compress daily journals into weekly roll-up summaries.\n * Groups journals by ISO week, aggregates structured sections, writes\n * weekly summary files to memory/journal/weekly/. Pure file-based — no LLM calls.\n *\n * Returns only weeks that were newly created (skips existing unless force=true).\n */\nexport function compressJournals(\n harnessDir: string,\n options?: { force?: boolean },\n): WeekSummary[] {\n const journalDir = join(harnessDir, 'memory', 'journal');\n if (!existsSync(journalDir)) return [];\n\n const weeklyDir = join(journalDir, 'weekly');\n if (!existsSync(weeklyDir)) {\n mkdirSync(weeklyDir, { recursive: true });\n }\n\n // Load all daily journals\n const files = readdirSync(journalDir)\n .filter((f) => f.endsWith('.md') && !f.startsWith('.') && !f.startsWith('_'))\n .sort();\n\n // Group by week\n const weeks = new Map<string, string[]>();\n for (const file of files) {\n const dateMatch = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (!dateMatch) continue;\n const weekStart = getWeekStart(dateMatch[1]);\n if (!weeks.has(weekStart)) weeks.set(weekStart, []);\n weeks.get(weekStart)!.push(file);\n }\n\n const results: WeekSummary[] = [];\n\n for (const [weekStart, journalFiles] of weeks) {\n const weekEnd = getWeekEnd(weekStart);\n const weeklyFile = join(weeklyDir, `${weekStart}.md`);\n\n // Skip existing unless force\n if (!options?.force && existsSync(weeklyFile)) continue;\n\n // Only compress complete past weeks (not the current week)\n const today = new Date().toISOString().split('T')[0];\n const currentWeekStart = getWeekStart(today);\n if (weekStart === currentWeekStart) continue;\n\n // Aggregate structured sections from each journal\n const allSummaries: string[] = [];\n const allInsights: string[] = [];\n const allInstinctCandidates: string[] = [];\n const allKnowledgeUpdates: string[] = [];\n const journalDates: string[] = [];\n\n for (const file of journalFiles) {\n const content = readFileSync(join(journalDir, file), 'utf-8');\n const dateMatch = file.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) journalDates.push(dateMatch[1]);\n\n const structured = parseJournalSynthesis(content);\n if (structured.summary) allSummaries.push(`**${dateMatch?.[1]}:** ${structured.summary}`);\n allInsights.push(...structured.insights);\n allInstinctCandidates.push(...structured.instinct_candidates);\n allKnowledgeUpdates.push(...structured.knowledge_updates);\n }\n\n // Deduplicate\n const uniqueInsights = [...new Set(allInsights)];\n const uniqueInstincts = [...new Set(allInstinctCandidates)];\n const uniqueKnowledge = [...new Set(allKnowledgeUpdates)];\n\n const weekSummary = allSummaries.join('\\n\\n');\n const insightsBullets = uniqueInsights.map((i) => `- ${i}`).join('\\n');\n const instinctBullets = uniqueInstincts.map((i) => `- INSTINCT: ${i}`).join('\\n');\n const knowledgeBullets = uniqueKnowledge.map((k) => `- ${k}`).join('\\n');\n\n const weeklyContent = `---\nid: weekly-${weekStart}\ntags: [journal, weekly]\ncreated: ${weekStart}\nupdated: ${new Date().toISOString().split('T')[0]}\nauthor: infrastructure\nstatus: active\n---\n\n<!-- L0: Weekly journal roll-up ${weekStart} to ${weekEnd} (${journalDates.length} days) -->\n<!-- L1: ${allSummaries[0]?.slice(0, 200) || 'No summaries available'} -->\n\n# Weekly Journal: ${weekStart} to ${weekEnd}\n\n**Days journaled:** ${journalDates.length}\n**Dates:** ${journalDates.join(', ')}\n\n## Summary\n${weekSummary || 'No daily summaries available.'}\n\n## Insights\n${insightsBullets || '(none)'}\n\n## Instinct Candidates\n${instinctBullets || '(none)'}\n\n## Knowledge Updates\n${knowledgeBullets || '(none)'}\n`;\n\n writeFileSync(weeklyFile, weeklyContent, 'utf-8');\n\n results.push({\n weekStart,\n weekEnd,\n journalDates,\n summary: weekSummary,\n allInsights: uniqueInsights,\n allInstinctCandidates: uniqueInstincts,\n allKnowledgeUpdates: uniqueKnowledge,\n filePath: weeklyFile,\n });\n }\n\n return results;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/tool-executor.ts"],"sourcesContent":["import { tool as aiTool, jsonSchema, type ToolSet } from 'ai';\nimport { z } from 'zod';\nimport { loadTools, type ToolDefinition, type ToolOperation } from './tools.js';\nimport type { HarnessConfig } from '../core/types.js';\nimport { log } from '../core/logger.js';\n\n// --- Types ---\n\n/** Result of a single tool execution */\nexport interface ToolCallResult {\n toolName: string;\n input: Record<string, unknown>;\n output: unknown;\n durationMs: number;\n error: string | null;\n}\n\n/** Record of all tool calls in a run (for session recording) */\nexport interface ToolCallRecord {\n calls: ToolCallResult[];\n totalDurationMs: number;\n}\n\n/** A programmatic tool definition (not from markdown) */\nexport interface ProgrammaticTool {\n name: string;\n description: string;\n inputSchema: z.ZodType;\n execute: (input: Record<string, unknown>) => Promise<unknown>;\n}\n\n/** Configuration for tool execution */\nexport interface ToolExecutorConfig {\n /** Maximum tool calls per run (default: 10) */\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 /** Additional programmatic tools */\n tools?: ProgrammaticTool[];\n}\n\n/** AI SDK ToolSet — record of named tool definitions */\nexport type AIToolSet = ToolSet;\n\n// --- HTTP Execution ---\n\n/**\n * Resolve a URL template by replacing `{param}` placeholders with input values.\n * E.g., `/repos/{owner}/{repo}/pulls` with { owner: 'a', repo: 'b' } → `/repos/a/b/pulls`\n */\nexport function resolveEndpoint(endpoint: string, input: Record<string, unknown>): string {\n return endpoint.replace(/\\{(\\w+)\\}/g, (_match, key: string) => {\n const value = input[key];\n if (value === undefined || value === null) {\n return `{${key}}`;\n }\n return encodeURIComponent(String(value));\n });\n}\n\n/**\n * Build a JSON Schema object for a tool operation's URL parameters.\n * Extracts `{param}` patterns from the endpoint URL and creates string properties for each.\n */\nexport function buildOperationSchema(operation: ToolOperation): Record<string, unknown> {\n const params: string[] = [];\n const paramRegex = /\\{(\\w+)\\}/g;\n let match: RegExpExecArray | null;\n while ((match = paramRegex.exec(operation.endpoint)) !== null) {\n params.push(match[1]);\n }\n\n const properties: Record<string, { type: string; description: string }> = {};\n for (const param of params) {\n properties[param] = { type: 'string', description: `Value for ${param}` };\n }\n\n // Add a body property for POST/PUT/PATCH\n if (['POST', 'PUT', 'PATCH'].includes(operation.method)) {\n properties['body'] = { type: 'string', description: 'Request body (JSON string)' };\n }\n\n // Add optional query parameters\n properties['query'] = { type: 'string', description: 'Query parameters (key=value&key2=value2)' };\n\n return {\n type: 'object',\n properties,\n required: params,\n };\n}\n\n/**\n * Execute an HTTP tool operation.\n * Resolves URL parameters, attaches auth headers, and makes the HTTP request.\n */\nexport async function executeHttpOperation(\n operation: ToolOperation,\n baseUrl: string,\n authHeaders: Record<string, string>,\n input: Record<string, unknown>,\n timeoutMs: number,\n): Promise<unknown> {\n const resolvedPath = resolveEndpoint(operation.endpoint, input);\n let url = resolvedPath.startsWith('http') ? resolvedPath : `${baseUrl}${resolvedPath}`;\n\n // Append query parameters if provided\n const query = input['query'];\n if (typeof query === 'string' && query.length > 0) {\n const separator = url.includes('?') ? '&' : '?';\n url = `${url}${separator}${query}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...authHeaders,\n };\n\n const fetchOptions: RequestInit = {\n method: operation.method,\n headers,\n signal: AbortSignal.timeout(timeoutMs),\n };\n\n // Attach body for methods that support it\n if (['POST', 'PUT', 'PATCH'].includes(operation.method)) {\n const body = input['body'];\n if (typeof body === 'string') {\n fetchOptions.body = body;\n } else if (body !== undefined && body !== null) {\n fetchOptions.body = JSON.stringify(body);\n }\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(`HTTP ${response.status} ${response.statusText}: ${errorText.slice(0, 500)}`);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n return response.json() as Promise<unknown>;\n }\n return response.text();\n}\n\n// --- Tool Conversion ---\n\n/**\n * Sanitize a tool name for the AI SDK.\n * Tool names must be alphanumeric with underscores/hyphens only.\n */\nfunction sanitizeToolName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '')\n .slice(0, 64);\n}\n\n/**\n * Extract a base URL from the tool's operations or body.\n * Looks for full URLs in operations, or common API URL patterns in the body.\n */\nfunction extractBaseUrl(toolDef: ToolDefinition): string {\n // Check operations for full URLs\n for (const op of toolDef.operations) {\n if (op.endpoint.startsWith('http')) {\n try {\n const url = new URL(op.endpoint);\n return `${url.protocol}//${url.host}`;\n } catch {\n // not a valid URL\n }\n }\n }\n\n // Try to find API base URL in the document body\n const urlMatch = toolDef.doc.body.match(/(?:base[_ ]?url|api[_ ]?url|endpoint)\\s*[:=]\\s*`?(https?:\\/\\/[^\\s`\"']+)/i);\n if (urlMatch) {\n try {\n const url = new URL(urlMatch[1]);\n return `${url.protocol}//${url.host}`;\n } catch {\n // not a valid URL\n }\n }\n\n return '';\n}\n\n/**\n * Build auth headers from a tool's auth configuration.\n * Maps known env var patterns to standard header formats.\n */\nexport function buildAuthHeaders(toolDef: ToolDefinition): Record<string, string> {\n const headers: Record<string, string> = {};\n\n for (const auth of toolDef.auth) {\n const value = process.env[auth.envVar];\n if (!value) continue;\n\n // Common patterns for auth header mapping (check specific patterns first)\n const envLower = auth.envVar.toLowerCase();\n if (envLower.includes('bot_token')) {\n headers['Authorization'] = `Bot ${value}`;\n } else if (envLower.includes('token') || envLower.includes('api_key') || envLower.includes('apikey')) {\n headers['Authorization'] = `Bearer ${value}`;\n } else {\n // Generic: use as Bearer token\n headers['Authorization'] = `Bearer ${value}`;\n }\n }\n\n return headers;\n}\n\n/**\n * Convert a single ToolDefinition (from markdown) into AI SDK tools.\n * Each operation becomes a separate tool entry.\n */\nexport function convertToolDefinition(\n toolDef: ToolDefinition,\n config: ToolExecutorConfig,\n): AIToolSet {\n const tools: AIToolSet = {};\n const baseUrl = extractBaseUrl(toolDef);\n const allowHttp = config.allowHttpExecution !== false;\n const timeoutMs = config.toolTimeoutMs ?? 30_000;\n\n for (const operation of toolDef.operations) {\n const toolName = sanitizeToolName(`${toolDef.id}_${operation.name}`);\n const opSchema = buildOperationSchema(operation);\n\n tools[toolName] = aiTool({\n description: `[${toolDef.id}] ${operation.method} ${operation.endpoint} — ${toolDef.doc.l0}`,\n inputSchema: jsonSchema<Record<string, unknown>>(opSchema),\n execute: async (input) => {\n const typedInput = input;\n\n if (!allowHttp) {\n return { error: 'HTTP tool execution is disabled' };\n }\n\n // Check auth\n const missingAuth = toolDef.auth.filter((a) => !process.env[a.envVar]);\n if (missingAuth.length > 0) {\n return {\n error: `Missing required auth: ${missingAuth.map((a) => a.envVar).join(', ')}`,\n };\n }\n\n const authHeaders = buildAuthHeaders(toolDef);\n\n try {\n const result = await executeHttpOperation(\n operation,\n baseUrl,\n authHeaders,\n typedInput,\n timeoutMs,\n );\n return result;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.error(`Tool ${toolName} execution failed: ${message}`);\n return { error: message };\n }\n },\n });\n }\n\n return tools;\n}\n\n/**\n * Convert a programmatic tool definition into an AI SDK tool.\n */\nfunction convertProgrammaticTool(pt: ProgrammaticTool): AIToolSet {\n const toolName = sanitizeToolName(pt.name);\n\n return {\n [toolName]: aiTool({\n description: pt.description,\n inputSchema: pt.inputSchema,\n execute: async (input: unknown) => {\n try {\n return await pt.execute(input as Record<string, unknown>);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log.error(`Tool ${toolName} execution failed: ${message}`);\n return { error: message };\n }\n },\n }),\n };\n}\n\n// --- Public API ---\n\n/**\n * Load all tools from the harness directory and convert them to AI SDK format.\n * Includes markdown-defined tools, programmatic tools from config, and MCP tools.\n *\n * Returns an empty object if no tools are configured.\n *\n * @param harnessDir - Path to the harness directory\n * @param config - Tool executor configuration\n * @param mcpTools - Pre-loaded MCP tools to merge (from McpManager.getTools())\n */\nexport function buildToolSet(\n harnessDir: string,\n config?: ToolExecutorConfig,\n mcpTools?: AIToolSet,\n): AIToolSet {\n const executorConfig = config ?? {};\n const tools: AIToolSet = {};\n\n // Load markdown-defined tools\n const toolDefs = loadTools(harnessDir);\n for (const toolDef of toolDefs) {\n // Skip inactive tools\n if (toolDef.status !== 'active') continue;\n\n // Skip tools without operations\n if (toolDef.operations.length === 0) continue;\n\n const converted = convertToolDefinition(toolDef, executorConfig);\n Object.assign(tools, converted);\n }\n\n // Add programmatic tools\n if (executorConfig.tools) {\n for (const pt of executorConfig.tools) {\n const converted = convertProgrammaticTool(pt);\n Object.assign(tools, converted);\n }\n }\n\n // Merge MCP tools (from connected MCP servers)\n if (mcpTools) {\n Object.assign(tools, mcpTools);\n }\n\n return tools;\n}\n\n/**\n * Create a ToolCallRecord tracker for recording tool calls in a run.\n */\nexport function createToolCallTracker(): {\n record: (result: ToolCallResult) => void;\n getRecord: () => ToolCallRecord;\n} {\n const calls: ToolCallResult[] = [];\n let totalDurationMs = 0;\n\n return {\n record(result: ToolCallResult) {\n calls.push(result);\n totalDurationMs += result.durationMs;\n },\n getRecord(): ToolCallRecord {\n return { calls: [...calls], totalDurationMs };\n },\n };\n}\n\n/**\n * Get a human-readable summary of tools available in the harness.\n */\nexport function getToolSetSummary(tools: AIToolSet): string[] {\n return Object.entries(tools).map(([name, t]) => {\n const desc = (t as { description?: string }).description ?? '';\n return `${name}: ${desc}`;\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- export {
9
- __require
10
- };
11
- //# sourceMappingURL=chunk-DGUM43GV.js.map
@@ -1,204 +0,0 @@
1
- // src/llm/provider.ts
2
- import { createOpenRouter } from "@openrouter/ai-sdk-provider";
3
- import { createAnthropic } from "@ai-sdk/anthropic";
4
- import { createOpenAI } from "@ai-sdk/openai";
5
- import { generateText, streamText, stepCountIs } from "ai";
6
- var ENV_KEYS = {
7
- openrouter: "OPENROUTER_API_KEY",
8
- anthropic: "ANTHROPIC_API_KEY",
9
- openai: "OPENAI_API_KEY"
10
- };
11
- var _providers = /* @__PURE__ */ new Map();
12
- function getOrCreateFactory(providerName, apiKey) {
13
- const cacheKey = `${providerName}:${apiKey ?? "env"}`;
14
- const cached = _providers.get(cacheKey);
15
- if (cached) return cached;
16
- const envKey = ENV_KEYS[providerName];
17
- const key = apiKey ?? process.env[envKey];
18
- let factory;
19
- switch (providerName) {
20
- case "openrouter": {
21
- if (!key) {
22
- throw new Error(
23
- `No API key found for provider "${providerName}". Set ${envKey} environment variable or pass apiKey option.`
24
- );
25
- }
26
- const provider = createOpenRouter({ apiKey: key });
27
- factory = (modelId) => provider(modelId);
28
- break;
29
- }
30
- case "anthropic": {
31
- const provider = createAnthropic(key ? { apiKey: key } : void 0);
32
- factory = (modelId) => provider(modelId);
33
- break;
34
- }
35
- case "openai": {
36
- const provider = createOpenAI(key ? { apiKey: key } : void 0);
37
- factory = (modelId) => provider(modelId);
38
- break;
39
- }
40
- default:
41
- throw new Error(
42
- `Unknown provider "${providerName}". Supported providers: ${Object.keys(ENV_KEYS).join(", ")}`
43
- );
44
- }
45
- _providers.set(cacheKey, factory);
46
- return factory;
47
- }
48
- function getProvider(apiKey) {
49
- const key = apiKey ?? process.env.OPENROUTER_API_KEY;
50
- if (!key) {
51
- throw new Error(
52
- "No OpenRouter API key found. Set OPENROUTER_API_KEY environment variable or pass apiKey option."
53
- );
54
- }
55
- return createOpenRouter({ apiKey: key });
56
- }
57
- function resetProvider() {
58
- _providers.clear();
59
- }
60
- function getModel(config, apiKey) {
61
- const providerName = config.model.provider ?? "openrouter";
62
- const factory = getOrCreateFactory(providerName, apiKey);
63
- return factory(config.model.id);
64
- }
65
- function getSummaryModel(config, apiKey) {
66
- const modelId = config.model.summary_model ?? config.model.id;
67
- const providerName = config.model.provider ?? "openrouter";
68
- const factory = getOrCreateFactory(providerName, apiKey);
69
- return factory(modelId);
70
- }
71
- function getFastModel(config, apiKey) {
72
- const modelId = config.model.fast_model ?? config.model.summary_model ?? config.model.id;
73
- const providerName = config.model.provider ?? "openrouter";
74
- const factory = getOrCreateFactory(providerName, apiKey);
75
- return factory(modelId);
76
- }
77
- function extractUsage(usage) {
78
- return {
79
- inputTokens: usage?.inputTokens ?? 0,
80
- outputTokens: usage?.outputTokens ?? 0,
81
- totalTokens: (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)
82
- };
83
- }
84
- function buildCallSettings(opts) {
85
- const hasTools = opts.tools && Object.keys(opts.tools).length > 0;
86
- return {
87
- ...opts.maxRetries !== void 0 ? { maxRetries: opts.maxRetries } : {},
88
- ...opts.timeoutMs !== void 0 ? { timeout: opts.timeoutMs } : {},
89
- ...opts.abortSignal ? { abortSignal: opts.abortSignal } : {},
90
- ...hasTools ? { tools: opts.tools } : {},
91
- ...hasTools ? { stopWhen: stepCountIs(opts.maxToolSteps ?? 5) } : {}
92
- };
93
- }
94
- function extractToolCalls(result) {
95
- const calls = [];
96
- if (!result.steps) return calls;
97
- for (const step of result.steps) {
98
- if (!step.toolCalls) continue;
99
- for (let i = 0; i < step.toolCalls.length; i++) {
100
- const tc = step.toolCalls[i];
101
- const tr = step.toolResults?.[i];
102
- calls.push({
103
- toolName: tc.toolName,
104
- args: tc.input ?? {},
105
- result: tr?.output ?? null
106
- });
107
- }
108
- }
109
- return calls;
110
- }
111
- async function generate(opts) {
112
- const result = await generateText({
113
- model: opts.model,
114
- system: opts.system,
115
- prompt: opts.prompt,
116
- maxOutputTokens: opts.maxOutputTokens,
117
- ...buildCallSettings(opts)
118
- });
119
- const usage = result.totalUsage ?? result.usage;
120
- return {
121
- text: result.text,
122
- usage: extractUsage(usage),
123
- toolCalls: extractToolCalls(result),
124
- steps: result.steps?.length ?? 1
125
- };
126
- }
127
- async function generateWithMessages(opts) {
128
- const result = await generateText({
129
- model: opts.model,
130
- system: opts.system,
131
- messages: opts.messages,
132
- maxOutputTokens: opts.maxOutputTokens,
133
- ...buildCallSettings(opts)
134
- });
135
- const usage = result.totalUsage ?? result.usage;
136
- return {
137
- text: result.text,
138
- usage: extractUsage(usage),
139
- toolCalls: extractToolCalls(result),
140
- steps: result.steps?.length ?? 1
141
- };
142
- }
143
- async function* streamGenerate(opts) {
144
- const result = streamText({
145
- model: opts.model,
146
- system: opts.system,
147
- prompt: opts.prompt,
148
- maxOutputTokens: opts.maxOutputTokens,
149
- ...buildCallSettings(opts)
150
- });
151
- for await (const chunk of result.textStream) {
152
- yield chunk;
153
- }
154
- }
155
- function streamWithMessages(opts) {
156
- const result = streamText({
157
- model: opts.model,
158
- system: opts.system,
159
- messages: opts.messages,
160
- maxOutputTokens: opts.maxOutputTokens,
161
- ...buildCallSettings(opts)
162
- });
163
- const totalUsage = Promise.resolve(result.totalUsage ?? result.usage).then((u) => extractUsage(u));
164
- const toolCalls = Promise.resolve(result.steps).then((s) => extractToolCalls({ steps: s }));
165
- const steps = Promise.resolve(result.steps).then((s) => s?.length ?? 1);
166
- return {
167
- textStream: result.textStream,
168
- usage: totalUsage,
169
- toolCalls,
170
- steps
171
- };
172
- }
173
- function streamGenerateWithDetails(opts) {
174
- const result = streamText({
175
- model: opts.model,
176
- system: opts.system,
177
- prompt: opts.prompt,
178
- maxOutputTokens: opts.maxOutputTokens,
179
- ...buildCallSettings(opts)
180
- });
181
- const totalUsage = Promise.resolve(result.totalUsage ?? result.usage).then((u) => extractUsage(u));
182
- const toolCalls = Promise.resolve(result.steps).then((s) => extractToolCalls({ steps: s }));
183
- const steps = Promise.resolve(result.steps).then((s) => s?.length ?? 1);
184
- return {
185
- textStream: result.textStream,
186
- usage: totalUsage,
187
- toolCalls,
188
- steps
189
- };
190
- }
191
-
192
- export {
193
- getProvider,
194
- resetProvider,
195
- getModel,
196
- getSummaryModel,
197
- getFastModel,
198
- generate,
199
- generateWithMessages,
200
- streamGenerate,
201
- streamWithMessages,
202
- streamGenerateWithDetails
203
- };
204
- //# sourceMappingURL=chunk-FD55B3IO.js.map
@@ -1 +0,0 @@
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';\n\n/** Provider factory — maps provider names to (apiKey) => LanguageModel functions */\ntype ProviderFactory = (modelId: string, apiKey?: string) => LanguageModel;\n\nconst ENV_KEYS: Record<ProviderName, string> = {\n openrouter: 'OPENROUTER_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n openai: 'OPENAI_API_KEY',\n};\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 ?? process.env[envKey];\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 default:\n throw new Error(\n `Unknown provider \"${providerName}\". ` +\n `Supported providers: ${Object.keys(ENV_KEYS).join(', ')}`\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":[]}