@circuitwall/jarela 2.2.0 → 2.2.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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +2 -2
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +61 -20
- package/.next/standalone/.next/server/app/api/v1/models/route.js +5 -3
- package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +27 -24
- package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page.js +313 -251
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +2 -2
- package/.next/standalone/.next/server/chunks/2471.js +17 -17
- package/.next/standalone/.next/server/chunks/2563.js +24 -50
- package/.next/standalone/.next/server/chunks/3399.js +10695 -10695
- package/.next/standalone/.next/server/chunks/3524.js +5 -33
- package/.next/standalone/.next/server/chunks/424.js +10 -5
- package/.next/standalone/.next/server/chunks/4508.js +2 -2
- package/.next/standalone/.next/server/chunks/46.js +111 -46
- package/.next/standalone/.next/server/chunks/466.js +88 -13
- package/.next/standalone/.next/server/chunks/6649.js +1 -1
- package/.next/standalone/.next/server/chunks/9590.js +108 -46
- package/.next/standalone/.next/server/chunks/9640.js +3 -6
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/middleware.js +104 -45
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/preview-props.json +3 -3
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{1395-f201e3e2e1f57715.js → 1395-a340fb0a345382a4.js} +89 -14
- package/.next/standalone/.next/static/chunks/{4576-13f7546a145a3624.js → 7045-8bc2f14e430ca661.js} +58 -2
- package/.next/standalone/.next/static/chunks/app/{page-c6e972a7fd13dae8.js → page-7017f07f8a7a083c.js} +170 -151
- package/.next/standalone/package.json +1 -1
- package/CHANGELOG.md +8 -0
- package/api/client.models.test.ts +31 -0
- package/api/client.ts +16 -1
- package/api/types.ts +8 -0
- package/app/api/v1/models/[name]/route.test.ts +89 -0
- package/app/api/v1/models/[name]/route.ts +54 -3
- package/app/api/v1/models/route.ts +4 -2
- package/app/api/v1/providers/[provider]/models/route.test.ts +53 -0
- package/app/api/v1/providers/[provider]/models/route.ts +27 -16
- package/components/agents/agent-editor/AdvancedSection.tsx +8 -2
- package/components/agents/agent-editor/ModelSection.tsx +6 -3
- package/components/models/ModelEditor.tsx +1 -1
- package/components/models/ModelsPanel.tsx +34 -8
- package/components/models/model-editor/GitHubCopilotAuth.tsx +1 -1
- package/components/models/model-editor/save-helpers.ts +2 -2
- package/components/models/model-editor/useModelEditorForm.ts +1 -1
- package/components/models/model-editor/useModelSaveHandlers.ts +1 -1
- package/components/setup/wizard/StepCredentials.tsx +1 -1
- package/components/setup/wizard/StepModel.tsx +3 -8
- package/hooks/useModels.ts +17 -1
- package/lib/agents/effective-model.test.ts +45 -0
- package/lib/agents/effective-model.ts +11 -5
- package/lib/agents/llm.ts +2 -2
- package/lib/agents/run-thread.ts +10 -5
- package/lib/agents/warm-summary-background.test.ts +1 -2
- package/lib/agents/warm-summary-background.ts +4 -7
- package/lib/db/migrations.ts +10 -0
- package/lib/health/probes.test.ts +8 -11
- package/lib/health/probes.ts +5 -31
- package/lib/models/editor-payload.ts +1 -1
- package/lib/providers/github-copilot-auth.ts +2 -3
- package/lib/providers/github-copilot.test.ts +27 -0
- package/lib/providers/github-copilot.ts +21 -44
- package/lib/stores/integrations.test.ts +7 -0
- package/lib/stores/integrations.ts +4 -4
- package/lib/stores/model-config.test.ts +88 -0
- package/lib/stores/model-config.ts +90 -8
- package/package.json +1 -1
- /package/.next/standalone/.next/static/{e2NV1wk6mWg3SIeELXevg → NUrC9xax1sp1Q70nlFqS6}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{e2NV1wk6mWg3SIeELXevg → NUrC9xax1sp1Q70nlFqS6}/_ssgManifest.js +0 -0
|
@@ -17,6 +17,9 @@ export function withModelConfigMutation<T>(
|
|
|
17
17
|
export interface ModelConfigRow {
|
|
18
18
|
name: string; provider: string; model_id: string;
|
|
19
19
|
params: string; is_default: number;
|
|
20
|
+
// ADR-0102: 0 hides the config from model selection, routing, and the
|
|
21
|
+
// default fallback without deleting it. Optional for rows built in tests.
|
|
22
|
+
enabled?: number;
|
|
20
23
|
// ADR forthcoming ??? first-class credentials. NULL until the row is
|
|
21
24
|
// explicitly bound (or until the auto-migration in lib/db/migrations.ts
|
|
22
25
|
// lifts an inline api_key into a credential row).
|
|
@@ -24,6 +27,16 @@ export interface ModelConfigRow {
|
|
|
24
27
|
created_at: string; updated_at: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
export class ModelConfigStateError extends Error {
|
|
31
|
+
constructor(message: string, readonly status: 404 | 409) {
|
|
32
|
+
super(message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isModelConfigEnabled(cfg: Pick<ModelConfigRow, "enabled"> | null | undefined): boolean {
|
|
37
|
+
return !!cfg && cfg.enabled !== 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
// `params` holds the provider API key alongside hyperparameters and is
|
|
28
41
|
// stored encrypted at rest (ADR-0005). Decrypt before returning rows.
|
|
29
42
|
function decryptRow<T extends { params: string }>(row: T): T {
|
|
@@ -37,6 +50,11 @@ export function listModelConfigs(): ModelConfigRow[] {
|
|
|
37
50
|
return rows.map(decryptRow);
|
|
38
51
|
}
|
|
39
52
|
|
|
53
|
+
/** Model configs that may be offered for selection or routing. */
|
|
54
|
+
export function listEnabledModelConfigs(): ModelConfigRow[] {
|
|
55
|
+
return listModelConfigs().filter(isModelConfigEnabled);
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
export function getModelConfig(name: string): ModelConfigRow | null {
|
|
41
59
|
const row = (getDb().prepare("SELECT * FROM model_configs WHERE name=?").get(name) as unknown as ModelConfigRow) ?? null;
|
|
42
60
|
return row ? decryptRow(row) : null;
|
|
@@ -44,15 +62,77 @@ export function getModelConfig(name: string): ModelConfigRow | null {
|
|
|
44
62
|
|
|
45
63
|
export function getDefaultModelConfig(): ModelConfigRow | null {
|
|
46
64
|
const db = getDb();
|
|
47
|
-
const row = (db.prepare("SELECT * FROM model_configs WHERE is_default=1 LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
|
|
65
|
+
const row = (db.prepare("SELECT * FROM model_configs WHERE is_default=1 AND enabled=1 LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
|
|
48
66
|
if (row) return decryptRow(row);
|
|
49
|
-
const fallback = (db.prepare("SELECT * FROM model_configs ORDER BY name ASC LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
|
|
67
|
+
const fallback = (db.prepare("SELECT * FROM model_configs WHERE enabled=1 ORDER BY name ASC LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
|
|
50
68
|
return fallback ? decryptRow(fallback) : null;
|
|
51
69
|
}
|
|
52
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Resolve the config a run should use: the named config when it exists and is
|
|
73
|
+
* enabled, otherwise the workspace default. A disabled assignment therefore
|
|
74
|
+
* falls back without being cleared, so re-enabling restores it.
|
|
75
|
+
*/
|
|
76
|
+
export function resolveRunnableModelConfig(name: string | null | undefined): ModelConfigRow | null {
|
|
77
|
+
const named = name ? getModelConfig(name) : null;
|
|
78
|
+
if (named && isModelConfigEnabled(named)) return named;
|
|
79
|
+
return getDefaultModelConfig();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Atomically make `name` the only default model config. */
|
|
83
|
+
export function setDefaultModelConfig(name: string): ModelConfigRow {
|
|
84
|
+
return withDbTransaction(() => {
|
|
85
|
+
const db = getDb();
|
|
86
|
+
const target = getModelConfig(name);
|
|
87
|
+
if (!target) throw new ModelConfigStateError(`Model config "${name}" not found`, 404);
|
|
88
|
+
if (!isModelConfigEnabled(target)) {
|
|
89
|
+
throw new ModelConfigStateError(`Model config "${name}" is disabled; enable it before making it the default`, 409);
|
|
90
|
+
}
|
|
91
|
+
const t = now();
|
|
92
|
+
db.prepare("UPDATE model_configs SET is_default=0, updated_at=? WHERE is_default=1 AND name<>?").run(t, name);
|
|
93
|
+
db.prepare("UPDATE model_configs SET is_default=1, updated_at=? WHERE name=?").run(t, name);
|
|
94
|
+
return getModelConfig(name)!;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Enable or disable a model config. Disabling the default promotes the
|
|
100
|
+
* alphabetically-first other enabled config in the same transaction, and the
|
|
101
|
+
* last enabled config cannot be disabled so runs always have a model.
|
|
102
|
+
*/
|
|
103
|
+
export function setModelConfigEnabled(name: string, enabled: boolean): ModelConfigRow {
|
|
104
|
+
return withDbTransaction(() => {
|
|
105
|
+
const db = getDb();
|
|
106
|
+
const target = getModelConfig(name);
|
|
107
|
+
if (!target) throw new ModelConfigStateError(`Model config "${name}" not found`, 404);
|
|
108
|
+
if (isModelConfigEnabled(target) === enabled) return target;
|
|
109
|
+
const t = now();
|
|
110
|
+
if (enabled) {
|
|
111
|
+
db.prepare("UPDATE model_configs SET enabled=1, updated_at=? WHERE name=?").run(t, name);
|
|
112
|
+
return getModelConfig(name)!;
|
|
113
|
+
}
|
|
114
|
+
const next = db.prepare(
|
|
115
|
+
"SELECT name FROM model_configs WHERE enabled=1 AND name<>? ORDER BY name ASC LIMIT 1",
|
|
116
|
+
).get(name) as { name?: string } | undefined;
|
|
117
|
+
if (!next?.name) {
|
|
118
|
+
throw new ModelConfigStateError("At least one model config must stay enabled", 409);
|
|
119
|
+
}
|
|
120
|
+
db.prepare("UPDATE model_configs SET enabled=0, is_default=0, updated_at=? WHERE name=?").run(t, name);
|
|
121
|
+
if (target.is_default === 1) {
|
|
122
|
+
db.prepare("UPDATE model_configs SET is_default=1, updated_at=? WHERE name=?").run(t, next.name);
|
|
123
|
+
}
|
|
124
|
+
return getModelConfig(name)!;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Insert or update a model config. `is_default` undefined keeps the current
|
|
130
|
+
* flag (false for new rows); true atomically clears every other default and
|
|
131
|
+
* re-enables the row, because the default must always be selectable.
|
|
132
|
+
*/
|
|
53
133
|
export function upsertModelConfig(
|
|
54
134
|
name: string, provider: string, model_id: string,
|
|
55
|
-
params: Record<string, unknown>, is_default: boolean,
|
|
135
|
+
params: Record<string, unknown>, is_default: boolean | undefined,
|
|
56
136
|
credential_id: string | null = null,
|
|
57
137
|
): ModelConfigRow {
|
|
58
138
|
return withDbTransaction(() => {
|
|
@@ -67,11 +147,13 @@ export function upsertModelConfig(
|
|
|
67
147
|
// other field a custom provider relies on (e.g. custom-provider.js's
|
|
68
148
|
// username/password auth) on every save.
|
|
69
149
|
const mergedParams = { ...decodeInlineParams(existing), ...params };
|
|
150
|
+
const finalDefault = is_default ?? existing?.is_default === 1;
|
|
151
|
+
const finalEnabled = finalDefault || !existing || isModelConfigEnabled(existing);
|
|
70
152
|
const db = getDb();
|
|
71
|
-
if (
|
|
153
|
+
if (finalDefault) db.prepare("UPDATE model_configs SET is_default=0 WHERE name<>?").run(name);
|
|
72
154
|
db.prepare(
|
|
73
|
-
"INSERT OR REPLACE INTO model_configs (name,provider,model_id,params,is_default,credential_id,created_at,updated_at) VALUES (
|
|
74
|
-
).run(name, provider, model_id, encrypt(JSON.stringify(mergedParams)),
|
|
155
|
+
"INSERT OR REPLACE INTO model_configs (name,provider,model_id,params,is_default,enabled,credential_id,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
|
156
|
+
).run(name, provider, model_id, encrypt(JSON.stringify(mergedParams)), finalDefault ? 1 : 0, finalEnabled ? 1 : 0, finalCredId, created_at, t);
|
|
75
157
|
return getModelConfig(name)!;
|
|
76
158
|
});
|
|
77
159
|
}
|
|
@@ -85,10 +167,10 @@ export function deleteModelConfig(name: string): boolean {
|
|
|
85
167
|
// Automatically reset any agent pointing to this deleted model config to NULL (automatic / default model)
|
|
86
168
|
db.prepare("UPDATE agent_configs SET model_config_name = NULL WHERE model_config_name = ?").run(name);
|
|
87
169
|
// Avoid the "no default" state: if the deleted row was the default and any
|
|
88
|
-
// other rows remain, promote the alphabetically-first
|
|
170
|
+
// other enabled rows remain, promote the alphabetically-first one so
|
|
89
171
|
// agents that fall back to the default keep working.
|
|
90
172
|
if (wasDefault) {
|
|
91
|
-
const next = db.prepare("SELECT name FROM model_configs ORDER BY name ASC LIMIT 1").get() as { name?: string } | undefined;
|
|
173
|
+
const next = db.prepare("SELECT name FROM model_configs WHERE enabled=1 ORDER BY name ASC LIMIT 1").get() as { name?: string } | undefined;
|
|
92
174
|
if (next?.name) db.prepare("UPDATE model_configs SET is_default=1 WHERE name=?").run(next.name);
|
|
93
175
|
}
|
|
94
176
|
return true;
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|