Skip to content
Merged
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
24 changes: 23 additions & 1 deletion docs/agent-profile-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ name: reviewer
description: Read-only reviewer for bugs, security risks, and missing tests.
provider: codex
model: gpt-5.4
thinking: high
disabled: false
---

Expand Down Expand Up @@ -86,6 +87,26 @@ model: gpt-5.4
model: sonnet
```

### `thinking`

Optional provider reasoning effort, thinking level, or model variant. If omitted,
DevSpace lets the provider default apply. Values are provider-specific
passthrough strings; DevSpace does not translate names between harnesses.

```yaml
thinking: low
thinking: high
thinking: xhigh
```

DevSpace passes this through to providers that expose a matching control:

- `claude`: SDK effort with adaptive thinking.
- `codex`: SDK model reasoning effort.
- `pi`: `--thinking`.
- `opencode`: model variant.
- `cursor` and `copilot`: ACP thought-level config when supported.

### `disabled`

Optional boolean. Disabled profiles are not exposed.
Expand Down Expand Up @@ -123,7 +144,8 @@ devspace agents show <id>
"name": "reviewer",
"description": "Read-only reviewer for bugs, security risks, and missing tests.",
"provider": "codex",
"model": "gpt-5.4"
"model": "gpt-5.4",
"thinking": "high"
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/chatgpt-coding-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ It also keeps compatibility with:
When Subagents are enabled, DevSpace discovers agent profiles
from `~/.devspace/agents/*.md` and project `.devspace/agents/*.md`.
`open_workspace` exposes a compact catalog with profile names, descriptions,
providers, and optional models so the model can choose a configured agent
providers, and optional models/thinking levels so the model can choose a configured agent
without seeing provider-specific launch details.

Example profiles are packaged under `examples/agents/` for users who want
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ from:
- project `.devspace/agents/*.md`

`open_workspace` returns a compact catalog containing profile names,
descriptions, providers, and optional models so the host model can choose an
descriptions, providers, and optional models/thinking levels so the host model can choose an
agent without reading provider-specific launch details. `devspace agents ls`
lists existing subagent sessions for the current workspace, scoped by the
workspace environment injected into shell commands. The `subagent-delegation`
Expand Down
1 change: 1 addition & 0 deletions examples/agents/claude-implementer.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ name: claude-implementer
description: Claude Code profile for larger implementation, refactor, and repair tasks.
provider: claude
model: sonnet
thinking: high
---

You are a local Claude Code implementation worker under supervisor review.
Expand Down
1 change: 1 addition & 0 deletions examples/agents/pi-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ schema: devspace-agent/v1
name: pi-reviewer
description: Pi read-only profile for quick code review and targeted questions.
provider: pi
thinking: medium
---

You are a read-only local code reviewer.
Expand Down
12 changes: 10 additions & 2 deletions skills/subagent-delegation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,21 @@ Choose profiles from the compact subagent profile catalog returned by
profile fits and delegation is still appropriate, use a built-in provider name
from `open_workspace`.

Profiles may declare a model. To override the configured/default provider model
for a run, pass `--model`:
Profiles may declare a model and optional thinking level. To override the
configured/default provider model or thinking level for a run, pass `--model`
or `--thinking`:

```bash
devspace agents run <profile-or-provider> --model <model> "<prompt>"
devspace agents run <profile-or-provider> --thinking <level> "<prompt>"
```

Use `--thinking` only when the user asks for a specific reasoning depth or when
the task clearly needs a different effort than the configured profile default.
Thinking values are provider-specific passthrough values. Use names supported by
the selected local agent harness; DevSpace does not translate values between
providers.

Good delegation targets:

- `reviewer`: second opinion, bug risk, security risk, test gaps.
Expand Down
4 changes: 3 additions & 1 deletion src/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ try {
"description: Read-only reviewer.",
"provider: codex",
"model: gpt-5.4",
"thinking: high",
"---",
"",
"Review only.",
Expand All @@ -49,6 +50,7 @@ try {
profileName: "reviewer",
provider: "codex",
model: "gpt-5.4",
thinking: "high",
}).id,
{ status: "idle" },
);
Expand Down Expand Up @@ -78,7 +80,7 @@ try {
},
});

assert.match(output, new RegExp(`${current.id} idle reviewer codex gpt-5\\.4`));
assert.match(output, new RegExp(`${current.id} idle reviewer codex gpt-5\\.4 thinking=high`));
assert.doesNotMatch(output, /profile reviewer/);
assert.doesNotMatch(output, new RegExp(other.id));

Expand Down
20 changes: 15 additions & 5 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,16 +371,22 @@ async function runAgentsRun(args: string[]): Promise<void> {
store.update(existing.id, {
status: "starting",
model: parsed.model ?? existing.model,
thinking: parsed.thinking ?? existing.thinking,
latestResponse: undefined,
error: undefined,
});
spawnAgentWorker(existing.id, promptFile);
console.log(formatAgentLine({ ...existing, status: "running", model: parsed.model ?? existing.model }));
console.log(formatAgentLine({
...existing,
status: "running",
model: parsed.model ?? existing.model,
thinking: parsed.thinking ?? existing.thinking,
}));
return;
}

const profiles = await loadLocalAgentProfiles(config, workspaceRoot);
const target = resolveLocalAgentTarget(parsed.target, profiles, parsed.model);
const target = resolveLocalAgentTarget(parsed.target, profiles, parsed.model, parsed.thinking);
if (!target) {
throw new Error(
`Unknown subagent profile, provider, or id: ${parsed.target}. Available ${formatAvailableLocalAgentTargets(profiles)}`,
Expand All @@ -395,6 +401,7 @@ async function runAgentsRun(args: string[]): Promise<void> {
profileName: target.name,
provider: target.provider,
model: target.model,
thinking: target.thinking,
});

spawnAgentWorker(record.id, promptFile);
Expand Down Expand Up @@ -476,6 +483,7 @@ async function runLocalAgentProfile(
providerSessionId: record.providerSessionId,
writeMode: "allowed",
model: record.model ?? profile.model,
thinking: record.thinking ?? profile.thinking,
});
}

Expand All @@ -493,6 +501,7 @@ async function runRawLocalAgentProvider(
providerSessionId: record.providerSessionId,
writeMode: "allowed",
model: record.model,
thinking: record.thinking,
});
}

Expand Down Expand Up @@ -533,10 +542,11 @@ function resolveCurrentWorkspaceScope(): { workspaceId?: string; workspaceRoot:

function formatAgentLine(agent: Pick<
LocalAgentRecord,
"id" | "status" | "profileName" | "provider" | "model"
"id" | "status" | "profileName" | "provider" | "model" | "thinking"
>): string {
const model = agent.model ? ` ${agent.model}` : "";
return `${agent.id} ${agent.status} ${agent.profileName} ${agent.provider}${model}`;
const thinking = agent.thinking ? ` thinking=${agent.thinking}` : "";
return `${agent.id} ${agent.status} ${agent.profileName} ${agent.provider}${model}${thinking}`;
}

function sleep(ms: number): Promise<void> {
Expand All @@ -550,7 +560,7 @@ function printAgentsHelp(): void {
"",
"Usage:",
" devspace agents ls",
" devspace agents run <profile-or-provider-or-id> [--model <model>] <prompt>",
" devspace agents run <profile-or-provider-or-id> [--model <model>] [--thinking <level>] <prompt>",
" devspace agents show <id>",
].join("\n"),
);
Expand Down
5 changes: 4 additions & 1 deletion src/db/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ function migrateLocalAgentSessions(sqlite: Database.Database): void {
profile_name text not null,
provider text not null,
model text,
thinking text,
provider_session_id text,
status text not null,
latest_response text,
Expand All @@ -169,11 +170,13 @@ function migrateLocalAgentSessions(sqlite: Database.Database): void {
create index if not exists local_agent_sessions_provider_session_id_idx
on local_agent_sessions(provider_session_id);
`);

addColumnIfMissing(sqlite, "local_agent_sessions", "thinking", "text");
}

function addColumnIfMissing(
sqlite: Database.Database,
table: "workspace_sessions",
table: "workspace_sessions" | "local_agent_sessions",
column: string,
definition: string,
): void {
Expand Down
1 change: 1 addition & 0 deletions src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const localAgentSessions = sqliteTable(
profileName: text("profile_name").notNull(),
provider: text("provider").notNull(),
model: text("model"),
thinking: text("thinking"),
providerSessionId: text("provider_session_id"),
status: text("status").notNull(),
latestResponse: text("latest_response"),
Expand Down
Loading
Loading