flavor-code 1.3.9 → 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-XAV5LRM7.js → app-L52CTVNR.js} +43 -6
- package/dist/{chunk-M3U2JICC.js → chunk-IGFN2DM5.js} +174 -36
- package/dist/{chunk-D4334NAE.js → chunk-JZ5FVBET.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/desktop/main.js +177 -36
- 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/tools/search.d.ts +2 -2
- 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
package/dist/desktop/main.js
CHANGED
|
@@ -4256,6 +4256,8 @@ function normalizeProviderError(error) {
|
|
|
4256
4256
|
code = "context_overflow";
|
|
4257
4257
|
} else if (status === 404 || /model.*not.?found|not.?found.*model/.test(searchable)) {
|
|
4258
4258
|
code = "model_not_found";
|
|
4259
|
+
} else if (status !== void 0 && status >= 500 && status <= 599) {
|
|
4260
|
+
code = "network";
|
|
4259
4261
|
} else if (status === void 0 && /econn|enet|socket|network|fetch failed|connection|timeout/.test(searchable)) {
|
|
4260
4262
|
code = "network";
|
|
4261
4263
|
}
|
|
@@ -6093,9 +6095,10 @@ function withStructuredOutput(options) {
|
|
|
6093
6095
|
throw new Error("Structured output retry delays must be non-negative integers");
|
|
6094
6096
|
}
|
|
6095
6097
|
}
|
|
6096
|
-
const
|
|
6098
|
+
const generatedTool = options.modelInputSchema === void 0 ? modelToolFromZod(options.name, options.description, options.schema) : { name: options.name, description: options.description, inputSchema: options.modelInputSchema };
|
|
6099
|
+
const tool = options.modelStrict === void 0 ? generatedTool : { ...generatedTool, strict: options.modelStrict };
|
|
6097
6100
|
const maxAttempts = retry.maxRetries + 1;
|
|
6098
|
-
const
|
|
6101
|
+
const validationSchema = jsonSchemaFromZod(options.schema);
|
|
6099
6102
|
const model = {
|
|
6100
6103
|
async *stream(request) {
|
|
6101
6104
|
let candidate;
|
|
@@ -6168,7 +6171,7 @@ function withStructuredOutput(options) {
|
|
|
6168
6171
|
}
|
|
6169
6172
|
}
|
|
6170
6173
|
if (candidateCount === 1 && candidate !== null && typeof candidate === "object") {
|
|
6171
|
-
candidate = coerceByJsonSchema(candidate,
|
|
6174
|
+
candidate = coerceByJsonSchema(candidate, validationSchema);
|
|
6172
6175
|
}
|
|
6173
6176
|
if (candidateCount !== 1) {
|
|
6174
6177
|
attemptError = {
|
|
@@ -6240,7 +6243,13 @@ function withStructuredOutput(options) {
|
|
|
6240
6243
|
return model;
|
|
6241
6244
|
}
|
|
6242
6245
|
function strictJsonSchema(schema) {
|
|
6243
|
-
return
|
|
6246
|
+
return strictJsonSchemaObject(jsonSchemaFromZod(schema));
|
|
6247
|
+
}
|
|
6248
|
+
function jsonSchemaFromZod(schema) {
|
|
6249
|
+
return z12.toJSONSchema(schema);
|
|
6250
|
+
}
|
|
6251
|
+
function strictJsonSchemaObject(schema) {
|
|
6252
|
+
return ensureStrictSchema(schema);
|
|
6244
6253
|
}
|
|
6245
6254
|
function extractJsonObject(text) {
|
|
6246
6255
|
const trimmed = text.trim();
|
|
@@ -6288,6 +6297,7 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6288
6297
|
const node = schema;
|
|
6289
6298
|
const branches = [
|
|
6290
6299
|
...Array.isArray(node.anyOf) ? node.anyOf : [],
|
|
6300
|
+
...Array.isArray(node.oneOf) ? node.oneOf : [],
|
|
6291
6301
|
...Array.isArray(node.allOf) ? node.allOf : []
|
|
6292
6302
|
].filter((branch) => branch !== null && typeof branch === "object");
|
|
6293
6303
|
const types = [];
|
|
@@ -6307,40 +6317,108 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6307
6317
|
if (lowered === "true") return true;
|
|
6308
6318
|
if (lowered === "false") return false;
|
|
6309
6319
|
}
|
|
6320
|
+
if (types.includes("object") && !types.includes("string") && typeof value === "string") {
|
|
6321
|
+
const trimmed = value.trim();
|
|
6322
|
+
if (trimmed.startsWith("{")) {
|
|
6323
|
+
try {
|
|
6324
|
+
const parsed = JSON.parse(trimmed);
|
|
6325
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
6326
|
+
return coerceByJsonSchema(parsed, node);
|
|
6327
|
+
}
|
|
6328
|
+
} catch {
|
|
6329
|
+
}
|
|
6330
|
+
}
|
|
6331
|
+
}
|
|
6332
|
+
if (types.includes("array") && !Array.isArray(value) && value !== null && value !== void 0 && !types.some((type) => matchesJsonSchemaType(value, type))) {
|
|
6333
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
6334
|
+
const type = candidate.type;
|
|
6335
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
6336
|
+
});
|
|
6337
|
+
if (typeof value === "string" && value.trim().startsWith("[")) {
|
|
6338
|
+
try {
|
|
6339
|
+
const parsed = JSON.parse(value.trim());
|
|
6340
|
+
if (Array.isArray(parsed)) return coerceByJsonSchema(parsed, arraySchema ?? node);
|
|
6341
|
+
} catch {
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
return [arraySchema?.items === void 0 ? value : coerceByJsonSchema(value, arraySchema.items)];
|
|
6345
|
+
}
|
|
6310
6346
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
6311
|
-
const
|
|
6347
|
+
const objectSchema = [node, ...branches].find((candidate) => candidate.type === "object" || candidate.properties !== void 0);
|
|
6348
|
+
const properties = objectSchema?.properties;
|
|
6312
6349
|
if (properties !== void 0) {
|
|
6313
6350
|
const output = {};
|
|
6351
|
+
const required2 = new Set(Array.isArray(objectSchema?.required) ? objectSchema.required : []);
|
|
6314
6352
|
for (const [key, child] of Object.entries(value)) {
|
|
6315
|
-
|
|
6353
|
+
const childSchema = properties[key];
|
|
6354
|
+
if (child === null && childSchema !== void 0 && !required2.has(key) && !jsonSchemaAllowsNull(childSchema)) {
|
|
6355
|
+
continue;
|
|
6356
|
+
}
|
|
6357
|
+
output[key] = childSchema !== void 0 ? coerceByJsonSchema(child, childSchema) : child;
|
|
6316
6358
|
}
|
|
6317
6359
|
return output;
|
|
6318
6360
|
}
|
|
6319
6361
|
}
|
|
6320
|
-
if (types.includes("array") && Array.isArray(value)
|
|
6321
|
-
|
|
6362
|
+
if (types.includes("array") && Array.isArray(value)) {
|
|
6363
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
6364
|
+
const type = candidate.type;
|
|
6365
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
6366
|
+
});
|
|
6367
|
+
if (arraySchema?.items !== void 0) {
|
|
6368
|
+
return value.map((item) => coerceByJsonSchema(item, arraySchema.items));
|
|
6369
|
+
}
|
|
6322
6370
|
}
|
|
6323
6371
|
return value;
|
|
6324
6372
|
}
|
|
6373
|
+
function matchesJsonSchemaType(value, type) {
|
|
6374
|
+
if (type === "null") return value === null;
|
|
6375
|
+
if (type === "array") return Array.isArray(value);
|
|
6376
|
+
if (type === "object") return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6377
|
+
if (type === "integer") return typeof value === "number" && Number.isInteger(value);
|
|
6378
|
+
if (type === "number") return typeof value === "number";
|
|
6379
|
+
return typeof value === type;
|
|
6380
|
+
}
|
|
6381
|
+
function jsonSchemaAllowsNull(schema) {
|
|
6382
|
+
if (schema === null || typeof schema !== "object") return false;
|
|
6383
|
+
const node = schema;
|
|
6384
|
+
if (node.type === "null" || Array.isArray(node.type) && node.type.includes("null")) return true;
|
|
6385
|
+
return [node.anyOf, node.oneOf].some((branches) => Array.isArray(branches) && branches.some((branch) => jsonSchemaAllowsNull(branch)));
|
|
6386
|
+
}
|
|
6325
6387
|
function modelToolFromZod(name, description, schema) {
|
|
6326
6388
|
return { name, description, inputSchema: strictJsonSchema(schema) };
|
|
6327
6389
|
}
|
|
6328
6390
|
function ensureStrictSchema(schema) {
|
|
6391
|
+
const output = { ...schema };
|
|
6392
|
+
for (const keyword of ["anyOf", "oneOf", "allOf", "prefixItems"]) {
|
|
6393
|
+
const branches = schema[keyword];
|
|
6394
|
+
if (Array.isArray(branches)) {
|
|
6395
|
+
output[keyword] = branches.map((branch) => typeof branch === "object" && branch !== null ? ensureStrictSchema(branch) : branch);
|
|
6396
|
+
}
|
|
6397
|
+
}
|
|
6398
|
+
if (typeof schema.items === "object" && schema.items !== null) {
|
|
6399
|
+
output.items = ensureStrictSchema(schema.items);
|
|
6400
|
+
}
|
|
6401
|
+
for (const keyword of ["$defs", "definitions"]) {
|
|
6402
|
+
const definitions = schema[keyword];
|
|
6403
|
+
if (typeof definitions === "object" && definitions !== null && !Array.isArray(definitions)) {
|
|
6404
|
+
output[keyword] = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [
|
|
6405
|
+
key,
|
|
6406
|
+
typeof definition === "object" && definition !== null ? ensureStrictSchema(definition) : definition
|
|
6407
|
+
]));
|
|
6408
|
+
}
|
|
6409
|
+
}
|
|
6329
6410
|
if (schema.type !== "object" || typeof schema.properties !== "object" || schema.properties === null) {
|
|
6330
|
-
return
|
|
6411
|
+
return output;
|
|
6331
6412
|
}
|
|
6332
|
-
const
|
|
6333
|
-
const requiredSet = new Set(required2);
|
|
6413
|
+
const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
6334
6414
|
const properties = {};
|
|
6335
6415
|
for (const [key, value] of Object.entries(schema.properties)) {
|
|
6336
6416
|
const child = typeof value === "object" && value !== null ? ensureStrictSchema(value) : value;
|
|
6337
|
-
if (requiredSet.has(key)) properties[key] = child;
|
|
6338
|
-
else {
|
|
6339
|
-
|
|
6340
|
-
requiredSet.add(key);
|
|
6341
|
-
}
|
|
6417
|
+
if (requiredSet.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
|
|
6418
|
+
else properties[key] = { anyOf: [child, { type: "null" }] };
|
|
6419
|
+
requiredSet.add(key);
|
|
6342
6420
|
}
|
|
6343
|
-
return { ...
|
|
6421
|
+
return { ...output, additionalProperties: false, required: [...requiredSet], properties };
|
|
6344
6422
|
}
|
|
6345
6423
|
function repairMessages(messages, tool, original, candidate, error) {
|
|
6346
6424
|
const details = [
|
|
@@ -6710,19 +6788,11 @@ var AgentLoop = class {
|
|
|
6710
6788
|
});
|
|
6711
6789
|
continue;
|
|
6712
6790
|
}
|
|
6713
|
-
const validation = collected.kind === "valid" ? this.#options.runtime.
|
|
6791
|
+
const validation = collected.kind === "valid" ? this.#options.runtime.normalize(collected) : { ok: false, error: collected.error };
|
|
6714
6792
|
if (validation.ok) {
|
|
6715
6793
|
toolCalls.push({ id: collected.id, name: collected.name, input: validation.input });
|
|
6716
6794
|
continue;
|
|
6717
6795
|
}
|
|
6718
|
-
if (collected.kind === "valid") {
|
|
6719
|
-
const coerced = coerceByJsonSchema(collected.input, strictJsonSchema(definition.inputSchema));
|
|
6720
|
-
const revalidation = this.#options.runtime.validate({ ...collected, input: coerced });
|
|
6721
|
-
if (revalidation.ok) {
|
|
6722
|
-
toolCalls.push({ id: collected.id, name: collected.name, input: revalidation.input });
|
|
6723
|
-
continue;
|
|
6724
|
-
}
|
|
6725
|
-
}
|
|
6726
6796
|
const repairModelId = this.#options.fallbackModelId ?? this.#options.modelId;
|
|
6727
6797
|
const invalidOutput = collected.kind === "invalid" ? collected.rawInput : serializeToolInput(collected.input);
|
|
6728
6798
|
const structured = withStructuredOutput({
|
|
@@ -6731,6 +6801,8 @@ var AgentLoop = class {
|
|
|
6731
6801
|
name: definition.name,
|
|
6732
6802
|
description: definition.description,
|
|
6733
6803
|
schema: definition.inputSchema,
|
|
6804
|
+
...definition.modelInputSchema === void 0 ? {} : { modelInputSchema: definition.modelInputSchema },
|
|
6805
|
+
...definition.modelStrict === void 0 ? {} : { modelStrict: definition.modelStrict },
|
|
6734
6806
|
beforeAttempt: async ({ attempt: repairAttempt, maxAttempts: repairMaxAttempts, messageCount }) => {
|
|
6735
6807
|
const before = await this.#options.hooks.emit({
|
|
6736
6808
|
version: 1,
|
|
@@ -7656,12 +7728,24 @@ var ToolRuntime = class {
|
|
|
7656
7728
|
throw error;
|
|
7657
7729
|
}
|
|
7658
7730
|
}
|
|
7731
|
+
/**
|
|
7732
|
+
* Validates a call and applies the same conservative provider-argument
|
|
7733
|
+
* normalization used by the agent loop before falling back to repair.
|
|
7734
|
+
*/
|
|
7735
|
+
normalize(call) {
|
|
7736
|
+
const validation = this.validate(call);
|
|
7737
|
+
if (validation.ok || validation.error.code === "unknown_tool") return validation;
|
|
7738
|
+
const tool = this.#tools.get(call.name);
|
|
7739
|
+
if (tool === void 0) return validation;
|
|
7740
|
+
const input = coerceByJsonSchema(call.input, jsonSchemaFromZod(tool.inputSchema));
|
|
7741
|
+
return this.validate({ ...call, input });
|
|
7742
|
+
}
|
|
7659
7743
|
async #execute(call, context) {
|
|
7660
7744
|
const tool = this.#tools.get(call.name);
|
|
7661
7745
|
if (tool === void 0) return { ok: false, error: { code: "unknown_tool", message: `Unknown tool: ${call.name}` } };
|
|
7662
7746
|
const signal = context.signal ?? new AbortController().signal;
|
|
7663
7747
|
const toolCallId = call.id ?? randomUUID7();
|
|
7664
|
-
const validation = this.
|
|
7748
|
+
const validation = this.normalize(call);
|
|
7665
7749
|
if (!validation.ok) {
|
|
7666
7750
|
return this.#fail(toolCallId, call.name, call.input, context.agent, validation.error.code, validation.error.message);
|
|
7667
7751
|
}
|
|
@@ -9412,6 +9496,7 @@ var PluginHost = class {
|
|
|
9412
9496
|
description: contribution.description,
|
|
9413
9497
|
inputSchema: z18.unknown(),
|
|
9414
9498
|
...contribution.modelInputSchema === void 0 ? {} : { modelInputSchema: contribution.modelInputSchema },
|
|
9499
|
+
...contribution.modelInputSchema === void 0 ? {} : { modelStrict: false },
|
|
9415
9500
|
...contribution.readOnly === void 0 ? {} : { readOnly: contribution.readOnly },
|
|
9416
9501
|
paths: () => [],
|
|
9417
9502
|
execute: (input, _signal, toolContext) => session.invoke("tool", contribution.name, [
|
|
@@ -17894,10 +17979,17 @@ var FILE_TYPE_EXTENSIONS = {
|
|
|
17894
17979
|
python: [".py", ".pyi"],
|
|
17895
17980
|
typescript: [".ts", ".tsx", ".mts", ".cts"]
|
|
17896
17981
|
};
|
|
17982
|
+
var BooleanInput = z30.preprocess((value) => {
|
|
17983
|
+
if (typeof value !== "string") return value;
|
|
17984
|
+
const normalized = value.trim().toLowerCase();
|
|
17985
|
+
if (normalized === "true") return true;
|
|
17986
|
+
if (normalized === "false") return false;
|
|
17987
|
+
return value;
|
|
17988
|
+
}, z30.boolean());
|
|
17897
17989
|
var GlobInput = z30.object({
|
|
17898
17990
|
pattern: z30.string().min(1),
|
|
17899
17991
|
path: z30.string().min(1).describe('Workspace-relative search directory. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
|
|
17900
|
-
includeIgnored:
|
|
17992
|
+
includeIgnored: BooleanInput.describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
|
|
17901
17993
|
limit: z30.coerce.number().int().positive().max(1e5).nullable().optional()
|
|
17902
17994
|
});
|
|
17903
17995
|
var GrepInput = z30.object({
|
|
@@ -17905,7 +17997,7 @@ var GrepInput = z30.object({
|
|
|
17905
17997
|
path: z30.string().min(1).describe('Workspace-relative search path. Use JSON null, not the string "null", for the workspace root.').nullable().optional(),
|
|
17906
17998
|
glob: z30.string().min(1).nullable().optional(),
|
|
17907
17999
|
fileType: z30.enum(FILE_TYPES).nullable().optional(),
|
|
17908
|
-
includeIgnored:
|
|
18000
|
+
includeIgnored: BooleanInput.describe("Include files excluded by .gitignore or .ignore. Git metadata remains excluded.").nullable().optional(),
|
|
17909
18001
|
context: z30.coerce.number().int().nonnegative().max(100).nullable().optional(),
|
|
17910
18002
|
limit: z30.coerce.number().int().positive().max(1e5).nullable().optional()
|
|
17911
18003
|
});
|
|
@@ -19914,7 +20006,7 @@ function compileDefinition(record3, scope2, workspace) {
|
|
|
19914
20006
|
name: record3.name,
|
|
19915
20007
|
description: record3.description,
|
|
19916
20008
|
inputSchema,
|
|
19917
|
-
modelInputSchema: record3.inputSchema,
|
|
20009
|
+
modelInputSchema: strictJsonSchemaObject(record3.inputSchema),
|
|
19918
20010
|
modelStrict: true,
|
|
19919
20011
|
...record3.agents === void 0 ? {} : { agents: record3.agents },
|
|
19920
20012
|
paths: () => [],
|
|
@@ -20404,16 +20496,24 @@ var MVP_COMMANDS = [
|
|
|
20404
20496
|
"fork",
|
|
20405
20497
|
"pals",
|
|
20406
20498
|
"chat",
|
|
20407
|
-
"co-work"
|
|
20499
|
+
"co-work",
|
|
20500
|
+
"tool"
|
|
20408
20501
|
];
|
|
20409
|
-
function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
20502
|
+
function parseSlashCommand(input, dynamicCommands = [], skillCommands = [], managedTools = []) {
|
|
20410
20503
|
const trimmed = input.trim();
|
|
20411
20504
|
if (!trimmed.startsWith("/")) return null;
|
|
20412
|
-
const
|
|
20505
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed.slice(1));
|
|
20506
|
+
const rawName = match?.[1] ?? "";
|
|
20507
|
+
const rawArguments = match?.[2] ?? "";
|
|
20508
|
+
const args = rawArguments.length === 0 ? [] : rawArguments.split(/\s+/u);
|
|
20413
20509
|
const name = rawName.toLowerCase();
|
|
20414
20510
|
if (!MVP_COMMANDS.includes(name) && dynamicCommands.includes(name)) {
|
|
20415
20511
|
return { name: "plugin", command: name, args };
|
|
20416
20512
|
}
|
|
20513
|
+
if (!MVP_COMMANDS.includes(name)) {
|
|
20514
|
+
const managedTool = managedTools.find((tool) => tool.toLowerCase() === name);
|
|
20515
|
+
if (managedTool !== void 0) return { name: "managed-tool", tool: managedTool, input: rawArguments };
|
|
20516
|
+
}
|
|
20417
20517
|
if (!MVP_COMMANDS.includes(name) && skillCommands.includes(name)) {
|
|
20418
20518
|
return { name: "skill", skill: name, prompt: args.join(" ") };
|
|
20419
20519
|
}
|
|
@@ -20435,6 +20535,15 @@ function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
|
20435
20535
|
}
|
|
20436
20536
|
return { name, mode: normalized };
|
|
20437
20537
|
}
|
|
20538
|
+
if (name === "tool") {
|
|
20539
|
+
const [requested] = args;
|
|
20540
|
+
const managedTool = requested === void 0 ? void 0 : managedTools.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());
|
|
20541
|
+
if (managedTool === void 0) {
|
|
20542
|
+
return { name: "invalid", command: name, message: "Use /tool <registered-tool> [JSON object]." };
|
|
20543
|
+
}
|
|
20544
|
+
const inputStart = rawArguments.search(/\s/u);
|
|
20545
|
+
return { name: "managed-tool", tool: managedTool, input: inputStart < 0 ? "" : rawArguments.slice(inputStart).trimStart() };
|
|
20546
|
+
}
|
|
20438
20547
|
if (name === "audit") {
|
|
20439
20548
|
const toolFilter = args.length > 0 ? args.join(" ") : void 0;
|
|
20440
20549
|
return { name, toolFilter };
|
|
@@ -20662,6 +20771,7 @@ var HELP = [
|
|
|
20662
20771
|
"/review [focus] review uncommitted changes before committing",
|
|
20663
20772
|
"/evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>> self-improvement loop",
|
|
20664
20773
|
"/mcp [status|tools|reconnect|enable|disable] manage MCP servers",
|
|
20774
|
+
"/tool <registered-tool> [JSON object] run a registered tool (or use /<tool-name>)",
|
|
20665
20775
|
"/ide show VS Code connection and cursor/selection",
|
|
20666
20776
|
"/pals [--verbose|rename <alias>|info <alias-or-uuid>]",
|
|
20667
20777
|
"/chat <alias-or-uuid> <goal> send a task that starts on the receiving pal",
|
|
@@ -20933,7 +21043,12 @@ var FlavorSession = class {
|
|
|
20933
21043
|
} catch {
|
|
20934
21044
|
}
|
|
20935
21045
|
}
|
|
20936
|
-
const command = parseSlashCommand(
|
|
21046
|
+
const command = parseSlashCommand(
|
|
21047
|
+
prompt,
|
|
21048
|
+
this.#services.pluginCommands().map(({ name }) => name),
|
|
21049
|
+
skillNames,
|
|
21050
|
+
this.#services.managedToolCommands().map(({ name }) => name)
|
|
21051
|
+
);
|
|
20937
21052
|
if (command !== null) await this.#dispatch(command, controller2.signal);
|
|
20938
21053
|
else for await (const event of this.#services.run(prompt, controller2.signal, {
|
|
20939
21054
|
getSteeringMessages: () => this.#drainMessages("steer", true).map((item) => item.text),
|
|
@@ -21035,6 +21150,8 @@ var FlavorSession = class {
|
|
|
21035
21150
|
this.#notice(`Main permissions set to ${command.mode}. Child approvals use bubble mode unless plan mode is active.`);
|
|
21036
21151
|
} else if (command.name === "plugin") {
|
|
21037
21152
|
this.#notice(format(await this.#services.runPluginCommand(command.command, command.args, signal)));
|
|
21153
|
+
} else if (command.name === "managed-tool") {
|
|
21154
|
+
this.#notice(format(await this.#services.runManagedTool(command.tool, command.input, signal)));
|
|
21038
21155
|
} else if (command.name === "skill") {
|
|
21039
21156
|
for await (const event of this.#services.runSkill(command.skill, command.prompt, signal)) this.#services.output(event);
|
|
21040
21157
|
} else if (command.name === "loop") {
|
|
@@ -24635,6 +24752,7 @@ async function createProductionRuntime(options) {
|
|
|
24635
24752
|
managedTools.push(tool);
|
|
24636
24753
|
}
|
|
24637
24754
|
if (harnessCreated) harness.replaceMainTools(tools);
|
|
24755
|
+
options.onToolsChange?.();
|
|
24638
24756
|
};
|
|
24639
24757
|
tools.push(...createManagedToolManagementTools({
|
|
24640
24758
|
store: managedToolStore,
|
|
@@ -25964,6 +26082,25 @@ ${renderMemoryDocument(entries)}`;
|
|
|
25964
26082
|
signal.throwIfAborted();
|
|
25965
26083
|
return awaitWithSignal3(Promise.resolve(handler(args, { workspace, signal })), signal);
|
|
25966
26084
|
},
|
|
26085
|
+
managedToolCommands: () => managedTools.map(({ name, description }) => ({ name, description })).sort((left, right) => left.name.localeCompare(right.name)),
|
|
26086
|
+
runManagedTool: async (name, rawInput, signal) => {
|
|
26087
|
+
const tool = managedTools.find((candidate) => sameToolName(candidate.name, name));
|
|
26088
|
+
if (tool === void 0) throw new Error(`Registered tool "${name}" is no longer available.`);
|
|
26089
|
+
signal.throwIfAborted();
|
|
26090
|
+
const input = normalizeToolCallInput(rawInput);
|
|
26091
|
+
const call = { name: tool.name, input };
|
|
26092
|
+
const validation = harness.main.runtime.normalize(call);
|
|
26093
|
+
if (!validation.ok) throw new Error(`Invalid input for registered tool "${tool.name}": ${validation.error.message}`);
|
|
26094
|
+
harness.main.runtime.beginTurn();
|
|
26095
|
+
const result = await harness.main.runtime.execute(
|
|
26096
|
+
{ name: tool.name, input: validation.input },
|
|
26097
|
+
{ agent: "main", ownerId: "main", signal }
|
|
26098
|
+
);
|
|
26099
|
+
if (!result.ok) {
|
|
26100
|
+
throw new Error(`Registered tool "${tool.name}" failed (${result.error?.code ?? "unknown"}): ${result.error?.message ?? "Unknown error"}`);
|
|
26101
|
+
}
|
|
26102
|
+
return result.output !== void 0 ? result.output : result.content;
|
|
26103
|
+
},
|
|
25967
26104
|
output: emitOutput,
|
|
25968
26105
|
questions,
|
|
25969
26106
|
async login() {
|
|
@@ -26358,7 +26495,7 @@ ${expandSkillArguments(await skills.loadBody(skill), prompt)}`);
|
|
|
26358
26495
|
...additionalContext === void 0 ? {} : { additionalContext },
|
|
26359
26496
|
...getSteeringMessages === void 0 ? {} : { getSteeringMessages }
|
|
26360
26497
|
})) {
|
|
26361
|
-
if (event.type === "error" && /adapter|provider|api.?key|model/i.test(event.error.message)) {
|
|
26498
|
+
if (event.type === "error" && event.error.code !== "network" && event.error.code !== "rate_limit" && /adapter|provider|api.?key|model/i.test(event.error.message)) {
|
|
26362
26499
|
yield { ...event, error: {
|
|
26363
26500
|
...event.error,
|
|
26364
26501
|
message: `${event.error.message}. Configure providers and agents in .flavor/flavor.json or set OPENAI_API_KEY/ANTHROPIC_API_KEY.`
|
|
@@ -29277,7 +29414,8 @@ var DesktopRuntimeController = class {
|
|
|
29277
29414
|
...runtime.approvals.pending === void 0 ? {} : { approval: runtime.approvals.pending },
|
|
29278
29415
|
...runtime.services.questions.pending === void 0 ? {} : { questions: runtime.services.questions.pending },
|
|
29279
29416
|
...runtime.memoryReviews.pending.length === 0 ? {} : { memoryReviews: runtime.memoryReviews.pending },
|
|
29280
|
-
...(runtime.memoryReviews.autoDismissSeconds ?? 0) > 0 ? { memoryAutoDismissSeconds: runtime.memoryReviews.autoDismissSeconds } : {}
|
|
29417
|
+
...(runtime.memoryReviews.autoDismissSeconds ?? 0) > 0 ? { memoryAutoDismissSeconds: runtime.memoryReviews.autoDismissSeconds } : {},
|
|
29418
|
+
...(runtime.services.managedToolCommands?.().length ?? 0) === 0 ? {} : { managedTools: runtime.services.managedToolCommands() }
|
|
29281
29419
|
},
|
|
29282
29420
|
diagnostics: runtime?.diagnostics ?? [],
|
|
29283
29421
|
models: this.#models,
|
|
@@ -29331,6 +29469,9 @@ var DesktopRuntimeController = class {
|
|
|
29331
29469
|
},
|
|
29332
29470
|
onApprovalChange: () => {
|
|
29333
29471
|
if (this.#runtime !== void 0) this.#publishSnapshot();
|
|
29472
|
+
},
|
|
29473
|
+
onToolsChange: () => {
|
|
29474
|
+
if (this.#runtime !== void 0) this.#publishSnapshot();
|
|
29334
29475
|
}
|
|
29335
29476
|
});
|
|
29336
29477
|
outputSessionId = runtime.sessionId;
|