opencode-codeops 1.10.1 → 1.10.3
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
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to CodeOps are recorded here.
|
|
4
4
|
|
|
5
|
+
## 1.10.3 — 2026-10-04
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- effort: prefer the model variant over the reasoning-support flag
|
|
10
|
+
|
|
11
|
+
## 1.10.2 — 2026-10-04
|
|
12
|
+
|
|
13
|
+
### Fixes
|
|
14
|
+
|
|
15
|
+
- effort: remember dispatch markers per session
|
|
16
|
+
|
|
5
17
|
## 1.10.1 — 2026-10-04
|
|
6
18
|
|
|
7
19
|
### Features
|
|
@@ -43,6 +43,10 @@ A dispatch marker is one standalone line in a dispatch message:
|
|
|
43
43
|
For quality-agent packets the marker follows the dispatch header; for packet kinds without a
|
|
44
44
|
header it is the first line. `exec-plan` owns the composition rule.
|
|
45
45
|
|
|
46
|
+
A captured marker is remembered for the whole session: every request in that session uses it
|
|
47
|
+
until a newer marker replaces it or the session ends. This is what keeps the marker effective
|
|
48
|
+
when the host passes a later user message to the request hook.
|
|
49
|
+
|
|
46
50
|
## Precedence
|
|
47
51
|
|
|
48
52
|
The most specific source wins:
|
|
@@ -309,9 +309,13 @@ export function modelSupportsReasoning(model) {
|
|
|
309
309
|
* The runtime model carries a `variants` record whose entries are the exact
|
|
310
310
|
* provider options for each level (for example `reasoningEffort`, or a nested
|
|
311
311
|
* `reasoning.effort`). This function is the only place that mapping is
|
|
312
|
-
* consumed, so the plugin never hardcodes a provider key.
|
|
313
|
-
*
|
|
314
|
-
*
|
|
312
|
+
* consumed, so the plugin never hardcodes a provider key. A matching variant
|
|
313
|
+
* is applied even when the model's reasoning capability flag is absent or
|
|
314
|
+
* false: the variant itself is the provider-known option set, and the host
|
|
315
|
+
* applies inherited variants the same way. Only when no variants record
|
|
316
|
+
* exists does the documented `reasoningEffort` passthrough require an
|
|
317
|
+
* explicit reasoning capability. The function is pure: it returns a new
|
|
318
|
+
* object when a change applies and the original object reference otherwise.
|
|
315
319
|
*
|
|
316
320
|
* @param options - Current provider options
|
|
317
321
|
* @param level - Candidate level from {@link resolveEffort}
|
|
@@ -320,7 +324,6 @@ export function modelSupportsReasoning(model) {
|
|
|
320
324
|
*/
|
|
321
325
|
export function applyEffort(options, level, model) {
|
|
322
326
|
if (!isRoutingReasoning(level)) return options
|
|
323
|
-
if (!modelSupportsReasoning(model)) return options
|
|
324
327
|
|
|
325
328
|
const variants = extractModelVariants(model)
|
|
326
329
|
if (variants !== undefined) {
|
|
@@ -330,6 +333,7 @@ export function applyEffort(options, level, model) {
|
|
|
330
333
|
return deepMergePlain(options, variantOptions)
|
|
331
334
|
}
|
|
332
335
|
|
|
336
|
+
if (!modelSupportsReasoning(model)) return options
|
|
333
337
|
return { ...options, reasoningEffort: level }
|
|
334
338
|
}
|
|
335
339
|
|
package/package.json
CHANGED
package/plugin/index.ts
CHANGED
|
@@ -12,10 +12,12 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
appendEffortTrace,
|
|
14
14
|
applyEffort,
|
|
15
|
+
extractModelVariants,
|
|
15
16
|
findEffortMarker,
|
|
16
17
|
isEffortLevel,
|
|
17
18
|
isEffortTraceEnabled,
|
|
18
19
|
isRoutingReasoning,
|
|
20
|
+
modelSupportsReasoning,
|
|
19
21
|
readRoutingReasoning,
|
|
20
22
|
readSessionEffort,
|
|
21
23
|
resolveEffort,
|
|
@@ -196,9 +198,9 @@ function traceEffort(
|
|
|
196
198
|
// ---------------------------------------------------------------------------
|
|
197
199
|
export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
198
200
|
// Reasoning-effort state lives for the lifetime of this plugin instance:
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
const effortMarkers = new Map<string,
|
|
201
|
+
// the latest dispatch-marker level per session, plus a deduplication set
|
|
202
|
+
// for unsupported-level warnings.
|
|
203
|
+
const effortMarkers = new Map<string, EffortLevel>()
|
|
202
204
|
const warnedEffortLevels = new Set<string>()
|
|
203
205
|
const effortTraceEnabled = isEffortTraceEnabled(process.env.CODEOPS_EFFORT_TRACE)
|
|
204
206
|
|
|
@@ -221,9 +223,7 @@ export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
|
221
223
|
const info = (event.properties as { info: { id: string } }).info
|
|
222
224
|
removeSessionTmpDir(info.id)
|
|
223
225
|
try {
|
|
224
|
-
|
|
225
|
-
if (entry.sessionID === info.id) effortMarkers.delete(messageID)
|
|
226
|
-
}
|
|
226
|
+
effortMarkers.delete(info.id)
|
|
227
227
|
} catch {
|
|
228
228
|
await warnContentFree(client, "Could not clear captured reasoning-effort markers.")
|
|
229
229
|
}
|
|
@@ -288,8 +288,9 @@ export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
|
288
288
|
|
|
289
289
|
// -----------------------------------------------------------------------
|
|
290
290
|
// Hook 6: capture a dispatch marker from an incoming user message. The
|
|
291
|
-
// marker travels in the dispatch packet text;
|
|
292
|
-
//
|
|
291
|
+
// marker travels in the dispatch packet text; it is remembered for the
|
|
292
|
+
// whole session, because the later chat.params hook receives the latest
|
|
293
|
+
// user message, which can differ from the message that carried it.
|
|
293
294
|
// -----------------------------------------------------------------------
|
|
294
295
|
"chat.message": async (input, output) => {
|
|
295
296
|
try {
|
|
@@ -298,7 +299,7 @@ export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
|
298
299
|
)
|
|
299
300
|
const level = findEffortMarker(texts)
|
|
300
301
|
if (level !== undefined) {
|
|
301
|
-
effortMarkers.set(
|
|
302
|
+
effortMarkers.set(input.sessionID, level)
|
|
302
303
|
traceEffort(effortTraceEnabled, input.sessionID, {
|
|
303
304
|
event: "capture",
|
|
304
305
|
messageID: output.message.id,
|
|
@@ -317,8 +318,7 @@ export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
|
317
318
|
// -----------------------------------------------------------------------
|
|
318
319
|
"chat.params": async (input, output) => {
|
|
319
320
|
try {
|
|
320
|
-
const
|
|
321
|
-
const marker = stored && stored.sessionID === input.sessionID ? stored.level : undefined
|
|
321
|
+
const marker = effortMarkers.get(input.sessionID)
|
|
322
322
|
const session = readSessionEffort(input.sessionID)
|
|
323
323
|
const routing = readRoutingReasoning(readRoutingConfig(directory), input.agent)
|
|
324
324
|
const level = resolveEffort({ marker, session, routing })
|
|
@@ -350,6 +350,8 @@ export const CodeOpsPlugin: Plugin = async ({ client, directory }) => {
|
|
|
350
350
|
level,
|
|
351
351
|
source,
|
|
352
352
|
applied: changed,
|
|
353
|
+
reasoningSupported: modelSupportsReasoning(input.model),
|
|
354
|
+
variantLevels: Object.keys(extractModelVariants(input.model) ?? {}),
|
|
353
355
|
})
|
|
354
356
|
if (!changed) {
|
|
355
357
|
if (marker !== undefined) {
|
|
Binary file
|