@botiverse/raft-daemon 0.72.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-FNFNAY5B.js → chunk-FGXAADHM.js} +437 -107
- package/dist/cli/index.js +166 -13
- package/dist/core.js +1 -1
- package/dist/{dist-54TOXXOV.js → dist-YLMDSQ55.js} +160 -13
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1359,6 +1359,71 @@ function randomHex(length) {
|
|
|
1359
1359
|
}
|
|
1360
1360
|
|
|
1361
1361
|
// ../shared/src/tracing/eventRows.ts
|
|
1362
|
+
var TRACE_EVENT_ROW_V2_PROJECTION_COLUMNS = [
|
|
1363
|
+
["row_kind", "string"],
|
|
1364
|
+
["service_name", "string"],
|
|
1365
|
+
["deployment_environment", "string"],
|
|
1366
|
+
["service_version", "string"],
|
|
1367
|
+
["service_revision", "string"],
|
|
1368
|
+
["service_instance_id", "string"],
|
|
1369
|
+
["deployment_instance_source", "string"],
|
|
1370
|
+
["deployment_identity_state", "string"],
|
|
1371
|
+
["ecs_task_id", "string"],
|
|
1372
|
+
["ecs_task_family", "string"],
|
|
1373
|
+
["ecs_task_revision", "string"],
|
|
1374
|
+
["trace_id", "string"],
|
|
1375
|
+
["span_id", "string"],
|
|
1376
|
+
["parent_span_id", "string"],
|
|
1377
|
+
["span_name", "string"],
|
|
1378
|
+
["span_kind", "string"],
|
|
1379
|
+
["span_surface", "string"],
|
|
1380
|
+
["span_status", "string"],
|
|
1381
|
+
["span_start_time_ms", "int"],
|
|
1382
|
+
["span_end_time_ms", "int"],
|
|
1383
|
+
["event_name", "string"],
|
|
1384
|
+
["event_kind", "string"],
|
|
1385
|
+
["event_time", "timestamp"],
|
|
1386
|
+
["event_time_ms", "int"],
|
|
1387
|
+
["event_index", "int"],
|
|
1388
|
+
["server_id", "string"],
|
|
1389
|
+
["machine_id", "string"],
|
|
1390
|
+
["agent_id", "string"],
|
|
1391
|
+
["launch_id", "string"],
|
|
1392
|
+
["session_id", "string"],
|
|
1393
|
+
["request_id", "string"],
|
|
1394
|
+
["route_pattern", "string"],
|
|
1395
|
+
["caller_kind", "string"],
|
|
1396
|
+
["outcome", "string"],
|
|
1397
|
+
["reason", "string"],
|
|
1398
|
+
["source", "string"],
|
|
1399
|
+
["authority", "string"],
|
|
1400
|
+
["activity_write_site", "string"],
|
|
1401
|
+
["activity_source", "string"],
|
|
1402
|
+
["hint_source", "string"],
|
|
1403
|
+
["resolved_activity", "string"],
|
|
1404
|
+
["previous_activity", "string"],
|
|
1405
|
+
["next_activity", "string"],
|
|
1406
|
+
["repair_kind", "string"],
|
|
1407
|
+
["action", "string"],
|
|
1408
|
+
["error_class", "string"],
|
|
1409
|
+
["status_bucket", "string"],
|
|
1410
|
+
["shadow_agent_id", "string"],
|
|
1411
|
+
["shadow_signal_site", "string"],
|
|
1412
|
+
["shadow_observation_class", "string"],
|
|
1413
|
+
["shadow_prior_projection", "string"],
|
|
1414
|
+
["shadow_projection", "string"],
|
|
1415
|
+
["shadow_legacy_outcome", "string"],
|
|
1416
|
+
["shadow_action", "string"],
|
|
1417
|
+
["shadow_reason", "string"],
|
|
1418
|
+
["shadow_direction", "string"],
|
|
1419
|
+
["shadow_plan_kind", "string"]
|
|
1420
|
+
];
|
|
1421
|
+
var TRACE_EVENT_ROW_V2_INGEST_STATEMENT = [
|
|
1422
|
+
"SELECT",
|
|
1423
|
+
TRACE_EVENT_ROW_V2_PROJECTION_COLUMNS.map(([column, type]) => `$0["${column}"]::${type} AS ${column}`).join(", "),
|
|
1424
|
+
"INSERT INTO raft.trace_events_v2",
|
|
1425
|
+
`(${TRACE_EVENT_ROW_V2_PROJECTION_COLUMNS.map(([column]) => column).join(", ")})`
|
|
1426
|
+
].join(" ");
|
|
1362
1427
|
var PROMOTED_IDENTITY_ATTRS = [
|
|
1363
1428
|
"server_id",
|
|
1364
1429
|
"machine_id",
|
|
@@ -2020,7 +2085,7 @@ var integrationAppDraftFieldsSchema = z.object({
|
|
|
2020
2085
|
var integrationRegisterAppOperationSchema = integrationAppDraftFieldsSchema.extend({
|
|
2021
2086
|
type: z.literal("integration:register_app"),
|
|
2022
2087
|
name: z.string().trim().min(1).max(120),
|
|
2023
|
-
clientKey: z.string().trim().min(1).max(120),
|
|
2088
|
+
clientKey: z.string().trim().min(1).max(120).optional(),
|
|
2024
2089
|
returnUrl: z.string().trim().min(1).max(2e3),
|
|
2025
2090
|
scopes: z.array(z.string().trim().min(1).max(120)).max(64).default([]),
|
|
2026
2091
|
unsafeDemoUrlOverride: z.boolean().optional(),
|
|
@@ -2440,10 +2505,8 @@ var agentApiIntegrationLoginBodySchema = passthroughObject({
|
|
|
2440
2505
|
scopes: optionalStringArraySchema,
|
|
2441
2506
|
target: optionalStringSchema
|
|
2442
2507
|
});
|
|
2443
|
-
var
|
|
2444
|
-
mode: z3.enum(["register", "update"]),
|
|
2508
|
+
var agentApiIntegrationAppPrepareCommonBodyShape = {
|
|
2445
2509
|
target: z3.string().trim().min(1),
|
|
2446
|
-
clientKey: z3.string().trim().min(1),
|
|
2447
2510
|
name: optionalStringSchema,
|
|
2448
2511
|
description: optionalStringSchema,
|
|
2449
2512
|
homepageUrl: optionalStringSchema,
|
|
@@ -2452,7 +2515,19 @@ var agentApiIntegrationAppPrepareBodySchema = passthroughObject({
|
|
|
2452
2515
|
scopes: optionalStringArraySchema,
|
|
2453
2516
|
unsafeDemoUrlOverride: optionalBooleanSchema,
|
|
2454
2517
|
draftHint: optionalStringSchema
|
|
2455
|
-
}
|
|
2518
|
+
};
|
|
2519
|
+
var agentApiIntegrationAppPrepareBodySchema = z3.discriminatedUnion("mode", [
|
|
2520
|
+
passthroughObject({
|
|
2521
|
+
mode: z3.literal("register"),
|
|
2522
|
+
...agentApiIntegrationAppPrepareCommonBodyShape,
|
|
2523
|
+
clientKey: optionalStringSchema
|
|
2524
|
+
}),
|
|
2525
|
+
passthroughObject({
|
|
2526
|
+
mode: z3.literal("update"),
|
|
2527
|
+
...agentApiIntegrationAppPrepareCommonBodyShape,
|
|
2528
|
+
clientKey: z3.string().trim().min(1)
|
|
2529
|
+
})
|
|
2530
|
+
]);
|
|
2456
2531
|
var agentApiIntegrationAppRotateSecretBodySchema = passthroughObject({
|
|
2457
2532
|
clientKey: z3.string().trim().min(1)
|
|
2458
2533
|
});
|
|
@@ -4032,6 +4107,55 @@ var CANONICAL_MESSAGE_MANIFEST = Object.freeze({
|
|
|
4032
4107
|
excludedClientOnly: EXCLUDED_CLIENT_ONLY_MESSAGE_FIELDS
|
|
4033
4108
|
});
|
|
4034
4109
|
|
|
4110
|
+
// ../shared/src/canonicalMessageV2.ts
|
|
4111
|
+
var CANONICAL_MESSAGE_V2_SCHEMA_VERSION = 5;
|
|
4112
|
+
var CANONICAL_MESSAGE_V2_ENVELOPE_KIND = "normalized-message-v2";
|
|
4113
|
+
var CANONICAL_REACTION_PREVIEW_LIMIT = 3;
|
|
4114
|
+
var CANONICAL_REACTION_LIMIT = 30;
|
|
4115
|
+
var CANONICAL_MESSAGE_V2_MANIFEST = Object.freeze({
|
|
4116
|
+
schemaVersion: CANONICAL_MESSAGE_V2_SCHEMA_VERSION,
|
|
4117
|
+
envelopeKind: CANONICAL_MESSAGE_V2_ENVELOPE_KIND,
|
|
4118
|
+
legacyIngressManifestVersion: CANONICAL_MESSAGE_MANIFEST_VERSION,
|
|
4119
|
+
soleApplyEligible: true,
|
|
4120
|
+
reactions: Object.freeze({
|
|
4121
|
+
mergePolicy: "present-overwrite",
|
|
4122
|
+
maxItems: CANONICAL_REACTION_LIMIT,
|
|
4123
|
+
fields: Object.freeze(["count", "emoji", "previewK"]),
|
|
4124
|
+
previewFields: Object.freeze(["displayName", "id"]),
|
|
4125
|
+
previewLimit: CANONICAL_REACTION_PREVIEW_LIMIT,
|
|
4126
|
+
legacyCompatibilityPreviewPolicy: "empty-without-room-common-provenance",
|
|
4127
|
+
deterministicOrder: "emoji-code-unit/actor-id-code-unit"
|
|
4128
|
+
}),
|
|
4129
|
+
viewerOverlayFields: Object.freeze(["reactions.reactedByMe"]),
|
|
4130
|
+
readCacheRelations: Object.freeze(["Message.ReactionActors"]),
|
|
4131
|
+
forbiddenCanonicalPaths: Object.freeze([
|
|
4132
|
+
"reactions[].reactorIds",
|
|
4133
|
+
"reactions[].reactorNames"
|
|
4134
|
+
])
|
|
4135
|
+
});
|
|
4136
|
+
|
|
4137
|
+
// ../shared/src/discussionGraph.ts
|
|
4138
|
+
var DISCUSSION_RELATION_REGISTRY = Object.freeze({
|
|
4139
|
+
messageReactionActors: Object.freeze({
|
|
4140
|
+
rootKind: "message",
|
|
4141
|
+
relation: "reaction-actors",
|
|
4142
|
+
backing: "read-cache",
|
|
4143
|
+
consistency: "read-page",
|
|
4144
|
+
provenance: Object.freeze({ count: "shared-parent-fold", previewK: "shared-parent-fold" }),
|
|
4145
|
+
invalidation: "parent-scope-epoch",
|
|
4146
|
+
allowedCommands: Object.freeze(["set-interaction"])
|
|
4147
|
+
}),
|
|
4148
|
+
messageReplies: Object.freeze({
|
|
4149
|
+
rootKind: "message",
|
|
4150
|
+
relation: "replies",
|
|
4151
|
+
backing: "sync-scope",
|
|
4152
|
+
consistency: "sync-scope-window",
|
|
4153
|
+
provenance: Object.freeze({ replyCount: "shared-parent-fold" }),
|
|
4154
|
+
invalidation: "own-scope-rebaseline",
|
|
4155
|
+
allowedCommands: Object.freeze(["reply"])
|
|
4156
|
+
})
|
|
4157
|
+
});
|
|
4158
|
+
|
|
4035
4159
|
// ../shared/src/index.ts
|
|
4036
4160
|
var COMPUTER_CAPABILITY_SUPERVISOR_MUTATIONS = "computer:supervisor-mutations-v1";
|
|
4037
4161
|
var RUNTIME_CONFIG_VERSION = 1;
|
|
@@ -4558,7 +4682,7 @@ var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()
|
|
|
4558
4682
|
|
|
4559
4683
|
// src/agentProcessManager.ts
|
|
4560
4684
|
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync6, readdirSync as readdirSync4, statSync, writeFileSync as writeFileSync4 } from "fs";
|
|
4561
|
-
import {
|
|
4685
|
+
import { readdir as readdir2, stat as stat2, readFile, rm as rm2, lstat, realpath, open } from "fs/promises";
|
|
4562
4686
|
import { createHash as createHash3, randomUUID as randomUUID6 } from "crypto";
|
|
4563
4687
|
import path14 from "path";
|
|
4564
4688
|
import { gzipSync } from "zlib";
|
|
@@ -4566,8 +4690,9 @@ import os6 from "os";
|
|
|
4566
4690
|
|
|
4567
4691
|
// src/proxy.ts
|
|
4568
4692
|
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
4569
|
-
import { ProxyAgent } from "undici";
|
|
4693
|
+
import { Agent, ProxyAgent } from "undici";
|
|
4570
4694
|
var fetchDispatcherCache = /* @__PURE__ */ new Map();
|
|
4695
|
+
var isolatedFetchDispatcherCache = /* @__PURE__ */ new Map();
|
|
4571
4696
|
function getFetchPreResponseTimeoutMs(env) {
|
|
4572
4697
|
const parsed = Number.parseInt(env.SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS || "", 10);
|
|
4573
4698
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 3e4;
|
|
@@ -4632,32 +4757,60 @@ function resolveProxyUrl(targetUrl, env) {
|
|
|
4632
4757
|
if (shouldBypassProxy(targetUrl, env)) return void 0;
|
|
4633
4758
|
return proxyUrl;
|
|
4634
4759
|
}
|
|
4760
|
+
function createProxyDispatcher(proxyUrl, timeoutMs) {
|
|
4761
|
+
return new ProxyAgent({
|
|
4762
|
+
uri: proxyUrl,
|
|
4763
|
+
connect: { timeout: timeoutMs },
|
|
4764
|
+
requestTls: { timeout: timeoutMs },
|
|
4765
|
+
headersTimeout: timeoutMs
|
|
4766
|
+
});
|
|
4767
|
+
}
|
|
4768
|
+
function closeDispatcherBestEffort(dispatcher) {
|
|
4769
|
+
void Promise.resolve().then(() => dispatcher.close()).catch(() => dispatcher.destroy?.(new Error("evicted"))).catch(() => {
|
|
4770
|
+
});
|
|
4771
|
+
}
|
|
4635
4772
|
function buildFetchDispatcher(targetUrl, env) {
|
|
4636
4773
|
const proxyUrl = resolveProxyUrl(targetUrl, env);
|
|
4637
4774
|
if (!proxyUrl) return void 0;
|
|
4638
4775
|
const cached = fetchDispatcherCache.get(proxyUrl);
|
|
4639
4776
|
if (cached) return cached;
|
|
4640
4777
|
const timeoutMs = getFetchPreResponseTimeoutMs(env);
|
|
4641
|
-
const dispatcher =
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4778
|
+
const dispatcher = createProxyDispatcher(proxyUrl, timeoutMs);
|
|
4779
|
+
fetchDispatcherCache.set(proxyUrl, dispatcher);
|
|
4780
|
+
return dispatcher;
|
|
4781
|
+
}
|
|
4782
|
+
function getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env) {
|
|
4783
|
+
const proxyUrl = resolveProxyUrl(targetUrl, env);
|
|
4784
|
+
const routeKey = proxyUrl ? `proxy:${proxyUrl}` : `direct:${new URL(targetUrl).origin}`;
|
|
4785
|
+
return { cacheKey: `${isolationKey}\0${routeKey}`, proxyUrl };
|
|
4786
|
+
}
|
|
4787
|
+
function buildIsolatedFetchDispatcher(targetUrl, isolationKey, env) {
|
|
4788
|
+
const { cacheKey, proxyUrl } = getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env);
|
|
4789
|
+
const cached = isolatedFetchDispatcherCache.get(cacheKey);
|
|
4790
|
+
if (cached) return cached;
|
|
4791
|
+
const timeoutMs = getFetchPreResponseTimeoutMs(env);
|
|
4792
|
+
const dispatcher = proxyUrl ? createProxyDispatcher(proxyUrl, timeoutMs) : new Agent({
|
|
4646
4793
|
connect: { timeout: timeoutMs },
|
|
4647
|
-
requestTls: { timeout: timeoutMs },
|
|
4648
4794
|
headersTimeout: timeoutMs
|
|
4649
4795
|
});
|
|
4650
|
-
|
|
4796
|
+
isolatedFetchDispatcherCache.set(cacheKey, dispatcher);
|
|
4651
4797
|
return dispatcher;
|
|
4652
4798
|
}
|
|
4799
|
+
function evictIsolatedFetchDispatcher(targetUrl, isolationKey, env) {
|
|
4800
|
+
const { cacheKey } = getIsolatedDispatcherCacheKey(targetUrl, isolationKey, env);
|
|
4801
|
+
const cached = isolatedFetchDispatcherCache.get(cacheKey);
|
|
4802
|
+
if (!cached) return false;
|
|
4803
|
+
isolatedFetchDispatcherCache.delete(cacheKey);
|
|
4804
|
+
closeDispatcherBestEffort(cached);
|
|
4805
|
+
return true;
|
|
4806
|
+
}
|
|
4653
4807
|
function evictFetchDispatcher(targetUrl, env) {
|
|
4654
4808
|
const proxyUrl = resolveProxyUrl(targetUrl, env);
|
|
4655
4809
|
if (!proxyUrl) return false;
|
|
4656
4810
|
const cached = fetchDispatcherCache.get(proxyUrl);
|
|
4657
4811
|
if (!cached) return false;
|
|
4658
4812
|
fetchDispatcherCache.delete(proxyUrl);
|
|
4659
|
-
|
|
4660
|
-
});
|
|
4813
|
+
closeDispatcherBestEffort(cached);
|
|
4661
4814
|
return true;
|
|
4662
4815
|
}
|
|
4663
4816
|
|
|
@@ -4666,11 +4819,17 @@ function withDaemonFetchProxy(input, init = {}, env = process.env) {
|
|
|
4666
4819
|
const dispatcher = buildFetchDispatcher(input.toString(), env);
|
|
4667
4820
|
return dispatcher ? { ...init, dispatcher } : init;
|
|
4668
4821
|
}
|
|
4669
|
-
async function daemonFetch(input, init, env = process.env) {
|
|
4822
|
+
async function daemonFetch(input, init, env = process.env, options = {}) {
|
|
4823
|
+
const targetUrl = input.toString();
|
|
4824
|
+
const fetchInit = options.isolationKey ? { ...init, dispatcher: buildIsolatedFetchDispatcher(targetUrl, options.isolationKey, env) } : withDaemonFetchProxy(input, init, env);
|
|
4670
4825
|
try {
|
|
4671
|
-
return await fetch(input,
|
|
4826
|
+
return await fetch(input, fetchInit);
|
|
4672
4827
|
} catch (err) {
|
|
4673
|
-
|
|
4828
|
+
if (options.isolationKey) {
|
|
4829
|
+
evictIsolatedFetchDispatcher(targetUrl, options.isolationKey, env);
|
|
4830
|
+
} else {
|
|
4831
|
+
evictFetchDispatcher(targetUrl, env);
|
|
4832
|
+
}
|
|
4674
4833
|
throw err;
|
|
4675
4834
|
}
|
|
4676
4835
|
}
|
|
@@ -5051,14 +5210,14 @@ Threads are sub-conversations attached to a specific message. They let you discu
|
|
|
5051
5210
|
- **Start a new thread**: Use the \`msg=\` field from the header as the thread suffix. For example, if you see \`[target=#general msg=00000000 ...]\`, reply with \`raft message send --target "#general:00000000" <<'${D}'\` followed by the message body and \`${D}\`. The thread will be auto-created if it doesn't exist yet. Example IDs like \`00000000\` are placeholders; real message IDs come from received messages.
|
|
5052
5211
|
- When you send a message, the response includes the message ID. You can use it to start a thread on your own message.
|
|
5053
5212
|
- You can read thread history: \`raft message read --target "#general:00000000"\`
|
|
5054
|
-
-
|
|
5213
|
+
- Unfollowing a thread removes its follow record and stops its ordinary delivery while the parent channel is unmuted: \`raft thread unfollow --target "#general:00000000"\`. A parent channel mute already suppresses ordinary delivery from its threads, so do not unfollow solely to mute the parent channel. Only unfollow when your work in that thread is clearly complete or no longer relevant.
|
|
5055
5214
|
- Threads cannot be nested \u2014 you cannot start a thread inside a thread.`;
|
|
5056
5215
|
}
|
|
5057
5216
|
function buildDiscoverySection() {
|
|
5058
5217
|
return `### Discovering people and channels
|
|
5059
5218
|
|
|
5060
5219
|
Call \`raft server info\` to see all channels in this server, which ones you have joined, other agents, and humans.
|
|
5061
|
-
Visible public channels may appear even when \`joined=false\`. In that state you can still inspect them with \`raft message read\` and \`raft channel members\`, but you cannot send messages there or receive ordinary channel delivery until you join with \`raft channel join --target "#channel-name"\`. Private channels require a human with access to add you. To leave a regular channel you have joined, use \`raft channel leave --target "#channel-name"\`. To mute ordinary Activity delivery
|
|
5220
|
+
Visible public channels may appear even when \`joined=false\`. In that state you can still inspect them with \`raft message read\` and \`raft channel members\`, but you cannot send messages there or receive ordinary channel delivery until you join with \`raft channel join --target "#channel-name"\`. Private channels require a human with access to add you. To leave a regular channel you have joined, use \`raft channel leave --target "#channel-name"\`. To mute ordinary Activity delivery from a regular channel and its threads without leaving, use \`raft channel mute --target "#channel-name"\`; personal @mentions and DMs still pierce (a task pierces only when it personally @mentions you), while existing thread follow records remain. To reverse that setting, use \`raft channel unmute --target "#channel-name"\`. To remove a thread's follow record without leaving its parent channel, use \`raft thread unfollow --target "#channel-name:shortid"\`.
|
|
5062
5221
|
Private channels are membership-gated. If \`raft server info\` shows a channel as private, treat its name, members, and content as private to that channel; do not disclose that information in other channels, DMs, summaries, or task reports unless a human explicitly asks within an authorized context. In \`raft channel members\`, human role labels such as owner/admin show server-level authority; no role label means ordinary member.`;
|
|
5063
5222
|
}
|
|
5064
5223
|
function buildChannelAwarenessSection() {
|
|
@@ -6499,6 +6658,7 @@ var HOP_BY_HOP_REQUEST_HEADERS = /* @__PURE__ */ new Set([
|
|
|
6499
6658
|
var LOCAL_HELD_CONTEXT_LIMIT = 3;
|
|
6500
6659
|
var AGENT_CREDENTIAL_PROXY_HOST = "127.0.0.1";
|
|
6501
6660
|
var AGENT_CREDENTIAL_PROXY_BIND_MAX_ATTEMPTS = 3;
|
|
6661
|
+
var AGENT_CREDENTIAL_PROXY_FETCH_ISOLATION_KEY = "agent-credential-proxy";
|
|
6502
6662
|
function createProxyRequestHandler() {
|
|
6503
6663
|
return (req, res) => {
|
|
6504
6664
|
void handleProxyRequest(req, res);
|
|
@@ -6592,6 +6752,32 @@ async function handleProxyRequest(req, res) {
|
|
|
6592
6752
|
const method = req.method ?? "GET";
|
|
6593
6753
|
const correlationId = randomBytes(8).toString("hex");
|
|
6594
6754
|
let target;
|
|
6755
|
+
const inboundTraceparent = firstRequestHeader(req.headers.traceparent);
|
|
6756
|
+
const parent = parseTraceparent(inboundTraceparent);
|
|
6757
|
+
const traceContextState = parent ? "continued" : inboundTraceparent ? "malformed" : "new_root";
|
|
6758
|
+
let localPathname = "unknown";
|
|
6759
|
+
try {
|
|
6760
|
+
localPathname = new URL2(req.url ?? "/", "http://agent-proxy.local").pathname;
|
|
6761
|
+
} catch {
|
|
6762
|
+
}
|
|
6763
|
+
const proxySpan = registration.tracer.startSpan("daemon.agent_proxy.request", {
|
|
6764
|
+
parent,
|
|
6765
|
+
surface: "daemon",
|
|
6766
|
+
kind: "client",
|
|
6767
|
+
attrs: {
|
|
6768
|
+
route_family: routeFamilyForPath(localPathname),
|
|
6769
|
+
method: normalizedProxyMethod(method),
|
|
6770
|
+
trace_context_state: traceContextState,
|
|
6771
|
+
proxy_launch_id_present: registration.launchId !== null,
|
|
6772
|
+
correlation_id: correlationId
|
|
6773
|
+
}
|
|
6774
|
+
});
|
|
6775
|
+
let proxySpanStatus = "error";
|
|
6776
|
+
let proxySpanEndAttrs = {
|
|
6777
|
+
outcome: "proxy_failure",
|
|
6778
|
+
normalized_code: "transport_failure",
|
|
6779
|
+
response_started: false
|
|
6780
|
+
};
|
|
6595
6781
|
try {
|
|
6596
6782
|
target = new URL2(req.url ?? "/", registration.serverUrl);
|
|
6597
6783
|
const headers = new Headers();
|
|
@@ -6612,6 +6798,7 @@ async function handleProxyRequest(req, res) {
|
|
|
6612
6798
|
headers.set("X-Agent-Id", registration.agentId);
|
|
6613
6799
|
headers.set("X-Slock-Client", "cli");
|
|
6614
6800
|
headers.set("X-Slock-Agent-Active-Capabilities", registration.activeCapabilities);
|
|
6801
|
+
headers.set("traceparent", formatTraceparent(proxySpan.context));
|
|
6615
6802
|
let body;
|
|
6616
6803
|
let rawBodyBuffer;
|
|
6617
6804
|
if (method !== "GET" && method !== "HEAD") {
|
|
@@ -6626,6 +6813,12 @@ async function handleProxyRequest(req, res) {
|
|
|
6626
6813
|
if (method === "GET" && target.pathname === "/internal/agent-api/inbox") {
|
|
6627
6814
|
const localInbox = localAgentApiInboxResponse(registration);
|
|
6628
6815
|
if (localInbox) {
|
|
6816
|
+
proxySpanStatus = "ok";
|
|
6817
|
+
proxySpanEndAttrs = {
|
|
6818
|
+
outcome: "local_response",
|
|
6819
|
+
local_response_kind: "inbox",
|
|
6820
|
+
http_status: localInbox.status
|
|
6821
|
+
};
|
|
6629
6822
|
res.writeHead(localInbox.status, { "content-type": "application/json" });
|
|
6630
6823
|
res.end(JSON.stringify(localInbox.body));
|
|
6631
6824
|
return;
|
|
@@ -6634,6 +6827,12 @@ async function handleProxyRequest(req, res) {
|
|
|
6634
6827
|
if (method === "GET" && target.pathname === "/internal/agent-api/events") {
|
|
6635
6828
|
const localEvents = localAgentApiEventsResponse(registration, target);
|
|
6636
6829
|
if (localEvents) {
|
|
6830
|
+
proxySpanStatus = "ok";
|
|
6831
|
+
proxySpanEndAttrs = {
|
|
6832
|
+
outcome: "local_response",
|
|
6833
|
+
local_response_kind: "events",
|
|
6834
|
+
http_status: localEvents.status
|
|
6835
|
+
};
|
|
6637
6836
|
res.writeHead(localEvents.status, { "content-type": "application/json" });
|
|
6638
6837
|
res.end(JSON.stringify(localEvents.body));
|
|
6639
6838
|
return;
|
|
@@ -6643,6 +6842,12 @@ async function handleProxyRequest(req, res) {
|
|
|
6643
6842
|
const rawBody = rawBodyBuffer?.toString("utf8") ?? "";
|
|
6644
6843
|
const prepared = await prepareAgentApiSideEffectForward(registration, headers, rawBody, sideEffectAction);
|
|
6645
6844
|
if (prepared.localResponse) {
|
|
6845
|
+
proxySpanStatus = "ok";
|
|
6846
|
+
proxySpanEndAttrs = {
|
|
6847
|
+
outcome: "local_response",
|
|
6848
|
+
local_response_kind: "freshness_hold",
|
|
6849
|
+
http_status: 200
|
|
6850
|
+
};
|
|
6646
6851
|
const responseText = JSON.stringify(prepared.localResponse);
|
|
6647
6852
|
res.writeHead(200, { "content-type": "application/json" });
|
|
6648
6853
|
res.end(responseText);
|
|
@@ -6653,17 +6858,35 @@ async function handleProxyRequest(req, res) {
|
|
|
6653
6858
|
headers.set("content-type", "application/json");
|
|
6654
6859
|
headers.delete("content-length");
|
|
6655
6860
|
}
|
|
6656
|
-
const upstream = await daemonFetch(
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6861
|
+
const upstream = await daemonFetch(
|
|
6862
|
+
target,
|
|
6863
|
+
{
|
|
6864
|
+
method,
|
|
6865
|
+
headers,
|
|
6866
|
+
body
|
|
6867
|
+
},
|
|
6868
|
+
process.env,
|
|
6869
|
+
{ isolationKey: AGENT_CREDENTIAL_PROXY_FETCH_ISOLATION_KEY }
|
|
6870
|
+
);
|
|
6661
6871
|
if (upstream.status >= 500) {
|
|
6662
6872
|
const transportError = transportNormalizedErrorForHttpStatus(target, upstream.status, registration.launchId);
|
|
6873
|
+
proxySpanStatus = "error";
|
|
6874
|
+
proxySpanEndAttrs = {
|
|
6875
|
+
outcome: "upstream_5xx",
|
|
6876
|
+
http_status: upstream.status,
|
|
6877
|
+
normalized_code: transportError.normalizedCode,
|
|
6878
|
+
response_started: transportError.responseStarted
|
|
6879
|
+
};
|
|
6663
6880
|
logger.warn(
|
|
6664
6881
|
`[Agent Credential Proxy] upstream returned HTTP ${upstream.status} (agent=${registration.agentId}, launch=${registration.launchId ?? "none"}, correlation=${correlationId}, method=${method}, path=${target.pathname}, route_family=${transportError.routeFamily}, target_host_class=${transportError.targetHostClass})`
|
|
6665
6882
|
);
|
|
6666
6883
|
registration.inboxCoordinator?.recordTransportNormalizedError?.(transportError);
|
|
6884
|
+
} else {
|
|
6885
|
+
proxySpanStatus = "ok";
|
|
6886
|
+
proxySpanEndAttrs = {
|
|
6887
|
+
outcome: "upstream_response",
|
|
6888
|
+
http_status: upstream.status
|
|
6889
|
+
};
|
|
6667
6890
|
}
|
|
6668
6891
|
if (shouldBufferJsonResponse(upstream, target.pathname, registration)) {
|
|
6669
6892
|
const responseText = await upstream.text();
|
|
@@ -6695,8 +6918,28 @@ async function handleProxyRequest(req, res) {
|
|
|
6695
6918
|
);
|
|
6696
6919
|
registration.inboxCoordinator?.recordProxyFailure?.(failure);
|
|
6697
6920
|
registration.inboxCoordinator?.recordTransportNormalizedError?.(transportError);
|
|
6921
|
+
proxySpanStatus = "error";
|
|
6922
|
+
proxySpanEndAttrs = {
|
|
6923
|
+
outcome: "proxy_failure",
|
|
6924
|
+
normalized_code: transportError.normalizedCode,
|
|
6925
|
+
response_started: transportError.responseStarted,
|
|
6926
|
+
...transportError.upstreamStatus === void 0 ? {} : { http_status: transportError.upstreamStatus }
|
|
6927
|
+
};
|
|
6698
6928
|
writeProxyFailureResponse(res, failure);
|
|
6929
|
+
} finally {
|
|
6930
|
+
proxySpan.end(proxySpanStatus, { attrs: proxySpanEndAttrs });
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
function firstRequestHeader(value) {
|
|
6934
|
+
if (typeof value === "string") return value;
|
|
6935
|
+
return value?.[0];
|
|
6936
|
+
}
|
|
6937
|
+
function normalizedProxyMethod(method) {
|
|
6938
|
+
const normalized = method.toUpperCase();
|
|
6939
|
+
if (normalized === "GET" || normalized === "POST" || normalized === "PUT" || normalized === "PATCH" || normalized === "DELETE" || normalized === "HEAD" || normalized === "OPTIONS") {
|
|
6940
|
+
return normalized;
|
|
6699
6941
|
}
|
|
6942
|
+
return "OTHER";
|
|
6700
6943
|
}
|
|
6701
6944
|
function writeProxyFailureResponse(res, failure) {
|
|
6702
6945
|
if (res.writableEnded) return;
|
|
@@ -6997,7 +7240,12 @@ async function loadRecentTargetMessages(registration, headers, target) {
|
|
|
6997
7240
|
const historyHeaders = new Headers(headers);
|
|
6998
7241
|
historyHeaders.delete("content-length");
|
|
6999
7242
|
historyHeaders.delete("content-type");
|
|
7000
|
-
const res = await
|
|
7243
|
+
const res = await daemonFetch(
|
|
7244
|
+
historyUrl,
|
|
7245
|
+
{ method: "GET", headers: historyHeaders },
|
|
7246
|
+
process.env,
|
|
7247
|
+
{ isolationKey: AGENT_CREDENTIAL_PROXY_FETCH_ISOLATION_KEY }
|
|
7248
|
+
);
|
|
7001
7249
|
if (!res.ok) return [];
|
|
7002
7250
|
const parsed = await res.json().catch(() => null);
|
|
7003
7251
|
return Array.isArray(parsed?.messages) ? normalizeInboxVisibleMessages(parsed.messages, target) : [];
|
|
@@ -7113,7 +7361,8 @@ async function registerAgentCredentialProxy(input) {
|
|
|
7113
7361
|
agentId: input.agentId,
|
|
7114
7362
|
launchId: input.launchId ?? null,
|
|
7115
7363
|
activeCapabilities: input.activeCapabilities,
|
|
7116
|
-
inboxCoordinator: input.inboxCoordinator
|
|
7364
|
+
inboxCoordinator: input.inboxCoordinator,
|
|
7365
|
+
tracer: input.tracer ?? noopTracer
|
|
7117
7366
|
});
|
|
7118
7367
|
return {
|
|
7119
7368
|
proxyUrl: server.proxyUrl,
|
|
@@ -7372,7 +7621,8 @@ async function prepareCliTransport(ctx, extraEnv = {}, platform = process.platfo
|
|
|
7372
7621
|
serverUrl: ctx.config.serverUrl,
|
|
7373
7622
|
apiKey: agentCredentialKey,
|
|
7374
7623
|
activeCapabilities: DEFAULT_ACTIVE_CAPABILITIES,
|
|
7375
|
-
inboxCoordinator: ctx.agentCredentialProxyInboxCoordinator
|
|
7624
|
+
inboxCoordinator: ctx.agentCredentialProxyInboxCoordinator,
|
|
7625
|
+
tracer: ctx.tracer
|
|
7376
7626
|
});
|
|
7377
7627
|
const launchPart = buildCliTransportLaunchPart(ctx.launchId);
|
|
7378
7628
|
const proxyTokenDir = path2.join(slockHome, "agent-proxy-tokens", safePathPart(ctx.agentId));
|
|
@@ -11731,7 +11981,11 @@ function buildBuiltInAgentDir(workingDirectory) {
|
|
|
11731
11981
|
async function buildPiSpawnEnv(ctx) {
|
|
11732
11982
|
return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
11733
11983
|
}
|
|
11734
|
-
function
|
|
11984
|
+
function seedPiSessionAuthStorage(authStorage, runtimeConfig) {
|
|
11985
|
+
if (runtimeConfig.runtime === "pi" && runtimeConfig.provider?.kind === "pi-builtin") {
|
|
11986
|
+
authStorage.setRuntimeApiKey(runtimeConfig.provider.providerId, runtimeConfig.provider.apiKey);
|
|
11987
|
+
return;
|
|
11988
|
+
}
|
|
11735
11989
|
if (runtimeConfig.runtime !== "builtin") return;
|
|
11736
11990
|
if (runtimeConfig.provider.kind === "preset") {
|
|
11737
11991
|
authStorage.setRuntimeApiKey(runtimeConfig.provider.providerId, runtimeConfig.provider.apiKey);
|
|
@@ -11744,11 +11998,12 @@ function seedBuiltInAuthStorage(authStorage, runtimeConfig) {
|
|
|
11744
11998
|
}
|
|
11745
11999
|
}
|
|
11746
12000
|
function buildPiSessionCreateEnvPatch(runtimeConfig, envVars) {
|
|
11747
|
-
if (
|
|
11748
|
-
const providerApiKeyEnvNames = /* @__PURE__ */ new Set([
|
|
12001
|
+
if (!envVars) return null;
|
|
12002
|
+
const providerApiKeyEnvNames = runtimeConfig.runtime === "builtin" ? /* @__PURE__ */ new Set([
|
|
11749
12003
|
...Object.values(BUILTIN_RUNTIME_PROVIDER_ENV_KEYS),
|
|
11750
12004
|
...Object.values(BUILTIN_RUNTIME_GATEWAY_PROVIDER_ENV_KEYS)
|
|
11751
|
-
]);
|
|
12005
|
+
]) : runtimeConfig.runtime === "pi" && runtimeConfig.provider?.kind === "pi-builtin" ? /* @__PURE__ */ new Set([PI_BUILTIN_PROVIDER_ENV_KEYS[runtimeConfig.provider.providerId]]) : /* @__PURE__ */ new Set();
|
|
12006
|
+
if (providerApiKeyEnvNames.size === 0) return envVars;
|
|
11752
12007
|
const filtered = Object.fromEntries(
|
|
11753
12008
|
Object.entries(envVars).filter(([key]) => !providerApiKeyEnvNames.has(key))
|
|
11754
12009
|
);
|
|
@@ -12106,7 +12361,7 @@ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
|
|
|
12106
12361
|
const agentDir = opts.agentDir ?? spawnEnv.PI_CODING_AGENT_DIR ?? getAgentDir();
|
|
12107
12362
|
mkdirSync3(agentDir, { recursive: true });
|
|
12108
12363
|
const authStorage = AuthStorage.create(path12.join(agentDir, "auth.json"));
|
|
12109
|
-
|
|
12364
|
+
seedPiSessionAuthStorage(authStorage, runtimeConfig);
|
|
12110
12365
|
const settingsManager = SettingsManager.create(ctx.workingDirectory, agentDir);
|
|
12111
12366
|
const providerEnvScope = opts.isolateHostProviderEnv ? BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS : void 0;
|
|
12112
12367
|
const sessionCreateEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
|
|
@@ -12229,22 +12484,17 @@ async function createPiAgentSessionForContext(ctx, sessionId, opts = {}) {
|
|
|
12229
12484
|
throw error;
|
|
12230
12485
|
}
|
|
12231
12486
|
}
|
|
12487
|
+
var piPromptsInFlight = 0;
|
|
12232
12488
|
var PiSdkRuntimeSession = class {
|
|
12233
|
-
constructor(ctx, setCurrentSessionId, sessionFactory = createPiAgentSessionForContext
|
|
12489
|
+
constructor(ctx, setCurrentSessionId, sessionFactory = createPiAgentSessionForContext) {
|
|
12234
12490
|
this.ctx = ctx;
|
|
12235
12491
|
this.setCurrentSessionId = setCurrentSessionId;
|
|
12236
12492
|
this.sessionFactory = sessionFactory;
|
|
12237
12493
|
this.mappingState = createPiSdkEventMappingState(ctx.config.sessionId || null);
|
|
12238
|
-
const runtimeConfig = hydrateRuntimeConfig(ctx.config);
|
|
12239
|
-
const launchRuntimeFields = runtimeConfigToLaunchFields(runtimeConfig);
|
|
12240
|
-
this.sdkCallEnvPatch = buildPiSessionCreateEnvPatch(runtimeConfig, launchRuntimeFields.envVars);
|
|
12241
|
-
this.sdkCallEnvRemoveFirst = opts.isolateHostProviderEnv ? BUILTIN_BLOCKED_HOST_PROVIDER_ENV_KEYS : void 0;
|
|
12242
12494
|
}
|
|
12243
12495
|
descriptor = PI_RUNTIME_SESSION_DESCRIPTOR;
|
|
12244
12496
|
events = new EventEmitter2();
|
|
12245
12497
|
mappingState;
|
|
12246
|
-
sdkCallEnvPatch;
|
|
12247
|
-
sdkCallEnvRemoveFirst;
|
|
12248
12498
|
session = null;
|
|
12249
12499
|
unsubscribe = null;
|
|
12250
12500
|
started = false;
|
|
@@ -12377,10 +12627,41 @@ var PiSdkRuntimeSession = class {
|
|
|
12377
12627
|
return !this.didClose && this.session === session && !session.isStreaming;
|
|
12378
12628
|
}
|
|
12379
12629
|
deferSdkCall(invoke) {
|
|
12630
|
+
const queuedAt = currentTimeMs();
|
|
12380
12631
|
setImmediate(() => {
|
|
12381
12632
|
if (this.didClose) return;
|
|
12633
|
+
const span = this.ctx.tracer?.startSpan("daemon.pi.prompt", {
|
|
12634
|
+
surface: "daemon",
|
|
12635
|
+
kind: "internal",
|
|
12636
|
+
attrs: {
|
|
12637
|
+
agentId: this.ctx.agentId,
|
|
12638
|
+
launchId: this.ctx.launchId || void 0,
|
|
12639
|
+
runtime: this.ctx.config.runtime
|
|
12640
|
+
}
|
|
12641
|
+
});
|
|
12642
|
+
const startedAt = currentTimeMs();
|
|
12643
|
+
piPromptsInFlight += 1;
|
|
12644
|
+
span?.addEvent("daemon.pi.prompt.start", {
|
|
12645
|
+
agentId: this.ctx.agentId,
|
|
12646
|
+
queued_ms: startedAt - queuedAt,
|
|
12647
|
+
prompts_in_flight: piPromptsInFlight
|
|
12648
|
+
});
|
|
12649
|
+
let settled = false;
|
|
12650
|
+
const settle = (status) => {
|
|
12651
|
+
if (settled) return;
|
|
12652
|
+
settled = true;
|
|
12653
|
+
piPromptsInFlight -= 1;
|
|
12654
|
+
span?.end(status, {
|
|
12655
|
+
attrs: {
|
|
12656
|
+
queued_ms: startedAt - queuedAt,
|
|
12657
|
+
duration_ms: currentTimeMs() - startedAt,
|
|
12658
|
+
prompts_in_flight_after: piPromptsInFlight
|
|
12659
|
+
}
|
|
12660
|
+
});
|
|
12661
|
+
};
|
|
12382
12662
|
try {
|
|
12383
|
-
void
|
|
12663
|
+
void invoke().then(() => settle("ok")).catch((error) => {
|
|
12664
|
+
settle("error");
|
|
12384
12665
|
if (this.didClose) return;
|
|
12385
12666
|
this.events.emit("runtime_event", {
|
|
12386
12667
|
kind: "error",
|
|
@@ -12388,6 +12669,7 @@ var PiSdkRuntimeSession = class {
|
|
|
12388
12669
|
});
|
|
12389
12670
|
});
|
|
12390
12671
|
} catch (error) {
|
|
12672
|
+
settle("error");
|
|
12391
12673
|
if (this.didClose) return;
|
|
12392
12674
|
this.events.emit("runtime_event", {
|
|
12393
12675
|
kind: "error",
|
|
@@ -12513,7 +12795,7 @@ var BuiltInDriver = class extends PiDriver {
|
|
|
12513
12795
|
exposeLaunchTraceEvidence: true,
|
|
12514
12796
|
exposeLaunchEnvToTools: false,
|
|
12515
12797
|
isolateHostProviderEnv: true
|
|
12516
|
-
})
|
|
12798
|
+
}));
|
|
12517
12799
|
}
|
|
12518
12800
|
buildSystemPrompt(config, _agentId) {
|
|
12519
12801
|
return buildCliTransportSystemPrompt(config, {
|
|
@@ -12778,8 +13060,27 @@ async function reapOrphanProcesses(pids, logger2, recordTrace) {
|
|
|
12778
13060
|
}
|
|
12779
13061
|
|
|
12780
13062
|
// src/workspaces.ts
|
|
12781
|
-
import { readdir, rm, stat } from "fs/promises";
|
|
13063
|
+
import { access, mkdir, readdir, rm, stat, writeFile } from "fs/promises";
|
|
12782
13064
|
import path13 from "path";
|
|
13065
|
+
async function initializeAgentWorkspace(workspacePath, initialMemoryMd, seedFiles) {
|
|
13066
|
+
await mkdir(workspacePath, { recursive: true });
|
|
13067
|
+
const memoryMdPath = path13.join(workspacePath, "MEMORY.md");
|
|
13068
|
+
try {
|
|
13069
|
+
await access(memoryMdPath);
|
|
13070
|
+
} catch {
|
|
13071
|
+
await writeFile(memoryMdPath, initialMemoryMd);
|
|
13072
|
+
}
|
|
13073
|
+
await mkdir(path13.join(workspacePath, "notes"), { recursive: true });
|
|
13074
|
+
for (const { relativePath, content } of seedFiles) {
|
|
13075
|
+
const fullPath = path13.join(workspacePath, relativePath);
|
|
13076
|
+
try {
|
|
13077
|
+
await access(fullPath);
|
|
13078
|
+
} catch {
|
|
13079
|
+
await mkdir(path13.dirname(fullPath), { recursive: true });
|
|
13080
|
+
await writeFile(fullPath, content);
|
|
13081
|
+
}
|
|
13082
|
+
}
|
|
13083
|
+
}
|
|
12783
13084
|
function isValidWorkspaceDirectoryName(directoryName) {
|
|
12784
13085
|
return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
|
|
12785
13086
|
}
|
|
@@ -17395,29 +17696,12 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
17395
17696
|
const originalLaunchId = launchId || null;
|
|
17396
17697
|
try {
|
|
17397
17698
|
const agentDataDir = path14.join(this.dataDir, agentId);
|
|
17398
|
-
await mkdir(agentDataDir, { recursive: true });
|
|
17399
17699
|
const initialRuntimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
|
|
17400
|
-
|
|
17401
|
-
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17405
|
-
await writeFile(memoryMdPath, initialMemoryMd);
|
|
17406
|
-
}
|
|
17407
|
-
const notesDir = path14.join(agentDataDir, "notes");
|
|
17408
|
-
await mkdir(notesDir, { recursive: true });
|
|
17409
|
-
if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
|
|
17410
|
-
const seedFiles = buildOnboardingSeedFiles();
|
|
17411
|
-
for (const { relativePath, content } of seedFiles) {
|
|
17412
|
-
const fullPath = path14.join(agentDataDir, relativePath);
|
|
17413
|
-
try {
|
|
17414
|
-
await access(fullPath);
|
|
17415
|
-
} catch {
|
|
17416
|
-
await mkdir(path14.dirname(fullPath), { recursive: true });
|
|
17417
|
-
await writeFile(fullPath, content);
|
|
17418
|
-
}
|
|
17419
|
-
}
|
|
17420
|
-
}
|
|
17700
|
+
await initializeAgentWorkspace(
|
|
17701
|
+
agentDataDir,
|
|
17702
|
+
buildInitialMemoryMd(initialRuntimeConfig),
|
|
17703
|
+
getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE ? buildOnboardingSeedFiles() : []
|
|
17704
|
+
);
|
|
17421
17705
|
pendingStartRebind = this.lifecycleRecords.getPendingStartRebind(agentId);
|
|
17422
17706
|
if (pendingStartRebind) {
|
|
17423
17707
|
this.lifecycleRecords.deletePendingStartRebind(agentId);
|
|
@@ -18189,36 +18473,26 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18189
18473
|
async buildSpawnConfig(agentId, config) {
|
|
18190
18474
|
const baseConfig = config.serverUrl === this.serverUrl ? config : { ...config, serverUrl: this.serverUrl };
|
|
18191
18475
|
const runnerConfig = await this.ensureManagedRunnerCredential(agentId, baseConfig);
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
return runnerConfig;
|
|
18476
|
+
let effectiveConfig = runnerConfig;
|
|
18477
|
+
if (this.defaultAgentEnvVarsProvider) {
|
|
18478
|
+
try {
|
|
18479
|
+
const defaultEnvVars = await this.defaultAgentEnvVarsProvider({
|
|
18480
|
+
runtime: runnerConfig.runtime,
|
|
18481
|
+
model: runnerConfig.model,
|
|
18482
|
+
envVars: runnerConfig.envVars
|
|
18483
|
+
});
|
|
18484
|
+
const mergedEnvVars = { ...defaultEnvVars ?? {}, ...runnerConfig.envVars ?? {} };
|
|
18485
|
+
if (!this.sameEnvVars(mergedEnvVars, runnerConfig.envVars)) {
|
|
18486
|
+
effectiveConfig = { ...runnerConfig, envVars: mergedEnvVars };
|
|
18487
|
+
}
|
|
18488
|
+
} catch (error) {
|
|
18489
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
18490
|
+
logger.warn(
|
|
18491
|
+
`[Agent ${agentId}] Failed to resolve default runtime env vars \u2014 continuing without machine-level defaults (${reason})`
|
|
18492
|
+
);
|
|
18210
18493
|
}
|
|
18211
|
-
return {
|
|
18212
|
-
...runnerConfig,
|
|
18213
|
-
envVars: mergedEnvVars
|
|
18214
|
-
};
|
|
18215
|
-
} catch (error) {
|
|
18216
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
18217
|
-
logger.warn(
|
|
18218
|
-
`[Agent ${agentId}] Failed to resolve default runtime env vars \u2014 continuing without machine-level defaults (${reason})`
|
|
18219
|
-
);
|
|
18220
|
-
return runnerConfig;
|
|
18221
18494
|
}
|
|
18495
|
+
return effectiveConfig;
|
|
18222
18496
|
}
|
|
18223
18497
|
async requestManagedRunnerCredentialOnce(agentId, config) {
|
|
18224
18498
|
const url = new URL(`/internal/computer/runners/${encodeURIComponent(agentId)}/credentials`, this.serverUrl);
|
|
@@ -21788,6 +22062,10 @@ var systemClock = {
|
|
|
21788
22062
|
clearTimeout: (timer) => clearTimeout(timer)
|
|
21789
22063
|
};
|
|
21790
22064
|
var INBOUND_WATCHDOG_MS = 7e4;
|
|
22065
|
+
var LEGACY_MACHINE_KEY_MIGRATED_REASON = "legacy_machine_key_migrated";
|
|
22066
|
+
function isTerminalMigratedKeyRejection(statusCode, reason) {
|
|
22067
|
+
return statusCode === 401 && reason === LEGACY_MACHINE_KEY_MIGRATED_REASON;
|
|
22068
|
+
}
|
|
21791
22069
|
function normalizeHandshakeReason(value) {
|
|
21792
22070
|
const raw = Array.isArray(value) ? value[0] : value;
|
|
21793
22071
|
if (typeof raw !== "string") return null;
|
|
@@ -21964,6 +22242,17 @@ var DaemonConnection = class {
|
|
|
21964
22242
|
slock_reason_present: Boolean(reason),
|
|
21965
22243
|
slock_reason: reason
|
|
21966
22244
|
}, "error");
|
|
22245
|
+
if (isTerminalMigratedKeyRejection(statusCode, reason)) {
|
|
22246
|
+
this.shouldConnect = false;
|
|
22247
|
+
logger.error(
|
|
22248
|
+
'[Daemon] This legacy machine key was already migrated to Raft Computer. Reconnects are stopped because this key cannot authenticate again.\nStop and disable this legacy raft-daemon process. In Raft, open this offline Computer and choose "raft-computer: command not found? Install or re-run setup" to copy the install and setup commands for this server.'
|
|
22249
|
+
);
|
|
22250
|
+
this.trace("daemon.connection.reconnect_stopped", {
|
|
22251
|
+
status_code: statusCode,
|
|
22252
|
+
slock_reason: reason,
|
|
22253
|
+
terminal: true
|
|
22254
|
+
}, "error");
|
|
22255
|
+
}
|
|
21967
22256
|
this.options.onHandshakeRejected?.({ statusCode, reason });
|
|
21968
22257
|
response.resume();
|
|
21969
22258
|
try {
|
|
@@ -24556,6 +24845,22 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
24556
24845
|
},
|
|
24557
24846
|
endAttrs: ["outcome", "ackSeq", "deliveryId", "error_class", "pending_count"]
|
|
24558
24847
|
},
|
|
24848
|
+
"daemon.agent_proxy.request": {
|
|
24849
|
+
spanAttrs: [
|
|
24850
|
+
"route_family",
|
|
24851
|
+
"method",
|
|
24852
|
+
"trace_context_state",
|
|
24853
|
+
"proxy_launch_id_present",
|
|
24854
|
+
"correlation_id"
|
|
24855
|
+
],
|
|
24856
|
+
endAttrs: [
|
|
24857
|
+
"outcome",
|
|
24858
|
+
"local_response_kind",
|
|
24859
|
+
"http_status",
|
|
24860
|
+
"normalized_code",
|
|
24861
|
+
"response_started"
|
|
24862
|
+
]
|
|
24863
|
+
},
|
|
24559
24864
|
"daemon.runtime_profile.control.received": {
|
|
24560
24865
|
spanAttrs: ["agentId", "control_kind", "key_present", "launchId"],
|
|
24561
24866
|
endAttrs: ["outcome", "error_class"]
|
|
@@ -24580,6 +24885,17 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
24580
24885
|
},
|
|
24581
24886
|
endAttrs: ["outcome", "models_count", "default_model_present", "verified_as", "error_class"]
|
|
24582
24887
|
},
|
|
24888
|
+
// task #510: per-prompt span. `prompts_in_flight` is the cross-agent concurrency
|
|
24889
|
+
// observable — under the old process-env-patch lock it could never exceed 1
|
|
24890
|
+
// (every Pi prompt serialized process-wide); > 1 proves the queue is gone.
|
|
24891
|
+
// `queued_ms` is the queued -> prompt-start wait that users experienced as the
|
|
24892
|
+
// 60-165s stall.
|
|
24893
|
+
"daemon.pi.prompt": {
|
|
24894
|
+
spanAttrs: ["agentId", "launchId", "runtime", "queued_ms", "duration_ms", "prompts_in_flight_after"],
|
|
24895
|
+
eventAttrs: {
|
|
24896
|
+
"daemon.pi.prompt.start": ["agentId", "queued_ms", "prompts_in_flight"]
|
|
24897
|
+
}
|
|
24898
|
+
},
|
|
24583
24899
|
"daemon.pi.session.create": {
|
|
24584
24900
|
spanAttrs: ["agentId", "launchId", "runtime", "model", "session_id_present", "requested_model"],
|
|
24585
24901
|
eventAttrs: {
|
|
@@ -24780,7 +25096,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
24780
25096
|
}
|
|
24781
25097
|
async function runBundledSlockCli(argv) {
|
|
24782
25098
|
process.argv = [process.execPath, "slock", ...argv];
|
|
24783
|
-
await import("./dist-
|
|
25099
|
+
await import("./dist-YLMDSQ55.js");
|
|
24784
25100
|
}
|
|
24785
25101
|
function detectRuntimes(tracer = noopTracer) {
|
|
24786
25102
|
const ids = [];
|
|
@@ -26149,9 +26465,9 @@ var DaemonCore = class {
|
|
|
26149
26465
|
});
|
|
26150
26466
|
}
|
|
26151
26467
|
emitReadyIfConnected() {
|
|
26152
|
-
if (this.connection.connected) this.emitReady();
|
|
26468
|
+
if (this.connection.connected) void this.emitReady();
|
|
26153
26469
|
}
|
|
26154
|
-
emitReady() {
|
|
26470
|
+
async emitReady() {
|
|
26155
26471
|
const { ids: runtimes, versions: runtimeVersions, diagnostics: runtimeDiagnostics = {} } = this.runtimeDetector();
|
|
26156
26472
|
const runtimeInfo = runtimes.map((id) => runtimeVersions[id] ? `${id} (${runtimeVersions[id]})` : id);
|
|
26157
26473
|
logger.info(`[Daemon] Detected runtimes: ${runtimeInfo.join(", ") || "none"}`);
|
|
@@ -26161,6 +26477,15 @@ var DaemonCore = class {
|
|
|
26161
26477
|
const runningAgentIds = this.agentManager.getRunningAgentIds();
|
|
26162
26478
|
const idleAgentSessions = this.agentManager.getIdleAgentSessionIds();
|
|
26163
26479
|
const runtimeProfileReports = this.agentManager.getAgentRuntimeProfileReports();
|
|
26480
|
+
let lifecycleAcks = this.options.getComputerLifecycleAcks?.() ?? [];
|
|
26481
|
+
if (this.options.getComputerLifecycleReadyAcks) {
|
|
26482
|
+
try {
|
|
26483
|
+
lifecycleAcks = await this.options.getComputerLifecycleReadyAcks();
|
|
26484
|
+
} catch (error) {
|
|
26485
|
+
logger.warn(`[Daemon] Computer lifecycle attestation skipped: ${error instanceof Error ? error.message : String(error)}`);
|
|
26486
|
+
lifecycleAcks = [];
|
|
26487
|
+
}
|
|
26488
|
+
}
|
|
26164
26489
|
this.connection.send({
|
|
26165
26490
|
type: "ready",
|
|
26166
26491
|
capabilities: [
|
|
@@ -26177,7 +26502,7 @@ var DaemonCore = class {
|
|
|
26177
26502
|
daemonVersion: this.daemonVersion,
|
|
26178
26503
|
...this.computerVersion ? { computerVersion: this.computerVersion } : {},
|
|
26179
26504
|
migrationTransport: this.getMigrationTransportReady(),
|
|
26180
|
-
...this.options.getComputerLifecycleAcks ? { lifecycleAcks
|
|
26505
|
+
...this.options.getComputerLifecycleAcks || this.options.getComputerLifecycleReadyAcks ? { lifecycleAcks } : {}
|
|
26181
26506
|
});
|
|
26182
26507
|
this.recordDaemonTrace("daemon.ready.sent", {
|
|
26183
26508
|
runtimes_count: runtimes.length,
|
|
@@ -26198,20 +26523,25 @@ var DaemonCore = class {
|
|
|
26198
26523
|
logger.warn(`[Daemon] opencli wrapper refresh skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
26199
26524
|
}
|
|
26200
26525
|
}
|
|
26201
|
-
this.emitReady();
|
|
26526
|
+
void this.emitReady();
|
|
26202
26527
|
const runningAgentIds = this.agentManager.getRunningAgentIds();
|
|
26203
26528
|
const idleAgentSessions = this.agentManager.getIdleAgentSessionIds();
|
|
26204
26529
|
const runtimeProfileReports = this.agentManager.getAgentRuntimeProfileReports();
|
|
26205
26530
|
if (this.options.onComputerUpgradeReconcile) {
|
|
26206
26531
|
void Promise.resolve().then(
|
|
26207
|
-
() => this.options.onComputerUpgradeReconcile(
|
|
26208
|
-
|
|
26209
|
-
|
|
26210
|
-
|
|
26211
|
-
|
|
26212
|
-
|
|
26213
|
-
|
|
26214
|
-
|
|
26532
|
+
() => this.options.onComputerUpgradeReconcile(
|
|
26533
|
+
(done) => {
|
|
26534
|
+
this.connection.send({ type: "computer:upgrade:done", ...done });
|
|
26535
|
+
this.recordDaemonTrace("daemon.computer_upgrade.reconciled", {
|
|
26536
|
+
request_id: done.requestId,
|
|
26537
|
+
ok: done.ok,
|
|
26538
|
+
...done.newVersion ? { new_version: done.newVersion } : {}
|
|
26539
|
+
});
|
|
26540
|
+
},
|
|
26541
|
+
(progress) => {
|
|
26542
|
+
this.connection.send({ type: "computer:upgrade:progress", ...progress });
|
|
26543
|
+
}
|
|
26544
|
+
)
|
|
26215
26545
|
).catch((err) => {
|
|
26216
26546
|
logger.error(
|
|
26217
26547
|
`[Daemon] computer upgrade reconcile failed: ${err instanceof Error ? err.message : String(err)}`
|