@bridge4dev/runner 0.51.0 → 0.52.0
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/dist/adapters/codex.js +93 -0
- package/dist/adapters/types.d.ts +9 -2
- package/dist/supervisor.js +8 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/adapters/codex.js
CHANGED
|
@@ -284,6 +284,12 @@ class CodexSession {
|
|
|
284
284
|
sessionId: this.spec.sessionId,
|
|
285
285
|
});
|
|
286
286
|
}
|
|
287
|
+
// Before the thread, not after: a model this CLI no longer offers is
|
|
288
|
+
// refused by `thread/start` itself, and the pin is stored — so the same
|
|
289
|
+
// session would fail again on every relaunch (#374).
|
|
290
|
+
await this.dropModelTheCliNoLongerHas();
|
|
291
|
+
if (this.stopped)
|
|
292
|
+
return;
|
|
287
293
|
const thread = await this.openThread();
|
|
288
294
|
if (this.stopped)
|
|
289
295
|
return;
|
|
@@ -1915,6 +1921,93 @@ class CodexSession {
|
|
|
1915
1921
|
};
|
|
1916
1922
|
this.emit({ type: 'capabilities', capabilities });
|
|
1917
1923
|
}
|
|
1924
|
+
/**
|
|
1925
|
+
* A pinned model the installed CLI does not have is dropped before it can
|
|
1926
|
+
* fail the session (#374).
|
|
1927
|
+
*
|
|
1928
|
+
* The pin is chosen from a catalogue that was measured the last time an agent
|
|
1929
|
+
* ran on this machine, and the CLI moves underneath it: codex 0.153.4 gained
|
|
1930
|
+
* `gpt-6-astra` and lost `gpt-5.3-codex-spark`, so a machine that had not run
|
|
1931
|
+
* a session since the update was offering — and storing — a model that no
|
|
1932
|
+
* longer exists. `turn/start` does not warn about that, it refuses, and since
|
|
1933
|
+
* the pin is persisted the refusal repeats on every relaunch.
|
|
1934
|
+
*
|
|
1935
|
+
* Asked of `model/list` rather than recognised in an error message: matching
|
|
1936
|
+
* on text is what the retry rules were explicitly moved away from in 0.44.1,
|
|
1937
|
+
* because the wording is the vendor's to change.
|
|
1938
|
+
*
|
|
1939
|
+
* A probe that itself fails changes nothing. Diagnosing the start must not be
|
|
1940
|
+
* able to prevent it — an unreachable `model/list` on a CLI that would have
|
|
1941
|
+
* accepted the model would otherwise cost the user their choice.
|
|
1942
|
+
*/
|
|
1943
|
+
async dropModelTheCliNoLongerHas() {
|
|
1944
|
+
const pinned = this.model;
|
|
1945
|
+
if (!pinned)
|
|
1946
|
+
return;
|
|
1947
|
+
let known;
|
|
1948
|
+
try {
|
|
1949
|
+
known = await this.probeModelIds();
|
|
1950
|
+
}
|
|
1951
|
+
catch (error) {
|
|
1952
|
+
log.warn('codex: could not check the pinned model — leaving it alone', {
|
|
1953
|
+
sessionId: this.spec.sessionId,
|
|
1954
|
+
error: describe(error),
|
|
1955
|
+
});
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
// Only a COMPLETE list can convict a model. An empty answer means this build
|
|
1959
|
+
// does not really implement `model/list`; a truncated one means the answer
|
|
1960
|
+
// continues on a page we did not ask for. Both must read as «no verdict»,
|
|
1961
|
+
// or the check invents an absence and takes the user's choice away.
|
|
1962
|
+
if (!known.complete || known.ids.size === 0)
|
|
1963
|
+
return;
|
|
1964
|
+
if (known.ids.has(pinned))
|
|
1965
|
+
return;
|
|
1966
|
+
delete this.model;
|
|
1967
|
+
// Said out loud, because the session is about to run on a different model
|
|
1968
|
+
// than the one that was picked — silently substituting it would be worse
|
|
1969
|
+
// than the failure this replaces.
|
|
1970
|
+
this.notice('warn', `This server's codex no longer offers ${pinned} — starting on the agent's own default instead.`);
|
|
1971
|
+
// Cleared everywhere, not just here: the API stores the pin and hands it
|
|
1972
|
+
// back in the next relaunch descriptor, so a pin dropped only in memory
|
|
1973
|
+
// comes back on the next restart (the same trap as QA-100 MAJOR-5).
|
|
1974
|
+
//
|
|
1975
|
+
// What the column ends up holding is «nothing pinned» only until the thread
|
|
1976
|
+
// opens: the capabilities frame right after it reports `currentModel`, and
|
|
1977
|
+
// with no pin that is the thread's own model. Either way the invariant the
|
|
1978
|
+
// clearing exists for holds — what is stored is a model this CLI has.
|
|
1979
|
+
this.emit({ type: 'settings', model: null });
|
|
1980
|
+
if (this.effort) {
|
|
1981
|
+
// The level was chosen for a model that is not there. Keeping it would
|
|
1982
|
+
// apply «Ultra» to whatever the CLI defaults to, which may not have it.
|
|
1983
|
+
delete this.effort;
|
|
1984
|
+
this.emit({ type: 'settings', effort: null });
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
/**
|
|
1988
|
+
* Every model id this CLI knows, for the pin check only — including the ones
|
|
1989
|
+
* `listModels()` filters out of the PICKER.
|
|
1990
|
+
*
|
|
1991
|
+
* `hidden` means «do not offer this», not «this does not exist»: codex ships
|
|
1992
|
+
* internal entries like `codex-auto-review` that way, and a pin is not an
|
|
1993
|
+
* offer. Judging a stored pin by the picker's list would delete a model the
|
|
1994
|
+
* CLI still accepts.
|
|
1995
|
+
*
|
|
1996
|
+
* `complete` is false when the answer is paged, and a paged answer proves
|
|
1997
|
+
* nothing about what is missing.
|
|
1998
|
+
*/
|
|
1999
|
+
async probeModelIds() {
|
|
2000
|
+
const result = asRecord(await this.client.request('model/list', { limit: 50 }, 15_000));
|
|
2001
|
+
const data = Array.isArray(result['data']) ? result['data'] : [];
|
|
2002
|
+
const ids = new Set();
|
|
2003
|
+
for (const entry of data) {
|
|
2004
|
+
const row = asRecord(entry);
|
|
2005
|
+
const id = str(row['id']) ?? str(row['model']);
|
|
2006
|
+
if (id)
|
|
2007
|
+
ids.add(id);
|
|
2008
|
+
}
|
|
2009
|
+
return { ids, complete: !str(result['nextCursor']) };
|
|
2010
|
+
}
|
|
1918
2011
|
async listModels() {
|
|
1919
2012
|
const result = asRecord(await this.client.request('model/list', { limit: 50 }, 15_000));
|
|
1920
2013
|
const data = Array.isArray(result['data']) ? result['data'] : [];
|
package/dist/adapters/types.d.ts
CHANGED
|
@@ -406,9 +406,16 @@ export type AgentEvent = {
|
|
|
406
406
|
} | {
|
|
407
407
|
type: 'capabilities';
|
|
408
408
|
capabilities: AgentCapabilities;
|
|
409
|
-
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* `model: null` — the pin is GONE, not merely unchanged: the installed CLI
|
|
412
|
+
* stopped offering it (#374). Spelled like `effort: null` and read the same
|
|
413
|
+
* way by the API, which clears the stored column instead of handing the dead
|
|
414
|
+
* pin back in the next descriptor.
|
|
415
|
+
*/
|
|
416
|
+
| {
|
|
410
417
|
type: 'settings';
|
|
411
|
-
model?: string;
|
|
418
|
+
model?: string | null;
|
|
412
419
|
mode?: AgentMode;
|
|
413
420
|
effort?: string | null;
|
|
414
421
|
} | {
|
package/dist/supervisor.js
CHANGED
|
@@ -2456,7 +2456,13 @@ export class Supervisor {
|
|
|
2456
2456
|
case 'settings':
|
|
2457
2457
|
if (event.mode)
|
|
2458
2458
|
running.mode = event.mode;
|
|
2459
|
-
|
|
2459
|
+
// null = the agent dropped the pinned MODEL, because the installed CLI
|
|
2460
|
+
// stopped offering it (#374). Dropped from the local record too: this
|
|
2461
|
+
// object is what a relaunch inside the same runner process starts from,
|
|
2462
|
+
// so keeping it would re-pin the model the adapter just refused.
|
|
2463
|
+
if (event.model === null)
|
|
2464
|
+
delete running.model;
|
|
2465
|
+
else if (event.model)
|
|
2460
2466
|
running.model = event.model;
|
|
2461
2467
|
// null = the agent dropped the pinned level (model without it) — the
|
|
2462
2468
|
// API must clear its column, so the value is forwarded as-is.
|
|
@@ -2465,7 +2471,7 @@ export class Supervisor {
|
|
|
2465
2471
|
else if (event.effort)
|
|
2466
2472
|
running.effort = event.effort;
|
|
2467
2473
|
this.sendEvent(running, 'settings', {
|
|
2468
|
-
model: event.model,
|
|
2474
|
+
...(event.model === undefined ? {} : { model: event.model }),
|
|
2469
2475
|
mode: event.mode,
|
|
2470
2476
|
...(event.effort === undefined ? {} : { effort: event.effort }),
|
|
2471
2477
|
});
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const RUNNER_VERSION = "0.
|
|
1
|
+
export declare const RUNNER_VERSION = "0.52.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/package.json
CHANGED