@slock-ai/daemon 0.57.1 → 0.57.2-play.20260608142014
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-6RZCYFJP.js → chunk-JVPMCKSF.js} +528 -73
- package/dist/cli/index.js +80 -5
- package/dist/core.js +5 -1
- package/dist/drivers/piSdkRunner.js +96 -0
- package/dist/index.js +5 -3
- package/package.json +1 -1
|
@@ -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,6 +2081,19 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
1980
2081
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
1981
2082
|
}
|
|
1982
2083
|
|
|
2084
|
+
// src/authEnv.ts
|
|
2085
|
+
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
2086
|
+
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
2087
|
+
function scrubDaemonAuthEnv(env) {
|
|
2088
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
2089
|
+
return env;
|
|
2090
|
+
}
|
|
2091
|
+
function scrubDaemonChildEnv(env) {
|
|
2092
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
2093
|
+
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
2094
|
+
return env;
|
|
2095
|
+
}
|
|
2096
|
+
|
|
1983
2097
|
// src/agentCredentialProxy.ts
|
|
1984
2098
|
import { randomBytes } from "crypto";
|
|
1985
2099
|
import http from "http";
|
|
@@ -3466,7 +3580,9 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
|
|
|
3466
3580
|
var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
|
|
3467
3581
|
var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
3468
3582
|
var RAW_CREDENTIAL_ENV_DENYLIST = [
|
|
3469
|
-
"
|
|
3583
|
+
"SLOCK_AGENT_TOKEN",
|
|
3584
|
+
"SLOCK_AGENT_CREDENTIAL_KEY",
|
|
3585
|
+
"SLOCK_AGENT_CREDENTIAL_KEY_FILE"
|
|
3470
3586
|
];
|
|
3471
3587
|
var cachedOpencliBinPath;
|
|
3472
3588
|
function resolveOpencliBinPath() {
|
|
@@ -3681,7 +3797,7 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(opencliBinPath)} "
|
|
|
3681
3797
|
...agentCredentialProxy ? {} : { SLOCK_AGENT_TOKEN_FILE: tokenFile },
|
|
3682
3798
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
3683
3799
|
};
|
|
3684
|
-
|
|
3800
|
+
scrubDaemonChildEnv(spawnEnv);
|
|
3685
3801
|
for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
|
|
3686
3802
|
delete spawnEnv[key];
|
|
3687
3803
|
}
|
|
@@ -4110,7 +4226,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn) {
|
|
|
4110
4226
|
}
|
|
4111
4227
|
function resolveCommandOnPath(command, deps = {}) {
|
|
4112
4228
|
const platform = deps.platform ?? process.platform;
|
|
4113
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4229
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
4114
4230
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4115
4231
|
const existsSyncFn = deps.existsSyncFn ?? existsSync2;
|
|
4116
4232
|
if (platform === "win32") {
|
|
@@ -4136,7 +4252,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
4136
4252
|
return null;
|
|
4137
4253
|
}
|
|
4138
4254
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
4139
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
4255
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
4140
4256
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
4141
4257
|
try {
|
|
4142
4258
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -5490,11 +5606,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
5490
5606
|
return parseCursorModelsOutput(String(result.stdout || ""));
|
|
5491
5607
|
}
|
|
5492
5608
|
function buildCursorModelProbeEnv(deps = {}) {
|
|
5493
|
-
return withWindowsUserEnvironment({
|
|
5609
|
+
return scrubDaemonChildEnv(withWindowsUserEnvironment({
|
|
5494
5610
|
...deps.env ?? process.env,
|
|
5495
5611
|
FORCE_COLOR: "0",
|
|
5496
5612
|
NO_COLOR: "1"
|
|
5497
|
-
}, deps);
|
|
5613
|
+
}, deps));
|
|
5498
5614
|
}
|
|
5499
5615
|
function runCursorModelsCommand() {
|
|
5500
5616
|
return spawnSync("cursor-agent", ["models"], {
|
|
@@ -5550,7 +5666,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
5550
5666
|
}
|
|
5551
5667
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
5552
5668
|
const existsSyncFn = deps.existsSyncFn ?? existsSync4;
|
|
5553
|
-
const env = deps.env ?? process.env;
|
|
5669
|
+
const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
|
|
5554
5670
|
const winPath = path6.win32;
|
|
5555
5671
|
let geminiEntry = null;
|
|
5556
5672
|
try {
|
|
@@ -5690,12 +5806,15 @@ var GeminiDriver = class {
|
|
|
5690
5806
|
// src/drivers/kimi.ts
|
|
5691
5807
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5692
5808
|
import { spawn as spawn7 } from "child_process";
|
|
5693
|
-
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
5809
|
+
import { chmodSync, existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
5694
5810
|
import os3 from "os";
|
|
5695
5811
|
import path7 from "path";
|
|
5696
5812
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
5697
5813
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
5698
5814
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
5815
|
+
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
5816
|
+
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
5817
|
+
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
5699
5818
|
function parseToolArguments(raw) {
|
|
5700
5819
|
if (typeof raw !== "string") return raw;
|
|
5701
5820
|
try {
|
|
@@ -5704,6 +5823,73 @@ function parseToolArguments(raw) {
|
|
|
5704
5823
|
return raw;
|
|
5705
5824
|
}
|
|
5706
5825
|
}
|
|
5826
|
+
function readKimiConfigSource(home = os3.homedir(), env = process.env) {
|
|
5827
|
+
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5828
|
+
if (inlineConfig && inlineConfig.trim()) {
|
|
5829
|
+
return {
|
|
5830
|
+
raw: inlineConfig,
|
|
5831
|
+
explicitPath: null,
|
|
5832
|
+
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
5833
|
+
};
|
|
5834
|
+
}
|
|
5835
|
+
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5836
|
+
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path7.join(home, ".kimi", "config.toml");
|
|
5837
|
+
try {
|
|
5838
|
+
return {
|
|
5839
|
+
raw: readFileSync3(configPath, "utf8"),
|
|
5840
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5841
|
+
sourcePath: configPath
|
|
5842
|
+
};
|
|
5843
|
+
} catch {
|
|
5844
|
+
return {
|
|
5845
|
+
raw: null,
|
|
5846
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
5847
|
+
sourcePath: configPath
|
|
5848
|
+
};
|
|
5849
|
+
}
|
|
5850
|
+
}
|
|
5851
|
+
function buildKimiSpawnEnv(env = process.env) {
|
|
5852
|
+
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
5853
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
5854
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
5855
|
+
return scrubDaemonChildEnv(spawnEnv);
|
|
5856
|
+
}
|
|
5857
|
+
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
5858
|
+
return {
|
|
5859
|
+
...process.env,
|
|
5860
|
+
...ctx.config.envVars || {},
|
|
5861
|
+
...overrideEnv || {}
|
|
5862
|
+
};
|
|
5863
|
+
}
|
|
5864
|
+
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
5865
|
+
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
5866
|
+
const source = readKimiConfigSource(opts.home ?? os3.homedir(), env);
|
|
5867
|
+
const args = [];
|
|
5868
|
+
let configFilePath = null;
|
|
5869
|
+
let configContent = null;
|
|
5870
|
+
if (source.explicitPath) {
|
|
5871
|
+
configFilePath = source.explicitPath;
|
|
5872
|
+
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
5873
|
+
configFilePath = path7.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
5874
|
+
configContent = source.raw;
|
|
5875
|
+
if (opts.writeGeneratedConfig !== false) {
|
|
5876
|
+
writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
5877
|
+
chmodSync(configFilePath, 384);
|
|
5878
|
+
}
|
|
5879
|
+
}
|
|
5880
|
+
if (configFilePath) {
|
|
5881
|
+
args.push("--config-file", configFilePath);
|
|
5882
|
+
}
|
|
5883
|
+
if (ctx.config.model && ctx.config.model !== "default") {
|
|
5884
|
+
args.push("--model", ctx.config.model);
|
|
5885
|
+
}
|
|
5886
|
+
return {
|
|
5887
|
+
args,
|
|
5888
|
+
env: buildKimiSpawnEnv(env),
|
|
5889
|
+
configFilePath,
|
|
5890
|
+
configContent
|
|
5891
|
+
};
|
|
5892
|
+
}
|
|
5707
5893
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
5708
5894
|
return {
|
|
5709
5895
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -5727,7 +5913,25 @@ var KimiDriver = class {
|
|
|
5727
5913
|
};
|
|
5728
5914
|
model = {
|
|
5729
5915
|
detectedModelsVerifiedAs: "launchable",
|
|
5730
|
-
toLaunchSpec: (modelId) =>
|
|
5916
|
+
toLaunchSpec: (modelId, ctx, opts) => {
|
|
5917
|
+
if (!ctx) return { args: ["--model", modelId] };
|
|
5918
|
+
const launchCtx = {
|
|
5919
|
+
...ctx,
|
|
5920
|
+
config: {
|
|
5921
|
+
...ctx.config,
|
|
5922
|
+
model: modelId
|
|
5923
|
+
}
|
|
5924
|
+
};
|
|
5925
|
+
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
5926
|
+
home: opts?.home,
|
|
5927
|
+
writeGeneratedConfig: false
|
|
5928
|
+
});
|
|
5929
|
+
return {
|
|
5930
|
+
args: launch.args,
|
|
5931
|
+
env: launch.env,
|
|
5932
|
+
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
5933
|
+
};
|
|
5934
|
+
}
|
|
5731
5935
|
};
|
|
5732
5936
|
supportsStdinNotification = true;
|
|
5733
5937
|
mcpToolPrefix = "";
|
|
@@ -5753,21 +5957,23 @@ var KimiDriver = class {
|
|
|
5753
5957
|
` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
|
|
5754
5958
|
""
|
|
5755
5959
|
].join("\n"), "utf8");
|
|
5960
|
+
const launch = buildKimiLaunchOptions(ctx);
|
|
5756
5961
|
const args = [
|
|
5757
5962
|
"--wire",
|
|
5758
5963
|
"--yolo",
|
|
5759
5964
|
"--agent-file",
|
|
5760
5965
|
agentFilePath,
|
|
5761
5966
|
"--session",
|
|
5762
|
-
this.sessionId
|
|
5967
|
+
this.sessionId,
|
|
5968
|
+
...launch.args
|
|
5763
5969
|
];
|
|
5764
5970
|
const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
|
|
5765
5971
|
if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
|
|
5766
5972
|
args.push("--model", launchRuntimeFields.model);
|
|
5767
5973
|
}
|
|
5768
5974
|
const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
5769
|
-
const
|
|
5770
|
-
const proc = spawn7(
|
|
5975
|
+
const spawnTarget = resolveKimiSpawn(args);
|
|
5976
|
+
const proc = spawn7(spawnTarget.command, spawnTarget.args, {
|
|
5771
5977
|
cwd: ctx.workingDirectory,
|
|
5772
5978
|
stdio: ["pipe", "pipe", "pipe"],
|
|
5773
5979
|
env: spawnEnv,
|
|
@@ -5775,7 +5981,7 @@ var KimiDriver = class {
|
|
|
5775
5981
|
// and has an 8191-character command-line limit. Kimi's official
|
|
5776
5982
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
5777
5983
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
5778
|
-
shell:
|
|
5984
|
+
shell: spawnTarget.shell
|
|
5779
5985
|
});
|
|
5780
5986
|
proc.stdin?.write(JSON.stringify({
|
|
5781
5987
|
jsonrpc: "2.0",
|
|
@@ -5889,14 +6095,9 @@ var KimiDriver = class {
|
|
|
5889
6095
|
return detectKimiModels();
|
|
5890
6096
|
}
|
|
5891
6097
|
};
|
|
5892
|
-
function detectKimiModels(home = os3.homedir()) {
|
|
5893
|
-
const
|
|
5894
|
-
|
|
5895
|
-
try {
|
|
5896
|
-
raw = readFileSync3(configPath, "utf8");
|
|
5897
|
-
} catch {
|
|
5898
|
-
return null;
|
|
5899
|
-
}
|
|
6098
|
+
function detectKimiModels(home = os3.homedir(), opts = {}) {
|
|
6099
|
+
const raw = readKimiConfigSource(home, opts.env).raw;
|
|
6100
|
+
if (raw === null) return null;
|
|
5900
6101
|
const models = [];
|
|
5901
6102
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
5902
6103
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -6136,7 +6337,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
6136
6337
|
const platform = deps.platform ?? process.platform;
|
|
6137
6338
|
const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
|
|
6138
6339
|
const result = spawnSyncFn("opencode", ["models"], {
|
|
6139
|
-
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
6340
|
+
env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
|
|
6140
6341
|
encoding: "utf8",
|
|
6141
6342
|
timeout: 5e3,
|
|
6142
6343
|
shell: platform === "win32"
|
|
@@ -7381,16 +7582,19 @@ var RuntimeProgressState = class {
|
|
|
7381
7582
|
};
|
|
7382
7583
|
|
|
7383
7584
|
// src/runtimeNotificationState.ts
|
|
7585
|
+
function inboxNoticeMessageIdentity(message) {
|
|
7586
|
+
const seq = typeof message.seq === "number" && Number.isFinite(message.seq) && message.seq > 0 ? Math.floor(message.seq) : null;
|
|
7587
|
+
if (seq !== null) {
|
|
7588
|
+
return `s:${seq}`;
|
|
7589
|
+
}
|
|
7590
|
+
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 : "";
|
|
7591
|
+
return id.length > 0 ? `m:${id}` : "";
|
|
7592
|
+
}
|
|
7384
7593
|
function computeInboxNoticeFingerprint(messages) {
|
|
7385
7594
|
const keys = [];
|
|
7386
7595
|
for (const m of messages) {
|
|
7387
|
-
const
|
|
7388
|
-
if (
|
|
7389
|
-
keys.push(`s:${seq}`);
|
|
7390
|
-
continue;
|
|
7391
|
-
}
|
|
7392
|
-
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 : "";
|
|
7393
|
-
if (id.length > 0) keys.push(`m:${id}`);
|
|
7596
|
+
const key = inboxNoticeMessageIdentity(m);
|
|
7597
|
+
if (key.length > 0) keys.push(key);
|
|
7394
7598
|
}
|
|
7395
7599
|
if (keys.length === 0) return "";
|
|
7396
7600
|
keys.sort();
|
|
@@ -7401,6 +7605,10 @@ var RuntimeNotificationState = class {
|
|
|
7401
7605
|
pendingCountValue = 0;
|
|
7402
7606
|
lastNoticeFingerprint = null;
|
|
7403
7607
|
lastNoticeSessionId = null;
|
|
7608
|
+
lastEncodeFailedFingerprint = null;
|
|
7609
|
+
lastEncodeFailedSessionId = null;
|
|
7610
|
+
contributedSessionId = null;
|
|
7611
|
+
contributedIdentities = /* @__PURE__ */ new Set();
|
|
7404
7612
|
get pendingCount() {
|
|
7405
7613
|
return this.pendingCountValue;
|
|
7406
7614
|
}
|
|
@@ -7443,13 +7651,63 @@ var RuntimeNotificationState = class {
|
|
|
7443
7651
|
return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
|
|
7444
7652
|
}
|
|
7445
7653
|
/** Register a fingerprint as written — call ONLY after a successful stdin write. */
|
|
7446
|
-
recordNoticeWritten(fingerprint, sessionId) {
|
|
7654
|
+
recordNoticeWritten(fingerprint, sessionId, messages = []) {
|
|
7447
7655
|
this.lastNoticeFingerprint = fingerprint;
|
|
7448
7656
|
this.lastNoticeSessionId = sessionId;
|
|
7657
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7658
|
+
this.lastEncodeFailedSessionId = null;
|
|
7659
|
+
this.ensureContributionSession(sessionId);
|
|
7660
|
+
for (const message of messages) {
|
|
7661
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7662
|
+
if (identity.length > 0) {
|
|
7663
|
+
this.contributedIdentities.add(identity);
|
|
7664
|
+
}
|
|
7665
|
+
}
|
|
7666
|
+
}
|
|
7667
|
+
hasContributedMessage(message, sessionId) {
|
|
7668
|
+
if (this.contributedSessionId !== sessionId) return false;
|
|
7669
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7670
|
+
return identity.length > 0 && this.contributedIdentities.has(identity);
|
|
7671
|
+
}
|
|
7672
|
+
filterUncontributedMessages(messages, sessionId) {
|
|
7673
|
+
if (this.contributedSessionId !== sessionId || this.contributedIdentities.size === 0) {
|
|
7674
|
+
return [...messages];
|
|
7675
|
+
}
|
|
7676
|
+
return messages.filter((message) => {
|
|
7677
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7678
|
+
return identity.length === 0 || !this.contributedIdentities.has(identity);
|
|
7679
|
+
});
|
|
7680
|
+
}
|
|
7681
|
+
pruneContributedToPending(messages, sessionId) {
|
|
7682
|
+
this.ensureContributionSession(sessionId);
|
|
7683
|
+
if (this.contributedIdentities.size === 0) return;
|
|
7684
|
+
const pending = /* @__PURE__ */ new Set();
|
|
7685
|
+
for (const message of messages) {
|
|
7686
|
+
const identity = inboxNoticeMessageIdentity(message);
|
|
7687
|
+
if (identity.length > 0) pending.add(identity);
|
|
7688
|
+
}
|
|
7689
|
+
for (const identity of this.contributedIdentities) {
|
|
7690
|
+
if (!pending.has(identity)) {
|
|
7691
|
+
this.contributedIdentities.delete(identity);
|
|
7692
|
+
}
|
|
7693
|
+
}
|
|
7694
|
+
}
|
|
7695
|
+
isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
|
|
7696
|
+
if (fingerprint.length === 0) return false;
|
|
7697
|
+
return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
|
|
7698
|
+
}
|
|
7699
|
+
recordNoticeEncodeFailed(fingerprint, sessionId) {
|
|
7700
|
+
if (fingerprint.length === 0) return;
|
|
7701
|
+
this.lastEncodeFailedFingerprint = fingerprint;
|
|
7702
|
+
this.lastEncodeFailedSessionId = sessionId;
|
|
7449
7703
|
}
|
|
7450
7704
|
clearNoticeFingerprint() {
|
|
7451
7705
|
this.lastNoticeFingerprint = null;
|
|
7452
7706
|
this.lastNoticeSessionId = null;
|
|
7707
|
+
this.lastEncodeFailedFingerprint = null;
|
|
7708
|
+
this.lastEncodeFailedSessionId = null;
|
|
7709
|
+
this.contributedSessionId = null;
|
|
7710
|
+
this.contributedIdentities.clear();
|
|
7453
7711
|
}
|
|
7454
7712
|
schedule(callback, delayMs) {
|
|
7455
7713
|
if (this.timerValue) return false;
|
|
@@ -7462,6 +7720,11 @@ var RuntimeNotificationState = class {
|
|
|
7462
7720
|
this.clearTimer();
|
|
7463
7721
|
return count;
|
|
7464
7722
|
}
|
|
7723
|
+
ensureContributionSession(sessionId) {
|
|
7724
|
+
if (this.contributedSessionId === sessionId) return;
|
|
7725
|
+
this.contributedSessionId = sessionId;
|
|
7726
|
+
this.contributedIdentities.clear();
|
|
7727
|
+
}
|
|
7465
7728
|
};
|
|
7466
7729
|
|
|
7467
7730
|
// src/agentProcessManager.ts
|
|
@@ -8605,6 +8868,7 @@ var RUNTIME_TELEMETRY_RESERVED_ATTR_KEYS = /* @__PURE__ */ new Set([
|
|
|
8605
8868
|
"sessionId",
|
|
8606
8869
|
"turnId",
|
|
8607
8870
|
"runtimeResultId",
|
|
8871
|
+
"runtimeResultIdSource",
|
|
8608
8872
|
"daemonVersion",
|
|
8609
8873
|
"daemon_version",
|
|
8610
8874
|
"daemon_version_present",
|
|
@@ -8780,13 +9044,33 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8780
9044
|
this.sendStdinNotification(agentId);
|
|
8781
9045
|
}, delayMs);
|
|
8782
9046
|
}
|
|
9047
|
+
flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, source) {
|
|
9048
|
+
if (ap.notifications.pendingCount === 0) return false;
|
|
9049
|
+
if (ap.isIdle) return false;
|
|
9050
|
+
if (!ap.sessionId) return false;
|
|
9051
|
+
if (!ap.driver.supportsStdinNotification) return false;
|
|
9052
|
+
if (ap.runtime.descriptor.busyDelivery !== "direct") return false;
|
|
9053
|
+
if (ap.gatedSteering.compacting) return false;
|
|
9054
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification.retry_signal", {
|
|
9055
|
+
agentId,
|
|
9056
|
+
runtime: ap.config.runtime,
|
|
9057
|
+
model: ap.config.model,
|
|
9058
|
+
launchId: ap.launchId || void 0,
|
|
9059
|
+
source,
|
|
9060
|
+
mode: "busy",
|
|
9061
|
+
pending_notification_count: ap.notifications.pendingCount,
|
|
9062
|
+
inbox_count: ap.inbox.length,
|
|
9063
|
+
session_id_present: true
|
|
9064
|
+
});
|
|
9065
|
+
return this.sendStdinNotification(agentId, { forceUnsupportedRetry: true });
|
|
9066
|
+
}
|
|
8783
9067
|
clearRuntimeErrorDeliveryBackoff(ap) {
|
|
8784
9068
|
if (ap.runtimeErrorDeliveryBackoff.timer) {
|
|
8785
9069
|
clearTimeout(ap.runtimeErrorDeliveryBackoff.timer);
|
|
8786
9070
|
}
|
|
8787
9071
|
ap.runtimeErrorDeliveryBackoff = createRuntimeErrorDeliveryBackoffState();
|
|
8788
9072
|
}
|
|
8789
|
-
|
|
9073
|
+
clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, resetSource) {
|
|
8790
9074
|
if (ap.runtimeErrorDeliveryBackoff.attempts === 0 && ap.runtimeErrorDeliveryBackoff.untilMs === 0) return;
|
|
8791
9075
|
const attempts = ap.runtimeErrorDeliveryBackoff.attempts;
|
|
8792
9076
|
const reason = ap.runtimeErrorDeliveryBackoff.reason;
|
|
@@ -8798,9 +9082,12 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8798
9082
|
launchId: ap.launchId || void 0,
|
|
8799
9083
|
reason: reason || void 0,
|
|
8800
9084
|
attempts,
|
|
8801
|
-
reset_source:
|
|
9085
|
+
reset_source: resetSource
|
|
8802
9086
|
});
|
|
8803
9087
|
}
|
|
9088
|
+
clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, eventKind) {
|
|
9089
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, eventKind);
|
|
9090
|
+
}
|
|
8804
9091
|
runtimeErrorDeliveryBackoffRemainingMs(ap) {
|
|
8805
9092
|
return Math.max(0, ap.runtimeErrorDeliveryBackoff.untilMs - Date.now());
|
|
8806
9093
|
}
|
|
@@ -8828,8 +9115,10 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8828
9115
|
return "provider_connection_error";
|
|
8829
9116
|
case "ProviderStreamError":
|
|
8830
9117
|
return "provider_stream_error";
|
|
8831
|
-
|
|
9118
|
+
case "TimeoutError":
|
|
8832
9119
|
return null;
|
|
9120
|
+
default:
|
|
9121
|
+
return "runtime_error";
|
|
8833
9122
|
}
|
|
8834
9123
|
}
|
|
8835
9124
|
noteRuntimeErrorDeliveryBackoff(agentId, ap, message, terminalFailure, stickyTerminalFailure, reasonOverride) {
|
|
@@ -8900,9 +9189,24 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
8900
9189
|
if (ap.inbox.length === 0) return false;
|
|
8901
9190
|
const reason = ap.runtimeErrorDeliveryBackoff.reason || "runtime_error_backoff";
|
|
8902
9191
|
if (ap.isIdle && ap.driver.supportsStdinNotification && ap.sessionId) {
|
|
8903
|
-
|
|
9192
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
9193
|
+
const messages = ap.notifications.filterUncontributedMessages(ap.inbox, ap.sessionId);
|
|
8904
9194
|
ap.notifications.clearPending();
|
|
8905
9195
|
ap.notifications.clearTimer();
|
|
9196
|
+
if (messages.length === 0) {
|
|
9197
|
+
this.recordDaemonTrace("daemon.agent.runtime_error_delivery_backoff.flush", {
|
|
9198
|
+
agentId,
|
|
9199
|
+
runtime: ap.config.runtime,
|
|
9200
|
+
model: ap.config.model,
|
|
9201
|
+
launchId: ap.launchId || void 0,
|
|
9202
|
+
reason,
|
|
9203
|
+
mode: "idle",
|
|
9204
|
+
outcome: "suppressed_already_contributed",
|
|
9205
|
+
inbox_count: ap.inbox.length,
|
|
9206
|
+
messages_count: 0
|
|
9207
|
+
});
|
|
9208
|
+
return false;
|
|
9209
|
+
}
|
|
8906
9210
|
this.commitApmIdleState(agentId, ap, false);
|
|
8907
9211
|
this.startRuntimeTrace(agentId, ap, "runtime-error-backoff-idle-delivery", messages);
|
|
8908
9212
|
this.broadcastActivity(agentId, "working", "Message received");
|
|
@@ -9583,6 +9887,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
9583
9887
|
runtimeProgress: new RuntimeProgressState(Date.now()),
|
|
9584
9888
|
runtimeTraceSpan: null,
|
|
9585
9889
|
runtimeTraceCounters: createRuntimeTraceCounters(),
|
|
9890
|
+
runtimeTelemetryResultSeq: 0,
|
|
9586
9891
|
lastActivity: "",
|
|
9587
9892
|
lastActivityDetail: "",
|
|
9588
9893
|
recentStdout: [],
|
|
@@ -10135,6 +10440,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10135
10440
|
this.agents.delete(agentId);
|
|
10136
10441
|
if (!silent) {
|
|
10137
10442
|
this.activityClientSeqByAgent.delete(agentId);
|
|
10443
|
+
this.agentVisibleBoundaries.delete(agentId);
|
|
10444
|
+
this.agentVisibleMessageIds.delete(agentId);
|
|
10138
10445
|
}
|
|
10139
10446
|
this.runtimeExitTraceAttrs.set(ap.runtime, {
|
|
10140
10447
|
stop_source: silent ? "daemon_internal" : "explicit_request",
|
|
@@ -10358,6 +10665,25 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
10358
10665
|
}));
|
|
10359
10666
|
return true;
|
|
10360
10667
|
}
|
|
10668
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
10669
|
+
const noticeFingerprint = computeInboxNoticeFingerprint([message]);
|
|
10670
|
+
const messageAlreadyPending = noticeFingerprint.length > 0 && ap.inbox.some((pending) => computeInboxNoticeFingerprint([pending]) === noticeFingerprint);
|
|
10671
|
+
const messageAlreadyContributed = ap.notifications.hasContributedMessage(message, ap.sessionId);
|
|
10672
|
+
if (messageAlreadyPending && (messageAlreadyContributed || ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId))) {
|
|
10673
|
+
this.recordDaemonTrace("daemon.agent.delivery.routed", this.deliveryTraceAttrs(agentId, message, {
|
|
10674
|
+
outcome: "suppressed_duplicate_stdin_idle_delivery",
|
|
10675
|
+
accepted: true,
|
|
10676
|
+
process_present: true,
|
|
10677
|
+
runtime: ap.config.runtime,
|
|
10678
|
+
session_id_present: true,
|
|
10679
|
+
launchId: ap.launchId || void 0,
|
|
10680
|
+
is_idle: ap.isIdle,
|
|
10681
|
+
inbox_count: ap.inbox.length,
|
|
10682
|
+
pending_notification_count: ap.notifications.pendingCount
|
|
10683
|
+
}));
|
|
10684
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate idle stdin inbox update (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
10685
|
+
return true;
|
|
10686
|
+
}
|
|
10361
10687
|
ap.inbox.push(message);
|
|
10362
10688
|
const nextMessages = [...ap.inbox];
|
|
10363
10689
|
this.commitApmIdleState(agentId, ap, false);
|
|
@@ -11226,6 +11552,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11226
11552
|
if (row.flags.includes("task")) taskTargetCount += 1;
|
|
11227
11553
|
}
|
|
11228
11554
|
return {
|
|
11555
|
+
target_count: rows.length,
|
|
11556
|
+
changed_target_count: rows.length,
|
|
11229
11557
|
inbox_target_count: rows.length,
|
|
11230
11558
|
pending_message_count: pendingMessageCount,
|
|
11231
11559
|
max_pending_per_target: maxPendingCount,
|
|
@@ -11399,7 +11727,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11399
11727
|
return false;
|
|
11400
11728
|
}
|
|
11401
11729
|
const messages = [...ap.inbox];
|
|
11402
|
-
ap.notifications.
|
|
11730
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
11731
|
+
ap.notifications.clearPending();
|
|
11732
|
+
ap.notifications.clearTimer();
|
|
11403
11733
|
if (messages.length === 0) {
|
|
11404
11734
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11405
11735
|
outcome: "empty",
|
|
@@ -11415,12 +11745,23 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11415
11745
|
messageCount: messages.length
|
|
11416
11746
|
});
|
|
11417
11747
|
}
|
|
11418
|
-
this.broadcastActivity(agentId, "working", "Message received");
|
|
11419
11748
|
const runtimeProfileMessages = messages.filter((message) => runtimeProfileNotificationFromMessage(message));
|
|
11420
|
-
const
|
|
11749
|
+
const ordinaryMessageCandidates = messages.filter((message) => !runtimeProfileNotificationFromMessage(message));
|
|
11750
|
+
const ordinaryMessages = ap.notifications.filterUncontributedMessages(
|
|
11751
|
+
ordinaryMessageCandidates,
|
|
11752
|
+
ap.sessionId
|
|
11753
|
+
);
|
|
11754
|
+
if (runtimeProfileMessages.length === 0 && ordinaryMessages.length === 0) {
|
|
11755
|
+
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11756
|
+
outcome: "suppressed_already_contributed",
|
|
11757
|
+
delivered_messages_count: 0
|
|
11758
|
+
});
|
|
11759
|
+
return false;
|
|
11760
|
+
}
|
|
11761
|
+
this.broadcastActivity(agentId, "working", "Message received");
|
|
11421
11762
|
let accepted = true;
|
|
11422
11763
|
if (runtimeProfileMessages.length > 0) {
|
|
11423
|
-
ap.inbox.splice(0, ap.inbox.length, ...
|
|
11764
|
+
ap.inbox.splice(0, ap.inbox.length, ...ordinaryMessageCandidates);
|
|
11424
11765
|
accepted = this.deliverMessagesViaStdin(agentId, ap, runtimeProfileMessages, effect.stdinMode);
|
|
11425
11766
|
}
|
|
11426
11767
|
if (ordinaryMessages.length > 0) {
|
|
@@ -11434,7 +11775,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11434
11775
|
}
|
|
11435
11776
|
this.recordApmGatedSteeringEffectTrace(agentId, ap, effect, {
|
|
11436
11777
|
outcome: accepted ? "written" : "not_written",
|
|
11437
|
-
delivered_messages_count:
|
|
11778
|
+
delivered_messages_count: runtimeProfileMessages.length + ordinaryMessages.length
|
|
11438
11779
|
});
|
|
11439
11780
|
return accepted;
|
|
11440
11781
|
}
|
|
@@ -11666,6 +12007,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11666
12007
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11667
12008
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11668
12009
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "thinking" });
|
|
12010
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11669
12011
|
}
|
|
11670
12012
|
break;
|
|
11671
12013
|
}
|
|
@@ -11676,6 +12018,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11676
12018
|
this.clearRuntimeErrorDeliveryBackoffAfterProgress(agentId, ap, event.kind);
|
|
11677
12019
|
const reduction = reduceApmGatedAssistantContinuation(ap.gatedSteering);
|
|
11678
12020
|
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "text" });
|
|
12021
|
+
this.flushPendingDirectStdinNotificationOnRuntimeProgress(agentId, ap, event.kind);
|
|
11679
12022
|
}
|
|
11680
12023
|
break;
|
|
11681
12024
|
}
|
|
@@ -11748,6 +12091,9 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11748
12091
|
if (ap) {
|
|
11749
12092
|
if (event.sessionId) ap.sessionId = event.sessionId;
|
|
11750
12093
|
const stickyTerminalFailure = classifyStickyTerminalFailure(ap);
|
|
12094
|
+
if (!stickyTerminalFailure && ap.runtimeErrorDeliveryBackoff.reason === "runtime_error") {
|
|
12095
|
+
this.clearRuntimeErrorDeliveryBackoffWithTrace(agentId, ap, "turn_end_unclassified_runtime_error");
|
|
12096
|
+
}
|
|
11751
12097
|
const reduction = reduceApmGatedTurnEnd(ap.gatedSteering, {
|
|
11752
12098
|
inboxLength: stickyTerminalFailure ? 0 : ap.inbox.length,
|
|
11753
12099
|
supportsStdinNotification: ap.driver.supportsStdinNotification,
|
|
@@ -11879,7 +12225,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11879
12225
|
}
|
|
11880
12226
|
}
|
|
11881
12227
|
recordRuntimeTelemetry(agentId, ap, event) {
|
|
11882
|
-
const sessionId = ap.driver.currentSessionId ?? event.sessionId;
|
|
12228
|
+
const sessionId = ap.driver.currentSessionId ?? event.sessionId ?? ap.sessionId ?? ap.config.sessionId;
|
|
12229
|
+
const resultIdentity = this.runtimeTelemetryResultIdentity(agentId, ap, event);
|
|
11883
12230
|
const payloadAttrs = sanitizeRuntimeTelemetryPayloadAttrs(event.attrs);
|
|
11884
12231
|
const versionAttrs = this.runtimeTelemetryVersionAttrs();
|
|
11885
12232
|
const telemetryAttrs = {
|
|
@@ -11889,7 +12236,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11889
12236
|
...event.usageKind ? { usageKind: event.usageKind } : {},
|
|
11890
12237
|
...sessionId ? { sessionId } : {},
|
|
11891
12238
|
...event.turnId ? { turnId: event.turnId } : {},
|
|
11892
|
-
...
|
|
12239
|
+
...resultIdentity
|
|
11893
12240
|
};
|
|
11894
12241
|
const attrs = {
|
|
11895
12242
|
agentId,
|
|
@@ -11902,6 +12249,16 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11902
12249
|
ap.runtimeTraceSpan?.addEvent(`runtime.telemetry.${event.name}`, telemetryAttrs);
|
|
11903
12250
|
this.recordDaemonTrace(`daemon.runtime.telemetry.${event.name}`, attrs);
|
|
11904
12251
|
}
|
|
12252
|
+
runtimeTelemetryResultIdentity(agentId, ap, event) {
|
|
12253
|
+
if (event.runtimeResultId) return { runtimeResultId: event.runtimeResultId };
|
|
12254
|
+
if (event.name !== "token_usage" || event.source !== "claude_result_usage") return {};
|
|
12255
|
+
const sequence = ++ap.runtimeTelemetryResultSeq;
|
|
12256
|
+
const scope = ap.launchId || agentId;
|
|
12257
|
+
return {
|
|
12258
|
+
runtimeResultId: `${scope}:claude_result_usage:${sequence}`,
|
|
12259
|
+
runtimeResultIdSource: "daemon_sequence"
|
|
12260
|
+
};
|
|
12261
|
+
}
|
|
11905
12262
|
runtimeTelemetryVersionAttrs() {
|
|
11906
12263
|
return {
|
|
11907
12264
|
...this.daemonVersion ? {
|
|
@@ -11970,7 +12327,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
11970
12327
|
}
|
|
11971
12328
|
}
|
|
11972
12329
|
/** Send a batched notification to the agent via stdin about pending messages */
|
|
11973
|
-
sendStdinNotification(agentId) {
|
|
12330
|
+
sendStdinNotification(agentId, options = {}) {
|
|
11974
12331
|
const ap = this.agents.get(agentId);
|
|
11975
12332
|
if (!ap) return false;
|
|
11976
12333
|
const count = ap.notifications.takePendingAndClearTimer();
|
|
@@ -12012,7 +12369,24 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12012
12369
|
}
|
|
12013
12370
|
const inboxCount = ap.inbox.length;
|
|
12014
12371
|
if (inboxCount === 0) return false;
|
|
12015
|
-
|
|
12372
|
+
ap.notifications.pruneContributedToPending(ap.inbox, ap.sessionId);
|
|
12373
|
+
const changedMessageCandidates = ap.inbox.slice(Math.max(0, ap.inbox.length - count));
|
|
12374
|
+
const changedMessages = ap.notifications.filterUncontributedMessages(changedMessageCandidates, ap.sessionId);
|
|
12375
|
+
if (changedMessages.length === 0) {
|
|
12376
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12377
|
+
agentId,
|
|
12378
|
+
runtime: ap.config.runtime,
|
|
12379
|
+
model: ap.config.model,
|
|
12380
|
+
launchId: ap.launchId || void 0,
|
|
12381
|
+
outcome: "suppressed_already_contributed",
|
|
12382
|
+
mode: "busy",
|
|
12383
|
+
pending_notification_count: count,
|
|
12384
|
+
inbox_count: ap.inbox.length,
|
|
12385
|
+
session_id_present: true
|
|
12386
|
+
});
|
|
12387
|
+
logger.info(`[Agent ${agentId}] Suppressing stdin inbox notice because all candidate messages already contributed; pending=${ap.inbox.length}`);
|
|
12388
|
+
return false;
|
|
12389
|
+
}
|
|
12016
12390
|
const noticeFingerprint = computeInboxNoticeFingerprint(changedMessages);
|
|
12017
12391
|
if (ap.notifications.isDuplicateNotice(noticeFingerprint, ap.sessionId)) {
|
|
12018
12392
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
@@ -12029,6 +12403,22 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
12029
12403
|
logger.info(`[Agent ${agentId}] Suppressing duplicate stdin inbox notice (unread-set unchanged since last write); pending=${ap.inbox.length}`);
|
|
12030
12404
|
return false;
|
|
12031
12405
|
}
|
|
12406
|
+
if (!options.forceUnsupportedRetry && ap.notifications.isDuplicateEncodeFailedNotice(noticeFingerprint, ap.sessionId)) {
|
|
12407
|
+
ap.notifications.add(count);
|
|
12408
|
+
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12409
|
+
agentId,
|
|
12410
|
+
runtime: ap.config.runtime,
|
|
12411
|
+
model: ap.config.model,
|
|
12412
|
+
launchId: ap.launchId || void 0,
|
|
12413
|
+
outcome: "suppressed_duplicate_encode_failed",
|
|
12414
|
+
mode: "busy",
|
|
12415
|
+
pending_notification_count: count,
|
|
12416
|
+
inbox_count: ap.inbox.length,
|
|
12417
|
+
session_id_present: true
|
|
12418
|
+
});
|
|
12419
|
+
logger.info(`[Agent ${agentId}] Suppressing duplicate unsupported stdin inbox notice (unread-set unchanged since last encode failure); pending=${ap.inbox.length}`);
|
|
12420
|
+
return false;
|
|
12421
|
+
}
|
|
12032
12422
|
const inboxRows = projectAgentInboxSnapshot(changedMessages);
|
|
12033
12423
|
const notification = `[Slock inbox notice:
|
|
12034
12424
|
${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
@@ -12051,6 +12441,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12051
12441
|
model: ap.config.model,
|
|
12052
12442
|
launchId: ap.launchId || void 0,
|
|
12053
12443
|
mode: "busy",
|
|
12444
|
+
source: "busy_stdin_notification",
|
|
12054
12445
|
notification_byte_count: notificationByteCount,
|
|
12055
12446
|
...projectionAttrs
|
|
12056
12447
|
});
|
|
@@ -12066,12 +12457,15 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12066
12457
|
inbox_target_count: inboxRows.length,
|
|
12067
12458
|
session_id_present: true
|
|
12068
12459
|
});
|
|
12069
|
-
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId);
|
|
12460
|
+
ap.notifications.recordNoticeWritten(noticeFingerprint, ap.sessionId, changedMessages);
|
|
12070
12461
|
return true;
|
|
12071
12462
|
} else {
|
|
12072
12463
|
ap.notifications.add(count);
|
|
12073
|
-
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12464
|
+
const retryScheduled = ap.runtime.descriptor.busyDelivery === "direct" && sendResult.reason !== "unsupported" ? this.scheduleStdinNotification(agentId, ap, this.stdinNotificationRetryMs) : false;
|
|
12074
12465
|
const outcome = runtimeSendFailureOutcome(sendResult);
|
|
12466
|
+
if (outcome === "encode_failed") {
|
|
12467
|
+
ap.notifications.recordNoticeEncodeFailed(noticeFingerprint, ap.sessionId);
|
|
12468
|
+
}
|
|
12075
12469
|
this.recordDaemonTrace("daemon.agent.stdin_notification", {
|
|
12076
12470
|
agentId,
|
|
12077
12471
|
runtime: ap.config.runtime,
|
|
@@ -12113,6 +12507,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12113
12507
|
model: ap.config.model,
|
|
12114
12508
|
launchId: ap.launchId || void 0,
|
|
12115
12509
|
mode,
|
|
12510
|
+
source,
|
|
12116
12511
|
notification_byte_count: Buffer.byteLength(renderedInput, "utf8"),
|
|
12117
12512
|
cursors_advanced: "none",
|
|
12118
12513
|
...projectionAttrs
|
|
@@ -12191,6 +12586,7 @@ ${formatAgentInboxDelta(inboxRows, { totalPendingMessages: inboxCount })}]`;
|
|
|
12191
12586
|
stdin_write_attempted: true,
|
|
12192
12587
|
cursors_advanced: "none"
|
|
12193
12588
|
});
|
|
12589
|
+
ap.notifications.recordNoticeWritten(computeInboxNoticeFingerprint(messages), ap.sessionId, messages);
|
|
12194
12590
|
return true;
|
|
12195
12591
|
}
|
|
12196
12592
|
/** Deliver a message to an agent via stdin, formatting it the same way as the MCP bridge */
|
|
@@ -12407,7 +12803,7 @@ var DaemonConnection = class {
|
|
|
12407
12803
|
logger.warn(`[Daemon] Dropping outbound message while disconnected: ${msg.type}`);
|
|
12408
12804
|
}
|
|
12409
12805
|
this.trace("daemon.connection.outbound_dropped", {
|
|
12410
|
-
|
|
12806
|
+
outbound_message_kind: msg.type,
|
|
12411
12807
|
ws_ready_state: this.ws?.readyState ?? null
|
|
12412
12808
|
});
|
|
12413
12809
|
}
|
|
@@ -12456,7 +12852,7 @@ var DaemonConnection = class {
|
|
|
12456
12852
|
this.resetWatchdog();
|
|
12457
12853
|
if (messageKind !== "ping") {
|
|
12458
12854
|
this.trace("daemon.connection.inbound_received", {
|
|
12459
|
-
|
|
12855
|
+
inbound_message_kind: messageKind,
|
|
12460
12856
|
last_inbound_age_ms_bucket: "0"
|
|
12461
12857
|
});
|
|
12462
12858
|
}
|
|
@@ -12547,7 +12943,7 @@ var DaemonConnection = class {
|
|
|
12547
12943
|
if (msg.launchId && latestLaunchId && msg.launchId !== latestLaunchId) {
|
|
12548
12944
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12549
12945
|
reason: "launch_changed",
|
|
12550
|
-
|
|
12946
|
+
outbound_message_kind: msg.type,
|
|
12551
12947
|
agentId: msg.agentId,
|
|
12552
12948
|
stale_launch_id_present: true,
|
|
12553
12949
|
next_launch_id_present: true
|
|
@@ -12567,7 +12963,7 @@ var DaemonConnection = class {
|
|
|
12567
12963
|
this.pendingActivityByAgent.delete(identity.agentId);
|
|
12568
12964
|
this.trace("daemon.connection.pending_activity_invalidated", {
|
|
12569
12965
|
reason: "launch_changed",
|
|
12570
|
-
|
|
12966
|
+
outbound_message_kind: msg.type,
|
|
12571
12967
|
agentId: identity.agentId,
|
|
12572
12968
|
stale_launch_id_present: Boolean(pending.launchId),
|
|
12573
12969
|
next_launch_id_present: true
|
|
@@ -12596,7 +12992,7 @@ var DaemonConnection = class {
|
|
|
12596
12992
|
ws.send(JSON.stringify(msg));
|
|
12597
12993
|
}
|
|
12598
12994
|
this.trace("daemon.connection.outbound_replayed", {
|
|
12599
|
-
|
|
12995
|
+
outbound_message_kind: "agent:activity",
|
|
12600
12996
|
message_count: pending.length
|
|
12601
12997
|
});
|
|
12602
12998
|
}
|
|
@@ -13422,7 +13818,52 @@ var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
|
13422
13818
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
13423
13819
|
var RUNNER_CREDENTIAL_MINT_MAX_ATTEMPTS2 = 3;
|
|
13424
13820
|
var RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2 = 250;
|
|
13425
|
-
var
|
|
13821
|
+
var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
13822
|
+
"daemon.lifecycle.start": {
|
|
13823
|
+
spanAttrs: ["machine_dir_present", "local_trace_enabled"],
|
|
13824
|
+
eventAttrs: {
|
|
13825
|
+
"daemon.machine_lock.acquired": ["machine_dir_present"]
|
|
13826
|
+
}
|
|
13827
|
+
},
|
|
13828
|
+
"daemon.lifecycle.stop": {
|
|
13829
|
+
spanAttrs: ["machine_lock_present"]
|
|
13830
|
+
},
|
|
13831
|
+
"daemon.runner_credential_mint.retry": {
|
|
13832
|
+
spanAttrs: ["agentId", "runtime", "attempt", "max_attempts", "status", "code", "reason", "retryable"]
|
|
13833
|
+
},
|
|
13834
|
+
"daemon.runner_credential_mint.failed": {
|
|
13835
|
+
spanAttrs: ["agentId", "runtime", "status", "code", "reason", "retryable", "max_attempts"]
|
|
13836
|
+
},
|
|
13837
|
+
"daemon.agent.spawn.failed": {
|
|
13838
|
+
spanAttrs: ["agentId", "launchId", "runtime", "model", "failure_reason", "failure_detail", "session_id_present"]
|
|
13839
|
+
},
|
|
13840
|
+
"daemon.agent.delivery": {
|
|
13841
|
+
spanAttrs: ["agentId", "deliveryId", "delivery_correlation_id", "messageId", "message_id_present", "seq"],
|
|
13842
|
+
eventAttrs: {
|
|
13843
|
+
"daemon.receive": ["seq", "deliveryId"],
|
|
13844
|
+
"daemon.deliver_to_agent_manager": ["accepted"],
|
|
13845
|
+
"daemon.ack.sent": ["seq"]
|
|
13846
|
+
},
|
|
13847
|
+
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class"]
|
|
13848
|
+
},
|
|
13849
|
+
"daemon.runtime_profile.control.received": {
|
|
13850
|
+
spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
|
|
13851
|
+
endAttrs: ["outcome", "error_class"]
|
|
13852
|
+
},
|
|
13853
|
+
"daemon.computer_control.received": {
|
|
13854
|
+
spanAttrs: ["action", "handled"]
|
|
13855
|
+
},
|
|
13856
|
+
"daemon.ready.sent": {
|
|
13857
|
+
spanAttrs: ["runtimes_count", "running_agents_count", "idle_agents_count", "runtime_profile_reports_count"]
|
|
13858
|
+
},
|
|
13859
|
+
"daemon.runtime_profile.report.sent": {
|
|
13860
|
+
spanAttrs: ["agentId", "launchId", "runtime", "report_source", "model_present", "session_ref_present", "workspace_ref_present"]
|
|
13861
|
+
},
|
|
13862
|
+
"daemon.connection.local_disconnect_observed": {
|
|
13863
|
+
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
13864
|
+
}
|
|
13865
|
+
};
|
|
13866
|
+
var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
|
|
13426
13867
|
var RunnerCredentialMintError2 = class extends Error {
|
|
13427
13868
|
code;
|
|
13428
13869
|
retryable;
|
|
@@ -13458,9 +13899,9 @@ function runnerCredentialErrorDetail2(error) {
|
|
|
13458
13899
|
async function waitForRunnerCredentialRetry2() {
|
|
13459
13900
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
|
|
13460
13901
|
}
|
|
13461
|
-
function parseDaemonCliArgs(args) {
|
|
13902
|
+
function parseDaemonCliArgs(args, env = {}) {
|
|
13462
13903
|
let serverUrl = "";
|
|
13463
|
-
let apiKey = "";
|
|
13904
|
+
let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
|
|
13464
13905
|
for (let i = 0; i < args.length; i++) {
|
|
13465
13906
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
13466
13907
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -13629,6 +14070,8 @@ var DaemonCore = class {
|
|
|
13629
14070
|
tracer;
|
|
13630
14071
|
injectedTracer;
|
|
13631
14072
|
machineLock = null;
|
|
14073
|
+
observedServerId = null;
|
|
14074
|
+
observedMachineId = null;
|
|
13632
14075
|
localTraceSink = null;
|
|
13633
14076
|
traceBundleUploader = null;
|
|
13634
14077
|
constructor(options) {
|
|
@@ -13679,6 +14122,7 @@ var DaemonCore = class {
|
|
|
13679
14122
|
return process.env.SLOCK_DAEMON_LOCAL_TRACE !== "0";
|
|
13680
14123
|
}
|
|
13681
14124
|
resolveTraceJitter() {
|
|
14125
|
+
if (process.env.SLOCK_DAEMON_TRACE_JITTER_DISABLED === "1") return NO_JITTER;
|
|
13682
14126
|
const lockId = this.machineLock?.lockId;
|
|
13683
14127
|
return lockId ? computeTraceJitter(lockId) : NO_JITTER;
|
|
13684
14128
|
}
|
|
@@ -13710,7 +14154,7 @@ var DaemonCore = class {
|
|
|
13710
14154
|
workerUrl,
|
|
13711
14155
|
tracer: this.tracer,
|
|
13712
14156
|
currentFileProvider: () => this.localTraceSink?.getCurrentFile() ?? null,
|
|
13713
|
-
|
|
14157
|
+
jitter: this.resolveTraceJitter()
|
|
13714
14158
|
});
|
|
13715
14159
|
this.traceBundleUploader.start();
|
|
13716
14160
|
}
|
|
@@ -13789,22 +14233,29 @@ var DaemonCore = class {
|
|
|
13789
14233
|
span.end(status);
|
|
13790
14234
|
}
|
|
13791
14235
|
withDaemonTraceScope(tracer) {
|
|
13792
|
-
return
|
|
14236
|
+
return {
|
|
14237
|
+
startSpan: (name, options) => createTraceScopeTracer(tracer, this.daemonTraceScope(), {
|
|
14238
|
+
spanAttrContracts: DAEMON_CORE_TRACE_ATTR_CONTRACTS
|
|
14239
|
+
}).startSpan(name, options)
|
|
14240
|
+
};
|
|
13793
14241
|
}
|
|
13794
|
-
|
|
14242
|
+
daemonTraceScope() {
|
|
13795
14243
|
return {
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13803
|
-
} : {
|
|
13804
|
-
computer_version_present: false
|
|
14244
|
+
resource: {
|
|
14245
|
+
daemonVersion: this.daemonVersion,
|
|
14246
|
+
computerVersion: this.computerVersion
|
|
14247
|
+
},
|
|
14248
|
+
actor: {
|
|
14249
|
+
serverId: this.observedServerId,
|
|
14250
|
+
machineId: this.observedMachineId
|
|
13805
14251
|
}
|
|
13806
14252
|
};
|
|
13807
14253
|
}
|
|
14254
|
+
observeRuntimeContext(config) {
|
|
14255
|
+
const ctx = config.runtimeContext;
|
|
14256
|
+
if (ctx?.serverId) this.observedServerId = ctx.serverId;
|
|
14257
|
+
if (ctx?.machineId) this.observedMachineId = ctx.machineId;
|
|
14258
|
+
}
|
|
13808
14259
|
async requestRunnerCredentialOnce(agentId, config) {
|
|
13809
14260
|
const url = new URL(`/internal/computer/runners/${encodeURIComponent(agentId)}/credentials`, this.options.serverUrl);
|
|
13810
14261
|
const res = await daemonFetch(url, {
|
|
@@ -13896,6 +14347,7 @@ var DaemonCore = class {
|
|
|
13896
14347
|
);
|
|
13897
14348
|
}
|
|
13898
14349
|
async startAgentFromMessage(msg) {
|
|
14350
|
+
this.observeRuntimeContext(msg.config);
|
|
13899
14351
|
const agentCredential = await this.mintRunnerCredential(msg.agentId, msg.config);
|
|
13900
14352
|
const config = { ...msg.config, agentCredentialKey: agentCredential.apiKey, agentCredentialId: agentCredential.credentialId };
|
|
13901
14353
|
await this.agentManager.startAgent(
|
|
@@ -13913,6 +14365,7 @@ var DaemonCore = class {
|
|
|
13913
14365
|
logger.info(`[Daemon] Received ${msg.type}${summary ? ` ${summary}` : ""}`);
|
|
13914
14366
|
switch (msg.type) {
|
|
13915
14367
|
case "agent:start":
|
|
14368
|
+
this.observeRuntimeContext(msg.config);
|
|
13916
14369
|
logger.info(`[Agent ${msg.agentId}] Start requested (runtime=${msg.config.runtime}, model=${msg.config.model}, session=${msg.config.sessionId || "new"}${msg.wakeMessage ? ", wake=true" : ""})`);
|
|
13917
14370
|
this.startAgentFromMessage(msg).catch((err) => {
|
|
13918
14371
|
const classification = classifySpawnFailure(err);
|
|
@@ -14229,6 +14682,8 @@ var DaemonCore = class {
|
|
|
14229
14682
|
};
|
|
14230
14683
|
|
|
14231
14684
|
export {
|
|
14685
|
+
DAEMON_API_KEY_ENV,
|
|
14686
|
+
scrubDaemonAuthEnv,
|
|
14232
14687
|
subscribeDaemonLogs,
|
|
14233
14688
|
resolveWorkspaceDirectoryPath,
|
|
14234
14689
|
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,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
DAEMON_API_KEY_ENV,
|
|
2
3
|
DAEMON_CLI_USAGE,
|
|
3
4
|
DaemonCore,
|
|
4
5
|
deleteWorkspaceDirectory,
|
|
@@ -8,9 +9,11 @@ import {
|
|
|
8
9
|
resolveSlockCliPath,
|
|
9
10
|
resolveWorkspaceDirectoryPath,
|
|
10
11
|
scanWorkspaceDirectories,
|
|
12
|
+
scrubDaemonAuthEnv,
|
|
11
13
|
subscribeDaemonLogs
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JVPMCKSF.js";
|
|
13
15
|
export {
|
|
16
|
+
DAEMON_API_KEY_ENV,
|
|
14
17
|
DAEMON_CLI_USAGE,
|
|
15
18
|
DaemonCore,
|
|
16
19
|
deleteWorkspaceDirectory,
|
|
@@ -20,5 +23,6 @@ export {
|
|
|
20
23
|
resolveSlockCliPath,
|
|
21
24
|
resolveWorkspaceDirectoryPath,
|
|
22
25
|
scanWorkspaceDirectories,
|
|
26
|
+
scrubDaemonAuthEnv,
|
|
23
27
|
subscribeDaemonLogs
|
|
24
28
|
};
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DAEMON_CLI_USAGE,
|
|
4
4
|
DaemonCore,
|
|
5
|
-
parseDaemonCliArgs
|
|
6
|
-
|
|
5
|
+
parseDaemonCliArgs,
|
|
6
|
+
scrubDaemonAuthEnv
|
|
7
|
+
} from "./chunk-JVPMCKSF.js";
|
|
7
8
|
|
|
8
9
|
// src/index.ts
|
|
9
|
-
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
|
|
10
|
+
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2), process.env);
|
|
11
|
+
scrubDaemonAuthEnv(process.env);
|
|
10
12
|
if (!parsedArgs) {
|
|
11
13
|
console.error(DAEMON_CLI_USAGE);
|
|
12
14
|
process.exit(1);
|