@slock-ai/daemon 0.57.1-play.20260607140323 → 0.57.2
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/{chunk-4PZVJXRJ.js → chunk-EKSATDT3.js} +426 -175
- package/dist/cli/index.js +80 -5
- package/dist/core.js +1 -5
- package/dist/index.js +3 -5
- package/package.json +1 -1
- package/dist/drivers/piSdkRunner.js +0 -96
|
@@ -351,40 +351,127 @@ var NoopActiveSpan = class {
|
|
|
351
351
|
}
|
|
352
352
|
};
|
|
353
353
|
var noopTracer = new NoopTracer();
|
|
354
|
-
function
|
|
354
|
+
function projectTraceScopeAttrs(scope) {
|
|
355
|
+
const attrs = {};
|
|
356
|
+
addOptionalStringAttr(attrs, "daemon_version", scope.resource?.daemonVersion);
|
|
357
|
+
addPresenceAttr(attrs, "daemon_version_present", scope.resource?.daemonVersion);
|
|
358
|
+
addOptionalStringAttr(attrs, "computer_version", scope.resource?.computerVersion);
|
|
359
|
+
addPresenceAttr(attrs, "computer_version_present", scope.resource?.computerVersion);
|
|
360
|
+
addOptionalStringAttr(attrs, "deployment_environment", scope.resource?.deploymentEnvironment);
|
|
361
|
+
addOptionalStringAttr(attrs, "service_revision", scope.resource?.serviceRevision);
|
|
362
|
+
addOptionalStringAttr(attrs, "request_id", scope.request?.requestId);
|
|
363
|
+
addPresenceAttr(attrs, "request_id_present", scope.request?.requestId);
|
|
364
|
+
addOptionalStringAttr(attrs, "route_pattern", scope.request?.routePattern);
|
|
365
|
+
addOptionalStringAttr(attrs, "method", scope.request?.method);
|
|
366
|
+
addOptionalStringAttr(attrs, "caller_kind", scope.request?.callerKind);
|
|
367
|
+
if (typeof scope.request?.userIdPresent === "boolean") {
|
|
368
|
+
attrs.user_id_present = scope.request.userIdPresent;
|
|
369
|
+
}
|
|
370
|
+
addOptionalStringAttr(attrs, "server_id", scope.actor?.serverId);
|
|
371
|
+
addPresenceAttr(attrs, "server_id_present", scope.actor?.serverId, scope.actor?.serverIdPresent);
|
|
372
|
+
addOptionalStringAttr(attrs, "machine_id", scope.actor?.machineId);
|
|
373
|
+
addPresenceAttr(attrs, "machine_id_present", scope.actor?.machineId, scope.actor?.machineIdPresent);
|
|
374
|
+
addOptionalStringAttr(attrs, "agent_id", scope.actor?.agentId);
|
|
375
|
+
addPresenceAttr(attrs, "agent_id_present", scope.actor?.agentId, scope.actor?.agentIdPresent);
|
|
376
|
+
addOptionalStringAttr(attrs, "launch_id", scope.actor?.launchId);
|
|
377
|
+
addPresenceAttr(attrs, "launch_id_present", scope.actor?.launchId, scope.actor?.launchIdPresent);
|
|
378
|
+
addOptionalStringAttr(attrs, "session_id", scope.actor?.sessionId);
|
|
379
|
+
addPresenceAttr(attrs, "session_id_present", scope.actor?.sessionId, scope.actor?.sessionIdPresent);
|
|
380
|
+
return attrs;
|
|
381
|
+
}
|
|
382
|
+
function createTraceScopeTracer(tracer, scope, options = {}) {
|
|
383
|
+
const scopedTracer = createScopedTracer(tracer, projectTraceScopeAttrs(scope), {
|
|
384
|
+
attrPrecedence: options.scopeAttrPrecedence
|
|
385
|
+
});
|
|
386
|
+
return options.spanAttrContracts ? createSpanAttrContractTracer(scopedTracer, options.spanAttrContracts) : scopedTracer;
|
|
387
|
+
}
|
|
388
|
+
function createScopedTracer(tracer, scopeAttrs, options = {}) {
|
|
355
389
|
if (!Object.keys(scopeAttrs).length) return tracer;
|
|
356
|
-
return new ScopedTracer(tracer, scopeAttrs);
|
|
390
|
+
return new ScopedTracer(tracer, scopeAttrs, options.attrPrecedence ?? "scope");
|
|
357
391
|
}
|
|
358
392
|
var ScopedTracer = class {
|
|
359
|
-
constructor(tracer, scopeAttrs) {
|
|
393
|
+
constructor(tracer, scopeAttrs, attrPrecedence) {
|
|
360
394
|
this.tracer = tracer;
|
|
361
395
|
this.scopeAttrs = scopeAttrs;
|
|
396
|
+
this.attrPrecedence = attrPrecedence;
|
|
362
397
|
}
|
|
363
398
|
startSpan(name, options) {
|
|
364
399
|
const span = this.tracer.startSpan(name, {
|
|
365
400
|
...options,
|
|
366
|
-
attrs:
|
|
401
|
+
attrs: this.mergeScopeAttrs(options.attrs)
|
|
367
402
|
});
|
|
368
|
-
return new ScopedActiveSpan(span, this.scopeAttrs);
|
|
403
|
+
return new ScopedActiveSpan(span, this.scopeAttrs, this.attrPrecedence);
|
|
404
|
+
}
|
|
405
|
+
mergeScopeAttrs(attrs) {
|
|
406
|
+
return this.attrPrecedence === "caller" ? mergeAttrs(this.scopeAttrs, attrs) : mergeAttrs(attrs, this.scopeAttrs);
|
|
369
407
|
}
|
|
370
408
|
};
|
|
371
409
|
var ScopedActiveSpan = class {
|
|
372
|
-
constructor(span, scopeAttrs) {
|
|
410
|
+
constructor(span, scopeAttrs, attrPrecedence) {
|
|
373
411
|
this.span = span;
|
|
374
412
|
this.scopeAttrs = scopeAttrs;
|
|
413
|
+
this.attrPrecedence = attrPrecedence;
|
|
375
414
|
this.context = span.context;
|
|
376
415
|
}
|
|
377
416
|
context;
|
|
378
417
|
addEvent(name, attrs) {
|
|
379
|
-
this.span.addEvent(name,
|
|
418
|
+
this.span.addEvent(name, this.mergeScopeAttrs(attrs));
|
|
380
419
|
}
|
|
381
420
|
end(status, options) {
|
|
382
421
|
this.span.end(status, options ? {
|
|
383
422
|
...options,
|
|
384
|
-
attrs:
|
|
423
|
+
attrs: this.mergeScopeAttrs(options.attrs)
|
|
385
424
|
} : void 0);
|
|
386
425
|
}
|
|
426
|
+
mergeScopeAttrs(attrs) {
|
|
427
|
+
return this.attrPrecedence === "caller" ? mergeAttrs(this.scopeAttrs, attrs) : mergeAttrs(attrs, this.scopeAttrs);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function createSpanAttrContractTracer(tracer, contracts) {
|
|
431
|
+
if (!Object.keys(contracts).length) return tracer;
|
|
432
|
+
return new SpanAttrContractTracer(tracer, contracts);
|
|
433
|
+
}
|
|
434
|
+
var SpanAttrContractTracer = class {
|
|
435
|
+
constructor(tracer, contracts) {
|
|
436
|
+
this.tracer = tracer;
|
|
437
|
+
this.contracts = contracts;
|
|
438
|
+
}
|
|
439
|
+
startSpan(name, options) {
|
|
440
|
+
const contract = this.contracts[name];
|
|
441
|
+
if (!contract) return this.tracer.startSpan(name, options);
|
|
442
|
+
const span = this.tracer.startSpan(name, {
|
|
443
|
+
...options,
|
|
444
|
+
attrs: filterTraceAttrs(options.attrs, contract.spanAttrs)
|
|
445
|
+
});
|
|
446
|
+
return new SpanAttrContractActiveSpan(span, contract);
|
|
447
|
+
}
|
|
387
448
|
};
|
|
449
|
+
var SpanAttrContractActiveSpan = class {
|
|
450
|
+
constructor(span, contract) {
|
|
451
|
+
this.span = span;
|
|
452
|
+
this.contract = contract;
|
|
453
|
+
this.context = span.context;
|
|
454
|
+
}
|
|
455
|
+
context;
|
|
456
|
+
addEvent(name, attrs) {
|
|
457
|
+
this.span.addEvent(name, filterTraceAttrs(attrs, this.contract.eventAttrs?.[name]));
|
|
458
|
+
}
|
|
459
|
+
end(status, options) {
|
|
460
|
+
this.span.end(status, options ? {
|
|
461
|
+
...options,
|
|
462
|
+
attrs: filterTraceAttrs(options.attrs, this.contract.endAttrs)
|
|
463
|
+
} : void 0);
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
function filterTraceAttrs(attrs, allowedKeys) {
|
|
467
|
+
if (!attrs || !allowedKeys) return attrs;
|
|
468
|
+
const allowed = new Set(allowedKeys);
|
|
469
|
+
const filtered = {};
|
|
470
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
471
|
+
if (allowed.has(key)) filtered[key] = value;
|
|
472
|
+
}
|
|
473
|
+
return Object.keys(filtered).length ? filtered : void 0;
|
|
474
|
+
}
|
|
388
475
|
var BasicTracer = class {
|
|
389
476
|
sink;
|
|
390
477
|
clock;
|
|
@@ -482,6 +569,14 @@ function mergeAttrs(base, extra) {
|
|
|
482
569
|
if (!extra) return base;
|
|
483
570
|
return { ...base, ...extra };
|
|
484
571
|
}
|
|
572
|
+
function addOptionalStringAttr(attrs, key, value) {
|
|
573
|
+
const normalized = value?.trim();
|
|
574
|
+
if (!normalized) return;
|
|
575
|
+
attrs[key] = normalized;
|
|
576
|
+
}
|
|
577
|
+
function addPresenceAttr(attrs, key, value, explicitPresent) {
|
|
578
|
+
attrs[key] = typeof explicitPresent === "boolean" ? explicitPresent : Boolean(value?.trim());
|
|
579
|
+
}
|
|
485
580
|
function generateTraceId() {
|
|
486
581
|
return randomNonZeroHex(TRACE_ID_HEX_LENGTH);
|
|
487
582
|
}
|
|
@@ -1046,6 +1141,9 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
1046
1141
|
|
|
1047
1142
|
// ../shared/src/index.ts
|
|
1048
1143
|
var RUNTIME_CONFIG_VERSION = 1;
|
|
1144
|
+
var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
1145
|
+
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
1146
|
+
var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
|
|
1049
1147
|
var RUNTIMES = [
|
|
1050
1148
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
1051
1149
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
@@ -1058,6 +1156,9 @@ var RUNTIMES = [
|
|
|
1058
1156
|
{ id: "pi", displayName: "Pi", binary: "pi", supported: true }
|
|
1059
1157
|
];
|
|
1060
1158
|
var RUNTIME_MODELS = {
|
|
1159
|
+
[EXTERNAL_AGENT_RUNTIME_ID]: [
|
|
1160
|
+
{ id: EXTERNAL_AGENT_RUNTIME_MODEL, label: EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME }
|
|
1161
|
+
],
|
|
1061
1162
|
claude: [
|
|
1062
1163
|
{ id: "opus", label: "Claude Opus" },
|
|
1063
1164
|
{ id: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
@@ -1980,19 +2081,6 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
1980
2081
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
1981
2082
|
}
|
|
1982
2083
|
|
|
1983
|
-
// src/authEnv.ts
|
|
1984
|
-
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
1985
|
-
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
1986
|
-
function scrubDaemonAuthEnv(env) {
|
|
1987
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1988
|
-
return env;
|
|
1989
|
-
}
|
|
1990
|
-
function scrubDaemonChildEnv(env) {
|
|
1991
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1992
|
-
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
1993
|
-
return env;
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
2084
|
// src/agentCredentialProxy.ts
|
|
1997
2085
|
import { randomBytes } from "crypto";
|
|
1998
2086
|
import http from "http";
|
|
@@ -3479,9 +3567,7 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
|
|
|
3479
3567
|
var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
|
|
3480
3568
|
var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
3481
3569
|
var RAW_CREDENTIAL_ENV_DENYLIST = [
|
|
3482
|
-
"
|
|
3483
|
-
"SLOCK_AGENT_CREDENTIAL_KEY",
|
|
3484
|
-
"SLOCK_AGENT_CREDENTIAL_KEY_FILE"
|
|
3570
|
+
"SLOCK_AGENT_CREDENTIAL_KEY"
|
|
3485
3571
|
];
|
|
3486
3572
|
var cachedOpencliBinPath;
|
|
3487
3573
|
function resolveOpencliBinPath() {
|
|
@@ -3696,7 +3782,7 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(opencliBinPath)} "
|
|
|
3696
3782
|
...agentCredentialProxy ? {} : { SLOCK_AGENT_TOKEN_FILE: tokenFile },
|
|
3697
3783
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
3698
3784
|
};
|
|
3699
|
-
|
|
3785
|
+
delete spawnEnv.SLOCK_AGENT_TOKEN;
|
|
3700
3786
|
for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
|
|
3701
3787
|
delete spawnEnv[key];
|
|
3702
3788
|
}
|
|
@@ -4125,7 +4211,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn) {
|
|
|
4125
4211
|
}
|
|
4126
4212
|
function resolveCommandOnPath(command, deps = {}) {
|
|
4127
4213
|
const platform = deps.platform ?? process.platform;
|
|
4128
|
-
const env =
|
|
4214
|
+
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4129
4215
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4130
4216
|
const existsSyncFn = deps.existsSyncFn ?? existsSync2;
|
|
4131
4217
|
if (platform === "win32") {
|
|
@@ -4151,7 +4237,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
4151
4237
|
return null;
|
|
4152
4238
|
}
|
|
4153
4239
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
4154
|
-
const env =
|
|
4240
|
+
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4155
4241
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4156
4242
|
try {
|
|
4157
4243
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -5505,11 +5591,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
5505
5591
|
return parseCursorModelsOutput(String(result.stdout || ""));
|
|
5506
5592
|
}
|
|
5507
5593
|
function buildCursorModelProbeEnv(deps = {}) {
|
|
5508
|
-
return
|
|
5594
|
+
return withWindowsUserEnvironment({
|
|
5509
5595
|
...deps.env ?? process.env,
|
|
5510
5596
|
FORCE_COLOR: "0",
|
|
5511
5597
|
NO_COLOR: "1"
|
|
5512
|
-
}, deps)
|
|
5598
|
+
}, deps);
|
|
5513
5599
|
}
|
|
5514
5600
|
function runCursorModelsCommand() {
|
|
5515
5601
|
return spawnSync("cursor-agent", ["models"], {
|
|
@@ -5565,7 +5651,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
5565
5651
|
}
|
|
5566
5652
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
5567
5653
|
const existsSyncFn = deps.existsSyncFn ?? existsSync4;
|
|
5568
|
-
const env =
|
|
5654
|
+
const env = deps.env ?? process.env;
|
|
5569
5655
|
const winPath = path6.win32;
|
|
5570
5656
|
let geminiEntry = null;
|
|
5571
5657
|
try {
|
|
@@ -5705,15 +5791,12 @@ var GeminiDriver = class {
|
|
|
5705
5791
|
// src/drivers/kimi.ts
|
|
5706
5792
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5707
5793
|
import { spawn as spawn7 } from "child_process";
|
|
5708
|
-
import {
|
|
5794
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
5709
5795
|
import os3 from "os";
|
|
5710
5796
|
import path7 from "path";
|
|
5711
5797
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
5712
5798
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
5713
5799
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
5714
|
-
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
5715
|
-
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
5716
|
-
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
5717
5800
|
function parseToolArguments(raw) {
|
|
5718
5801
|
if (typeof raw !== "string") return raw;
|
|
5719
5802
|
try {
|
|
@@ -5722,73 +5805,6 @@ function parseToolArguments(raw) {
|
|
|
5722
5805
|
return raw;
|
|
5723
5806
|
}
|
|
5724
5807
|
}
|
|
5725
|
-
function readKimiConfigSource(home = os3.homedir(), env = process.env) {
|
|
5726
|
-
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5727
|
-
if (inlineConfig && inlineConfig.trim()) {
|
|
5728
|
-
return {
|
|
5729
|
-
raw: inlineConfig,
|
|
5730
|
-
explicitPath: null,
|
|
5731
|
-
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
5732
|
-
};
|
|
5733
|
-
}
|
|
5734
|
-
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5735
|
-
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path7.join(home, ".kimi", "config.toml");
|
|
5736
|
-
try {
|
|
5737
|
-
return {
|
|
5738
|
-
raw: readFileSync3(configPath, "utf8"),
|
|
5739
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5740
|
-
sourcePath: configPath
|
|
5741
|
-
};
|
|
5742
|
-
} catch {
|
|
5743
|
-
return {
|
|
5744
|
-
raw: null,
|
|
5745
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5746
|
-
sourcePath: configPath
|
|
5747
|
-
};
|
|
5748
|
-
}
|
|
5749
|
-
}
|
|
5750
|
-
function buildKimiSpawnEnv(env = process.env) {
|
|
5751
|
-
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
5752
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5753
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5754
|
-
return scrubDaemonChildEnv(spawnEnv);
|
|
5755
|
-
}
|
|
5756
|
-
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
5757
|
-
return {
|
|
5758
|
-
...process.env,
|
|
5759
|
-
...ctx.config.envVars || {},
|
|
5760
|
-
...overrideEnv || {}
|
|
5761
|
-
};
|
|
5762
|
-
}
|
|
5763
|
-
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
5764
|
-
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
5765
|
-
const source = readKimiConfigSource(opts.home ?? os3.homedir(), env);
|
|
5766
|
-
const args = [];
|
|
5767
|
-
let configFilePath = null;
|
|
5768
|
-
let configContent = null;
|
|
5769
|
-
if (source.explicitPath) {
|
|
5770
|
-
configFilePath = source.explicitPath;
|
|
5771
|
-
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
5772
|
-
configFilePath = path7.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
5773
|
-
configContent = source.raw;
|
|
5774
|
-
if (opts.writeGeneratedConfig !== false) {
|
|
5775
|
-
writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
5776
|
-
chmodSync(configFilePath, 384);
|
|
5777
|
-
}
|
|
5778
|
-
}
|
|
5779
|
-
if (configFilePath) {
|
|
5780
|
-
args.push("--config-file", configFilePath);
|
|
5781
|
-
}
|
|
5782
|
-
if (ctx.config.model && ctx.config.model !== "default") {
|
|
5783
|
-
args.push("--model", ctx.config.model);
|
|
5784
|
-
}
|
|
5785
|
-
return {
|
|
5786
|
-
args,
|
|
5787
|
-
env: buildKimiSpawnEnv(env),
|
|
5788
|
-
configFilePath,
|
|
5789
|
-
configContent
|
|
5790
|
-
};
|
|
5791
|
-
}
|
|
5792
5808
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
5793
5809
|
return {
|
|
5794
5810
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -5812,25 +5828,7 @@ var KimiDriver = class {
|
|
|
5812
5828
|
};
|
|
5813
5829
|
model = {
|
|
5814
5830
|
detectedModelsVerifiedAs: "launchable",
|
|
5815
|
-
toLaunchSpec: (modelId
|
|
5816
|
-
if (!ctx) return { args: ["--model", modelId] };
|
|
5817
|
-
const launchCtx = {
|
|
5818
|
-
...ctx,
|
|
5819
|
-
config: {
|
|
5820
|
-
...ctx.config,
|
|
5821
|
-
model: modelId
|
|
5822
|
-
}
|
|
5823
|
-
};
|
|
5824
|
-
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
5825
|
-
home: opts?.home,
|
|
5826
|
-
writeGeneratedConfig: false
|
|
5827
|
-
});
|
|
5828
|
-
return {
|
|
5829
|
-
args: launch.args,
|
|
5830
|
-
env: launch.env,
|
|
5831
|
-
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
5832
|
-
};
|
|
5833
|
-
}
|
|
5831
|
+
toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
|
|
5834
5832
|
};
|
|
5835
5833
|
supportsStdinNotification = true;
|
|
5836
5834
|
mcpToolPrefix = "";
|
|
@@ -5856,23 +5854,21 @@ var KimiDriver = class {
|
|
|
5856
5854
|
` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
|
|
5857
5855
|
""
|
|
5858
5856
|
].join("\n"), "utf8");
|
|
5859
|
-
const launch = buildKimiLaunchOptions(ctx);
|
|
5860
5857
|
const args = [
|
|
5861
5858
|
"--wire",
|
|
5862
5859
|
"--yolo",
|
|
5863
5860
|
"--agent-file",
|
|
5864
5861
|
agentFilePath,
|
|
5865
5862
|
"--session",
|
|
5866
|
-
this.sessionId
|
|
5867
|
-
...launch.args
|
|
5863
|
+
this.sessionId
|
|
5868
5864
|
];
|
|
5869
5865
|
const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
|
|
5870
5866
|
if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
|
|
5871
5867
|
args.push("--model", launchRuntimeFields.model);
|
|
5872
5868
|
}
|
|
5873
5869
|
const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
5874
|
-
const
|
|
5875
|
-
const proc = spawn7(
|
|
5870
|
+
const launch = resolveKimiSpawn(args);
|
|
5871
|
+
const proc = spawn7(launch.command, launch.args, {
|
|
5876
5872
|
cwd: ctx.workingDirectory,
|
|
5877
5873
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5878
5874
|
env: spawnEnv,
|
|
@@ -5880,7 +5876,7 @@ var KimiDriver = class {
|
|
|
5880
5876
|
// and has an 8191-character command-line limit. Kimi's official
|
|
5881
5877
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
5882
5878
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
5883
|
-
shell:
|
|
5879
|
+
shell: launch.shell
|
|
5884
5880
|
});
|
|
5885
5881
|
proc.stdin?.write(JSON.stringify({
|
|
5886
5882
|
jsonrpc: "2.0",
|
|
@@ -5994,9 +5990,14 @@ var KimiDriver = class {
|
|
|
5994
5990
|
return detectKimiModels();
|
|
5995
5991
|
}
|
|
5996
5992
|
};
|
|
5997
|
-
function detectKimiModels(home = os3.homedir()
|
|
5998
|
-
const
|
|
5999
|
-
|
|
5993
|
+
function detectKimiModels(home = os3.homedir()) {
|
|
5994
|
+
const configPath = path7.join(home, ".kimi", "config.toml");
|
|
5995
|
+
let raw;
|
|
5996
|
+
try {
|
|
5997
|
+
raw = readFileSync3(configPath, "utf8");
|
|
5998
|
+
} catch {
|
|
5999
|
+
return null;
|
|
6000
|
+
}
|
|
6000
6001
|
const models = [];
|
|
6001
6002
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
6002
6003
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -6236,7 +6237,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
6236
6237
|
const platform = deps.platform ?? process.platform;
|
|
6237
6238
|
const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
|
|
6238
6239
|
const result = spawnSyncFn("opencode", ["models"], {
|
|
6239
|
-
env:
|
|
6240
|
+
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
6240
6241
|
encoding: "utf8",
|
|
6241
6242
|
timeout: 5e3,
|
|
6242
6243
|
shell: platform === "win32"
|
|
@@ -7481,16 +7482,19 @@ var RuntimeProgressState = class {
|
|
|
7481
7482
|
};
|
|
7482
7483
|
|
|
7483
7484
|
// src/runtimeNotificationState.ts
|
|
7485
|
+
function inboxNoticeMessageIdentity(message) {
|
|
7486
|
+
const seq = typeof message.seq === "number" && Number.isFinite(message.seq) && message.seq > 0 ? Math.floor(message.seq) : null;
|
|
7487
|
+
if (seq !== null) {
|
|
7488
|
+
return `s:${seq}`;
|
|
7489
|
+
}
|
|
7490
|
+
const id = typeof message.message_id === "string" && message.message_id.length > 0 ? message.message_id : typeof message.id === "string" && message.id.length > 0 ? message.id : "";
|
|
7491
|
+
return id.length > 0 ? `m:${id}` : "";
|
|
7492
|
+
}
|
|
7484
7493
|
function computeInboxNoticeFingerprint(messages) {
|
|
7485
7494
|
const keys = [];
|
|
7486
7495
|
for (const m of messages) {
|
|
7487
|
-
const
|
|
7488
|
-
if (
|
|
7489
|
-
keys.push(`s:${seq}`);
|
|
7490
|
-
continue;
|
|
7491
|
-
}
|
|
7492
|
-
const id = typeof m.message_id === "string" && m.message_id.length > 0 ? m.message_id : typeof m.id === "string" && m.id.length > 0 ? m.id : "";
|
|
7493
|
-
if (id.length > 0) keys.push(`m:${id}`);
|
|
7496
|
+
const key = inboxNoticeMessageIdentity(m);
|
|
7497
|
+
if (key.length > 0) keys.push(key);
|
|
7494
7498
|
}
|
|
7495
7499
|
if (keys.length === 0) return "";
|
|
7496
7500
|
keys.sort();
|
|
@@ -7501,6 +7505,10 @@ var RuntimeNotificationState = class {
|
|
|
7501
7505
|
pendingCountValue = 0;
|
|
7502
7506
|
lastNoticeFingerprint = null;
|
|
7503
7507
|
lastNoticeSessionId = null;
|
|
7508
|
+
lastEncodeFailedFingerprint = null;
|
|
7509
|
+
lastEncodeFailedSessionId = null;
|
|
7510
|
+
contributedSessionId = null;
|
|
7511
|
+
contributedIdentities = /* @__PURE__ */ new Set();
|
|
7504
7512
|
get pendingCount() {
|
|
7505
7513
|
return this.pendingCountValue;
|
|
7506
7514
|
}
|
|
@@ -7543,13 +7551,63 @@ var RuntimeNotificationState = class {
|
|
|
7543
7551
|
return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
|
|
7544
7552
|
}
|
|
7545
7553
|
/** Register a fingerprint as written — call ONLY after a successful stdin write. */
|
|
7546
|
-
recordNoticeWritten(fingerprint, sessionId) {
|
|
7554
|
+
recordNoticeWritten(fingerprint, sessionId, messages = []) {
|
|
7547
7555
|
this.lastNoticeFingerprint = fingerprint;
|
|
7548
7556
|
this.lastNoticeSessionId = sessionId;
|
|
7557
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7558
|
+
this.lastEncodeFailedSessionId = null;
|
|
7559
|
+
this.ensureContributionSession(sessionId);
|
|
7560
|
+
for (const message of messages) {
|
|
7561
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7562
|
+
if (identity.length > 0) {
|
|
7563
|
+
this.contributedIdentities.add(identity);
|
|
7564
|
+
}
|
|
7565
|
+
}
|
|
7566
|
+
}
|
|
7567
|
+
hasContributedMessage(message, sessionId) {
|
|
7568
|
+
if (this.contributedSessionId !== sessionId) return false;
|
|
7569
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7570
|
+
return identity.length > 0 && this.contributedIdentities.has(identity);
|
|
7571
|
+
}
|
|
7572
|
+
filterUncontributedMessages(messages, sessionId) {
|
|
7573
|
+
if (this.contributedSessionId !== sessionId || this.contributedIdentities.size === 0) {
|
|
7574
|
+
return [...messages];
|
|
7575
|
+
}
|
|
7576
|
+
return messages.filter((message) => {
|
|
7577
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7578
|
+
return identity.length === 0 || !this.contributedIdentities.has(identity);
|
|
7579
|
+
});
|
|
7580
|
+
}
|
|
7581
|
+
pruneContributedToPending(messages, sessionId) {
|
|
7582
|
+
this.ensureContributionSession(sessionId);
|
|
7583
|
+
if (this.contributedIdentities.size === 0) return;
|
|
7584
|
+
const pending = /* @__PURE__ */ new Set();
|
|
7585
|
+
for (const message of messages) {
|
|
7586
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7587
|
+
if (identity.length > 0) pending.add(identity);
|
|
7588
|
+
}
|
|
7589
|
+
for (const identity of this.contributedIdentities) {
|
|
7590
|
+
if (!pending.has(identity)) {
|
|
7591
|
+
this.contributedIdentities.delete(identity);
|
|
7592
|
+
}
|
|
7593
|
+
}
|
|
7594
|
+
}
|
|
7595
|
+
isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
|
|
7596
|
+
if (fingerprint.length === 0) return false;
|
|
7597
|
+
return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
|
|
7598
|
+
}
|
|
7599
|
+
recordNoticeEncodeFailed(fingerprint, sessionId) {
|
|
7600
|
+
if (fingerprint.length === 0) return;
|
|
7601
|
+
this.lastEncodeFailedFingerprint = fingerprint;
|
|
7602
|
+
this.lastEncodeFailedSessionId = sessionId;
|
|
7549
7603
|
}
|
|
7550
7604
|
clearNoticeFingerprint() {
|
|
7551
7605
|
this.lastNoticeFingerprint = null;
|
|
7552
7606
|
this.lastNoticeSessionId = null;
|
|
7607
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7608
|
+
this.lastEncodeFailedSessionId = null;
|
|
7609
|
+
this.contributedSessionId = null;
|
|
7610
|
+
this.contributedIdentities.clear();
|
|
7553
7611
|
}
|
|
7554
7612
|
schedule(callback, delayMs) {
|
|
7555
7613
|
if (this.timerValue) return false;
|
|
@@ -7562,6 +7620,11 @@ var RuntimeNotificationState = class {
|
|
|
7562
7620
|
this.clearTimer();
|
|
7563
7621
|
return count;
|
|
7564
7622
|
}
|
|
7623
|
+
ensureContributionSession(sessionId) {
|
|
7624
|
+
if (this.contributedSessionId === sessionId) return;
|
|
7625
|
+
this.contributedSessionId = sessionId;
|
|
7626
|
+
this.contributedIdentities.clear();
|
|
7627
|
+
}
|
|
7565
7628
|
};
|
|
7566
7629
|
|
|
7567
7630
|
// src/agentProcessManager.ts
|
|
@@ -8705,6 +8768,7 @@ var RUNTIME_TELEMETRY_RESERVED_ATTR_KEYS = /* @__PURE__ */ new Set([
|
|
|
8705
8768
|
"sessionId",
|
|
8706
8769
|
"turnId",
|
|
8707
8770
|
"runtimeResultId",
|
|
8771
|
+
"runtimeResultIdSource",
|
|
8708
8772
|
"daemonVersion",
|
|
8709
8773
|
"daemon_version",
|
|
8710
8774
|
"daemon_version_present",
|
|
@@ -8880,13 +8944,33 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8880
8944
|
this.sendStdinNotification(agentId);
|
|
8881
8945
|
}, delayMs);
|
|
8882
8946
|
}
|
|
8947
|
+
flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, source) {
|
|
8948
|
+
if (ap.notifications.pendingCount === 0) return false;
|
|
8949
|
+
if (ap.isIdle) return false;
|
|
8950
|
+
if (!ap.sessionId) return false;
|
|
8951
|
+
if (!ap.driver.supportsStdinNotification) return false;
|
|
8952
|
+
if (ap.runtime.descriptor.busyDelivery !== "direct") return false;
|
|
8953
|
+
if (ap.gatedSteering.compacting) return false;
|
|
8954
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification.retry_signal", {
|
|
8955
|
+
agentId,
|
|
8956
|
+
runtime: ap.config.runtime,
|
|
8957
|
+
model: ap.config.model,
|
|
8958
|
+
launchId: ap.launchId || void 0,
|
|
8959
|
+
source,
|
|
8960
|
+
mode: "busy",
|
|
8961
|
+
pending_notification_count: ap.notifications.pendingCount,
|
|
8962
|
+
inbox_count: ap.inbox.length,
|
|
8963
|
+
session_id_present: true
|
|
8964
|
+
});
|
|
8965
|
+
return this.sendStdinNotification(agentId, { forceUnsupportedRetry: true });
|
|
8966
|
+
}
|
|
8883
8967
|
clearRuntimeErrorDeliveryBackoff(ap) {
|
|
8884
8968
|
if (ap.runtimeErrorDeliveryBackoff.timer) {
|
|
8885
8969
|
clearTimeout(ap.runtimeErrorDeliveryBackoff.timer);
|
|
8886
8970
|
}
|
|
8887
8971
|
ap.runtimeErrorDeliveryBackoff = createRuntimeErrorDeliveryBackoffState();
|
|
8888
8972
|
}
|
|
8889
|
-
|
|
8973
|
+
clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, resetSource) {
|
|
8890
8974
|
if (ap.runtimeErrorDeliveryBackoff.attempts === 0 && ap.runtimeErrorDeliveryBackoff.untilMs === 0) return;
|
|
8891
8975
|
const attempts = ap.runtimeErrorDeliveryBackoff.attempts;
|
|
8892
8976
|
const reason = ap.runtimeErrorDeliveryBackoff.reason;
|
|
@@ -8898,9 +8982,12 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8898
8982
|
launchId: ap.launchId || void 0,
|
|
8899
8983
|
reason: reason || void 0,
|
|
8900
8984
|
attempts,
|
|
8901
|
-
reset_source:
|
|
8985
|
+
reset_source: resetSource
|
|
8902
8986
|
});
|
|
8903
8987
|
}
|
|
8988
|
+
clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, eventKind) {
|
|
8989
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, eventKind);
|
|
8990
|
+
}
|
|
8904
8991
|
runtimeErrorDeliveryBackoffRemainingMs(ap) {
|
|
8905
8992
|
return Math.max(0, ap.runtimeErrorDeliveryBackoff.untilMs - Date.now());
|
|
8906
8993
|
}
|
|
@@ -8928,8 +9015,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8928
9015
|
return "provider_connection_error";
|
|
8929
9016
|
case "ProviderStreamError":
|
|
8930
9017
|
return "provider_stream_error";
|
|
8931
|
-
|
|
9018
|
+
case "TimeoutError":
|
|
8932
9019
|
return null;
|
|
9020
|
+
default:
|
|
9021
|
+
return "runtime_error";
|
|
8933
9022
|
}
|
|
8934
9023
|
}
|
|
8935
9024
|
noteRuntimeErrorDeliveryBackoff(agentId, ap, message, terminalFailure, stickyTerminalFailure, reasonOverride) {
|
|
@@ -9000,9 +9089,24 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
9000
9089
|
if (ap.inbox.length === 0) return false;
|
|
9001
9090
|
const reason = ap.runtimeErrorDeliveryBackoff.reason || "runtime_error_backoff";
|
|
9002
9091
|
if (ap.isIdle && ap.driver.supportsStdinNotification && ap.sessionId) {
|
|
9003
|
-
|
|
9092
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
9093
|
+
const messages = ap.notifications.filterUncontributedMessages(ap.inbox, ap.sessionId);
|
|
9004
9094
|
ap.notifications.clearPending();
|
|
9005
9095
|
ap.notifications.clearTimer();
|
|
9096
|
+
if (messages.length === 0) {
|
|
9097
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_delivery_backoff.flush", {
|
|
9098
|
+
agentId,
|
|
9099
|
+
runtime: ap.config.runtime,
|
|
9100
|
+
model: ap.config.model,
|
|
9101
|
+
launchId: ap.launchId || void 0,
|
|
9102
|
+
reason,
|
|
9103
|
+
mode: "idle",
|
|
9104
|
+
outcome: "suppressed_already_contributed",
|
|
9105
|
+
inbox_count: ap.inbox.length,
|
|
9106
|
+
messages_count: 0
|
|
9107
|
+
});
|
|
9108
|
+
return false;
|
|
9109
|
+
}
|
|
9006
9110
|
this.commitApmIdleState(agentId, ap, false);
|
|
9007
9111
|
this.startRuntimeTrace(agentId, ap, "runtime-error-backoff-idle-delivery", messages);
|
|
9008
9112
|
this.broadcastActivity(agentId, "working", "Message received");
|
|
@@ -9683,6 +9787,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
9683
9787
|
runtimeProgress: new RuntimeProgressState(Date.now()),
|
|
9684
9788
|
runtimeTraceSpan: null,
|
|
9685
9789
|
runtimeTraceCounters: createRuntimeTraceCounters(),
|
|
9790
|
+
runtimeTelemetryResultSeq: 0,
|
|
9686
9791
|
lastActivity: "",
|
|
9687
9792
|
lastActivityDetail: "",
|
|
9688
9793
|
recentStdout: [],
|
|
@@ -10235,6 +10340,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10235
10340
|
this.agents.delete(agentId);
|
|
10236
10341
|
if (!silent) {
|
|
10237
10342
|
this.activityClientSeqByAgent.delete(agentId);
|
|
10343
|
+
this.agentVisibleBoundaries.delete(agentId);
|
|
10344
|
+
this.agentVisibleMessageIds.delete(agentId);
|
|
10238
10345
|
}
|
|
10239
10346
|
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
10240
10347
|
stop_source: silent ? "daemon_internal" : "explicit_request",
|
|
@@ -10458,6 +10565,25 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10458
10565
|
}));
|
|
10459
10566
|
return true;
|
|
10460
10567
|
}
|
|
10568
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
10569
|
+
const noticeFingerprint = computeInboxNoticeFingerprint([message]);
|
|
10570
|
+
const messageAlreadyPending = noticeFingerprint.length > 0 && ap.inbox.some((pending) => computeInboxNoticeFingerprint([pending]) === noticeFingerprint);
|
|
10571
|
+
const messageAlreadyContributed = ap.notifications.hasContributedMessage(message, ap.sessionId);
|
|
10572
|
+
if (messageAlreadyPending && (messageAlreadyContributed || ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId))) {
|
|
10573
|
+
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
10574
|
+
outcome: "suppressed_duplicate_stdin_idle_delivery",
|
|
10575
|
+
accepted: true,
|
|
10576
|
+
process_present: true,
|
|
10577
|
+
runtime: ap.config.runtime,
|
|
10578
|
+
session_id_present: true,
|
|
10579
|
+
launchId: ap.launchId || void 0,
|
|
10580
|
+
is_idle: ap.isIdle,
|
|
10581
|
+
inbox_count: ap.inbox.length,
|
|
10582
|
+
pending_notification_count: ap.notifications.pendingCount
|
|
10583
|
+
}));
|
|
10584
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate idle stdin inbox update (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
10585
|
+
return true;
|
|
10586
|
+
}
|
|
10461
10587
|
ap.inbox.push(message);
|
|
10462
10588
|
const nextMessages = [...ap.inbox];
|
|
10463
10589
|
this.commitApmIdleState(agentId, ap, false);
|
|
@@ -11326,6 +11452,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11326
11452
|
if (row.flags.includes("task")) taskTargetCount += 1;
|
|
11327
11453
|
}
|
|
11328
11454
|
return {
|
|
11455
|
+
target_count: rows.length,
|
|
11456
|
+
changed_target_count: rows.length,
|
|
11329
11457
|
inbox_target_count: rows.length,
|
|
11330
11458
|
pending_message_count: pendingMessageCount,
|
|
11331
11459
|
max_pending_per_target: maxPendingCount,
|
|
@@ -11499,7 +11627,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11499
11627
|
return false;
|
|
11500
11628
|
}
|
|
11501
11629
|
const messages = [...ap.inbox];
|
|
11502
|
-
ap.notifications.
|
|
11630
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
11631
|
+
ap.notifications.clearPending();
|
|
11632
|
+
ap.notifications.clearTimer();
|
|
11503
11633
|
if (messages.length === 0) {
|
|
11504
11634
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11505
11635
|
outcome: "empty",
|
|
@@ -11515,12 +11645,23 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11515
11645
|
messageCount: messages.length
|
|
11516
11646
|
});
|
|
11517
11647
|
}
|
|
11518
|
-
this.broadcastActivity(agentId, "working", "Message received");
|
|
11519
11648
|
const runtimeProfileMessages = messages.filter((message) => runtimeProfileNotificationFromMessage(message));
|
|
11520
|
-
const
|
|
11649
|
+
const ordinaryMessageCandidates = messages.filter((message) => !runtimeProfileNotificationFromMessage(message));
|
|
11650
|
+
const ordinaryMessages = ap.notifications.filterUncontributedMessages(
|
|
11651
|
+
ordinaryMessageCandidates,
|
|
11652
|
+
ap.sessionId
|
|
11653
|
+
);
|
|
11654
|
+
if (runtimeProfileMessages.length === 0 && ordinaryMessages.length === 0) {
|
|
11655
|
+
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11656
|
+
outcome: "suppressed_already_contributed",
|
|
11657
|
+
delivered_messages_count: 0
|
|
11658
|
+
});
|
|
11659
|
+
return false;
|
|
11660
|
+
}
|
|
11661
|
+
this.broadcastActivity(agentId, "working", "Message received");
|
|
11521
11662
|
let accepted = true;
|
|
11522
11663
|
if (runtimeProfileMessages.length > 0) {
|
|
11523
|
-
ap.inbox.splice(0, ap.inbox.length, ...
|
|
11664
|
+
ap.inbox.splice(0, ap.inbox.length, ...ordinaryMessageCandidates);
|
|
11524
11665
|
accepted = this.deliverMessagesViaStdin(agentId, ap, runtimeProfileMessages, effect.stdinMode);
|
|
11525
11666
|
}
|
|
11526
11667
|
if (ordinaryMessages.length > 0) {
|
|
@@ -11534,7 +11675,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11534
11675
|
}
|
|
11535
11676
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11536
11677
|
outcome: accepted ? "written" : "not_written",
|
|
11537
|
-
delivered_messages_count:
|
|
11678
|
+
delivered_messages_count: runtimeProfileMessages.length + ordinaryMessages.length
|
|
11538
11679
|
});
|
|
11539
11680
|
return accepted;
|
|
11540
11681
|
}
|
|
@@ -11766,6 +11907,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11766
11907
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11767
11908
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11768
11909
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "thinking" });
|
|
11910
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11769
11911
|
}
|
|
11770
11912
|
break;
|
|
11771
11913
|
}
|
|
@@ -11776,6 +11918,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11776
11918
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11777
11919
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11778
11920
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "text" });
|
|
11921
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11779
11922
|
}
|
|
11780
11923
|
break;
|
|
11781
11924
|
}
|
|
@@ -11848,6 +11991,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11848
11991
|
if (ap) {
|
|
11849
11992
|
if (event.sessionId) ap.sessionId = event.sessionId;
|
|
11850
11993
|
const stickyTerminalFailure = classifyStickyTerminalFailure(ap);
|
|
11994
|
+
if (!stickyTerminalFailure && ap.runtimeErrorDeliveryBackoff.reason === "runtime_error") {
|
|
11995
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, "turn_end_unclassified_runtime_error");
|
|
11996
|
+
}
|
|
11851
11997
|
const reduction = reduceApmGatedTurnEnd(ap.gatedSteering, {
|
|
11852
11998
|
inboxLength: stickyTerminalFailure ? 0 : ap.inbox.length,
|
|
11853
11999
|
supportsStdinNotification: ap.driver.supportsStdinNotification,
|
|
@@ -11979,7 +12125,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11979
12125
|
}
|
|
11980
12126
|
}
|
|
11981
12127
|
recordRuntimeTelemetry(agentId, ap, event) {
|
|
11982
|
-
const sessionId = ap.driver.currentSessionId ?? event.sessionId;
|
|
12128
|
+
const sessionId = ap.driver.currentSessionId ?? event.sessionId ?? ap.sessionId ?? ap.config.sessionId;
|
|
12129
|
+
const resultIdentity = this.runtimeTelemetryResultIdentity(agentId, ap, event);
|
|
11983
12130
|
const payloadAttrs = sanitizeRuntimeTelemetryPayloadAttrs(event.attrs);
|
|
11984
12131
|
const versionAttrs = this.runtimeTelemetryVersionAttrs();
|
|
11985
12132
|
const telemetryAttrs = {
|
|
@@ -11989,7 +12136,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11989
12136
|
...event.usageKind ? { usageKind: event.usageKind } : {},
|
|
11990
12137
|
...sessionId ? { sessionId } : {},
|
|
11991
12138
|
...event.turnId ? { turnId: event.turnId } : {},
|
|
11992
|
-
...
|
|
12139
|
+
...resultIdentity
|
|
11993
12140
|
};
|
|
11994
12141
|
const attrs = {
|
|
11995
12142
|
agentId,
|
|
@@ -12002,6 +12149,16 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12002
12149
|
ap.runtimeTraceSpan?.addEvent(`runtime.telemetry.${event.name}`, telemetryAttrs);
|
|
12003
12150
|
this.recordDaemonTrace(`daemon.runtime.telemetry.${event.name}`, attrs);
|
|
12004
12151
|
}
|
|
12152
|
+
runtimeTelemetryResultIdentity(agentId, ap, event) {
|
|
12153
|
+
if (event.runtimeResultId) return { runtimeResultId: event.runtimeResultId };
|
|
12154
|
+
if (event.name !== "token_usage" || event.source !== "claude_result_usage") return {};
|
|
12155
|
+
const sequence = ++ap.runtimeTelemetryResultSeq;
|
|
12156
|
+
const scope = ap.launchId || agentId;
|
|
12157
|
+
return {
|
|
12158
|
+
runtimeResultId: `${scope}:claude_result_usage:${sequence}`,
|
|
12159
|
+
runtimeResultIdSource: "daemon_sequence"
|
|
12160
|
+
};
|
|
12161
|
+
}
|
|
12005
12162
|
runtimeTelemetryVersionAttrs() {
|
|
12006
12163
|
return {
|
|
12007
12164
|
...this.daemonVersion ? {
|
|
@@ -12070,7 +12227,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12070
12227
|
}
|
|
12071
12228
|
}
|
|
12072
12229
|
/** Send a batched notification to the agent via stdin about pending messages */
|
|
12073
|
-
sendStdinNotification(agentId) {
|
|
12230
|
+
sendStdinNotification(agentId, options = {}) {
|
|
12074
12231
|
const ap = this.agents.get(agentId);
|
|
12075
12232
|
if (!ap) return false;
|
|
12076
12233
|
const count = ap.notifications.takePendingAndClearTimer();
|
|
@@ -12112,7 +12269,24 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12112
12269
|
}
|
|
12113
12270
|
const inboxCount = ap.inbox.length;
|
|
12114
12271
|
if (inboxCount === 0) return false;
|
|
12115
|
-
|
|
12272
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
12273
|
+
const changedMessageCandidates = ap.inbox.slice(Math.max(0, ap.inbox.length - count));
|
|
12274
|
+
const changedMessages = ap.notifications.filterUncontributedMessages(changedMessageCandidates, ap.sessionId);
|
|
12275
|
+
if (changedMessages.length === 0) {
|
|
12276
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12277
|
+
agentId,
|
|
12278
|
+
runtime: ap.config.runtime,
|
|
12279
|
+
model: ap.config.model,
|
|
12280
|
+
launchId: ap.launchId || void 0,
|
|
12281
|
+
outcome: "suppressed_already_contributed",
|
|
12282
|
+
mode: "busy",
|
|
12283
|
+
pending_notification_count: count,
|
|
12284
|
+
inbox_count: ap.inbox.length,
|
|
12285
|
+
session_id_present: true
|
|
12286
|
+
});
|
|
12287
|
+
logger.info(`[Agent ${agentId}] Suppressing stdin inbox notice because all candidate messages already contributed; pending=${ap.inbox.length}`);
|
|
12288
|
+
return false;
|
|
12289
|
+
}
|
|
12116
12290
|
const noticeFingerprint = computeInboxNoticeFingerprint(changedMessages);
|
|
12117
12291
|
if (ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId)) {
|
|
12118
12292
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
@@ -12129,6 +12303,22 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12129
12303
|
logger.info(`[Agent ${agentId}] Suppressing duplicate stdin inbox notice (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
12130
12304
|
return false;
|
|
12131
12305
|
}
|
|
12306
|
+
if (!options.forceUnsupportedRetry && ap.notifications.isDuplicateEncodeFailedNotice(noticeFingerprint, ap.sessionId)) {
|
|
12307
|
+
ap.notifications.add(count);
|
|
12308
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12309
|
+
agentId,
|
|
12310
|
+
runtime: ap.config.runtime,
|
|
12311
|
+
model: ap.config.model,
|
|
12312
|
+
launchId: ap.launchId || void 0,
|
|
12313
|
+
outcome: "suppressed_duplicate_encode_failed",
|
|
12314
|
+
mode: "busy",
|
|
12315
|
+
pending_notification_count: count,
|
|
12316
|
+
inbox_count: ap.inbox.length,
|
|
12317
|
+
session_id_present: true
|
|
12318
|
+
});
|
|
12319
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate unsupported stdin inbox notice (unread-set unchanged since last encode failure); pending=${ap.inbox.length}`);
|
|
12320
|
+
return false;
|
|
12321
|
+
}
|
|
12132
12322
|
const inboxRows = projectAgentInboxSnapshot(changedMessages);
|
|
12133
12323
|
const notification = `[Slock inbox notice:
|
|
12134
12324
|
${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
@@ -12151,6 +12341,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12151
12341
|
model: ap.config.model,
|
|
12152
12342
|
launchId: ap.launchId || void 0,
|
|
12153
12343
|
mode: "busy",
|
|
12344
|
+
source: "busy_stdin_notification",
|
|
12154
12345
|
notification_byte_count: notificationByteCount,
|
|
12155
12346
|
...projectionAttrs
|
|
12156
12347
|
});
|
|
@@ -12166,12 +12357,15 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12166
12357
|
inbox_target_count: inboxRows.length,
|
|
12167
12358
|
session_id_present: true
|
|
12168
12359
|
});
|
|
12169
|
-
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId);
|
|
12360
|
+
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId, changedMessages);
|
|
12170
12361
|
return true;
|
|
12171
12362
|
} else {
|
|
12172
12363
|
ap.notifications.add(count);
|
|
12173
|
-
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12364
|
+
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" && sendResult.reason !== "unsupported" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12174
12365
|
const outcome = runtimeSendFailureOutcome(sendResult);
|
|
12366
|
+
if (outcome === "encode_failed") {
|
|
12367
|
+
ap.notifications.recordNoticeEncodeFailed(noticeFingerprint, ap.sessionId);
|
|
12368
|
+
}
|
|
12175
12369
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12176
12370
|
agentId,
|
|
12177
12371
|
runtime: ap.config.runtime,
|
|
@@ -12213,6 +12407,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12213
12407
|
model: ap.config.model,
|
|
12214
12408
|
launchId: ap.launchId || void 0,
|
|
12215
12409
|
mode,
|
|
12410
|
+
source,
|
|
12216
12411
|
notification_byte_count: Buffer.byteLength(renderedInput, "utf8"),
|
|
12217
12412
|
cursors_advanced: "none",
|
|
12218
12413
|
...projectionAttrs
|
|
@@ -12291,6 +12486,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12291
12486
|
stdin_write_attempted: true,
|
|
12292
12487
|
cursors_advanced: "none"
|
|
12293
12488
|
});
|
|
12489
|
+
ap.notifications.recordNoticeWritten(computeInboxNoticeFingerprint(messages), ap.sessionId, messages);
|
|
12294
12490
|
return true;
|
|
12295
12491
|
}
|
|
12296
12492
|
/** Deliver a message to an agent via stdin, formatting it the same way as the MCP bridge */
|
|
@@ -12507,7 +12703,7 @@ var DaemonConnection = class {
|
|
|
12507
12703
|
logger.warn(`[Daemon] Dropping outbound message while disconnected: ${msg.type}`);
|
|
12508
12704
|
}
|
|
12509
12705
|
this.trace("daemon.connection.outbound_dropped", {
|
|
12510
|
-
|
|
12706
|
+
outbound_message_kind: msg.type,
|
|
12511
12707
|
ws_ready_state: this.ws?.readyState ?? null
|
|
12512
12708
|
});
|
|
12513
12709
|
}
|
|
@@ -12556,7 +12752,7 @@ var DaemonConnection = class {
|
|
|
12556
12752
|
this.resetWatchdog();
|
|
12557
12753
|
if (messageKind !== "ping") {
|
|
12558
12754
|
this.trace("daemon.connection.inbound_received", {
|
|
12559
|
-
|
|
12755
|
+
inbound_message_kind: messageKind,
|
|
12560
12756
|
last_inbound_age_ms_bucket: "0"
|
|
12561
12757
|
});
|
|
12562
12758
|
}
|
|
@@ -12647,7 +12843,7 @@ var DaemonConnection = class {
|
|
|
12647
12843
|
if (msg.launchId && latestLaunchId && msg.launchId !== latestLaunchId) {
|
|
12648
12844
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12649
12845
|
reason: "launch_changed",
|
|
12650
|
-
|
|
12846
|
+
outbound_message_kind: msg.type,
|
|
12651
12847
|
agentId: msg.agentId,
|
|
12652
12848
|
stale_launch_id_present: true,
|
|
12653
12849
|
next_launch_id_present: true
|
|
@@ -12667,7 +12863,7 @@ var DaemonConnection = class {
|
|
|
12667
12863
|
this.pendingActivityByAgent.delete(identity.agentId);
|
|
12668
12864
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12669
12865
|
reason: "launch_changed",
|
|
12670
|
-
|
|
12866
|
+
outbound_message_kind: msg.type,
|
|
12671
12867
|
agentId: identity.agentId,
|
|
12672
12868
|
stale_launch_id_present: Boolean(pending.launchId),
|
|
12673
12869
|
next_launch_id_present: true
|
|
@@ -12696,7 +12892,7 @@ var DaemonConnection = class {
|
|
|
12696
12892
|
ws.send(JSON.stringify(msg));
|
|
12697
12893
|
}
|
|
12698
12894
|
this.trace("daemon.connection.outbound_replayed", {
|
|
12699
|
-
|
|
12895
|
+
outbound_message_kind: "agent:activity",
|
|
12700
12896
|
message_count: pending.length
|
|
12701
12897
|
});
|
|
12702
12898
|
}
|
|
@@ -13522,7 +13718,52 @@ var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
|
13522
13718
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
13523
13719
|
var RUNNER_CREDENTIAL_MINT_MAX_ATTEMPTS2 = 3;
|
|
13524
13720
|
var RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2 = 250;
|
|
13525
|
-
var
|
|
13721
|
+
var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
13722
|
+
"daemon.lifecycle.start": {
|
|
13723
|
+
spanAttrs: ["machine_dir_present", "local_trace_enabled"],
|
|
13724
|
+
eventAttrs: {
|
|
13725
|
+
"daemon.machine_lock.acquired": ["machine_dir_present"]
|
|
13726
|
+
}
|
|
13727
|
+
},
|
|
13728
|
+
"daemon.lifecycle.stop": {
|
|
13729
|
+
spanAttrs: ["machine_lock_present"]
|
|
13730
|
+
},
|
|
13731
|
+
"daemon.runner_credential_mint.retry": {
|
|
13732
|
+
spanAttrs: ["agentId", "runtime", "attempt", "max_attempts", "status", "code", "reason", "retryable"]
|
|
13733
|
+
},
|
|
13734
|
+
"daemon.runner_credential_mint.failed": {
|
|
13735
|
+
spanAttrs: ["agentId", "runtime", "status", "code", "reason", "retryable", "max_attempts"]
|
|
13736
|
+
},
|
|
13737
|
+
"daemon.agent.spawn.failed": {
|
|
13738
|
+
spanAttrs: ["agentId", "launchId", "runtime", "model", "failure_reason", "failure_detail", "session_id_present"]
|
|
13739
|
+
},
|
|
13740
|
+
"daemon.agent.delivery": {
|
|
13741
|
+
spanAttrs: ["agentId", "deliveryId", "delivery_correlation_id", "messageId", "message_id_present", "seq"],
|
|
13742
|
+
eventAttrs: {
|
|
13743
|
+
"daemon.receive": ["seq", "deliveryId"],
|
|
13744
|
+
"daemon.deliver_to_agent_manager": ["accepted"],
|
|
13745
|
+
"daemon.ack.sent": ["seq"]
|
|
13746
|
+
},
|
|
13747
|
+
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class"]
|
|
13748
|
+
},
|
|
13749
|
+
"daemon.runtime_profile.control.received": {
|
|
13750
|
+
spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
|
|
13751
|
+
endAttrs: ["outcome", "error_class"]
|
|
13752
|
+
},
|
|
13753
|
+
"daemon.computer_control.received": {
|
|
13754
|
+
spanAttrs: ["action", "handled"]
|
|
13755
|
+
},
|
|
13756
|
+
"daemon.ready.sent": {
|
|
13757
|
+
spanAttrs: ["runtimes_count", "running_agents_count", "idle_agents_count", "runtime_profile_reports_count"]
|
|
13758
|
+
},
|
|
13759
|
+
"daemon.runtime_profile.report.sent": {
|
|
13760
|
+
spanAttrs: ["agentId", "launchId", "runtime", "report_source", "model_present", "session_ref_present", "workspace_ref_present"]
|
|
13761
|
+
},
|
|
13762
|
+
"daemon.connection.local_disconnect_observed": {
|
|
13763
|
+
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
13764
|
+
}
|
|
13765
|
+
};
|
|
13766
|
+
var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
|
|
13526
13767
|
var RunnerCredentialMintError2 = class extends Error {
|
|
13527
13768
|
code;
|
|
13528
13769
|
retryable;
|
|
@@ -13558,9 +13799,9 @@ function runnerCredentialErrorDetail2(error) {
|
|
|
13558
13799
|
async function waitForRunnerCredentialRetry2() {
|
|
13559
13800
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
|
|
13560
13801
|
}
|
|
13561
|
-
function parseDaemonCliArgs(args
|
|
13802
|
+
function parseDaemonCliArgs(args) {
|
|
13562
13803
|
let serverUrl = "";
|
|
13563
|
-
let apiKey =
|
|
13804
|
+
let apiKey = "";
|
|
13564
13805
|
for (let i = 0; i < args.length; i++) {
|
|
13565
13806
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
13566
13807
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -13729,6 +13970,8 @@ var DaemonCore = class {
|
|
|
13729
13970
|
tracer;
|
|
13730
13971
|
injectedTracer;
|
|
13731
13972
|
machineLock = null;
|
|
13973
|
+
observedServerId = null;
|
|
13974
|
+
observedMachineId = null;
|
|
13732
13975
|
localTraceSink = null;
|
|
13733
13976
|
traceBundleUploader = null;
|
|
13734
13977
|
constructor(options) {
|
|
@@ -13779,6 +14022,7 @@ var DaemonCore = class {
|
|
|
13779
14022
|
return process.env.SLOCK_DAEMON_LOCAL_TRACE !== "0";
|
|
13780
14023
|
}
|
|
13781
14024
|
resolveTraceJitter() {
|
|
14025
|
+
if (process.env.SLOCK_DAEMON_TRACE_JITTER_DISABLED === "1") return NO_JITTER;
|
|
13782
14026
|
const lockId = this.machineLock?.lockId;
|
|
13783
14027
|
return lockId ? computeTraceJitter(lockId) : NO_JITTER;
|
|
13784
14028
|
}
|
|
@@ -13810,7 +14054,7 @@ var DaemonCore = class {
|
|
|
13810
14054
|
workerUrl,
|
|
13811
14055
|
tracer: this.tracer,
|
|
13812
14056
|
currentFileProvider: () => this.localTraceSink?.getCurrentFile() ?? null,
|
|
13813
|
-
|
|
14057
|
+
jitter: this.resolveTraceJitter()
|
|
13814
14058
|
});
|
|
13815
14059
|
this.traceBundleUploader.start();
|
|
13816
14060
|
}
|
|
@@ -13889,22 +14133,29 @@ var DaemonCore = class {
|
|
|
13889
14133
|
span.end(status);
|
|
13890
14134
|
}
|
|
13891
14135
|
withDaemonTraceScope(tracer) {
|
|
13892
|
-
return
|
|
14136
|
+
return {
|
|
14137
|
+
startSpan: (name, options) => createTraceScopeTracer(tracer, this.daemonTraceScope(), {
|
|
14138
|
+
spanAttrContracts: DAEMON_CORE_TRACE_ATTR_CONTRACTS
|
|
14139
|
+
}).startSpan(name, options)
|
|
14140
|
+
};
|
|
13893
14141
|
}
|
|
13894
|
-
|
|
14142
|
+
daemonTraceScope() {
|
|
13895
14143
|
return {
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
13899
|
-
|
|
13900
|
-
|
|
13901
|
-
|
|
13902
|
-
|
|
13903
|
-
} : {
|
|
13904
|
-
computer_version_present: false
|
|
14144
|
+
resource: {
|
|
14145
|
+
daemonVersion: this.daemonVersion,
|
|
14146
|
+
computerVersion: this.computerVersion
|
|
14147
|
+
},
|
|
14148
|
+
actor: {
|
|
14149
|
+
serverId: this.observedServerId,
|
|
14150
|
+
machineId: this.observedMachineId
|
|
13905
14151
|
}
|
|
13906
14152
|
};
|
|
13907
14153
|
}
|
|
14154
|
+
observeRuntimeContext(config) {
|
|
14155
|
+
const ctx = config.runtimeContext;
|
|
14156
|
+
if (ctx?.serverId) this.observedServerId = ctx.serverId;
|
|
14157
|
+
if (ctx?.machineId) this.observedMachineId = ctx.machineId;
|
|
14158
|
+
}
|
|
13908
14159
|
async requestRunnerCredentialOnce(agentId, config) {
|
|
13909
14160
|
const url = new URL(`/internal/computer/runners/${encodeURIComponent(agentId)}/credentials`, this.options.serverUrl);
|
|
13910
14161
|
const res = await daemonFetch(url, {
|
|
@@ -13996,6 +14247,7 @@ var DaemonCore = class {
|
|
|
13996
14247
|
);
|
|
13997
14248
|
}
|
|
13998
14249
|
async startAgentFromMessage(msg) {
|
|
14250
|
+
this.observeRuntimeContext(msg.config);
|
|
13999
14251
|
const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
|
|
14000
14252
|
const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
|
|
14001
14253
|
await this.agentManager.startAgent(
|
|
@@ -14013,6 +14265,7 @@ var DaemonCore = class {
|
|
|
14013
14265
|
logger.info(`[Daemon] Received ${msg.type}${summary ? ` ${summary}` : ""}`);
|
|
14014
14266
|
switch (msg.type) {
|
|
14015
14267
|
case "agent:start":
|
|
14268
|
+
this.observeRuntimeContext(msg.config);
|
|
14016
14269
|
logger.info(`[Agent ${msg.agentId}] Start requested (runtime=${msg.config.runtime}, model=${msg.config.model}, session=${msg.config.sessionId || "new"}${msg.wakeMessage ? ", wake=true" : ""})`);
|
|
14017
14270
|
this.startAgentFromMessage(msg).catch((err) => {
|
|
14018
14271
|
const classification = classifySpawnFailure(err);
|
|
@@ -14329,8 +14582,6 @@ var DaemonCore = class {
|
|
|
14329
14582
|
};
|
|
14330
14583
|
|
|
14331
14584
|
export {
|
|
14332
|
-
DAEMON_API_KEY_ENV,
|
|
14333
|
-
scrubDaemonAuthEnv,
|
|
14334
14585
|
subscribeDaemonLogs,
|
|
14335
14586
|
resolveWorkspaceDirectoryPath,
|
|
14336
14587
|
scanWorkspaceDirectories,
|
package/dist/cli/index.js
CHANGED
|
@@ -860,11 +860,17 @@ async function runDeviceCodeLogin(options) {
|
|
|
860
860
|
const pollIntervalMs = options.pollIntervalOverrideMs ?? serverIntervalMs;
|
|
861
861
|
const deadlineMs = Date.now() + Math.max(1, authorizeBody.expiresIn ?? 600) * 1e3;
|
|
862
862
|
while (Date.now() < deadlineMs) {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
863
|
+
let tokenRes;
|
|
864
|
+
try {
|
|
865
|
+
tokenRes = await httpFetch(`${base}/api/auth/device/token`, {
|
|
866
|
+
method: "POST",
|
|
867
|
+
headers: { "content-type": "application/json" },
|
|
868
|
+
body: JSON.stringify({ deviceCode: authorizeBody.deviceCode })
|
|
869
|
+
});
|
|
870
|
+
} catch {
|
|
871
|
+
await delay(pollIntervalMs);
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
868
874
|
if (tokenRes.ok) {
|
|
869
875
|
const tokenBody = await tokenRes.json();
|
|
870
876
|
if (!tokenBody.accessToken || !tokenBody.refreshToken || !tokenBody.userId) {
|
|
@@ -15249,6 +15255,12 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
15249
15255
|
};
|
|
15250
15256
|
|
|
15251
15257
|
// ../shared/src/index.ts
|
|
15258
|
+
var EXTERNAL_AGENT_RUNTIME_ID = "external";
|
|
15259
|
+
var EXTERNAL_AGENT_RUNTIME_MODEL = "external";
|
|
15260
|
+
var EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME = "External agent";
|
|
15261
|
+
function isExternalAgentRuntime(runtime) {
|
|
15262
|
+
return runtime === EXTERNAL_AGENT_RUNTIME_ID;
|
|
15263
|
+
}
|
|
15252
15264
|
var RUNTIMES = [
|
|
15253
15265
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
15254
15266
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
@@ -15261,8 +15273,71 @@ var RUNTIMES = [
|
|
|
15261
15273
|
{ id: "pi", displayName: "Pi", binary: "pi", supported: true }
|
|
15262
15274
|
];
|
|
15263
15275
|
function getRuntimeDisplayName(id) {
|
|
15276
|
+
if (isExternalAgentRuntime(id)) return EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME;
|
|
15264
15277
|
return RUNTIMES.find((r) => r.id === id)?.displayName ?? id;
|
|
15265
15278
|
}
|
|
15279
|
+
var RUNTIME_MODELS = {
|
|
15280
|
+
[EXTERNAL_AGENT_RUNTIME_ID]: [
|
|
15281
|
+
{ id: EXTERNAL_AGENT_RUNTIME_MODEL, label: EXTERNAL_AGENT_RUNTIME_DISPLAY_NAME }
|
|
15282
|
+
],
|
|
15283
|
+
claude: [
|
|
15284
|
+
{ id: "opus", label: "Claude Opus" },
|
|
15285
|
+
{ id: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
15286
|
+
{ id: "claude-opus-4-7", label: "Claude Opus 4.7" },
|
|
15287
|
+
{ id: "claude-opus-4-6", label: "Claude Opus 4.6" },
|
|
15288
|
+
{ id: "sonnet", label: "Claude Sonnet" },
|
|
15289
|
+
{ id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
|
|
15290
|
+
{ id: "haiku", label: "Claude Haiku" },
|
|
15291
|
+
{ id: "claude-haiku-4-5", label: "Claude Haiku 4.5" }
|
|
15292
|
+
],
|
|
15293
|
+
codex: [
|
|
15294
|
+
{ id: "gpt-5.5", label: "GPT-5.5" },
|
|
15295
|
+
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
15296
|
+
{ id: "gpt-5.3-codex", label: "GPT-5.3 Codex" },
|
|
15297
|
+
{ id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark" },
|
|
15298
|
+
{ id: "gpt-5.2-codex", label: "GPT-5.2 Codex" },
|
|
15299
|
+
{ id: "gpt-5.2", label: "GPT-5.2" },
|
|
15300
|
+
{ id: "gpt-5.1-codex-max", label: "GPT-5.1 Codex Max" },
|
|
15301
|
+
{ id: "gpt-5.1-codex", label: "GPT-5.1 Codex" },
|
|
15302
|
+
{ id: "gpt-5-codex", label: "GPT-5 Codex" },
|
|
15303
|
+
{ id: "gpt-5", label: "GPT-5" }
|
|
15304
|
+
],
|
|
15305
|
+
antigravity: [
|
|
15306
|
+
{ id: "default", label: "AGY configured default", verified: "suggestion_only" }
|
|
15307
|
+
],
|
|
15308
|
+
copilot: [
|
|
15309
|
+
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
15310
|
+
{ id: "gpt-5.2", label: "GPT-5.2" },
|
|
15311
|
+
{ id: "claude-4-sonnet", label: "Claude 4 Sonnet" },
|
|
15312
|
+
{ id: "claude-4.5-sonnet", label: "Claude 4.5 Sonnet" }
|
|
15313
|
+
],
|
|
15314
|
+
cursor: [
|
|
15315
|
+
{ id: "composer-2-fast", label: "Composer 2 Fast" },
|
|
15316
|
+
{ id: "composer-2", label: "Composer 2" },
|
|
15317
|
+
{ id: "auto", label: "Auto" }
|
|
15318
|
+
],
|
|
15319
|
+
gemini: [
|
|
15320
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
15321
|
+
{ id: "gemini-3.1-pro-preview", label: "Gemini 3.1 Pro (Preview)" },
|
|
15322
|
+
{ id: "gemini-3-flash-preview", label: "Gemini 3 Flash (Preview)" },
|
|
15323
|
+
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro" },
|
|
15324
|
+
{ id: "gemini-2.5-flash", label: "Gemini 2.5 Flash" }
|
|
15325
|
+
],
|
|
15326
|
+
opencode: [
|
|
15327
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" },
|
|
15328
|
+
{ id: "deepseek/deepseek-v4-pro", label: "DeepSeek V4 Pro (OpenCode)", verified: "suggestion_only" },
|
|
15329
|
+
{ id: "openrouter/anthropic/claude-opus-4.5", label: "Claude Opus 4.5 via OpenRouter", verified: "suggestion_only" },
|
|
15330
|
+
{ id: "fusecode/opus[1m]", label: "Opus 1M via FuseCode", verified: "suggestion_only" }
|
|
15331
|
+
],
|
|
15332
|
+
pi: [
|
|
15333
|
+
{ id: "default", label: "Configured Default / Auto", verified: "suggestion_only" }
|
|
15334
|
+
],
|
|
15335
|
+
// Kimi CLI resolves model keys from each user's local config, so the safest
|
|
15336
|
+
// built-in option is to defer to whatever default model the CLI already uses.
|
|
15337
|
+
kimi: [
|
|
15338
|
+
{ id: "default", label: "Configured Default" }
|
|
15339
|
+
]
|
|
15340
|
+
};
|
|
15266
15341
|
var PLAN_CONFIG = {
|
|
15267
15342
|
free: {
|
|
15268
15343
|
displayName: "Hobby",
|
package/dist/core.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DAEMON_API_KEY_ENV,
|
|
3
2
|
DAEMON_CLI_USAGE,
|
|
4
3
|
DaemonCore,
|
|
5
4
|
deleteWorkspaceDirectory,
|
|
@@ -9,11 +8,9 @@ import {
|
|
|
9
8
|
resolveSlockCliPath,
|
|
10
9
|
resolveWorkspaceDirectoryPath,
|
|
11
10
|
scanWorkspaceDirectories,
|
|
12
|
-
scrubDaemonAuthEnv,
|
|
13
11
|
subscribeDaemonLogs
|
|
14
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EKSATDT3.js";
|
|
15
13
|
export {
|
|
16
|
-
DAEMON_API_KEY_ENV,
|
|
17
14
|
DAEMON_CLI_USAGE,
|
|
18
15
|
DaemonCore,
|
|
19
16
|
deleteWorkspaceDirectory,
|
|
@@ -23,6 +20,5 @@ export {
|
|
|
23
20
|
resolveSlockCliPath,
|
|
24
21
|
resolveWorkspaceDirectoryPath,
|
|
25
22
|
scanWorkspaceDirectories,
|
|
26
|
-
scrubDaemonAuthEnv,
|
|
27
23
|
subscribeDaemonLogs
|
|
28
24
|
};
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DAEMON_CLI_USAGE,
|
|
4
4
|
DaemonCore,
|
|
5
|
-
parseDaemonCliArgs
|
|
6
|
-
|
|
7
|
-
} from "./chunk-4PZVJXRJ.js";
|
|
5
|
+
parseDaemonCliArgs
|
|
6
|
+
} from "./chunk-EKSATDT3.js";
|
|
8
7
|
|
|
9
8
|
// src/index.ts
|
|
10
|
-
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2)
|
|
11
|
-
scrubDaemonAuthEnv(process.env);
|
|
9
|
+
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
|
|
12
10
|
if (!parsedArgs) {
|
|
13
11
|
console.error(DAEMON_CLI_USAGE);
|
|
14
12
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
// src/drivers/piSdkRunner.ts
|
|
2
|
-
import { readFile } from "fs/promises";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import {
|
|
5
|
-
AuthStorage,
|
|
6
|
-
createAgentSessionFromServices,
|
|
7
|
-
createAgentSessionServices,
|
|
8
|
-
SessionManager
|
|
9
|
-
} from "@earendil-works/pi-coding-agent";
|
|
10
|
-
function writeJson(value) {
|
|
11
|
-
process.stdout.write(`${JSON.stringify(value)}
|
|
12
|
-
`);
|
|
13
|
-
}
|
|
14
|
-
function parseArgs(argv) {
|
|
15
|
-
const index = argv.indexOf("--config");
|
|
16
|
-
const configPath = index >= 0 ? argv[index + 1] : void 0;
|
|
17
|
-
if (!configPath) throw new Error("Missing --config <path>");
|
|
18
|
-
return { configPath };
|
|
19
|
-
}
|
|
20
|
-
function resolveConfiguredModel(modelId, modelRegistry) {
|
|
21
|
-
if (!modelId) return void 0;
|
|
22
|
-
const [provider, ...rest] = modelId.split("/");
|
|
23
|
-
const providerScopedId = rest.join("/");
|
|
24
|
-
if (provider && providerScopedId) {
|
|
25
|
-
const exact = modelRegistry.find(provider, providerScopedId);
|
|
26
|
-
if (exact) return exact;
|
|
27
|
-
}
|
|
28
|
-
return modelRegistry.getAll().find(
|
|
29
|
-
(model) => model.id === modelId || `${model.provider}/${model.id}` === modelId || (providerScopedId ? model.id === providerScopedId : false)
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
async function createSessionManager(config) {
|
|
33
|
-
if (!config.sessionId) return SessionManager.create(config.cwd, config.sessionDir);
|
|
34
|
-
const localSessions = await SessionManager.list(config.cwd, config.sessionDir);
|
|
35
|
-
const match = localSessions.find((session) => session.id.startsWith(config.sessionId));
|
|
36
|
-
if (match) return SessionManager.open(match.path, config.sessionDir);
|
|
37
|
-
return SessionManager.create(config.cwd, config.sessionDir);
|
|
38
|
-
}
|
|
39
|
-
async function run() {
|
|
40
|
-
const { configPath } = parseArgs(process.argv.slice(2));
|
|
41
|
-
const config = JSON.parse(await readFile(configPath, "utf8"));
|
|
42
|
-
const authStorage = AuthStorage.create(path.join(config.agentDir, "auth.json"));
|
|
43
|
-
const services = await createAgentSessionServices({
|
|
44
|
-
cwd: config.cwd,
|
|
45
|
-
agentDir: config.agentDir,
|
|
46
|
-
authStorage,
|
|
47
|
-
resourceLoaderOptions: {
|
|
48
|
-
appendSystemPrompt: [config.standingPrompt],
|
|
49
|
-
noContextFiles: true,
|
|
50
|
-
noExtensions: true,
|
|
51
|
-
noPromptTemplates: true,
|
|
52
|
-
noSkills: true,
|
|
53
|
-
noThemes: true
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
for (const diagnostic of services.diagnostics) {
|
|
57
|
-
const line = `[Pi SDK] ${diagnostic.type}: ${diagnostic.message}`;
|
|
58
|
-
if (diagnostic.type === "error") throw new Error(line);
|
|
59
|
-
process.stderr.write(`${line}
|
|
60
|
-
`);
|
|
61
|
-
}
|
|
62
|
-
const sessionManager = await createSessionManager(config);
|
|
63
|
-
const model = resolveConfiguredModel(config.model, services.modelRegistry);
|
|
64
|
-
if (config.model && !model) {
|
|
65
|
-
throw new Error(`Configured Pi model '${config.model}' was not found in Pi model registry.`);
|
|
66
|
-
}
|
|
67
|
-
const { session } = await createAgentSessionFromServices({
|
|
68
|
-
services,
|
|
69
|
-
sessionManager,
|
|
70
|
-
model
|
|
71
|
-
});
|
|
72
|
-
const header = session.sessionManager.getHeader();
|
|
73
|
-
if (header) writeJson(header);
|
|
74
|
-
const unsubscribe = session.subscribe((event) => writeJson(event));
|
|
75
|
-
try {
|
|
76
|
-
await session.prompt(config.prompt);
|
|
77
|
-
} finally {
|
|
78
|
-
unsubscribe();
|
|
79
|
-
session.dispose();
|
|
80
|
-
await services.settingsManager.flush();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
run().catch((error) => {
|
|
84
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
85
|
-
writeJson({
|
|
86
|
-
type: "message_end",
|
|
87
|
-
message: {
|
|
88
|
-
role: "assistant",
|
|
89
|
-
content: [],
|
|
90
|
-
stopReason: "error",
|
|
91
|
-
errorMessage: message
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
writeJson({ type: "turn_end" });
|
|
95
|
-
process.exitCode = 1;
|
|
96
|
-
});
|