flavor-code 1.4.0-beta.8 → 1.4.1-beta.1

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.
@@ -214,9 +214,8 @@ var ProviderConfigSchema = z2.object({
214
214
  // parameter. Provider thinking deltas are forwarded whenever they arrive.
215
215
  thinkingBudget: z2.number().int().min(0).optional(),
216
216
  // Reasoning effort requested from the OpenAI Responses protocol (sent as
217
- // reasoning.effort). Omitted by default so strict compatible gateways never
218
- // see an unknown parameter and the endpoint uses its server-side default.
219
- thinkingEffort: z2.enum(["minimal", "low", "medium", "high", "xhigh"]).optional(),
217
+ // reasoning.effort). The adapter defaults an omitted value to high.
218
+ thinkingEffort: z2.enum(["minimal", "low", "medium", "high", "xhigh", "ultra"]).optional(),
220
219
  // Send the Claude Code client fingerprint (User-Agent/x-app) with Anthropic requests,
221
220
  // for gateways that restrict the Anthropic protocol to Claude clients.
222
221
  claudeClient: z2.boolean().optional(),
@@ -4267,10 +4266,12 @@ function normalizeProviderError(error) {
4267
4266
  code = "authentication";
4268
4267
  } else if (status === 429 || /rate.?limit|overloaded/.test(searchable)) {
4269
4268
  code = "rate_limit";
4270
- } else if (/context|too many tokens|prompt.*long/.test(searchable)) {
4269
+ } else if (/context[_\s-]?(?:length|window|overflow)(?:[_\s-]?(?:exceeded|limit))?/.test(searchable) || /maximum context length|too many tokens|prompt.*(?:too )?long/.test(searchable)) {
4271
4270
  code = "context_overflow";
4272
4271
  } else if (status === 404 || /model.*not.?found|not.?found.*model/.test(searchable)) {
4273
4272
  code = "model_not_found";
4273
+ } else if (status === 400 || status === 422 || /invalid schema|schema.*(?:invalid|not (?:a )?valid)/.test(searchable)) {
4274
+ code = "invalid_request";
4274
4275
  } else if (status !== void 0 && status >= 500 && status <= 599) {
4275
4276
  code = "network";
4276
4277
  } else if (status === void 0 && /econn|enet|socket|network|fetch failed|connection|timeout/.test(searchable)) {
@@ -6404,7 +6405,10 @@ function jsonSchemaFromZod(schema) {
6404
6405
  return z12.toJSONSchema(schema);
6405
6406
  }
6406
6407
  function strictJsonSchemaObject(schema) {
6407
- return ensureStrictSchema(schema);
6408
+ return normalizeOpenAIJsonSchemaObject(schema, true);
6409
+ }
6410
+ function openAIJsonSchemaObject(schema, strict) {
6411
+ return normalizeOpenAIJsonSchemaObject(schema, strict);
6408
6412
  }
6409
6413
  function extractJsonObject(text) {
6410
6414
  const trimmed = text.trim();
@@ -6542,40 +6546,194 @@ function jsonSchemaAllowsNull(schema) {
6542
6546
  function modelToolFromZod(name, description, schema) {
6543
6547
  return { name, description, inputSchema: strictJsonSchema(schema) };
6544
6548
  }
6545
- function ensureStrictSchema(schema) {
6549
+ var JSON_SCHEMA_TYPES = /* @__PURE__ */ new Set(["null", "boolean", "object", "array", "number", "string", "integer"]);
6550
+ var OPENAI_UNSUPPORTED_SCHEMA_KEYWORDS = [
6551
+ "$schema",
6552
+ "$id",
6553
+ "$anchor",
6554
+ "$dynamicAnchor",
6555
+ "$dynamicRef",
6556
+ "$comment",
6557
+ "default",
6558
+ "examples",
6559
+ "example",
6560
+ "deprecated",
6561
+ "readOnly",
6562
+ "writeOnly",
6563
+ "format",
6564
+ "propertyNames",
6565
+ "patternProperties",
6566
+ "unevaluatedProperties",
6567
+ "unevaluatedItems",
6568
+ "additionalItems",
6569
+ "contains",
6570
+ "minContains",
6571
+ "maxContains",
6572
+ "uniqueItems",
6573
+ "minProperties",
6574
+ "maxProperties",
6575
+ "contentEncoding",
6576
+ "contentMediaType",
6577
+ "not",
6578
+ "if",
6579
+ "then",
6580
+ "else",
6581
+ "dependentRequired",
6582
+ "dependentSchemas",
6583
+ "dependencies"
6584
+ ];
6585
+ function normalizeOpenAIJsonSchemaObject(schema, strict) {
6586
+ const normalized = normalizeOpenAIJsonSchemaNode(schema, strict);
6587
+ if (normalized.type === "object") return normalized;
6588
+ return strict ? { type: "object", properties: {}, required: [], additionalProperties: false } : { type: "object", properties: {}, additionalProperties: true };
6589
+ }
6590
+ function normalizeOpenAIJsonSchemaNode(rawSchema, strict) {
6591
+ const schema = mergeObjectAllOf(rawSchema);
6546
6592
  const output = { ...schema };
6547
- delete output.propertyNames;
6548
- delete output.patternProperties;
6549
- for (const keyword of ["anyOf", "oneOf", "allOf", "prefixItems"]) {
6550
- const branches = schema[keyword];
6551
- if (Array.isArray(branches)) {
6552
- output[keyword] = branches.map((branch) => typeof branch === "object" && branch !== null ? ensureStrictSchema(branch) : branch);
6553
- }
6554
- }
6555
- if (typeof schema.items === "object" && schema.items !== null) {
6556
- output.items = ensureStrictSchema(schema.items);
6557
- }
6558
- for (const keyword of ["$defs", "definitions"]) {
6559
- const definitions = schema[keyword];
6560
- if (typeof definitions === "object" && definitions !== null && !Array.isArray(definitions)) {
6561
- output[keyword] = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [
6562
- key,
6563
- typeof definition === "object" && definition !== null ? ensureStrictSchema(definition) : definition
6564
- ]));
6593
+ for (const keyword of OPENAI_UNSUPPORTED_SCHEMA_KEYWORDS) delete output[keyword];
6594
+ delete output.oneOf;
6595
+ delete output.allOf;
6596
+ delete output.prefixItems;
6597
+ delete output.nullable;
6598
+ delete output.definitions;
6599
+ if (typeof output.$ref === "string" && output.$ref.startsWith("#/definitions/")) {
6600
+ output.$ref = output.$ref.replace("#/definitions/", "#/$defs/");
6601
+ }
6602
+ const compositionBranches = [
6603
+ ...Array.isArray(schema.anyOf) ? schema.anyOf : [],
6604
+ ...Array.isArray(schema.oneOf) ? schema.oneOf : [],
6605
+ ...Array.isArray(schema.allOf) ? schema.allOf : []
6606
+ ];
6607
+ if (compositionBranches.length > 0) {
6608
+ output.anyOf = compositionBranches.map((branch) => normalizeOpenAISchemaValue(branch, strict));
6609
+ } else {
6610
+ delete output.anyOf;
6611
+ }
6612
+ const definitions = {
6613
+ ...isSchemaRecord(schema.definitions) ? schema.definitions : {},
6614
+ ...isSchemaRecord(schema.$defs) ? schema.$defs : {}
6615
+ };
6616
+ if (Object.keys(definitions).length > 0) {
6617
+ output.$defs = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [key, normalizeOpenAISchemaValue(definition, strict)]));
6618
+ }
6619
+ const prefixItems = Array.isArray(schema.prefixItems) ? schema.prefixItems : void 0;
6620
+ if (prefixItems !== void 0 && prefixItems.length > 0) {
6621
+ const tupleItems = prefixItems.map((item) => normalizeOpenAISchemaValue(item, strict));
6622
+ output.items = tupleItems.length === 1 ? tupleItems[0] : { anyOf: tupleItems };
6623
+ } else if (Array.isArray(schema.items)) {
6624
+ const tupleItems = schema.items.map((item) => normalizeOpenAISchemaValue(item, strict));
6625
+ output.items = tupleItems.length === 1 ? tupleItems[0] : { anyOf: tupleItems };
6626
+ } else if (isSchemaRecord(schema.items)) {
6627
+ output.items = normalizeOpenAIJsonSchemaNode(schema.items, strict);
6628
+ } else if (schema.items === true || schema.items === false) {
6629
+ output.items = universalJsonValueSchema(strict);
6630
+ }
6631
+ let type = schema.type;
6632
+ if (type === void 0 && isSchemaRecord(schema.properties)) type = "object";
6633
+ if (type === void 0 && output.items !== void 0) type = "array";
6634
+ if (type === void 0 && Array.isArray(schema.enum)) type = inferJsonTypes(schema.enum);
6635
+ if (type === void 0 && Object.hasOwn(schema, "const")) type = inferJsonTypes([schema.const]);
6636
+ if (typeof type === "string" && !JSON_SCHEMA_TYPES.has(type)) type = void 0;
6637
+ if (Array.isArray(type)) {
6638
+ const types = type.filter((candidate) => typeof candidate === "string" && JSON_SCHEMA_TYPES.has(candidate));
6639
+ type = types.length === 0 ? void 0 : types;
6640
+ }
6641
+ delete output.type;
6642
+ if (type !== void 0) output.type = type;
6643
+ if (schemaTypeIncludes(type, "array") && output.items === void 0) {
6644
+ output.items = universalJsonValueSchema(strict);
6645
+ }
6646
+ if (schemaTypeIncludes(type, "object")) {
6647
+ const sourceProperties = isSchemaRecord(schema.properties) ? schema.properties : {};
6648
+ const sourceRequired = new Set(Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === "string") : []);
6649
+ const properties = {};
6650
+ for (const [key, value] of Object.entries(sourceProperties)) {
6651
+ const child = normalizeOpenAISchemaValue(value, strict);
6652
+ if (!strict || sourceRequired.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
6653
+ else properties[key] = { anyOf: [child, { type: "null" }] };
6654
+ if (strict) sourceRequired.add(key);
6655
+ }
6656
+ output.properties = properties;
6657
+ const required2 = strict ? Object.keys(properties) : [...sourceRequired].filter((key) => Object.hasOwn(properties, key));
6658
+ if (strict || required2.length > 0 || Array.isArray(schema.required)) output.required = required2;
6659
+ else delete output.required;
6660
+ if (strict) {
6661
+ output.additionalProperties = false;
6662
+ } else if (schema.additionalProperties === true || schema.additionalProperties === false) {
6663
+ output.additionalProperties = schema.additionalProperties;
6664
+ } else if (isSchemaRecord(schema.additionalProperties)) {
6665
+ output.additionalProperties = Object.keys(schema.additionalProperties).length === 0 ? true : normalizeOpenAIJsonSchemaNode(schema.additionalProperties, false);
6666
+ } else {
6667
+ delete output.additionalProperties;
6565
6668
  }
6566
6669
  }
6567
- if (schema.type !== "object" || typeof schema.properties !== "object" || schema.properties === null) {
6568
- return output;
6670
+ if (schema.nullable === true && !jsonSchemaAllowsNull(output)) {
6671
+ const description = typeof output.description === "string" ? output.description : void 0;
6672
+ const branch = { ...output };
6673
+ delete branch.description;
6674
+ return {
6675
+ ...description === void 0 ? {} : { description },
6676
+ anyOf: [branch, { type: "null" }]
6677
+ };
6569
6678
  }
6570
- const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
6571
- const properties = {};
6572
- for (const [key, value] of Object.entries(schema.properties)) {
6573
- const child = typeof value === "object" && value !== null ? ensureStrictSchema(value) : value;
6574
- if (requiredSet.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
6575
- else properties[key] = { anyOf: [child, { type: "null" }] };
6576
- requiredSet.add(key);
6679
+ if (isTypedOrComposedSchema(output)) return output;
6680
+ return universalJsonValueSchema(strict);
6681
+ }
6682
+ function mergeObjectAllOf(schema) {
6683
+ const branches = Array.isArray(schema.allOf) ? schema.allOf.filter(isSchemaRecord) : [];
6684
+ if (branches.length === 0 || !branches.every(isObjectSchema)) return schema;
6685
+ const base = { ...schema };
6686
+ delete base.allOf;
6687
+ const properties = isSchemaRecord(base.properties) ? { ...base.properties } : {};
6688
+ const required2 = new Set(Array.isArray(base.required) ? base.required.filter((key) => typeof key === "string") : []);
6689
+ for (const branch of branches) {
6690
+ if (isSchemaRecord(branch.properties)) {
6691
+ for (const [key, value] of Object.entries(branch.properties)) {
6692
+ const existing = properties[key];
6693
+ properties[key] = existing === void 0 ? value : { anyOf: [existing, value] };
6694
+ }
6695
+ }
6696
+ if (Array.isArray(branch.required)) {
6697
+ for (const key of branch.required) if (typeof key === "string") required2.add(key);
6698
+ }
6577
6699
  }
6578
- return { ...output, additionalProperties: false, required: [...requiredSet], properties };
6700
+ return { ...base, type: "object", properties, required: [...required2] };
6701
+ }
6702
+ function normalizeOpenAISchemaValue(value, strict) {
6703
+ if (isSchemaRecord(value)) return normalizeOpenAIJsonSchemaNode(value, strict);
6704
+ return universalJsonValueSchema(strict);
6705
+ }
6706
+ function universalJsonValueSchema(strict) {
6707
+ const scalar = [{ type: "string" }, { type: "number" }, { type: "boolean" }, { type: "null" }];
6708
+ return {
6709
+ anyOf: [
6710
+ ...scalar,
6711
+ strict ? { type: "object", properties: {}, required: [], additionalProperties: false } : { type: "object", properties: {}, additionalProperties: true },
6712
+ { type: "array", items: { anyOf: scalar } }
6713
+ ]
6714
+ };
6715
+ }
6716
+ function inferJsonTypes(values) {
6717
+ const types = [...new Set(values.map((value) => {
6718
+ if (value === null) return "null";
6719
+ if (Array.isArray(value)) return "array";
6720
+ if (typeof value === "number") return Number.isInteger(value) ? "integer" : "number";
6721
+ if (typeof value === "object") return "object";
6722
+ return typeof value;
6723
+ }).filter((type) => ["null", "array", "object", "integer", "number", "string", "boolean"].includes(type)))];
6724
+ return types.length === 0 ? void 0 : types.length === 1 ? types[0] : types;
6725
+ }
6726
+ function isSchemaRecord(value) {
6727
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6728
+ }
6729
+ function isObjectSchema(schema) {
6730
+ return schema.type === "object" || isSchemaRecord(schema.properties);
6731
+ }
6732
+ function isTypedOrComposedSchema(schema) {
6733
+ return typeof schema.type === "string" || Array.isArray(schema.type) || typeof schema.$ref === "string" || Array.isArray(schema.anyOf);
6734
+ }
6735
+ function schemaTypeIncludes(type, expected) {
6736
+ return type === expected || Array.isArray(type) && type.includes(expected);
6579
6737
  }
6580
6738
  function repairMessages(messages, tool, original, candidate, error) {
6581
6739
  const details = [
@@ -7979,9 +8137,11 @@ var ToolRuntime = class {
7979
8137
  if (pre.decision === "deny") {
7980
8138
  return this.#fail(toolCallId, tool.name, input, context.agent, "hook_denied", pre.reason ?? "Tool use denied by hook");
7981
8139
  }
8140
+ const approvalInput = tool.permissionInput?.(input) ?? input;
7982
8141
  const request = {
7983
8142
  agent: context.agent,
7984
8143
  tool: tool.name,
8144
+ input: approvalInput,
7985
8145
  ...tool.permissions?.(input) ?? { paths: tool.paths(input) },
7986
8146
  ...tool.readOnly === true ? { readOnly: true } : {}
7987
8147
  };
@@ -8014,7 +8174,7 @@ var ToolRuntime = class {
8014
8174
  payload: {
8015
8175
  toolCallId,
8016
8176
  tool: tool.name,
8017
- input: tool.permissionInput?.(input) ?? input,
8177
+ input: approvalInput,
8018
8178
  agent: context.agent,
8019
8179
  reason,
8020
8180
  toolCategory: getToolCategory(tool.name),
@@ -11460,10 +11620,11 @@ async function createExampleFlavorConfig(cwd) {
11460
11620
  pkce: {
11461
11621
  type: "oauth-callback",
11462
11622
  apiType: "anthropic",
11463
- authorizationUrl: "http://192.168.1.100:8091/authorize",
11464
- tokenUrl: "http://192.168.1.100:8091/token",
11623
+ authorizationUrl: "http://127.0.0.1:8091/authorize",
11624
+ tokenUrl: "http://127.0.0.1:8091/token",
11465
11625
  clientId: "flavor-code-cli",
11466
- scope: "models:read models:use"
11626
+ scope: "models:read models:use",
11627
+ thinkingEffort: "high"
11467
11628
  }
11468
11629
  },
11469
11630
  agents: {
@@ -12033,7 +12194,7 @@ ${evidence.summary}`;
12033
12194
  }
12034
12195
  };
12035
12196
  function isResumableWorkerError(error) {
12036
- return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "cancelled" && error.code !== "memory_pressure";
12197
+ return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "invalid_request" && error.code !== "cancelled" && error.code !== "memory_pressure";
12037
12198
  }
12038
12199
  function countTrailingFailureSignature(cycles, signature) {
12039
12200
  let count = 0;
@@ -12747,10 +12908,10 @@ function resumeStartRound(state) {
12747
12908
  return state.verifyRounds >= state.workerRounds ? state.workerRounds + 1 : Math.max(state.workerRounds, 1);
12748
12909
  }
12749
12910
  function isResumableWorkerError2(error) {
12750
- return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "cancelled" && error.code !== "memory_pressure";
12911
+ return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "invalid_request" && error.code !== "cancelled" && error.code !== "memory_pressure";
12751
12912
  }
12752
12913
  function isResumableStageError(error) {
12753
- return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "cancelled" && error.code !== "memory_pressure";
12914
+ return error.code !== "authentication" && error.code !== "model_not_found" && error.code !== "invalid_request" && error.code !== "cancelled" && error.code !== "memory_pressure";
12754
12915
  }
12755
12916
  function stageRetryDelay(options, attempt) {
12756
12917
  const delayMs = options.stageRetryDelayMs?.(attempt) ?? Math.min(6e4, 1e3 * 2 ** Math.min(attempt - 1, 6));
@@ -14578,6 +14739,7 @@ function resolveCacheProfile(input) {
14578
14739
  // src/models/openai.ts
14579
14740
  import OpenAI from "openai";
14580
14741
  import { readFile as readFile16 } from "fs/promises";
14742
+ var DEFAULT_THINKING_EFFORT = "high";
14581
14743
  async function toInput(message2) {
14582
14744
  if (message2.role === "tool") {
14583
14745
  if (!message2.toolCallId) throw new Error("Tool messages require toolCallId");
@@ -14653,7 +14815,7 @@ var OpenAIModelAdapter = class {
14653
14815
  ...options.baseURL === void 0 ? {} : { baseURL: options.baseURL }
14654
14816
  });
14655
14817
  this.debugUsage = options.debugUsage ?? isEnvTruthy(process.env.FLAVOR_DEBUG_USAGE);
14656
- this.thinkingEffort = options.thinkingEffort;
14818
+ this.thinkingEffort = options.thinkingEffort ?? DEFAULT_THINKING_EFFORT;
14657
14819
  }
14658
14820
  #logUsage(model, breakdown) {
14659
14821
  if (breakdown === void 0) return;
@@ -14676,12 +14838,12 @@ var OpenAIModelAdapter = class {
14676
14838
  const body = {
14677
14839
  model: request.model,
14678
14840
  input: (await Promise.all(request.messages.map(toInput))).flat(),
14679
- ...this.thinkingEffort === void 0 ? {} : { reasoning: { effort: this.thinkingEffort } },
14841
+ reasoning: { effort: this.thinkingEffort },
14680
14842
  tools: [...request.tools].sort((a, b) => a.name.localeCompare(b.name)).map((tool) => ({
14681
14843
  type: "function",
14682
14844
  name: tool.name,
14683
14845
  description: tool.description,
14684
- parameters: tool.inputSchema,
14846
+ parameters: openAIJsonSchemaObject(tool.inputSchema, tool.strict ?? true),
14685
14847
  strict: tool.strict ?? true
14686
14848
  }))
14687
14849
  };
@@ -21467,6 +21629,15 @@ var RegisterManagedToolInputSchema = z37.object({
21467
21629
  "Agent roles allowed to call the generated tool; omit to allow both"
21468
21630
  )
21469
21631
  }).strict();
21632
+ var RegisterManagedToolModelInputSchema = (() => {
21633
+ const schema = jsonSchemaFromZod(RegisterManagedToolInputSchema);
21634
+ const properties = schema.properties;
21635
+ const inputSchema = { ...properties.inputSchema };
21636
+ delete inputSchema.propertyNames;
21637
+ delete inputSchema.patternProperties;
21638
+ inputSchema.additionalProperties = true;
21639
+ return { ...schema, properties: { ...properties, inputSchema } };
21640
+ })();
21470
21641
  var RemoveManagedToolInputSchema = z37.object({
21471
21642
  name: z37.string().regex(TOOL_NAME).describe("Managed tool name to remove"),
21472
21643
  scope: z37.enum(["project", "global"]).optional().describe("Required only when the same name exists in both scopes")
@@ -21612,6 +21783,8 @@ function createManagedToolManagementTools(options) {
21612
21783
  name: "RegisterTool",
21613
21784
  description: "Create a durable custom tool from JSON Schema and async JavaScript, then expose it immediately",
21614
21785
  inputSchema: RegisterManagedToolInputSchema,
21786
+ modelInputSchema: RegisterManagedToolModelInputSchema,
21787
+ modelStrict: false,
21615
21788
  agents: mainOnly,
21616
21789
  paths: (rawInput) => {
21617
21790
  const parsed = RegisterManagedToolInputSchema.safeParse(rawInput);
@@ -28793,7 +28966,7 @@ function terminalProgressState(status) {
28793
28966
  return "failed";
28794
28967
  }
28795
28968
  function isResumableLongTaskError(code) {
28796
- return code !== "authentication" && code !== "model_not_found" && code !== "cancelled" && code !== "memory_pressure";
28969
+ return code !== "authentication" && code !== "model_not_found" && code !== "invalid_request" && code !== "cancelled" && code !== "memory_pressure";
28797
28970
  }
28798
28971
  async function workspaceFingerprint(workspace) {
28799
28972
  const hash = createHash21("sha256");