akemon 0.3.5 → 0.3.7
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/DATA_POLICY.md +128 -0
- package/README.md +156 -19
- package/TRADEMARK.md +74 -0
- package/dist/akemon-home.js +56 -0
- package/dist/akemon-message.js +107 -0
- package/dist/best-effort.js +8 -0
- package/dist/cli.js +1411 -132
- package/dist/cognitive-artifact-store.js +101 -0
- package/dist/cognitive-event-log.js +47 -0
- package/dist/config.js +45 -9
- package/dist/context.js +27 -6
- package/dist/core/contracts/layers.js +1 -0
- package/dist/core/contracts/permission.js +1 -0
- package/dist/core/contracts/workspace.js +1 -0
- package/dist/core-cognitive-module.js +768 -0
- package/dist/engine-peripheral.js +127 -26
- package/dist/engine-routing.js +58 -17
- package/dist/interactive-session.js +361 -0
- package/dist/local-interconnect.js +156 -0
- package/dist/local-registry.js +178 -0
- package/dist/mcp-server.js +4 -1
- package/dist/memory-proposal.js +379 -0
- package/dist/memory-recorder.js +368 -0
- package/dist/orphan-scan.js +36 -24
- package/dist/passive-reflection-cognitive-module.js +172 -0
- package/dist/peripheral-registry.js +235 -0
- package/dist/permission-audit.js +132 -0
- package/dist/relay-client.js +68 -9
- package/dist/relay-mode.js +34 -0
- package/dist/relay-peripheral.js +139 -49
- package/dist/runtime-platform.js +122 -0
- package/dist/secretariat/client.js +87 -0
- package/dist/self.js +15 -6
- package/dist/server.js +3695 -439
- package/dist/social-discovery.js +231 -0
- package/dist/software-agent-peripheral.js +314 -235
- package/dist/software-agent-result-cli.js +69 -0
- package/dist/software-agent-stream-cli.js +23 -0
- package/dist/software-agent-transport.js +177 -0
- package/dist/task-module.js +243 -0
- package/dist/task-registry.js +756 -0
- package/dist/vendor/xterm/addon-fit.js +2 -0
- package/dist/vendor/xterm/addon-search.js +2 -0
- package/dist/vendor/xterm/addon-web-links.js +2 -0
- package/dist/vendor/xterm/xterm.css +285 -0
- package/dist/vendor/xterm/xterm.js +2 -0
- package/dist/work-memory.js +339 -0
- package/dist/workbench-peripheral-guide.js +79 -0
- package/dist/workbench-session.js +1074 -0
- package/dist/workbench.html +4011 -0
- package/package.json +11 -4
- package/scripts/build.cjs +24 -0
- package/scripts/check-architecture-baseline.cjs +68 -0
- package/scripts/test.cjs +38 -0
|
@@ -17,8 +17,20 @@ import { callAgent, sendTaskEnd, sendTaskStart, sendTaskStream } from "./relay-c
|
|
|
17
17
|
import { SIG, sig } from "./types.js";
|
|
18
18
|
import { updateMetrics, pushExecMs } from "./metrics.js";
|
|
19
19
|
import { sendFailureEvent } from "./relay-client.js";
|
|
20
|
+
import { shouldDetachChildProcess, terminateProcessTree } from "./runtime-platform.js";
|
|
20
21
|
import { resolveEngineRoute, } from "./engine-routing.js";
|
|
21
22
|
export const LLM_ENGINES = new Set(["claude", "codex", "opencode", "gemini", "raw"]);
|
|
23
|
+
export function normalizeEngineName(value) {
|
|
24
|
+
const raw = String(value ?? "").trim();
|
|
25
|
+
const cleaned = raw.replace(/[\x00-\x1f\x7f]/g, "").trim();
|
|
26
|
+
if (!cleaned)
|
|
27
|
+
throw new Error("Invalid engine: must not be empty");
|
|
28
|
+
return cleaned;
|
|
29
|
+
}
|
|
30
|
+
function engineIdSegment(engine) {
|
|
31
|
+
const cleaned = engine.replace(/[^a-zA-Z0-9._:-]+/g, "_").replace(/^_+|_+$/g, "");
|
|
32
|
+
return cleaned || "custom";
|
|
33
|
+
}
|
|
22
34
|
const defaultTaskRelay = {
|
|
23
35
|
sendTaskStart,
|
|
24
36
|
sendTaskStream,
|
|
@@ -30,12 +42,15 @@ const defaultTaskRelay = {
|
|
|
30
42
|
export class EnginePeripheral {
|
|
31
43
|
id;
|
|
32
44
|
name;
|
|
45
|
+
engineName;
|
|
33
46
|
capabilities = ["text-in", "text-out"];
|
|
34
47
|
tags = ["engine", "llm"];
|
|
35
48
|
config;
|
|
36
49
|
bus = null;
|
|
37
50
|
/** Last execution trace (for error reporting) */
|
|
38
51
|
lastTrace = [];
|
|
52
|
+
/** Last selected invocation target, used by compute audit logging. */
|
|
53
|
+
lastInvocation = null;
|
|
39
54
|
/** Active CLI child processes — tracked so SIGTERM handler can kill them. */
|
|
40
55
|
activeChildren = new Set();
|
|
41
56
|
/**
|
|
@@ -49,18 +64,17 @@ export class EnginePeripheral {
|
|
|
49
64
|
for (const child of this.activeChildren) {
|
|
50
65
|
if (!child.pid)
|
|
51
66
|
continue;
|
|
52
|
-
console.log(`[engine] shutdown:
|
|
53
|
-
|
|
54
|
-
process.kill(-child.pid, "SIGKILL");
|
|
55
|
-
}
|
|
56
|
-
catch { }
|
|
67
|
+
console.log(`[engine] shutdown: terminating process tree pid=${child.pid}`);
|
|
68
|
+
terminateProcessTree(child.pid, { signal: "SIGKILL" });
|
|
57
69
|
}
|
|
58
70
|
this.activeChildren.clear();
|
|
59
71
|
}
|
|
60
72
|
constructor(config) {
|
|
61
|
-
|
|
62
|
-
this.
|
|
63
|
-
this.
|
|
73
|
+
const engine = normalizeEngineName(config.engine);
|
|
74
|
+
this.config = { ...config, engine };
|
|
75
|
+
this.engineName = engine;
|
|
76
|
+
this.id = `engine:${engineIdSegment(engine)}`;
|
|
77
|
+
this.name = engine === "raw" ? "Local Raw Engine" : `${engine} CLI`;
|
|
64
78
|
}
|
|
65
79
|
get connected() {
|
|
66
80
|
return true; // engines are always "available"
|
|
@@ -100,19 +114,27 @@ export class EnginePeripheral {
|
|
|
100
114
|
// ---------------------------------------------------------------------------
|
|
101
115
|
// Unified engine runner
|
|
102
116
|
// ---------------------------------------------------------------------------
|
|
103
|
-
async runEngine(task, allowAll, extraAllowedTools, signal, origin, routing, taskId, routeRequest) {
|
|
117
|
+
async runEngine(task, allowAll, extraAllowedTools, signal, origin, routing, taskId, routeRequest, engineResources) {
|
|
104
118
|
const resolution = resolveEngineRoute(routing, { origin, ...routeRequest });
|
|
105
119
|
const entry = resolution.entry;
|
|
106
|
-
const cfg = entry ? applyRoutingEntry(this.config, entry) : this.config;
|
|
120
|
+
const cfg = entry ? applyRoutingEntry(this.config, entry, engineResources) : this.config;
|
|
121
|
+
this.lastInvocation = describeEngineInvocation(cfg, resolution.routeId);
|
|
107
122
|
if (origin && entry) {
|
|
108
|
-
|
|
123
|
+
const target = cfg.resourceId || cfg.engine;
|
|
124
|
+
console.log(`[engine] using ${target}${cfg.model ? `/${cfg.model}` : ""} (origin=${origin}, source=${resolution.source})`);
|
|
109
125
|
}
|
|
110
126
|
const t0 = Date.now();
|
|
111
127
|
try {
|
|
112
128
|
if (cfg.engine === "raw") {
|
|
113
129
|
return await this.runRawEngine(task, cfg);
|
|
114
130
|
}
|
|
115
|
-
const cmd =
|
|
131
|
+
const cmd = cfg.cliCommand
|
|
132
|
+
? buildResourceCliCommand(cfg, allowAll ?? cfg.allowAll, extraAllowedTools)
|
|
133
|
+
: buildEngineCommand(cfg.engine, cfg.model, allowAll ?? cfg.allowAll, extraAllowedTools);
|
|
134
|
+
this.lastInvocation = {
|
|
135
|
+
...this.lastInvocation,
|
|
136
|
+
command: [cmd.cmd, ...cmd.args].join(" "),
|
|
137
|
+
};
|
|
116
138
|
return await runCommand(cmd.cmd, cmd.args, task, cfg.workdir, cmd.stdinMode, signal, this.activeChildren, origin, taskId, cfg.taskRelay ?? defaultTaskRelay, cfg.spawnImpl ?? spawn);
|
|
117
139
|
}
|
|
118
140
|
finally {
|
|
@@ -379,8 +401,38 @@ export const RAW_TOOLS = [
|
|
|
379
401
|
* Resolves rawApiKeyEnv → rawApiKey from environment at call time.
|
|
380
402
|
* Never mutates the base config.
|
|
381
403
|
*/
|
|
382
|
-
function applyRoutingEntry(base, entry) {
|
|
383
|
-
const
|
|
404
|
+
function applyRoutingEntry(base, entry, engineResources) {
|
|
405
|
+
const resource = entry.resource ? engineResources?.[entry.resource] : undefined;
|
|
406
|
+
const override = entry.engine ? { engine: entry.engine } : {};
|
|
407
|
+
if (resource) {
|
|
408
|
+
override.resourceId = entry.resource;
|
|
409
|
+
override.resourceKind = resource.kind;
|
|
410
|
+
if (resource.kind === "cli") {
|
|
411
|
+
override.engine = `cli:${entry.resource}`;
|
|
412
|
+
override.cliCommand = resource.command;
|
|
413
|
+
override.cliArgs = resource.args || [];
|
|
414
|
+
override.cliStdin = resource.stdin !== false;
|
|
415
|
+
override.cliModelArg = resource.modelArg;
|
|
416
|
+
if (resource.allowAll !== undefined)
|
|
417
|
+
override.allowAll = resource.allowAll;
|
|
418
|
+
override.model = entry.model ?? resource.defaultModel;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
override.engine = "raw";
|
|
422
|
+
override.provider = resource.provider;
|
|
423
|
+
override.protocol = resource.protocol || "openai_chat_completions";
|
|
424
|
+
override.rawApiUrl = resource.baseUrl;
|
|
425
|
+
if (resource.rawMaxRounds !== undefined)
|
|
426
|
+
override.rawMaxRounds = resource.rawMaxRounds;
|
|
427
|
+
override.model = entry.model ?? resource.defaultModel;
|
|
428
|
+
if (resource.apiKeyEnv)
|
|
429
|
+
override.rawApiKey = process.env[resource.apiKeyEnv] ?? "";
|
|
430
|
+
else if (resource.apiKey !== undefined)
|
|
431
|
+
override.rawApiKey = resource.apiKey;
|
|
432
|
+
else if (resource.credential)
|
|
433
|
+
override.rawApiKey = process.env[credentialEnvName(resource.credential)] ?? "";
|
|
434
|
+
}
|
|
435
|
+
}
|
|
384
436
|
if (entry.model !== undefined)
|
|
385
437
|
override.model = entry.model ?? undefined;
|
|
386
438
|
if (entry.rawApiUrl !== undefined)
|
|
@@ -389,6 +441,10 @@ function applyRoutingEntry(base, entry) {
|
|
|
389
441
|
override.rawMaxRounds = entry.rawMaxRounds;
|
|
390
442
|
if (entry.allowAll !== undefined)
|
|
391
443
|
override.allowAll = entry.allowAll;
|
|
444
|
+
if (entry.reasoningEffort !== undefined)
|
|
445
|
+
override.reasoningEffort = entry.reasoningEffort;
|
|
446
|
+
if (entry.verbosity !== undefined)
|
|
447
|
+
override.verbosity = entry.verbosity;
|
|
392
448
|
// rawApiKeyEnv takes precedence over rawApiKey (env vars preferred for secrets)
|
|
393
449
|
if (entry.rawApiKeyEnv)
|
|
394
450
|
override.rawApiKey = process.env[entry.rawApiKeyEnv] ?? "";
|
|
@@ -396,6 +452,9 @@ function applyRoutingEntry(base, entry) {
|
|
|
396
452
|
override.rawApiKey = entry.rawApiKey;
|
|
397
453
|
return { ...base, ...override };
|
|
398
454
|
}
|
|
455
|
+
function credentialEnvName(credential) {
|
|
456
|
+
return `${credential.trim().replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase()}_API_KEY`;
|
|
457
|
+
}
|
|
399
458
|
function buildEngineCommand(engine, model, allowAll, extraAllowedTools) {
|
|
400
459
|
switch (engine) {
|
|
401
460
|
case "claude": {
|
|
@@ -428,6 +487,57 @@ function buildEngineCommand(engine, model, allowAll, extraAllowedTools) {
|
|
|
428
487
|
return { cmd: engine, args: [], stdinMode: true };
|
|
429
488
|
}
|
|
430
489
|
}
|
|
490
|
+
function buildResourceCliCommand(cfg, _allowAll, _extraAllowedTools) {
|
|
491
|
+
const args = [...(cfg.cliArgs || [])];
|
|
492
|
+
if (cfg.model && cfg.cliModelArg)
|
|
493
|
+
args.push(cfg.cliModelArg, cfg.model);
|
|
494
|
+
return {
|
|
495
|
+
cmd: cfg.cliCommand || cfg.engine,
|
|
496
|
+
args,
|
|
497
|
+
stdinMode: cfg.cliStdin !== false,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function describeEngineInvocation(cfg, routeId) {
|
|
501
|
+
if (cfg.engine === "raw") {
|
|
502
|
+
const apiUrl = `${cfg.rawApiUrl || "http://localhost:11434/v1"}/chat/completions`;
|
|
503
|
+
return {
|
|
504
|
+
routeId,
|
|
505
|
+
resourceId: cfg.resourceId,
|
|
506
|
+
resourceKind: cfg.resourceKind,
|
|
507
|
+
provider: cfg.provider,
|
|
508
|
+
protocol: cfg.protocol || "openai_chat_completions",
|
|
509
|
+
engine: cfg.engine,
|
|
510
|
+
model: cfg.model,
|
|
511
|
+
reasoningEffort: cfg.reasoningEffort,
|
|
512
|
+
verbosity: cfg.verbosity,
|
|
513
|
+
command: `POST ${apiUrl}`,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
if (cfg.cliCommand) {
|
|
517
|
+
const cmd = buildResourceCliCommand(cfg);
|
|
518
|
+
return {
|
|
519
|
+
routeId,
|
|
520
|
+
resourceId: cfg.resourceId,
|
|
521
|
+
resourceKind: cfg.resourceKind,
|
|
522
|
+
engine: cfg.engine,
|
|
523
|
+
model: cfg.model,
|
|
524
|
+
reasoningEffort: cfg.reasoningEffort,
|
|
525
|
+
verbosity: cfg.verbosity,
|
|
526
|
+
command: [cmd.cmd, ...cmd.args].join(" "),
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
const cmd = buildEngineCommand(cfg.engine, cfg.model, cfg.allowAll);
|
|
530
|
+
return {
|
|
531
|
+
routeId,
|
|
532
|
+
resourceId: cfg.resourceId,
|
|
533
|
+
resourceKind: cfg.resourceKind || "cli",
|
|
534
|
+
engine: cfg.engine,
|
|
535
|
+
model: cfg.model,
|
|
536
|
+
reasoningEffort: cfg.reasoningEffort,
|
|
537
|
+
verbosity: cfg.verbosity,
|
|
538
|
+
command: [cmd.cmd, ...cmd.args].join(" "),
|
|
539
|
+
};
|
|
540
|
+
}
|
|
431
541
|
function runCommand(cmd, args, task, cwd, stdinMode = true, signal, activeChildren, origin, taskId, taskRelay = defaultTaskRelay, spawnImpl = spawn) {
|
|
432
542
|
return new Promise((resolve, reject) => {
|
|
433
543
|
const { CLAUDECODE, ...cleanEnv } = process.env;
|
|
@@ -450,7 +560,7 @@ function runCommand(cmd, args, task, cwd, stdinMode = true, signal, activeChildr
|
|
|
450
560
|
cwd,
|
|
451
561
|
env: cleanEnv,
|
|
452
562
|
stdio: [stdinMode ? "pipe" : "ignore", "pipe", "pipe"],
|
|
453
|
-
detached:
|
|
563
|
+
detached: shouldDetachChildProcess(),
|
|
454
564
|
});
|
|
455
565
|
}
|
|
456
566
|
catch (err) {
|
|
@@ -470,18 +580,9 @@ function runCommand(cmd, args, task, cwd, stdinMode = true, signal, activeChildr
|
|
|
470
580
|
if (aborted || !child.pid)
|
|
471
581
|
return;
|
|
472
582
|
aborted = true;
|
|
473
|
-
console.log(`[${cmd}] aborted,
|
|
583
|
+
console.log(`[${cmd}] aborted, terminating process tree pid=${child.pid}`);
|
|
474
584
|
sendFailureEvent("engine_abort", cmd, "engine subprocess aborted via signal");
|
|
475
|
-
|
|
476
|
-
process.kill(-child.pid, "SIGTERM");
|
|
477
|
-
}
|
|
478
|
-
catch { }
|
|
479
|
-
setTimeout(() => {
|
|
480
|
-
try {
|
|
481
|
-
process.kill(-child.pid, "SIGKILL");
|
|
482
|
-
}
|
|
483
|
-
catch { }
|
|
484
|
-
}, 3000).unref();
|
|
585
|
+
terminateProcessTree(child.pid, { signal: "SIGTERM", forceAfterMs: 3000 });
|
|
485
586
|
};
|
|
486
587
|
if (signal) {
|
|
487
588
|
if (signal.aborted)
|
package/dist/engine-routing.js
CHANGED
|
@@ -42,15 +42,20 @@ export function resolveEngineRoute(routing, request = {}) {
|
|
|
42
42
|
}
|
|
43
43
|
const route = selectRoute(routing.routes, request);
|
|
44
44
|
if (route) {
|
|
45
|
+
const entry = stripRouteMetadata(route);
|
|
45
46
|
return {
|
|
46
|
-
entry
|
|
47
|
+
entry,
|
|
48
|
+
routeId: route.id,
|
|
49
|
+
resourceId: entry.resource,
|
|
47
50
|
source: "route",
|
|
48
51
|
reason: "matched registry route",
|
|
49
52
|
};
|
|
50
53
|
}
|
|
51
54
|
if (request.origin && routing[request.origin]) {
|
|
55
|
+
const entry = routing[request.origin];
|
|
52
56
|
return {
|
|
53
|
-
entry
|
|
57
|
+
entry,
|
|
58
|
+
resourceId: entry.resource,
|
|
54
59
|
source: "origin",
|
|
55
60
|
reason: `matched legacy origin route ${request.origin}`,
|
|
56
61
|
};
|
|
@@ -58,10 +63,19 @@ export function resolveEngineRoute(routing, request = {}) {
|
|
|
58
63
|
if (routing.default) {
|
|
59
64
|
return {
|
|
60
65
|
entry: routing.default,
|
|
66
|
+
resourceId: routing.default.resource,
|
|
61
67
|
source: "default",
|
|
62
68
|
reason: "matched legacy default route",
|
|
63
69
|
};
|
|
64
70
|
}
|
|
71
|
+
if (routing.defaultResource) {
|
|
72
|
+
return {
|
|
73
|
+
entry: { resource: routing.defaultResource },
|
|
74
|
+
resourceId: routing.defaultResource,
|
|
75
|
+
source: "default",
|
|
76
|
+
reason: "matched default resource",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
65
79
|
return { entry: null, source: "none", reason: "no matching route" };
|
|
66
80
|
}
|
|
67
81
|
/**
|
|
@@ -103,15 +117,24 @@ function selectRoute(routes, request) {
|
|
|
103
117
|
return best?.route ?? null;
|
|
104
118
|
}
|
|
105
119
|
function routeMatches(route, request) {
|
|
106
|
-
|
|
120
|
+
const match = route.match;
|
|
121
|
+
const origins = match?.origins ?? route.origins;
|
|
122
|
+
const taskKinds = match?.taskKinds ?? route.taskKinds;
|
|
123
|
+
const capabilities = match?.requiredCapabilities ?? route.capabilities;
|
|
124
|
+
const privacy = match?.privacy ?? route.privacy;
|
|
125
|
+
const maxCost = match?.maxCost ?? route.cost;
|
|
126
|
+
const maxLatency = match?.maxLatency ?? route.latency;
|
|
127
|
+
if (request.origin && origins?.length && !origins.includes(request.origin))
|
|
128
|
+
return false;
|
|
129
|
+
if (taskKinds?.length && (!request.taskKind || !taskKinds.includes(request.taskKind)))
|
|
107
130
|
return false;
|
|
108
|
-
if (!hasRequiredCapabilities(
|
|
131
|
+
if (!hasRequiredCapabilities(capabilities, request.requiredCapabilities))
|
|
109
132
|
return false;
|
|
110
|
-
if (request.privacy &&
|
|
133
|
+
if (request.privacy && privacy && privacy !== request.privacy)
|
|
111
134
|
return false;
|
|
112
|
-
if (request.maxCost &&
|
|
135
|
+
if (request.maxCost && maxCost && tierRank(maxCost) > tierRank(request.maxCost))
|
|
113
136
|
return false;
|
|
114
|
-
if (request.maxLatency &&
|
|
137
|
+
if (request.maxLatency && maxLatency && tierRank(maxLatency) > tierRank(request.maxLatency))
|
|
115
138
|
return false;
|
|
116
139
|
return true;
|
|
117
140
|
}
|
|
@@ -124,23 +147,41 @@ function hasRequiredCapabilities(available, required) {
|
|
|
124
147
|
}
|
|
125
148
|
function scoreRoute(route, request) {
|
|
126
149
|
let score = route.priority ?? 0;
|
|
127
|
-
|
|
150
|
+
const match = route.match;
|
|
151
|
+
const origins = match?.origins ?? route.origins;
|
|
152
|
+
const taskKinds = match?.taskKinds ?? route.taskKinds;
|
|
153
|
+
const capabilities = match?.requiredCapabilities ?? route.capabilities;
|
|
154
|
+
const privacy = match?.privacy ?? route.privacy;
|
|
155
|
+
const cost = match?.maxCost ?? route.cost;
|
|
156
|
+
const latency = match?.maxLatency ?? route.latency;
|
|
157
|
+
if (request.taskKind && taskKinds?.includes(request.taskKind))
|
|
158
|
+
score += 120;
|
|
159
|
+
if (request.origin && origins?.includes(request.origin))
|
|
128
160
|
score += 100;
|
|
129
|
-
if (request.origin && !
|
|
161
|
+
if (request.origin && !origins?.length)
|
|
130
162
|
score += 10;
|
|
131
163
|
if (request.requiredCapabilities?.length)
|
|
132
|
-
score += (
|
|
133
|
-
if (request.privacy &&
|
|
164
|
+
score += (capabilities?.length || 0) * 2;
|
|
165
|
+
if (request.privacy && privacy === request.privacy)
|
|
134
166
|
score += 20;
|
|
135
|
-
if (
|
|
136
|
-
score += 6 - tierRank(
|
|
137
|
-
if (
|
|
138
|
-
score += 6 - tierRank(
|
|
167
|
+
if (cost)
|
|
168
|
+
score += 6 - tierRank(cost);
|
|
169
|
+
if (latency)
|
|
170
|
+
score += 6 - tierRank(latency);
|
|
139
171
|
return score;
|
|
140
172
|
}
|
|
141
173
|
function stripRouteMetadata(route) {
|
|
142
|
-
const { origins: _origins, priority: _priority, ...entry } = route;
|
|
143
|
-
return
|
|
174
|
+
const { id, origins: _origins, taskKinds: _taskKinds, priority: _priority, match: _match, use, ...entry } = route;
|
|
175
|
+
return {
|
|
176
|
+
...entry,
|
|
177
|
+
...(id ? { routeId: id } : {}),
|
|
178
|
+
...(use?.resource ? { resource: use.resource } : {}),
|
|
179
|
+
...(use?.model !== undefined ? { model: use.model } : {}),
|
|
180
|
+
...(use?.allowAll !== undefined ? { allowAll: use.allowAll } : {}),
|
|
181
|
+
...(use?.rawMaxRounds !== undefined ? { rawMaxRounds: use.rawMaxRounds } : {}),
|
|
182
|
+
...(use?.reasoningEffort !== undefined ? { reasoningEffort: use.reasoningEffort } : {}),
|
|
183
|
+
...(use?.verbosity !== undefined ? { verbosity: use.verbosity } : {}),
|
|
184
|
+
};
|
|
144
185
|
}
|
|
145
186
|
function tierRank(tier) {
|
|
146
187
|
switch (tier) {
|