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

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

### `thinking`
### `effort`

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
effort: low
effort: high
effort: 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`.
- `pi`: CLI `--thinking` (provider-native flag; DevSpace field is still `effort`).
- `opencode`: model variant.
- `cursor` and `copilot`: ACP thought-level config when supported.

Legacy profile frontmatter key `thinking:` is still accepted and maps to `effort`.

### `disabled`

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

Expand Down
1,150 changes: 1,150 additions & 0 deletions docs/claude-code-dynamic-workflows.html

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions docs/dynamic-workflow/claude/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Claude Code Dynamic Workflows

In-depth reference for Claude Code’s **dynamic workflow** system: the model-facing `Workflow` tool, the JavaScript script contract, every primitive injected into the script, resume/budget semantics, quality patterns, and how this enables a stronger model to orchestrate subagents one level above ordinary tool use.

| Document | Contents |
|---|---|
| [Architecture](./architecture.md) | Three layers, control flow vs worker content, mental model |
| [Opt-in & Ultracode](./opt-in.md) | When the model may call Workflow; standing multi-agent mode |
| [Workflow tool API](./workflow-tool.md) | Tool inputs, return envelope, launch/iterate/named workflows |
| [Script contract](./script-contract.md) | `export const meta`, language rules, determinism bans |
| [Primitives overview](./primitives.md) | Map of all script hooks |
| [agent()](./agent.md) | Spawn API, schema, model/effort, worktree, agentType |
| [pipeline() & parallel()](./concurrency.md) | No-barrier default vs barrier; when each is correct |
| [phase, log, args, budget, workflow()](./control-and-io.md) | Progress UX, parameterization, token ceiling, nesting |
| [Limits & sandbox](./limits.md) | Concurrency caps, agent caps, script isolation |
| [Resume & journal](./resume.md) | `resumeFromRunId`, cache identity, `journal.jsonl` |
| [Quality patterns](./patterns.md) | Adversarial verify, judge panel, loop-until-dry, … |
| [Lifecycle & UX](./lifecycle.md) | Permission, `/workflows`, notifications, multi-phase |
| [One level above](./orchestration.md) | Bigger brain orchestrates smaller hands |
| [Use cases](./usecases.md) | Review fleets, migrations, research, self-repair |
| [Cheatsheet](./cheatsheet.md) | One-page API card |

Related: standalone HTML overview at [`docs/claude-code-dynamic-workflows.html`](../../claude-code-dynamic-workflows.html).

---

## One-sentence thesis

**Deterministic control flow + stochastic workers + one orchestrator brain.**

A single agent loop confuses *what to do next* with *how to do the work*. Dynamic workflows split them: the orchestrator model authors a short plain-JS script; the harness runs loops, conditionals, and fan-out as **code**; only `agent()` escapes into a model with tools.

## Why it exists

| Without workflows | With workflows |
|---|---|
| Fan-out is ad-hoc tool spam each turn | Fan-out is `parallel` / `pipeline` in a script |
| Verification is optional and forgettable | Verification is a stage in the graph |
| One context holds plan + all tool churn | Workers isolate tool churn; script aggregates returns |
| Scale = longer single conversation | Scale = fleet size × stages under budget |

## Scope of this doc set

- **In scope:** model-facing API as exposed by Claude Code ~2.1.x (`Workflow` / `RunWorkflow` tool, script primitives, opt-in, resume, budget, patterns).
- **Out of scope:** Anthropic product marketing, undocumented internal harness code, DevSpace’s separate durable workflow engine (see feature branches / other docs if present).

Source basis: Claude Code Workflow tool description, session `workflows/scripts/*.js` examples, and engine rules encoded in the tool prompt (opt-in, ultracode, resume, concurrency).
205 changes: 205 additions & 0 deletions docs/dynamic-workflow/claude/agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# `agent()`

The only primitive that spends model/tool budget on real work. Everything else in the script is control flow, UX, or nesting.

## Signature

```ts
agent(
prompt: string,
opts?: {
label?: string
phase?: string
schema?: object // JSON Schema
model?: string // e.g. session model ids / 'sonnet' | 'opus' | 'haiku'
effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max'
isolation?: 'worktree'
agentType?: string // registry name: 'general-purpose', 'code-reviewer', 'claude', …
}
): Promise<any>
```

## Return value

| Mode | Resolves to |
|---|---|
| No `schema` | Final assistant text (`string`) |
| With `schema` | **Validated object** matching the JSON Schema (StructuredOutput tool; model retries on mismatch) |
| User skip / terminal API death after retries | `null` |

Always treat results as possibly null when fan-out is large:

```js
const rows = (await parallel(tasks)).filter(Boolean)
```

## Semantics

1. Spawns a **subagent** with its own tool loop (Read, Bash, Edit, …).
2. Subagents are instructed that their **final text/object is the return value** to the coordinator script — not a user-facing message.
3. Prompt should be **self-contained**: workers do not inherit the full main-session transcript.
4. Session-connected **MCP tools** are reachable via ToolSearch (on-demand schemas). Interactively authenticated MCP may be missing in headless/cron.
5. Errors in the agent path surface as `null` for that call in combinators that swallow rejections; check journals if results look empty ([resume](./resume.md)).

## Options

### `label`

Short string for `/workflows` progress UI (e.g. `review:security`, `verify:src/auth.ts`). Does not affect model behavior.

### `phase`

Explicit progress group assignment. **Prefer this inside `pipeline` / `parallel` stages** to avoid races on the global `phase()` state. Same string → same group box. Should match titles in `meta.phases` when you want tidy UI.

### `schema`

JSON Schema object. Forces structured output:

- Validation at the tool-call layer.
- `agent()` returns the object — no `JSON.parse` of prose.
- Composes with `agentType` (StructuredOutput instruction is appended to that agent’s system prompt).

Example:

```js
const FINDINGS = {
type: 'object',
properties: {
findings: {
type: 'array',
items: {
type: 'object',
properties: {
file: { type: 'string' },
line: { type: 'integer' },
issue: { type: 'string' },
severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
},
required: ['file', 'line', 'issue', 'severity'],
additionalProperties: false,
},
},
summary: { type: 'string' },
},
required: ['findings', 'summary'],
additionalProperties: false,
}

const result = await agent(
'Review auth changes for session fixation. Read-only. Cite file:line.',
{
label: 'review:auth',
phase: 'Review',
schema: FINDINGS,
effort: 'medium',
}
)
// result.findings is already shaped
```

### `model`

Override the model for this call.

- **Default: omit** — inherit the main-loop / session model (almost always correct).
- Set only when you are confident a different tier fits (e.g. small model for mechanical map, large for hard judge).
- When unsure, omit.

### `effort`

Reasoning effort for this call: `'low' | 'medium' | 'high' | 'xhigh' | 'max'`.

- Omit → inherit session effort.
- Use `'low'` for cheap mechanical stages (enumerate files, simple extract).
- Reserve higher tiers for hard verify / judge / design stages.

### `isolation: 'worktree'`

Runs the agent in a **fresh git worktree**.

| Property | Detail |
|---|---|
| Cost | Expensive (~200–500ms setup + disk) per agent |
| When | **Only** when agents **mutate files in parallel** and would otherwise conflict |
| Cleanup | Auto-removed if unchanged |
| When not | Read-only review, single writer, sequential pipeline of mutators on one tree |

### `agentType`

Custom subagent from the **same registry as the Agent tool** (e.g. `general-purpose`, `code-reviewer`, `Explore`, project-defined types, or `claude` where configured).

- Overrides the default workflow subagent personality/tools policy for that call.
- Composes with `schema`.

## Prompting workers well

Workers start with **only** the prompt you pass (+ profile/system for `agentType`). Patterns:

**Implementation**

```text
Goal: …
Context: …
Relevant files: …
Acceptance criteria:
- …
Rules:
- Keep changes focused
- Do not unrelated-refactor
- Report blockers clearly
```

**Read-only investigation**

```text
Question: …
Scope: …
Rules:
- Do not modify files
- Cite paths and symbols
- Separate facts from guesses
```

**Structured judge / refuter**

```text
Try to REFUTE: <claim>
Default to refuted=true if uncertain.
Return only via the schema fields.
```

Pass prior stage data by **embedding it in the prompt** (stringified structured JSON), not by shared mutable state — scripts have no shared worker memory beyond what you thread through returns.

## Cost & altitude tips

| Stage kind | Typical opts |
|---|---|
| Enumerate / map / extract | `effort: 'low'`, maybe smaller `model` |
| Implement / edit | inherit model; medium effort; `isolation: 'worktree'` if parallel |
| Review dimension | schema + medium effort |
| Adversarial judge | higher effort; schema; independent prompts |
| Final verify gates | low/medium; focused prompt |

The orchestrator stays high-altitude by keeping **structure** in the script and **content** in workers. See [orchestration](./orchestration.md).

## Null and failure hygiene

```js
const reviews = await parallel([
() => agent(p1, { schema: FINDINGS }),
() => agent(p2, { schema: FINDINGS }),
() => agent(p3, { schema: FINDINGS }),
]).then(xs => xs.filter(Boolean))

if (!reviews.length) {
log('all reviewers failed or were skipped')
return { confirmed: [], error: 'no_reviews' }
}
```

Before claiming “workflow returned empty,” read `transcriptDir/journal.jsonl` — cached or failed agents may explain it ([resume](./resume.md)).

## Next

- [pipeline & parallel](./concurrency.md)
- [Patterns](./patterns.md)
Loading
Loading