@hachej/boring-agent 0.1.104 → 0.1.105
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-I7KFNGB4.js → chunk-F2OJI2LX.js} +37 -14
- package/dist/{chunk-BTYOMR7W.js → chunk-LFN45QDZ.js} +209 -134
- package/dist/{createHarness-POZ4AXCZ.js → createHarness-GMBZZPTN.js} +1 -1
- package/dist/front/index.d.ts +7 -0
- package/dist/front/index.js +17 -5
- package/dist/front/styles.css +52 -15
- package/dist/server/agent-host/testing/gatewayConformance.d.ts +1 -1
- package/dist/server/index.d.ts +43 -34
- package/dist/server/index.js +4 -2
- package/dist/server/worker/index.js +2 -2
- package/dist/{types-B1xDlBSo.d.ts → types-BTsdaAQ2.d.ts} +29 -10
- package/docs/ERROR_CODES.md +1 -1
- package/package.json +6 -6
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
readConfiguredDefaultModel,
|
|
8
8
|
registerConfiguredModelProviders,
|
|
9
9
|
withPiHarnessDefaults
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-F2OJI2LX.js";
|
|
11
11
|
import {
|
|
12
12
|
AGENT_KNOWLEDGE_FILESYSTEM_ID,
|
|
13
13
|
AgentDefinitionValidationError,
|
|
@@ -2824,7 +2824,7 @@ async function createConfiguredAgentHostAgentSpec(input) {
|
|
|
2824
2824
|
...plugin.config === void 0 ? {} : { config: frozenJson(plugin.config) }
|
|
2825
2825
|
}));
|
|
2826
2826
|
const preferredModel = nonEmpty(policy.preferredModel);
|
|
2827
|
-
const
|
|
2827
|
+
const instructionSources = policy.instructionSources?.length ? Object.freeze(policy.instructionSources.map((source) => Object.freeze({ ...source }))) : void 0;
|
|
2828
2828
|
return Object.freeze({
|
|
2829
2829
|
agentTypeId: input.source.agentTypeId,
|
|
2830
2830
|
definition: Object.freeze({
|
|
@@ -2834,24 +2834,75 @@ async function createConfiguredAgentHostAgentSpec(input) {
|
|
|
2834
2834
|
...input.source.definitionDigest === void 0 ? {} : { digest: input.source.definitionDigest }
|
|
2835
2835
|
}),
|
|
2836
2836
|
...input.source.knowledgeDir === void 0 ? {} : { knowledge: Object.freeze({ rootDir: input.source.knowledgeDir }) },
|
|
2837
|
-
...
|
|
2837
|
+
...instructionSources ? { instructionSources } : {},
|
|
2838
2838
|
...plugins?.length ? { plugins: Object.freeze(plugins) } : {},
|
|
2839
2839
|
...preferredModel ? { model: Object.freeze({ preferred: preferredModel }) } : {}
|
|
2840
2840
|
});
|
|
2841
2841
|
}
|
|
2842
2842
|
|
|
2843
2843
|
// src/server/agentDefinition/loadConfiguredAgentFleet.ts
|
|
2844
|
-
import { lstat as lstat3, readFile as readFile3, realpath as
|
|
2845
|
-
import { basename as basename2,
|
|
2844
|
+
import { lstat as lstat3, readFile as readFile3, realpath as realpath5 } from "node:fs/promises";
|
|
2845
|
+
import { basename as basename2, resolve as resolve5 } from "node:path";
|
|
2846
2846
|
import { parse as parseYaml } from "yaml";
|
|
2847
2847
|
|
|
2848
|
+
// src/server/agentDefinition/instructionFileRefs.ts
|
|
2849
|
+
import { realpath as realpath4 } from "node:fs/promises";
|
|
2850
|
+
import { isAbsolute as isAbsolute5, relative as relative6, resolve as resolve4, sep as sep5 } from "node:path";
|
|
2851
|
+
|
|
2848
2852
|
// src/server/agent-host/types.ts
|
|
2849
2853
|
var AGENT_USER_FILESYSTEM_ID = "user";
|
|
2850
2854
|
|
|
2851
|
-
// src/server/agentDefinition/
|
|
2855
|
+
// src/server/agentDefinition/instructionFileRefs.ts
|
|
2856
|
+
function isCanonicalPathInside(root, target) {
|
|
2857
|
+
const fromRoot = relative6(root, target);
|
|
2858
|
+
return fromRoot === "" || fromRoot !== ".." && !fromRoot.startsWith(`..${sep5}`) && !isAbsolute5(fromRoot);
|
|
2859
|
+
}
|
|
2852
2860
|
function isPublishableWorkspacePath(value) {
|
|
2853
2861
|
return value.length > 0 && !value.includes("\0") && !value.includes("\\") && !value.startsWith("/") && !/^[A-Za-z]:[\\/]/.test(value) && !/%(?:2e|2f|5c)/i.test(value) && !/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value) && !value.split("/").some((segment) => segment === "" || segment === "." || segment === "..");
|
|
2854
2862
|
}
|
|
2863
|
+
async function resolveAgentInstructionFileRefs(input) {
|
|
2864
|
+
const sources = input.sources ?? [];
|
|
2865
|
+
if (sources.length === 0) return Object.freeze({ refs: Object.freeze([]), withheld: Object.freeze([]) });
|
|
2866
|
+
const canonicalWorkspaceRoot = typeof input.workspaceRoot === "string" && input.workspaceRoot.trim() ? await realpath4(resolve4(input.workspaceRoot)).catch(() => null) : null;
|
|
2867
|
+
const refs = [];
|
|
2868
|
+
const withheld = [];
|
|
2869
|
+
for (const source of sources) {
|
|
2870
|
+
if (canonicalWorkspaceRoot === null) {
|
|
2871
|
+
withheld.push({
|
|
2872
|
+
code: ErrorCode.enum.AGENT_FLEET_SEAT_INSTRUCTIONS_PATH_UNPUBLISHABLE,
|
|
2873
|
+
absolutePath: source.absolutePath,
|
|
2874
|
+
message: `this request resolves no readable workspace root, so persona instructions have no "${AGENT_USER_FILESYSTEM_ID}" path to be addressed against`
|
|
2875
|
+
});
|
|
2876
|
+
continue;
|
|
2877
|
+
}
|
|
2878
|
+
const canonicalSource = await realpath4(resolve4(source.absolutePath)).catch(() => null);
|
|
2879
|
+
if (canonicalSource === null || !isCanonicalPathInside(canonicalWorkspaceRoot, canonicalSource)) {
|
|
2880
|
+
withheld.push({
|
|
2881
|
+
code: ErrorCode.enum.AGENT_FLEET_SEAT_INSTRUCTIONS_PATH_UNPUBLISHABLE,
|
|
2882
|
+
absolutePath: source.absolutePath,
|
|
2883
|
+
message: `instruction source resolves outside the workspace root that the "${AGENT_USER_FILESYSTEM_ID}" filesystem serves for this request`
|
|
2884
|
+
});
|
|
2885
|
+
continue;
|
|
2886
|
+
}
|
|
2887
|
+
const path = relative6(canonicalWorkspaceRoot, canonicalSource).split(sep5).join("/");
|
|
2888
|
+
if (!isPublishableWorkspacePath(path)) {
|
|
2889
|
+
withheld.push({
|
|
2890
|
+
code: ErrorCode.enum.AGENT_FLEET_SEAT_INSTRUCTIONS_PATH_UNPUBLISHABLE,
|
|
2891
|
+
absolutePath: source.absolutePath,
|
|
2892
|
+
message: `instruction source composes an unsafe workspace-relative path (${JSON.stringify(path)})`
|
|
2893
|
+
});
|
|
2894
|
+
continue;
|
|
2895
|
+
}
|
|
2896
|
+
refs.push(Object.freeze({
|
|
2897
|
+
filesystem: AGENT_USER_FILESYSTEM_ID,
|
|
2898
|
+
path,
|
|
2899
|
+
role: source.role
|
|
2900
|
+
}));
|
|
2901
|
+
}
|
|
2902
|
+
return Object.freeze({ refs: Object.freeze(refs), withheld: Object.freeze(withheld) });
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
// src/server/agentDefinition/loadConfiguredAgentFleet.ts
|
|
2855
2906
|
var FleetConfigError = class extends Error {
|
|
2856
2907
|
code;
|
|
2857
2908
|
field;
|
|
@@ -2862,10 +2913,6 @@ var FleetConfigError = class extends Error {
|
|
|
2862
2913
|
this.field = input.field;
|
|
2863
2914
|
}
|
|
2864
2915
|
};
|
|
2865
|
-
function isCanonicalPathInside(root, target) {
|
|
2866
|
-
const fromRoot = relative6(root, target);
|
|
2867
|
-
return fromRoot === "" || fromRoot !== ".." && !fromRoot.startsWith(`..${sep5}`) && !isAbsolute5(fromRoot);
|
|
2868
|
-
}
|
|
2869
2916
|
function isRecord(value) {
|
|
2870
2917
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2871
2918
|
}
|
|
@@ -2974,13 +3021,13 @@ function resolveSeatModel(tier, env, modelTierCandidates) {
|
|
|
2974
3021
|
return void 0;
|
|
2975
3022
|
}
|
|
2976
3023
|
async function readVerifiedSkillContent(root, reference, skill) {
|
|
2977
|
-
const rootTarget = await
|
|
2978
|
-
let candidate =
|
|
3024
|
+
const rootTarget = await realpath5(root);
|
|
3025
|
+
let candidate = resolve5(rootTarget, reference);
|
|
2979
3026
|
const candidateStat = await lstat3(candidate);
|
|
2980
|
-
if (candidateStat.isDirectory()) candidate =
|
|
3027
|
+
if (candidateStat.isDirectory()) candidate = resolve5(candidate, "SKILL.md");
|
|
2981
3028
|
const fileStat = await lstat3(candidate);
|
|
2982
3029
|
if (!fileStat.isFile() || fileStat.isSymbolicLink()) throw new Error("skill source is not a regular file");
|
|
2983
|
-
const target = await
|
|
3030
|
+
const target = await realpath5(candidate);
|
|
2984
3031
|
if (!isCanonicalPathInside(rootTarget, target)) throw new Error("skill source resolves outside its admitted root");
|
|
2985
3032
|
const content = await readFile3(target, "utf8");
|
|
2986
3033
|
if (await sha256(content) !== skill.digest) throw new Error("skill digest mismatch");
|
|
@@ -3012,7 +3059,6 @@ async function loadConfiguredAgentFleet(options) {
|
|
|
3012
3059
|
seatTiers = Object.freeze({});
|
|
3013
3060
|
}
|
|
3014
3061
|
validateSeatTierCandidates(seatTiers, modelTierCandidates, options.fleetConfigPath, options.policyPath);
|
|
3015
|
-
const canonicalWorkspaceRoot = options.workspaceRoot === null ? null : await realpath4(resolve4(options.workspaceRoot)).catch(() => null);
|
|
3016
3062
|
const agents = [];
|
|
3017
3063
|
const diagnostics = [];
|
|
3018
3064
|
const packagesByDefinitionId = /* @__PURE__ */ new Map();
|
|
@@ -3054,7 +3100,7 @@ async function loadConfiguredAgentFleet(options) {
|
|
|
3054
3100
|
if (conflictedDefinitionIds.has(binding.agentTypeId)) continue;
|
|
3055
3101
|
const descriptor = descriptors[0];
|
|
3056
3102
|
if (!descriptor || !descriptor.preflight.ok) throw new Error(`seat "${binding.seat}" has no valid discovered agent package`);
|
|
3057
|
-
const personaSource = await
|
|
3103
|
+
const personaSource = await realpath5(resolve5(descriptor.rootDir));
|
|
3058
3104
|
const source = await materializeAgentDirectory({
|
|
3059
3105
|
directory: personaSource,
|
|
3060
3106
|
expectedAgentTypeId: binding.agentTypeId,
|
|
@@ -3092,29 +3138,15 @@ async function loadConfiguredAgentFleet(options) {
|
|
|
3092
3138
|
instructionAppendices.push({ name: appendixName, digest: skill.digest, content });
|
|
3093
3139
|
}
|
|
3094
3140
|
const preferredModel = resolveSeatModel(seatTiers[binding.seat], env, modelTierCandidates);
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
if (unpublishableReason) {
|
|
3100
|
-
diagnostics.push({
|
|
3101
|
-
seat: binding.seat,
|
|
3102
|
-
agentTypeId: binding.agentTypeId,
|
|
3103
|
-
code: ErrorCode.enum.AGENT_FLEET_SEAT_INSTRUCTIONS_PATH_UNPUBLISHABLE,
|
|
3104
|
-
message: `${unpublishableReason}; its persona instructions will not be linkable`
|
|
3105
|
-
});
|
|
3106
|
-
} else {
|
|
3107
|
-
instructionFiles = [{
|
|
3108
|
-
filesystem: AGENT_USER_FILESYSTEM_ID,
|
|
3109
|
-
path: publishedInstructionPath,
|
|
3110
|
-
role: "persona"
|
|
3111
|
-
}];
|
|
3112
|
-
}
|
|
3141
|
+
const instructionSources = [{
|
|
3142
|
+
absolutePath: resolve5(personaSource, "instructions.md"),
|
|
3143
|
+
role: "persona"
|
|
3144
|
+
}];
|
|
3113
3145
|
const spec = await createConfiguredAgentHostAgentSpec({
|
|
3114
3146
|
source,
|
|
3115
3147
|
policy: {
|
|
3116
3148
|
instructionAppendices,
|
|
3117
|
-
|
|
3149
|
+
instructionSources,
|
|
3118
3150
|
...preferredModel ? { preferredModel } : {}
|
|
3119
3151
|
}
|
|
3120
3152
|
});
|
|
@@ -3134,7 +3166,7 @@ async function loadConfiguredAgentFleet(options) {
|
|
|
3134
3166
|
}
|
|
3135
3167
|
|
|
3136
3168
|
// src/server/agentDefinition/resolveDefaultAgentFleet.ts
|
|
3137
|
-
import { resolve as
|
|
3169
|
+
import { resolve as resolve6 } from "node:path";
|
|
3138
3170
|
import { createLogger } from "@hachej/boring-bash/server";
|
|
3139
3171
|
var logger = createLogger("agent-fleet-loader");
|
|
3140
3172
|
var LEGACY_DEFAULT_AGENT_FLEET = Object.freeze([
|
|
@@ -3148,15 +3180,13 @@ async function resolveDefaultAgentFleet(options) {
|
|
|
3148
3180
|
if (!options.discoveredPackages) throw new Error("agent package discovery descriptors were not injected by the boot layer");
|
|
3149
3181
|
const { agents: configuredAgents, diagnostics } = await loadConfiguredAgentFleet({
|
|
3150
3182
|
discoveredPackages: options.discoveredPackages,
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
skillsRoot: resolve5(root, ".agents", "skills"),
|
|
3183
|
+
fleetConfigPath: resolve6(root, ".agents", "factory", "fleet.yaml"),
|
|
3184
|
+
policyPath: resolve6(root, ".agents", "factory", "policy.yaml"),
|
|
3185
|
+
skillsRoot: resolve6(root, ".agents", "skills"),
|
|
3155
3186
|
env
|
|
3156
3187
|
});
|
|
3157
3188
|
for (const diagnostic of diagnostics) {
|
|
3158
|
-
|
|
3159
|
-
logger.warn(excluded ? "fleet package excluded or inert" : "fleet seat instructions not linkable", {
|
|
3189
|
+
logger.warn("fleet package excluded or inert", {
|
|
3160
3190
|
seat: diagnostic.seat,
|
|
3161
3191
|
agentTypeId: diagnostic.agentTypeId,
|
|
3162
3192
|
code: diagnostic.code,
|
|
@@ -4256,13 +4286,13 @@ function resultTool(result) {
|
|
|
4256
4286
|
};
|
|
4257
4287
|
}
|
|
4258
4288
|
function deferred() {
|
|
4259
|
-
let
|
|
4289
|
+
let resolve10;
|
|
4260
4290
|
let reject;
|
|
4261
4291
|
const promise = new Promise((res, rej) => {
|
|
4262
|
-
|
|
4292
|
+
resolve10 = res;
|
|
4263
4293
|
reject = rej;
|
|
4264
4294
|
});
|
|
4265
|
-
return { promise, resolve:
|
|
4295
|
+
return { promise, resolve: resolve10, reject };
|
|
4266
4296
|
}
|
|
4267
4297
|
function errorTool(error) {
|
|
4268
4298
|
const safe = safeError(error);
|
|
@@ -4676,7 +4706,7 @@ function isSqliteBusy(error) {
|
|
|
4676
4706
|
return (code === "SQLITE_BUSY" || code === "ERR_SQLITE_ERROR") && /busy|lock/i.test(error.message);
|
|
4677
4707
|
}
|
|
4678
4708
|
function delay(ms) {
|
|
4679
|
-
return new Promise((
|
|
4709
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
4680
4710
|
}
|
|
4681
4711
|
function clampLimit(value, defaultValue, maxValue) {
|
|
4682
4712
|
if (value === void 0) return defaultValue;
|
|
@@ -5893,6 +5923,11 @@ function normalizeMeteringUsage(value) {
|
|
|
5893
5923
|
}
|
|
5894
5924
|
};
|
|
5895
5925
|
}
|
|
5926
|
+
function isExplicitCompleteZeroUsage(value) {
|
|
5927
|
+
if (!isRecord4(value) || !isRecord4(value.cost)) return false;
|
|
5928
|
+
const hasOwnZeroFields = (record, fields) => fields.every((field) => Object.prototype.hasOwnProperty.call(record, field) && record[field] === 0);
|
|
5929
|
+
return hasOwnZeroFields(value, ["input", "output", "cacheRead", "cacheWrite", "totalTokens"]) && hasOwnZeroFields(value.cost, ["input", "output", "cacheRead", "cacheWrite", "total"]);
|
|
5930
|
+
}
|
|
5896
5931
|
var PiChatMeteringCoordinator = class {
|
|
5897
5932
|
sessions = /* @__PURE__ */ new Map();
|
|
5898
5933
|
inflightOps = /* @__PURE__ */ new Set();
|
|
@@ -6160,13 +6195,18 @@ var PiChatMeteringCoordinator = class {
|
|
|
6160
6195
|
}
|
|
6161
6196
|
recordAssistantUsage(state, message, opts = {}) {
|
|
6162
6197
|
if (!isRecord4(message) || message.role !== "assistant") return;
|
|
6198
|
+
if (!Object.prototype.hasOwnProperty.call(message, "usage")) return;
|
|
6199
|
+
const explicitCompleteZero = isExplicitCompleteZeroUsage(message.usage);
|
|
6163
6200
|
const usage = normalizeMeteringUsage(message.usage);
|
|
6164
|
-
if (!usage) return;
|
|
6165
6201
|
const run2 = state.active ?? state.pendingPrompts[0];
|
|
6166
6202
|
if (!run2 || run2.terminal) {
|
|
6167
6203
|
this.logError("assistant usage arrived with no reserved run; usage not metered", { messageRole: "assistant" });
|
|
6168
6204
|
return;
|
|
6169
6205
|
}
|
|
6206
|
+
if (!usage) {
|
|
6207
|
+
run2.allUsageReportsExplicitZero = false;
|
|
6208
|
+
return;
|
|
6209
|
+
}
|
|
6170
6210
|
const messageId = typeof message.id === "string" && message.id.length > 0 ? message.id : void 0;
|
|
6171
6211
|
if (messageId) {
|
|
6172
6212
|
if (run2.recordedMessageIds.has(messageId)) return;
|
|
@@ -6178,6 +6218,7 @@ var PiChatMeteringCoordinator = class {
|
|
|
6178
6218
|
run2.lastIdlessUsageKey = signature;
|
|
6179
6219
|
}
|
|
6180
6220
|
run2.usageCount += 1;
|
|
6221
|
+
if (!explicitCompleteZero) run2.allUsageReportsExplicitZero = false;
|
|
6181
6222
|
const model = typeof message.model === "string" && message.model.length > 0 ? message.model : void 0;
|
|
6182
6223
|
const provider = typeof message.provider === "string" && message.provider.length > 0 ? message.provider : void 0;
|
|
6183
6224
|
const stopReason = typeof message.stopReason === "string" ? message.stopReason : void 0;
|
|
@@ -6196,9 +6237,9 @@ var PiChatMeteringCoordinator = class {
|
|
|
6196
6237
|
stopReason
|
|
6197
6238
|
});
|
|
6198
6239
|
if (result.billedMicros > 0) run2.billableUsageCount += 1;
|
|
6240
|
+
if (explicitCompleteZero) run2.persistedExplicitZeroUsageCount += 1;
|
|
6199
6241
|
} catch (error) {
|
|
6200
|
-
|
|
6201
|
-
if (couldBill) run2.usageWriteFailed = true;
|
|
6242
|
+
if (!explicitCompleteZero) run2.usageWriteFailed = true;
|
|
6202
6243
|
throw error;
|
|
6203
6244
|
}
|
|
6204
6245
|
},
|
|
@@ -6222,6 +6263,8 @@ var PiChatMeteringCoordinator = class {
|
|
|
6222
6263
|
reservationId: void 0,
|
|
6223
6264
|
instanceId: this.runInstances += 1,
|
|
6224
6265
|
usageCount: 0,
|
|
6266
|
+
allUsageReportsExplicitZero: true,
|
|
6267
|
+
persistedExplicitZeroUsageCount: 0,
|
|
6225
6268
|
billableUsageCount: 0,
|
|
6226
6269
|
recordedMessageIds: /* @__PURE__ */ new Set(),
|
|
6227
6270
|
lastIdlessUsageKey: void 0,
|
|
@@ -6268,8 +6311,10 @@ var PiChatMeteringCoordinator = class {
|
|
|
6268
6311
|
if (run2.billableUsageCount > 0) {
|
|
6269
6312
|
return this.sink.settleRun({ ...run2.scope, reservationId: run2.reservationId, status });
|
|
6270
6313
|
}
|
|
6271
|
-
|
|
6272
|
-
|
|
6314
|
+
if (status === "ok" && !run2.userStopped && run2.usageCount > 0 && run2.allUsageReportsExplicitZero && run2.persistedExplicitZeroUsageCount === run2.usageCount) {
|
|
6315
|
+
return this.sink.settleRun({ ...run2.scope, reservationId: run2.reservationId, status });
|
|
6316
|
+
}
|
|
6317
|
+
if (status === "ok" && !run2.userStopped) {
|
|
6273
6318
|
return this.sink.releaseRun({ ...run2.scope, reservationId: run2.reservationId, reason: "fallback-hold-charge" });
|
|
6274
6319
|
}
|
|
6275
6320
|
return this.sink.releaseRun({
|
|
@@ -6372,11 +6417,11 @@ function bindingDisposedError() {
|
|
|
6372
6417
|
});
|
|
6373
6418
|
}
|
|
6374
6419
|
function deferred2() {
|
|
6375
|
-
let
|
|
6420
|
+
let resolve10;
|
|
6376
6421
|
const promise = new Promise((nextResolve) => {
|
|
6377
|
-
|
|
6422
|
+
resolve10 = () => nextResolve();
|
|
6378
6423
|
});
|
|
6379
|
-
return { promise, resolve:
|
|
6424
|
+
return { promise, resolve: resolve10 };
|
|
6380
6425
|
}
|
|
6381
6426
|
|
|
6382
6427
|
// src/server/codedError.ts
|
|
@@ -7254,13 +7299,13 @@ function promptCancelledError() {
|
|
|
7254
7299
|
});
|
|
7255
7300
|
}
|
|
7256
7301
|
function deferred3() {
|
|
7257
|
-
let
|
|
7302
|
+
let resolve10;
|
|
7258
7303
|
let reject;
|
|
7259
7304
|
const promise = new Promise((nextResolve, nextReject) => {
|
|
7260
|
-
|
|
7305
|
+
resolve10 = nextResolve;
|
|
7261
7306
|
reject = nextReject;
|
|
7262
7307
|
});
|
|
7263
|
-
return { promise, resolve:
|
|
7308
|
+
return { promise, resolve: resolve10, reject };
|
|
7264
7309
|
}
|
|
7265
7310
|
function rejectedReasons(results) {
|
|
7266
7311
|
return results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
@@ -7789,10 +7834,17 @@ var AgentSessionInventory = class {
|
|
|
7789
7834
|
compiledById;
|
|
7790
7835
|
resolveAgentRuntimeScope;
|
|
7791
7836
|
stores = /* @__PURE__ */ new Map();
|
|
7792
|
-
|
|
7837
|
+
/**
|
|
7838
|
+
* Lists a seat's sessions. `options` is threaded straight into the store so a
|
|
7839
|
+
* bounded page reads a bounded number of transcripts: an unbounded call makes
|
|
7840
|
+
* the store stream and parse EVERY native transcript it holds (see
|
|
7841
|
+
* `summarizeNativeTranscript`, whose result is intentionally never cached),
|
|
7842
|
+
* which is what made a per-seat boot listing cost tens of seconds (#1338).
|
|
7843
|
+
*/
|
|
7844
|
+
async list(agentTypeId, scope, claim, options) {
|
|
7793
7845
|
const resolved = await this.resolveStore(agentTypeId, scope, claim);
|
|
7794
7846
|
if (!resolved) return [];
|
|
7795
|
-
return await resolved.store.list({ workspaceId: claim.workspaceScopeId });
|
|
7847
|
+
return await resolved.store.list({ workspaceId: claim.workspaceScopeId }, options);
|
|
7796
7848
|
}
|
|
7797
7849
|
async resolveSessionRuntime(agentTypeId, scope, claim, sessionId) {
|
|
7798
7850
|
const resolved = await this.resolveStore(agentTypeId, scope, claim);
|
|
@@ -7985,7 +8037,7 @@ async function buildAgentComposition(input) {
|
|
|
7985
8037
|
sessionNamespace: configuredNamespace,
|
|
7986
8038
|
sessionDir: runtimeScope.sessionDir ?? factoryInput.sessionDir
|
|
7987
8039
|
}) : async (factoryInput) => {
|
|
7988
|
-
const { createPiCodingAgentHarness } = await import("./createHarness-
|
|
8040
|
+
const { createPiCodingAgentHarness } = await import("./createHarness-GMBZZPTN.js");
|
|
7989
8041
|
return createPiCodingAgentHarness({
|
|
7990
8042
|
...factoryInput,
|
|
7991
8043
|
pi,
|
|
@@ -8059,7 +8111,7 @@ var AgentSessionEventQueue = class {
|
|
|
8059
8111
|
const event = this.pending.shift();
|
|
8060
8112
|
if (event) return { done: false, value: event };
|
|
8061
8113
|
if (this.ended) return { done: true, value: void 0 };
|
|
8062
|
-
return await new Promise((
|
|
8114
|
+
return await new Promise((resolve10) => this.waiters.push(resolve10));
|
|
8063
8115
|
},
|
|
8064
8116
|
return: async () => {
|
|
8065
8117
|
this.close();
|
|
@@ -8248,20 +8300,27 @@ var EmbeddedAgentGateway = class {
|
|
|
8248
8300
|
if (input.agentTypeId && !this.runtime.compiledById.has(input.agentTypeId)) {
|
|
8249
8301
|
throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_TYPE_UNKNOWN, "agent type is not available");
|
|
8250
8302
|
}
|
|
8251
|
-
const cursor = input.cursor ? this.decodeCursor(input.cursor, claim.workspaceScopeId, input.agentTypeId, normalizedLimit) : void 0;
|
|
8303
|
+
const cursor = input.cursor ? this.decodeCursor(input.cursor, claim.workspaceScopeId, input.agentTypeId, normalizedLimit) : { depth: 0, after: void 0 };
|
|
8252
8304
|
const agents = input.agentTypeId ? [input.agentTypeId] : [...this.runtime.compiledById.keys()];
|
|
8305
|
+
const perAgentLimit = cursor.depth + normalizedLimit + 1;
|
|
8253
8306
|
const rows = [];
|
|
8254
8307
|
for (const agentTypeId of agents) {
|
|
8255
|
-
const listed = await this.runtime.listSessionSummaries(agentTypeId, input.scope, claim);
|
|
8308
|
+
const listed = await this.runtime.listSessionSummaries(agentTypeId, input.scope, claim, { limit: perAgentLimit });
|
|
8256
8309
|
for (const item of listed) {
|
|
8257
8310
|
const ref = { agentTypeId, sessionId: item.id };
|
|
8258
8311
|
rows.push(summaryFromLegacy(ref, item, this.runtime.activity.get(claim.workspaceScopeId, ref)));
|
|
8259
8312
|
}
|
|
8260
8313
|
}
|
|
8261
8314
|
rows.sort(compareSessions);
|
|
8262
|
-
const eligible = cursor ? rows.filter((row) => isAfterCursor(row, cursor)) : rows;
|
|
8315
|
+
const eligible = cursor.after ? rows.filter((row) => isAfterCursor(row, cursor.after)) : rows;
|
|
8263
8316
|
const sessions = eligible.slice(0, normalizedLimit);
|
|
8264
|
-
const nextCursor = eligible.length > sessions.length && sessions.length > 0 ? this.encodeCursor(
|
|
8317
|
+
const nextCursor = eligible.length > sessions.length && sessions.length > 0 ? this.encodeCursor(
|
|
8318
|
+
claim.workspaceScopeId,
|
|
8319
|
+
input.agentTypeId,
|
|
8320
|
+
normalizedLimit,
|
|
8321
|
+
cursor.depth + sessions.length,
|
|
8322
|
+
sessions.at(-1)
|
|
8323
|
+
) : void 0;
|
|
8265
8324
|
return { sessions, ...nextCursor ? { nextCursor } : {} };
|
|
8266
8325
|
}
|
|
8267
8326
|
async createSession(input) {
|
|
@@ -8804,8 +8863,8 @@ var EmbeddedAgentGateway = class {
|
|
|
8804
8863
|
const key = agentSessionKey(workspaceScopeId, ref);
|
|
8805
8864
|
const previous = this.writerTails.get(key) ?? Promise.resolve();
|
|
8806
8865
|
let release;
|
|
8807
|
-
const current = new Promise((
|
|
8808
|
-
release =
|
|
8866
|
+
const current = new Promise((resolve10) => {
|
|
8867
|
+
release = resolve10;
|
|
8809
8868
|
});
|
|
8810
8869
|
const tail = previous.then(() => current);
|
|
8811
8870
|
this.writerTails.set(key, tail);
|
|
@@ -8817,11 +8876,12 @@ var EmbeddedAgentGateway = class {
|
|
|
8817
8876
|
if (this.writerTails.get(key) === tail) this.writerTails.delete(key);
|
|
8818
8877
|
}
|
|
8819
8878
|
}
|
|
8820
|
-
encodeCursor(workspaceScopeId, agentTypeId, limit, last) {
|
|
8879
|
+
encodeCursor(workspaceScopeId, agentTypeId, limit, depth, last) {
|
|
8821
8880
|
const payload = JSON.stringify({
|
|
8822
8881
|
workspaceScopeId,
|
|
8823
8882
|
agentTypeId: agentTypeId ?? null,
|
|
8824
8883
|
limit,
|
|
8884
|
+
depth,
|
|
8825
8885
|
updatedAt: last.updatedAt,
|
|
8826
8886
|
lastAgentTypeId: last.ref.agentTypeId,
|
|
8827
8887
|
sessionId: last.ref.sessionId
|
|
@@ -8837,11 +8897,14 @@ var EmbeddedAgentGateway = class {
|
|
|
8837
8897
|
const expected = createHash6("sha256").update(`${this.cursorSecret}:${encoded}`).digest("base64url");
|
|
8838
8898
|
if (signature !== expected) throw new Error("signature");
|
|
8839
8899
|
const decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
8840
|
-
if (decoded.workspaceScopeId !== workspaceScopeId || decoded.agentTypeId !== (agentTypeId ?? null) || decoded.limit !== limit || typeof decoded.updatedAt !== "number" || typeof decoded.lastAgentTypeId !== "string" || typeof decoded.sessionId !== "string") throw new Error("binding");
|
|
8900
|
+
if (decoded.workspaceScopeId !== workspaceScopeId || decoded.agentTypeId !== (agentTypeId ?? null) || decoded.limit !== limit || typeof decoded.depth !== "number" || !Number.isInteger(decoded.depth) || decoded.depth < 0 || typeof decoded.updatedAt !== "number" || typeof decoded.lastAgentTypeId !== "string" || typeof decoded.sessionId !== "string") throw new Error("binding");
|
|
8841
8901
|
return {
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
|
|
8902
|
+
depth: decoded.depth,
|
|
8903
|
+
after: {
|
|
8904
|
+
updatedAt: decoded.updatedAt,
|
|
8905
|
+
agentTypeId: decoded.lastAgentTypeId,
|
|
8906
|
+
sessionId: decoded.sessionId
|
|
8907
|
+
}
|
|
8845
8908
|
};
|
|
8846
8909
|
} catch {
|
|
8847
8910
|
throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_SESSION_CURSOR_INVALID, "session cursor is invalid");
|
|
@@ -8863,7 +8926,7 @@ function closedError() {
|
|
|
8863
8926
|
return new AgentGatewayError(AgentGatewayErrorCode.AGENT_GATEWAY_CLOSED, "agent host is closing");
|
|
8864
8927
|
}
|
|
8865
8928
|
function delay2(ms) {
|
|
8866
|
-
return new Promise((
|
|
8929
|
+
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
8867
8930
|
}
|
|
8868
8931
|
var EnvironmentLeaseManager = class {
|
|
8869
8932
|
constructor(adapter) {
|
|
@@ -9295,7 +9358,7 @@ function sessionChangesRoutes(app, opts, done) {
|
|
|
9295
9358
|
}
|
|
9296
9359
|
|
|
9297
9360
|
// src/server/http/routes/skills.ts
|
|
9298
|
-
import { dirname as dirname6, isAbsolute as isAbsolute6, relative as relative7, resolve as
|
|
9361
|
+
import { dirname as dirname6, isAbsolute as isAbsolute6, relative as relative7, resolve as resolve7, sep as sep6 } from "node:path";
|
|
9299
9362
|
import {
|
|
9300
9363
|
DefaultPackageManager,
|
|
9301
9364
|
getAgentDir,
|
|
@@ -9304,12 +9367,12 @@ import {
|
|
|
9304
9367
|
var CACHE_TTL_MS = 3e4;
|
|
9305
9368
|
function provisionedWorkspaceRoots(additionalSkillPaths) {
|
|
9306
9369
|
const userSkillsSuffix = `${sep6}.agents${sep6}skills`;
|
|
9307
|
-
return additionalSkillPaths.map((skillPath) =>
|
|
9370
|
+
return additionalSkillPaths.map((skillPath) => resolve7(skillPath)).filter((skillPath) => skillPath.endsWith(userSkillsSuffix)).map((skillPath) => dirname6(dirname6(skillPath)));
|
|
9308
9371
|
}
|
|
9309
9372
|
function pathForWorkspaceEditor(workspace, filePath, additionalSkillPaths = []) {
|
|
9310
9373
|
const roots = [workspace.root, ...provisionedWorkspaceRoots(additionalSkillPaths)];
|
|
9311
9374
|
for (const root of roots) {
|
|
9312
|
-
const pathWithinWorkspace = relative7(
|
|
9375
|
+
const pathWithinWorkspace = relative7(resolve7(root), resolve7(filePath));
|
|
9313
9376
|
if (pathWithinWorkspace === "" || pathWithinWorkspace === ".." || pathWithinWorkspace.startsWith(`..${sep6}`) || isAbsolute6(pathWithinWorkspace)) {
|
|
9314
9377
|
continue;
|
|
9315
9378
|
}
|
|
@@ -9535,7 +9598,7 @@ function createAgentHostRuntimeCapabilityProjection(input) {
|
|
|
9535
9598
|
);
|
|
9536
9599
|
return { scope, claim, resolved };
|
|
9537
9600
|
};
|
|
9538
|
-
const
|
|
9601
|
+
const resolve10 = async (request, agentTypeId, sessionId) => {
|
|
9539
9602
|
if (sessionId) {
|
|
9540
9603
|
const { scope: scope2 } = await authorize(request);
|
|
9541
9604
|
const pinned = await gateway.resolveHostSessionBinding(scope2, { agentTypeId, sessionId });
|
|
@@ -9557,7 +9620,7 @@ function createAgentHostRuntimeCapabilityProjection(input) {
|
|
|
9557
9620
|
}
|
|
9558
9621
|
},
|
|
9559
9622
|
async resolveBinding({ request, agentTypeId, sessionId }) {
|
|
9560
|
-
const { claim, binding } = await
|
|
9623
|
+
const { claim, binding } = await resolve10(request, agentTypeId, sessionId);
|
|
9561
9624
|
const skillResourceSnapshotPromise = binding.scope.getSkillResourceSnapshot?.({
|
|
9562
9625
|
scope: claim,
|
|
9563
9626
|
sessionId,
|
|
@@ -9621,7 +9684,7 @@ function createAgentHostRuntimeCapabilityProjection(input) {
|
|
|
9621
9684
|
};
|
|
9622
9685
|
},
|
|
9623
9686
|
async describeAgent({ request, agentTypeId }) {
|
|
9624
|
-
const { claim } = await authorizeAgentAccess(request, agentTypeId);
|
|
9687
|
+
const { claim, resolved } = await authorizeAgentAccess(request, agentTypeId);
|
|
9625
9688
|
const spec = runtime.compiledById.get(agentTypeId);
|
|
9626
9689
|
if (!spec) {
|
|
9627
9690
|
throw new AgentGatewayError(AgentGatewayErrorCode.AGENT_TYPE_UNKNOWN, "agent type is not available");
|
|
@@ -9632,28 +9695,39 @@ function createAgentHostRuntimeCapabilityProjection(input) {
|
|
|
9632
9695
|
const refs = mcpGrants.getMcpServerRefs(agentTypeId) ?? [];
|
|
9633
9696
|
if (refs.length > 0) {
|
|
9634
9697
|
const listed = await mcpGrants.store.listGrants(claim.workspaceScopeId);
|
|
9635
|
-
const
|
|
9698
|
+
const resolved2 = resolveAgentMcpGrants({
|
|
9636
9699
|
workspaceId: claim.workspaceScopeId,
|
|
9637
9700
|
agentTypeId,
|
|
9638
9701
|
mcpServerRefs: refs,
|
|
9639
9702
|
grants: listed.grants,
|
|
9640
9703
|
catalog: mcpGrants.catalog
|
|
9641
9704
|
});
|
|
9642
|
-
mcpServers =
|
|
9705
|
+
mcpServers = resolved2.connectors.map((connector) => ({
|
|
9643
9706
|
id: connector.connectorId,
|
|
9644
9707
|
tools: connector.allowedTools
|
|
9645
9708
|
}));
|
|
9646
9709
|
}
|
|
9647
9710
|
}
|
|
9711
|
+
const { refs: instructionFiles, withheld } = legacy ? { refs: [], withheld: [] } : await resolveAgentInstructionFileRefs({
|
|
9712
|
+
sources: spec.instructionSources,
|
|
9713
|
+
workspaceRoot: resolved.environment.workspaceRoot
|
|
9714
|
+
});
|
|
9715
|
+
for (const entry of withheld) {
|
|
9716
|
+
request.log?.warn?.({
|
|
9717
|
+
agentTypeId,
|
|
9718
|
+
code: entry.code,
|
|
9719
|
+
workspaceScopeId: claim.workspaceScopeId
|
|
9720
|
+
}, `${entry.message}; its persona instructions are not linkable here`);
|
|
9721
|
+
}
|
|
9648
9722
|
return {
|
|
9649
9723
|
agentTypeId,
|
|
9650
9724
|
model: legacy ? null : spec.model?.preferred ?? null,
|
|
9651
|
-
instructionFiles
|
|
9725
|
+
instructionFiles,
|
|
9652
9726
|
mcpServers
|
|
9653
9727
|
};
|
|
9654
9728
|
},
|
|
9655
9729
|
async executeCommand({ request, agentTypeId, requestId, sessionId, name, args }) {
|
|
9656
|
-
const { scope, binding } = await
|
|
9730
|
+
const { scope, binding } = await resolve10(request, agentTypeId, sessionId);
|
|
9657
9731
|
if (!binding.composition.harness.executeSlashCommand) {
|
|
9658
9732
|
throw new AgentGatewayError(
|
|
9659
9733
|
AgentGatewayErrorCode.AGENT_COMMAND_INVALID_STATE,
|
|
@@ -9854,7 +9928,7 @@ function createAgentHostRuntimeCapabilityRoutes(projection) {
|
|
|
9854
9928
|
return async (app) => {
|
|
9855
9929
|
app.setErrorHandler((error, _request, reply) => sendError(reply, error));
|
|
9856
9930
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
9857
|
-
const
|
|
9931
|
+
const resolve10 = (request, agentTypeId, sessionId) => {
|
|
9858
9932
|
let entries = cache.get(request);
|
|
9859
9933
|
if (!entries) {
|
|
9860
9934
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -9873,40 +9947,40 @@ function createAgentHostRuntimeCapabilityRoutes(projection) {
|
|
|
9873
9947
|
path: "/api/v1/agents/:agentTypeId/models",
|
|
9874
9948
|
filterModels: projection.filterModels,
|
|
9875
9949
|
authorizeRequest: async (request) => {
|
|
9876
|
-
await
|
|
9950
|
+
await resolve10(request, agentId(request));
|
|
9877
9951
|
}
|
|
9878
9952
|
});
|
|
9879
9953
|
await app.register(skillsRoutes, {
|
|
9880
9954
|
path: "/api/v1/agents/:agentTypeId/skills",
|
|
9881
9955
|
authorizeRequest: async (request) => {
|
|
9882
|
-
await
|
|
9956
|
+
await resolve10(request, agentId(request));
|
|
9883
9957
|
},
|
|
9884
|
-
getWorkspace: async (request) => (await
|
|
9958
|
+
getWorkspace: async (request) => (await resolve10(request, agentId(request))).workspace,
|
|
9885
9959
|
getAdditionalSkillPaths: async (request) => [
|
|
9886
|
-
...(await
|
|
9887
|
-
...(await
|
|
9960
|
+
...(await resolve10(request, agentId(request))).additionalSkillPaths ?? [],
|
|
9961
|
+
...(await resolve10(request, agentId(request))).pi?.additionalSkillPaths ?? []
|
|
9888
9962
|
],
|
|
9889
|
-
getPiPackages: async (request) => (await
|
|
9890
|
-
getNoSkills: async (request) => (await
|
|
9891
|
-
getSkillResourceSnapshot: async (request) => (await
|
|
9963
|
+
getPiPackages: async (request) => (await resolve10(request, agentId(request))).pi?.packages,
|
|
9964
|
+
getNoSkills: async (request) => (await resolve10(request, agentId(request))).pi?.noSkills,
|
|
9965
|
+
getSkillResourceSnapshot: async (request) => (await resolve10(request, agentId(request))).skillResourceSnapshot
|
|
9892
9966
|
});
|
|
9893
9967
|
await app.register(catalogRoutes, {
|
|
9894
9968
|
path: "/api/v1/agents/:agentTypeId/tools",
|
|
9895
9969
|
authorizeRequest: async (request) => {
|
|
9896
|
-
await
|
|
9970
|
+
await resolve10(request, agentId(request));
|
|
9897
9971
|
},
|
|
9898
|
-
getTools: async (request) => [...(await
|
|
9972
|
+
getTools: async (request) => [...(await resolve10(request, agentId(request))).tools]
|
|
9899
9973
|
});
|
|
9900
9974
|
await app.register(systemPromptRoutes, {
|
|
9901
9975
|
path: "/api/v1/agents/:agentTypeId/sessions/:sessionId/system-prompt",
|
|
9902
9976
|
sessionIdParam: "sessionId",
|
|
9903
9977
|
authorizeRequest: async (request) => {
|
|
9904
9978
|
const value = request.params;
|
|
9905
|
-
await
|
|
9979
|
+
await resolve10(request, value.agentTypeId, value.sessionId);
|
|
9906
9980
|
},
|
|
9907
9981
|
getHarness: async (request) => {
|
|
9908
9982
|
const value = request.params;
|
|
9909
|
-
return (await
|
|
9983
|
+
return (await resolve10(request, value.agentTypeId, value.sessionId)).harness;
|
|
9910
9984
|
}
|
|
9911
9985
|
});
|
|
9912
9986
|
await app.register(sessionChangesRoutes, {
|
|
@@ -9915,11 +9989,11 @@ function createAgentHostRuntimeCapabilityRoutes(projection) {
|
|
|
9915
9989
|
tracker: projection.sessionChangesTracker,
|
|
9916
9990
|
authorizeRequest: async (request) => {
|
|
9917
9991
|
const value = request.params;
|
|
9918
|
-
await
|
|
9992
|
+
await resolve10(request, value.agentTypeId, value.sessionId);
|
|
9919
9993
|
},
|
|
9920
9994
|
resolveScope: async (request, sessionId) => {
|
|
9921
9995
|
const value = request.params;
|
|
9922
|
-
const binding = await
|
|
9996
|
+
const binding = await resolve10(request, value.agentTypeId, sessionId);
|
|
9923
9997
|
return {
|
|
9924
9998
|
workspaceScopeId: binding.runContext.workspaceId,
|
|
9925
9999
|
agentTypeId: value.agentTypeId,
|
|
@@ -9930,9 +10004,9 @@ function createAgentHostRuntimeCapabilityRoutes(projection) {
|
|
|
9930
10004
|
await app.register(readyStatusRoutes, {
|
|
9931
10005
|
path: "/api/v1/agents/:agentTypeId/ready-status",
|
|
9932
10006
|
authorizeRequest: async (request) => {
|
|
9933
|
-
await
|
|
10007
|
+
await resolve10(request, agentId(request));
|
|
9934
10008
|
},
|
|
9935
|
-
getTracker: async (request) => (await
|
|
10009
|
+
getTracker: async (request) => (await resolve10(request, agentId(request))).readyTracker,
|
|
9936
10010
|
registerStreamClose: projection.registerSubscription
|
|
9937
10011
|
});
|
|
9938
10012
|
app.get("/api/v1/agents/:agentTypeId/describe", async (request, reply) => {
|
|
@@ -9953,7 +10027,7 @@ function createAgentHostRuntimeCapabilityRoutes(projection) {
|
|
|
9953
10027
|
try {
|
|
9954
10028
|
const query = request.query;
|
|
9955
10029
|
const sessionId = typeof query.sessionId === "string" && query.sessionId.trim() ? query.sessionId.trim() : "default";
|
|
9956
|
-
const binding = await
|
|
10030
|
+
const binding = await resolve10(
|
|
9957
10031
|
request,
|
|
9958
10032
|
value.agentTypeId,
|
|
9959
10033
|
typeof query.sessionId === "string" && query.sessionId.trim() ? sessionId : void 0
|
|
@@ -11027,12 +11101,12 @@ async function runWithWorkspaceAgentLease(input) {
|
|
|
11027
11101
|
const operations = /* @__PURE__ */ new Set();
|
|
11028
11102
|
const cleanups = /* @__PURE__ */ new Set();
|
|
11029
11103
|
let signalDrain;
|
|
11030
|
-
const drainRequested = new Promise((
|
|
11031
|
-
signalDrain =
|
|
11104
|
+
const drainRequested = new Promise((resolve10) => {
|
|
11105
|
+
signalDrain = resolve10;
|
|
11032
11106
|
});
|
|
11033
11107
|
let signalRevocation;
|
|
11034
|
-
const revocation = new Promise((
|
|
11035
|
-
signalRevocation =
|
|
11108
|
+
const revocation = new Promise((resolve10) => {
|
|
11109
|
+
signalRevocation = resolve10;
|
|
11036
11110
|
});
|
|
11037
11111
|
let drainDeadline;
|
|
11038
11112
|
const registerCleanup = (cleanup) => {
|
|
@@ -11087,8 +11161,8 @@ async function runWithWorkspaceAgentLease(input) {
|
|
|
11087
11161
|
const remainingMs = Math.max(0, drainDeadline - Date.now());
|
|
11088
11162
|
const outcome = await Promise.race([
|
|
11089
11163
|
Promise.allSettled(pending).then((results) => ({ kind: "settled", results })),
|
|
11090
|
-
new Promise((
|
|
11091
|
-
setTimeout(() =>
|
|
11164
|
+
new Promise((resolve10) => {
|
|
11165
|
+
setTimeout(() => resolve10({ kind: "expired" }), remainingMs);
|
|
11092
11166
|
})
|
|
11093
11167
|
]);
|
|
11094
11168
|
if (outcome.kind === "expired") break;
|
|
@@ -11370,9 +11444,9 @@ function createRuntime(options, compiledAgents) {
|
|
|
11370
11444
|
},
|
|
11371
11445
|
activity,
|
|
11372
11446
|
shutdownGraceMs: graceMs,
|
|
11373
|
-
listSessionSummaries(agentTypeId, scope, claim) {
|
|
11447
|
+
listSessionSummaries(agentTypeId, scope, claim, options2) {
|
|
11374
11448
|
runtime.assertOpen();
|
|
11375
|
-
return inventory.list(agentTypeId, scope, claim);
|
|
11449
|
+
return inventory.list(agentTypeId, scope, claim, options2);
|
|
11376
11450
|
},
|
|
11377
11451
|
isDraining: () => draining,
|
|
11378
11452
|
assertOpen() {
|
|
@@ -11550,8 +11624,8 @@ function createRuntime(options, compiledAgents) {
|
|
|
11550
11624
|
if (work.length === 0) return;
|
|
11551
11625
|
const completed = await Promise.race([
|
|
11552
11626
|
Promise.allSettled(work).then((results) => ({ completed: true, results })),
|
|
11553
|
-
new Promise((
|
|
11554
|
-
setTimeout(() =>
|
|
11627
|
+
new Promise((resolve10) => {
|
|
11628
|
+
setTimeout(() => resolve10({ completed: false }), graceMs);
|
|
11555
11629
|
})
|
|
11556
11630
|
]);
|
|
11557
11631
|
if (completed.completed) {
|
|
@@ -11594,8 +11668,8 @@ function createRuntime(options, compiledAgents) {
|
|
|
11594
11668
|
runtime.assertOpen();
|
|
11595
11669
|
let resolveEffect;
|
|
11596
11670
|
let rejectEffect;
|
|
11597
|
-
const effect = new Promise((
|
|
11598
|
-
resolveEffect =
|
|
11671
|
+
const effect = new Promise((resolve10, reject) => {
|
|
11672
|
+
resolveEffect = resolve10;
|
|
11599
11673
|
rejectEffect = reject;
|
|
11600
11674
|
});
|
|
11601
11675
|
finiteEffects.set(effect, key);
|
|
@@ -11611,8 +11685,8 @@ function createRuntime(options, compiledAgents) {
|
|
|
11611
11685
|
async runBindingOperation(bindingKey, operation) {
|
|
11612
11686
|
const previous = bindingOperationTails.get(bindingKey) ?? Promise.resolve();
|
|
11613
11687
|
let release;
|
|
11614
|
-
const current = new Promise((
|
|
11615
|
-
release =
|
|
11688
|
+
const current = new Promise((resolve10) => {
|
|
11689
|
+
release = resolve10;
|
|
11616
11690
|
});
|
|
11617
11691
|
const tail = previous.then(() => current);
|
|
11618
11692
|
bindingOperationTails.set(bindingKey, tail);
|
|
@@ -11643,7 +11717,7 @@ function createRuntime(options, compiledAgents) {
|
|
|
11643
11717
|
));
|
|
11644
11718
|
const bindingCleanupResult = await Promise.race([
|
|
11645
11719
|
bindingCleanup.then((results) => ({ completed: true, results })),
|
|
11646
|
-
new Promise((
|
|
11720
|
+
new Promise((resolve10) => setTimeout(() => resolve10({ completed: false }), graceMs))
|
|
11647
11721
|
]);
|
|
11648
11722
|
if (bindingCleanupResult.completed) {
|
|
11649
11723
|
const failed = bindingCleanupResult.results.find(
|
|
@@ -11659,7 +11733,7 @@ function createRuntime(options, compiledAgents) {
|
|
|
11659
11733
|
try {
|
|
11660
11734
|
await Promise.race([
|
|
11661
11735
|
options.runtimeModeAdapter.dispose?.() ?? Promise.resolve(),
|
|
11662
|
-
new Promise((
|
|
11736
|
+
new Promise((resolve10) => setTimeout(resolve10, graceMs))
|
|
11663
11737
|
]);
|
|
11664
11738
|
} catch (error) {
|
|
11665
11739
|
firstError ??= error;
|
|
@@ -11924,7 +11998,7 @@ async function registerAgentHostEnvironmentRoutes(app, options) {
|
|
|
11924
11998
|
|
|
11925
11999
|
// src/server/harness/pi-coding-agent/pluginLoader.ts
|
|
11926
12000
|
import { readdir as readdir4, stat as stat6, readFile as readFile5 } from "node:fs/promises";
|
|
11927
|
-
import { join as join8, extname, resolve as
|
|
12001
|
+
import { join as join8, extname, resolve as resolve8, sep as sep7, relative as relative8 } from "node:path";
|
|
11928
12002
|
import { homedir } from "node:os";
|
|
11929
12003
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
11930
12004
|
var VALID_EXTENSIONS = /* @__PURE__ */ new Set([".js", ".mjs"]);
|
|
@@ -11994,8 +12068,8 @@ async function loadNpmPlugin(pkgDir, importFn) {
|
|
|
11994
12068
|
if (!await fileExists(pkgJsonPath)) return [];
|
|
11995
12069
|
const pkgJson = JSON.parse(await readFile5(pkgJsonPath, "utf-8"));
|
|
11996
12070
|
const main = pkgJson.main ?? "index.js";
|
|
11997
|
-
const resolvedMain =
|
|
11998
|
-
const resolvedPkgDir =
|
|
12071
|
+
const resolvedMain = resolve8(pkgDir, main);
|
|
12072
|
+
const resolvedPkgDir = resolve8(pkgDir);
|
|
11999
12073
|
if (resolvedMain !== resolvedPkgDir && !resolvedMain.startsWith(resolvedPkgDir + sep7)) {
|
|
12000
12074
|
return [];
|
|
12001
12075
|
}
|
|
@@ -12134,9 +12208,9 @@ function withRuntimeEnvContributions(runtimeBundle, baseContext, contributions,
|
|
|
12134
12208
|
// src/server/piResourceDigest.ts
|
|
12135
12209
|
import { createHash as createHash7 } from "node:crypto";
|
|
12136
12210
|
import { constants as constants3 } from "node:fs";
|
|
12137
|
-
import { lstat as lstat4, open as open2, opendir, realpath as
|
|
12211
|
+
import { lstat as lstat4, open as open2, opendir, realpath as realpath6, stat as statPath } from "node:fs/promises";
|
|
12138
12212
|
import { homedir as homedir2 } from "node:os";
|
|
12139
|
-
import { dirname as dirname8, isAbsolute as isAbsolute7, join as join9, parse, relative as relative9, resolve as
|
|
12213
|
+
import { dirname as dirname8, isAbsolute as isAbsolute7, join as join9, parse, relative as relative9, resolve as resolve9, sep as sep8 } from "node:path";
|
|
12140
12214
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
12141
12215
|
import { DefaultPackageManager as DefaultPackageManager2, getAgentDir as getAgentDir2, loadProjectContextFiles } from "@mariozechner/pi-coding-agent";
|
|
12142
12216
|
var DEFAULT_PI_RESOURCE_DIGEST_LIMITS = Object.freeze({
|
|
@@ -12334,11 +12408,11 @@ function resolvePiPath(input, baseDir) {
|
|
|
12334
12408
|
let normalized = input.trim();
|
|
12335
12409
|
if (normalized === "~") normalized = homedir2();
|
|
12336
12410
|
else if (normalized.startsWith("~/") || process.platform === "win32" && normalized.startsWith("~\\")) {
|
|
12337
|
-
normalized =
|
|
12411
|
+
normalized = resolve9(homedir2(), normalized.slice(2));
|
|
12338
12412
|
} else if (/^file:\/\//.test(normalized)) {
|
|
12339
12413
|
normalized = fileURLToPath7(normalized);
|
|
12340
12414
|
}
|
|
12341
|
-
return isAbsolute7(normalized) ?
|
|
12415
|
+
return isAbsolute7(normalized) ? resolve9(normalized) : resolve9(baseDir, normalized);
|
|
12342
12416
|
}
|
|
12343
12417
|
async function findContainingArtifactRoot(path, authorizedRoots) {
|
|
12344
12418
|
let current = dirname8(path);
|
|
@@ -12346,7 +12420,7 @@ async function findContainingArtifactRoot(path, authorizedRoots) {
|
|
|
12346
12420
|
if (!boundary) throw stableError(ErrorCode.enum.PATH_ESCAPE, 403, `Pi resource path is outside authorized roots: ${path}`);
|
|
12347
12421
|
while (isContained(current, boundary)) {
|
|
12348
12422
|
try {
|
|
12349
|
-
const packageStat = await lstat4(
|
|
12423
|
+
const packageStat = await lstat4(resolve9(current, "package.json"));
|
|
12350
12424
|
if (packageStat.isSymbolicLink()) {
|
|
12351
12425
|
throw stableError(ErrorCode.enum.PATH_SYMLINK_ESCAPE, 403, `Pi resource package manifest cannot be a symlink: ${current}`);
|
|
12352
12426
|
}
|
|
@@ -12360,7 +12434,7 @@ async function findContainingArtifactRoot(path, authorizedRoots) {
|
|
|
12360
12434
|
return dirname8(path);
|
|
12361
12435
|
}
|
|
12362
12436
|
async function hashLocalResource(state, path, logicalPath, depth) {
|
|
12363
|
-
const absolutePath =
|
|
12437
|
+
const absolutePath = resolve9(path);
|
|
12364
12438
|
await assertContainedWithoutSymlinks(absolutePath, state.authorizedRoots);
|
|
12365
12439
|
if (depth > state.limits.maxDepth) {
|
|
12366
12440
|
throw limitError(`Pi resource tree exceeds maximum depth ${state.limits.maxDepth}`);
|
|
@@ -12384,7 +12458,7 @@ async function hashLocalResource(state, path, logicalPath, depth) {
|
|
|
12384
12458
|
}
|
|
12385
12459
|
if (stat7.isDirectory()) {
|
|
12386
12460
|
frameString(state.hash, "directory", logicalPath);
|
|
12387
|
-
const openedTarget = await
|
|
12461
|
+
const openedTarget = await realpath6(absolutePath);
|
|
12388
12462
|
if (!mostSpecificContainingRoot(openedTarget, state.authorizedRoots)) {
|
|
12389
12463
|
throw stableError(ErrorCode.enum.PATH_SYMLINK_ESCAPE, 403, `Pi resource resolves outside authorized roots: ${absolutePath}`);
|
|
12390
12464
|
}
|
|
@@ -12403,12 +12477,12 @@ async function hashLocalResource(state, path, logicalPath, depth) {
|
|
|
12403
12477
|
frameString(state.hash, "entry-name", entry.name);
|
|
12404
12478
|
await hashLocalResource(
|
|
12405
12479
|
state,
|
|
12406
|
-
|
|
12480
|
+
resolve9(openedTarget, entry.name),
|
|
12407
12481
|
logicalPath === "." ? entry.name : `${logicalPath}/${entry.name}`,
|
|
12408
12482
|
depth + 1
|
|
12409
12483
|
);
|
|
12410
12484
|
}
|
|
12411
|
-
const afterTarget = await
|
|
12485
|
+
const afterTarget = await realpath6(absolutePath);
|
|
12412
12486
|
if (afterTarget !== openedTarget) throw changedError(absolutePath);
|
|
12413
12487
|
assertSameFile(stat7, await statPath(afterTarget), absolutePath);
|
|
12414
12488
|
return;
|
|
@@ -12428,7 +12502,7 @@ async function hashLocalResource(state, path, logicalPath, depth) {
|
|
|
12428
12502
|
try {
|
|
12429
12503
|
const opened = await handle.stat();
|
|
12430
12504
|
assertSameFile(stat7, opened, absolutePath);
|
|
12431
|
-
const openedTarget = await
|
|
12505
|
+
const openedTarget = await realpath6(absolutePath);
|
|
12432
12506
|
if (!mostSpecificContainingRoot(openedTarget, state.authorizedRoots)) {
|
|
12433
12507
|
throw stableError(ErrorCode.enum.PATH_SYMLINK_ESCAPE, 403, `Pi resource resolves outside authorized roots: ${absolutePath}`);
|
|
12434
12508
|
}
|
|
@@ -12443,7 +12517,7 @@ async function hashLocalResource(state, path, logicalPath, depth) {
|
|
|
12443
12517
|
}
|
|
12444
12518
|
const after = await handle.stat();
|
|
12445
12519
|
assertSameFile(opened, after, absolutePath);
|
|
12446
|
-
const afterTarget = await
|
|
12520
|
+
const afterTarget = await realpath6(absolutePath);
|
|
12447
12521
|
if (afterTarget !== openedTarget) throw changedError(absolutePath);
|
|
12448
12522
|
assertSameFile(after, await statPath(afterTarget), absolutePath);
|
|
12449
12523
|
state.bytes += offset;
|
|
@@ -12459,12 +12533,12 @@ async function assertContainedWithoutSymlinks(path, roots) {
|
|
|
12459
12533
|
if (!root) {
|
|
12460
12534
|
throw stableError(ErrorCode.enum.PATH_ESCAPE, 403, `Pi resource path is outside authorized roots: ${path}`);
|
|
12461
12535
|
}
|
|
12462
|
-
const absolutePath =
|
|
12536
|
+
const absolutePath = resolve9(path);
|
|
12463
12537
|
const pathRoot = parse(absolutePath).root;
|
|
12464
12538
|
const segments = relative9(pathRoot, absolutePath).split(sep8).filter(Boolean);
|
|
12465
12539
|
let current = pathRoot;
|
|
12466
12540
|
for (const segment of segments) {
|
|
12467
|
-
current =
|
|
12541
|
+
current = resolve9(current, segment);
|
|
12468
12542
|
try {
|
|
12469
12543
|
if ((await lstat4(current)).isSymbolicLink()) {
|
|
12470
12544
|
throw stableError(ErrorCode.enum.PATH_SYMLINK_ESCAPE, 403, `Pi resource symlinks are not allowed: ${current}`);
|
|
@@ -12479,7 +12553,7 @@ function mostSpecificContainingRoot(path, roots) {
|
|
|
12479
12553
|
return roots.filter((root) => isContained(path, root)).sort((left, right) => right.length - left.length)[0];
|
|
12480
12554
|
}
|
|
12481
12555
|
function isContained(path, root) {
|
|
12482
|
-
const value = relative9(
|
|
12556
|
+
const value = relative9(resolve9(root), resolve9(path));
|
|
12483
12557
|
return value === "" || value !== ".." && !value.startsWith(`..${sep8}`) && !isAbsolute7(value);
|
|
12484
12558
|
}
|
|
12485
12559
|
function frameString(hash, tag, value) {
|
|
@@ -13572,6 +13646,7 @@ export {
|
|
|
13572
13646
|
materializeAgentDirectory,
|
|
13573
13647
|
TrustedAgentCompositionError,
|
|
13574
13648
|
createConfiguredAgentHostAgentSpec,
|
|
13649
|
+
resolveAgentInstructionFileRefs,
|
|
13575
13650
|
FleetConfigError,
|
|
13576
13651
|
loadConfiguredAgentFleet,
|
|
13577
13652
|
LEGACY_DEFAULT_AGENT_FLEET,
|