@ghostmind-dev/agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/budget.d.ts +39 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +34 -0
- package/dist/budget.js.map +1 -0
- package/dist/consult.d.ts +25 -0
- package/dist/consult.d.ts.map +1 -0
- package/dist/consult.js +80 -0
- package/dist/consult.js.map +1 -0
- package/dist/events.d.ts +119 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +24 -0
- package/dist/events.js.map +1 -0
- package/dist/guide.d.ts +103 -0
- package/dist/guide.d.ts.map +1 -0
- package/dist/guide.js +268 -0
- package/dist/guide.js.map +1 -0
- package/dist/hooks.d.ts +80 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +56 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/jev.d.ts +74 -0
- package/dist/jev.d.ts.map +1 -0
- package/dist/jev.js +82 -0
- package/dist/jev.js.map +1 -0
- package/dist/loop.d.ts +142 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +550 -0
- package/dist/loop.js.map +1 -0
- package/dist/model.d.ts +173 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +205 -0
- package/dist/model.js.map +1 -0
- package/dist/seams.d.ts +137 -0
- package/dist/seams.d.ts.map +1 -0
- package/dist/seams.js +45 -0
- package/dist/seams.js.map +1 -0
- package/dist/skills.d.ts +36 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +168 -0
- package/dist/skills.js.map +1 -0
- package/dist/testing.d.ts +36 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +60 -0
- package/dist/testing.js.map +1 -0
- package/dist/tools.d.ts +114 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +136 -0
- package/dist/tools.js.map +1 -0
- package/package.json +50 -0
package/dist/guide.js
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The guide — Jev asking "is this going the right way?" so a weaker model gets through uncertainty.
|
|
3
|
+
*
|
|
4
|
+
* A strong worker rarely needs help; a cheap one often does, and a calibrated yes/no costs about
|
|
5
|
+
* $0.00002. So the HARNESS asks Jev at fixed checkpoints — not only when the model thinks to call
|
|
6
|
+
* `ask_jev` — and turns the probability into a move, in code:
|
|
7
|
+
*
|
|
8
|
+
* after_tool "does this result move toward the request?" low → a transient steer
|
|
9
|
+
* before_write "is this change what the person asked for?" low → the call is held back once,
|
|
10
|
+
* with the doubt, before approval
|
|
11
|
+
* before_answer "does this answer respond to the request?" low → sent back (a nudge)
|
|
12
|
+
* hesitation (an empty reply, a repeated call, leaked markup) a choice over the tools + "answer
|
|
13
|
+
* "which next step moves the request forward?" now" → a transient steer naming it
|
|
14
|
+
*
|
|
15
|
+
* The guide STEERS; it does not overrule. A held-back change goes through if the model makes it
|
|
16
|
+
* again, and a person still approves it. That is the lesson of the verdict node Potion's Talk dropped
|
|
17
|
+
* before its first commit ("Pi — the model decides; no second judge"): it judged the WHOLE transcript
|
|
18
|
+
* and asked whether every fact and number was supported, which is exactly where Jev's documented
|
|
19
|
+
* jaggedness lies (counting and numbers, long context, multi-hop). Here every question is atomic,
|
|
20
|
+
* the state is the task and the latest step only, and nothing asks Jev to count or compare figures.
|
|
21
|
+
*
|
|
22
|
+
* How closely it watches follows the model (`guidance`, default 'auto'):
|
|
23
|
+
* 1. a starting level from what the provider knows of the model (`card()`: price, context, tools —
|
|
24
|
+
* the live OpenRouter catalogue, never a list of ids);
|
|
25
|
+
* 2. adapted within the run from evidence: repeated low probabilities tighten it, a run of confident
|
|
26
|
+
* passes loosens it — each change an event;
|
|
27
|
+
* 3. learned across runs: a per-model profile (how often Jev corrected it, and whether corrected runs
|
|
28
|
+
* still succeeded) in a pluggable store, which seeds the next run's level.
|
|
29
|
+
* Every checkpoint is an event with its question, probability and action, and its cost is spent
|
|
30
|
+
* against the run's budget, so the value of guidance can be measured (see bench/).
|
|
31
|
+
*/
|
|
32
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
33
|
+
import { dirname } from 'node:path';
|
|
34
|
+
export const DEFAULT_THRESHOLDS = { onTrack: 0.35, write: 0.3, answer: 0.35, confident: 0.85, tightenAfter: 2, loosenAfter: 4 };
|
|
35
|
+
const ORDER = ['off', 'light', 'normal', 'close'];
|
|
36
|
+
/** What each level checks. `afterTool` is a period: every Nth tool result (0 = never). */
|
|
37
|
+
export const LEVELS = {
|
|
38
|
+
off: { afterTool: 0, beforeWrite: false, beforeAnswer: false, hesitation: false },
|
|
39
|
+
light: { afterTool: 0, beforeWrite: true, beforeAnswer: true, hesitation: false },
|
|
40
|
+
normal: { afterTool: 3, beforeWrite: true, beforeAnswer: true, hesitation: true },
|
|
41
|
+
close: { afterTool: 1, beforeWrite: true, beforeAnswer: true, hesitation: true },
|
|
42
|
+
};
|
|
43
|
+
export function memoryProfiles() {
|
|
44
|
+
const profiles = new Map();
|
|
45
|
+
return { profiles, get: async (m) => (profiles.has(m) ? { ...profiles.get(m) } : null), put: async (p) => void profiles.set(p.model, { ...p }) };
|
|
46
|
+
}
|
|
47
|
+
/** Profiles in one JSON file (written atomically). Good for a CLI or a single server. */
|
|
48
|
+
export function fileProfiles(path) {
|
|
49
|
+
const read = () => {
|
|
50
|
+
try {
|
|
51
|
+
return existsSync(path) ? JSON.parse(readFileSync(path, 'utf8')) : {};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
get: async (m) => read()[m] ?? null,
|
|
59
|
+
put: async (p) => {
|
|
60
|
+
const all = read();
|
|
61
|
+
all[p.model] = p;
|
|
62
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
63
|
+
writeFileSync(`${path}.tmp`, JSON.stringify(all, null, 2));
|
|
64
|
+
renameSync(`${path}.tmp`, path);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// ── the starting level ──────────────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* From what the catalogue says of a model. Price is the strongest cheap signal of capability a
|
|
71
|
+
* catalogue gives; a small context or no tool support tightens one more notch. Unknown → normal.
|
|
72
|
+
*/
|
|
73
|
+
export function levelFromCard(card) {
|
|
74
|
+
if (!card)
|
|
75
|
+
return { level: 'normal', why: 'nothing known about the model' };
|
|
76
|
+
const perMillion = card.completion * 1e6;
|
|
77
|
+
let i = perMillion >= 10 ? 1 : perMillion >= 2 ? 2 : 3;
|
|
78
|
+
const weak = [];
|
|
79
|
+
if (!card.tools)
|
|
80
|
+
weak.push('no tool support');
|
|
81
|
+
if (card.context > 0 && card.context < 64_000)
|
|
82
|
+
weak.push(`${card.context} context`);
|
|
83
|
+
if (weak.length)
|
|
84
|
+
i = Math.min(3, i + 1);
|
|
85
|
+
const level = ORDER[i];
|
|
86
|
+
return { level, why: `$${perMillion.toFixed(2)}/M output${weak.length ? `, ${weak.join(', ')}` : ''}` };
|
|
87
|
+
}
|
|
88
|
+
/** From a model's history, once there is enough of it (3+ runs); null otherwise. */
|
|
89
|
+
export function levelFromProfile(p) {
|
|
90
|
+
if (!p || p.runs < 3 || p.checkpoints === 0)
|
|
91
|
+
return null;
|
|
92
|
+
const lowRate = p.lows / p.checkpoints;
|
|
93
|
+
const success = p.successes / p.runs;
|
|
94
|
+
const why = `${p.runs} runs, ${Math.round(lowRate * 100)}% low checkpoints, ${Math.round(success * 100)}% done`;
|
|
95
|
+
if (lowRate > 0.3 || success < 0.6)
|
|
96
|
+
return { level: 'close', why };
|
|
97
|
+
if (lowRate > 0.12)
|
|
98
|
+
return { level: 'normal', why };
|
|
99
|
+
if (success >= 0.8)
|
|
100
|
+
return { level: 'light', why };
|
|
101
|
+
return { level: 'normal', why };
|
|
102
|
+
}
|
|
103
|
+
const clip = (s, n) => (s.length > n ? `${s.slice(0, n)}…` : s);
|
|
104
|
+
const firstSentence = (d) => clip(d.trim().split(/(?<=\.)\s/)[0] ?? d, 200);
|
|
105
|
+
const callText = (tool, args) => clip(`${tool}(${JSON.stringify(args)})`, 400);
|
|
106
|
+
export const ANSWER_NOW = 'answer_now';
|
|
107
|
+
export function createGuide(options, deps) {
|
|
108
|
+
const T = { ...DEFAULT_THRESHOLDS, ...options.thresholds };
|
|
109
|
+
const setting = options.guidance ?? 'auto';
|
|
110
|
+
const decide = deps.provider.decide?.bind(deps.provider);
|
|
111
|
+
const adaptive = setting === 'auto';
|
|
112
|
+
const period = typeof setting === 'number' ? Math.max(1, Math.round(setting)) : null;
|
|
113
|
+
let level = typeof setting === 'number' ? 'close' : setting === 'auto' ? 'normal' : setting;
|
|
114
|
+
const active = () => !!decide && level !== 'off';
|
|
115
|
+
let results = 0;
|
|
116
|
+
let lowStreak = 0;
|
|
117
|
+
let confidentStreak = 0;
|
|
118
|
+
let checkpoints = 0;
|
|
119
|
+
let lows = 0;
|
|
120
|
+
let corrections = 0;
|
|
121
|
+
const heldBack = new Set();
|
|
122
|
+
const setLevel = (next, reason) => {
|
|
123
|
+
if (next === level)
|
|
124
|
+
return;
|
|
125
|
+
deps.emit({ type: 'guidance', from: level, level: next, reason });
|
|
126
|
+
level = next;
|
|
127
|
+
};
|
|
128
|
+
/** Record a probability: counts, streaks, and (auto) tightening or loosening. */
|
|
129
|
+
const observe = (p, threshold) => {
|
|
130
|
+
checkpoints++;
|
|
131
|
+
if (p < threshold) {
|
|
132
|
+
lows++;
|
|
133
|
+
lowStreak++;
|
|
134
|
+
confidentStreak = 0;
|
|
135
|
+
if (adaptive && lowStreak >= T.tightenAfter && level !== 'close') {
|
|
136
|
+
setLevel(ORDER[ORDER.indexOf(level) + 1], `${lowStreak} low checkpoints in a row`);
|
|
137
|
+
lowStreak = 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
lowStreak = 0;
|
|
142
|
+
confidentStreak = p >= T.confident ? confidentStreak + 1 : 0;
|
|
143
|
+
if (adaptive && confidentStreak >= T.loosenAfter && ORDER.indexOf(level) > 1) {
|
|
144
|
+
setLevel(ORDER[ORDER.indexOf(level) - 1], `${confidentStreak} confident checkpoints in a row`);
|
|
145
|
+
confidentStreak = 0;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const ask = async (state, questions) => {
|
|
150
|
+
if (!decide || !deps.affordable() || deps.signal.aborted)
|
|
151
|
+
return null;
|
|
152
|
+
try {
|
|
153
|
+
const reply = await decide(state, questions, deps.signal);
|
|
154
|
+
deps.spend(reply.cost, 'guide');
|
|
155
|
+
return reply.answers;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return null; // No answer is never read as a verdict.
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const yesNo = async (at, question, state, threshold, lowAction) => {
|
|
162
|
+
const answers = await ask(state, { q: { type: 'noul', instructions: question } });
|
|
163
|
+
const a = answers?.q;
|
|
164
|
+
if (!a || a.type !== 'noul') {
|
|
165
|
+
deps.emit({ type: 'checkpoint', at, question, p: null, action: 'none', level });
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const low = a.noul < threshold;
|
|
169
|
+
deps.emit({ type: 'checkpoint', at, question, p: a.noul, action: low ? lowAction : 'pass', level });
|
|
170
|
+
observe(a.noul, threshold);
|
|
171
|
+
if (low)
|
|
172
|
+
corrections++;
|
|
173
|
+
return { p: a.noul, low };
|
|
174
|
+
};
|
|
175
|
+
const pct = (p) => `${Math.round(p * 100)}%`;
|
|
176
|
+
return {
|
|
177
|
+
get level() {
|
|
178
|
+
return level;
|
|
179
|
+
},
|
|
180
|
+
get active() {
|
|
181
|
+
return active();
|
|
182
|
+
},
|
|
183
|
+
async start() {
|
|
184
|
+
if (!decide || !adaptive)
|
|
185
|
+
return;
|
|
186
|
+
const model = deps.model ?? '';
|
|
187
|
+
const learned = options.profiles && model ? levelFromProfile(await options.profiles.get(model).catch(() => null)) : null;
|
|
188
|
+
const from = learned ?? levelFromCard(model && deps.provider.card ? await deps.provider.card(model, deps.signal).catch(() => null) : null);
|
|
189
|
+
deps.emit({ type: 'guidance', from: null, level: from.level, reason: `${learned ? 'profile' : 'catalogue'}: ${from.why}` });
|
|
190
|
+
level = from.level;
|
|
191
|
+
},
|
|
192
|
+
async afterTools(batch) {
|
|
193
|
+
if (!active() || !batch.length)
|
|
194
|
+
return null;
|
|
195
|
+
const every = period ?? LEVELS[level].afterTool;
|
|
196
|
+
const due = batch.filter(() => every > 0 && ++results % every === 0);
|
|
197
|
+
if (!due.length)
|
|
198
|
+
return null;
|
|
199
|
+
// Judge the last result that fell due: the latest step, not the transcript.
|
|
200
|
+
const last = due.at(-1);
|
|
201
|
+
const question = 'Does `result` (what `call` returned) move the agent closer to doing what `goal` asks?';
|
|
202
|
+
const out = await yesNo('after_tool', question, { goal: clip(deps.task.goal, 600), call: callText(last.tool, last.args), result: clip(last.result, 1500) }, T.onTrack, 'steer');
|
|
203
|
+
if (!out?.low)
|
|
204
|
+
return null;
|
|
205
|
+
return `Guide (Jev, ${pct(out.p)} on track): the last result may not move toward the request "${clip(deps.task.goal, 200)}". Before the next call, reconsider: another tool, other arguments, or answering with what you have.`;
|
|
206
|
+
},
|
|
207
|
+
async beforeWrite(tool, args, change, key) {
|
|
208
|
+
if (!active() || !LEVELS[level].beforeWrite || heldBack.has(key))
|
|
209
|
+
return null;
|
|
210
|
+
const question = 'Is `change` something `goal` asks for?';
|
|
211
|
+
const out = await yesNo('before_write', question, { goal: clip(deps.task.goal, 600), change: clip(change, 400), call: callText(tool, args) }, T.write, 'hold');
|
|
212
|
+
if (!out?.low)
|
|
213
|
+
return null;
|
|
214
|
+
// Held back once: the same change made again goes on to approval.
|
|
215
|
+
heldBack.add(key);
|
|
216
|
+
return `Not run yet — Guide (Jev, ${pct(out.p)}): this change may not be what the person asked for ("${clip(deps.task.goal, 200)}"). If it is, make the same call again; otherwise choose another action or ask the person.`;
|
|
217
|
+
},
|
|
218
|
+
async beforeAnswer(answer) {
|
|
219
|
+
if (!active() || !LEVELS[level].beforeAnswer || !answer)
|
|
220
|
+
return null;
|
|
221
|
+
const question = 'Does `answer` respond to what `goal` asks for?';
|
|
222
|
+
const out = await yesNo('before_answer', question, { goal: clip(deps.task.goal, 600), expected: clip(deps.task.expectation, 400), answer: clip(answer, 2000) }, T.answer, 'send_back');
|
|
223
|
+
if (!out?.low)
|
|
224
|
+
return null;
|
|
225
|
+
return `Guide (Jev, ${pct(out.p)}): your answer may not respond to the request "${clip(deps.task.goal, 200)}". Check what was asked, fix what is missing, and reply with the corrected answer.`;
|
|
226
|
+
},
|
|
227
|
+
async hesitation(why, last, tools) {
|
|
228
|
+
if (!active() || !LEVELS[level].hesitation)
|
|
229
|
+
return null;
|
|
230
|
+
const criteria = { [ANSWER_NOW]: 'Enough is known: answer now with what the tools returned.' };
|
|
231
|
+
for (const t of tools.slice(0, 250))
|
|
232
|
+
criteria[t.name] = firstSentence(t.description);
|
|
233
|
+
const question = 'Which next step most helps do what `goal` asks, given `last`?';
|
|
234
|
+
const answers = await ask({ goal: clip(deps.task.goal, 600), last: clip(last, 1200), hesitation: why }, { q: { type: 'choice', instructions: question, criteria } });
|
|
235
|
+
const a = answers?.q;
|
|
236
|
+
if (!a || a.type !== 'choice' || !(a.choice in criteria)) {
|
|
237
|
+
deps.emit({ type: 'checkpoint', at: 'hesitation', question, p: null, action: 'none', level });
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
checkpoints++;
|
|
241
|
+
corrections++;
|
|
242
|
+
deps.emit({ type: 'checkpoint', at: 'hesitation', question, p: a.confidence, choice: a.choice, action: 'steer', level });
|
|
243
|
+
return a.choice === ANSWER_NOW
|
|
244
|
+
? `Guide (Jev, ${pct(a.confidence)}): you likely have enough — answer now from what the tools returned.`
|
|
245
|
+
: `Guide (Jev, ${pct(a.confidence)}): the next step most likely to help is \`${a.choice}\`.`;
|
|
246
|
+
},
|
|
247
|
+
async finish(status) {
|
|
248
|
+
const model = deps.model;
|
|
249
|
+
if (!options.profiles || !model || !decide || checkpoints === 0)
|
|
250
|
+
return;
|
|
251
|
+
const p = (await options.profiles.get(model).catch(() => null)) ?? { model, runs: 0, successes: 0, checkpoints: 0, lows: 0, correctedRuns: 0, correctedSuccesses: 0, lastLevel: level };
|
|
252
|
+
const done = status === 'done';
|
|
253
|
+
await options.profiles
|
|
254
|
+
.put({
|
|
255
|
+
model,
|
|
256
|
+
runs: p.runs + 1,
|
|
257
|
+
successes: p.successes + (done ? 1 : 0),
|
|
258
|
+
checkpoints: p.checkpoints + checkpoints,
|
|
259
|
+
lows: p.lows + lows,
|
|
260
|
+
correctedRuns: p.correctedRuns + (corrections ? 1 : 0),
|
|
261
|
+
correctedSuccesses: p.correctedSuccesses + (corrections && done ? 1 : 0),
|
|
262
|
+
lastLevel: level,
|
|
263
|
+
})
|
|
264
|
+
.catch(() => { });
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guide.js","sourceRoot":"","sources":["../src/guide.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks — where an app bends the loop without forking it.
|
|
3
|
+
*
|
|
4
|
+
* Frontier harnesses converged on the same design: a minimal kernel, with everything else as hooks
|
|
5
|
+
* at the loop's stages (Claude Code's PreToolUse / Stop, DeepSeek's pre-execute). Four stages here:
|
|
6
|
+
*
|
|
7
|
+
* beforeStep — before each model call go · pause (end, 'paused') · stop (end, 'stopped')
|
|
8
|
+
* toolGate — before each tool call go (optionally with rewritten args, or a result
|
|
9
|
+
* given instead of running) · pause · stop
|
|
10
|
+
* rewriteOutput — each tool result, before the model sees it: redact, trim, annotate
|
|
11
|
+
* stopCheck — when the model stops stop (accept: done) · go (send it back with the
|
|
12
|
+
* reason, counted as a nudge) · pause (needs_person)
|
|
13
|
+
*
|
|
14
|
+
* One vocabulary — go / pause / stop — on purpose: it is the same shape as ensemble's
|
|
15
|
+
* `guard(step) -> go | pause | stop`, so a supervisor that speaks one speaks both. "go" always means
|
|
16
|
+
* the run continues; "pause" means a person's move is next and the run can be resumed; "stop" ends.
|
|
17
|
+
* A hook returning nothing is "go" — except stopCheck, where nothing means no objection: the stop
|
|
18
|
+
* stands, exactly as if it had said "stop".
|
|
19
|
+
*/
|
|
20
|
+
import type { ChatMessage } from './model.ts';
|
|
21
|
+
import type { AgentTask } from './seams.ts';
|
|
22
|
+
export type Verdict = 'go' | 'pause' | 'stop';
|
|
23
|
+
export interface HookDecision {
|
|
24
|
+
verdict: Verdict;
|
|
25
|
+
/** Why — logged, returned as the result's `reason`, and (for a stopCheck "go") told to the model. */
|
|
26
|
+
reason?: string;
|
|
27
|
+
}
|
|
28
|
+
export type HookReply = Verdict | HookDecision | void | undefined;
|
|
29
|
+
type Maybe<T> = T | Promise<T>;
|
|
30
|
+
export interface StepContext {
|
|
31
|
+
step: number;
|
|
32
|
+
/** USD so far. */
|
|
33
|
+
spent: number;
|
|
34
|
+
toolCalls: number;
|
|
35
|
+
nudges: number;
|
|
36
|
+
task: AgentTask;
|
|
37
|
+
/** The conversation as the model sees it. Read-only: change the run through verdicts. */
|
|
38
|
+
messages: readonly ChatMessage[];
|
|
39
|
+
/** Add USD a hook spent (a Jev decision) to the run's total and budget. */
|
|
40
|
+
spend(usd: number, on: string): void;
|
|
41
|
+
}
|
|
42
|
+
export interface ToolGateContext extends StepContext {
|
|
43
|
+
tool: string;
|
|
44
|
+
args: Record<string, unknown>;
|
|
45
|
+
callId: string;
|
|
46
|
+
/** The approval sentence when this call changes something, else null. */
|
|
47
|
+
change: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface ToolGateDecision extends HookDecision {
|
|
50
|
+
/** Run with these arguments instead. */
|
|
51
|
+
args?: Record<string, unknown>;
|
|
52
|
+
/** Do not run: hand the model this result instead (a refusal, a cached answer). */
|
|
53
|
+
result?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface OutputContext extends StepContext {
|
|
56
|
+
tool: string;
|
|
57
|
+
args: Record<string, unknown>;
|
|
58
|
+
callId: string;
|
|
59
|
+
ok: boolean;
|
|
60
|
+
result: string;
|
|
61
|
+
}
|
|
62
|
+
export interface StopContext extends StepContext {
|
|
63
|
+
answer: string | null;
|
|
64
|
+
}
|
|
65
|
+
export interface Hooks {
|
|
66
|
+
beforeStep?(ctx: StepContext): Maybe<HookReply>;
|
|
67
|
+
toolGate?(ctx: ToolGateContext): Maybe<Verdict | ToolGateDecision | void | undefined>;
|
|
68
|
+
/** Return the text the model should see instead, or nothing to keep it. */
|
|
69
|
+
rewriteOutput?(ctx: OutputContext): Maybe<string | void | undefined>;
|
|
70
|
+
stopCheck?(ctx: StopContext): Maybe<HookReply>;
|
|
71
|
+
}
|
|
72
|
+
/** Any hook reply as a decision. Nothing is "go". */
|
|
73
|
+
export declare function readVerdict<T extends HookDecision>(reply: Verdict | T | void | undefined): T | HookDecision;
|
|
74
|
+
/**
|
|
75
|
+
* Several hook sets as one. Gates run in order and the first non-"go" wins (a rewrite of args by one
|
|
76
|
+
* gate is what the next one sees); output rewrites chain; for stopCheck the first objection wins.
|
|
77
|
+
*/
|
|
78
|
+
export declare function combineHooks(...sets: (Hooks | undefined)[]): Hooks;
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,qGAAqG;IACrG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;AAClE,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE/B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,yFAAyF;IACzF,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,2EAA2E;IAC3E,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,CAAC,GAAG,EAAE,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAChD,QAAQ,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,KAAK,CAAC,OAAO,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtF,2EAA2E;IAC3E,aAAa,CAAC,CAAC,GAAG,EAAE,aAAa,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACrE,SAAS,CAAC,CAAC,GAAG,EAAE,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;CAChD;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,GAAG,YAAY,CAI3G;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,GAAG,KAAK,CAsClE"}
|
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Any hook reply as a decision. Nothing is "go". */
|
|
2
|
+
export function readVerdict(reply) {
|
|
3
|
+
if (!reply)
|
|
4
|
+
return { verdict: 'go' };
|
|
5
|
+
if (typeof reply === 'string')
|
|
6
|
+
return { verdict: reply };
|
|
7
|
+
return reply;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Several hook sets as one. Gates run in order and the first non-"go" wins (a rewrite of args by one
|
|
11
|
+
* gate is what the next one sees); output rewrites chain; for stopCheck the first objection wins.
|
|
12
|
+
*/
|
|
13
|
+
export function combineHooks(...sets) {
|
|
14
|
+
const hooks = sets.filter((h) => !!h);
|
|
15
|
+
return {
|
|
16
|
+
async beforeStep(ctx) {
|
|
17
|
+
for (const h of hooks) {
|
|
18
|
+
const d = readVerdict(await h.beforeStep?.(ctx));
|
|
19
|
+
if (d.verdict !== 'go')
|
|
20
|
+
return d;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
async toolGate(ctx) {
|
|
24
|
+
let args = ctx.args;
|
|
25
|
+
let rewritten = false;
|
|
26
|
+
for (const h of hooks) {
|
|
27
|
+
const d = readVerdict(await h.toolGate?.({ ...ctx, args }));
|
|
28
|
+
if (d.verdict !== 'go' || d.result !== undefined)
|
|
29
|
+
return { ...d, ...(rewritten && !d.args ? { args } : {}) };
|
|
30
|
+
if (d.args) {
|
|
31
|
+
args = d.args;
|
|
32
|
+
rewritten = true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return rewritten ? { verdict: 'go', args } : undefined;
|
|
36
|
+
},
|
|
37
|
+
async rewriteOutput(ctx) {
|
|
38
|
+
let result = ctx.result;
|
|
39
|
+
for (const h of hooks) {
|
|
40
|
+
const next = await h.rewriteOutput?.({ ...ctx, result });
|
|
41
|
+
if (typeof next === 'string')
|
|
42
|
+
result = next;
|
|
43
|
+
}
|
|
44
|
+
return result === ctx.result ? undefined : result;
|
|
45
|
+
},
|
|
46
|
+
async stopCheck(ctx) {
|
|
47
|
+
// Nothing or "stop" accepts the stop; the first objection ("go" back to work, or "pause") wins.
|
|
48
|
+
for (const h of hooks) {
|
|
49
|
+
const reply = await h.stopCheck?.(ctx);
|
|
50
|
+
if (reply && readVerdict(reply).verdict !== 'stop')
|
|
51
|
+
return reply;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAiFA,qDAAqD;AACrD,MAAM,UAAU,WAAW,CAAyB,KAAqC;IACvF,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAG,IAA2B;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO;QACL,KAAK,CAAC,UAAU,CAAC,GAAG;YAClB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACjD,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI;oBAAE,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,GAAG;YAChB,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YACpB,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,CAAqB,CAAC;gBAChF,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;oBAAE,OAAO,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC7G,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;oBACX,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;oBACd,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,aAAa,CAAC,GAAG;YACrB,IAAI,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YACxB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzD,IAAI,OAAO,IAAI,KAAK,QAAQ;oBAAE,MAAM,GAAG,IAAI,CAAC;YAC9C,CAAC;YACD,OAAO,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QACpD,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,GAAG;YACjB,gGAAgG;YAChG,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,MAAM;oBAAE,OAAO,KAAK,CAAC;YACnE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ghostmind-dev/agent — the engine every app builds its own agent from.
|
|
3
|
+
*
|
|
4
|
+
* The package is the loop and what it needs to run safely: the model seam (a worker through
|
|
5
|
+
* OpenRouter, Jev for decisions), budgets with a USD cap, go/pause/stop hooks, an append-only event
|
|
6
|
+
* log, and the seams an app fills in to make the agent its own. It is a library: import it, give it
|
|
7
|
+
* tools, run it. There is no server, no connection to call, and nothing here names an app.
|
|
8
|
+
*/
|
|
9
|
+
export { runAgent, subagentTool, passNode, parseLeakedCalls, leakFilter, LEAKED_CALL } from './loop.ts';
|
|
10
|
+
export type { AgentOptions, SubagentSpec, DecisionNode, NodeOutcome } from './loop.ts';
|
|
11
|
+
export { openrouter, modelCatalog, forgetCatalog, ModelError, OPENROUTER_URL, DEFAULT_DECISION_MODEL } from './model.ts';
|
|
12
|
+
export type { ModelProvider, OpenRouterConfig, ChatMessage, AssistantMessage, ChatRequest, ChatReply, ToolCall, ToolSpec, Question, Answer, DecideReply, ModelCard, ModelErrorCode, } from './model.ts';
|
|
13
|
+
export { foldTools, mcpToolset, forgivingArgs, readCall, stableJson } from './tools.ts';
|
|
14
|
+
export type { AgentTool, Toolset, ToolContext, ApprovalRequest, FoldOptions, McpLike, McpToolsetOptions } from './tools.ts';
|
|
15
|
+
export { readVerdict, combineHooks } from './hooks.ts';
|
|
16
|
+
export type { Hooks, Verdict, HookDecision, HookReply, StepContext, ToolGateContext, ToolGateDecision, OutputContext, StopContext } from './hooks.ts';
|
|
17
|
+
export { jevStopCheck, jevToolGate, ask, workLog, DEFAULT_CHECKS } from './jev.ts';
|
|
18
|
+
export type { JevCheck, JevGateOptions } from './jev.ts';
|
|
19
|
+
export { createGuide, levelFromCard, levelFromProfile, memoryProfiles, fileProfiles, DEFAULT_THRESHOLDS, LEVELS, ANSWER_NOW } from './guide.ts';
|
|
20
|
+
export type { Guide, Guidance, GuidanceLevel, GuideOptions, GuideProfile, ProfileStore, Thresholds, Checkpoint } from './guide.ts';
|
|
21
|
+
export { limits, overBudget, DEFAULT_BUDGET } from './budget.ts';
|
|
22
|
+
export type { Budget, Limits } from './budget.ts';
|
|
23
|
+
export { eventLog } from './events.ts';
|
|
24
|
+
export type { AgentEvent, EventLog, LoggedEvent, EventLogOptions } from './events.ts';
|
|
25
|
+
export { defaultPrompts, memorySessions } from './seams.ts';
|
|
26
|
+
export type { AgentTask, AgentResult, AgentStatus, PromptPack, MemoryStore, SessionStore, Approve, PostProcessor, PostContext, SkillSource, SkillMeta } from './seams.ts';
|
|
27
|
+
export { inlineSkills, dirSkills, pickSkills, skillsToolset, readFrontmatter, SKILL_TOOLS, NO_SKILL } from './skills.ts';
|
|
28
|
+
export type { InlineSkill } from './skills.ts';
|
|
29
|
+
export { askJevTool, askModelTool } from './consult.ts';
|
|
30
|
+
export type { AskModelOptions } from './consult.ts';
|
|
31
|
+
export { scriptedModel, firstOption } from './testing.ts';
|
|
32
|
+
export type { ScriptedModel, ScriptStep, ScriptedDecide } from './testing.ts';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxG,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEvF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACzH,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,SAAS,EACT,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxF,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5H,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtJ,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACnF,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChJ,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnI,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1K,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzH,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ghostmind-dev/agent — the engine every app builds its own agent from.
|
|
3
|
+
*
|
|
4
|
+
* The package is the loop and what it needs to run safely: the model seam (a worker through
|
|
5
|
+
* OpenRouter, Jev for decisions), budgets with a USD cap, go/pause/stop hooks, an append-only event
|
|
6
|
+
* log, and the seams an app fills in to make the agent its own. It is a library: import it, give it
|
|
7
|
+
* tools, run it. There is no server, no connection to call, and nothing here names an app.
|
|
8
|
+
*/
|
|
9
|
+
export { runAgent, subagentTool, passNode, parseLeakedCalls, leakFilter, LEAKED_CALL } from "./loop.js";
|
|
10
|
+
export { openrouter, modelCatalog, forgetCatalog, ModelError, OPENROUTER_URL, DEFAULT_DECISION_MODEL } from "./model.js";
|
|
11
|
+
export { foldTools, mcpToolset, forgivingArgs, readCall, stableJson } from "./tools.js";
|
|
12
|
+
export { readVerdict, combineHooks } from "./hooks.js";
|
|
13
|
+
export { jevStopCheck, jevToolGate, ask, workLog, DEFAULT_CHECKS } from "./jev.js";
|
|
14
|
+
export { createGuide, levelFromCard, levelFromProfile, memoryProfiles, fileProfiles, DEFAULT_THRESHOLDS, LEVELS, ANSWER_NOW } from "./guide.js";
|
|
15
|
+
export { limits, overBudget, DEFAULT_BUDGET } from "./budget.js";
|
|
16
|
+
export { eventLog } from "./events.js";
|
|
17
|
+
export { defaultPrompts, memorySessions } from "./seams.js";
|
|
18
|
+
export { inlineSkills, dirSkills, pickSkills, skillsToolset, readFrontmatter, SKILL_TOOLS, NO_SKILL } from "./skills.js";
|
|
19
|
+
export { askJevTool, askModelTool } from "./consult.js";
|
|
20
|
+
export { scriptedModel, firstOption } from "./testing.js";
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxG,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAiBzH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGhJ,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGzH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/jev.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jev behind the hooks — calibrated decisions an app can add to its own gates and checks.
|
|
3
|
+
*
|
|
4
|
+
* The built-in guidance lives in guide.ts (checkpoints the loop asks itself, sized to the model).
|
|
5
|
+
* This module is the explicit, app-owned variant.
|
|
6
|
+
*
|
|
7
|
+
* Jev is the engine's second model and its cheapest judge: it answers typed questions with
|
|
8
|
+
* probabilities, not prose, so it cannot be talked into agreeing, and at a fraction of a cent in
|
|
9
|
+
* well under a second it is affordable at every step. The loop already asks it whether there is a
|
|
10
|
+
* task at all and which skills a task needs, and offers `ask_jev` to the worker. This module puts it
|
|
11
|
+
* behind the hook vocabulary too, so an app can have Jev GATE a change or CHECK an answer, and a
|
|
12
|
+
* supervisor reads the same go / pause / stop it would from any other hook:
|
|
13
|
+
*
|
|
14
|
+
* jevStopCheck — when the worker stops, Jev answers yes/no questions about the answer against the
|
|
15
|
+
* work (the defaults: every part answered, every fact backed by a tool result, the
|
|
16
|
+
* expected form). A failed check sends the worker back with that check's feedback.
|
|
17
|
+
* jevToolGate — before a change (or any call), Jev judges whether it serves the person's goal;
|
|
18
|
+
* below the bar the run pauses for the person, or the call is refused.
|
|
19
|
+
*
|
|
20
|
+
* Both are opt-in: they cost a decision per stop / per gated call, and Potion's evaluation found
|
|
21
|
+
* the code check (an app's own stopCheck) catches most of what a second judge would. What they spend
|
|
22
|
+
* goes through the hook context's `spend`, so it counts toward the run's total and USD cap.
|
|
23
|
+
*/
|
|
24
|
+
import type { Hooks } from './hooks.ts';
|
|
25
|
+
import type { ChatMessage, ModelProvider, Question } from './model.ts';
|
|
26
|
+
/** The work so far as a compact log for Jev — the last steps weigh most. */
|
|
27
|
+
export declare function workLog(messages: readonly ChatMessage[]): ({
|
|
28
|
+
tool_result: string;
|
|
29
|
+
agent?: undefined;
|
|
30
|
+
calls?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
agent: string | null;
|
|
33
|
+
calls: string[] | undefined;
|
|
34
|
+
tool_result?: undefined;
|
|
35
|
+
} | {
|
|
36
|
+
[x: string]: string;
|
|
37
|
+
tool_result?: undefined;
|
|
38
|
+
agent?: undefined;
|
|
39
|
+
calls?: undefined;
|
|
40
|
+
})[];
|
|
41
|
+
export interface JevCheck {
|
|
42
|
+
/** A yes/no question about `task`, `final_answer` and `work`. */
|
|
43
|
+
question: string;
|
|
44
|
+
/** What the worker is told when the check fails. */
|
|
45
|
+
feedback: string;
|
|
46
|
+
/** Below this probability of yes, the check fails. Default 0.5. */
|
|
47
|
+
min?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The answer checks from Potion's dropped verdict node, minus the one Jev is documented to be bad at:
|
|
51
|
+
* "is every fact and number supported by the work" asks it to compare figures across a long
|
|
52
|
+
* transcript (counting, numbers and long context are its jaggedness). Keep questions atomic.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEFAULT_CHECKS: Record<string, JevCheck>;
|
|
55
|
+
/** A stopCheck that sends the worker back when Jev finds the answer falls short. */
|
|
56
|
+
export declare function jevStopCheck(provider: ModelProvider, checks?: Record<string, JevCheck>): NonNullable<Hooks['stopCheck']>;
|
|
57
|
+
export interface JevGateOptions {
|
|
58
|
+
/** The question about `goal`, `tool`, `args` and `change`. */
|
|
59
|
+
question?: string;
|
|
60
|
+
/** Below this probability of yes, the gate acts. Default 0.3. */
|
|
61
|
+
min?: number;
|
|
62
|
+
/** What happens below the bar: pause the run for the person (default), or refuse this call and go on. */
|
|
63
|
+
below?: 'pause' | 'refuse';
|
|
64
|
+
/** Gate every call, not only changes. Default false. */
|
|
65
|
+
everyCall?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** A toolGate where Jev judges whether a call serves the person's goal. */
|
|
68
|
+
export declare function jevToolGate(provider: ModelProvider, options?: JevGateOptions): NonNullable<Hooks['toolGate']>;
|
|
69
|
+
/** Ask Jev one question outside the loop — a convenience with the same cost accounting. */
|
|
70
|
+
export declare function ask(provider: ModelProvider, state: unknown, question: Question, signal?: AbortSignal): Promise<{
|
|
71
|
+
answer: import("./model.ts").Answer;
|
|
72
|
+
cost: number;
|
|
73
|
+
}>;
|
|
74
|
+
//# sourceMappingURL=jev.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.d.ts","sourceRoot":"","sources":["../src/jev.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,KAAK,EAAoB,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvE,4EAA4E;AAC5E,wBAAgB,OAAO,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE;;;;;;;;;;;;;KAWvD;AAED,MAAM,WAAW,QAAQ;IACvB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAGnD,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAkB,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAqBxI;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yGAAyG;IACzG,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAkBjH;AAED,2FAA2F;AAC3F,wBAAsB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,WAAW;;;GAI1G"}
|