omnexx 0.8.0 → 0.9.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/{chat-context-OL7LLKBT.js → chat-context-37IAD72P.js} +5 -5
- package/dist/{chat-server-HUYEZGT7.js → chat-server-RMR3QGFJ.js} +11 -11
- package/dist/chat-server-RMR3QGFJ.js.map +1 -0
- package/dist/{chat-settings-4OW4MUSE.js → chat-settings-AMSAWVT6.js} +5 -5
- package/dist/{chunk-ANSOFQ32.js → chunk-27GOEUTN.js} +41 -11
- package/dist/chunk-27GOEUTN.js.map +1 -0
- package/dist/{chunk-UCIHYU6B.js → chunk-3S4ULH6B.js} +3 -3
- package/dist/{chunk-O75OQQDP.js → chunk-EDB7FXDP.js} +2 -2
- package/dist/{chunk-CNUYDXSI.js → chunk-FNHEOL3X.js} +14 -10
- package/dist/chunk-FNHEOL3X.js.map +1 -0
- package/dist/{chunk-KC7YVX2B.js → chunk-IXTUJETQ.js} +81 -33
- package/dist/chunk-IXTUJETQ.js.map +1 -0
- package/dist/{chunk-JEHAJ45I.js → chunk-IZYY3NPJ.js} +385 -299
- package/dist/chunk-IZYY3NPJ.js.map +1 -0
- package/dist/{chunk-263JZDVT.js → chunk-LU3LFPGQ.js} +23 -6
- package/dist/chunk-LU3LFPGQ.js.map +1 -0
- package/dist/{chunk-7T24V7UU.js → chunk-NV4LO7BY.js} +28 -5
- package/dist/chunk-NV4LO7BY.js.map +1 -0
- package/dist/{chunk-6OQWQDGP.js → chunk-NVDO3QO5.js} +20 -3
- package/dist/chunk-NVDO3QO5.js.map +1 -0
- package/dist/{chunk-L43V7MUO.js → chunk-STU6YIQJ.js} +3 -3
- package/dist/{chunk-YEUB2OJI.js → chunk-T2NUPPUG.js} +2 -2
- package/dist/cli.js +15 -14
- package/dist/cli.js.map +1 -1
- package/dist/{model-picker-M2ZETIKE.js → model-picker-QX6NHUGJ.js} +6 -6
- package/dist/{ollama-HHDVJRPX.js → ollama-USDNXHTB.js} +5 -5
- package/dist/{print-WTEHAUQ6.js → print-K4HFWHCL.js} +6 -6
- package/dist/{roles-PPNR2ECT.js → roles-IHKWWYJL.js} +2 -4
- package/dist/session-QGVKS2YJ.js +32 -0
- package/dist/{start-3JFBG6PM.js → start-NBU4UITZ.js} +12 -12
- package/package.json +3 -2
- package/dist/chat-server-HUYEZGT7.js.map +0 -1
- package/dist/chunk-263JZDVT.js.map +0 -1
- package/dist/chunk-6OQWQDGP.js.map +0 -1
- package/dist/chunk-7T24V7UU.js.map +0 -1
- package/dist/chunk-ANSOFQ32.js.map +0 -1
- package/dist/chunk-CNUYDXSI.js.map +0 -1
- package/dist/chunk-JEHAJ45I.js.map +0 -1
- package/dist/chunk-KC7YVX2B.js.map +0 -1
- package/dist/session-GUDTYRZ5.js +0 -32
- /package/dist/{chat-context-OL7LLKBT.js.map → chat-context-37IAD72P.js.map} +0 -0
- /package/dist/{chat-settings-4OW4MUSE.js.map → chat-settings-AMSAWVT6.js.map} +0 -0
- /package/dist/{chunk-UCIHYU6B.js.map → chunk-3S4ULH6B.js.map} +0 -0
- /package/dist/{chunk-O75OQQDP.js.map → chunk-EDB7FXDP.js.map} +0 -0
- /package/dist/{chunk-L43V7MUO.js.map → chunk-STU6YIQJ.js.map} +0 -0
- /package/dist/{chunk-YEUB2OJI.js.map → chunk-T2NUPPUG.js.map} +0 -0
- /package/dist/{model-picker-M2ZETIKE.js.map → model-picker-QX6NHUGJ.js.map} +0 -0
- /package/dist/{ollama-HHDVJRPX.js.map → ollama-USDNXHTB.js.map} +0 -0
- /package/dist/{print-WTEHAUQ6.js.map → print-K4HFWHCL.js.map} +0 -0
- /package/dist/{roles-PPNR2ECT.js.map → roles-IHKWWYJL.js.map} +0 -0
- /package/dist/{session-GUDTYRZ5.js.map → session-QGVKS2YJ.js.map} +0 -0
- /package/dist/{start-3JFBG6PM.js.map → start-NBU4UITZ.js.map} +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
repoRoot
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-T2NUPPUG.js";
|
|
5
5
|
import {
|
|
6
6
|
RunStore,
|
|
7
7
|
listRunIds,
|
|
8
8
|
repoMemoryFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NV4LO7BY.js";
|
|
10
10
|
import {
|
|
11
11
|
SECTION_IDS,
|
|
12
12
|
SECTION_INFO,
|
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
loadConfig,
|
|
16
16
|
readSectionModes,
|
|
17
17
|
sectionsFile
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NVDO3QO5.js";
|
|
19
19
|
import {
|
|
20
20
|
UsageError,
|
|
21
21
|
resolvePaths
|
|
22
22
|
} from "./chunk-XQTM3SWX.js";
|
|
23
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-27GOEUTN.js";
|
|
24
24
|
import "./chunk-2H7UOFLK.js";
|
|
25
25
|
|
|
26
26
|
// src/cli/chat-context.ts
|
|
@@ -117,4 +117,4 @@ export {
|
|
|
117
117
|
contextFiles,
|
|
118
118
|
setSectionMode
|
|
119
119
|
};
|
|
120
|
-
//# sourceMappingURL=chat-context-
|
|
120
|
+
//# sourceMappingURL=chat-context-37IAD72P.js.map
|
|
@@ -32,7 +32,7 @@ function text(c, key) {
|
|
|
32
32
|
return v;
|
|
33
33
|
}
|
|
34
34
|
async function serveChat(io, runCli, opts) {
|
|
35
|
-
const { Session } = await import("./session-
|
|
35
|
+
const { Session } = await import("./session-QGVKS2YJ.js");
|
|
36
36
|
const session = new Session(io, runCli);
|
|
37
37
|
const write = (msg) => {
|
|
38
38
|
println(io.stdout, JSON.stringify(msg));
|
|
@@ -102,7 +102,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
102
102
|
};
|
|
103
103
|
session.onChange(schedule);
|
|
104
104
|
const sendModels = async () => {
|
|
105
|
-
const { loadModelChoices } = await import("./model-picker-
|
|
105
|
+
const { loadModelChoices } = await import("./model-picker-QX6NHUGJ.js");
|
|
106
106
|
const { items, unreachable } = await loadModelChoices(io);
|
|
107
107
|
write({
|
|
108
108
|
type: "models",
|
|
@@ -112,15 +112,15 @@ async function serveChat(io, runCli, opts) {
|
|
|
112
112
|
});
|
|
113
113
|
};
|
|
114
114
|
const sendSettings = async () => {
|
|
115
|
-
const { providerSettings } = await import("./chat-settings-
|
|
115
|
+
const { providerSettings } = await import("./chat-settings-AMSAWVT6.js");
|
|
116
116
|
write({ type: "settings", ...await providerSettings(io) });
|
|
117
117
|
};
|
|
118
118
|
const sendContextFiles = async () => {
|
|
119
|
-
const { contextFiles } = await import("./chat-context-
|
|
119
|
+
const { contextFiles } = await import("./chat-context-37IAD72P.js");
|
|
120
120
|
write({ type: "contextFiles", ...await contextFiles(io) });
|
|
121
121
|
};
|
|
122
122
|
const sendRoles = async () => {
|
|
123
|
-
const { readRoles } = await import("./roles-
|
|
123
|
+
const { readRoles } = await import("./roles-IHKWWYJL.js");
|
|
124
124
|
const { QuotaLedger } = await import("./quota-ledger-7F6QTZAM.js");
|
|
125
125
|
const paths = resolvePaths(io.env);
|
|
126
126
|
write({
|
|
@@ -192,7 +192,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
192
192
|
return typeof v === "string" ? v : void 0;
|
|
193
193
|
};
|
|
194
194
|
run(
|
|
195
|
-
import("./chat-settings-
|
|
195
|
+
import("./chat-settings-AMSAWVT6.js").then(async ({ addProvider }) => {
|
|
196
196
|
await providersChanged(
|
|
197
197
|
await addProvider(io, {
|
|
198
198
|
provider: str("provider"),
|
|
@@ -206,7 +206,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
206
206
|
}
|
|
207
207
|
case "testProvider":
|
|
208
208
|
run(
|
|
209
|
-
import("./chat-settings-
|
|
209
|
+
import("./chat-settings-AMSAWVT6.js").then(async ({ testProvider }) => {
|
|
210
210
|
write({ type: "providerTest", ...await testProvider(io, text(c, "name")) });
|
|
211
211
|
})
|
|
212
212
|
);
|
|
@@ -216,7 +216,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
216
216
|
return;
|
|
217
217
|
case "setSectionMode":
|
|
218
218
|
run(
|
|
219
|
-
import("./chat-context-
|
|
219
|
+
import("./chat-context-37IAD72P.js").then(async ({ setSectionMode }) => {
|
|
220
220
|
await setSectionMode(io, text(c, "id"), text(c, "mode"));
|
|
221
221
|
await sendContextFiles();
|
|
222
222
|
})
|
|
@@ -227,7 +227,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
227
227
|
return;
|
|
228
228
|
case "setRoles":
|
|
229
229
|
run(
|
|
230
|
-
import("./roles-
|
|
230
|
+
import("./roles-IHKWWYJL.js").then(async ({ parseRoles, writeRoles }) => {
|
|
231
231
|
await writeRoles(resolvePaths(io.env), parseRoles(c.roles));
|
|
232
232
|
session.push("system", "model roles saved; new chats and runs use them");
|
|
233
233
|
await sendRoles();
|
|
@@ -236,7 +236,7 @@ async function serveChat(io, runCli, opts) {
|
|
|
236
236
|
return;
|
|
237
237
|
case "removeProvider":
|
|
238
238
|
run(
|
|
239
|
-
import("./chat-settings-
|
|
239
|
+
import("./chat-settings-AMSAWVT6.js").then(async ({ removeProvider }) => {
|
|
240
240
|
await providersChanged(await removeProvider(io, text(c, "name")));
|
|
241
241
|
})
|
|
242
242
|
);
|
|
@@ -281,4 +281,4 @@ async function serveChat(io, runCli, opts) {
|
|
|
281
281
|
export {
|
|
282
282
|
serveChat
|
|
283
283
|
};
|
|
284
|
-
//# sourceMappingURL=chat-server-
|
|
284
|
+
//# sourceMappingURL=chat-server-RMR3QGFJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/chat-server.ts"],"sourcesContent":["import { join } from 'node:path';\nimport { resolvePaths } from '../core/paths.js';\nimport { readFile } from 'node:fs/promises';\nimport { createInterface } from 'node:readline';\nimport { describeError } from '../errors.js';\nimport type { Telemetry } from '../telemetry/aggregate.js';\nimport type { TodoItem } from '../tools/todo.js';\nimport type { Entry, Helper, Mode, RunCli } from '../tui/session.js';\nimport { println, type CliIO } from './io.js';\n\n/**\n * `omnexx chat-server`: the interactive session behind a JSON-lines protocol on stdin/stdout, for\n * editor panels (the VS Code chat). It drives the same Session as the terminal UI, so slash\n * commands, approvals, model switching and plan mode behave the same way.\n *\n * In (one JSON object per line): send {text} · answer {yes} · stop · pause · resume · mode {mode} ·\n * yolo {on} ·\n * model {ref} · models · connect {value, name?} · undo · clear · compact · sync (resend all) ·\n * settings · addProvider {provider?, key?, url?} · removeProvider {name} · testProvider {name} ·\n * roles · setRoles {roles} · contextFiles · setSectionMode {id, mode}.\n * Out: ready {version} · state (below; `entries` holds only lines not sent before) · models\n * {items, unreachable, current} · settings {catalog, connected} · providerTest {name, ok, models,\n * detail} · error {message}.\n */\n\nexport interface ChatUsage {\n /** When the chat's first event happened (epoch ms), for an uptime clock. */\n startedAt: number | null;\n tokens: Telemetry['tokens'];\n usd: number;\n turns: number;\n toolCalls: number;\n toolErrors: number;\n compactions: number;\n}\n\nexport interface ChatState {\n type: 'state';\n entries: Entry[];\n /** The reply as it streams in; empty once it lands in `entries`. */\n live: string;\n todos: TodoItem[];\n /** A question waiting for allow / deny, or null. */\n pending: string | null;\n mode: Mode;\n busy: boolean;\n paused: boolean;\n autoApprove: boolean;\n model: string | null;\n /** Tokens in use, the compaction limit, and what they are made of. */\n context: {\n used: number;\n limit: number;\n parts?: { system: number; tools: number; conversation: number };\n } | null;\n usage: ChatUsage | null;\n run: { id: string; alive: boolean; phase?: string; done?: number; tasks?: number } | null;\n /** Helpers (subagents) for the current message. */\n helpers: Helper[];\n /** The latest browser frame's number and page; the image comes as a `browserFrame` message. */\n browser: { seq: number; url: string; action: string; at: number } | null;\n}\n\n/** Frames larger than this are skipped rather than pushed through the pipe. */\nconst MAX_FRAME_BYTES = 4 * 1024 * 1024;\n\nconst MODES = new Set<Mode>(['chat', 'plan', 'run']);\n/** Coalesce bursts of changes (a streaming reply fires one per token) into one state line. */\nconst EMIT_EVERY_MS = 40;\n\ntype Command = { type: string } & Record<string, unknown>;\n\nfunction parseCommand(line: string): Command {\n let data: unknown;\n try {\n data = JSON.parse(line);\n } catch {\n throw new Error('expected one JSON object per line');\n }\n if (typeof data !== 'object' || data === null || typeof (data as Command).type !== 'string')\n throw new Error('expected an object with a \"type\"');\n return data as Command;\n}\n\nfunction text(c: Command, key: string): string {\n const v = c[key];\n if (typeof v !== 'string' || !v.trim()) throw new Error(`\"${c.type}\" needs a \"${key}\" string`);\n return v;\n}\n\nexport async function serveChat(\n io: CliIO,\n runCli: RunCli,\n opts: { version: string },\n): Promise<number> {\n const { Session } = await import('../tui/session.js');\n const session = new Session(io, runCli);\n const write = (msg: object): void => {\n println(io.stdout, JSON.stringify(msg));\n };\n const fail = (err: unknown): void => {\n write({ type: 'error', message: describeError(err) });\n };\n\n let sentUpTo = -1;\n let sentFrame = 0;\n /** Send the browser's latest screenshot once per new frame. */\n const sendFrame = async (): Promise<void> => {\n const f = session.browserFrame;\n if (!f || f.seq === sentFrame) return;\n sentFrame = f.seq;\n const data = await readFile(f.path).catch(() => undefined);\n if (!data || data.length > MAX_FRAME_BYTES) return;\n write({\n type: 'browserFrame',\n seq: f.seq,\n mime: f.mime,\n url: f.url,\n action: f.action,\n data: data.toString('base64'),\n });\n };\n /** The last entry before the latest new chat; a reloaded panel starts after it. */\n let clearedAt = -1;\n let timer: NodeJS.Timeout | undefined;\n const emit = (): void => {\n timer = undefined;\n const fresh = session.entries.filter((e) => e.id > sentUpTo);\n sentUpTo = session.entries.at(-1)?.id ?? sentUpTo;\n const t = session.chatTelemetry;\n const state: ChatState = {\n type: 'state',\n entries: fresh,\n live: session.live,\n todos: session.todos,\n pending: session.pending?.question ?? null,\n mode: session.mode,\n busy: session.busy !== undefined || session.chatBusy,\n paused: session.chatPaused,\n autoApprove: session.autoApprove,\n model: session.chatModelName ?? null,\n context: session.context ?? null,\n usage: t\n ? {\n startedAt: t.startedAt ?? null,\n tokens: t.tokens,\n usd: t.usd,\n turns: t.turns,\n toolCalls: t.toolCalls,\n toolErrors: t.toolErrors,\n compactions: t.compactions,\n }\n : null,\n run: session.runId ? { id: session.runId, alive: session.runAlive, ...session.info } : null,\n helpers: session.helpers,\n browser: session.browserFrame\n ? {\n seq: session.browserFrame.seq,\n url: session.browserFrame.url,\n action: session.browserFrame.action,\n at: session.browserFrame.at,\n }\n : null,\n };\n write(state);\n void sendFrame();\n };\n const schedule = (): void => {\n timer ??= setTimeout(emit, EMIT_EVERY_MS);\n };\n session.onChange(schedule);\n\n const sendModels = async (): Promise<void> => {\n const { loadModelChoices } = await import('../tui/model-picker.js');\n const { items, unreachable } = await loadModelChoices(io);\n write({\n type: 'models',\n items: items.filter((i) => i.kind === 'model'),\n unreachable,\n current: session.chatModelName ?? null,\n });\n };\n const sendSettings = async (): Promise<void> => {\n const { providerSettings } = await import('./chat-settings.js');\n write({ type: 'settings', ...(await providerSettings(io)) });\n };\n const sendContextFiles = async (): Promise<void> => {\n const { contextFiles } = await import('./chat-context.js');\n write({ type: 'contextFiles', ...(await contextFiles(io)) });\n };\n /** Roles as saved, plus which models are out of quota right now (ref → when it ran out). */\n const sendRoles = async (): Promise<void> => {\n const { readRoles } = await import('../config/roles.js');\n const { QuotaLedger } = await import('../providers/quota-ledger.js');\n const paths = resolvePaths(io.env);\n write({\n type: 'roles',\n roles: await readRoles(paths),\n exhausted: new QuotaLedger(join(paths.configHome, 'quota.json')).all(),\n });\n };\n /** After a provider change: say what happened, then refresh the settings page and models. */\n const providersChanged = async (message: string): Promise<void> => {\n session.push('system', message);\n await sendSettings();\n await sendModels();\n };\n\n /** Commands still running, so a closed pipe lets them finish before the process exits. */\n const inflight = new Set<Promise<unknown>>();\n const run = (p: Promise<unknown>): void => {\n const tracked = p.catch(fail).finally(() => {\n inflight.delete(tracked);\n schedule();\n });\n inflight.add(tracked);\n };\n\n const handle = (c: Command): void => {\n switch (c.type) {\n case 'send':\n run(session.submit(text(c, 'text')));\n return;\n case 'answer':\n if (!session.pending) throw new Error('nothing is waiting for an answer');\n run(session.submit(c.yes === true ? 'y' : 'n'));\n return;\n case 'stop':\n case 'pause':\n case 'resume':\n case 'undo':\n case 'compact':\n run(session.command(c.type));\n return;\n case 'clear':\n run(\n session.command('clear').then(() => {\n // A new chat starts the panel over: nothing from before the clear is sent again.\n clearedAt = session.entries.at(-1)?.id ?? clearedAt;\n sentUpTo = clearedAt;\n write({ type: 'ready', version: opts.version });\n emit();\n }),\n );\n return;\n case 'mode': {\n const mode = c.mode as Mode;\n if (!MODES.has(mode)) throw new Error('mode is one of chat, plan, run');\n if (session.mode !== mode) session.setMode(mode);\n return;\n }\n case 'yolo':\n // /yolo toggles; only run it when the state differs from what was asked, and without\n // echoing it as a message.\n if ((c.on === true) !== session.autoApprove) run(session.command('yolo'));\n return;\n case 'model':\n run(session.switchModel(text(c, 'ref')));\n return;\n case 'models':\n run(sendModels());\n return;\n case 'settings':\n run(sendSettings());\n return;\n case 'addProvider': {\n const str = (k: string): string | undefined => {\n const v = c[k];\n return typeof v === 'string' ? v : undefined;\n };\n run(\n import('./chat-settings.js').then(async ({ addProvider }) => {\n await providersChanged(\n await addProvider(io, {\n provider: str('provider'),\n key: str('key'),\n url: str('url'),\n }),\n );\n }),\n );\n return;\n }\n case 'testProvider':\n run(\n import('./chat-settings.js').then(async ({ testProvider }) => {\n write({ type: 'providerTest', ...(await testProvider(io, text(c, 'name'))) });\n }),\n );\n return;\n case 'contextFiles':\n run(sendContextFiles());\n return;\n case 'setSectionMode':\n run(\n import('./chat-context.js').then(async ({ setSectionMode }) => {\n await setSectionMode(io, text(c, 'id'), text(c, 'mode'));\n await sendContextFiles();\n }),\n );\n return;\n case 'roles':\n run(sendRoles());\n return;\n case 'setRoles':\n run(\n import('../config/roles.js').then(async ({ parseRoles, writeRoles }) => {\n await writeRoles(resolvePaths(io.env), parseRoles(c.roles));\n session.push('system', 'model roles saved; new chats and runs use them');\n await sendRoles();\n }),\n );\n return;\n case 'removeProvider':\n run(\n import('./chat-settings.js').then(async ({ removeProvider }) => {\n await providersChanged(await removeProvider(io, text(c, 'name')));\n }),\n );\n return;\n case 'connect': {\n const name = typeof c.name === 'string' && c.name.trim() ? ` --name ${c.name.trim()}` : '';\n run(session.submit(`/model ${text(c, 'value')}${name}`));\n return;\n }\n case 'sync':\n // A reloaded panel: start it over with the conversation since the last new chat.\n sentUpTo = clearedAt;\n sentFrame = 0;\n write({ type: 'ready', version: opts.version });\n emit();\n return;\n default:\n throw new Error(`unknown command \"${c.type}\"`);\n }\n };\n\n await session.loadCommands();\n await session.continueChat().catch(fail);\n await session.greet(false).catch(fail);\n write({ type: 'ready', version: opts.version });\n emit();\n\n const lines = createInterface({ input: io.stdin, crlfDelay: Infinity });\n for await (const line of lines) {\n if (!line.trim()) continue;\n try {\n handle(parseCommand(line));\n } catch (err) {\n fail(err);\n }\n }\n // The editor closed the pipe: end any turn in progress, let running commands finish, then\n // flush the last state.\n if (session.chatBusy) await session.command('stop');\n await Promise.allSettled([...inflight]);\n if (timer) {\n clearTimeout(timer);\n emit();\n }\n return 0;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
connect,
|
|
4
4
|
describeConnect
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3S4ULH6B.js";
|
|
6
6
|
import {
|
|
7
7
|
PROVIDER_TEMPLATES,
|
|
8
8
|
removeEndpointBlock
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-EDB7FXDP.js";
|
|
10
10
|
import "./chunk-7PC4SSYS.js";
|
|
11
11
|
import {
|
|
12
12
|
clearKey,
|
|
@@ -15,13 +15,13 @@ import {
|
|
|
15
15
|
} from "./chunk-TJWLF5MU.js";
|
|
16
16
|
import {
|
|
17
17
|
loadConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NVDO3QO5.js";
|
|
19
19
|
import {
|
|
20
20
|
UsageError,
|
|
21
21
|
resolvePaths,
|
|
22
22
|
userConfigFile
|
|
23
23
|
} from "./chunk-XQTM3SWX.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-27GOEUTN.js";
|
|
25
25
|
import "./chunk-UX4MF6V4.js";
|
|
26
26
|
import "./chunk-2H7UOFLK.js";
|
|
27
27
|
|
|
@@ -144,4 +144,4 @@ export {
|
|
|
144
144
|
removeProvider,
|
|
145
145
|
testProvider
|
|
146
146
|
};
|
|
147
|
-
//# sourceMappingURL=chat-settings-
|
|
147
|
+
//# sourceMappingURL=chat-settings-AMSAWVT6.js.map
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/config/routing.ts
|
|
4
|
+
var STRATEGIES = ["priority", "random", "least-busy", "smart"];
|
|
5
|
+
function orderForStrategy(chain, strategy, ctx = {}) {
|
|
6
|
+
const indexed = chain.map((m, i) => ({ m, i }));
|
|
7
|
+
switch (strategy) {
|
|
8
|
+
case "random": {
|
|
9
|
+
const rnd = ctx.random ?? Math.random;
|
|
10
|
+
const keys = new Map(indexed.map((x) => [x.i, rnd()]));
|
|
11
|
+
return indexed.sort((a, b) => (keys.get(a.i) ?? 0) - (keys.get(b.i) ?? 0)).map((x) => x.m);
|
|
12
|
+
}
|
|
13
|
+
case "least-busy": {
|
|
14
|
+
const busy = ctx.busy ?? /* @__PURE__ */ new Map();
|
|
15
|
+
return indexed.sort((a, b) => (busy.get(a.m.provider) ?? 0) - (busy.get(b.m.provider) ?? 0) || a.i - b.i).map((x) => x.m);
|
|
16
|
+
}
|
|
17
|
+
case "smart":
|
|
18
|
+
return indexed.sort((a, b) => (b.m.price?.output ?? 0) - (a.m.price?.output ?? 0) || a.i - b.i).map((x) => x.m);
|
|
19
|
+
default:
|
|
20
|
+
return [...chain];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function strategyFor(models, role) {
|
|
24
|
+
const set = models.routing?.[role];
|
|
25
|
+
if (set) return set;
|
|
26
|
+
return role === "helpers" && models.spread_helpers !== false ? "least-busy" : "priority";
|
|
27
|
+
}
|
|
28
|
+
|
|
3
29
|
// src/config/roles.ts
|
|
4
30
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
5
31
|
import { dirname, join } from "path";
|
|
@@ -20,13 +46,20 @@ function parseRoles(raw) {
|
|
|
20
46
|
const list = cleanList(modelsIn[role]);
|
|
21
47
|
if (list.length) models[role] = list;
|
|
22
48
|
}
|
|
23
|
-
|
|
49
|
+
const strategiesIn = typeof obj.strategies === "object" && obj.strategies !== null ? obj.strategies : {};
|
|
50
|
+
const strategies = {};
|
|
51
|
+
for (const role of ROLE_NAMES) {
|
|
52
|
+
const s = strategiesIn[role];
|
|
53
|
+
if (typeof s === "string" && STRATEGIES.includes(s))
|
|
54
|
+
strategies[role] = s;
|
|
55
|
+
}
|
|
56
|
+
return { models, strategies, spreadHelpers: obj.spreadHelpers !== false };
|
|
24
57
|
}
|
|
25
58
|
async function readRoles(p) {
|
|
26
59
|
try {
|
|
27
60
|
return parseRoles(JSON.parse(await readFile(rolesFile(p), "utf8")));
|
|
28
61
|
} catch {
|
|
29
|
-
return { models: {}, spreadHelpers: true };
|
|
62
|
+
return { models: {}, strategies: {}, spreadHelpers: true };
|
|
30
63
|
}
|
|
31
64
|
}
|
|
32
65
|
async function writeRoles(p, roles) {
|
|
@@ -46,22 +79,19 @@ function rolesLayer(r) {
|
|
|
46
79
|
if (cheap?.length) models.cheap = cheap;
|
|
47
80
|
if (helpers?.length) models.helpers = helpers;
|
|
48
81
|
if (!r.spreadHelpers) models.spread_helpers = false;
|
|
82
|
+
if (Object.keys(r.strategies).length) models.routing = r.strategies;
|
|
49
83
|
return Object.keys(models).length ? { models } : void 0;
|
|
50
84
|
}
|
|
51
|
-
function spreadAcrossProviders(chain, n) {
|
|
52
|
-
const providers = [...new Set(chain.map((m) => m.provider))];
|
|
53
|
-
if (providers.length < 2) return [...chain];
|
|
54
|
-
const lead = providers[n % providers.length];
|
|
55
|
-
return [...chain.filter((m) => m.provider === lead), ...chain.filter((m) => m.provider !== lead)];
|
|
56
|
-
}
|
|
57
85
|
|
|
58
86
|
export {
|
|
87
|
+
STRATEGIES,
|
|
88
|
+
orderForStrategy,
|
|
89
|
+
strategyFor,
|
|
59
90
|
ROLE_NAMES,
|
|
60
91
|
rolesFile,
|
|
61
92
|
parseRoles,
|
|
62
93
|
readRoles,
|
|
63
94
|
writeRoles,
|
|
64
|
-
rolesLayer
|
|
65
|
-
spreadAcrossProviders
|
|
95
|
+
rolesLayer
|
|
66
96
|
};
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-27GOEUTN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/routing.ts","../src/config/roles.ts"],"sourcesContent":["/**\n * How a role's models are ordered before each use. The first model is tried first; the rest are\n * the failover chain, so every strategy keeps every model as a fallback.\n * - priority: as the person arranged them.\n * - random: a fresh shuffle each time, spreading load evenly.\n * - least-busy: providers with the fewest helpers running go first (parallel helpers spread out).\n * - smart: the most capable first, with output price as the stand-in for capability.\n */\nexport const STRATEGIES = ['priority', 'random', 'least-busy', 'smart'] as const;\nexport type Strategy = (typeof STRATEGIES)[number];\n\ninterface Routable {\n provider: string;\n price?: { output?: number } | undefined;\n}\n\nexport interface OrderContext {\n /** Helpers running per provider right now (least-busy). */\n busy?: ReadonlyMap<string, number>;\n /** Source of randomness (tests pass a fixed one). */\n random?: () => number;\n}\n\nexport function orderForStrategy<T extends Routable>(\n chain: readonly T[],\n strategy: Strategy,\n ctx: OrderContext = {},\n): T[] {\n const indexed = chain.map((m, i) => ({ m, i }));\n switch (strategy) {\n case 'random': {\n const rnd = ctx.random ?? Math.random;\n const keys = new Map(indexed.map((x) => [x.i, rnd()]));\n return indexed.sort((a, b) => (keys.get(a.i) ?? 0) - (keys.get(b.i) ?? 0)).map((x) => x.m);\n }\n case 'least-busy': {\n const busy = ctx.busy ?? new Map<string, number>();\n return indexed\n .sort((a, b) => (busy.get(a.m.provider) ?? 0) - (busy.get(b.m.provider) ?? 0) || a.i - b.i)\n .map((x) => x.m);\n }\n case 'smart':\n return indexed\n .sort((a, b) => (b.m.price?.output ?? 0) - (a.m.price?.output ?? 0) || a.i - b.i)\n .map((x) => x.m);\n default:\n return [...chain];\n }\n}\n\n/** The strategy a role uses: its setting, else least-busy for helpers (when spreading) and priority. */\nexport function strategyFor(\n models: { routing?: Partial<Record<string, Strategy>>; spread_helpers?: boolean },\n role: string,\n): Strategy {\n const set = models.routing?.[role];\n if (set) return set;\n return role === 'helpers' && models.spread_helpers !== false ? 'least-busy' : 'priority';\n}\n","import { STRATEGIES, type Strategy } from './routing.js';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport type { OmnexxPaths } from '../core/paths.js';\n\n/**\n * Which models power which role, chosen in the editor's settings and kept next to the /models\n * pool (`roles.json`). A role left empty falls back to the pool and config.toml as before.\n * `helpers` powers subagents. Each role also has a routing strategy (see routing.ts): least-busy\n * helpers spread over providers, so several providers' quotas are used at once.\n */\nexport const ROLE_NAMES = ['chat', 'planner', 'worker', 'cheap', 'helpers'] as const;\nexport type Role = (typeof ROLE_NAMES)[number];\n\nexport interface Roles {\n models: Partial<Record<Role, string[]>>;\n /** How each role routes between its models; unset roles use the default. */\n strategies: Partial<Record<Role, Strategy>>;\n spreadHelpers: boolean;\n}\n\nconst REF = /^[a-z][a-z0-9_-]*:\\S+$/;\nconst MAX_PER_ROLE = 20;\n\nexport const rolesFile = (p: OmnexxPaths): string => join(p.configHome, 'roles.json');\n\n/** Keep only well-formed, distinct refs, in order. */\nfunction cleanList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const refs = value.filter((r): r is string => typeof r === 'string' && REF.test(r));\n return [...new Set(refs)].slice(0, MAX_PER_ROLE);\n}\n\nexport function parseRoles(raw: unknown): Roles {\n const obj = typeof raw === 'object' && raw !== null ? (raw as Record<string, unknown>) : {};\n const modelsIn =\n typeof obj.models === 'object' && obj.models !== null\n ? (obj.models as Record<string, unknown>)\n : {};\n const models: Partial<Record<Role, string[]>> = {};\n for (const role of ROLE_NAMES) {\n const list = cleanList(modelsIn[role]);\n if (list.length) models[role] = list;\n }\n const strategiesIn =\n typeof obj.strategies === 'object' && obj.strategies !== null\n ? (obj.strategies as Record<string, unknown>)\n : {};\n const strategies: Partial<Record<Role, Strategy>> = {};\n for (const role of ROLE_NAMES) {\n const s = strategiesIn[role];\n if (typeof s === 'string' && (STRATEGIES as readonly string[]).includes(s))\n strategies[role] = s as Strategy;\n }\n return { models, strategies, spreadHelpers: obj.spreadHelpers !== false };\n}\n\nexport async function readRoles(p: OmnexxPaths): Promise<Roles> {\n try {\n return parseRoles(JSON.parse(await readFile(rolesFile(p), 'utf8')));\n } catch {\n return { models: {}, strategies: {}, spreadHelpers: true };\n }\n}\n\nexport async function writeRoles(p: OmnexxPaths, roles: Roles): Promise<Roles> {\n const clean = parseRoles(roles);\n const file = rolesFile(p);\n await mkdir(dirname(file), { recursive: true });\n await writeFile(file, `${JSON.stringify(clean, null, 2)}\\n`);\n return clean;\n}\n\n/** The roles as a config layer: only the roles that were set, so the rest fall through. */\nexport function rolesLayer(r: Roles): Record<string, unknown> | undefined {\n const models: Record<string, unknown> = {};\n const { chat, planner, worker, cheap, helpers } = r.models;\n if (chat?.[0]) models.chat = chat[0];\n if (planner?.length) models.planner = planner;\n if (worker?.length) models.worker = worker;\n if (cheap?.length) models.cheap = cheap;\n if (helpers?.length) models.helpers = helpers;\n if (!r.spreadHelpers) models.spread_helpers = false;\n if (Object.keys(r.strategies).length) models.routing = r.strategies;\n return Object.keys(models).length ? { models } : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
PROVIDER_TEMPLATES,
|
|
4
4
|
appendEndpointBlock
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EDB7FXDP.js";
|
|
6
6
|
import {
|
|
7
7
|
findProviderKey,
|
|
8
8
|
storeKey
|
|
9
9
|
} from "./chunk-TJWLF5MU.js";
|
|
10
10
|
import {
|
|
11
11
|
loadConfig
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NVDO3QO5.js";
|
|
13
13
|
import {
|
|
14
14
|
UsageError,
|
|
15
15
|
resolvePaths,
|
|
@@ -183,4 +183,4 @@ export {
|
|
|
183
183
|
envKeys,
|
|
184
184
|
connectFromEnv
|
|
185
185
|
};
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
186
|
+
//# sourceMappingURL=chunk-3S4ULH6B.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
loadConfig,
|
|
13
13
|
parseDuration
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NVDO3QO5.js";
|
|
15
15
|
import {
|
|
16
16
|
UsageError,
|
|
17
17
|
resolvePaths,
|
|
@@ -277,4 +277,4 @@ export {
|
|
|
277
277
|
removeEndpointBlock,
|
|
278
278
|
register
|
|
279
279
|
};
|
|
280
|
-
//# sourceMappingURL=chunk-
|
|
280
|
+
//# sourceMappingURL=chunk-EDB7FXDP.js.map
|
|
@@ -6,26 +6,26 @@ import {
|
|
|
6
6
|
humanize,
|
|
7
7
|
pickRun,
|
|
8
8
|
supervisorAlive
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IXTUJETQ.js";
|
|
10
10
|
import {
|
|
11
11
|
CodeChat,
|
|
12
12
|
attachImages,
|
|
13
13
|
resolveModelLenient
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LU3LFPGQ.js";
|
|
15
15
|
import {
|
|
16
16
|
emptyTelemetry,
|
|
17
17
|
fold,
|
|
18
18
|
parseFrontmatter,
|
|
19
19
|
resolveRunDeps,
|
|
20
20
|
todoItemsOf
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-IZYY3NPJ.js";
|
|
22
22
|
import {
|
|
23
23
|
RunStore,
|
|
24
24
|
compactPlanView,
|
|
25
25
|
git,
|
|
26
26
|
listRunIds,
|
|
27
27
|
planCounts
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-NV4LO7BY.js";
|
|
29
29
|
import {
|
|
30
30
|
QuotaLedger
|
|
31
31
|
} from "./chunk-DGKPM32R.js";
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
RED,
|
|
37
37
|
filterChoices,
|
|
38
38
|
loadModelChoices
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-STU6YIQJ.js";
|
|
40
40
|
import {
|
|
41
41
|
connect,
|
|
42
42
|
connectFromEnv,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
envKeys,
|
|
45
45
|
findKeyInText,
|
|
46
46
|
looksLikeKey
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-3S4ULH6B.js";
|
|
48
48
|
import {
|
|
49
49
|
findProviderKey,
|
|
50
50
|
maskKey
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
readRanking,
|
|
57
57
|
writePoolMode,
|
|
58
58
|
writeRanking
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-NVDO3QO5.js";
|
|
60
60
|
import {
|
|
61
61
|
UsageError,
|
|
62
62
|
describeError,
|
|
@@ -621,7 +621,7 @@ var Session = class {
|
|
|
621
621
|
}
|
|
622
622
|
/** No provider yet but Ollama is running locally: connect it, so the first chat just works. */
|
|
623
623
|
async autoOllama() {
|
|
624
|
-
const { ollamaModels, pickOllamaModel } = await import("./ollama-
|
|
624
|
+
const { ollamaModels, pickOllamaModel } = await import("./ollama-USDNXHTB.js");
|
|
625
625
|
const model = pickOllamaModel(await ollamaModels(this.io.fetch ?? fetch) ?? []);
|
|
626
626
|
if (!model) return false;
|
|
627
627
|
try {
|
|
@@ -1120,7 +1120,11 @@ var Session = class {
|
|
|
1120
1120
|
}
|
|
1121
1121
|
/** Context in use / the limit chat compacts at, once a chat is open. */
|
|
1122
1122
|
get context() {
|
|
1123
|
-
return this.code ? {
|
|
1123
|
+
return this.code ? {
|
|
1124
|
+
used: this.code.contextUsed,
|
|
1125
|
+
limit: this.code.contextLimit,
|
|
1126
|
+
parts: this.code.contextParts
|
|
1127
|
+
} : void 0;
|
|
1124
1128
|
}
|
|
1125
1129
|
/** True while /pause holds the chat at its next step. */
|
|
1126
1130
|
get chatPaused() {
|
|
@@ -1628,4 +1632,4 @@ export {
|
|
|
1628
1632
|
Session,
|
|
1629
1633
|
helpText
|
|
1630
1634
|
};
|
|
1631
|
-
//# sourceMappingURL=chunk-
|
|
1635
|
+
//# sourceMappingURL=chunk-FNHEOL3X.js.map
|