@livx.cc/agentx 0.99.121 → 0.99.122
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 +2 -0
- package/dist/cli.d.ts +29 -2
- package/dist/cli.js +664 -240
- package/dist/cli.js.map +1 -1
- package/dist/directives.d.ts +15 -1
- package/dist/directives.js +47 -2
- package/dist/directives.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +337 -144
- package/dist/index.js.map +1 -1
- package/dist/{secondChannel-D33Wvruo.d.ts → secondChannel-BddfVzTp.d.ts} +101 -1
- package/package.json +1 -1
package/dist/directives.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ interface Directives {
|
|
|
6
6
|
engine?: string;
|
|
7
7
|
/** Session resume for this conversation (host-defined). */
|
|
8
8
|
resume?: boolean;
|
|
9
|
+
/** DELEGATE mode `[planner->worker]` (key `delegate`): the worker model; `model` (the left side) plans. */
|
|
10
|
+
delegate?: string;
|
|
11
|
+
/** ADVISOR mode `[worker<-advisor]` (key `advisor`): the advisor model; `model` (the left side) works. */
|
|
12
|
+
advisor?: string;
|
|
13
|
+
/** `[off]` / `[mode:off]` (key `mode`): clear a sticky delegate/advisor mode. */
|
|
14
|
+
modeOff?: boolean;
|
|
9
15
|
}
|
|
10
16
|
interface ParsedPrompt {
|
|
11
17
|
prompt: string;
|
|
@@ -25,7 +31,15 @@ type ModelResolver = (token: string) => ModelHit | {
|
|
|
25
31
|
} | null;
|
|
26
32
|
/** Vendor shorthand → provider id: `[cc-opus]` / `[cc/opus]` = `claude-code/opus`. Extend per host via options. */
|
|
27
33
|
declare const VENDOR_SHORTHAND: Record<string, string>;
|
|
34
|
+
/** Every key agentx understands. A host passing its own `keys` must list `delegate` / `advisor` / `mode` to honour
|
|
35
|
+
* `[a->b]` / `[a<-b]` / `[off]` (and their keyed forms `delegate:x`, `advisor:x`, `mode:off`). */
|
|
28
36
|
declare const DIRECTIVE_KEYS: string[];
|
|
37
|
+
/** `a->b` (delegate) / `a<-b` (advisor): the left side may be empty (keep the current model). */
|
|
38
|
+
declare function splitModePair(token: string): {
|
|
39
|
+
left: string;
|
|
40
|
+
op: '->' | '<-';
|
|
41
|
+
right: string;
|
|
42
|
+
} | null;
|
|
29
43
|
interface DirectiveOptions {
|
|
30
44
|
/** Host catalog lookup. Default: the one set by `setModelResolver` (none). */
|
|
31
45
|
resolveModel: ModelResolver | null;
|
|
@@ -71,4 +85,4 @@ interface EngineModels {
|
|
|
71
85
|
*/
|
|
72
86
|
declare function makeModelResolver(engines: () => EngineModels[]): ModelResolver;
|
|
73
87
|
|
|
74
|
-
export { DIRECTIVE_KEYS, type DirectiveOptions, type Directives, type EngineModels, type ModelHit, type ModelResolver, type ParsedPrompt, VENDOR_SHORTHAND, expandVendor, isDirectiveGroup, makeModelResolver, parseDirectives, resolveModelToken, setModelResolver, splitDirectiveGroups };
|
|
88
|
+
export { DIRECTIVE_KEYS, type DirectiveOptions, type Directives, type EngineModels, type ModelHit, type ModelResolver, type ParsedPrompt, VENDOR_SHORTHAND, expandVendor, isDirectiveGroup, makeModelResolver, parseDirectives, resolveModelToken, setModelResolver, splitDirectiveGroups, splitModePair };
|
package/dist/directives.js
CHANGED
|
@@ -4,7 +4,17 @@ var MODEL_ALIASES = { ...claudeModelAliases };
|
|
|
4
4
|
|
|
5
5
|
// src/directives.ts
|
|
6
6
|
var VENDOR_SHORTHAND = { cc: "claude-code", cur: "cursor", oa: "openai" };
|
|
7
|
-
var DIRECTIVE_KEYS = ["model", "turns", "thinking", "think", "effort", "engine", "resume"];
|
|
7
|
+
var DIRECTIVE_KEYS = ["model", "turns", "thinking", "think", "effort", "engine", "resume", "delegate", "advisor", "mode"];
|
|
8
|
+
function splitModePair(token) {
|
|
9
|
+
const i = token.search(/->|<-/);
|
|
10
|
+
if (i === -1) return null;
|
|
11
|
+
const right = token.slice(i + 2).trim();
|
|
12
|
+
return right ? { left: token.slice(0, i).trim(), op: token.slice(i, i + 2), right } : null;
|
|
13
|
+
}
|
|
14
|
+
var isModel = (t, p) => {
|
|
15
|
+
const h = resolveModelToken(t, p);
|
|
16
|
+
return !!h && "model" in h;
|
|
17
|
+
};
|
|
8
18
|
var defaultResolver = null;
|
|
9
19
|
function setModelResolver(fn) {
|
|
10
20
|
defaultResolver = fn;
|
|
@@ -49,6 +59,9 @@ function isDirectiveGroup(raw, o) {
|
|
|
49
59
|
const i = t.indexOf(":");
|
|
50
60
|
if (i !== -1) return p.keys.includes(t.slice(0, i).trim().toLowerCase());
|
|
51
61
|
const v = t.toLowerCase();
|
|
62
|
+
const pair = splitModePair(v);
|
|
63
|
+
if (pair) return p.keys.includes(pair.op === "->" ? "delegate" : "advisor") && (!!pair.left && isModel(pair.left, p) || isModel(pair.right, p));
|
|
64
|
+
if (v === "off") return p.keys.includes("mode");
|
|
52
65
|
return !!resolveModelToken(v, p) || p.catalogOnly && !!p.aliases[v] || p.keys.includes("turns") && /^\d+$/.test(v) || p.keys.includes("thinking") && THINK.includes(v);
|
|
53
66
|
});
|
|
54
67
|
}
|
|
@@ -102,6 +115,13 @@ function parseDirectives(text, o) {
|
|
|
102
115
|
p.warn(`[directives] Unknown directive key: "${key}"`);
|
|
103
116
|
continue;
|
|
104
117
|
}
|
|
118
|
+
if (key === "delegate" || key === "advisor") {
|
|
119
|
+
const hit = resolveModelToken(val2, p);
|
|
120
|
+
if (hit && "model" in hit) d[key] = hit.model;
|
|
121
|
+
else if (!hit && isQualifiedModel(val2) && !p.catalogOnly) d[key] = val2;
|
|
122
|
+
else fail(val2, hit);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
105
125
|
if (key === "model") {
|
|
106
126
|
const r2 = setModel(val2);
|
|
107
127
|
if (r2 === true) continue;
|
|
@@ -114,6 +134,26 @@ function parseDirectives(text, o) {
|
|
|
114
134
|
continue;
|
|
115
135
|
}
|
|
116
136
|
const val = t.toLowerCase();
|
|
137
|
+
const pair = splitModePair(val);
|
|
138
|
+
if (pair && p.keys.includes(pair.op === "->" ? "delegate" : "advisor")) {
|
|
139
|
+
const lhit = pair.left ? resolveModelToken(pair.left, p) : null, rhit = resolveModelToken(pair.right, p);
|
|
140
|
+
const lok = !pair.left || !!lhit && "model" in lhit, rok = !!rhit && "model" in rhit;
|
|
141
|
+
if (lok && rok) {
|
|
142
|
+
if (pair.left) setModel(pair.left);
|
|
143
|
+
if (pair.op === "->") d.delegate = rhit.model;
|
|
144
|
+
else d.advisor = rhit.model;
|
|
145
|
+
} else if (lok || rok) {
|
|
146
|
+
if (!lok) fail(pair.left, lhit);
|
|
147
|
+
else fail(pair.right, rhit);
|
|
148
|
+
} else p.warn(`[directives] Unknown models in "${t}"`);
|
|
149
|
+
pos++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (val === "off" && p.keys.includes("mode")) {
|
|
153
|
+
d.modeOff = true;
|
|
154
|
+
pos++;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
117
157
|
const r = pos === 0 ? setModel(val) : null;
|
|
118
158
|
if (r === true) {
|
|
119
159
|
} else if (pos <= 1 && /^\d+$/.test(val) && p.keys.includes("turns")) d.turns = parseInt(val, 10);
|
|
@@ -145,6 +185,10 @@ function applyKey(d, key, val, warn) {
|
|
|
145
185
|
case "engine":
|
|
146
186
|
d.engine = val;
|
|
147
187
|
break;
|
|
188
|
+
case "mode":
|
|
189
|
+
if (val === "off") d.modeOff = true;
|
|
190
|
+
else warn(`[directives] Invalid mode value: "${val}"`);
|
|
191
|
+
break;
|
|
148
192
|
case "resume":
|
|
149
193
|
if (["on", "true", "1"].includes(val)) d.resume = true;
|
|
150
194
|
else if (["off", "false", "0"].includes(val)) d.resume = false;
|
|
@@ -177,6 +221,7 @@ export {
|
|
|
177
221
|
parseDirectives,
|
|
178
222
|
resolveModelToken,
|
|
179
223
|
setModelResolver,
|
|
180
|
-
splitDirectiveGroups
|
|
224
|
+
splitDirectiveGroups,
|
|
225
|
+
splitModePair
|
|
181
226
|
};
|
|
182
227
|
//# sourceMappingURL=directives.js.map
|
package/dist/directives.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/models.ts","../src/directives.ts"],"sourcesContent":["/**\n * Model aliasing + mid-conversation switch resolution — pure; aliases come from ai.libx.js's catalog.\n *\n * Harness-level so every agentx consumer (unclaw, para-chat, …) resolves `[opus]`-style\n * aliases, gates by an allow-list, and announces a switch the same way. Policy (which models\n * a caller may use) and session state (the prior model) stay with the consumer; this module\n * is the shared mechanism.\n */\nimport { claudeModelAliases } from 'ai.libx.js';\n\n/** Canonical short aliases → concrete Anthropic model ids — DERIVED from ai.libx.js's catalog (newest entry per\n * family, plus versioned `opus-5`-style aliases). Never hand-pin an id here: a new model = one catalog entry. */\nexport const MODEL_ALIASES: Record<string, string> = { ...claudeModelAliases };\n\n/** Newest catalog model of a Claude family as a provider-qualified id (`'sonnet'` → `'anthropic/claude-sonnet-5-5'`).\n * Use this for every default/tier — a literal dated id goes stale the day the next model ships. */\nexport function latestClaude(family: 'fable' | 'opus' | 'sonnet' | 'haiku', provider = 'anthropic'): string {\n const id = MODEL_ALIASES[family];\n if (!id) throw new Error(`ai.libx.js catalog has no Claude ${family} model`);\n return `${provider}/${id}`;\n}\n\n/** Resolve an alias to a concrete id. A provider prefix (\"anthropic/\") is preserved; unknown ids pass through. */\nexport function resolveModelAlias(input: string): string {\n const slash = input.indexOf('/');\n const prefix = slash === -1 ? '' : input.slice(0, slash + 1);\n const rest = slash === -1 ? input : input.slice(slash + 1);\n // claude-code's catalogue IS the aliases (claude-code/opus); expanding them yields an unknown id.\n if (prefix === 'claude-code/') return input;\n return prefix + (MODEL_ALIASES[rest.toLowerCase()] ?? rest);\n}\n\n/** The provider of a model id (\"cursor/x\" -> \"cursor\"). Provider-specific `providerOptions` are only\n * portable within the same provider — leaking them across is a hard 400.\n *\n * A BARE id is the common case, not the exception: `resolveModelAlias('haiku')` yields\n * `claude-haiku-5-5` with no prefix (ai.libx.js resolves it fuzzily downstream), so reading\n * only the literal \"/\" made every aliased child look like a provider switch and silently dropped the\n * parent's options. The fix belongs HERE — the alias table must keep emitting the ids ai.libx.js\n * expects, and the comparison is provider identity, not string identity.\n *\n * A bare id we can't attribute is UNKNOWN, not a shared provider: it gets a per-id marker so two\n * different unknown ids never compare equal (returning \"\" for both made them look like one provider\n * and would have leaked one host's options onto the other's model). An unknown id still compares\n * equal to ITSELF, so a child staying on the parent's exact model keeps the parent's options. */\nexport function modelProvider(model: string): string {\n const i = model.indexOf('/');\n if (i !== -1) return model.slice(0, i);\n if (/^claude-/i.test(model)) return 'anthropic';\n return `?${model}`; // unknown: identity-scoped, never equal to a different unknown id\n}\n\n/** Short, human-friendly name for a resolved model id (e.g. \"anthropic/claude-opus-4-8\" → \"opus\"). */\nexport function modelShortLabel(model?: string): string {\n if (!model) return 'default';\n const id = model.split('/').pop()!;\n return id.replace(/^claude-/, '').replace(/-\\d.*$/, '');\n}\n\nexport interface ResolveModelSwitchOpts {\n /** Model requested for this turn (e.g. from an inline directive). Undefined = keep `current`. */\n requested?: string;\n /** The turn's default/current model when nothing is requested. */\n current: string;\n /** The session's prior resolved model — drives change detection + the notice. */\n prior?: string;\n /** If set, `requested` must match one of these (by short label) or it's denied and `current` is kept. */\n allowed?: string[];\n /** Announcement formatter. Default: `_[switching from x to y]_\\n\\n`. */\n format?: (from: string, to: string) => string;\n}\n\nexport interface ModelSwitch {\n /** The model to run this turn. */\n model: string;\n /** True when `requested` was rejected by `allowed` and `model` fell back to `current`. */\n denied: boolean;\n /** Inline notice to surface when the model actually changed vs `prior`, else undefined. */\n notice?: string;\n}\n\n/**\n * Resolve which model a turn runs, given an optional request, an allow-list, and the prior model.\n * Comparisons are by short label so provider-prefixed and dated ids unify\n * (\"anthropic/claude-opus-4-8\" ≡ \"claude-opus-4-8\" ≡ \"opus\").\n */\nexport function resolveModelSwitch(opts: ResolveModelSwitchOpts): ModelSwitch {\n const { requested, current, prior, allowed } = opts;\n if (!requested) return { model: current, denied: false };\n if (allowed && !allowed.some((a) => modelShortLabel(a) === modelShortLabel(requested))) {\n return { model: current, denied: true };\n }\n const fmt = opts.format ?? ((from: string, to: string) => `_[switching from ${from} to ${to}]_\\n\\n`);\n const changed = prior !== undefined && modelShortLabel(prior) !== modelShortLabel(requested);\n return {\n model: requested,\n denied: false,\n notice: changed ? fmt(modelShortLabel(prior!), modelShortLabel(requested)) : undefined,\n };\n}\n","/**\n * Inline prompt directives — `[opus] fix x`, `[cc-opus, 50] …`, `[model:openai/gpt-5.5] …` — pure,\n * dependency-free. A message may open with one or more `[..]` groups that pick the model (and, for\n * hosts that honour them, turns/thinking/effort/engine/resume); the rest is the prompt.\n *\n * Shared by every agentx host (unclaw/Shraga, Bare) so the grammar and its edge cases live once:\n * multi-group, strict mode (bracketed prose stays prose), and an unresolvable EXPLICIT model is\n * reported (`unresolvedModel`) rather than dropped — dropping it ran the turn on the previous model.\n *\n * Model tokens resolve through the alias table and an injected `ModelResolver` (the host's catalog,\n * see `makeModelResolver`). `<vendor>-<model>` / `<vendor>/<model>` shorthands (`cc-opus` →\n * `claude-code/opus`, see `VENDOR_SHORTHAND`) select a model only when they resolve (`[cc-by] …` stays prose).\n */\nimport { MODEL_ALIASES } from './models';\n\nexport interface Directives {\n model?: string;\n turns?: number;\n thinking?: 'adaptive' | 'enabled' | 'disabled';\n effort?: 'low' | 'medium' | 'high' | 'max';\n engine?: string;\n /** Session resume for this conversation (host-defined). */\n resume?: boolean;\n}\n\nexport interface ParsedPrompt {\n prompt: string;\n directives: Directives;\n /** An EXPLICIT model selection nothing could resolve. The caller must fail the turn, never run the old model. */\n unresolvedModel?: string;\n /** When `unresolvedModel` matched several catalog ids: the candidates (use the full id). */\n ambiguous?: string[];\n}\n\nexport type ModelHit = { model: string; engine?: string };\n/** Resolves a model token against a host catalog. `{ ambiguous }` = several ids match; never guess. */\nexport type ModelResolver = (token: string) => ModelHit | { ambiguous: string[] } | null;\n\n/** Vendor shorthand → provider id: `[cc-opus]` / `[cc/opus]` = `claude-code/opus`. Extend per host via options. */\nexport const VENDOR_SHORTHAND: Record<string, string> = { cc: 'claude-code', cur: 'cursor', oa: 'openai' };\n\nexport const DIRECTIVE_KEYS = ['model', 'turns', 'thinking', 'think', 'effort', 'engine', 'resume'];\n\nexport interface DirectiveOptions {\n /** Host catalog lookup. Default: the one set by `setModelResolver` (none). */\n resolveModel: ModelResolver | null;\n /** Try the catalog before the alias table (Bare: `[opus]` = the catalog's `claude-code/opus`). */\n resolverFirst: boolean;\n aliases: Record<string, string>;\n vendors: Record<string, string>;\n /** Keys this host honours; positional turns/thinking count only when `turns`/`thinking` are listed. */\n keys: string[];\n /** Every group, the first included, must look like directives (else it stays prompt text). */\n strict: boolean;\n /** Resolve to catalog ids ONLY (Bare): no alias-table fallback, a full id the catalog lacks is refused, and a\n * bare word matches an id's tail only when it is a known alias or carries a digit (`[auto]` stays prose). */\n catalogOnly: boolean;\n warn: (msg: string) => void;\n}\n\nlet defaultResolver: ModelResolver | null = null;\n/** Process-wide default resolver (Shraga's engine registry injects it once). Per-call options override. */\nexport function setModelResolver(fn: ModelResolver | null): void { defaultResolver = fn; }\n\nconst opt = (o?: Partial<DirectiveOptions>): DirectiveOptions => ({\n resolveModel: defaultResolver, resolverFirst: false, aliases: MODEL_ALIASES, vendors: VENDOR_SHORTHAND,\n keys: DIRECTIVE_KEYS, strict: false, catalogOnly: false, warn: (m) => console.warn(m), ...o,\n});\n\n// A group ends at whitespace or the end: `[opus](http://x)` is a markdown link, not a directive.\nconst DIRECTIVE_RE = /^\\s*\\[([^\\]]*)\\](?=\\s|$)\\s*([\\s\\S]*)/;\nconst isQualifiedModel = (v: string) => /^[a-z0-9._-]+\\/[a-z0-9./_-]+$/.test(v);\n\n/** `cc-opus` / `cc/opus` → `claude-code/opus`; a full `claude-code/opus` is returned as is. Else null. */\nexport function expandVendor(token: string, vendors: Record<string, string> = VENDOR_SHORTHAND): string | null {\n const v = token.trim().toLowerCase();\n const m = v.match(/^([a-z0-9]+)[-/](.+)$/);\n if (m && vendors[m[1]]) return `${vendors[m[1]]}/${m[2]}`;\n const slash = v.indexOf('/');\n return slash > 0 && Object.values(vendors).includes(v.slice(0, slash)) ? v : null;\n}\n\n/** Resolve one model token: vendor shorthand → catalog exact id; else alias table + catalog in the configured order. */\nexport function resolveModelToken(token: string, o?: Partial<DirectiveOptions>): ModelHit | { ambiguous: string[] } | null {\n const p = opt(o);\n const v = token.trim().toLowerCase();\n const vendored = expandVendor(v, p.vendors);\n if (vendored) return p.resolveModel ? p.resolveModel(vendored) : p.catalogOnly ? null : { model: vendored }; // no catalog: trust the explicit id\n if (p.catalogOnly) return v.includes('/') || p.aliases[v] || /\\d/.test(v) ? p.resolveModel?.(v) ?? null : null;\n const alias = p.aliases[v] ? { model: p.aliases[v] } : null;\n if (!p.resolverFirst) return alias ?? p.resolveModel?.(v) ?? null;\n const hit = p.resolveModel?.(v) ?? null;\n return hit && 'model' in hit ? hit : alias ?? hit;\n}\n\nconst THINK = ['think', 'adaptive', 'nothink', 'nothinking'];\n\n/** Does a bracket group look like directives (vs. prompt text that happens to start with `[`)? */\nexport function isDirectiveGroup(raw: string, o?: Partial<DirectiveOptions>): boolean {\n const p = opt(o);\n const tokens = raw.split(',').map((t) => t.trim()).filter(Boolean);\n if (!tokens.length) return false;\n return tokens.every((t) => {\n const i = t.indexOf(':');\n if (i !== -1) return p.keys.includes(t.slice(0, i).trim().toLowerCase());\n const v = t.toLowerCase();\n return !!resolveModelToken(v, p) || (p.catalogOnly && !!p.aliases[v])\n || (p.keys.includes('turns') && /^\\d+$/.test(v)) || (p.keys.includes('thinking') && THINK.includes(v));\n });\n}\n\n/** Splits the leading `[..]` directive groups off a prompt — EVERY consecutive leading group. */\nexport function splitDirectiveGroups(text: string, o?: Partial<DirectiveOptions>): { groups: string[]; body: string } {\n const p = opt(o);\n let rest = text;\n const groups: string[] = [];\n for (;;) {\n const m = rest.match(DIRECTIVE_RE);\n if (!m) break;\n const g = m[1].trim();\n if ((groups.length || p.strict) && g && !isDirectiveGroup(g, p)) break;\n groups.push(g);\n rest = m[2];\n }\n return { groups, body: rest };\n}\n\nexport function parseDirectives(text: string, o?: Partial<DirectiveOptions>): ParsedPrompt {\n const p = opt(o);\n const { groups, body } = splitDirectiveGroups(text, p);\n if (!groups.length) return { prompt: text, directives: {} };\n const prompt = body.trim();\n const raw = groups.filter(Boolean).join(',');\n if (!raw) return { prompt, directives: {} };\n\n const d: Directives = {};\n const out: ParsedPrompt = { prompt, directives: d };\n const tokens = raw.split(',');\n // A keyed sibling proves the group is directives, so an unresolvable leading model there IS a dropped selection.\n const proven = tokens.some((t) => { const i = t.indexOf(':'); return i !== -1 && p.keys.includes(t.slice(0, i).trim().toLowerCase()); });\n const fail = (tok: string, hit: ReturnType<typeof resolveModelToken>) => {\n out.unresolvedModel ??= tok;\n if (hit && 'ambiguous' in hit) out.ambiguous ??= hit.ambiguous;\n };\n const setModel = (val: string): boolean | ReturnType<typeof resolveModelToken> => {\n const hit = resolveModelToken(val, p);\n if (!hit || !('model' in hit)) return hit;\n d.model = hit.model;\n if (hit.engine && !d.engine) d.engine = hit.engine; // an engine-owned model implies its engine, never over `[engine:x]`\n return true;\n };\n\n let pos = 0;\n for (const token of tokens) {\n const t = token.trim();\n if (!t) continue;\n const i = t.indexOf(':');\n if (i !== -1) {\n const key = t.slice(0, i).trim().toLowerCase(), val = t.slice(i + 1).trim().toLowerCase();\n if (!p.keys.includes(key)) { p.warn(`[directives] Unknown directive key: \"${key}\"`); continue; }\n if (key === 'model') {\n const r = setModel(val);\n if (r === true) continue;\n // A plain `provider/model` with no catalog to check is concrete — the engine owns the verdict.\n if (!r && isQualifiedModel(val) && !p.catalogOnly) { d.model = val; continue; }\n fail(val, r as any);\n } else applyKey(d, key, val, p.warn);\n continue;\n }\n const val = t.toLowerCase();\n const r = pos === 0 ? setModel(val) : null;\n if (r === true) { /* model */ }\n else if (pos <= 1 && /^\\d+$/.test(val) && p.keys.includes('turns')) d.turns = parseInt(val, 10);\n else if (['think', 'adaptive'].includes(val) && p.keys.includes('thinking')) d.thinking = 'adaptive';\n else if (['nothink', 'nothinking'].includes(val) && p.keys.includes('thinking')) d.thinking = 'disabled';\n else if (pos === 0) {\n // Ambiguous tokens (and, catalog-only, a known alias the catalog lacks) are model selections; a plain unknown one\n // only with a keyed sibling. An unresolved vendor form (`[cc-by]`) is not a selection.\n if (r || (p.catalogOnly && p.aliases[val]) || (proven && !isQualifiedModel(val))) fail(t, r as any);\n p.warn(`[directives] Unknown model: \"${t}\"`);\n }\n pos++;\n }\n return out;\n}\n\nfunction applyKey(d: Directives, key: string, val: string, warn: (m: string) => void): void {\n switch (key) {\n case 'turns': if (/^\\d+$/.test(val)) d.turns = parseInt(val, 10); else warn(`[directives] Invalid turns value: \"${val}\"`); break;\n case 'thinking':\n case 'think': if (['adaptive', 'enabled', 'disabled'].includes(val)) d.thinking = val as Directives['thinking']; else warn(`[directives] Invalid thinking value: \"${val}\"`); break;\n case 'effort': if (['low', 'medium', 'high', 'max'].includes(val)) d.effort = val as Directives['effort']; else warn(`[directives] Invalid effort value: \"${val}\"`); break;\n case 'engine': d.engine = val; break;\n case 'resume':\n if (['on', 'true', '1'].includes(val)) d.resume = true;\n else if (['off', 'false', '0'].includes(val)) d.resume = false;\n else warn(`[directives] Invalid resume value: \"${val}\"`);\n break;\n }\n}\n\n/** Engine/provider → the model ids it advertises. */\nexport interface EngineModels { name: string; models: { value: string }[] }\n\n/**\n * A resolver over host catalogs: exact id first, then the bare suffix after the provider prefix —\n * ONLY when unambiguous across engines (`{ ambiguous }` otherwise, never the first match).\n */\nexport function makeModelResolver(engines: () => EngineModels[]): ModelResolver {\n return (token) => {\n const t = token.toLowerCase();\n const hits: ModelHit[] = [];\n for (const { name, models } of engines()) {\n for (const m of models) {\n if (!m.value) continue;\n const v = m.value.toLowerCase();\n if (v === t) return { model: m.value, engine: name };\n if (v.slice(v.lastIndexOf('/') + 1) === t && !hits.some((h) => h.model === m.value)) hits.push({ model: m.value, engine: name });\n }\n }\n if (hits.length === 1) return hits[0];\n return hits.length > 1 ? { ambiguous: hits.map((h) => h.model) } : null;\n };\n}\n"],"mappings":"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","names":["val","r"]}
|
|
1
|
+
{"version":3,"sources":["../src/models.ts","../src/directives.ts"],"sourcesContent":["/**\n * Model aliasing + mid-conversation switch resolution — pure; aliases come from ai.libx.js's catalog.\n *\n * Harness-level so every agentx consumer (unclaw, para-chat, …) resolves `[opus]`-style\n * aliases, gates by an allow-list, and announces a switch the same way. Policy (which models\n * a caller may use) and session state (the prior model) stay with the consumer; this module\n * is the shared mechanism.\n */\nimport { claudeModelAliases } from 'ai.libx.js';\n\n/** Canonical short aliases → concrete Anthropic model ids — DERIVED from ai.libx.js's catalog (newest entry per\n * family, plus versioned `opus-5`-style aliases). Never hand-pin an id here: a new model = one catalog entry. */\nexport const MODEL_ALIASES: Record<string, string> = { ...claudeModelAliases };\n\n/** Newest catalog model of a Claude family as a provider-qualified id (`'sonnet'` → `'anthropic/claude-sonnet-5-5'`).\n * Use this for every default/tier — a literal dated id goes stale the day the next model ships. */\nexport function latestClaude(family: 'fable' | 'opus' | 'sonnet' | 'haiku', provider = 'anthropic'): string {\n const id = MODEL_ALIASES[family];\n if (!id) throw new Error(`ai.libx.js catalog has no Claude ${family} model`);\n return `${provider}/${id}`;\n}\n\n/** Resolve an alias to a concrete id. A provider prefix (\"anthropic/\") is preserved; unknown ids pass through. */\nexport function resolveModelAlias(input: string): string {\n const slash = input.indexOf('/');\n const prefix = slash === -1 ? '' : input.slice(0, slash + 1);\n const rest = slash === -1 ? input : input.slice(slash + 1);\n // claude-code's catalogue IS the aliases (claude-code/opus); expanding them yields an unknown id.\n if (prefix === 'claude-code/') return input;\n return prefix + (MODEL_ALIASES[rest.toLowerCase()] ?? rest);\n}\n\n/** The provider of a model id (\"cursor/x\" -> \"cursor\"). Provider-specific `providerOptions` are only\n * portable within the same provider — leaking them across is a hard 400.\n *\n * A BARE id is the common case, not the exception: `resolveModelAlias('haiku')` yields\n * `claude-haiku-5-5` with no prefix (ai.libx.js resolves it fuzzily downstream), so reading\n * only the literal \"/\" made every aliased child look like a provider switch and silently dropped the\n * parent's options. The fix belongs HERE — the alias table must keep emitting the ids ai.libx.js\n * expects, and the comparison is provider identity, not string identity.\n *\n * A bare id we can't attribute is UNKNOWN, not a shared provider: it gets a per-id marker so two\n * different unknown ids never compare equal (returning \"\" for both made them look like one provider\n * and would have leaked one host's options onto the other's model). An unknown id still compares\n * equal to ITSELF, so a child staying on the parent's exact model keeps the parent's options. */\nexport function modelProvider(model: string): string {\n const i = model.indexOf('/');\n if (i !== -1) return model.slice(0, i);\n if (/^claude-/i.test(model)) return 'anthropic';\n return `?${model}`; // unknown: identity-scoped, never equal to a different unknown id\n}\n\n/** Short, human-friendly name for a resolved model id (e.g. \"anthropic/claude-opus-4-8\" → \"opus\"). */\nexport function modelShortLabel(model?: string): string {\n if (!model) return 'default';\n const id = model.split('/').pop()!;\n return id.replace(/^claude-/, '').replace(/-\\d.*$/, '');\n}\n\nexport interface ResolveModelSwitchOpts {\n /** Model requested for this turn (e.g. from an inline directive). Undefined = keep `current`. */\n requested?: string;\n /** The turn's default/current model when nothing is requested. */\n current: string;\n /** The session's prior resolved model — drives change detection + the notice. */\n prior?: string;\n /** If set, `requested` must match one of these (by short label) or it's denied and `current` is kept. */\n allowed?: string[];\n /** Announcement formatter. Default: `_[switching from x to y]_\\n\\n`. */\n format?: (from: string, to: string) => string;\n}\n\nexport interface ModelSwitch {\n /** The model to run this turn. */\n model: string;\n /** True when `requested` was rejected by `allowed` and `model` fell back to `current`. */\n denied: boolean;\n /** Inline notice to surface when the model actually changed vs `prior`, else undefined. */\n notice?: string;\n}\n\n/**\n * Resolve which model a turn runs, given an optional request, an allow-list, and the prior model.\n * Comparisons are by short label so provider-prefixed and dated ids unify\n * (\"anthropic/claude-opus-4-8\" ≡ \"claude-opus-4-8\" ≡ \"opus\").\n */\nexport function resolveModelSwitch(opts: ResolveModelSwitchOpts): ModelSwitch {\n const { requested, current, prior, allowed } = opts;\n if (!requested) return { model: current, denied: false };\n if (allowed && !allowed.some((a) => modelShortLabel(a) === modelShortLabel(requested))) {\n return { model: current, denied: true };\n }\n const fmt = opts.format ?? ((from: string, to: string) => `_[switching from ${from} to ${to}]_\\n\\n`);\n const changed = prior !== undefined && modelShortLabel(prior) !== modelShortLabel(requested);\n return {\n model: requested,\n denied: false,\n notice: changed ? fmt(modelShortLabel(prior!), modelShortLabel(requested)) : undefined,\n };\n}\n","/**\n * Inline prompt directives — `[opus] fix x`, `[cc-opus, 50] …`, `[model:openai/gpt-5.5] …` — pure,\n * dependency-free. A message may open with one or more `[..]` groups that pick the model (and, for\n * hosts that honour them, turns/thinking/effort/engine/resume); the rest is the prompt.\n *\n * Shared by every agentx host (unclaw/Shraga, Bare) so the grammar and its edge cases live once:\n * multi-group, strict mode (bracketed prose stays prose), and an unresolvable EXPLICIT model is\n * reported (`unresolvedModel`) rather than dropped — dropping it ran the turn on the previous model.\n *\n * Model tokens resolve through the alias table and an injected `ModelResolver` (the host's catalog,\n * see `makeModelResolver`). `<vendor>-<model>` / `<vendor>/<model>` shorthands (`cc-opus` →\n * `claude-code/opus`, see `VENDOR_SHORTHAND`) select a model only when they resolve (`[cc-by] …` stays prose).\n */\nimport { MODEL_ALIASES } from './models';\n\nexport interface Directives {\n model?: string;\n turns?: number;\n thinking?: 'adaptive' | 'enabled' | 'disabled';\n effort?: 'low' | 'medium' | 'high' | 'max';\n engine?: string;\n /** Session resume for this conversation (host-defined). */\n resume?: boolean;\n /** DELEGATE mode `[planner->worker]` (key `delegate`): the worker model; `model` (the left side) plans. */\n delegate?: string;\n /** ADVISOR mode `[worker<-advisor]` (key `advisor`): the advisor model; `model` (the left side) works. */\n advisor?: string;\n /** `[off]` / `[mode:off]` (key `mode`): clear a sticky delegate/advisor mode. */\n modeOff?: boolean;\n}\n\nexport interface ParsedPrompt {\n prompt: string;\n directives: Directives;\n /** An EXPLICIT model selection nothing could resolve. The caller must fail the turn, never run the old model. */\n unresolvedModel?: string;\n /** When `unresolvedModel` matched several catalog ids: the candidates (use the full id). */\n ambiguous?: string[];\n}\n\nexport type ModelHit = { model: string; engine?: string };\n/** Resolves a model token against a host catalog. `{ ambiguous }` = several ids match; never guess. */\nexport type ModelResolver = (token: string) => ModelHit | { ambiguous: string[] } | null;\n\n/** Vendor shorthand → provider id: `[cc-opus]` / `[cc/opus]` = `claude-code/opus`. Extend per host via options. */\nexport const VENDOR_SHORTHAND: Record<string, string> = { cc: 'claude-code', cur: 'cursor', oa: 'openai' };\n\n/** Every key agentx understands. A host passing its own `keys` must list `delegate` / `advisor` / `mode` to honour\n * `[a->b]` / `[a<-b]` / `[off]` (and their keyed forms `delegate:x`, `advisor:x`, `mode:off`). */\nexport const DIRECTIVE_KEYS = ['model', 'turns', 'thinking', 'think', 'effort', 'engine', 'resume', 'delegate', 'advisor', 'mode'];\n\n/** `a->b` (delegate) / `a<-b` (advisor): the left side may be empty (keep the current model). */\nexport function splitModePair(token: string): { left: string; op: '->' | '<-'; right: string } | null {\n const i = token.search(/->|<-/);\n if (i === -1) return null;\n const right = token.slice(i + 2).trim();\n return right ? { left: token.slice(0, i).trim(), op: token.slice(i, i + 2) as '->' | '<-', right } : null;\n}\nconst isModel = (t: string, p: DirectiveOptions) => { const h = resolveModelToken(t, p); return !!h && 'model' in h; };\n\nexport interface DirectiveOptions {\n /** Host catalog lookup. Default: the one set by `setModelResolver` (none). */\n resolveModel: ModelResolver | null;\n /** Try the catalog before the alias table (Bare: `[opus]` = the catalog's `claude-code/opus`). */\n resolverFirst: boolean;\n aliases: Record<string, string>;\n vendors: Record<string, string>;\n /** Keys this host honours; positional turns/thinking count only when `turns`/`thinking` are listed. */\n keys: string[];\n /** Every group, the first included, must look like directives (else it stays prompt text). */\n strict: boolean;\n /** Resolve to catalog ids ONLY (Bare): no alias-table fallback, a full id the catalog lacks is refused, and a\n * bare word matches an id's tail only when it is a known alias or carries a digit (`[auto]` stays prose). */\n catalogOnly: boolean;\n warn: (msg: string) => void;\n}\n\nlet defaultResolver: ModelResolver | null = null;\n/** Process-wide default resolver (Shraga's engine registry injects it once). Per-call options override. */\nexport function setModelResolver(fn: ModelResolver | null): void { defaultResolver = fn; }\n\nconst opt = (o?: Partial<DirectiveOptions>): DirectiveOptions => ({\n resolveModel: defaultResolver, resolverFirst: false, aliases: MODEL_ALIASES, vendors: VENDOR_SHORTHAND,\n keys: DIRECTIVE_KEYS, strict: false, catalogOnly: false, warn: (m) => console.warn(m), ...o,\n});\n\n// A group ends at whitespace or the end: `[opus](http://x)` is a markdown link, not a directive.\nconst DIRECTIVE_RE = /^\\s*\\[([^\\]]*)\\](?=\\s|$)\\s*([\\s\\S]*)/;\nconst isQualifiedModel = (v: string) => /^[a-z0-9._-]+\\/[a-z0-9./_-]+$/.test(v);\n\n/** `cc-opus` / `cc/opus` → `claude-code/opus`; a full `claude-code/opus` is returned as is. Else null. */\nexport function expandVendor(token: string, vendors: Record<string, string> = VENDOR_SHORTHAND): string | null {\n const v = token.trim().toLowerCase();\n const m = v.match(/^([a-z0-9]+)[-/](.+)$/);\n if (m && vendors[m[1]]) return `${vendors[m[1]]}/${m[2]}`;\n const slash = v.indexOf('/');\n return slash > 0 && Object.values(vendors).includes(v.slice(0, slash)) ? v : null;\n}\n\n/** Resolve one model token: vendor shorthand → catalog exact id; else alias table + catalog in the configured order. */\nexport function resolveModelToken(token: string, o?: Partial<DirectiveOptions>): ModelHit | { ambiguous: string[] } | null {\n const p = opt(o);\n const v = token.trim().toLowerCase();\n const vendored = expandVendor(v, p.vendors);\n if (vendored) return p.resolveModel ? p.resolveModel(vendored) : p.catalogOnly ? null : { model: vendored }; // no catalog: trust the explicit id\n if (p.catalogOnly) return v.includes('/') || p.aliases[v] || /\\d/.test(v) ? p.resolveModel?.(v) ?? null : null;\n const alias = p.aliases[v] ? { model: p.aliases[v] } : null;\n if (!p.resolverFirst) return alias ?? p.resolveModel?.(v) ?? null;\n const hit = p.resolveModel?.(v) ?? null;\n return hit && 'model' in hit ? hit : alias ?? hit;\n}\n\nconst THINK = ['think', 'adaptive', 'nothink', 'nothinking'];\n\n/** Does a bracket group look like directives (vs. prompt text that happens to start with `[`)? */\nexport function isDirectiveGroup(raw: string, o?: Partial<DirectiveOptions>): boolean {\n const p = opt(o);\n const tokens = raw.split(',').map((t) => t.trim()).filter(Boolean);\n if (!tokens.length) return false;\n return tokens.every((t) => {\n const i = t.indexOf(':');\n if (i !== -1) return p.keys.includes(t.slice(0, i).trim().toLowerCase());\n const v = t.toLowerCase();\n const pair = splitModePair(v);\n if (pair) return p.keys.includes(pair.op === '->' ? 'delegate' : 'advisor') && ((!!pair.left && isModel(pair.left, p)) || isModel(pair.right, p)); // one resolved side makes it explicit: the other one's miss is reported\n if (v === 'off') return p.keys.includes('mode');\n return !!resolveModelToken(v, p) || (p.catalogOnly && !!p.aliases[v])\n || (p.keys.includes('turns') && /^\\d+$/.test(v)) || (p.keys.includes('thinking') && THINK.includes(v));\n });\n}\n\n/** Splits the leading `[..]` directive groups off a prompt — EVERY consecutive leading group. */\nexport function splitDirectiveGroups(text: string, o?: Partial<DirectiveOptions>): { groups: string[]; body: string } {\n const p = opt(o);\n let rest = text;\n const groups: string[] = [];\n for (;;) {\n const m = rest.match(DIRECTIVE_RE);\n if (!m) break;\n const g = m[1].trim();\n if ((groups.length || p.strict) && g && !isDirectiveGroup(g, p)) break;\n groups.push(g);\n rest = m[2];\n }\n return { groups, body: rest };\n}\n\nexport function parseDirectives(text: string, o?: Partial<DirectiveOptions>): ParsedPrompt {\n const p = opt(o);\n const { groups, body } = splitDirectiveGroups(text, p);\n if (!groups.length) return { prompt: text, directives: {} };\n const prompt = body.trim();\n const raw = groups.filter(Boolean).join(',');\n if (!raw) return { prompt, directives: {} };\n\n const d: Directives = {};\n const out: ParsedPrompt = { prompt, directives: d };\n const tokens = raw.split(',');\n // A keyed sibling proves the group is directives, so an unresolvable leading model there IS a dropped selection.\n const proven = tokens.some((t) => { const i = t.indexOf(':'); return i !== -1 && p.keys.includes(t.slice(0, i).trim().toLowerCase()); });\n const fail = (tok: string, hit: ReturnType<typeof resolveModelToken>) => {\n out.unresolvedModel ??= tok;\n if (hit && 'ambiguous' in hit) out.ambiguous ??= hit.ambiguous;\n };\n const setModel = (val: string): boolean | ReturnType<typeof resolveModelToken> => {\n const hit = resolveModelToken(val, p);\n if (!hit || !('model' in hit)) return hit;\n d.model = hit.model;\n if (hit.engine && !d.engine) d.engine = hit.engine; // an engine-owned model implies its engine, never over `[engine:x]`\n return true;\n };\n\n let pos = 0;\n for (const token of tokens) {\n const t = token.trim();\n if (!t) continue;\n const i = t.indexOf(':');\n if (i !== -1) {\n const key = t.slice(0, i).trim().toLowerCase(), val = t.slice(i + 1).trim().toLowerCase();\n if (!p.keys.includes(key)) { p.warn(`[directives] Unknown directive key: \"${key}\"`); continue; }\n if (key === 'delegate' || key === 'advisor') {\n const hit = resolveModelToken(val, p);\n if (hit && 'model' in hit) d[key] = hit.model;\n else if (!hit && isQualifiedModel(val) && !p.catalogOnly) d[key] = val;\n else fail(val, hit);\n continue;\n }\n if (key === 'model') {\n const r = setModel(val);\n if (r === true) continue;\n // A plain `provider/model` with no catalog to check is concrete — the engine owns the verdict.\n if (!r && isQualifiedModel(val) && !p.catalogOnly) { d.model = val; continue; }\n fail(val, r as any);\n } else applyKey(d, key, val, p.warn);\n continue;\n }\n const val = t.toLowerCase();\n const pair = splitModePair(val);\n if (pair && p.keys.includes(pair.op === '->' ? 'delegate' : 'advisor')) {\n const lhit = pair.left ? resolveModelToken(pair.left, p) : null, rhit = resolveModelToken(pair.right, p);\n const lok = !pair.left || (!!lhit && 'model' in lhit), rok = !!rhit && 'model' in rhit;\n // Explicit once either side resolves: the other side's miss is a dropped selection, never a silent fallback.\n if (lok && rok) {\n if (pair.left) setModel(pair.left);\n if (pair.op === '->') d.delegate = (rhit as ModelHit).model; else d.advisor = (rhit as ModelHit).model;\n } else if (lok || rok) { if (!lok) fail(pair.left, lhit); else fail(pair.right, rhit); }\n else p.warn(`[directives] Unknown models in \"${t}\"`);\n pos++;\n continue;\n }\n if (val === 'off' && p.keys.includes('mode')) { d.modeOff = true; pos++; continue; }\n const r = pos === 0 ? setModel(val) : null;\n if (r === true) { /* model */ }\n else if (pos <= 1 && /^\\d+$/.test(val) && p.keys.includes('turns')) d.turns = parseInt(val, 10);\n else if (['think', 'adaptive'].includes(val) && p.keys.includes('thinking')) d.thinking = 'adaptive';\n else if (['nothink', 'nothinking'].includes(val) && p.keys.includes('thinking')) d.thinking = 'disabled';\n else if (pos === 0) {\n // Ambiguous tokens (and, catalog-only, a known alias the catalog lacks) are model selections; a plain unknown one\n // only with a keyed sibling. An unresolved vendor form (`[cc-by]`) is not a selection.\n if (r || (p.catalogOnly && p.aliases[val]) || (proven && !isQualifiedModel(val))) fail(t, r as any);\n p.warn(`[directives] Unknown model: \"${t}\"`);\n }\n pos++;\n }\n return out;\n}\n\nfunction applyKey(d: Directives, key: string, val: string, warn: (m: string) => void): void {\n switch (key) {\n case 'turns': if (/^\\d+$/.test(val)) d.turns = parseInt(val, 10); else warn(`[directives] Invalid turns value: \"${val}\"`); break;\n case 'thinking':\n case 'think': if (['adaptive', 'enabled', 'disabled'].includes(val)) d.thinking = val as Directives['thinking']; else warn(`[directives] Invalid thinking value: \"${val}\"`); break;\n case 'effort': if (['low', 'medium', 'high', 'max'].includes(val)) d.effort = val as Directives['effort']; else warn(`[directives] Invalid effort value: \"${val}\"`); break;\n case 'engine': d.engine = val; break;\n case 'mode': if (val === 'off') d.modeOff = true; else warn(`[directives] Invalid mode value: \"${val}\"`); break;\n case 'resume':\n if (['on', 'true', '1'].includes(val)) d.resume = true;\n else if (['off', 'false', '0'].includes(val)) d.resume = false;\n else warn(`[directives] Invalid resume value: \"${val}\"`);\n break;\n }\n}\n\n/** Engine/provider → the model ids it advertises. */\nexport interface EngineModels { name: string; models: { value: string }[] }\n\n/**\n * A resolver over host catalogs: exact id first, then the bare suffix after the provider prefix —\n * ONLY when unambiguous across engines (`{ ambiguous }` otherwise, never the first match).\n */\nexport function makeModelResolver(engines: () => EngineModels[]): ModelResolver {\n return (token) => {\n const t = token.toLowerCase();\n const hits: ModelHit[] = [];\n for (const { name, models } of engines()) {\n for (const m of models) {\n if (!m.value) continue;\n const v = m.value.toLowerCase();\n if (v === t) return { model: m.value, engine: name };\n if (v.slice(v.lastIndexOf('/') + 1) === t && !hits.some((h) => h.model === m.value)) hits.push({ model: m.value, engine: name });\n }\n }\n if (hits.length === 1) return hits[0];\n return hits.length > 1 ? { ambiguous: hits.map((h) => h.model) } : null;\n };\n}\n"],"mappings":"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","names":["val","r"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { c as AgentOptions, H as Hooks, v as RunResult, i as Decider, b as Agent, o as PermissionPolicy, G as Gender, L as LineKind, C as ChannelMode, w as SecondChannelOptions, S as SecondChannel } from './secondChannel-BddfVzTp.js';
|
|
2
|
+
export { A as ADVISE_LIMIT, a as AdvisorSetup, d as ChatFragment, e as ChatUsage, f as Classification, g as Classifier, h as CompactResult, D as DEFAULT_MUTATING, j as Decision, M as ModelRouter, k as ModelRouterOptions, P as PLANNER_BLOCKED, l as PLANNER_REFUSAL, m as PLAN_FIRST, n as PermissionOptions, p as PermissionRule, q as PreToolUseDecision, R as ReasoningEffort, r as RecordingHooks, s as RecordingLifecycle, t as RouteDecision, u as RouterState, T as Tier, x as ToolUse, y as ToolUseMeta, W as WRITE_TOOLS, z as advisorFor, B as advisorPrompt, E as claudeCodeDisallowedTools, F as composeHooks, I as delegatePrompt, J as delegateTools, K as delegateWorkerFor, N as estimateTokens, O as jevAvailable, Q as jevClassifier, U as makeAdvisor, V as meterWorkers, X as pickTier, Y as planMode, Z as reasoningToChatFragment } from './secondChannel-BddfVzTp.js';
|
|
3
3
|
export { MODEL_ALIASES, ModelSwitch, ResolveModelSwitchOpts, latestClaude, modelShortLabel, resolveModelAlias, resolveModelSwitch } from './models.js';
|
|
4
4
|
import { IFilesystem, FileMetadata } from '@livx.cc/wcli/core';
|
|
5
5
|
export { CommandExecutor, FileMetadata, IFilesystem, IndexedDbFilesystem, MemFilesystem, registerHeadlessCommands } from '@livx.cc/wcli/core';
|
|
@@ -1600,6 +1600,9 @@ interface TaskToolOptions {
|
|
|
1600
1600
|
/** Origin-anchored real-disk dir for child transcript traces (see `AgentOptions.traceDir`). Passed
|
|
1601
1601
|
* down UNCHANGED to nested children so every level writes to the same origin `.agent`. */
|
|
1602
1602
|
traceDir?: string;
|
|
1603
|
+
/** Also hand the parent's `postToolUse` to children (default off: observer hooks stay parent-only).
|
|
1604
|
+
* Delegate mode sets it — a worker's write IS the parent's work, so a host observing writes must see it. */
|
|
1605
|
+
inheritPostToolUse?: boolean;
|
|
1603
1606
|
}
|
|
1604
1607
|
/**
|
|
1605
1608
|
* `Task` tool — spawn a CHILD agent over the same VFS with its own step budget,
|