Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/quiet-resets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"opencode-adaptive-thinking": patch
---

Reset a temporary reasoning effort to the level in effect before the first override, so repeated changes no longer reset to an intermediate level or skip the reset. Read session history once per tool call with a bounded query, cache provider variants, merge guidance into an existing first system prompt, and remove the runtime Zod dependency.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ Example persisted change:

The system prompt lists the valid levels for the current session. Cached session state is only used when it is still valid for the current model, so switching models will not advertise or reuse an invalid effort level.

Adaptive-thinking guidance is merged into the first existing system prompt instead of a separate system message, so strict chat templates that allow only one system message keep working.

## Troubleshooting

If the tool returns `no valid reasoning effort levels are available for this session`, check that the active model exposes variants in OpenCode. Some providers or models may not support reasoning-effort levels.
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
"verify": "pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run build",
"version-packages": "changeset version"
},
"dependencies": {
"zod": "^4.4.3"
},
"devDependencies": {
"@changesets/changelog-github": "^0.7.0",
"@changesets/cli": "^2.31.0",
Expand Down
8 changes: 0 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 34 additions & 13 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
import * as z from "zod/v4";

export const defaultSystemPrompt =
"You MUST manage reasoning effort actively. " +
"Lower it before trivial or routine turns; raise it for ambiguity, debugging, risky changes, or multi-step synthesis. " +
"Reassess at turn start, after meaningful new evidence, and when the task shifts. " +
"NEVER leave the current level unchanged by inertia, and NEVER reply to a trivial turn before considering a downshift.";

export const configDefaults = {
export type Config = {
enabled: boolean;
quiet: boolean;
toolName: string;
toolDescription: string;
systemPrompt: string;
};

const defaults: Config = {
enabled: true,
quiet: false,
toolName: "set_reasoning_effort",
toolDescription: "Set your reasoning effort",
systemPrompt: defaultSystemPrompt,
};

export const ConfigSchema = z
.object({
enabled: z.boolean().default(configDefaults.enabled),
quiet: z.boolean().default(configDefaults.quiet),
toolName: z.string().default(configDefaults.toolName),
toolDescription: z.string().default(configDefaults.toolDescription),
systemPrompt: z.string().default(configDefaults.systemPrompt),
})
.optional()
.default(configDefaults);
export const parseConfig = (options: unknown): { config: Config } | { error: string } => {
if (options === undefined) return { config: { ...defaults } };
if (typeof options !== "object" || options === null || Array.isArray(options)) {
return { error: "options must be an object" };
}

const input = options as Record<string, unknown>;
const config = { ...defaults };

for (const key of ["enabled", "quiet"] as const) {
const value = input[key];
if (value === undefined) continue;
if (typeof value !== "boolean") return { error: `${key} must be a boolean` };
config[key] = value;
}

for (const key of ["toolName", "toolDescription", "systemPrompt"] as const) {
const value = input[key];
if (value === undefined) continue;
if (typeof value !== "string") return { error: `${key} must be a string` };
config[key] = value;
}

return { config };
};
Loading