zelari-code 1.14.1 → 1.14.3

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.
@@ -741,10 +741,11 @@ var init_providerConfig = __esm({
741
741
  DEFAULTS = {
742
742
  activeProviderId: "openai-compatible",
743
743
  modelByProvider: {
744
- "openai-compatible": "grok-4",
744
+ // grok-4.5: flagship; reasoning_effort defaults to "high" on the xAI API
745
+ "openai-compatible": "grok-4.5",
745
746
  "minimax": "MiniMax-M2.5",
746
747
  "glm": "glm-4.6",
747
- "grok": "grok-4",
748
+ "grok": "grok-4.5",
748
749
  "deepseek": "deepseek-v4-pro",
749
750
  "custom": ""
750
751
  },
@@ -19835,7 +19836,7 @@ ${cached2}`
19835
19836
  const key = hashToolCall(tt.name, tt.args);
19836
19837
  return !turnToolCalls.some((n) => hashToolCall(n.name, n.args) === key);
19837
19838
  });
19838
- if ((/---TOOLS---/.test(turnText) || /minimax|invoke\s+name=/i.test(turnText)) && textTools.length === 0) {
19839
+ if ((/---TOOLS---/.test(turnText) || /<\/?minimax:tool_call\b/i.test(turnText) || /invoke\s+name\s*=/i.test(turnText) || /\]\s*<\s*\]\s*minimax\s*\[/i.test(turnText)) && textTools.length === 0) {
19839
19840
  const parseErr = createBrainEvent("error", this.sessionId, {
19840
19841
  severity: "recoverable",
19841
19842
  message: "Found text-format tool block but parse failed; tool calls were not executed. Prefer native tool_call, or ---TOOLS--- with ONE valid JSON array.",
@@ -19902,6 +19903,9 @@ ${cached2}`
19902
19903
  finishRef.value = "tool_calls";
19903
19904
  }
19904
19905
  }
19906
+ if (turnToolResults.length > 0) {
19907
+ finishRef.value = "tool_calls";
19908
+ }
19905
19909
  if (finishRef.value === "tool_calls" && turnToolCalls.length === 0 && turnToolResults.length === 0) {
19906
19910
  const truncErr = createBrainEvent("error", this.sessionId, {
19907
19911
  severity: "recoverable",
@@ -20367,6 +20371,38 @@ function openaiCompatibleProvider(config2) {
20367
20371
  const decoder = new TextDecoder();
20368
20372
  let buffer = "";
20369
20373
  const toolCallAccumulator = /* @__PURE__ */ new Map();
20374
+ let emittedToolCall = false;
20375
+ let reasoningDetailsBuf = "";
20376
+ const tryParseArgs = (raw) => {
20377
+ const t = raw.trim();
20378
+ if (t.length === 0) return {};
20379
+ try {
20380
+ const parsed = JSON.parse(t);
20381
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
20382
+ return parsed;
20383
+ }
20384
+ return null;
20385
+ } catch {
20386
+ return null;
20387
+ }
20388
+ };
20389
+ const flushToolAccumulator = function* () {
20390
+ const entries = [...toolCallAccumulator.entries()].sort((a, b) => a[0] - b[0]);
20391
+ for (const [idx, existing] of entries) {
20392
+ if (!existing.name) continue;
20393
+ const args = tryParseArgs(existing.argsJson);
20394
+ if (args === null) continue;
20395
+ toolCallAccumulator.delete(idx);
20396
+ emittedToolCall = true;
20397
+ yield {
20398
+ kind: "tool_call",
20399
+ toolCallId: existing.id || `tc-${idx}`,
20400
+ toolName: existing.name,
20401
+ args
20402
+ };
20403
+ }
20404
+ toolCallAccumulator.clear();
20405
+ };
20370
20406
  try {
20371
20407
  while (true) {
20372
20408
  const { value, done } = await reader.read();
@@ -20379,7 +20415,11 @@ function openaiCompatibleProvider(config2) {
20379
20415
  if (!trimmed.startsWith("data:")) continue;
20380
20416
  const data = trimmed.slice(5).trim();
20381
20417
  if (data === "[DONE]") {
20382
- yield { kind: "finish", reason: "stop" };
20418
+ yield* flushToolAccumulator();
20419
+ yield {
20420
+ kind: "finish",
20421
+ reason: emittedToolCall ? "tool_calls" : "stop"
20422
+ };
20383
20423
  return;
20384
20424
  }
20385
20425
  try {
@@ -20408,6 +20448,22 @@ function openaiCompatibleProvider(config2) {
20408
20448
  if (typeof reasoning === "string" && reasoning.length > 0) {
20409
20449
  yield { kind: "thinking", delta: reasoning };
20410
20450
  }
20451
+ const details = delta?.reasoning_details;
20452
+ if (Array.isArray(details)) {
20453
+ for (const d of details) {
20454
+ if (!d || typeof d !== "object") continue;
20455
+ const t = d.text;
20456
+ if (typeof t !== "string" || t.length === 0) continue;
20457
+ if (t.startsWith(reasoningDetailsBuf)) {
20458
+ const piece = t.slice(reasoningDetailsBuf.length);
20459
+ reasoningDetailsBuf = t;
20460
+ if (piece.length > 0) yield { kind: "thinking", delta: piece };
20461
+ } else {
20462
+ reasoningDetailsBuf += t;
20463
+ yield { kind: "thinking", delta: t };
20464
+ }
20465
+ }
20466
+ }
20411
20467
  if (Array.isArray(delta?.tool_calls)) {
20412
20468
  for (const tc of delta.tool_calls) {
20413
20469
  const idx = tc.index ?? 0;
@@ -20421,27 +20477,34 @@ function openaiCompatibleProvider(config2) {
20421
20477
  if (tc.function?.arguments) existing.argsJson += tc.function.arguments;
20422
20478
  toolCallAccumulator.set(idx, existing);
20423
20479
  if (existing.argsJson.trim().endsWith("}")) {
20424
- try {
20425
- const parsedArgs = JSON.parse(existing.argsJson);
20480
+ const parsedArgs = tryParseArgs(existing.argsJson);
20481
+ if (parsedArgs !== null && existing.name) {
20426
20482
  toolCallAccumulator.delete(idx);
20483
+ emittedToolCall = true;
20427
20484
  yield {
20428
20485
  kind: "tool_call",
20429
20486
  toolCallId: existing.id || `tc-${idx}`,
20430
20487
  toolName: existing.name,
20431
20488
  args: parsedArgs
20432
20489
  };
20433
- } catch {
20434
20490
  }
20435
20491
  }
20436
20492
  }
20437
20493
  }
20438
20494
  if (choice?.finish_reason) {
20439
- yield { kind: "finish", reason: choice.finish_reason };
20495
+ yield* flushToolAccumulator();
20496
+ const reason = choice.finish_reason === "stop" && emittedToolCall ? "tool_calls" : choice.finish_reason;
20497
+ yield { kind: "finish", reason };
20440
20498
  }
20441
20499
  } catch {
20442
20500
  }
20443
20501
  }
20444
20502
  }
20503
+ yield* flushToolAccumulator();
20504
+ yield {
20505
+ kind: "finish",
20506
+ reason: emittedToolCall ? "tool_calls" : "stop"
20507
+ };
20445
20508
  } finally {
20446
20509
  reader.releaseLock();
20447
20510
  }
@@ -24760,7 +24823,12 @@ function parseThinking(text) {
24760
24823
  }
24761
24824
  function cleanAgentContent(text, opts = {}) {
24762
24825
  const stripQuestion = opts.stripQuestion !== false;
24763
- let out = text.replace(/<think(?:ing)?>[\s\S]*?<\/think(?:ing)?>/gi, "").replace(/<think(?:ing)?>[\s\S]*$/gi, "").replace(/<\/think(?:ing)?>/gi, "").replace(/<minimax:tool_call>[\s\S]*?<\/minimax:tool_call>/g, "");
24826
+ const stripThink = opts.stripThink !== false;
24827
+ let out = text;
24828
+ if (stripThink) {
24829
+ out = out.replace(/<think(?:ing)?>[\s\S]*?<\/think(?:ing)?>/gi, "").replace(/<think(?:ing)?>[\s\S]*$/gi, "").replace(/<\/think(?:ing)?>/gi, "");
24830
+ }
24831
+ out = out.replace(/<minimax:tool_call>[\s\S]*?<\/minimax:tool_call>/g, "");
24764
24832
  if (stripQuestion) {
24765
24833
  out = out.replace(/---QUESTION---[\s\S]*?---END---/g, "");
24766
24834
  }
@@ -31928,7 +31996,9 @@ import { Box as Box5, Text as Text6 } from "ink";
31928
31996
 
31929
31997
  // src/cli/modelPricing.ts
31930
31998
  var PRICES_PER_MILLION = {
31931
- // xAI Grok
31999
+ // xAI Grok (list prices; grok-4.5 default reasoning_effort is "high")
32000
+ "grok-4.5": { input: 2, output: 6, cachedInput: 0.5 },
32001
+ "grok-4.3": { input: 1.25, output: 2.5, cachedInput: 0.2 },
31932
32002
  "grok-4": { input: 3, output: 15 },
31933
32003
  "grok-4-fast": { input: 0.2, output: 0.5 },
31934
32004
  "grok-3": { input: 3, output: 15 },
@@ -35602,7 +35672,8 @@ function useChatTurn(params) {
35602
35672
  (m) => m.role === "assistant" && m.content ? {
35603
35673
  ...m,
35604
35674
  content: cleanAgentContent(m.content, {
35605
- stripQuestion: false
35675
+ stripQuestion: false,
35676
+ stripThink: false
35606
35677
  })
35607
35678
  } : m
35608
35679
  )
@@ -37853,7 +37924,7 @@ async function handleLoginOAuthGrok(ctx) {
37853
37924
  });
37854
37925
  setActiveProviderId("grok");
37855
37926
  if (!getModelForProvider("grok")) {
37856
- setModelForProvider("grok", ctx.providerDefaults["grok"] ?? "grok-4");
37927
+ setModelForProvider("grok", ctx.providerDefaults["grok"] ?? "grok-4.5");
37857
37928
  }
37858
37929
  const expiresHint = resultOAuth.expiresAt ? `, expires ${new Date(resultOAuth.expiresAt).toISOString()}` : "";
37859
37930
  const refreshHint = resultOAuth.refreshToken ? ", refresh token saved" : "";
@@ -38675,10 +38746,10 @@ function useTerminalSize(options = {}) {
38675
38746
  }
38676
38747
 
38677
38748
  // src/cli/app.tsx
38678
- var MODEL = process.env.OPENAI_MODEL ?? "grok-4";
38749
+ var MODEL = process.env.OPENAI_MODEL ?? "grok-4.5";
38679
38750
  var providerDefaults = {
38680
- "openai-compatible": "grok-4",
38681
- "grok": "grok-4",
38751
+ "openai-compatible": "grok-4.5",
38752
+ "grok": "grok-4.5",
38682
38753
  "minimax": "MiniMax-chat-latest",
38683
38754
  "glm": "glm-4.5",
38684
38755
  "deepseek": "deepseek-v4-pro"
@@ -39847,7 +39918,10 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
39847
39918
  const historySeed = (opts.history ?? []).filter((m) => m.role === "user" || m.role === "assistant").map(
39848
39919
  (m) => m.role === "assistant" && m.content ? {
39849
39920
  role: "assistant",
39850
- content: cleanAgentContent(m.content, { stripQuestion: false })
39921
+ content: cleanAgentContent(m.content, {
39922
+ stripQuestion: false,
39923
+ stripThink: false
39924
+ })
39851
39925
  } : { role: m.role, content: m.content ?? "" }
39852
39926
  ).filter((m) => (m.content ?? "").trim().length > 0);
39853
39927
  const effectiveTask = buildAgentUserWithHistory(opts.task, historySeed);
@@ -40006,7 +40080,10 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
40006
40080
  for (let i = all.length - 1; i >= 0; i--) {
40007
40081
  const m = all[i];
40008
40082
  if (m?.role === "assistant" && (m.content ?? "").trim()) {
40009
- lastAsst = cleanAgentContent(m.content, { stripQuestion: false });
40083
+ lastAsst = cleanAgentContent(m.content, {
40084
+ stripQuestion: false,
40085
+ stripThink: false
40086
+ });
40010
40087
  break;
40011
40088
  }
40012
40089
  }
@@ -40062,7 +40139,13 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
40062
40139
  const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
40063
40140
  const feedbackStore = new FeedbackStore2();
40064
40141
  const historySeed = (opts.history ?? []).map(
40065
- (m) => m.role === "assistant" && m.content ? { ...m, content: cleanAgentContent(m.content, { stripQuestion: false }) } : m
40142
+ (m) => m.role === "assistant" && m.content ? {
40143
+ ...m,
40144
+ content: cleanAgentContent(m.content, {
40145
+ stripQuestion: false,
40146
+ stripThink: false
40147
+ })
40148
+ } : m
40066
40149
  );
40067
40150
  const effectiveTask = buildCouncilTaskWithHistory(opts.task, historySeed);
40068
40151
  let exitCode = 0;
@@ -40161,7 +40244,13 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
40161
40244
  }
40162
40245
  };
40163
40246
  const historySeed = (opts.history ?? []).map(
40164
- (m) => m.role === "assistant" && m.content ? { ...m, content: cleanAgentContent(m.content, { stripQuestion: false }) } : m
40247
+ (m) => m.role === "assistant" && m.content ? {
40248
+ ...m,
40249
+ content: cleanAgentContent(m.content, {
40250
+ stripQuestion: false,
40251
+ stripThink: false
40252
+ })
40253
+ } : m
40165
40254
  );
40166
40255
  const missionTask = buildCouncilTaskWithHistory(opts.task, historySeed);
40167
40256
  emit(`[zelari] mission brief
@@ -40253,7 +40342,8 @@ ${ragContext}` : slicePrompt;
40253
40342
  }
40254
40343
  if (synthesisText.trim()) {
40255
40344
  lastMissionAssistant = cleanAgentContent(synthesisText, {
40256
- stripQuestion: false
40345
+ stripQuestion: false,
40346
+ stripThink: false
40257
40347
  });
40258
40348
  }
40259
40349
  return {