From e76242754421bed08be7e74f2681ea00b296bccf Mon Sep 17 00:00:00 2001 From: allocsys <225476909+allocsys@users.noreply.github.com> Date: Sun, 26 Jul 2026 22:49:00 +0330 Subject: [PATCH 1/2] Bump delegate_gemini default max_steps 6->10 and hard cap references 20->25 --- connectors/gemini/tools.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connectors/gemini/tools.js b/connectors/gemini/tools.js index a5056b7..86ee013 100644 --- a/connectors/gemini/tools.js +++ b/connectors/gemini/tools.js @@ -98,12 +98,12 @@ export function register(server) { "Default choice for any multi-file or open-ended GitHub/Notion/Cloudflare investigation -- prefer this over manual read_file/get_file_tree/list_directory loops unless you need exactly one named file. Delegate an open-ended, multi-step READ-ONLY investigation to Gemini instead of doing it yourself one tool call at a time. Gemini runs its own loop server-side -- reading GitHub files/trees/commits, Cloudflare Workers logs, and Notion pages/databases across as many turns as it needs (bounded by max_steps) -- and returns one synthesized answer. Use this for things like \"why is CI failing on PR #42\" or \"summarize what changed in this repo over the last week\" where you'd otherwise need 5-10 separate manual tool calls. Not for anything requiring a write -- this tool is read-only by design. If a run fails partway through (e.g. Gemini rate-limited), the response includes a resume_run_id -- pass it back on a follow-up call to continue from the last completed step instead of starting over.", { task: z.string().optional().describe("The investigation task/question, described with enough context (repo names, time ranges, etc.) for Gemini to act without needing to ask you anything back -- it can't. Ignored when resume_run_id resolves to a live checkpoint (the original task from that run is reused). Optional ONLY when resume_run_id is given and its checkpoint is still live; required otherwise -- omitting it on a fresh run (no resume_run_id, or an expired one) returns an error rather than silently proceeding with no task."), - max_steps: z.number().optional().describe("Max tool-use turns Gemini gets before being forced to answer (default 6, hard cap 20 regardless of this value). On a resumed run this is the new ceiling, not additional steps on top of what's already done."), + max_steps: z.number().optional().describe("Max tool-use turns Gemini gets before being forced to answer (default 10, hard cap 25 regardless of this value). On a resumed run this is the new ceiling, not additional steps on top of what's already done."), log_to_notion: z.boolean().optional().describe("Whether to log the task, step-by-step tool calls, and final answer as a page under the Gemini section of Notion (default: false). Write always targets the fixed Gemini root page."), resume_run_id: z.string().optional().describe("A runId returned from a previous failed/partial delegate_gemini call. If its checkpoint is still live (1 hour TTL), continues that run's conversation instead of starting fresh."), show_transcript: z.boolean().optional().describe("Include the full step-by-step tool-call transcript in the response, even on a successful run (default: false). Useful for debugging what Gemini actually called and in what order/grouping -- e.g. checking whether independent calls were batched into the same step. On a failed/partial run the transcript is always shown regardless of this flag."), }, - async ({ task, max_steps = 6, log_to_notion = false, resume_run_id, show_transcript = false }) => { + async ({ task, max_steps = 10, log_to_notion = false, resume_run_id, show_transcript = false }) => { // task is only genuinely optional when resuming a live checkpoint -- // runInvestigation ignores task entirely in that branch (it rebuilds // `contents` straight from the saved checkpoint). On a fresh run (no @@ -125,7 +125,7 @@ export function register(server) { // answer instead of surfacing that the input itself was invalid. if (max_steps !== undefined && (!Number.isInteger(max_steps) || max_steps < 1)) { return { - content: [{ type: "text", text: `Invalid max_steps: ${max_steps}. Must be a positive integer (at least 1); the hard cap is 20 regardless of a larger value.` }], + content: [{ type: "text", text: `Invalid max_steps: ${max_steps}. Must be a positive integer (at least 1); the hard cap is 25 regardless of a larger value.` }], isError: true, }; } From c6a1b825eaed293838c8eb1859700e333753c400 Mon Sep 17 00:00:00 2001 From: allocsys <225476909+allocsys@users.noreply.github.com> Date: Sun, 26 Jul 2026 22:49:11 +0330 Subject: [PATCH 2/2] Bump HARD_MAX_STEPS 20->25 and runInvestigation's default max_steps 6->10 --- connectors/gemini/delegate.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connectors/gemini/delegate.js b/connectors/gemini/delegate.js index 11e06be..30b1796 100644 --- a/connectors/gemini/delegate.js +++ b/connectors/gemini/delegate.js @@ -51,7 +51,7 @@ import { mem0Request } from "../mem/client.js"; import { notionRequest, notionRichTextToString, notionPageTitle, notionDatabaseTitle, notionBlocksToText } from "../notion/client.js"; import { DEFAULT_OWNER } from "../../config.js"; -const HARD_MAX_STEPS = 20; +const HARD_MAX_STEPS = 25; // 429 (rate limit) and 503 (overloaded/high demand) are the only cases // documented as transient -- see client.js's own model-fallback cascade, @@ -821,7 +821,7 @@ const SYSTEM_PREAMBLE = // (see checkpoint.js) -- if it's unavailable, resumption just isn't // possible, same as before this existed; a failure still returns whatever // transcript was gathered in-memory this call. -export async function runInvestigation({ task, max_steps = 6, resume_run_id }) { +export async function runInvestigation({ task, max_steps = 10, resume_run_id }) { const cappedSteps = Math.min(max_steps, HARD_MAX_STEPS); let runId = resume_run_id;