flavor-code 1.3.10 → 1.3.11
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/dist/{app-YSBW7GXH.js → app-L52CTVNR.js} +43 -6
- package/dist/{chunk-Y3DPUAEJ.js → chunk-IGFN2DM5.js} +162 -33
- package/dist/{chunk-T2ARW6CZ.js → chunk-JZ5FVBET.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/desktop/main.js +165 -33
- package/dist/desktop-renderer/assets/{index-bFGsR_uj.js → index-Bl5dmm02.js} +4 -4
- package/dist/desktop-renderer/assets/index-CDxzMJ9C.css +1 -0
- package/dist/desktop-renderer/assets/{interactive-terminal-BwS6MvIe.js → interactive-terminal-CNgUWG7b.js} +1 -1
- package/dist/desktop-renderer/index.html +2 -2
- package/dist/models/structured.d.ts +13 -4
- package/dist/production.d.ts +2 -0
- package/dist/sdk/index.js +2 -2
- package/dist/tools/runtime.d.ts +5 -0
- package/dist/ui/commands.d.ts +7 -3
- package/dist/ui/session.d.ts +5 -0
- package/package.json +1 -1
- package/dist/desktop-renderer/assets/index-CdeAi527.css +0 -1
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
redactErrorText,
|
|
17
17
|
transcriptReducer,
|
|
18
18
|
withTimeout
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IGFN2DM5.js";
|
|
20
20
|
import "./chunk-IG4Z23CL.js";
|
|
21
21
|
import {
|
|
22
22
|
Box_default,
|
|
@@ -1257,7 +1257,7 @@ function slashCandidatePresentation(selected) {
|
|
|
1257
1257
|
matchStyle: { color: "ansi:cyan", bold: true }
|
|
1258
1258
|
};
|
|
1259
1259
|
}
|
|
1260
|
-
function buildSlashCandidates(commands, plugins, skills) {
|
|
1260
|
+
function buildSlashCandidates(commands, plugins, skills, tools = []) {
|
|
1261
1261
|
const candidates = /* @__PURE__ */ new Map();
|
|
1262
1262
|
for (const command of commands) {
|
|
1263
1263
|
candidates.set(command.name, { name: command.name, kind: "command", description: command.description });
|
|
@@ -1267,6 +1267,11 @@ function buildSlashCandidates(commands, plugins, skills) {
|
|
|
1267
1267
|
candidates.set(plugin.name, plugin.description === void 0 ? { name: plugin.name, kind: "plugin" } : { name: plugin.name, kind: "plugin", description: plugin.description });
|
|
1268
1268
|
}
|
|
1269
1269
|
}
|
|
1270
|
+
for (const tool of tools) {
|
|
1271
|
+
if (!candidates.has(tool.name)) {
|
|
1272
|
+
candidates.set(tool.name, tool.description === void 0 ? { name: tool.name, kind: "tool" } : { name: tool.name, kind: "tool", description: tool.description });
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1270
1275
|
for (const skill of skills) {
|
|
1271
1276
|
if (!candidates.has(skill.name)) {
|
|
1272
1277
|
candidates.set(skill.name, {
|
|
@@ -1850,7 +1855,8 @@ function appRuntimeOptions(props, output, onApprovalChange) {
|
|
|
1850
1855
|
...props.palAlias === void 0 ? {} : { alias: props.palAlias }
|
|
1851
1856
|
},
|
|
1852
1857
|
output,
|
|
1853
|
-
onApprovalChange
|
|
1858
|
+
onApprovalChange,
|
|
1859
|
+
onToolsChange: onApprovalChange
|
|
1854
1860
|
};
|
|
1855
1861
|
}
|
|
1856
1862
|
function App({ workspace, home, resumeSession, instanceId, palAlias }) {
|
|
@@ -1954,13 +1960,23 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
|
|
|
1954
1960
|
}
|
|
1955
1961
|
dispatch({ type: "restore", state: created.restoredTranscript });
|
|
1956
1962
|
runtimeRef.current = created;
|
|
1957
|
-
setSlashCandidates(buildSlashCandidates(
|
|
1963
|
+
setSlashCandidates(buildSlashCandidates(
|
|
1964
|
+
BUILTIN_SLASH_CANDIDATES,
|
|
1965
|
+
created.services.pluginCommands(),
|
|
1966
|
+
[],
|
|
1967
|
+
created.services.managedToolCommands()
|
|
1968
|
+
));
|
|
1958
1969
|
setRuntime(created);
|
|
1959
1970
|
await created.session.start();
|
|
1960
1971
|
try {
|
|
1961
1972
|
const skills = await created.services.skills();
|
|
1962
1973
|
if (!disposed) {
|
|
1963
|
-
setSlashCandidates(buildSlashCandidates(
|
|
1974
|
+
setSlashCandidates(buildSlashCandidates(
|
|
1975
|
+
BUILTIN_SLASH_CANDIDATES,
|
|
1976
|
+
created.services.pluginCommands(),
|
|
1977
|
+
skills,
|
|
1978
|
+
created.services.managedToolCommands()
|
|
1979
|
+
));
|
|
1964
1980
|
}
|
|
1965
1981
|
} catch {
|
|
1966
1982
|
}
|
|
@@ -1975,6 +1991,28 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
|
|
|
1975
1991
|
`));
|
|
1976
1992
|
};
|
|
1977
1993
|
}, [workspace, home, resumeSession, instanceId, palAlias]);
|
|
1994
|
+
useEffect3(() => {
|
|
1995
|
+
if (runtime === void 0) return;
|
|
1996
|
+
let disposed = false;
|
|
1997
|
+
void runtime.services.skills().then((skills) => {
|
|
1998
|
+
if (!disposed) setSlashCandidates(buildSlashCandidates(
|
|
1999
|
+
BUILTIN_SLASH_CANDIDATES,
|
|
2000
|
+
runtime.services.pluginCommands(),
|
|
2001
|
+
skills,
|
|
2002
|
+
runtime.services.managedToolCommands()
|
|
2003
|
+
));
|
|
2004
|
+
}).catch(() => {
|
|
2005
|
+
if (!disposed) setSlashCandidates(buildSlashCandidates(
|
|
2006
|
+
BUILTIN_SLASH_CANDIDATES,
|
|
2007
|
+
runtime.services.pluginCommands(),
|
|
2008
|
+
[],
|
|
2009
|
+
runtime.services.managedToolCommands()
|
|
2010
|
+
));
|
|
2011
|
+
});
|
|
2012
|
+
return () => {
|
|
2013
|
+
disposed = true;
|
|
2014
|
+
};
|
|
2015
|
+
}, [runtime, revision]);
|
|
1978
2016
|
useEffect3(() => installSigintHandler(process, interrupt), [interrupt]);
|
|
1979
2017
|
useEffect3(() => {
|
|
1980
2018
|
if (runtime?.services.ideContext === void 0) {
|
|
@@ -2347,7 +2385,6 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
|
|
|
2347
2385
|
setDismissedMentionInput(void 0);
|
|
2348
2386
|
}
|
|
2349
2387
|
});
|
|
2350
|
-
void revision;
|
|
2351
2388
|
if (runtime === void 0) return /* @__PURE__ */ jsx5(
|
|
2352
2389
|
StartingLayout,
|
|
2353
2390
|
{
|
|
@@ -2996,7 +2996,8 @@ var MVP_COMMANDS = [
|
|
|
2996
2996
|
"fork",
|
|
2997
2997
|
"pals",
|
|
2998
2998
|
"chat",
|
|
2999
|
-
"co-work"
|
|
2999
|
+
"co-work",
|
|
3000
|
+
"tool"
|
|
3000
3001
|
];
|
|
3001
3002
|
var COMMAND_DESCRIPTIONS = {
|
|
3002
3003
|
model: "Switch the active model",
|
|
@@ -3034,16 +3035,24 @@ var COMMAND_DESCRIPTIONS = {
|
|
|
3034
3035
|
fork: "Continue context from a prior session node",
|
|
3035
3036
|
pals: "List, rename, or inspect active Flavor pals",
|
|
3036
3037
|
chat: "Send a task to another Flavor pal",
|
|
3037
|
-
"co-work": "Coordinate a shared goal with another Flavor pal"
|
|
3038
|
+
"co-work": "Coordinate a shared goal with another Flavor pal",
|
|
3039
|
+
tool: "Run a registered managed tool with a JSON object"
|
|
3038
3040
|
};
|
|
3039
|
-
function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
3041
|
+
function parseSlashCommand(input, dynamicCommands = [], skillCommands = [], managedTools = []) {
|
|
3040
3042
|
const trimmed = input.trim();
|
|
3041
3043
|
if (!trimmed.startsWith("/")) return null;
|
|
3042
|
-
const
|
|
3044
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed.slice(1));
|
|
3045
|
+
const rawName = match?.[1] ?? "";
|
|
3046
|
+
const rawArguments = match?.[2] ?? "";
|
|
3047
|
+
const args = rawArguments.length === 0 ? [] : rawArguments.split(/\s+/u);
|
|
3043
3048
|
const name = rawName.toLowerCase();
|
|
3044
3049
|
if (!MVP_COMMANDS.includes(name) && dynamicCommands.includes(name)) {
|
|
3045
3050
|
return { name: "plugin", command: name, args };
|
|
3046
3051
|
}
|
|
3052
|
+
if (!MVP_COMMANDS.includes(name)) {
|
|
3053
|
+
const managedTool = managedTools.find((tool) => tool.toLowerCase() === name);
|
|
3054
|
+
if (managedTool !== void 0) return { name: "managed-tool", tool: managedTool, input: rawArguments };
|
|
3055
|
+
}
|
|
3047
3056
|
if (!MVP_COMMANDS.includes(name) && skillCommands.includes(name)) {
|
|
3048
3057
|
return { name: "skill", skill: name, prompt: args.join(" ") };
|
|
3049
3058
|
}
|
|
@@ -3065,6 +3074,15 @@ function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
|
3065
3074
|
}
|
|
3066
3075
|
return { name, mode: normalized };
|
|
3067
3076
|
}
|
|
3077
|
+
if (name === "tool") {
|
|
3078
|
+
const [requested] = args;
|
|
3079
|
+
const managedTool = requested === void 0 ? void 0 : managedTools.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());
|
|
3080
|
+
if (managedTool === void 0) {
|
|
3081
|
+
return { name: "invalid", command: name, message: "Use /tool <registered-tool> [JSON object]." };
|
|
3082
|
+
}
|
|
3083
|
+
const inputStart = rawArguments.search(/\s/u);
|
|
3084
|
+
return { name: "managed-tool", tool: managedTool, input: inputStart < 0 ? "" : rawArguments.slice(inputStart).trimStart() };
|
|
3085
|
+
}
|
|
3068
3086
|
if (name === "audit") {
|
|
3069
3087
|
const toolFilter = args.length > 0 ? args.join(" ") : void 0;
|
|
3070
3088
|
return { name, toolFilter };
|
|
@@ -3292,6 +3310,7 @@ var HELP = [
|
|
|
3292
3310
|
"/review [focus] review uncommitted changes before committing",
|
|
3293
3311
|
"/evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>> self-improvement loop",
|
|
3294
3312
|
"/mcp [status|tools|reconnect|enable|disable] manage MCP servers",
|
|
3313
|
+
"/tool <registered-tool> [JSON object] run a registered tool (or use /<tool-name>)",
|
|
3295
3314
|
"/ide show VS Code connection and cursor/selection",
|
|
3296
3315
|
"/pals [--verbose|rename <alias>|info <alias-or-uuid>]",
|
|
3297
3316
|
"/chat <alias-or-uuid> <goal> send a task that starts on the receiving pal",
|
|
@@ -3563,7 +3582,12 @@ var FlavorSession = class {
|
|
|
3563
3582
|
} catch {
|
|
3564
3583
|
}
|
|
3565
3584
|
}
|
|
3566
|
-
const command = parseSlashCommand(
|
|
3585
|
+
const command = parseSlashCommand(
|
|
3586
|
+
prompt,
|
|
3587
|
+
this.#services.pluginCommands().map(({ name }) => name),
|
|
3588
|
+
skillNames,
|
|
3589
|
+
this.#services.managedToolCommands().map(({ name }) => name)
|
|
3590
|
+
);
|
|
3567
3591
|
if (command !== null) await this.#dispatch(command, controller.signal);
|
|
3568
3592
|
else for await (const event of this.#services.run(prompt, controller.signal, {
|
|
3569
3593
|
getSteeringMessages: () => this.#drainMessages("steer", true).map((item) => item.text),
|
|
@@ -3665,6 +3689,8 @@ var FlavorSession = class {
|
|
|
3665
3689
|
this.#notice(`Main permissions set to ${command.mode}. Child approvals use bubble mode unless plan mode is active.`);
|
|
3666
3690
|
} else if (command.name === "plugin") {
|
|
3667
3691
|
this.#notice(format(await this.#services.runPluginCommand(command.command, command.args, signal)));
|
|
3692
|
+
} else if (command.name === "managed-tool") {
|
|
3693
|
+
this.#notice(format(await this.#services.runManagedTool(command.tool, command.input, signal)));
|
|
3668
3694
|
} else if (command.name === "skill") {
|
|
3669
3695
|
for await (const event of this.#services.runSkill(command.skill, command.prompt, signal)) this.#services.output(event);
|
|
3670
3696
|
} else if (command.name === "loop") {
|
|
@@ -6536,9 +6562,10 @@ function withStructuredOutput(options) {
|
|
|
6536
6562
|
throw new Error("Structured output retry delays must be non-negative integers");
|
|
6537
6563
|
}
|
|
6538
6564
|
}
|
|
6539
|
-
const
|
|
6565
|
+
const generatedTool = options.modelInputSchema === void 0 ? modelToolFromZod(options.name, options.description, options.schema) : { name: options.name, description: options.description, inputSchema: options.modelInputSchema };
|
|
6566
|
+
const tool = options.modelStrict === void 0 ? generatedTool : { ...generatedTool, strict: options.modelStrict };
|
|
6540
6567
|
const maxAttempts = retry.maxRetries + 1;
|
|
6541
|
-
const
|
|
6568
|
+
const validationSchema = jsonSchemaFromZod(options.schema);
|
|
6542
6569
|
const model = {
|
|
6543
6570
|
async *stream(request) {
|
|
6544
6571
|
let candidate;
|
|
@@ -6611,7 +6638,7 @@ function withStructuredOutput(options) {
|
|
|
6611
6638
|
}
|
|
6612
6639
|
}
|
|
6613
6640
|
if (candidateCount === 1 && candidate !== null && typeof candidate === "object") {
|
|
6614
|
-
candidate = coerceByJsonSchema(candidate,
|
|
6641
|
+
candidate = coerceByJsonSchema(candidate, validationSchema);
|
|
6615
6642
|
}
|
|
6616
6643
|
if (candidateCount !== 1) {
|
|
6617
6644
|
attemptError = {
|
|
@@ -6683,7 +6710,13 @@ function withStructuredOutput(options) {
|
|
|
6683
6710
|
return model;
|
|
6684
6711
|
}
|
|
6685
6712
|
function strictJsonSchema(schema) {
|
|
6686
|
-
return
|
|
6713
|
+
return strictJsonSchemaObject(jsonSchemaFromZod(schema));
|
|
6714
|
+
}
|
|
6715
|
+
function jsonSchemaFromZod(schema) {
|
|
6716
|
+
return z7.toJSONSchema(schema);
|
|
6717
|
+
}
|
|
6718
|
+
function strictJsonSchemaObject(schema) {
|
|
6719
|
+
return ensureStrictSchema(schema);
|
|
6687
6720
|
}
|
|
6688
6721
|
function extractJsonObject(text) {
|
|
6689
6722
|
const trimmed = text.trim();
|
|
@@ -6731,6 +6764,7 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6731
6764
|
const node = schema;
|
|
6732
6765
|
const branches = [
|
|
6733
6766
|
...Array.isArray(node.anyOf) ? node.anyOf : [],
|
|
6767
|
+
...Array.isArray(node.oneOf) ? node.oneOf : [],
|
|
6734
6768
|
...Array.isArray(node.allOf) ? node.allOf : []
|
|
6735
6769
|
].filter((branch) => branch !== null && typeof branch === "object");
|
|
6736
6770
|
const types = [];
|
|
@@ -6750,40 +6784,108 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6750
6784
|
if (lowered === "true") return true;
|
|
6751
6785
|
if (lowered === "false") return false;
|
|
6752
6786
|
}
|
|
6787
|
+
if (types.includes("object") && !types.includes("string") && typeof value === "string") {
|
|
6788
|
+
const trimmed = value.trim();
|
|
6789
|
+
if (trimmed.startsWith("{")) {
|
|
6790
|
+
try {
|
|
6791
|
+
const parsed = JSON.parse(trimmed);
|
|
6792
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
6793
|
+
return coerceByJsonSchema(parsed, node);
|
|
6794
|
+
}
|
|
6795
|
+
} catch {
|
|
6796
|
+
}
|
|
6797
|
+
}
|
|
6798
|
+
}
|
|
6799
|
+
if (types.includes("array") && !Array.isArray(value) && value !== null && value !== void 0 && !types.some((type) => matchesJsonSchemaType(value, type))) {
|
|
6800
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
6801
|
+
const type = candidate.type;
|
|
6802
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
6803
|
+
});
|
|
6804
|
+
if (typeof value === "string" && value.trim().startsWith("[")) {
|
|
6805
|
+
try {
|
|
6806
|
+
const parsed = JSON.parse(value.trim());
|
|
6807
|
+
if (Array.isArray(parsed)) return coerceByJsonSchema(parsed, arraySchema ?? node);
|
|
6808
|
+
} catch {
|
|
6809
|
+
}
|
|
6810
|
+
}
|
|
6811
|
+
return [arraySchema?.items === void 0 ? value : coerceByJsonSchema(value, arraySchema.items)];
|
|
6812
|
+
}
|
|
6753
6813
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
6754
|
-
const
|
|
6814
|
+
const objectSchema = [node, ...branches].find((candidate) => candidate.type === "object" || candidate.properties !== void 0);
|
|
6815
|
+
const properties = objectSchema?.properties;
|
|
6755
6816
|
if (properties !== void 0) {
|
|
6756
6817
|
const output = {};
|
|
6818
|
+
const required2 = new Set(Array.isArray(objectSchema?.required) ? objectSchema.required : []);
|
|
6757
6819
|
for (const [key, child] of Object.entries(value)) {
|
|
6758
|
-
|
|
6820
|
+
const childSchema = properties[key];
|
|
6821
|
+
if (child === null && childSchema !== void 0 && !required2.has(key) && !jsonSchemaAllowsNull(childSchema)) {
|
|
6822
|
+
continue;
|
|
6823
|
+
}
|
|
6824
|
+
output[key] = childSchema !== void 0 ? coerceByJsonSchema(child, childSchema) : child;
|
|
6759
6825
|
}
|
|
6760
6826
|
return output;
|
|
6761
6827
|
}
|
|
6762
6828
|
}
|
|
6763
|
-
if (types.includes("array") && Array.isArray(value)
|
|
6764
|
-
|
|
6829
|
+
if (types.includes("array") && Array.isArray(value)) {
|
|
6830
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
6831
|
+
const type = candidate.type;
|
|
6832
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
6833
|
+
});
|
|
6834
|
+
if (arraySchema?.items !== void 0) {
|
|
6835
|
+
return value.map((item) => coerceByJsonSchema(item, arraySchema.items));
|
|
6836
|
+
}
|
|
6765
6837
|
}
|
|
6766
6838
|
return value;
|
|
6767
6839
|
}
|
|
6840
|
+
function matchesJsonSchemaType(value, type) {
|
|
6841
|
+
if (type === "null") return value === null;
|
|
6842
|
+
if (type === "array") return Array.isArray(value);
|
|
6843
|
+
if (type === "object") return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6844
|
+
if (type === "integer") return typeof value === "number" && Number.isInteger(value);
|
|
6845
|
+
if (type === "number") return typeof value === "number";
|
|
6846
|
+
return typeof value === type;
|
|
6847
|
+
}
|
|
6848
|
+
function jsonSchemaAllowsNull(schema) {
|
|
6849
|
+
if (schema === null || typeof schema !== "object") return false;
|
|
6850
|
+
const node = schema;
|
|
6851
|
+
if (node.type === "null" || Array.isArray(node.type) && node.type.includes("null")) return true;
|
|
6852
|
+
return [node.anyOf, node.oneOf].some((branches) => Array.isArray(branches) && branches.some((branch) => jsonSchemaAllowsNull(branch)));
|
|
6853
|
+
}
|
|
6768
6854
|
function modelToolFromZod(name, description, schema) {
|
|
6769
6855
|
return { name, description, inputSchema: strictJsonSchema(schema) };
|
|
6770
6856
|
}
|
|
6771
6857
|
function ensureStrictSchema(schema) {
|
|
6858
|
+
const output = { ...schema };
|
|
6859
|
+
for (const keyword of ["anyOf", "oneOf", "allOf", "prefixItems"]) {
|
|
6860
|
+
const branches = schema[keyword];
|
|
6861
|
+
if (Array.isArray(branches)) {
|
|
6862
|
+
output[keyword] = branches.map((branch) => typeof branch === "object" && branch !== null ? ensureStrictSchema(branch) : branch);
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
if (typeof schema.items === "object" && schema.items !== null) {
|
|
6866
|
+
output.items = ensureStrictSchema(schema.items);
|
|
6867
|
+
}
|
|
6868
|
+
for (const keyword of ["$defs", "definitions"]) {
|
|
6869
|
+
const definitions = schema[keyword];
|
|
6870
|
+
if (typeof definitions === "object" && definitions !== null && !Array.isArray(definitions)) {
|
|
6871
|
+
output[keyword] = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [
|
|
6872
|
+
key,
|
|
6873
|
+
typeof definition === "object" && definition !== null ? ensureStrictSchema(definition) : definition
|
|
6874
|
+
]));
|
|
6875
|
+
}
|
|
6876
|
+
}
|
|
6772
6877
|
if (schema.type !== "object" || typeof schema.properties !== "object" || schema.properties === null) {
|
|
6773
|
-
return
|
|
6878
|
+
return output;
|
|
6774
6879
|
}
|
|
6775
|
-
const
|
|
6776
|
-
const requiredSet = new Set(required2);
|
|
6880
|
+
const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
6777
6881
|
const properties = {};
|
|
6778
6882
|
for (const [key, value] of Object.entries(schema.properties)) {
|
|
6779
6883
|
const child = typeof value === "object" && value !== null ? ensureStrictSchema(value) : value;
|
|
6780
|
-
if (requiredSet.has(key)) properties[key] = child;
|
|
6781
|
-
else {
|
|
6782
|
-
|
|
6783
|
-
requiredSet.add(key);
|
|
6784
|
-
}
|
|
6884
|
+
if (requiredSet.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
|
|
6885
|
+
else properties[key] = { anyOf: [child, { type: "null" }] };
|
|
6886
|
+
requiredSet.add(key);
|
|
6785
6887
|
}
|
|
6786
|
-
return { ...
|
|
6888
|
+
return { ...output, additionalProperties: false, required: [...requiredSet], properties };
|
|
6787
6889
|
}
|
|
6788
6890
|
function repairMessages(messages, tool, original, candidate, error) {
|
|
6789
6891
|
const details = [
|
|
@@ -7153,19 +7255,11 @@ var AgentLoop = class {
|
|
|
7153
7255
|
});
|
|
7154
7256
|
continue;
|
|
7155
7257
|
}
|
|
7156
|
-
const validation = collected.kind === "valid" ? this.#options.runtime.
|
|
7258
|
+
const validation = collected.kind === "valid" ? this.#options.runtime.normalize(collected) : { ok: false, error: collected.error };
|
|
7157
7259
|
if (validation.ok) {
|
|
7158
7260
|
toolCalls.push({ id: collected.id, name: collected.name, input: validation.input });
|
|
7159
7261
|
continue;
|
|
7160
7262
|
}
|
|
7161
|
-
if (collected.kind === "valid") {
|
|
7162
|
-
const coerced = coerceByJsonSchema(collected.input, strictJsonSchema(definition.inputSchema));
|
|
7163
|
-
const revalidation = this.#options.runtime.validate({ ...collected, input: coerced });
|
|
7164
|
-
if (revalidation.ok) {
|
|
7165
|
-
toolCalls.push({ id: collected.id, name: collected.name, input: revalidation.input });
|
|
7166
|
-
continue;
|
|
7167
|
-
}
|
|
7168
|
-
}
|
|
7169
7263
|
const repairModelId = this.#options.fallbackModelId ?? this.#options.modelId;
|
|
7170
7264
|
const invalidOutput = collected.kind === "invalid" ? collected.rawInput : serializeToolInput(collected.input);
|
|
7171
7265
|
const structured = withStructuredOutput({
|
|
@@ -7174,6 +7268,8 @@ var AgentLoop = class {
|
|
|
7174
7268
|
name: definition.name,
|
|
7175
7269
|
description: definition.description,
|
|
7176
7270
|
schema: definition.inputSchema,
|
|
7271
|
+
...definition.modelInputSchema === void 0 ? {} : { modelInputSchema: definition.modelInputSchema },
|
|
7272
|
+
...definition.modelStrict === void 0 ? {} : { modelStrict: definition.modelStrict },
|
|
7177
7273
|
beforeAttempt: async ({ attempt: repairAttempt, maxAttempts: repairMaxAttempts, messageCount }) => {
|
|
7178
7274
|
const before = await this.#options.hooks.emit({
|
|
7179
7275
|
version: 1,
|
|
@@ -7654,12 +7750,24 @@ var ToolRuntime = class {
|
|
|
7654
7750
|
throw error;
|
|
7655
7751
|
}
|
|
7656
7752
|
}
|
|
7753
|
+
/**
|
|
7754
|
+
* Validates a call and applies the same conservative provider-argument
|
|
7755
|
+
* normalization used by the agent loop before falling back to repair.
|
|
7756
|
+
*/
|
|
7757
|
+
normalize(call) {
|
|
7758
|
+
const validation = this.validate(call);
|
|
7759
|
+
if (validation.ok || validation.error.code === "unknown_tool") return validation;
|
|
7760
|
+
const tool = this.#tools.get(call.name);
|
|
7761
|
+
if (tool === void 0) return validation;
|
|
7762
|
+
const input = coerceByJsonSchema(call.input, jsonSchemaFromZod(tool.inputSchema));
|
|
7763
|
+
return this.validate({ ...call, input });
|
|
7764
|
+
}
|
|
7657
7765
|
async #execute(call, context) {
|
|
7658
7766
|
const tool = this.#tools.get(call.name);
|
|
7659
7767
|
if (tool === void 0) return { ok: false, error: { code: "unknown_tool", message: `Unknown tool: ${call.name}` } };
|
|
7660
7768
|
const signal = context.signal ?? new AbortController().signal;
|
|
7661
7769
|
const toolCallId = call.id ?? randomUUID7();
|
|
7662
|
-
const validation = this.
|
|
7770
|
+
const validation = this.normalize(call);
|
|
7663
7771
|
if (!validation.ok) {
|
|
7664
7772
|
return this.#fail(toolCallId, call.name, call.input, context.agent, validation.error.code, validation.error.message);
|
|
7665
7773
|
}
|
|
@@ -9388,6 +9496,7 @@ var PluginHost = class {
|
|
|
9388
9496
|
description: contribution.description,
|
|
9389
9497
|
inputSchema: z13.unknown(),
|
|
9390
9498
|
...contribution.modelInputSchema === void 0 ? {} : { modelInputSchema: contribution.modelInputSchema },
|
|
9499
|
+
...contribution.modelInputSchema === void 0 ? {} : { modelStrict: false },
|
|
9391
9500
|
...contribution.readOnly === void 0 ? {} : { readOnly: contribution.readOnly },
|
|
9392
9501
|
paths: () => [],
|
|
9393
9502
|
execute: (input, _signal, toolContext) => session.invoke("tool", contribution.name, [
|
|
@@ -17795,7 +17904,7 @@ function compileDefinition(record, scope2, workspace) {
|
|
|
17795
17904
|
name: record.name,
|
|
17796
17905
|
description: record.description,
|
|
17797
17906
|
inputSchema,
|
|
17798
|
-
modelInputSchema: record.inputSchema,
|
|
17907
|
+
modelInputSchema: strictJsonSchemaObject(record.inputSchema),
|
|
17799
17908
|
modelStrict: true,
|
|
17800
17909
|
...record.agents === void 0 ? {} : { agents: record.agents },
|
|
17801
17910
|
paths: () => [],
|
|
@@ -20859,6 +20968,7 @@ async function createProductionRuntime(options) {
|
|
|
20859
20968
|
managedTools.push(tool);
|
|
20860
20969
|
}
|
|
20861
20970
|
if (harnessCreated) harness.replaceMainTools(tools);
|
|
20971
|
+
options.onToolsChange?.();
|
|
20862
20972
|
};
|
|
20863
20973
|
tools.push(...createManagedToolManagementTools({
|
|
20864
20974
|
store: managedToolStore,
|
|
@@ -22188,6 +22298,25 @@ ${renderMemoryDocument(entries)}`;
|
|
|
22188
22298
|
signal.throwIfAborted();
|
|
22189
22299
|
return awaitWithSignal(Promise.resolve(handler(args, { workspace, signal })), signal);
|
|
22190
22300
|
},
|
|
22301
|
+
managedToolCommands: () => managedTools.map(({ name, description }) => ({ name, description })).sort((left, right) => left.name.localeCompare(right.name)),
|
|
22302
|
+
runManagedTool: async (name, rawInput, signal) => {
|
|
22303
|
+
const tool = managedTools.find((candidate) => sameToolName(candidate.name, name));
|
|
22304
|
+
if (tool === void 0) throw new Error(`Registered tool "${name}" is no longer available.`);
|
|
22305
|
+
signal.throwIfAborted();
|
|
22306
|
+
const input = normalizeToolCallInput(rawInput);
|
|
22307
|
+
const call = { name: tool.name, input };
|
|
22308
|
+
const validation = harness.main.runtime.normalize(call);
|
|
22309
|
+
if (!validation.ok) throw new Error(`Invalid input for registered tool "${tool.name}": ${validation.error.message}`);
|
|
22310
|
+
harness.main.runtime.beginTurn();
|
|
22311
|
+
const result = await harness.main.runtime.execute(
|
|
22312
|
+
{ name: tool.name, input: validation.input },
|
|
22313
|
+
{ agent: "main", ownerId: "main", signal }
|
|
22314
|
+
);
|
|
22315
|
+
if (!result.ok) {
|
|
22316
|
+
throw new Error(`Registered tool "${tool.name}" failed (${result.error?.code ?? "unknown"}): ${result.error?.message ?? "Unknown error"}`);
|
|
22317
|
+
}
|
|
22318
|
+
return result.output !== void 0 ? result.output : result.content;
|
|
22319
|
+
},
|
|
22191
22320
|
output: emitOutput,
|
|
22192
22321
|
questions,
|
|
22193
22322
|
async login() {
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createRequire } from "node:module"; const require = createRequire(impor
|
|
|
3
3
|
import {
|
|
4
4
|
FlavorRpcServer,
|
|
5
5
|
TraceRecorder
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JZ5FVBET.js";
|
|
7
7
|
import {
|
|
8
8
|
staticTaskLines
|
|
9
9
|
} from "./chunk-KKIBYDJI.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
packageVersion,
|
|
24
24
|
redactErrorText,
|
|
25
25
|
runPalBroker
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-IGFN2DM5.js";
|
|
27
27
|
import {
|
|
28
28
|
McpServerConfigSchema,
|
|
29
29
|
McpServerNameSchema,
|
|
@@ -877,7 +877,7 @@ async function runInteractiveCli(props) {
|
|
|
877
877
|
const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
|
|
878
878
|
import("./claude-ink-ORUA7GWG.js"),
|
|
879
879
|
import("react"),
|
|
880
|
-
import("./app-
|
|
880
|
+
import("./app-L52CTVNR.js")
|
|
881
881
|
]);
|
|
882
882
|
const instance = await render(createElement(
|
|
883
883
|
AlternateScreen,
|