fix(opencode): add effort-aware model overrides and OpenRouter guidance (#354)
* chore: create empty commit for PR Co-authored-by: Cursor <cursoragent@cursor.com> * chore(action): trigger preview repo creation workflow Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): merge repo opencode config and log provider key presence Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): add effort-aware model override precedence Add OPENCODE_MODEL_MINI and OPENCODE_MODEL_MAX support with fallback to OPENCODE_MODEL and auto-selection, and keep provider resolution aligned via inline OpenCode config when overrides are used. Update workflow env wiring, test allowlists, and docs (including OpenRouter setup guidance and sidebar ordering) to document the new behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(effort): clarify OpenCode precedence and add section link Add a concise OpenCode precedence callout in the summary area and link directly to the OpenCode section for full details and examples. Co-authored-by: Cursor <cursoragent@cursor.com> * Restructure dash (#372) * Restructure dash * WIP * WIP * refactor trigger UI: extract PR summary card, add mentions section, rename labels Co-authored-by: Cursor <cursoragent@cursor.com> * clean up console UI: remove info icons from section descriptions, rename mentions trigger Co-authored-by: Cursor <cursoragent@cursor.com> * fix review feedback: layout, terminology, form scope - extract console sidebar sections to module-level constant - align three-column layout breakpoints to xl (match sidebar visibility) - fix mixed shell/bash terminology in beta page - scope FormProvider to trigger sections only, restore autoComplete="off" Co-authored-by: Cursor <cursoragent@cursor.com> * Bump --------- Co-authored-by: Cursor <cursoragent@cursor.com> * chore: create empty commit for PR Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): merge repo opencode config and log provider key presence Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): add effort-aware model override precedence Add OPENCODE_MODEL_MINI and OPENCODE_MODEL_MAX support with fallback to OPENCODE_MODEL and auto-selection, and keep provider resolution aligned via inline OpenCode config when overrides are used. Update workflow env wiring, test allowlists, and docs (including OpenRouter setup guidance and sidebar ordering) to document the new behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: update agent rules and OpenCode config docs Align AGENTS guidance with current preferences and apply review-driven wording updates in OpenCode-related files. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
pullfrog[bot]
parent
e2d8dfeebf
commit
b472aa1ba9
+53
-64
@@ -25,7 +25,6 @@ export type SubagentStatus = "running" | "completed" | "failed";
|
||||
|
||||
export type SubagentState = {
|
||||
id: string;
|
||||
label: string;
|
||||
status: SubagentStatus;
|
||||
mode: string;
|
||||
stdoutFilePath: string;
|
||||
@@ -47,9 +46,8 @@ export interface ToolState {
|
||||
selectedMode?: string;
|
||||
// per-subagent lifecycle tracking (keyed by subagent uuid)
|
||||
subagents: Map<string, SubagentState>;
|
||||
// only set on subagent shallow copies — routes set_output to the owning subagent.
|
||||
// never set on the orchestrator's shared state.
|
||||
selfSubagentId: string | undefined;
|
||||
// set while a subagent is running — routes set_output to the correct subagent and prevents nesting
|
||||
activeSubagentId: string | undefined;
|
||||
backgroundProcesses: Map<string, BackgroundProcess>;
|
||||
review?: {
|
||||
id: number;
|
||||
@@ -83,7 +81,7 @@ export function initToolState(params: InitToolStateParams): ToolState {
|
||||
return {
|
||||
progressCommentId: resolvedId,
|
||||
subagents: new Map(),
|
||||
selfSubagentId: undefined,
|
||||
activeSubagentId: undefined,
|
||||
backgroundProcesses: new Map(),
|
||||
usageEntries: [],
|
||||
};
|
||||
@@ -107,6 +105,24 @@ export interface ToolContext {
|
||||
tmpdir: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* tool names that are only available to the orchestrator.
|
||||
* subagent MCP servers are started with these tools excluded.
|
||||
*
|
||||
* - delegation tools: only the orchestrator can spawn/manage subagents
|
||||
* - remote-mutating tools: subagents work locally; the orchestrator pushes and creates PRs
|
||||
*/
|
||||
export const ORCHESTRATOR_ONLY_TOOLS = [
|
||||
"select_mode",
|
||||
"delegate",
|
||||
"ask_question",
|
||||
"push_branch",
|
||||
"push_tags",
|
||||
"delete_branch",
|
||||
"create_pull_request",
|
||||
"update_pull_request_body",
|
||||
] as const;
|
||||
|
||||
import { log } from "../utils/cli.ts";
|
||||
import type { RunContextData } from "../utils/runContextData.ts";
|
||||
import { AskQuestionTool } from "./askQuestion.ts";
|
||||
@@ -188,50 +204,27 @@ function isAddressInUse(error: unknown): boolean {
|
||||
return message.includes("eaddrinuse") || message.includes("address already in use");
|
||||
}
|
||||
|
||||
// subagent tools: file ops, shell, read-only GitHub, upload, set_output.
|
||||
// no git/checkout (mutates shared state), no dependencies (shared state),
|
||||
// no GitHub-write (user-facing side effects), no delegation/remote-mutating.
|
||||
function buildSubagentTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
const tools: Tool<any, any>[] = [
|
||||
IssueInfoTool(ctx),
|
||||
GetIssueCommentsTool(ctx),
|
||||
GetIssueEventsTool(ctx),
|
||||
PullRequestInfoTool(ctx),
|
||||
CommitInfoTool(ctx),
|
||||
GetReviewCommentsTool(ctx),
|
||||
ListPullRequestReviewsTool(ctx),
|
||||
GetCheckSuiteLogsTool(ctx),
|
||||
UploadFileTool(ctx),
|
||||
SetOutputTool(ctx),
|
||||
FileReadTool(ctx),
|
||||
FileWriteTool(ctx),
|
||||
FileEditTool(ctx),
|
||||
FileDeleteTool(ctx),
|
||||
ListDirectoryTool(ctx),
|
||||
];
|
||||
|
||||
if (ctx.payload.shell === "restricted") {
|
||||
tools.push(ShellTool(ctx));
|
||||
tools.push(KillBackgroundTool(ctx));
|
||||
}
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
// orchestrator gets everything: file ops, shell, git, GitHub, delegation, remote-mutating
|
||||
function buildOrchestratorTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
// tools shared by both orchestrator and subagent servers
|
||||
function buildCommonTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
const tools: Tool<any, any>[] = [
|
||||
StartDependencyInstallationTool(ctx),
|
||||
AwaitDependencyInstallationTool(ctx),
|
||||
CreateCommentTool(ctx),
|
||||
EditCommentTool(ctx),
|
||||
ReplyToReviewCommentTool(ctx),
|
||||
IssueTool(ctx),
|
||||
IssueInfoTool(ctx),
|
||||
GetIssueCommentsTool(ctx),
|
||||
GetIssueEventsTool(ctx),
|
||||
CreatePullRequestReviewTool(ctx),
|
||||
PullRequestInfoTool(ctx),
|
||||
CommitInfoTool(ctx),
|
||||
CheckoutPrTool(ctx),
|
||||
GetReviewCommentsTool(ctx),
|
||||
ListPullRequestReviewsTool(ctx),
|
||||
ResolveReviewThreadTool(ctx),
|
||||
GetCheckSuiteLogsTool(ctx),
|
||||
AddLabelsTool(ctx),
|
||||
GitTool(ctx),
|
||||
GitFetchTool(ctx),
|
||||
UploadFileTool(ctx),
|
||||
@@ -241,22 +234,7 @@ function buildOrchestratorTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
FileEditTool(ctx),
|
||||
FileDeleteTool(ctx),
|
||||
ListDirectoryTool(ctx),
|
||||
CreateCommentTool(ctx),
|
||||
EditCommentTool(ctx),
|
||||
ReplyToReviewCommentTool(ctx),
|
||||
CreatePullRequestReviewTool(ctx),
|
||||
ResolveReviewThreadTool(ctx),
|
||||
IssueTool(ctx),
|
||||
AddLabelsTool(ctx),
|
||||
ReportProgressTool(ctx),
|
||||
SelectModeTool(ctx),
|
||||
DelegateTool(ctx),
|
||||
AskQuestionTool(ctx),
|
||||
PushBranchTool(ctx),
|
||||
PushTagsTool(ctx),
|
||||
DeleteBranchTool(ctx),
|
||||
CreatePullRequestTool(ctx),
|
||||
UpdatePullRequestBodyTool(ctx),
|
||||
];
|
||||
|
||||
// only add ShellTool when shell is "restricted"
|
||||
@@ -271,6 +249,26 @@ function buildOrchestratorTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
return tools;
|
||||
}
|
||||
|
||||
// orchestrator gets common tools + delegation + remote-mutating tools
|
||||
function buildOrchestratorTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
return [
|
||||
...buildCommonTools(ctx),
|
||||
SelectModeTool(ctx),
|
||||
DelegateTool(ctx),
|
||||
AskQuestionTool(ctx),
|
||||
PushBranchTool(ctx),
|
||||
PushTagsTool(ctx),
|
||||
DeleteBranchTool(ctx),
|
||||
CreatePullRequestTool(ctx),
|
||||
UpdatePullRequestBodyTool(ctx),
|
||||
];
|
||||
}
|
||||
|
||||
// subagent gets only common tools (no delegation, no remote mutation)
|
||||
function buildSubagentTools(ctx: ToolContext): Tool<any, any>[] {
|
||||
return buildCommonTools(ctx);
|
||||
}
|
||||
|
||||
type McpStartResult = {
|
||||
server: FastMCP;
|
||||
url: string;
|
||||
@@ -393,30 +391,21 @@ export type ManagedMcpServer = {
|
||||
stop: () => Promise<void>;
|
||||
};
|
||||
|
||||
type StartSubagentMcpServerParams = {
|
||||
ctx: ToolContext;
|
||||
subagentId: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Start a per-subagent MCP server (common tools only — no push/PR/delegation).
|
||||
* Each subagent gets its own server; call stop() when the subagent completes.
|
||||
*
|
||||
* The subagent gets its own shallow copy of toolState so scalar writes
|
||||
* (pushUrl, pushDest, selectedMode, etc.) don't mutate the orchestrator's state.
|
||||
* selfSubagentId is set on the copy so set_output routes to the correct subagent.
|
||||
* Shared references (subagents Map, usageEntries array, dependencyInstallation)
|
||||
* are intentionally shared for coordination (set_output routing, usage tracking).
|
||||
*/
|
||||
export async function startSubagentMcpServer(
|
||||
params: StartSubagentMcpServerParams
|
||||
): Promise<ManagedMcpServer> {
|
||||
export async function startSubagentMcpServer(ctx: ToolContext): Promise<ManagedMcpServer> {
|
||||
const subagentToolState: ToolState = {
|
||||
...params.ctx.toolState,
|
||||
selfSubagentId: params.subagentId,
|
||||
...ctx.toolState,
|
||||
backgroundProcesses: new Map(),
|
||||
};
|
||||
const subagentCtx: ToolContext = { ...params.ctx, toolState: subagentToolState };
|
||||
const subagentCtx: ToolContext = { ...ctx, toolState: subagentToolState };
|
||||
const tools = buildSubagentTools(subagentCtx);
|
||||
const startResult = await selectMcpPort(subagentCtx, tools);
|
||||
return { url: startResult.url, stop: () => startResult.server.stop() };
|
||||
|
||||
Reference in New Issue
Block a user