@open-mercato/cezar 0.9.1-pr725.892 → 0.9.1-pr726.897
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/README.md +1 -0
- package/dist/agent-config/catalog.d.ts +6 -0
- package/dist/agent-config/catalog.js +17 -0
- package/dist/agent-config/catalog.js.map +1 -1
- package/dist/agent-config/models.d.ts +5 -0
- package/dist/agent-config/models.js +96 -0
- package/dist/agent-config/models.js.map +1 -0
- package/dist/core/agent-model-policy.d.ts +5 -0
- package/dist/core/agent-model-policy.js +8 -0
- package/dist/core/agent-model-policy.js.map +1 -0
- package/dist/core/model-identity.d.ts +4 -3
- package/dist/core/model-identity.js +17 -12
- package/dist/core/model-identity.js.map +1 -1
- package/dist/server/server.d.ts +36 -36
- package/dist/server/server.js +44 -19
- package/dist/server/server.js.map +1 -1
- package/dist/workflows/run.d.ts +16 -3
- package/dist/workflows/run.js +165 -43
- package/dist/workflows/run.js.map +1 -1
- package/package.json +2 -2
- package/web/dist/assets/{compare-variants-BnhCYsfo.js → compare-variants-DXfFTtfr.js} +1 -1
- package/web/dist/assets/{diff-BYWScKEf2.js → diff-CQY9DbEX2.js} +2 -2
- package/web/dist/assets/{diff-view-DQrWNV7l.js → diff-view-D1LKO1xk.js} +1 -1
- package/web/dist/assets/{git-toolbar-BWUVZ6yR.js → git-toolbar-BP1Y3NuC.js} +1 -1
- package/web/dist/assets/{github-Ox8fCBdG.js → github-BpU1rlah.js} +1 -1
- package/web/dist/assets/{index-D-0AJo1h.js → index-CUuvs-FD.js} +4 -4
- package/web/dist/assets/new-task-form-B-ifwpi0.js +1 -0
- package/web/dist/assets/{repo-git-CKp7XJDH.js → repo-git-3NyrzWNb.js} +1 -1
- package/web/dist/assets/{run-diff-Dclf6QqY.js → run-diff-BSEQ5brJ.js} +1 -1
- package/web/dist/assets/{run-header-DqjqwW-M.js → run-header-BIRLEI8K.js} +1 -1
- package/web/dist/assets/{skills-B6JggT7B.js → skills-CO8z1733.js} +1 -1
- package/web/dist/assets/{task-changes-D3WZw6Wm.js → task-changes-CylE3sZ0.js} +1 -1
- package/web/dist/assets/{task-commits-kzQcMB61.js → task-commits-D9u9HWm3.js} +1 -1
- package/web/dist/assets/{task-files-BuEzgMvG.js → task-files-nYjxrDpA.js} +1 -1
- package/web/dist/assets/{task-thread-YqnMa71e.js → task-thread-oz1-VMfl.js} +2 -2
- package/web/dist/assets/{use-desktop-CRwfloSK.js → use-desktop-FJpraByx.js} +1 -1
- package/web/dist/assets/{workflows-FiXcWMoj.js → workflows-BDnGBDS2.js} +1 -1
- package/web/dist/index.html +2 -2
- package/web/dist/assets/new-task-form-umhQeDuQ.js +0 -1
package/README.md
CHANGED
|
@@ -426,6 +426,7 @@ Useful environment variables:
|
|
|
426
426
|
| Var | Effect |
|
|
427
427
|
|---|---|
|
|
428
428
|
| `CEZ_DRY_RUN=1` | Use the bundled mock instead of the real `claude` CLI — the entire cockpit works offline, for demos and development. |
|
|
429
|
+
| `CEZ_AGENT_MODELS_LOCKED=1` | Lock model selection to the models configured in native Claude/Codex/OpenCode settings. Existing Cezar presets are preserved but ignored; only `1` enables it, and a restart is required. |
|
|
429
430
|
| `CEZ_APPROVAL_GATE=1` | Opt into Claude's interactive approval UI; by default, unapproved tools are denied without interrupting the run. |
|
|
430
431
|
| `CEZ_FOLLOWUPS=1` | Turn on the global follow-up **Inbox**: agents are asked to leave follow-ups in `todos.json` when they finish, and the Inbox view appears. Off by default — each task's own **Notes** handoff journal runs either way. |
|
|
431
432
|
| `CEZ_AUTOSAVE=1` | Re-enable the periodic (90 s) autosave commit in task worktrees. Off by default (#471) — turn-end and pre-PR flushes always run, so branches still end complete. Every autosave names its trigger in the commit subject (`cezar autosave (periodic)` vs `(turn end)` / `(run finalize)` / `(pre-PR)`), so the flushes you keep are distinguishable from the timer you disabled. |
|
|
@@ -47,6 +47,12 @@ export interface ConfigFileDef {
|
|
|
47
47
|
seeded?: boolean;
|
|
48
48
|
/** True when this file holds MCP server definitions (drives the MCP section's filter). */
|
|
49
49
|
holdsMcp?: boolean;
|
|
50
|
+
/** Top-level native setting that supplies the agent's new-session model, when present. */
|
|
51
|
+
modelKey?: string;
|
|
52
|
+
/** Native model keys checked in precedence order, including nested `env.*` settings. */
|
|
53
|
+
modelKeys?: readonly string[];
|
|
54
|
+
/** Higher values win when resolving a native default model across config scopes. */
|
|
55
|
+
modelPriority?: number;
|
|
50
56
|
/** VERBATIM from the vendor docs. Never computed, never generic. */
|
|
51
57
|
precedence: string;
|
|
52
58
|
/** Documented mid-run reload behaviour, or undefined when the vendor is silent. */
|
|
@@ -21,6 +21,9 @@ export const CONFIG_FILES = [
|
|
|
21
21
|
label: '~/.claude/settings.json',
|
|
22
22
|
format: 'json',
|
|
23
23
|
tracked: 'outside-repo',
|
|
24
|
+
modelKey: 'model',
|
|
25
|
+
modelKeys: ['env.ANTHROPIC_MODEL', 'model'],
|
|
26
|
+
modelPriority: 1,
|
|
24
27
|
precedence: 'Lowest priority. Project and local settings override it key by key — except permission rules, which merge across all scopes.',
|
|
25
28
|
hotReload: 'Edits to most keys — including permissions and hooks — apply to a running session without a restart.',
|
|
26
29
|
docsUrl: CLAUDE_SETTINGS_DOCS,
|
|
@@ -34,6 +37,9 @@ export const CONFIG_FILES = [
|
|
|
34
37
|
label: '.claude/settings.json',
|
|
35
38
|
format: 'json',
|
|
36
39
|
tracked: 'tracked',
|
|
40
|
+
modelKey: 'model',
|
|
41
|
+
modelKeys: ['env.ANTHROPIC_MODEL', 'model'],
|
|
42
|
+
modelPriority: 2,
|
|
37
43
|
precedence: 'Overrides user settings key by key (permission rules merge). Local settings override this.',
|
|
38
44
|
hotReload: 'Edits to most keys — including permissions and hooks — apply to a running session without a restart.',
|
|
39
45
|
docsUrl: CLAUDE_SETTINGS_DOCS,
|
|
@@ -48,6 +54,9 @@ export const CONFIG_FILES = [
|
|
|
48
54
|
format: 'json',
|
|
49
55
|
tracked: 'gitignored',
|
|
50
56
|
seeded: true,
|
|
57
|
+
modelKey: 'model',
|
|
58
|
+
modelKeys: ['env.ANTHROPIC_MODEL', 'model'],
|
|
59
|
+
modelPriority: 3,
|
|
51
60
|
precedence: 'Highest of the file scopes — overrides project and user (permission rules merge). Git-ignored; copied into each run’s worktree so it takes effect immediately.',
|
|
52
61
|
hotReload: 'Edits to most keys — including permissions and hooks — apply to a running session without a restart.',
|
|
53
62
|
docsUrl: CLAUDE_SETTINGS_DOCS,
|
|
@@ -113,6 +122,8 @@ export const CONFIG_FILES = [
|
|
|
113
122
|
format: 'toml',
|
|
114
123
|
tracked: 'outside-repo',
|
|
115
124
|
holdsMcp: true,
|
|
125
|
+
modelKey: 'model',
|
|
126
|
+
modelPriority: 1,
|
|
116
127
|
precedence: 'User-level defaults. A trusted project’s .codex/config.toml overrides these; some keys (provider, auth, telemetry) cannot be overridden at project scope. MCP servers live here under [mcp_servers.<id>].',
|
|
117
128
|
docsUrl: CODEX_CONFIG_DOCS,
|
|
118
129
|
},
|
|
@@ -125,6 +136,8 @@ export const CONFIG_FILES = [
|
|
|
125
136
|
label: '.codex/config.toml',
|
|
126
137
|
format: 'toml',
|
|
127
138
|
tracked: 'tracked',
|
|
139
|
+
modelKey: 'model',
|
|
140
|
+
modelPriority: 2,
|
|
128
141
|
holdsMcp: true,
|
|
129
142
|
precedence: 'Applies only in projects you have trusted. Some keys (provider, auth, telemetry) cannot be overridden here. MCP servers go under [mcp_servers.<id>]. Runs read the committed copy.',
|
|
130
143
|
docsUrl: CODEX_CONFIG_DOCS,
|
|
@@ -152,6 +165,8 @@ export const CONFIG_FILES = [
|
|
|
152
165
|
format: 'jsonc',
|
|
153
166
|
tracked: 'outside-repo',
|
|
154
167
|
holdsMcp: true,
|
|
168
|
+
modelKey: 'model',
|
|
169
|
+
modelPriority: 1,
|
|
155
170
|
precedence: 'Global config. Merged with the project config, not replaced — later configs override earlier ones only for conflicting keys. MCP servers live under the "mcp" key.',
|
|
156
171
|
docsUrl: OPENCODE_CONFIG_DOCS,
|
|
157
172
|
},
|
|
@@ -165,6 +180,8 @@ export const CONFIG_FILES = [
|
|
|
165
180
|
format: 'jsonc',
|
|
166
181
|
tracked: 'tracked',
|
|
167
182
|
holdsMcp: true,
|
|
183
|
+
modelKey: 'model',
|
|
184
|
+
modelPriority: 2,
|
|
168
185
|
precedence: 'Merged over the global config per conflicting key (not a wholesale replace). MCP servers live under the "mcp" key. Runs read the committed copy.',
|
|
169
186
|
docsUrl: OPENCODE_CONFIG_DOCS,
|
|
170
187
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/agent-config/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/agent-config/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RunnerId } from '../core/agent-runner.js';
|
|
2
|
+
/** The model defaults exposed by the coding agents' own settings files. */
|
|
3
|
+
export type AgentModelDefaults = Partial<Record<RunnerId, string>>;
|
|
4
|
+
/** Read the current default model for each installed/configured coding agent. */
|
|
5
|
+
export declare function readAgentModelDefaults(repoRoot: string, env?: NodeJS.ProcessEnv): Promise<AgentModelDefaults>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { parse as parseToml } from 'smol-toml';
|
|
2
|
+
import { CONFIG_FILES } from './catalog.js';
|
|
3
|
+
import { readConfigFile } from './files.js';
|
|
4
|
+
import { stripJsonComments } from './validate.js';
|
|
5
|
+
/**
|
|
6
|
+
* Native settings are read in the same order in which each agent applies them:
|
|
7
|
+
* the first valid model wins. Cezar deliberately only reads the settings files
|
|
8
|
+
* it already exposes in Settings → Agent config; managed/CLI/environment
|
|
9
|
+
* overrides stay with the agent process itself.
|
|
10
|
+
*/
|
|
11
|
+
/** Remove JSONC trailing commas without touching commas inside string values. */
|
|
12
|
+
function stripJsonTrailingCommas(input) {
|
|
13
|
+
let out = '';
|
|
14
|
+
let inString = false;
|
|
15
|
+
let escaped = false;
|
|
16
|
+
for (let i = 0; i < input.length; i++) {
|
|
17
|
+
const ch = input[i];
|
|
18
|
+
if (inString) {
|
|
19
|
+
out += ch;
|
|
20
|
+
if (escaped)
|
|
21
|
+
escaped = false;
|
|
22
|
+
else if (ch === '\\')
|
|
23
|
+
escaped = true;
|
|
24
|
+
else if (ch === '"')
|
|
25
|
+
inString = false;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (ch === '"') {
|
|
29
|
+
inString = true;
|
|
30
|
+
out += ch;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (ch === ',') {
|
|
34
|
+
let next = i + 1;
|
|
35
|
+
while (/\s/.test(input[next] ?? ''))
|
|
36
|
+
next++;
|
|
37
|
+
if (input[next] === '}' || input[next] === ']')
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
out += ch;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
function valueAtPath(value, path) {
|
|
45
|
+
return path.split('.').reduce((current, segment) => {
|
|
46
|
+
if (!current || typeof current !== 'object' || Array.isArray(current))
|
|
47
|
+
return undefined;
|
|
48
|
+
return current[segment];
|
|
49
|
+
}, value);
|
|
50
|
+
}
|
|
51
|
+
function modelFromContent(content, format, keys) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = format === 'toml'
|
|
54
|
+
? parseToml(content)
|
|
55
|
+
: JSON.parse(format === 'jsonc' ? stripJsonTrailingCommas(stripJsonComments(content)) : content);
|
|
56
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
57
|
+
return undefined;
|
|
58
|
+
for (const key of keys) {
|
|
59
|
+
const model = valueAtPath(parsed, key);
|
|
60
|
+
if (typeof model === 'string' && model.trim())
|
|
61
|
+
return model.trim();
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// A malformed higher-precedence file must not prevent a usable lower-level
|
|
67
|
+
// default from appearing in the cockpit.
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function readRunnerModel(runner, repoRoot, env) {
|
|
72
|
+
// Claude Code gives ANTHROPIC_MODEL higher priority than settings-file values.
|
|
73
|
+
// The terminal and cezar must therefore agree when the model is configured in
|
|
74
|
+
// the shell that launched the server.
|
|
75
|
+
if (runner === 'claude' && env.ANTHROPIC_MODEL?.trim())
|
|
76
|
+
return env.ANTHROPIC_MODEL.trim();
|
|
77
|
+
const modelFiles = CONFIG_FILES.filter((def) => def.kind === 'settings' &&
|
|
78
|
+
def.runners.includes(runner) &&
|
|
79
|
+
def.modelKey !== undefined &&
|
|
80
|
+
def.modelPriority !== undefined).sort((a, b) => (b.modelPriority ?? 0) - (a.modelPriority ?? 0));
|
|
81
|
+
for (const def of modelFiles) {
|
|
82
|
+
const file = await readConfigFile(def.id, repoRoot, env);
|
|
83
|
+
if (!file || 'error' in file || !file.exists)
|
|
84
|
+
continue;
|
|
85
|
+
const model = modelFromContent(file.content, def.format, def.modelKeys ?? [def.modelKey]);
|
|
86
|
+
if (model)
|
|
87
|
+
return model;
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
/** Read the current default model for each installed/configured coding agent. */
|
|
92
|
+
export async function readAgentModelDefaults(repoRoot, env = process.env) {
|
|
93
|
+
const entries = await Promise.all(['claude', 'codex', 'opencode'].map(async (runner) => [runner, await readRunnerModel(runner, repoRoot, env)]));
|
|
94
|
+
return Object.fromEntries(entries.filter((entry) => entry[1] !== undefined));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/agent-config/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The server-side switch that makes native agent settings authoritative. */
|
|
2
|
+
export declare const AGENT_MODELS_LOCKED_ENV = "CEZ_AGENT_MODELS_LOCKED";
|
|
3
|
+
/** Only the exact value `1` enables the lock; unset keeps the current behavior. */
|
|
4
|
+
export declare function agentModelsLocked(env?: NodeJS.ProcessEnv): boolean;
|
|
5
|
+
export declare const AGENT_MODELS_LOCKED_ERROR = "agent models are locked \u2014 configure the model in the native coding-agent settings";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The server-side switch that makes native agent settings authoritative. */
|
|
2
|
+
export const AGENT_MODELS_LOCKED_ENV = 'CEZ_AGENT_MODELS_LOCKED';
|
|
3
|
+
/** Only the exact value `1` enables the lock; unset keeps the current behavior. */
|
|
4
|
+
export function agentModelsLocked(env = process.env) {
|
|
5
|
+
return env[AGENT_MODELS_LOCKED_ENV] === '1';
|
|
6
|
+
}
|
|
7
|
+
export const AGENT_MODELS_LOCKED_ERROR = 'agent models are locked — configure the model in the native coding-agent settings';
|
|
8
|
+
//# sourceMappingURL=agent-model-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-model-policy.js","sourceRoot":"","sources":["../../src/core/agent-model-policy.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACpE,OAAO,GAAG,CAAC,uBAAuB,CAAC,KAAK,GAAG,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GACpC,mFAAmF,CAAC"}
|
|
@@ -54,6 +54,8 @@ interface BackendModelMap {
|
|
|
54
54
|
* It also selects the wire form in {@link toBackendModel}.
|
|
55
55
|
*/
|
|
56
56
|
readonly defaultProvider?: string;
|
|
57
|
+
/** Whether explicit foreign provider/model ids are valid backend-native ids. */
|
|
58
|
+
readonly allowExplicitProvider?: boolean;
|
|
57
59
|
/**
|
|
58
60
|
* Bare model id → provider override, for the rare backend whose bare ids
|
|
59
61
|
* span providers. Checked before `defaultProvider`; empty for today's set.
|
|
@@ -84,9 +86,8 @@ export declare function parseModelIdentity(raw: string | undefined | null): Mode
|
|
|
84
86
|
* explicit choice, not a silent fallback);
|
|
85
87
|
* - an explicit `provider/model` → that identity, for a multi-provider backend
|
|
86
88
|
* or when the provider is the single-provider backend's own;
|
|
87
|
-
* - an explicit `provider/model` naming a FOREIGN provider
|
|
88
|
-
* backend
|
|
89
|
-
* yet persisted, asserting a provider that never ran — #405 review M2);
|
|
89
|
+
* - an explicit `provider/model` naming a FOREIGN provider is preserved when
|
|
90
|
+
* the backend supports custom/gateway model ids;
|
|
90
91
|
* - a bare id → the backend's default provider;
|
|
91
92
|
* - a bare id on a backend with no default provider → throws
|
|
92
93
|
* {@link ModelIdentityError}.
|
|
@@ -22,8 +22,10 @@ export const KNOWN_PROVIDERS = ['anthropic', 'openai', 'google', 'openrouter'];
|
|
|
22
22
|
* to `claude`.
|
|
23
23
|
*/
|
|
24
24
|
export const BACKEND_MODEL_MAP = {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
// Claude Code supports custom/gateway model ids such as DeepSeek via an
|
|
26
|
+
// Anthropic-compatible endpoint, so preserve an explicit provider/model.
|
|
27
|
+
claude: { defaultProvider: 'anthropic', allowExplicitProvider: true },
|
|
28
|
+
'claude-cli': { defaultProvider: 'anthropic', allowExplicitProvider: true },
|
|
27
29
|
codex: { defaultProvider: 'openai' },
|
|
28
30
|
// opencode selects across providers, so a bare model is ambiguous: reject it
|
|
29
31
|
// loudly rather than let the server pick a default the user never asked for.
|
|
@@ -59,9 +61,8 @@ export function parseModelIdentity(raw) {
|
|
|
59
61
|
* explicit choice, not a silent fallback);
|
|
60
62
|
* - an explicit `provider/model` → that identity, for a multi-provider backend
|
|
61
63
|
* or when the provider is the single-provider backend's own;
|
|
62
|
-
* - an explicit `provider/model` naming a FOREIGN provider
|
|
63
|
-
* backend
|
|
64
|
-
* yet persisted, asserting a provider that never ran — #405 review M2);
|
|
64
|
+
* - an explicit `provider/model` naming a FOREIGN provider is preserved when
|
|
65
|
+
* the backend supports custom/gateway model ids;
|
|
65
66
|
* - a bare id → the backend's default provider;
|
|
66
67
|
* - a bare id on a backend with no default provider → throws
|
|
67
68
|
* {@link ModelIdentityError}.
|
|
@@ -72,12 +73,12 @@ export function resolveModelIdentity(backend, raw) {
|
|
|
72
73
|
const map = BACKEND_MODEL_MAP[backend] ?? {};
|
|
73
74
|
const explicit = parseModelIdentity(raw);
|
|
74
75
|
if (explicit) {
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// Most single-provider backends need their bare wire form, but Claude Code
|
|
77
|
+
// also accepts explicit gateway/custom provider ids. Keep rejecting foreign
|
|
78
|
+
// providers for backends that do not advertise that capability.
|
|
79
|
+
if (map.defaultProvider !== undefined &&
|
|
80
|
+
explicit.provider !== map.defaultProvider &&
|
|
81
|
+
!map.allowExplicitProvider) {
|
|
81
82
|
throw new ModelIdentityError(`provider "${explicit.provider}" can't be served by the ${backend} runner (serves ${map.defaultProvider}) — use "${map.defaultProvider}/${explicit.model}" or a bare model id`);
|
|
82
83
|
}
|
|
83
84
|
return explicit;
|
|
@@ -98,7 +99,11 @@ export function resolveModelIdentity(backend, raw) {
|
|
|
98
99
|
*/
|
|
99
100
|
export function toBackendModel(backend, id) {
|
|
100
101
|
const map = BACKEND_MODEL_MAP[backend] ?? {};
|
|
101
|
-
|
|
102
|
+
if (map.defaultProvider === undefined)
|
|
103
|
+
return formatModelIdentity(id);
|
|
104
|
+
if (map.allowExplicitProvider && id.provider !== map.defaultProvider)
|
|
105
|
+
return formatModelIdentity(id);
|
|
106
|
+
return id.model;
|
|
102
107
|
}
|
|
103
108
|
/**
|
|
104
109
|
* Normalise a raw model string for `backend` in one step: the backend-native
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-identity.js","sourceRoot":"","sources":["../../src/core/model-identity.ts"],"names":[],"mappings":"AAkCA;;;;;GAKG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"model-identity.js","sourceRoot":"","sources":["../../src/core/model-identity.ts"],"names":[],"mappings":"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"}
|
package/dist/server/server.d.ts
CHANGED
|
@@ -306,10 +306,14 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
306
306
|
"/agent-config/:id": {
|
|
307
307
|
$put: {
|
|
308
308
|
output: {
|
|
309
|
-
|
|
309
|
+
id: string;
|
|
310
|
+
path: string;
|
|
311
|
+
exists: boolean;
|
|
312
|
+
content: string;
|
|
313
|
+
version: string | null;
|
|
310
314
|
};
|
|
311
315
|
outputFormat: "json";
|
|
312
|
-
status:
|
|
316
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
313
317
|
input: {
|
|
314
318
|
param: {
|
|
315
319
|
id: string;
|
|
@@ -317,14 +321,10 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
317
321
|
};
|
|
318
322
|
} | {
|
|
319
323
|
output: {
|
|
320
|
-
|
|
321
|
-
path: string;
|
|
322
|
-
exists: boolean;
|
|
323
|
-
content: string;
|
|
324
|
-
version: string | null;
|
|
324
|
+
error: string;
|
|
325
325
|
};
|
|
326
326
|
outputFormat: "json";
|
|
327
|
-
status:
|
|
327
|
+
status: 404;
|
|
328
328
|
input: {
|
|
329
329
|
param: {
|
|
330
330
|
id: string;
|
|
@@ -381,14 +381,6 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
381
381
|
} & {
|
|
382
382
|
"/workflows": {
|
|
383
383
|
$post: {
|
|
384
|
-
output: {
|
|
385
|
-
path: string;
|
|
386
|
-
name: string;
|
|
387
|
-
};
|
|
388
|
-
outputFormat: "json";
|
|
389
|
-
status: 201;
|
|
390
|
-
input: {};
|
|
391
|
-
} | {
|
|
392
384
|
output: {
|
|
393
385
|
error: string;
|
|
394
386
|
};
|
|
@@ -410,6 +402,14 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
410
402
|
outputFormat: "json";
|
|
411
403
|
status: 500;
|
|
412
404
|
input: {};
|
|
405
|
+
} | {
|
|
406
|
+
output: {
|
|
407
|
+
path: string;
|
|
408
|
+
name: string;
|
|
409
|
+
};
|
|
410
|
+
outputFormat: "json";
|
|
411
|
+
status: 201;
|
|
412
|
+
input: {};
|
|
413
413
|
};
|
|
414
414
|
};
|
|
415
415
|
} & {
|
|
@@ -419,7 +419,7 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
419
419
|
error: string;
|
|
420
420
|
};
|
|
421
421
|
outputFormat: "json";
|
|
422
|
-
status:
|
|
422
|
+
status: 404;
|
|
423
423
|
input: {
|
|
424
424
|
param: {
|
|
425
425
|
name: string;
|
|
@@ -430,7 +430,7 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
430
430
|
error: string;
|
|
431
431
|
};
|
|
432
432
|
outputFormat: "json";
|
|
433
|
-
status:
|
|
433
|
+
status: 400;
|
|
434
434
|
input: {
|
|
435
435
|
param: {
|
|
436
436
|
name: string;
|
|
@@ -583,10 +583,14 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
583
583
|
"/agent-config/:id": {
|
|
584
584
|
$put: {
|
|
585
585
|
output: {
|
|
586
|
-
|
|
586
|
+
id: string;
|
|
587
|
+
path: string;
|
|
588
|
+
exists: boolean;
|
|
589
|
+
content: string;
|
|
590
|
+
version: string | null;
|
|
587
591
|
};
|
|
588
592
|
outputFormat: "json";
|
|
589
|
-
status:
|
|
593
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
590
594
|
input: {
|
|
591
595
|
param: {
|
|
592
596
|
id: string;
|
|
@@ -594,14 +598,10 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
594
598
|
};
|
|
595
599
|
} | {
|
|
596
600
|
output: {
|
|
597
|
-
|
|
598
|
-
path: string;
|
|
599
|
-
exists: boolean;
|
|
600
|
-
content: string;
|
|
601
|
-
version: string | null;
|
|
601
|
+
error: string;
|
|
602
602
|
};
|
|
603
603
|
outputFormat: "json";
|
|
604
|
-
status:
|
|
604
|
+
status: 404;
|
|
605
605
|
input: {
|
|
606
606
|
param: {
|
|
607
607
|
id: string;
|
|
@@ -658,14 +658,6 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
658
658
|
} & {
|
|
659
659
|
"/workflows": {
|
|
660
660
|
$post: {
|
|
661
|
-
output: {
|
|
662
|
-
path: string;
|
|
663
|
-
name: string;
|
|
664
|
-
};
|
|
665
|
-
outputFormat: "json";
|
|
666
|
-
status: 201;
|
|
667
|
-
input: {};
|
|
668
|
-
} | {
|
|
669
661
|
output: {
|
|
670
662
|
error: string;
|
|
671
663
|
};
|
|
@@ -687,6 +679,14 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
687
679
|
outputFormat: "json";
|
|
688
680
|
status: 500;
|
|
689
681
|
input: {};
|
|
682
|
+
} | {
|
|
683
|
+
output: {
|
|
684
|
+
path: string;
|
|
685
|
+
name: string;
|
|
686
|
+
};
|
|
687
|
+
outputFormat: "json";
|
|
688
|
+
status: 201;
|
|
689
|
+
input: {};
|
|
690
690
|
};
|
|
691
691
|
};
|
|
692
692
|
} & {
|
|
@@ -696,7 +696,7 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
696
696
|
error: string;
|
|
697
697
|
};
|
|
698
698
|
outputFormat: "json";
|
|
699
|
-
status:
|
|
699
|
+
status: 404;
|
|
700
700
|
input: {
|
|
701
701
|
param: {
|
|
702
702
|
name: string;
|
|
@@ -707,7 +707,7 @@ export declare function createApp(deps: ServerDeps): import("hono/hono-base").Ho
|
|
|
707
707
|
error: string;
|
|
708
708
|
};
|
|
709
709
|
outputFormat: "json";
|
|
710
|
-
status:
|
|
710
|
+
status: 400;
|
|
711
711
|
input: {
|
|
712
712
|
param: {
|
|
713
713
|
name: string;
|
package/dist/server/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import { streamSSE } from 'hono/streaming';
|
|
|
9
9
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { detectEnvironment } from '../core/backend-detect.js';
|
|
12
|
+
import { AGENT_MODELS_LOCKED_ERROR, agentModelsLocked } from '../core/agent-model-policy.js';
|
|
12
13
|
import { discoverCodexModels } from '../core/codex-model-catalog.js';
|
|
13
14
|
import { PROVIDER_IDS, ProviderAuthService, } from '../core/provider-auth.js';
|
|
14
15
|
import { applyProviderEnablement } from '../core/provider-availability.js';
|
|
@@ -30,6 +31,7 @@ import { collectChanges, collectCommitChanges, collectRunCommits, commitAll, cre
|
|
|
30
31
|
import { gatedSkillsRepos, loadConfig, resolveWorktreeRetention } from '../config.js';
|
|
31
32
|
import { findConfigFile } from '../agent-config/catalog.js';
|
|
32
33
|
import { readConfigFile, writeConfigFile } from '../agent-config/files.js';
|
|
34
|
+
import { readAgentModelDefaults } from '../agent-config/models.js';
|
|
33
35
|
import { listAgentConfig } from '../agent-config/service.js';
|
|
34
36
|
import { PROJECT_ID_RE, defaultWorkspaceConfig, effectiveSkillsAutoUpdate, loadWorkspaceConfig, mergeWriteWorkspaceConfig, effectiveComposerDefault, } from '../workspace/config.js';
|
|
35
37
|
import { allocateProjectSlug, listProjects, probeProjectStatus, registerProject, removeProject, shouldRegisterProject, } from '../workspace/projects.js';
|
|
@@ -1942,6 +1944,9 @@ export function createApp(deps) {
|
|
|
1942
1944
|
if (!parsed.success) {
|
|
1943
1945
|
return c.json({ error: parsed.error.issues.map((i) => i.message).join('; ') }, 400);
|
|
1944
1946
|
}
|
|
1947
|
+
if (agentModelsLocked() && parsed.data?.model?.trim()) {
|
|
1948
|
+
return c.json({ error: AGENT_MODELS_LOCKED_ERROR }, 409);
|
|
1949
|
+
}
|
|
1945
1950
|
let workflow;
|
|
1946
1951
|
if (parsed.data.steps) {
|
|
1947
1952
|
// Inline chain (spec 008): an approved plan runs as an ad-hoc workflow.
|
|
@@ -2293,6 +2298,9 @@ export function createApp(deps) {
|
|
|
2293
2298
|
if (!parsed.success) {
|
|
2294
2299
|
return c.json({ error: parsed.error.issues.map((i) => i.message).join('; ') }, 400);
|
|
2295
2300
|
}
|
|
2301
|
+
if (agentModelsLocked() && parsed.data?.model?.trim()) {
|
|
2302
|
+
return c.json({ error: AGENT_MODELS_LOCKED_ERROR }, 409);
|
|
2303
|
+
}
|
|
2296
2304
|
const blocked = await providerActionError([providerForExistingRun(run, parsed.data.runner)]);
|
|
2297
2305
|
if (blocked)
|
|
2298
2306
|
return c.json({ error: blocked }, 409);
|
|
@@ -2768,6 +2776,9 @@ export function createApp(deps) {
|
|
|
2768
2776
|
if (!parsed.success) {
|
|
2769
2777
|
return c.json({ error: parsed.error.issues.map((i) => i.message).join('; ') }, 400);
|
|
2770
2778
|
}
|
|
2779
|
+
if (agentModelsLocked() && parsed.data?.model?.trim()) {
|
|
2780
|
+
return c.json({ error: AGENT_MODELS_LOCKED_ERROR }, 409);
|
|
2781
|
+
}
|
|
2771
2782
|
if (todo.startedTaskId)
|
|
2772
2783
|
return c.json({ error: 'already started' }, 409);
|
|
2773
2784
|
let task = todoTaskText(todo);
|
|
@@ -3168,24 +3179,35 @@ export function createApp(deps) {
|
|
|
3168
3179
|
});
|
|
3169
3180
|
// The Settings → Agents knobs in one read (R6 Step 1.5) — an ADDITIVE
|
|
3170
3181
|
// sibling of PUT /api/config below; /api/health keeps its protected shape.
|
|
3171
|
-
const configAnswer = (config) =>
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3182
|
+
const configAnswer = async (repoRoot, config) => {
|
|
3183
|
+
const nativeModels = await readAgentModelDefaults(repoRoot);
|
|
3184
|
+
return {
|
|
3185
|
+
baseBranch: config.baseBranch ?? null,
|
|
3186
|
+
defaultRunner: config.defaultRunner,
|
|
3187
|
+
systemPrompt: config.systemPrompt ?? null,
|
|
3188
|
+
// Native settings are the initial/default source. In locked mode they are
|
|
3189
|
+
// authoritative; otherwise a Cezar preset remains an explicit override.
|
|
3190
|
+
defaultModels: agentModelsLocked()
|
|
3191
|
+
? nativeModels
|
|
3192
|
+
: { ...nativeModels, ...(config.defaultModels ?? {}) },
|
|
3193
|
+
modelsLocked: agentModelsLocked(),
|
|
3194
|
+
maxParallel: config.maxParallel,
|
|
3195
|
+
memoryLimitMb: config.memoryLimitMb ?? null,
|
|
3196
|
+
// Count-based worktree retention (#483): keep the last N finished worktrees
|
|
3197
|
+
// on disk. 0 = unlimited. Always materialized (schema default 10).
|
|
3198
|
+
worktreeRetention: config.worktreeRetention,
|
|
3199
|
+
// Live title updates (task auto-naming spec): tri-state — null means "no
|
|
3200
|
+
// config key, the CEZ_TITLE_UPDATES env default (ON) decides".
|
|
3201
|
+
liveTitleUpdates: config.liveTitleUpdates ?? null,
|
|
3202
|
+
// Optional review gate (#489): tri-state — null means "no config key, the
|
|
3203
|
+
// CEZ_REVIEW_GATE env default (OFF) decides".
|
|
3204
|
+
reviewGate: config.reviewGate ?? null,
|
|
3205
|
+
};
|
|
3206
|
+
};
|
|
3207
|
+
api.get('/config', async (c) => {
|
|
3208
|
+
const repoRoot = c.get('project').root;
|
|
3209
|
+
return c.json(await configAnswer(repoRoot, await loadConfig(repoRoot)));
|
|
3210
|
+
});
|
|
3189
3211
|
// Set/clear the agents' config knobs (Settings → Agents; the Repo tab's
|
|
3190
3212
|
// base-branch picker). Merges into the RAW config.json so user keys
|
|
3191
3213
|
// (skillsRepos…) survive and schema defaults are never materialized into
|
|
@@ -3224,6 +3246,9 @@ export function createApp(deps) {
|
|
|
3224
3246
|
if (!parsed.success) {
|
|
3225
3247
|
return c.json({ error: parsed.error.issues.map((i) => i.message).join('; ') }, 400);
|
|
3226
3248
|
}
|
|
3249
|
+
if (agentModelsLocked() && parsed.data.defaultModels !== undefined) {
|
|
3250
|
+
return c.json({ error: AGENT_MODELS_LOCKED_ERROR }, 409);
|
|
3251
|
+
}
|
|
3227
3252
|
const configPath = join(dataDir, 'config.json');
|
|
3228
3253
|
let raw = {};
|
|
3229
3254
|
try {
|
|
@@ -3308,7 +3333,7 @@ export function createApp(deps) {
|
|
|
3308
3333
|
return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
3309
3334
|
}
|
|
3310
3335
|
// Pre-R6 answer shape ({baseBranch, defaultRunner}) + additive R6 fields.
|
|
3311
|
-
return c.json(configAnswer(await loadConfig(repoRoot)));
|
|
3336
|
+
return c.json(await configAnswer(repoRoot, await loadConfig(repoRoot)));
|
|
3312
3337
|
});
|
|
3313
3338
|
const setAgentConfigSchema = z.object({
|
|
3314
3339
|
content: z.string().max(2_000_000),
|