@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.
- package/README.md +104 -43
- package/dist/{analytics-RPT73WNM.js → analytics-L24W3B7U.js} +1 -2
- package/dist/auto-processor-QIRUOGEI.js +12 -0
- package/dist/{chunk-UPLBF4RZ.js → chunk-2UVWCTAY.js} +2 -2
- package/dist/{chunk-CSL3ERUI.js → chunk-4P6TRFPZ.js} +3 -3
- package/dist/chunk-4P6TRFPZ.js.map +1 -0
- package/dist/{chunk-4CWAGBNS.js → chunk-4TQQZILG.js} +73 -3
- package/dist/chunk-4TQQZILG.js.map +1 -0
- package/dist/{chunk-DA7IKHC4.js → chunk-5CO5JTYT.js} +2 -2
- package/dist/chunk-5CO5JTYT.js.map +1 -0
- package/dist/{chunk-A7BJPQQ6.js → chunk-5O5OGOOQ.js} +2 -2
- package/dist/{chunk-UWQTZMNI.js → chunk-7GZ4D6V6.js} +2 -2
- package/dist/{chunk-FLZU44SV.js → chunk-AN6Y4MDD.js} +6 -6
- package/dist/{chunk-4FDUOGSZ.js → chunk-D7AWV24Z.js} +3 -3
- package/dist/{chunk-CHJ5GNZC.js → chunk-EC42HQQH.js} +2 -2
- package/dist/{chunk-YIJY5DBV.js → chunk-KLYMGWQJ.js} +4 -4
- package/dist/chunk-KLYMGWQJ.js.map +1 -0
- package/dist/{chunk-YUFNYN2H.js → chunk-M62KLIEK.js} +4 -4
- package/dist/chunk-M62KLIEK.js.map +1 -0
- package/dist/{chunk-GJNNR2RA.js → chunk-M6PDMK2O.js} +3 -3
- package/dist/{chunk-M7NXUK55.js → chunk-NVC2WY4K.js} +2 -2
- package/dist/{chunk-XTBKL5BI.js → chunk-PMFAYKBD.js} +2 -2
- package/dist/chunk-PMFAYKBD.js.map +1 -0
- package/dist/{chunk-274RV3YO.js → chunk-QMOIVORH.js} +3 -3
- package/dist/chunk-QMOIVORH.js.map +1 -0
- package/dist/{chunk-RY3ZFII7.js → chunk-SEHAQTBO.js} +6 -6
- package/dist/{chunk-MPZ3BPUI.js → chunk-UMXPOYZR.js} +4 -4
- package/dist/{chunk-W4T7PGI2.js → chunk-UXCHAS3Z.js} +4 -4
- package/dist/cli/index.js +153 -167
- package/dist/cli/index.js.map +1 -1
- package/dist/config-PYSS3QY6.js +12 -0
- package/dist/context-loader-RSXXFW5R.js +12 -0
- package/dist/{conversation-QDEIDQPH.js → conversation-TBTFIJVU.js} +6 -7
- package/dist/{cost-tracker-RS3W7SVY.js → cost-tracker-NZRZEHVA.js} +1 -2
- package/dist/{delegate-VJCJLYEK.js → delegate-3KJAL4NZ.js} +7 -8
- package/dist/{emotional-state-VQVRA6ED.js → emotional-state-IN4ZUL2Q.js} +1 -2
- package/dist/{emotional-state-VQVRA6ED.js.map → emotional-state-IN4ZUL2Q.js.map} +1 -1
- package/dist/{env-discovery-2BLVMAIM.js → env-discovery-PXBRE5FX.js} +1 -2
- package/dist/{env-discovery-2BLVMAIM.js.map → env-discovery-PXBRE5FX.js.map} +1 -1
- package/dist/{export-6GCYHEHQ.js → export-GYLWROMB.js} +3 -4
- package/dist/{export-6GCYHEHQ.js.map → export-GYLWROMB.js.map} +1 -1
- package/dist/graph-LEEO37L3.js +13 -0
- package/dist/{harness-WE4SLCML.js → harness-R5FKRICG.js} +8 -9
- package/dist/{health-NZ6WNIMV.js → health-HL2JYHIY.js} +1 -2
- package/dist/indexer-L5UC6J2V.js +15 -0
- package/dist/{instinct-learner-SRM72DHF.js → instinct-learner-QGAMIS3X.js} +5 -6
- package/dist/{intake-4M3HNU43.js → intake-SVJKFHTL.js} +5 -6
- package/dist/{intelligence-HJOCA4SJ.js → intelligence-XPV3MC5U.js} +10 -13
- package/dist/intelligence-XPV3MC5U.js.map +1 -0
- package/dist/{journal-WANJL3MI.js → journal-ITUMKT6U.js} +5 -6
- package/dist/{loader-C3TKIKZR.js → loader-27PLDCOJ.js} +3 -4
- package/dist/{mcp-WTQJJZAO.js → mcp-JSIUJJZV.js} +1 -2
- package/dist/{mcp-discovery-WPAQFL6S.js → mcp-discovery-DG3RQYLM.js} +1 -2
- package/dist/{mcp-discovery-WPAQFL6S.js.map → mcp-discovery-DG3RQYLM.js.map} +1 -1
- package/dist/{mcp-installer-6O2XXD3V.js → mcp-installer-X2TJ2S2G.js} +3 -4
- package/dist/{mcp-installer-6O2XXD3V.js.map → mcp-installer-X2TJ2S2G.js.map} +1 -1
- package/dist/{metrics-KXGNFAAB.js → metrics-2MNINXNQ.js} +1 -2
- package/dist/{primitive-registry-I6VTIR4W.js → primitive-registry-ZMGGXSO5.js} +3 -4
- package/dist/{primitive-registry-I6VTIR4W.js.map → primitive-registry-ZMGGXSO5.js.map} +1 -1
- package/dist/{project-discovery-C4UMD7JI.js → project-discovery-FQLAZKEM.js} +1 -2
- package/dist/project-discovery-FQLAZKEM.js.map +1 -0
- package/dist/{provider-SXPQZ74H.js → provider-HQY6SPZI.js} +1 -2
- package/dist/{rate-limiter-RLRVM325.js → rate-limiter-PH5DCVU4.js} +1 -2
- package/dist/{rule-engine-YGQ3RYZM.js → rule-engine-DM26S77N.js} +3 -4
- package/dist/{rule-engine-YGQ3RYZM.js.map → rule-engine-DM26S77N.js.map} +1 -1
- package/dist/{scaffold-A3VRRCBV.js → scaffold-2F36YVW6.js} +5 -6
- package/dist/{scaffold-A3VRRCBV.js.map → scaffold-2F36YVW6.js.map} +1 -1
- package/dist/{scheduler-XHHIVHRI.js → scheduler-Q7GB2KCW.js} +11 -12
- package/dist/{scheduler-XHHIVHRI.js.map → scheduler-Q7GB2KCW.js.map} +1 -1
- package/dist/{search-V3W5JMJG.js → search-6Y6NCOLQ.js} +3 -4
- package/dist/search-6Y6NCOLQ.js.map +1 -0
- package/dist/{semantic-search-2DTOO5UX.js → semantic-search-FN6FZIXI.js} +3 -4
- package/dist/semantic-search-FN6FZIXI.js.map +1 -0
- package/dist/{serve-DTQ3HENY.js → serve-MXRTP2HE.js} +10 -11
- package/dist/serve-MXRTP2HE.js.map +1 -0
- package/dist/{sessions-CZGVXKQE.js → sessions-G6SZZXWS.js} +1 -2
- package/dist/{sources-RW5DT56F.js → sources-7LDYO5GK.js} +1 -2
- package/dist/{starter-packs-76YUVHEU.js → starter-packs-OR7NI5NA.js} +1 -2
- package/dist/{starter-packs-76YUVHEU.js.map → starter-packs-OR7NI5NA.js.map} +1 -1
- package/dist/{state-GMXILIHW.js → state-25IQEC5C.js} +1 -2
- package/dist/{state-merge-NKO5FRBA.js → state-merge-E333OEIQ.js} +1 -2
- package/dist/{state-merge-NKO5FRBA.js.map → state-merge-E333OEIQ.js.map} +1 -1
- package/dist/{telemetry-UC6PBXC7.js → telemetry-RS2JZUZP.js} +4 -5
- package/dist/{tool-executor-MJ7IG7PQ.js → tool-executor-6I5PHQDY.js} +5 -6
- package/dist/{tools-DZ4KETET.js → tools-NDFJNVHK.js} +4 -5
- package/dist/{types-EW7AIB3R.js → types-NPJZAI72.js} +2 -3
- package/dist/{universal-installer-AAXXYM5A.js → universal-installer-LCAZHFZR.js} +91 -7
- package/dist/universal-installer-LCAZHFZR.js.map +1 -0
- package/dist/validator-LM7RZWSH.js +21 -0
- package/dist/{verification-gate-FYXUX6LH.js → verification-gate-2O6DF2B7.js} +3 -4
- package/dist/verification-gate-2O6DF2B7.js.map +1 -0
- package/dist/{versioning-Z3XNE2Q2.js → versioning-WEGF6KJG.js} +1 -2
- package/dist/versioning-WEGF6KJG.js.map +1 -0
- package/dist/{watcher-ISJC7YKL.js → watcher-GZWQSWZ6.js} +5 -6
- package/dist/{watcher-ISJC7YKL.js.map → watcher-GZWQSWZ6.js.map} +1 -1
- package/dist/{web-server-DD7ZOP46.js → web-server-2Y4CHD2W.js} +8 -9
- package/package.json +1 -9
- package/dist/agent-framework-K4GUIICH.js +0 -344
- package/dist/agent-framework-K4GUIICH.js.map +0 -1
- package/dist/auto-processor-OLE45UI3.js +0 -13
- package/dist/chunk-274RV3YO.js.map +0 -1
- package/dist/chunk-4CWAGBNS.js.map +0 -1
- package/dist/chunk-CSL3ERUI.js.map +0 -1
- package/dist/chunk-DA7IKHC4.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-FD55B3IO.js +0 -204
- package/dist/chunk-FD55B3IO.js.map +0 -1
- package/dist/chunk-GUJTBGVS.js +0 -2212
- package/dist/chunk-GUJTBGVS.js.map +0 -1
- package/dist/chunk-KFX54TQM.js +0 -165
- package/dist/chunk-KFX54TQM.js.map +0 -1
- package/dist/chunk-XTBKL5BI.js.map +0 -1
- package/dist/chunk-YIJY5DBV.js.map +0 -1
- package/dist/chunk-YUFNYN2H.js.map +0 -1
- package/dist/chunk-ZZJOFKAT.js +0 -13
- package/dist/config-WVMRUOCA.js +0 -13
- package/dist/context-loader-3ORBPMHJ.js +0 -13
- package/dist/graph-YUIPOSOO.js +0 -14
- package/dist/harness-LCHA3DWP.js +0 -10
- package/dist/index.d.ts +0 -3612
- package/dist/index.js +0 -13713
- package/dist/index.js.map +0 -1
- package/dist/indexer-LONANRRM.js +0 -16
- package/dist/intelligence-HJOCA4SJ.js.map +0 -1
- package/dist/project-discovery-C4UMD7JI.js.map +0 -1
- package/dist/provider-LQHQX7Z7.js +0 -26
- package/dist/search-V3W5JMJG.js.map +0 -1
- package/dist/semantic-search-2DTOO5UX.js.map +0 -1
- package/dist/serve-DTQ3HENY.js.map +0 -1
- package/dist/tools-DZ4KETET.js.map +0 -1
- package/dist/types-EW7AIB3R.js.map +0 -1
- package/dist/types-WGDLSPO6.js +0 -16
- package/dist/types-WGDLSPO6.js.map +0 -1
- package/dist/universal-installer-AAXXYM5A.js.map +0 -1
- package/dist/validator-7WXMDIHH.js +0 -22
- package/dist/validator-7WXMDIHH.js.map +0 -1
- package/dist/verification-gate-FYXUX6LH.js.map +0 -1
- package/dist/versioning-Z3XNE2Q2.js.map +0 -1
- package/dist/web-server-DD7ZOP46.js.map +0 -1
- /package/dist/{analytics-RPT73WNM.js.map → analytics-L24W3B7U.js.map} +0 -0
- /package/dist/{auto-processor-OLE45UI3.js.map → auto-processor-QIRUOGEI.js.map} +0 -0
- /package/dist/{chunk-UPLBF4RZ.js.map → chunk-2UVWCTAY.js.map} +0 -0
- /package/dist/{chunk-A7BJPQQ6.js.map → chunk-5O5OGOOQ.js.map} +0 -0
- /package/dist/{chunk-UWQTZMNI.js.map → chunk-7GZ4D6V6.js.map} +0 -0
- /package/dist/{chunk-FLZU44SV.js.map → chunk-AN6Y4MDD.js.map} +0 -0
- /package/dist/{chunk-4FDUOGSZ.js.map → chunk-D7AWV24Z.js.map} +0 -0
- /package/dist/{chunk-CHJ5GNZC.js.map → chunk-EC42HQQH.js.map} +0 -0
- /package/dist/{chunk-GJNNR2RA.js.map → chunk-M6PDMK2O.js.map} +0 -0
- /package/dist/{chunk-M7NXUK55.js.map → chunk-NVC2WY4K.js.map} +0 -0
- /package/dist/{chunk-RY3ZFII7.js.map → chunk-SEHAQTBO.js.map} +0 -0
- /package/dist/{chunk-MPZ3BPUI.js.map → chunk-UMXPOYZR.js.map} +0 -0
- /package/dist/{chunk-W4T7PGI2.js.map → chunk-UXCHAS3Z.js.map} +0 -0
- /package/dist/{chunk-DGUM43GV.js.map → config-PYSS3QY6.js.map} +0 -0
- /package/dist/{chunk-ZZJOFKAT.js.map → context-loader-RSXXFW5R.js.map} +0 -0
- /package/dist/{config-WVMRUOCA.js.map → conversation-TBTFIJVU.js.map} +0 -0
- /package/dist/{context-loader-3ORBPMHJ.js.map → cost-tracker-NZRZEHVA.js.map} +0 -0
- /package/dist/{conversation-QDEIDQPH.js.map → delegate-3KJAL4NZ.js.map} +0 -0
- /package/dist/{cost-tracker-RS3W7SVY.js.map → graph-LEEO37L3.js.map} +0 -0
- /package/dist/{delegate-VJCJLYEK.js.map → harness-R5FKRICG.js.map} +0 -0
- /package/dist/{graph-YUIPOSOO.js.map → health-HL2JYHIY.js.map} +0 -0
- /package/dist/{harness-LCHA3DWP.js.map → indexer-L5UC6J2V.js.map} +0 -0
- /package/dist/{harness-WE4SLCML.js.map → instinct-learner-QGAMIS3X.js.map} +0 -0
- /package/dist/{health-NZ6WNIMV.js.map → intake-SVJKFHTL.js.map} +0 -0
- /package/dist/{indexer-LONANRRM.js.map → journal-ITUMKT6U.js.map} +0 -0
- /package/dist/{instinct-learner-SRM72DHF.js.map → loader-27PLDCOJ.js.map} +0 -0
- /package/dist/{intake-4M3HNU43.js.map → mcp-JSIUJJZV.js.map} +0 -0
- /package/dist/{journal-WANJL3MI.js.map → metrics-2MNINXNQ.js.map} +0 -0
- /package/dist/{loader-C3TKIKZR.js.map → provider-HQY6SPZI.js.map} +0 -0
- /package/dist/{mcp-WTQJJZAO.js.map → rate-limiter-PH5DCVU4.js.map} +0 -0
- /package/dist/{metrics-KXGNFAAB.js.map → sessions-G6SZZXWS.js.map} +0 -0
- /package/dist/{provider-LQHQX7Z7.js.map → sources-7LDYO5GK.js.map} +0 -0
- /package/dist/{provider-SXPQZ74H.js.map → state-25IQEC5C.js.map} +0 -0
- /package/dist/{rate-limiter-RLRVM325.js.map → telemetry-RS2JZUZP.js.map} +0 -0
- /package/dist/{sessions-CZGVXKQE.js.map → tool-executor-6I5PHQDY.js.map} +0 -0
- /package/dist/{sources-RW5DT56F.js.map → tools-NDFJNVHK.js.map} +0 -0
- /package/dist/{state-GMXILIHW.js.map → types-NPJZAI72.js.map} +0 -0
- /package/dist/{telemetry-UC6PBXC7.js.map → validator-LM7RZWSH.js.map} +0 -0
- /package/dist/{tool-executor-MJ7IG7PQ.js.map → web-server-2Y4CHD2W.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,16 +1,82 @@
|
|
|
1
1
|
# Agent Harness
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **A self-managing, self-improving agent runtime. Point it at a problem, write what it should know in markdown, and watch it get better as you use it.**
|
|
4
4
|
|
|
5
|
-
Agent Harness is
|
|
5
|
+
Agent Harness is the layer between "I have an LLM API key" and "I have a working agent that does useful work." It handles identity, memory, tools, context budgeting, session capture, journal synthesis, instinct learning, progressive disclosure, and MCP integration — so you can describe the problem in markdown instead of wiring up 500 lines of TypeScript.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Who this is for**: anyone technical or semi-technical who has a repeating problem they want an agent to own. Writers, founders, ops people, researchers, developers, consultants, analysts. If you can describe what you want in a document, you can build an agent for it.
|
|
8
|
+
|
|
9
|
+
## What makes it different
|
|
10
|
+
|
|
11
|
+
Most agent frameworks give you a box of parts and leave the rest to you. agent-harness gives you a runtime that does three things nobody else does:
|
|
12
|
+
|
|
13
|
+
### 1. It manages itself
|
|
14
|
+
The harness handles its own upkeep automatically:
|
|
15
|
+
- **Context budget**: three disclosure levels (L0/L1/L2) loaded intelligently so you never hit the token ceiling
|
|
16
|
+
- **Session capture**: every interaction is recorded without asking
|
|
17
|
+
- **Journal synthesis**: run `harness journal` and the agent writes its own daily reflection
|
|
18
|
+
- **Dead primitive detection**: orphan files get flagged, contradictions get surfaced
|
|
19
|
+
- **Format auto-repair**: `harness doctor` fixes missing frontmatter, tags, and summaries
|
|
20
|
+
- **Scaffold validation**: primitives are checked for consistency on every load
|
|
21
|
+
|
|
22
|
+
You don't prune files, check token counts, or write cleanup scripts. The harness does its own housekeeping.
|
|
23
|
+
|
|
24
|
+
### 2. It learns from itself
|
|
25
|
+
The headline feature, and the one nobody else has shipped in a working form:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Interaction → Session → Journal → Instinct proposed → Auto-installed → Behavior changes
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
1. Every `harness run` is saved as a session.
|
|
32
|
+
2. `harness journal` synthesizes the day's sessions and finds patterns across them.
|
|
33
|
+
3. `harness learn --install` promotes patterns to **instincts** — behavioral rules written to disk with full provenance ("learned from session X because you kept doing Y").
|
|
34
|
+
4. On the next run, the agent loads the new instincts and **actually behaves differently**.
|
|
35
|
+
|
|
36
|
+
No retraining. No fine-tuning. No tokenization. You use the agent for a week and it measurably improves, with an auditable trail of what changed and why. [Verified end-to-end against real LLM runs in v0.1.0+.](#the-learning-loop)
|
|
37
|
+
|
|
38
|
+
### 3. It's pointable at any problem
|
|
39
|
+
The primitives (`rules/`, `skills/`, `playbooks/`, `instincts/`, `workflows/`, `tools/`, `agents/`) are domain-agnostic. The same harness layout handles:
|
|
40
|
+
|
|
41
|
+
- A research assistant that learns your writing style and source preferences
|
|
42
|
+
- An incident responder that composes runbooks from past resolutions
|
|
43
|
+
- A content marketer that learns what headlines your audience opens
|
|
44
|
+
- A personal planning agent that remembers how you make decisions
|
|
45
|
+
- A code review bot that encodes your team's review standards
|
|
46
|
+
- A customer support triage agent that learns from resolved tickets
|
|
47
|
+
|
|
48
|
+
You describe the problem in `CORE.md`, add a few `skills/` and `rules/`, point `config.yaml` at your LLM provider, and start using it. As you use it, the harness writes `instincts/` for you. Want to share with a teammate? Commit the folder to git.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install -g @agntk/agent-harness
|
|
54
|
+
harness init my-agent && cd my-agent
|
|
55
|
+
export OPENROUTER_API_KEY=sk-or-...
|
|
56
|
+
harness run "Help me decide between two options: A or B"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
That's it. No config file to wire up, no tool layer to build, no state store to provision. Your agent is the folder.
|
|
60
|
+
|
|
61
|
+
## Why markdown (not code)
|
|
62
|
+
|
|
63
|
+
Writing an agent in TypeScript or Python couples the agent's behavior to your programming environment. Markdown decouples them completely:
|
|
64
|
+
|
|
65
|
+
- **Non-coders can author and edit** — if you can write a document, you can write a skill.
|
|
66
|
+
- **Content is greppable, diffable, reviewable** — normal PR workflows work on agent behavior.
|
|
67
|
+
- **The agent reads itself** — when you edit `skills/research.md`, the next run picks it up. No rebuild, no restart.
|
|
68
|
+
- **The harness can write back** — `harness learn` produces markdown files you can read and edit by hand before accepting them.
|
|
69
|
+
- **Portability** — the folder IS the agent. Share it by copying. Version it with git. Deploy it by tarring it.
|
|
70
|
+
|
|
71
|
+
agent-harness is a CLI, not a library. There is no `import { createAgent }` API to wire into a TypeScript app — the entire authoring surface is markdown files inside a harness directory and the `harness` command. If you need programmatic control, script the CLI from your shell or call `harness run` from any process spawn (subprocess, Lambda, GitHub Actions). The tool is the boundary, not a JavaScript module.
|
|
8
72
|
|
|
9
73
|
## Why this is different
|
|
10
74
|
|
|
11
|
-
- **Self-
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
75
|
+
- **Self-managing**: automatic context budgeting, session capture, format repair, dead-primitive detection, contradiction surfacing. Zero maintenance.
|
|
76
|
+
- **Self-learning**: every interaction becomes training data for the agent itself. Patterns become instincts. Behavior measurably changes over time. No retraining.
|
|
77
|
+
- **File-first authoring**: edit markdown, not code. The folder IS the agent. Non-coders can author; coders have escape hatches.
|
|
78
|
+
- **MCP-native tools**: the entire Model Context Protocol ecosystem is your toolbox. No custom adapter layer to build.
|
|
79
|
+
- **License-aware installation**: every `harness install <url>` records source, detects the license, and blocks proprietary content by default. Bundled content is traceable, auditable, and safe by default.
|
|
14
80
|
|
|
15
81
|
## Quick Start
|
|
16
82
|
|
|
@@ -163,6 +229,38 @@ harness sources list
|
|
|
163
229
|
|
|
164
230
|
The installer auto-detects format (Claude Code skills, raw markdown, bash hooks, MCP configs) and normalizes to harness convention with proper frontmatter.
|
|
165
231
|
|
|
232
|
+
### Automatic provenance + license safety
|
|
233
|
+
|
|
234
|
+
Every `harness install <url>` records where content came from and what license governs it:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
# Auto-written into the installed file's frontmatter
|
|
238
|
+
source: https://raw.githubusercontent.com/owner/repo/main/skill.md
|
|
239
|
+
source_commit: 60af65e1d74303b965587f7d43ed7beb53e84d84
|
|
240
|
+
license: MIT
|
|
241
|
+
copyright: Copyright (c) 2024 Seth Hobson
|
|
242
|
+
license_source: https://github.com/owner/repo/blob/main/LICENSE
|
|
243
|
+
installed_at: '2026-04-08T13:50:09.623Z'
|
|
244
|
+
installed_by: agent-harness@0.1.5
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The detector checks per-file LICENSE siblings (catches repos where each subdirectory has its own proprietary LICENSE), then the repo-root LICENSE via the GitHub API, then the file's own frontmatter. Strictest finding wins.
|
|
248
|
+
|
|
249
|
+
**Proprietary content is blocked by default.** If a LICENSE says "all rights reserved" or the content is otherwise unlicensed, the install is refused with a clear error. Configure the policy in `config.yaml`:
|
|
250
|
+
|
|
251
|
+
```yaml
|
|
252
|
+
install:
|
|
253
|
+
allowed_licenses: [MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0, CC-BY-4.0, CC0-1.0, Unlicense]
|
|
254
|
+
on_unknown_license: warn # allow | warn | prompt | block
|
|
255
|
+
on_proprietary: block # never install without explicit override
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Override for one install when you have written permission:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
harness install <url> --force-license MIT
|
|
262
|
+
```
|
|
263
|
+
|
|
166
264
|
Share your own primitives as bundles:
|
|
167
265
|
|
|
168
266
|
```bash
|
|
@@ -325,43 +423,6 @@ harness dev --no-auto-process # Skip auto-processing
|
|
|
325
423
|
|
|
326
424
|
The dashboard includes: agent status, health checks, spending, sessions, workflows, primitives browser, file editor, MCP status, settings editor, and a chat interface.
|
|
327
425
|
|
|
328
|
-
## Using as a Library
|
|
329
|
-
|
|
330
|
-
```typescript
|
|
331
|
-
import { createHarness } from '@agntk/agent-harness';
|
|
332
|
-
|
|
333
|
-
const agent = createHarness({
|
|
334
|
-
dir: './my-agent',
|
|
335
|
-
apiKey: process.env.OPENROUTER_API_KEY,
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
await agent.boot();
|
|
339
|
-
|
|
340
|
-
// One-shot
|
|
341
|
-
const result = await agent.run('What should I work on today?');
|
|
342
|
-
console.log(result.text);
|
|
343
|
-
|
|
344
|
-
// Streaming
|
|
345
|
-
for await (const chunk of agent.stream('Explain this codebase')) {
|
|
346
|
-
process.stdout.write(chunk);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
await agent.shutdown();
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### Fluent Builder API
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
import { defineAgent } from '@agntk/agent-harness';
|
|
356
|
-
|
|
357
|
-
const agent = defineAgent('./my-agent')
|
|
358
|
-
.model('anthropic/claude-sonnet-4')
|
|
359
|
-
.provider('openrouter')
|
|
360
|
-
.onBoot(({ config }) => console.log(`Booted ${config.agent.name}`))
|
|
361
|
-
.onError(({ error }) => console.error(error))
|
|
362
|
-
.build();
|
|
363
|
-
```
|
|
364
|
-
|
|
365
426
|
## Configuration
|
|
366
427
|
|
|
367
428
|
`config.yaml`:
|
|
@@ -4,9 +4,8 @@ import {
|
|
|
4
4
|
getSessionAnalytics,
|
|
5
5
|
getSessionsInRange
|
|
6
6
|
} from "./chunk-GNUSHD2Y.js";
|
|
7
|
-
import "./chunk-ZZJOFKAT.js";
|
|
8
7
|
export {
|
|
9
8
|
getSessionAnalytics,
|
|
10
9
|
getSessionsInRange
|
|
11
10
|
};
|
|
12
|
-
//# sourceMappingURL=analytics-
|
|
11
|
+
//# sourceMappingURL=analytics-L24W3B7U.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
CORE_PRIMITIVE_DIRS,
|
|
5
5
|
FrontmatterSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4TQQZILG.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-
|
|
115
|
+
//# sourceMappingURL=chunk-2UVWCTAY.js.map
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
parseHarnessDocument
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2UVWCTAY.js";
|
|
6
6
|
import {
|
|
7
7
|
generate,
|
|
8
8
|
getModel
|
|
9
9
|
} from "./chunk-IZ6UZ3ZL.js";
|
|
10
10
|
import {
|
|
11
11
|
loadConfig
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EC42HQQH.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-
|
|
307
|
+
//# sourceMappingURL=chunk-4P6TRFPZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 { 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":[]}
|
|
@@ -124,7 +124,62 @@ var HarnessConfigSchema = z.object({
|
|
|
124
124
|
name: z.string().optional(),
|
|
125
125
|
/** Optional auth token for private registries */
|
|
126
126
|
token: z.string().optional()
|
|
127
|
-
}).passthrough()).default([])
|
|
127
|
+
}).passthrough()).default([]),
|
|
128
|
+
/**
|
|
129
|
+
* License policy for `harness install <url>`. Controls how the universal
|
|
130
|
+
* installer reacts to the license detected on a fetched primitive (Level 3
|
|
131
|
+
* of task 12.14). Detection itself runs unconditionally — this only governs
|
|
132
|
+
* what happens after the license is determined.
|
|
133
|
+
*/
|
|
134
|
+
install: z.object({
|
|
135
|
+
/**
|
|
136
|
+
* SPDX ids the installer accepts without warning. Permissive defaults
|
|
137
|
+
* cover the OSI-approved ecosystem most users care about. Add or remove
|
|
138
|
+
* here to tighten or loosen the policy.
|
|
139
|
+
*/
|
|
140
|
+
allowed_licenses: z.array(z.string()).default([
|
|
141
|
+
"MIT",
|
|
142
|
+
"Apache-2.0",
|
|
143
|
+
"BSD-2-Clause",
|
|
144
|
+
"BSD-3-Clause",
|
|
145
|
+
"ISC",
|
|
146
|
+
"MPL-2.0",
|
|
147
|
+
"CC-BY-4.0",
|
|
148
|
+
"CC0-1.0",
|
|
149
|
+
"Unlicense"
|
|
150
|
+
]),
|
|
151
|
+
/**
|
|
152
|
+
* What to do when the detected license is not in `allowed_licenses` and
|
|
153
|
+
* is not classified as PROPRIETARY. Includes the UNKNOWN case (no LICENSE
|
|
154
|
+
* file found anywhere) and any non-permissive SPDX id like GPL-3.0.
|
|
155
|
+
*
|
|
156
|
+
* - allow: install silently (legacy v0.1.3 behavior — safest for migration)
|
|
157
|
+
* - warn: install with a stderr warning naming the license_source
|
|
158
|
+
* - prompt: ask Y/n on TTY; treats non-TTY as `block`
|
|
159
|
+
* - block: refuse the install with an error showing the override flag
|
|
160
|
+
*/
|
|
161
|
+
on_unknown_license: z.enum(["allow", "warn", "prompt", "block"]).default("warn"),
|
|
162
|
+
/**
|
|
163
|
+
* What to do when the detected license is PROPRIETARY (text contains
|
|
164
|
+
* "all rights reserved" or no permission grant). Defaults to `block`
|
|
165
|
+
* because shipping proprietary content was the v0.1.0 yank cause.
|
|
166
|
+
*/
|
|
167
|
+
on_proprietary: z.enum(["allow", "warn", "prompt", "block"]).default("block")
|
|
168
|
+
}).passthrough().default({
|
|
169
|
+
allowed_licenses: [
|
|
170
|
+
"MIT",
|
|
171
|
+
"Apache-2.0",
|
|
172
|
+
"BSD-2-Clause",
|
|
173
|
+
"BSD-3-Clause",
|
|
174
|
+
"ISC",
|
|
175
|
+
"MPL-2.0",
|
|
176
|
+
"CC-BY-4.0",
|
|
177
|
+
"CC0-1.0",
|
|
178
|
+
"Unlicense"
|
|
179
|
+
],
|
|
180
|
+
on_unknown_license: "warn",
|
|
181
|
+
on_proprietary: "block"
|
|
182
|
+
})
|
|
128
183
|
}).passthrough();
|
|
129
184
|
var CONFIG_DEFAULTS = {
|
|
130
185
|
agent: { name: "agent", version: "0.1.0" },
|
|
@@ -143,7 +198,22 @@ var CONFIG_DEFAULTS = {
|
|
|
143
198
|
intelligence: { auto_journal: false, auto_learn: false },
|
|
144
199
|
proactive: { enabled: false, max_per_hour: 5, cooldown_minutes: 30 },
|
|
145
200
|
mcp: { servers: {} },
|
|
146
|
-
registries: []
|
|
201
|
+
registries: [],
|
|
202
|
+
install: {
|
|
203
|
+
allowed_licenses: [
|
|
204
|
+
"MIT",
|
|
205
|
+
"Apache-2.0",
|
|
206
|
+
"BSD-2-Clause",
|
|
207
|
+
"BSD-3-Clause",
|
|
208
|
+
"ISC",
|
|
209
|
+
"MPL-2.0",
|
|
210
|
+
"CC-BY-4.0",
|
|
211
|
+
"CC0-1.0",
|
|
212
|
+
"Unlicense"
|
|
213
|
+
],
|
|
214
|
+
on_unknown_license: "warn",
|
|
215
|
+
on_proprietary: "block"
|
|
216
|
+
}
|
|
147
217
|
};
|
|
148
218
|
var CORE_PRIMITIVE_DIRS = ["rules", "instincts", "skills", "playbooks", "workflows", "tools", "agents"];
|
|
149
219
|
function getPrimitiveDirs(config) {
|
|
@@ -165,4 +235,4 @@ export {
|
|
|
165
235
|
CORE_PRIMITIVE_DIRS,
|
|
166
236
|
getPrimitiveDirs
|
|
167
237
|
};
|
|
168
|
-
//# sourceMappingURL=chunk-
|
|
238
|
+
//# sourceMappingURL=chunk-4TQQZILG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 /**\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,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
loadTools
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PMFAYKBD.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-
|
|
229
|
+
//# sourceMappingURL=chunk-5CO5JTYT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 { 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":[]}
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./chunk-JKMGYWXB.js";
|
|
22
22
|
import {
|
|
23
23
|
loadConfig
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-EC42HQQH.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-
|
|
236
|
+
//# sourceMappingURL=chunk-5O5OGOOQ.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
estimateTokens,
|
|
5
5
|
getAtLevel,
|
|
6
6
|
loadAllPrimitivesWithErrors
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2UVWCTAY.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-
|
|
154
|
+
//# sourceMappingURL=chunk-7GZ4D6V6.js.map
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
fixCapability
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UXCHAS3Z.js";
|
|
6
6
|
import {
|
|
7
7
|
validateMcpConfig
|
|
8
8
|
} from "./chunk-5H34JPMB.js";
|
|
9
9
|
import {
|
|
10
10
|
buildSystemPrompt
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-7GZ4D6V6.js";
|
|
12
12
|
import {
|
|
13
13
|
loadState
|
|
14
14
|
} from "./chunk-UDZIS2AQ.js";
|
|
15
15
|
import {
|
|
16
16
|
loadDirectoryWithErrors
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-2UVWCTAY.js";
|
|
18
18
|
import {
|
|
19
19
|
loadConfig
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EC42HQQH.js";
|
|
21
21
|
import {
|
|
22
22
|
getPrimitiveDirs
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-4TQQZILG.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-
|
|
230
|
+
//# sourceMappingURL=chunk-AN6Y4MDD.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
loadDirectory
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2UVWCTAY.js";
|
|
6
6
|
import {
|
|
7
7
|
CORE_PRIMITIVE_DIRS
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4TQQZILG.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-
|
|
69
|
+
//# sourceMappingURL=chunk-D7AWV24Z.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
CONFIG_DEFAULTS,
|
|
5
5
|
HarnessConfigSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4TQQZILG.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-
|
|
100
|
+
//# sourceMappingURL=chunk-EC42HQQH.js.map
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
} from "./chunk-5H34JPMB.js";
|
|
9
9
|
import {
|
|
10
10
|
buildToolSet
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5CO5JTYT.js";
|
|
12
12
|
import {
|
|
13
13
|
buildSystemPrompt
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-7GZ4D6V6.js";
|
|
15
15
|
import {
|
|
16
16
|
loadState,
|
|
17
17
|
saveState
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
} from "./chunk-IZ6UZ3ZL.js";
|
|
39
39
|
import {
|
|
40
40
|
loadConfig
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-EC42HQQH.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-
|
|
399
|
+
//# sourceMappingURL=chunk-KLYMGWQJ.js.map
|