diff --git a/action.yml b/action.yml index a2cb97b..44f918d 100644 --- a/action.yml +++ b/action.yml @@ -12,6 +12,9 @@ inputs: model: description: "Ollama model to use. Default: qwen3.6:35b" required: false + context_window: + description: "Ollama context window size in tokens. Default: 262144" + required: false cwd: description: "Working directory for the agent (defaults to GITHUB_WORKSPACE)" required: false diff --git a/agents/ollama.ts b/agents/ollama.ts index eeba444..c20c316 100644 --- a/agents/ollama.ts +++ b/agents/ollama.ts @@ -119,6 +119,7 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise { } const model = ctx.model ?? process.env.OLLAMA_MODEL ?? DEFAULT_MODEL; + const numCtx = ctx.payload.contextWindow ?? 262144; log.info(`ยป connecting to Ollama at ${ollamaHost}, model ${model}`); @@ -170,7 +171,7 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise { tools, keep_alive: -1, think: false, - options: { num_ctx: 262144, temperature: 0.1 }, + options: { num_ctx: numCtx, temperature: 0.1 }, }), { delaysMs: [3_000, 8_000], @@ -196,11 +197,11 @@ async function runOllamaLoop(ctx: AgentRunContext): Promise { if (promptTokens !== undefined) { const total = promptTokens + (evalTokens ?? 0); - const pct = Math.round((total / 262144) * 100); + const pct = Math.round((total / numCtx) * 100); log.info( - ` context: ${promptTokens} prompt + ${evalTokens ?? 0} eval = ${total} tokens (${pct}% of limit)`, + ` context: ${promptTokens} prompt + ${evalTokens ?? 0} eval = ${total} tokens (${pct}% of ${numCtx} limit)`, ); - if (promptTokens > 200_000) { + if (promptTokens > numCtx * 0.77) { messages = pruneToolMessages(messages); } } diff --git a/utils/payload.ts b/utils/payload.ts index d6460e5..5a01329 100644 --- a/utils/payload.ts +++ b/utils/payload.ts @@ -11,6 +11,7 @@ const PushPermissionInput = type.enumerated("disabled", "restricted", "enabled") export const Inputs = type({ prompt: "string", "model?": type.string.or("undefined"), + "context_window?": type.number.or("undefined"), "timeout?": type.string.or("undefined"), "push?": PushPermissionInput.or("undefined"), "shell?": ShellPermissionInput.or("undefined"), @@ -58,8 +59,10 @@ export function resolvePromptInput(): ResolvedPromptInput { } function resolveNonPromptInputs() { + const contextWindowRaw = core.getInput("context_window"); return Inputs.omit("prompt").assert({ model: core.getInput("model") || undefined, + context_window: contextWindowRaw ? parseInt(contextWindowRaw, 10) : undefined, timeout: core.getInput("timeout") || undefined, cwd: core.getInput("cwd") || undefined, push: (core.getInput("push") as "disabled" | "restricted" | "enabled") || undefined, @@ -93,6 +96,12 @@ export function resolvePayload( const model = str(jsonPayload, "model") ?? inputs.model ?? repoSettings.model ?? process.env.OLLAMA_MODEL ?? undefined; + const contextWindowStr = str(jsonPayload, "context_window"); + const contextWindow = + (contextWindowStr ? parseInt(contextWindowStr, 10) : undefined) ?? + inputs.context_window ?? + undefined; + const isNonCollaborator = !isCollaborator(event); const repoShell = repoSettings.shell ?? "restricted"; const inputShell = inputs.shell; @@ -110,6 +119,7 @@ export function resolvePayload( return { "~shockbot": true as const, model, + contextWindow, prompt, triggerer: str(jsonPayload, "triggerer") ?? process.env.GITHUB_ACTOR ?? undefined,