@prestyj/boss 4.13.3 → 4.14.0

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.
@@ -63160,6 +63160,7 @@ var PROVIDER_DISPLAY = {
63160
63160
  moonshot: "Moonshot",
63161
63161
  deepseek: "DeepSeek",
63162
63162
  openrouter: "OpenRouter",
63163
+ sakana: "Sakana",
63163
63164
  xiaomi: "Xiaomi (MiMo)",
63164
63165
  minimax: "MiniMax"
63165
63166
  };
@@ -64051,8 +64052,12 @@ function toOpenAIToolChoice(choice) {
64051
64052
  if (choice === "required") return "required";
64052
64053
  return { type: "function", function: { name: choice.name } };
64053
64054
  }
64054
- function toOpenAIReasoningEffort(level, _model) {
64055
- return level === "max" ? "xhigh" : level;
64055
+ function toOpenAIReasoningEffort(level, model) {
64056
+ const effort = level === "max" ? "xhigh" : level;
64057
+ if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
64058
+ return "high";
64059
+ }
64060
+ return effort;
64056
64061
  }
64057
64062
  function normalizeAnthropicStopReason(reason) {
64058
64063
  switch (reason) {
@@ -66180,6 +66185,16 @@ providerRegistry.register("openrouter", {
66180
66185
  baseUrl: options.baseUrl ?? "https://openrouter.ai/api/v1"
66181
66186
  })
66182
66187
  });
66188
+ providerRegistry.register("sakana", {
66189
+ // Sakana Fugu is a multi-agent system exposed as a standard LLM through the
66190
+ // OpenAI-compatible Sakana API. We ride the Chat Completions transport (the
66191
+ // Responses API is also offered). Fugu models only accept "high"/"xhigh"
66192
+ // reasoning effort — clamped centrally in toOpenAIReasoningEffort.
66193
+ stream: (options) => streamOpenAI({
66194
+ ...options,
66195
+ baseUrl: options.baseUrl ?? "https://api.sakana.ai/v1"
66196
+ })
66197
+ });
66183
66198
  providerRegistry.register("minimax", {
66184
66199
  stream: (options) => streamAnthropic({
66185
66200
  ...options,
@@ -66556,6 +66571,9 @@ async function* agentLoop(messages, options) {
66556
66571
  const STREAM_THINKING_IDLE_TIMEOUT_MS = 3e5;
66557
66572
  const STREAM_THINKING_HARD_TIMEOUT_MS = 6e5;
66558
66573
  const NON_STREAMING_HARD_TIMEOUT_MS = 3e5;
66574
+ const isSakana = options.provider === "sakana";
66575
+ const firstEventTimeoutMs = isSakana ? STREAM_THINKING_IDLE_TIMEOUT_MS : STREAM_FIRST_EVENT_TIMEOUT_MS;
66576
+ const initialHardTimeoutMs = isSakana ? STREAM_THINKING_HARD_TIMEOUT_MS : STREAM_HARD_TIMEOUT_MS;
66559
66577
  const MAX_TOOLCALL_DELTA_CHARS = 1e6;
66560
66578
  const MAX_TOOLCALL_DELTA_EVENTS = 2e4;
66561
66579
  try {
@@ -66627,7 +66645,7 @@ async function* agentLoop(messages, options) {
66627
66645
  const resetIdleTimer = () => {
66628
66646
  if (useNonStreamingFallback) return;
66629
66647
  if (idleTimer) clearTimeout(idleTimer);
66630
- const timeoutMs = hasReceivedEvent ? STREAM_IDLE_TIMEOUT_MS : hasReceivedThinking ? STREAM_THINKING_IDLE_TIMEOUT_MS : STREAM_FIRST_EVENT_TIMEOUT_MS;
66648
+ const timeoutMs = hasReceivedEvent ? STREAM_IDLE_TIMEOUT_MS : hasReceivedThinking ? STREAM_THINKING_IDLE_TIMEOUT_MS : firstEventTimeoutMs;
66631
66649
  idleTimer = setTimeout(() => {
66632
66650
  diag("idle_timeout_fired", {
66633
66651
  events: streamEventCount,
@@ -66641,7 +66659,7 @@ async function* agentLoop(messages, options) {
66641
66659
  streamController.abort();
66642
66660
  }, timeoutMs);
66643
66661
  };
66644
- let hardTimeoutMs = useNonStreamingFallback ? NON_STREAMING_HARD_TIMEOUT_MS : STREAM_HARD_TIMEOUT_MS;
66662
+ let hardTimeoutMs = useNonStreamingFallback ? NON_STREAMING_HARD_TIMEOUT_MS : initialHardTimeoutMs;
66645
66663
  hardTimer = setTimeout(() => {
66646
66664
  diag("hard_timeout_fired", {
66647
66665
  events: typeof streamEventCount !== "undefined" ? streamEventCount : 0,
@@ -67654,7 +67672,7 @@ var Agent = class {
67654
67672
  }
67655
67673
  };
67656
67674
 
67657
- // ../core/dist/chunk-RHNQ3WBA.js
67675
+ // ../core/dist/chunk-PFBQN3DU.js
67658
67676
  init_esm_shims();
67659
67677
  var MODELS = [
67660
67678
  // ── Anthropic ──────────────────────────────────────────
@@ -67776,6 +67794,36 @@ var MODELS = [
67776
67794
  costTier: "high",
67777
67795
  maxThinkingLevel: "xhigh"
67778
67796
  },
67797
+ // ── Sakana (Fugu) ──────────────────────────────────────
67798
+ // Sakana Fugu is a multi-agent system surfaced as a standard LLM via the
67799
+ // OpenAI-compatible Sakana API (https://api.sakana.ai/v1). Both models take
67800
+ // text + image input and only accept "high"/"xhigh" reasoning effort, so the
67801
+ // top tier is `xhigh`. `fugu` routes across all providers; `fugu-ultra` is
67802
+ // the heavier tier (may need larger client timeouts on complex tasks).
67803
+ {
67804
+ id: "fugu",
67805
+ name: "Fugu",
67806
+ provider: "sakana",
67807
+ contextWindow: 1e6,
67808
+ maxOutputTokens: 128e3,
67809
+ supportsThinking: true,
67810
+ supportsImages: true,
67811
+ supportsVideo: false,
67812
+ costTier: "medium",
67813
+ maxThinkingLevel: "xhigh"
67814
+ },
67815
+ {
67816
+ id: "fugu-ultra",
67817
+ name: "Fugu Ultra",
67818
+ provider: "sakana",
67819
+ contextWindow: 1e6,
67820
+ maxOutputTokens: 128e3,
67821
+ supportsThinking: true,
67822
+ supportsImages: true,
67823
+ supportsVideo: false,
67824
+ costTier: "high",
67825
+ maxThinkingLevel: "xhigh"
67826
+ },
67779
67827
  // ── Gemini ─────────────────────────────────────────────
67780
67828
  {
67781
67829
  id: "gemini-3.1-flash-lite-preview",
@@ -67974,6 +68022,7 @@ function getDefaultModel(provider) {
67974
68022
  if (provider === "minimax") return MODELS.find((m) => m.id === "MiniMax-M3");
67975
68023
  if (provider === "deepseek") return MODELS.find((m) => m.id === "deepseek-v4-pro");
67976
68024
  if (provider === "openrouter") return MODELS.find((m) => m.id === "qwen/qwen3.6-plus");
68025
+ if (provider === "sakana") return MODELS.find((m) => m.id === "fugu");
67977
68026
  return MODELS.find((m) => m.id === "claude-sonnet-4-6");
67978
68027
  }
67979
68028
  function usesOpenAICodexTransport(options) {
@@ -68045,6 +68094,7 @@ import { spawn } from "child_process";
68045
68094
  import fs5 from "fs";
68046
68095
  import path42 from "path";
68047
68096
  var OPENAI_GPT_THINKING_LEVELS = ["medium", "high", "xhigh"];
68097
+ var SAKANA_THINKING_LEVELS = ["high", "xhigh"];
68048
68098
  var ANTHROPIC_OPUS_48_47_THINKING_LEVELS = [
68049
68099
  "low",
68050
68100
  "medium",
@@ -68061,6 +68111,9 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
68061
68111
  function isOpenAIGptModel(provider, model) {
68062
68112
  return provider === "openai" && model.startsWith("gpt-");
68063
68113
  }
68114
+ function isSakanaModel(provider) {
68115
+ return provider === "sakana";
68116
+ }
68064
68117
  function isAnthropicOpus48Or47Model(provider, model) {
68065
68118
  return provider === "anthropic" && /opus-4-8|opus-4-7/.test(model);
68066
68119
  }
@@ -68075,6 +68128,11 @@ function getSupportedThinkingLevels(provider, model) {
68075
68128
  if (maxIndex2 === -1) return ["low", "medium", "high"];
68076
68129
  return levels.slice(0, maxIndex2 + 1);
68077
68130
  }
68131
+ if (isSakanaModel(provider)) {
68132
+ const maxIndex2 = SAKANA_THINKING_LEVELS.indexOf(maxLevel);
68133
+ if (maxIndex2 === -1) return SAKANA_THINKING_LEVELS;
68134
+ return SAKANA_THINKING_LEVELS.slice(0, maxIndex2 + 1);
68135
+ }
68078
68136
  if (!isOpenAIGptModel(provider, model)) return [maxLevel];
68079
68137
  const maxIndex = OPENAI_GPT_THINKING_LEVELS.indexOf(maxLevel);
68080
68138
  if (maxIndex === -1) return ["medium"];
@@ -68085,7 +68143,7 @@ function isThinkingLevelSupported(provider, model, level) {
68085
68143
  }
68086
68144
  function getNextThinkingLevel(provider, model, current) {
68087
68145
  const supportedLevels = getSupportedThinkingLevels(provider, model);
68088
- const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model);
68146
+ const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider);
68089
68147
  if (!shouldCycleLevels) {
68090
68148
  return current ? void 0 : supportedLevels[0];
68091
68149
  }
@@ -68579,7 +68637,8 @@ var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
68579
68637
  "xiaomi",
68580
68638
  "minimax",
68581
68639
  "deepseek",
68582
- "openrouter"
68640
+ "openrouter",
68641
+ "sakana"
68583
68642
  ]);
68584
68643
  var AuthStorage = class {
68585
68644
  data = {};
@@ -74581,10 +74640,11 @@ async function saveTasks(cwd2, tasks) {
74581
74640
 
74582
74641
  // ../cli/dist/tools/tasks.js
74583
74642
  var TasksParams = external_exports.object({
74584
- action: external_exports.enum(["add", "list", "done", "remove"]).describe("Action: add a task, list tasks, mark done, or remove"),
74643
+ action: external_exports.enum(["add", "list", "update", "done", "remove"]).describe("Action: add a task, list tasks, update a task's status/title/prompt, mark done, or remove"),
74585
74644
  title: external_exports.string().optional().describe("Short task title for display (max ~10 words, required for add)"),
74586
74645
  prompt: external_exports.string().optional().describe("The standalone prompt sent to an agent with no context (required for add). Concise, actionable instruction with file paths and what to change."),
74587
- id: external_exports.string().optional().describe("Task ID (required for done/remove \u2014 use list to find IDs)")
74646
+ status: external_exports.enum(["pending", "in-progress", "done"]).optional().describe("New status for the update action (pending, in-progress, or done)."),
74647
+ id: external_exports.string().optional().describe("Task ID (required for update/done/remove \u2014 use list to find IDs)")
74588
74648
  });
74589
74649
  function createTasksTool(cwd2) {
74590
74650
  let pending = Promise.resolve();
@@ -74597,10 +74657,10 @@ function createTasksTool(cwd2) {
74597
74657
  }
74598
74658
  return {
74599
74659
  name: "tasks",
74600
- description: "Manage the project task list. Each task has a short title (shown in the task pane) and a prompt (sent as a standalone instruction to an agent with no context). Write prompts as concise, actionable directives with specific file paths \u2014 the agent must complete it from the prompt alone. When adding multiple tasks, order them by dependency \u2014 foundational work first, then core logic, integration, UI, and tests. Do not use this tool proactively \u2014 only manage the task list when the user explicitly requests it.",
74660
+ description: "Manage the project task list. Each task has a short title (shown in the task pane) and a prompt (sent as a standalone instruction to an agent with no context). Write prompts as concise, actionable directives with specific file paths \u2014 the agent must complete it from the prompt alone. When adding multiple tasks, order them by dependency \u2014 foundational work first, then core logic, integration, UI, and tests. Use the update action to change a task's status (pending/in-progress/done) or edit its title/prompt without recreating it. Do not use this tool proactively \u2014 only manage the task list when the user explicitly requests it.",
74601
74661
  parameters: TasksParams,
74602
74662
  executionMode: "sequential",
74603
- execute({ action, title, prompt, id: id2 }) {
74663
+ execute({ action, title, prompt, status, id: id2 }) {
74604
74664
  return enqueue(async () => {
74605
74665
  switch (action) {
74606
74666
  case "add": {
@@ -74631,6 +74691,30 @@ function createTasksTool(cwd2) {
74631
74691
  log("INFO", "tasks", `Listed ${tasks.length} tasks`);
74632
74692
  return lines.join("\n");
74633
74693
  }
74694
+ case "update": {
74695
+ if (!id2?.trim())
74696
+ return "Error: id is required for update action.";
74697
+ if (!status && !title?.trim() && !prompt?.trim())
74698
+ return "Error: update needs at least one of status, title, or prompt.";
74699
+ const tasks = await loadTasks(cwd2);
74700
+ const task = tasks.find((item) => item.id === id2 || item.id.startsWith(id2));
74701
+ if (!task)
74702
+ return `Error: no task found matching id "${id2}".`;
74703
+ const updated = tasks.map((item) => item.id === task.id ? {
74704
+ ...item,
74705
+ ...status ? { status } : {},
74706
+ ...title?.trim() ? { title: title.trim() } : {},
74707
+ ...prompt?.trim() ? { prompt: prompt.trim() } : {}
74708
+ } : item);
74709
+ await saveTasks(cwd2, updated);
74710
+ log("INFO", "tasks", `Task updated: ${task.title}`, { id: task.id });
74711
+ const changes = [
74712
+ status ? `status=${status}` : null,
74713
+ title?.trim() ? "title" : null,
74714
+ prompt?.trim() ? "prompt" : null
74715
+ ].filter(Boolean).join(", ");
74716
+ return `Updated "${title?.trim() ?? task.title}" (${changes}).`;
74717
+ }
74634
74718
  case "done": {
74635
74719
  if (!id2?.trim())
74636
74720
  return "Error: id is required for done action.";
@@ -78133,7 +78217,8 @@ var SettingsSchema = external_exports.object({
78133
78217
  "minimax",
78134
78218
  "xiaomi",
78135
78219
  "deepseek",
78136
- "openrouter"
78220
+ "openrouter",
78221
+ "sakana"
78137
78222
  ]).default("anthropic"),
78138
78223
  defaultModel: external_exports.string().optional(),
78139
78224
  maxTokens: external_exports.number().int().min(256).default(16384),
@@ -120144,4 +120229,4 @@ react/cjs/react-jsx-runtime.development.js:
120144
120229
  * LICENSE file in the root directory of this source tree.
120145
120230
  *)
120146
120231
  */
120147
- //# sourceMappingURL=chunk-7YGRM4YR.js.map
120232
+ //# sourceMappingURL=chunk-BAJJL262.js.map