opencode-codeops 1.9.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +16 -0
- package/_shared/quality-profile.md +4 -0
- package/_shared/reasoning-effort.md +144 -0
- package/bin/lib/reasoning-effort.d.mts +98 -0
- package/bin/lib/reasoning-effort.mjs +383 -0
- package/package.json +1 -1
- package/plugin/index.ts +152 -0
- package/scripts/__pycache__/install_agents.cpython-312.pyc +0 -0
- package/scripts/codeops_effort.py +216 -0
- package/skills/exec-plan/SKILL.md +12 -0
- package/skills/exec-plan/execution-protocol.md +43 -3
- package/skills/grill-me/SKILL.md +10 -0
- package/skills/make-plan/SKILL.md +17 -0
- package/skills/make-plan/templates.md +2 -0
- package/skills/make-requirements/SKILL.md +10 -0
- package/skills/preflight/SKILL.md +10 -0
- package/skills/retro-requirements/SKILL.md +10 -0
- package/skills/setup-routing/SKILL.md +2 -0
- package/skills/setup-routing/routing.md +16 -1
- package/skills/upgrade-plan/SKILL.md +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to CodeOps are recorded here.
|
|
4
4
|
|
|
5
|
+
## 1.10.1 — 2026-10-04
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- effort: add opt-in applied-level trace
|
|
10
|
+
|
|
11
|
+
## 1.10.0 — 2026-10-04
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- agents: refresh managed project facts
|
|
16
|
+
- routing: clarify runtime variant validation
|
|
17
|
+
- plan: fix phase 3 review wording gaps
|
|
18
|
+
|
|
19
|
+
### Fixes
|
|
20
|
+
|
|
21
|
+
- effort: tolerate malformed message parts in marker scan
|
|
22
|
+
- effort: correct phase 2 review findings
|
|
23
|
+
- effort: harden helper totality and contract wording
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
- docs: add auto-effort flags and reasoning documentation
|
|
28
|
+
- plan: carry reasoning suggestions through plan skills
|
|
29
|
+
- effort: add session CLI and plugin runtime hooks
|
|
30
|
+
- effort: add reasoning-effort contract and helper
|
|
31
|
+
|
|
32
|
+
### Tests
|
|
33
|
+
|
|
34
|
+
- effort: add implementation tests for reasoning-effort helper
|
|
35
|
+
|
|
5
36
|
## 1.9.0 — 2026-10-04
|
|
6
37
|
|
|
7
38
|
### Features
|
package/README.md
CHANGED
|
@@ -153,6 +153,22 @@ To pin specific models per role, use the `setup-routing` skill or add overrides
|
|
|
153
153
|
}
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
### Adaptive reasoning effort
|
|
157
|
+
|
|
158
|
+
CodeOps can pick a reasoning level per dispatch instead of always inheriting the parent session's
|
|
159
|
+
variant. A dispatch packet may carry one standalone marker line:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
[codeops-effort: medium]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Reasoning-heavy skills also accept `--auto-effort` (use the skill's recommended level) or
|
|
166
|
+
`--auto-effort=high` (explicit level), announce it, and clear it before the final run summary.
|
|
167
|
+
Resolution order: dispatch marker, then session `--auto-effort`, then
|
|
168
|
+
`routing.roles.<agent>.reasoning` in `codeops/codeops.json`, then the inherited parent variant.
|
|
169
|
+
The levels are suggestions: no permission, verification step, or review gate ever reads them. The
|
|
170
|
+
full contract is in `_shared/reasoning-effort.md`.
|
|
171
|
+
|
|
156
172
|
## Project specialists
|
|
157
173
|
|
|
158
174
|
CodeOps can recommend project-specific specialist subagents when repository evidence shows a
|
|
@@ -147,6 +147,10 @@ Resolution order is:
|
|
|
147
147
|
3. project `[agents]` defaults in `opencode.json`;
|
|
148
148
|
4. the parent session's model and effort.
|
|
149
149
|
|
|
150
|
+
For the runtime reasoning-effort override (a dispatch marker, a session `--auto-effort` level, or
|
|
151
|
+
a routing role default), see [reasoning-effort.md](reasoning-effort.md); the static resolution
|
|
152
|
+
order above is unchanged.
|
|
153
|
+
|
|
150
154
|
Use `python3 "${CODEOPS_PLUGIN_ROOT}/scripts/install_agents.py" --project . --roles ...` to create optional project agents. Generated agent files carry a CodeOps marker. The installer owns only marked files and preserves every hand-authored file. Use `--check` to detect missing or stale generated agents and `--dry-run` to preview changes. Project specialists are generated with `--custom <role>` from `codeops/specialists/<role>.md` and indexed into `AGENTS.md` with `--sync-agents-md`; their routing policy may also set `reasoning`.
|
|
151
155
|
|
|
152
156
|
Dynamic packets are the correctness baseline. If a named agent is missing or a model pin is unavailable, spawn a generic subagent with the complete packet or run inline. Report the fallback and preserve required reviewer independence, sandbox intent, and every ambiguity/readiness/verification gate.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Reasoning effort (shared contract)
|
|
2
|
+
|
|
3
|
+
> **CodeOps Artifact Schema**: 1
|
|
4
|
+
|
|
5
|
+
CodeOps subagents normally inherit the parent session's model variant, so a top-tier parent
|
|
6
|
+
would pay top-tier reasoning cost for every child dispatch. Adaptive reasoning effort lets an
|
|
7
|
+
explicit source pick a level per dispatch or per skill run. This document is the shipped
|
|
8
|
+
contract consumed by the plugin and the skills. It is advisory by design and never a gate.
|
|
9
|
+
|
|
10
|
+
## Levels
|
|
11
|
+
|
|
12
|
+
| Level | Meaning | Typical work |
|
|
13
|
+
| ----- | ------- | ------------ |
|
|
14
|
+
| `low` | Mechanical, fully specified, deterministic verification | Docs and formatting edits, renames, config updates |
|
|
15
|
+
| `medium` | Ordinary bounded feature work with known patterns | Standard implementation phases, recon, single-file reviews |
|
|
16
|
+
| `high` | Correctness- or security-sensitive, cross-cutting, or planning/review work | Requirements, planning, correctness/security review, ambiguous implementation |
|
|
17
|
+
| `max` | Adversarial or high-risk analysis where a missed detail is costly | Thorough preflight, complex or sensitive phases |
|
|
18
|
+
|
|
19
|
+
The four levels are the complete suggestion vocabulary. A level is applied only when the
|
|
20
|
+
runtime model exposes a matching variant, or when the model reports reasoning support but has no
|
|
21
|
+
variant record (the level is then written directly as the provider reasoning option). A level
|
|
22
|
+
the model does not expose leaves the request unchanged and never raises a provider error.
|
|
23
|
+
Routing policy is project configuration, not a suggestion:
|
|
24
|
+
`routing.roles.<agent>.reasoning` may name any value from the provider enum
|
|
25
|
+
(`none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`).
|
|
26
|
+
|
|
27
|
+
## Marker grammar
|
|
28
|
+
|
|
29
|
+
A dispatch marker is one standalone line in a dispatch message:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
[codeops-effort: <level>]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- The whole trimmed line must match `^\[codeops-effort:\s*(low|medium|high|max)\]\s*$`.
|
|
36
|
+
- The level is exactly lower-case. Unknown or malformed markers are ignored, never errors.
|
|
37
|
+
- Only user-role text parts of a message are scanned; tool output, diffs, and quoted documents
|
|
38
|
+
are never scanned.
|
|
39
|
+
- The first valid marker in message order wins; additional markers are ignored.
|
|
40
|
+
- The marker is deliberately distinct from the human-readable plan line
|
|
41
|
+
`> **Reasoning**: ...`, so a quoted plan line can never act as a machine directive.
|
|
42
|
+
|
|
43
|
+
For quality-agent packets the marker follows the dispatch header; for packet kinds without a
|
|
44
|
+
header it is the first line. `exec-plan` owns the composition rule.
|
|
45
|
+
|
|
46
|
+
## Precedence
|
|
47
|
+
|
|
48
|
+
The most specific source wins:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
dispatch marker > session auto-effort > routing.roles[<agent>].reasoning > inherit parent variant
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| Source | Scope | Owner |
|
|
55
|
+
| ------ | ----- | ----- |
|
|
56
|
+
| Dispatch marker | One child dispatch | `exec-plan` composes it from the phase suggestion or the run's forced level |
|
|
57
|
+
| Session auto-effort | One skill run in the user's session | `--auto-effort` through `scripts/codeops_effort.py` |
|
|
58
|
+
| Routing role default | Project policy for one agent name | `codeops/codeops.json` → `routing.roles.<agent>.reasoning` |
|
|
59
|
+
| Inherit | Everything else | The child keeps the parent model and variant |
|
|
60
|
+
|
|
61
|
+
Routing lookup applies only when the dispatching agent's name has an explicit `routing.roles`
|
|
62
|
+
entry. There are no built-in catalog defaults, hand-authored agents are untouched, and
|
|
63
|
+
generated specialists keep their embedded value unless the project adds a routing entry.
|
|
64
|
+
|
|
65
|
+
## Skill recommendation table
|
|
66
|
+
|
|
67
|
+
Used for suggestions and for a bare `--auto-effort`:
|
|
68
|
+
|
|
69
|
+
| Skill | Recommended level | Notes |
|
|
70
|
+
| ----- | ----------------- | ----- |
|
|
71
|
+
| `make-requirements` | `high` | Structured discovery and gap expansion |
|
|
72
|
+
| `make-plan` | `high` | Decomposition plus the Zero-Ambiguity Gate |
|
|
73
|
+
| `preflight` | `high`; `max` with `--thorough` | Adversarial multi-dimension audit |
|
|
74
|
+
| `grill-me` | `high` | Branch-by-branch disambiguation |
|
|
75
|
+
| `exec-plan` | current phase's `Reasoning:` level | Bare flag follows the phase; `=<level>` forces a constant |
|
|
76
|
+
| `retro-requirements` | `high` | Nine-phase archaeology |
|
|
77
|
+
| `upgrade-plan` | `high` | Content gate plus structural migration |
|
|
78
|
+
| `setup-codeops`, `setup-routing` | `high` (reference only) | Structure and policy authoring |
|
|
79
|
+
| `techdocs`, `analyze-project`, `clean-comments`, `outcome-review` | `medium` (reference only) | Structured but bounded |
|
|
80
|
+
| `roadmap`, `git-commit`, `github-issues` | `low` (reference only) | Mechanical bookkeeping |
|
|
81
|
+
|
|
82
|
+
Skills that accept `--auto-effort` are `make-requirements`, `make-plan`, `preflight`,
|
|
83
|
+
`grill-me`, `exec-plan`, `retro-requirements`, and `upgrade-plan`. Other skills document their
|
|
84
|
+
recommended levels for reference only and do not implement the flag.
|
|
85
|
+
|
|
86
|
+
## Plan suggestion derivation
|
|
87
|
+
|
|
88
|
+
`make-plan` derives an advisory level for every phase and every task mini-plan from signals it
|
|
89
|
+
already records:
|
|
90
|
+
|
|
91
|
+
| Signal | Suggested level |
|
|
92
|
+
| ------ | --------------- |
|
|
93
|
+
| Phase carries a complexity escalation approval, or a complex/sensitive tag | `max` |
|
|
94
|
+
| Phase carries a security, financial-integrity, concurrency, performance-critical, compiler-semantics, or migration lens/risk tag | `high` |
|
|
95
|
+
| Docs/config/rename-only phase with deterministic verification | `low` |
|
|
96
|
+
| Any other non-trivial phase | `medium` |
|
|
97
|
+
|
|
98
|
+
The line is written as `> **Reasoning**: <level> — <one-line reason>`. It is a suggestion: the
|
|
99
|
+
user may edit or delete it, and `exec-plan` never blocks on it. A plan without the line keeps
|
|
100
|
+
the inherited behavior.
|
|
101
|
+
|
|
102
|
+
## Auto-effort option
|
|
103
|
+
|
|
104
|
+
Skills listed above accept the flag. Parsing follows the existing standalone-token pattern
|
|
105
|
+
(`--auto-design`, `--explore-scope`): exactly one occurrence before the first `--` sentinel,
|
|
106
|
+
removed before resolving targets, paths, or modes; zero means advise-only; more than one or an
|
|
107
|
+
invalid `=<level>` is an argument error.
|
|
108
|
+
|
|
109
|
+
| Flag | Behavior |
|
|
110
|
+
| ---- | -------- |
|
|
111
|
+
| *(absent)* | Print `Suggested reasoning: <level> — <reason>` once at start (`exec-plan`: before each phase); change nothing |
|
|
112
|
+
| `--auto-effort` | Use the skill's recommended level (`exec-plan`: the current phase level) |
|
|
113
|
+
| `--auto-effort=<level>` | Use the named level; reject values outside the four-level set |
|
|
114
|
+
|
|
115
|
+
Semantics:
|
|
116
|
+
|
|
117
|
+
1. Announce `Auto-effort active — reasoning <level> applied for this run`.
|
|
118
|
+
2. Record the level for the session run through `scripts/codeops_effort.py`.
|
|
119
|
+
3. Clear it at run completion, before the final summary.
|
|
120
|
+
4. Run-scoped: the level applies from the point it is set until cleared or the session ends.
|
|
121
|
+
5. Fail-open: when the session temp directory is unavailable or the helper fails, print an
|
|
122
|
+
advise-only note and continue; the skill never blocks.
|
|
123
|
+
6. Never a gate: effort affects cost and latency only. No readiness check, verification step,
|
|
124
|
+
reviewer requirement, or finding gate may read it.
|
|
125
|
+
|
|
126
|
+
For `exec-plan`, a bare flag follows each phase's suggestion, while `--auto-effort=<level>`
|
|
127
|
+
forces that level for the whole run, including every dispatch marker composed during it.
|
|
128
|
+
|
|
129
|
+
## Optional tracing
|
|
130
|
+
|
|
131
|
+
Set `CODEOPS_EFFORT_TRACE=1` (or `true`) in the environment that starts OpenCode to record what
|
|
132
|
+
the plugin does. One content-free JSON line is appended per marker capture and per request to
|
|
133
|
+
`reasoning-effort-trace.jsonl` inside the session's scratch directory. Lines carry only a
|
|
134
|
+
timestamp, event name, message id, agent name, level, source, and applied flag — never prompt
|
|
135
|
+
text or file content. The trace lives with the rest of the session scratch and is removed with
|
|
136
|
+
it. Tracing is off by default and never affects a request.
|
|
137
|
+
|
|
138
|
+
## Suggestion-only guarantee
|
|
139
|
+
|
|
140
|
+
| Allowed | Forbidden |
|
|
141
|
+
| ------- | --------- |
|
|
142
|
+
| Printing a suggested level and its reason | Blocking a run because a level is missing or unsupported |
|
|
143
|
+
| Applying a level when a marker, flag, or routing entry explicitly asks | Overriding an explicit user plan edit with a derived default |
|
|
144
|
+
| Reporting the applied level and its source | Treating effort as an acceptance, review, or security control |
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for the CodeOps adaptive reasoning-effort helper.
|
|
3
|
+
*
|
|
4
|
+
* The helper is plain JavaScript so `node --test` can exercise it directly;
|
|
5
|
+
* these declarations give the TypeScript plugin entry point typed access.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** A level from the four-level suggestion vocabulary. */
|
|
9
|
+
export type EffortLevel = "low" | "medium" | "high" | "max"
|
|
10
|
+
|
|
11
|
+
/** A reasoning value accepted by `routing.roles.<agent>.reasoning`. */
|
|
12
|
+
export type RoutingReasoning =
|
|
13
|
+
| "none"
|
|
14
|
+
| "minimal"
|
|
15
|
+
| "low"
|
|
16
|
+
| "medium"
|
|
17
|
+
| "high"
|
|
18
|
+
| "xhigh"
|
|
19
|
+
| "max"
|
|
20
|
+
|
|
21
|
+
/** The four levels a plan or skill may suggest. */
|
|
22
|
+
export declare const EFFORT_LEVELS: readonly EffortLevel[]
|
|
23
|
+
|
|
24
|
+
/** Check whether a value is one of the four suggestion levels. */
|
|
25
|
+
export declare function isEffortLevel(value: unknown): value is EffortLevel
|
|
26
|
+
|
|
27
|
+
/** The reasoning values accepted by routing role entries. */
|
|
28
|
+
export declare const ROUTING_REASONING_VALUES: readonly RoutingReasoning[]
|
|
29
|
+
|
|
30
|
+
/** Check whether a value is a valid routing reasoning entry. */
|
|
31
|
+
export declare function isRoutingReasoning(value: unknown): value is RoutingReasoning
|
|
32
|
+
|
|
33
|
+
/** Find the first valid dispatch marker across message text parts. */
|
|
34
|
+
export declare function findEffortMarker(texts: unknown): EffortLevel | undefined
|
|
35
|
+
|
|
36
|
+
/** Candidate sources for {@link resolveEffort}. */
|
|
37
|
+
export interface ResolveEffortInput {
|
|
38
|
+
marker?: unknown
|
|
39
|
+
session?: unknown
|
|
40
|
+
routing?: unknown
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Resolve the effective level from the explicit sources, most specific first. */
|
|
44
|
+
export declare function resolveEffort(
|
|
45
|
+
input?: ResolveEffortInput
|
|
46
|
+
): EffortLevel | RoutingReasoning | undefined
|
|
47
|
+
|
|
48
|
+
/** Compute the session state-file path inside the session temp directory. */
|
|
49
|
+
export declare function sessionEffortPath(sessionID?: string, base?: string): string
|
|
50
|
+
|
|
51
|
+
/** Parse session state-file text into a validated level. */
|
|
52
|
+
export declare function parseStateFile(text: string): EffortLevel | undefined
|
|
53
|
+
|
|
54
|
+
/** Read the session's reasoning-effort state file. */
|
|
55
|
+
export declare function readSessionEffort(
|
|
56
|
+
sessionID?: string,
|
|
57
|
+
base?: string
|
|
58
|
+
): EffortLevel | undefined
|
|
59
|
+
|
|
60
|
+
/** Check whether the optional trace environment switch is on. */
|
|
61
|
+
export declare function isEffortTraceEnabled(value: unknown): boolean
|
|
62
|
+
|
|
63
|
+
/** Compute the trace-file path inside the session temp directory. */
|
|
64
|
+
export declare function sessionEffortTracePath(sessionID?: string, base?: string): string
|
|
65
|
+
|
|
66
|
+
/** Append one content-free trace entry to the session trace file. */
|
|
67
|
+
export declare function appendEffortTrace(
|
|
68
|
+
sessionID: string | undefined,
|
|
69
|
+
entry: unknown,
|
|
70
|
+
base?: string
|
|
71
|
+
): boolean
|
|
72
|
+
|
|
73
|
+
/** Read an agent's explicit reasoning entry from the project routing config. */
|
|
74
|
+
export declare function readRoutingReasoning(
|
|
75
|
+
config: unknown,
|
|
76
|
+
agent: unknown
|
|
77
|
+
): RoutingReasoning | undefined
|
|
78
|
+
|
|
79
|
+
/** Extract the model's runtime variant record, when the host exposes one. */
|
|
80
|
+
export declare function extractModelVariants(
|
|
81
|
+
model: unknown
|
|
82
|
+
): Record<string, unknown> | undefined
|
|
83
|
+
|
|
84
|
+
/** Check whether a model advertises reasoning support. */
|
|
85
|
+
export declare function modelSupportsReasoning(model: unknown): boolean
|
|
86
|
+
|
|
87
|
+
/** Merge the model's variant options for a level into the request options. */
|
|
88
|
+
export declare function applyEffort(
|
|
89
|
+
options: Record<string, unknown>,
|
|
90
|
+
level: unknown,
|
|
91
|
+
model: unknown
|
|
92
|
+
): Record<string, unknown>
|
|
93
|
+
|
|
94
|
+
/** Recursively merge plain objects into a new object. */
|
|
95
|
+
export declare function deepMergePlain(
|
|
96
|
+
target: unknown,
|
|
97
|
+
source: unknown
|
|
98
|
+
): Record<string, unknown>
|