omp-fabric 0.85.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/transports/process-transport.d.ts.map +1 -1
- package/dist/agents/transports/process-utils.d.ts +6 -1
- package/dist/agents/transports/process-utils.d.ts.map +1 -1
- package/dist/agents/types.d.ts +1 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/audit/details.d.ts +10 -0
- package/dist/audit/details.d.ts.map +1 -1
- package/dist/chunks/{chunk-GKOFZ76R.js → chunk-2LGLDM34.js} +22 -4
- package/dist/chunks/chunk-2LGLDM34.js.map +7 -0
- package/dist/chunks/{chunk-T6OAX4FO.js → chunk-3TWC6XOS.js} +37 -9
- package/dist/chunks/chunk-3TWC6XOS.js.map +7 -0
- package/dist/chunks/{chunk-ZNAJDPT7.js → chunk-B2SQR2JY.js} +32 -24
- package/dist/chunks/{chunk-ZNAJDPT7.js.map → chunk-B2SQR2JY.js.map} +2 -2
- package/dist/chunks/{chunk-SXMWV447.js → chunk-DOKANNFC.js} +206 -3
- package/dist/chunks/chunk-DOKANNFC.js.map +7 -0
- package/dist/chunks/{chunk-UPCARIJP.js → chunk-FFWALVBN.js} +20 -9
- package/dist/chunks/chunk-FFWALVBN.js.map +7 -0
- package/dist/chunks/{chunk-4LEDA76O.js → chunk-HAJPYJPY.js} +3 -3
- package/dist/chunks/{chunk-ROKMBLGN.js → chunk-IFNDRFW7.js} +34 -14
- package/dist/chunks/chunk-IFNDRFW7.js.map +7 -0
- package/dist/chunks/{chunk-ZTM45GH5.js → chunk-JZWLICMS.js} +125 -42
- package/dist/chunks/chunk-JZWLICMS.js.map +7 -0
- package/dist/chunks/{chunk-5GTPD4BA.js → chunk-L2FNMIOW.js} +66 -22
- package/dist/chunks/chunk-L2FNMIOW.js.map +7 -0
- package/dist/chunks/chunk-NX4SNIMR.js +226 -0
- package/dist/chunks/chunk-NX4SNIMR.js.map +7 -0
- package/dist/chunks/{chunk-YZZIKJX6.js → chunk-RBA54WC7.js} +1 -1
- package/dist/chunks/{chunk-YZZIKJX6.js.map → chunk-RBA54WC7.js.map} +1 -1
- package/dist/chunks/{chunk-OPTP4PSE.js → chunk-YPYVUGON.js} +3 -23
- package/dist/chunks/chunk-YPYVUGON.js.map +7 -0
- package/dist/chunks/{chunk-JP4LIZFT.js → chunk-Z6HEQPXX.js} +23 -6
- package/dist/chunks/chunk-Z6HEQPXX.js.map +7 -0
- package/dist/commands/fabric.d.ts.map +1 -1
- package/dist/core/action-registry.d.ts +2 -1
- package/dist/core/action-registry.d.ts.map +1 -1
- package/dist/core/action-registry.js +2 -2
- package/dist/core/compact-controller.d.ts +28 -3
- package/dist/core/compact-controller.d.ts.map +1 -1
- package/dist/core/compact-outcome-store.d.ts +3 -0
- package/dist/core/compact-outcome-store.d.ts.map +1 -0
- package/dist/entropy/index.js +2 -2
- package/dist/entropy/sessions.d.ts.map +1 -1
- package/dist/execution-service.d.ts.map +1 -1
- package/dist/fabric-exec-tool.d.ts.map +1 -1
- package/dist/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-runtime-state.js +883 -367
- package/dist/fabric-runtime-state.js.map +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +116 -18
- package/dist/index.js.map +3 -3
- package/dist/memory/discovery.d.ts +28 -14
- package/dist/memory/discovery.d.ts.map +1 -1
- package/dist/memory/discovery.js +9 -5
- package/dist/protocol.d.ts +5 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +1 -1
- package/dist/providers/mcp-descriptor-cache.d.ts +2 -0
- package/dist/providers/mcp-descriptor-cache.d.ts.map +1 -1
- package/dist/providers/mcp-provider.d.ts +4 -2
- package/dist/providers/mcp-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.js +2 -2
- package/dist/providers/omp-tools-provider.d.ts +1 -0
- package/dist/providers/omp-tools-provider.d.ts.map +1 -1
- package/dist/residency/host.js +5 -5
- package/dist/residency/omp-entry.js +5 -5
- package/dist/runtime/core-override-guest-types.js +1 -1
- package/dist/runtime/guest-types.d.ts +2 -2
- package/dist/runtime/guest-types.d.ts.map +1 -1
- package/dist/runtime/guest-types.js +1 -1
- package/dist/runtime/node-process-child-source.d.ts.map +1 -1
- package/dist/runtime/node-process-runtime.d.ts.map +1 -1
- package/dist/runtime/node-process-runtime.js +4 -2
- package/dist/runtime/node-process-runtime.js.map +2 -2
- package/dist/runtime/quickjs-runtime.d.ts +6 -1
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
- package/dist/runtime/quickjs-runtime.js +1 -1
- package/dist/speculation/guest-args.d.ts +2 -0
- package/dist/speculation/guest-args.d.ts.map +1 -0
- package/dist/speculation/scanner.d.ts.map +1 -1
- package/dist/speculation/scanner.js +312 -14
- package/dist/speculation/scanner.js.map +3 -3
- package/dist/speculation/store.d.ts +2 -0
- package/dist/speculation/store.d.ts.map +1 -1
- package/dist/speculation/stream-tap.d.ts +1 -0
- package/dist/speculation/stream-tap.d.ts.map +1 -1
- package/dist/speculation/summary.d.ts +4 -0
- package/dist/speculation/summary.d.ts.map +1 -0
- package/dist/speculation/types.d.ts +4 -0
- package/dist/speculation/types.d.ts.map +1 -1
- package/dist/speculation/warmup.d.ts +17 -0
- package/dist/speculation/warmup.d.ts.map +1 -0
- package/dist/ui/settings.d.ts.map +1 -1
- package/dist/ui/settings.js +6 -6
- package/dist/ui/settings.js.map +2 -2
- package/docs/agents.md +1 -1
- package/docs/compaction.md +2 -2
- package/docs/configuration.md +26 -12
- package/docs/interface.md +2 -2
- package/docs/speculation.md +11 -6
- package/package.json +3 -2
- package/dist/chunks/chunk-5GTPD4BA.js.map +0 -7
- package/dist/chunks/chunk-7BIA5BJN.js +0 -112
- package/dist/chunks/chunk-7BIA5BJN.js.map +0 -7
- package/dist/chunks/chunk-GKOFZ76R.js.map +0 -7
- package/dist/chunks/chunk-JP4LIZFT.js.map +0 -7
- package/dist/chunks/chunk-OPTP4PSE.js.map +0 -7
- package/dist/chunks/chunk-ROKMBLGN.js.map +0 -7
- package/dist/chunks/chunk-SXMWV447.js.map +0 -7
- package/dist/chunks/chunk-T6OAX4FO.js.map +0 -7
- package/dist/chunks/chunk-UPCARIJP.js.map +0 -7
- package/dist/chunks/chunk-ZTM45GH5.js.map +0 -7
- /package/dist/chunks/{chunk-4LEDA76O.js.map → chunk-HAJPYJPY.js.map} +0 -0
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
MemoryProvider,
|
|
12
12
|
actionArgNormalizer,
|
|
13
13
|
uniqueDeclaredKeyForSpelling
|
|
14
|
-
} from "./chunks/chunk-
|
|
14
|
+
} from "./chunks/chunk-3TWC6XOS.js";
|
|
15
15
|
import "./chunks/chunk-2KEWFW56.js";
|
|
16
16
|
import "./chunks/chunk-U5FYOMG5.js";
|
|
17
17
|
import {
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
FabricAutoApprovalClassifier,
|
|
23
23
|
FabricProviderComponentManifest,
|
|
24
24
|
FabricSessionApprovals,
|
|
25
|
+
FabricSpeculationStreamTap,
|
|
25
26
|
MainAgentController,
|
|
26
27
|
PrewalkController,
|
|
27
28
|
PrewalkDriftTracker,
|
|
@@ -32,7 +33,7 @@ import {
|
|
|
32
33
|
repairFabricGuestCode,
|
|
33
34
|
resolveFabricIdentity,
|
|
34
35
|
runFabricHandoffAtBoundary
|
|
35
|
-
} from "./chunks/chunk-
|
|
36
|
+
} from "./chunks/chunk-DOKANNFC.js";
|
|
36
37
|
import "./chunks/chunk-7VIQNUPS.js";
|
|
37
38
|
import {
|
|
38
39
|
AgentTranscriptReader,
|
|
@@ -49,7 +50,7 @@ import {
|
|
|
49
50
|
repairActionName,
|
|
50
51
|
setActiveCompiledSurface,
|
|
51
52
|
setActiveRepairCompiler
|
|
52
|
-
} from "./chunks/chunk-
|
|
53
|
+
} from "./chunks/chunk-2LGLDM34.js";
|
|
53
54
|
import {
|
|
54
55
|
formatFabricEffectConflict
|
|
55
56
|
} from "./chunks/chunk-LMAVZN7J.js";
|
|
@@ -62,14 +63,14 @@ import {
|
|
|
62
63
|
withExclusiveFileLockAsync
|
|
63
64
|
} from "./chunks/chunk-YWEXP724.js";
|
|
64
65
|
import "./chunks/chunk-4A4MVZQW.js";
|
|
65
|
-
import "./chunks/chunk-
|
|
66
|
+
import "./chunks/chunk-NX4SNIMR.js";
|
|
66
67
|
import "./chunks/chunk-6QBPSZJ5.js";
|
|
67
68
|
import {
|
|
68
69
|
FABRIC_COMPONENT_DISCOVER_EVENT,
|
|
69
70
|
FABRIC_PROVIDER_DISCOVER_EVENT,
|
|
70
71
|
FABRIC_TOOL_RESULT_PROXY_KIND,
|
|
71
72
|
readFabricToolResultProxyDetailsV1
|
|
72
|
-
} from "./chunks/chunk-
|
|
73
|
+
} from "./chunks/chunk-RBA54WC7.js";
|
|
73
74
|
import {
|
|
74
75
|
ActorDirectory,
|
|
75
76
|
ActorRegistryOwnershipError,
|
|
@@ -93,27 +94,27 @@ import {
|
|
|
93
94
|
resolveAgentCwd,
|
|
94
95
|
resolveOmpBinary,
|
|
95
96
|
validateAgentCwdRequest
|
|
96
|
-
} from "./chunks/chunk-
|
|
97
|
+
} from "./chunks/chunk-FFWALVBN.js";
|
|
97
98
|
import "./chunks/chunk-VPPIJRNZ.js";
|
|
98
99
|
import {
|
|
99
100
|
executeFile,
|
|
100
101
|
processIsAlive,
|
|
101
102
|
spawnDetached
|
|
102
|
-
} from "./chunks/chunk-
|
|
103
|
+
} from "./chunks/chunk-JZWLICMS.js";
|
|
103
104
|
import "./chunks/chunk-CT2AJ2UI.js";
|
|
104
105
|
import {
|
|
105
|
-
checkedHandoffCompaction
|
|
106
|
-
|
|
107
|
-
} from "./chunks/chunk-OPTP4PSE.js";
|
|
106
|
+
checkedHandoffCompaction
|
|
107
|
+
} from "./chunks/chunk-YPYVUGON.js";
|
|
108
108
|
import {
|
|
109
109
|
DEFAULT_FABRIC_CONFIG,
|
|
110
110
|
FUZZY_RESOLUTION_MARKERS,
|
|
111
111
|
MAX_AGENT_TIMEOUT_MS,
|
|
112
112
|
MIN_AGENT_TIMEOUT_MS,
|
|
113
113
|
loadFabricConfig,
|
|
114
|
+
resolveAgentDir,
|
|
114
115
|
resolveAvailableOmpModel,
|
|
115
116
|
resolveFabricModel
|
|
116
|
-
} from "./chunks/chunk-
|
|
117
|
+
} from "./chunks/chunk-IFNDRFW7.js";
|
|
117
118
|
import {
|
|
118
119
|
FABRIC_ACTOR_HOST_EVENTS,
|
|
119
120
|
isFabricActorHostEvent,
|
|
@@ -170,7 +171,7 @@ import {
|
|
|
170
171
|
} from "./chunks/chunk-6N4XGAZY.js";
|
|
171
172
|
|
|
172
173
|
// src/fabric-runtime-state.ts
|
|
173
|
-
import
|
|
174
|
+
import path16 from "node:path";
|
|
174
175
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
175
176
|
|
|
176
177
|
// src/actors/global-registry.ts
|
|
@@ -1039,8 +1040,8 @@ var MAX_CHILDREN_PER_COMPONENT = 256;
|
|
|
1039
1040
|
var componentLifecycleStorage;
|
|
1040
1041
|
var componentLifecycleStorageTask;
|
|
1041
1042
|
var lifecycleStorage = () => {
|
|
1042
|
-
componentLifecycleStorageTask ??= import("node:async_hooks").then(({ AsyncLocalStorage }) => {
|
|
1043
|
-
componentLifecycleStorage ??= new
|
|
1043
|
+
componentLifecycleStorageTask ??= import("node:async_hooks").then(({ AsyncLocalStorage: AsyncLocalStorage2 }) => {
|
|
1044
|
+
componentLifecycleStorage ??= new AsyncLocalStorage2();
|
|
1044
1045
|
return componentLifecycleStorage;
|
|
1045
1046
|
});
|
|
1046
1047
|
return componentLifecycleStorageTask;
|
|
@@ -2217,10 +2218,10 @@ var FabricComponentSupervisor = class {
|
|
|
2217
2218
|
adjacent.set(edge.from, targets);
|
|
2218
2219
|
}
|
|
2219
2220
|
const cycles = /* @__PURE__ */ new Map();
|
|
2220
|
-
const visit = (node,
|
|
2221
|
+
const visit = (node, path17, positions) => {
|
|
2221
2222
|
const position = positions.get(node);
|
|
2222
2223
|
if (position !== void 0) {
|
|
2223
|
-
const cycle =
|
|
2224
|
+
const cycle = path17.slice(position);
|
|
2224
2225
|
const rotations = cycle.map((_, index) => [
|
|
2225
2226
|
...cycle.slice(index),
|
|
2226
2227
|
...cycle.slice(0, index)
|
|
@@ -2230,10 +2231,10 @@ var FabricComponentSupervisor = class {
|
|
|
2230
2231
|
cycles.set(canonical.join("\0"), canonical);
|
|
2231
2232
|
return;
|
|
2232
2233
|
}
|
|
2233
|
-
if (
|
|
2234
|
-
const nextPositions = new Map(positions).set(node,
|
|
2234
|
+
if (path17.length > this.#components.size) return;
|
|
2235
|
+
const nextPositions = new Map(positions).set(node, path17.length);
|
|
2235
2236
|
for (const target of adjacent.get(node) ?? []) {
|
|
2236
|
-
visit(target, [...
|
|
2237
|
+
visit(target, [...path17, node], nextPositions);
|
|
2237
2238
|
}
|
|
2238
2239
|
};
|
|
2239
2240
|
for (const id of this.#components.keys()) visit(id, [], /* @__PURE__ */ new Map());
|
|
@@ -2562,13 +2563,53 @@ var checkedPreserve = (value) => {
|
|
|
2562
2563
|
}
|
|
2563
2564
|
return [...value];
|
|
2564
2565
|
};
|
|
2566
|
+
var finite = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
2567
|
+
var UNKNOWN_USAGE = {
|
|
2568
|
+
known: false,
|
|
2569
|
+
tokens: null,
|
|
2570
|
+
contextWindow: null,
|
|
2571
|
+
percent: null,
|
|
2572
|
+
remainingTokens: null
|
|
2573
|
+
};
|
|
2574
|
+
var readCompactContextUsage = (context) => {
|
|
2575
|
+
const modelWindow = finite(context?.model?.contextWindow);
|
|
2576
|
+
let usage;
|
|
2577
|
+
try {
|
|
2578
|
+
usage = context?.getContextUsage?.();
|
|
2579
|
+
} catch {
|
|
2580
|
+
usage = void 0;
|
|
2581
|
+
}
|
|
2582
|
+
if (!usage) return { ...UNKNOWN_USAGE, contextWindow: modelWindow };
|
|
2583
|
+
const tokens = finite(usage.tokens);
|
|
2584
|
+
const contextWindow = finite(usage.contextWindow) ?? modelWindow;
|
|
2585
|
+
const percent = finite(usage.percent) ?? (tokens !== null && contextWindow !== null && contextWindow > 0 ? tokens / contextWindow * 100 : null);
|
|
2586
|
+
return {
|
|
2587
|
+
known: tokens !== null || percent !== null,
|
|
2588
|
+
tokens,
|
|
2589
|
+
contextWindow,
|
|
2590
|
+
percent,
|
|
2591
|
+
remainingTokens: tokens !== null && contextWindow !== null ? Math.max(0, contextWindow - tokens) : null
|
|
2592
|
+
};
|
|
2593
|
+
};
|
|
2594
|
+
var sessionIdOf = (context) => {
|
|
2595
|
+
try {
|
|
2596
|
+
const id = context?.sessionManager?.getSessionId?.();
|
|
2597
|
+
return typeof id === "string" && id.length > 0 ? id : void 0;
|
|
2598
|
+
} catch {
|
|
2599
|
+
return void 0;
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2565
2602
|
var CompactController = class {
|
|
2566
2603
|
#pending;
|
|
2567
2604
|
#last;
|
|
2568
2605
|
#inFlight;
|
|
2606
|
+
#restoredFor;
|
|
2607
|
+
#restored;
|
|
2569
2608
|
#hooks;
|
|
2570
|
-
|
|
2609
|
+
#options;
|
|
2610
|
+
constructor(hooks = {}, options = {}) {
|
|
2571
2611
|
this.#hooks = hooks;
|
|
2612
|
+
this.#options = options;
|
|
2572
2613
|
}
|
|
2573
2614
|
// Record a pending compaction intent. A single slot: a new request replaces
|
|
2574
2615
|
// any pending one, keeping the latest instructions.
|
|
@@ -2597,10 +2638,39 @@ var CompactController = class {
|
|
|
2597
2638
|
cancel() {
|
|
2598
2639
|
this.#pending = void 0;
|
|
2599
2640
|
}
|
|
2600
|
-
|
|
2641
|
+
#settledOutcome(context) {
|
|
2642
|
+
if (this.#last) return this.#last;
|
|
2643
|
+
const store = this.#options.outcomes;
|
|
2644
|
+
if (!store) return void 0;
|
|
2645
|
+
const sessionId = sessionIdOf(context);
|
|
2646
|
+
if (sessionId === void 0) return void 0;
|
|
2647
|
+
if (this.#restoredFor !== sessionId) {
|
|
2648
|
+
this.#restoredFor = sessionId;
|
|
2649
|
+
this.#restored = store.load(sessionId);
|
|
2650
|
+
}
|
|
2651
|
+
return this.#restored;
|
|
2652
|
+
}
|
|
2653
|
+
#settle(context, outcome) {
|
|
2654
|
+
this.#last = outcome;
|
|
2655
|
+
this.#restoredFor = void 0;
|
|
2656
|
+
this.#restored = void 0;
|
|
2657
|
+
const store = this.#options.outcomes;
|
|
2658
|
+
const sessionId = store ? sessionIdOf(context) : void 0;
|
|
2659
|
+
if (store && sessionId !== void 0) store.save(sessionId, outcome);
|
|
2660
|
+
this.#hooks.onCommit?.(outcome);
|
|
2661
|
+
}
|
|
2662
|
+
status(context) {
|
|
2663
|
+
const settings = this.#options.settings?.();
|
|
2664
|
+
const last = this.#settledOutcome(context);
|
|
2665
|
+
const model = context?.model;
|
|
2666
|
+
const sessionId = sessionIdOf(context);
|
|
2601
2667
|
return {
|
|
2602
2668
|
...this.#pending ? { pending: this.#pending } : {},
|
|
2603
|
-
...
|
|
2669
|
+
...last ? { last } : {},
|
|
2670
|
+
context: readCompactContextUsage(context),
|
|
2671
|
+
...settings ? { engine: settings.engine, targetContextRatio: settings.targetContextRatio } : {},
|
|
2672
|
+
...model ? { model: `${model.provider}/${model.id}` } : {},
|
|
2673
|
+
...sessionId !== void 0 ? { sessionId } : {}
|
|
2604
2674
|
};
|
|
2605
2675
|
}
|
|
2606
2676
|
async maybeCommit(context) {
|
|
@@ -2616,23 +2686,32 @@ var CompactController = class {
|
|
|
2616
2686
|
const clearCommittedIntent = () => {
|
|
2617
2687
|
if (this.#pending === committing) this.#pending = void 0;
|
|
2618
2688
|
};
|
|
2689
|
+
const before = readCompactContextUsage(context);
|
|
2619
2690
|
const completion = (async () => {
|
|
2620
2691
|
try {
|
|
2621
2692
|
await context.compact(instructions);
|
|
2622
2693
|
clearCommittedIntent();
|
|
2623
|
-
|
|
2624
|
-
|
|
2694
|
+
const after = readCompactContextUsage(context);
|
|
2695
|
+
const measured = before.tokens !== null && after.tokens !== null;
|
|
2696
|
+
this.#settle(context, {
|
|
2697
|
+
at: Date.now(),
|
|
2698
|
+
requestedBy,
|
|
2699
|
+
status: measured && after.tokens >= before.tokens ? "skipped" : "committed",
|
|
2700
|
+
...before.tokens !== null ? { tokensBefore: before.tokens } : {},
|
|
2701
|
+
...after.tokens !== null ? { estimatedTokensAfter: after.tokens } : {},
|
|
2702
|
+
...measured && after.tokens >= before.tokens ? { error: "Compaction ran but freed no context tokens" } : {}
|
|
2703
|
+
});
|
|
2625
2704
|
} catch (error) {
|
|
2626
2705
|
const message2 = error instanceof Error ? error.message : "Compaction failed";
|
|
2627
2706
|
clearCommittedIntent();
|
|
2628
2707
|
const cancelled = message2 === "Compaction cancelled" || message2 === "Already compacted";
|
|
2629
|
-
this.#
|
|
2708
|
+
this.#settle(context, {
|
|
2630
2709
|
at: Date.now(),
|
|
2631
2710
|
requestedBy,
|
|
2632
2711
|
status: cancelled ? "cancelled" : "failed",
|
|
2712
|
+
...before.tokens !== null ? { tokensBefore: before.tokens } : {},
|
|
2633
2713
|
error: message2
|
|
2634
|
-
};
|
|
2635
|
-
this.#hooks.onCommit?.(this.#last);
|
|
2714
|
+
});
|
|
2636
2715
|
}
|
|
2637
2716
|
})();
|
|
2638
2717
|
this.#inFlight = completion;
|
|
@@ -2644,6 +2723,80 @@ var CompactController = class {
|
|
|
2644
2723
|
}
|
|
2645
2724
|
};
|
|
2646
2725
|
|
|
2726
|
+
// src/core/compact-outcome-store.ts
|
|
2727
|
+
import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
2728
|
+
import path2 from "node:path";
|
|
2729
|
+
var OUTCOME_DIR = ["fabric", "compact"];
|
|
2730
|
+
var MAX_OUTCOME_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
2731
|
+
var sessionFileName = (sessionId) => {
|
|
2732
|
+
const safe = sessionId.replace(/[^A-Za-z0-9._-]/g, "");
|
|
2733
|
+
return safe.length > 0 && safe.length <= 128 ? `${safe}.json` : void 0;
|
|
2734
|
+
};
|
|
2735
|
+
var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2736
|
+
var nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2737
|
+
var decodeOutcome = (raw) => {
|
|
2738
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
2739
|
+
const record = raw;
|
|
2740
|
+
const at = finiteNumber(record.at);
|
|
2741
|
+
const requestedBy = nonEmptyString(record.requestedBy);
|
|
2742
|
+
const status = record.status;
|
|
2743
|
+
if (at === void 0 || requestedBy === void 0) return void 0;
|
|
2744
|
+
if (status !== "committed" && status !== "cancelled" && status !== "failed" && status !== "skipped") {
|
|
2745
|
+
return void 0;
|
|
2746
|
+
}
|
|
2747
|
+
const summary = nonEmptyString(record.summary);
|
|
2748
|
+
const error = nonEmptyString(record.error);
|
|
2749
|
+
const tokensBefore = finiteNumber(record.tokensBefore);
|
|
2750
|
+
const estimatedTokensAfter = finiteNumber(record.estimatedTokensAfter);
|
|
2751
|
+
return {
|
|
2752
|
+
at,
|
|
2753
|
+
requestedBy,
|
|
2754
|
+
status,
|
|
2755
|
+
...summary !== void 0 ? { summary } : {},
|
|
2756
|
+
...tokensBefore !== void 0 ? { tokensBefore } : {},
|
|
2757
|
+
...estimatedTokensAfter !== void 0 ? { estimatedTokensAfter } : {},
|
|
2758
|
+
...error !== void 0 ? { error } : {},
|
|
2759
|
+
persisted: true
|
|
2760
|
+
};
|
|
2761
|
+
};
|
|
2762
|
+
var pruneStale = (dir, now) => {
|
|
2763
|
+
for (const entry of readdirSync(dir)) {
|
|
2764
|
+
if (!entry.endsWith(".json")) continue;
|
|
2765
|
+
const target = path2.join(dir, entry);
|
|
2766
|
+
try {
|
|
2767
|
+
if (now - statSync(target).mtimeMs > MAX_OUTCOME_AGE_MS) rmSync(target, { force: true });
|
|
2768
|
+
} catch {
|
|
2769
|
+
continue;
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
};
|
|
2773
|
+
var fileCompactOutcomeStore = (agentDir = resolveAgentDir) => ({
|
|
2774
|
+
load(sessionId) {
|
|
2775
|
+
const name = sessionFileName(sessionId);
|
|
2776
|
+
if (name === void 0) return void 0;
|
|
2777
|
+
try {
|
|
2778
|
+
return decodeOutcome(JSON.parse(readFileSync(path2.join(agentDir(), ...OUTCOME_DIR, name), "utf8")));
|
|
2779
|
+
} catch {
|
|
2780
|
+
return void 0;
|
|
2781
|
+
}
|
|
2782
|
+
},
|
|
2783
|
+
save(sessionId, outcome) {
|
|
2784
|
+
const name = sessionFileName(sessionId);
|
|
2785
|
+
if (name === void 0) return;
|
|
2786
|
+
try {
|
|
2787
|
+
const dir = path2.join(agentDir(), ...OUTCOME_DIR);
|
|
2788
|
+
mkdirSync(dir, { recursive: true });
|
|
2789
|
+
const target = path2.join(dir, name);
|
|
2790
|
+
const staging = `${target}.${process.pid}.tmp`;
|
|
2791
|
+
writeFileSync(staging, JSON.stringify(outcome), "utf8");
|
|
2792
|
+
renameSync(staging, target);
|
|
2793
|
+
pruneStale(dir, Date.now());
|
|
2794
|
+
} catch {
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
|
|
2647
2800
|
// src/core/tool-result-proxy.ts
|
|
2648
2801
|
var nativeLifecycleProviders = /* @__PURE__ */ new Set(["omp", "extensions"]);
|
|
2649
2802
|
var textFromContent = (content) => content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
@@ -2793,6 +2946,17 @@ var FabricExecutionService = class {
|
|
|
2793
2946
|
},
|
|
2794
2947
|
...this.#capabilityView ? { capabilityView: this.#capabilityView } : {}
|
|
2795
2948
|
});
|
|
2949
|
+
const proxyNames = {
|
|
2950
|
+
...guestTypeSources.extensionTools?.length ? { extensions: guestTypeSources.extensionTools.map((tool) => tool.name) } : {},
|
|
2951
|
+
...guestTypeSources.mcpServers?.length ? {
|
|
2952
|
+
mcp: Object.fromEntries(
|
|
2953
|
+
guestTypeSources.mcpServers.map((entry) => [
|
|
2954
|
+
entry.server,
|
|
2955
|
+
entry.tools.map((tool) => tool.name)
|
|
2956
|
+
])
|
|
2957
|
+
)
|
|
2958
|
+
} : {}
|
|
2959
|
+
};
|
|
2796
2960
|
const coreOverrideDeclarations = effectiveFullCodeMode ? dependencies.buildCoreOverrideGuestDeclarations(
|
|
2797
2961
|
this.capturedTools?.list().map((entry) => ({
|
|
2798
2962
|
name: entry.name,
|
|
@@ -3263,6 +3427,7 @@ var FabricExecutionService = class {
|
|
|
3263
3427
|
...checked.javascript ? { transpiledCode: checked.javascript } : {},
|
|
3264
3428
|
...checked.sourceMap ? { transpiledSourceMap: checked.sourceMap } : {},
|
|
3265
3429
|
...options.payloads ? { payloads: options.payloads } : {},
|
|
3430
|
+
...Object.keys(proxyNames).length > 0 ? { proxyNames } : {},
|
|
3266
3431
|
...options.tokenBudget !== void 0 ? { tokenBudget: options.tokenBudget } : {},
|
|
3267
3432
|
...options.signal ? { signal: options.signal } : {}
|
|
3268
3433
|
}
|
|
@@ -3370,7 +3535,7 @@ var actionAliasCandidate = (provider, actionName, declared) => {
|
|
|
3370
3535
|
|
|
3371
3536
|
// src/repairs/store.ts
|
|
3372
3537
|
import fs2 from "node:fs";
|
|
3373
|
-
import
|
|
3538
|
+
import path3 from "node:path";
|
|
3374
3539
|
|
|
3375
3540
|
// src/repairs/types.ts
|
|
3376
3541
|
var REPAIR_TABLE_VERSION = 1;
|
|
@@ -3391,8 +3556,8 @@ var emptyRepairTable = (catalogDigest, now = (/* @__PURE__ */ new Date()).toISOS
|
|
|
3391
3556
|
|
|
3392
3557
|
// src/repairs/store.ts
|
|
3393
3558
|
var LOCK_TIMEOUT_MESSAGE = "Timed out waiting for the Fabric repair table lock";
|
|
3394
|
-
var repairsDirectory = (agentDir) =>
|
|
3395
|
-
var currentPath = (directory) =>
|
|
3559
|
+
var repairsDirectory = (agentDir) => path3.join(agentDir, "fabric", "repairs");
|
|
3560
|
+
var currentPath = (directory) => path3.join(directory, "current.json");
|
|
3396
3561
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3397
3562
|
var errorCode = (error) => isRecord(error) && typeof error.code === "string" ? error.code : void 0;
|
|
3398
3563
|
var parseRepair = (value) => {
|
|
@@ -3736,7 +3901,7 @@ var isSpeculationEligible = (action, mcpAllowlist) => {
|
|
|
3736
3901
|
|
|
3737
3902
|
// src/speculation/freshness.ts
|
|
3738
3903
|
import fs3 from "node:fs";
|
|
3739
|
-
import
|
|
3904
|
+
import path4 from "node:path";
|
|
3740
3905
|
var statSignature = (filePath) => {
|
|
3741
3906
|
try {
|
|
3742
3907
|
const stats = fs3.statSync(filePath);
|
|
@@ -3750,7 +3915,7 @@ var signatureEquals = (left, right) => left === "missing" || right === "missing"
|
|
|
3750
3915
|
var readFreshness = (args, cwd) => {
|
|
3751
3916
|
const target = args.path;
|
|
3752
3917
|
if (typeof target !== "string" || target.length === 0) return void 0;
|
|
3753
|
-
const resolved =
|
|
3918
|
+
const resolved = path4.resolve(cwd, target);
|
|
3754
3919
|
const snapshot = statSignature(resolved);
|
|
3755
3920
|
if (snapshot === "error") return void 0;
|
|
3756
3921
|
return () => {
|
|
@@ -3770,6 +3935,7 @@ var FabricSpeculationStore = class _FabricSpeculationStore {
|
|
|
3770
3935
|
#stats = {
|
|
3771
3936
|
launched: 0,
|
|
3772
3937
|
served: 0,
|
|
3938
|
+
absent: 0,
|
|
3773
3939
|
epochInvalidated: 0,
|
|
3774
3940
|
freshnessInvalidated: 0,
|
|
3775
3941
|
failed: 0,
|
|
@@ -3779,6 +3945,7 @@ var FabricSpeculationStore = class _FabricSpeculationStore {
|
|
|
3779
3945
|
#maxConcurrent;
|
|
3780
3946
|
#maxEntries;
|
|
3781
3947
|
#entryTtlMs;
|
|
3948
|
+
#launching = /* @__PURE__ */ new Map();
|
|
3782
3949
|
constructor(config) {
|
|
3783
3950
|
this.#maxConcurrent = config.maxConcurrent;
|
|
3784
3951
|
this.#maxEntries = config.maxEntries;
|
|
@@ -3799,12 +3966,39 @@ ${ref}
|
|
|
3799
3966
|
${stableJsonHash(preparedArgs)}
|
|
3800
3967
|
${bindingToken}`;
|
|
3801
3968
|
}
|
|
3969
|
+
beginLaunch(parentToolCallId) {
|
|
3970
|
+
const pending = this.#launching.get(parentToolCallId) ?? { count: 0, waiters: [] };
|
|
3971
|
+
pending.count += 1;
|
|
3972
|
+
this.#launching.set(parentToolCallId, pending);
|
|
3973
|
+
let released = false;
|
|
3974
|
+
return () => {
|
|
3975
|
+
if (released) return;
|
|
3976
|
+
released = true;
|
|
3977
|
+
pending.count -= 1;
|
|
3978
|
+
if (pending.count > 0) return;
|
|
3979
|
+
this.#launching.delete(parentToolCallId);
|
|
3980
|
+
for (const waiter of pending.waiters.splice(0)) waiter();
|
|
3981
|
+
};
|
|
3982
|
+
}
|
|
3983
|
+
async settleLaunches(parentToolCallId, timeoutMs) {
|
|
3984
|
+
const pending = this.#launching.get(parentToolCallId);
|
|
3985
|
+
if (!pending || pending.count === 0) return;
|
|
3986
|
+
await new Promise((resolvePromise) => {
|
|
3987
|
+
const timer = setTimeout(resolvePromise, timeoutMs);
|
|
3988
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
3989
|
+
pending.waiters.push(() => {
|
|
3990
|
+
clearTimeout(timer);
|
|
3991
|
+
resolvePromise();
|
|
3992
|
+
});
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3802
3995
|
/**
|
|
3803
3996
|
* Register and start a speculative invocation. Returns false when at
|
|
3804
3997
|
* capacity; the candidate is dropped silently (a miss costs nothing, the
|
|
3805
3998
|
* real call executes normally later).
|
|
3806
3999
|
*/
|
|
3807
4000
|
launch(parentToolCallId, ref, preparedArgs, execute, freshness, replay, bindingToken) {
|
|
4001
|
+
this.#releaseLaunch(parentToolCallId);
|
|
3808
4002
|
this.#sweepExpired(Date.now());
|
|
3809
4003
|
if (this.#entries.size >= this.#maxEntries || this.#inFlightCount() >= this.#maxConcurrent) {
|
|
3810
4004
|
this.#stats.skipped += 1;
|
|
@@ -3838,6 +4032,7 @@ ${bindingToken}`;
|
|
|
3838
4032
|
const key = _FabricSpeculationStore.key(parentToolCallId, ref, preparedArgs, bindingToken);
|
|
3839
4033
|
const entry = this.#entries.get(key);
|
|
3840
4034
|
if (!entry || entry.parentToolCallId !== parentToolCallId) {
|
|
4035
|
+
this.#stats.absent += 1;
|
|
3841
4036
|
return { hit: false, reason: "absent" };
|
|
3842
4037
|
}
|
|
3843
4038
|
this.#entries.delete(key);
|
|
@@ -3872,6 +4067,19 @@ ${bindingToken}`;
|
|
|
3872
4067
|
reset() {
|
|
3873
4068
|
for (const entry of this.#entries.values()) entry.controller.abort();
|
|
3874
4069
|
this.#entries.clear();
|
|
4070
|
+
for (const pending of this.#launching.values()) {
|
|
4071
|
+
pending.count = 0;
|
|
4072
|
+
for (const waiter of pending.waiters.splice(0)) waiter();
|
|
4073
|
+
}
|
|
4074
|
+
this.#launching.clear();
|
|
4075
|
+
}
|
|
4076
|
+
#releaseLaunch(parentToolCallId) {
|
|
4077
|
+
const pending = this.#launching.get(parentToolCallId);
|
|
4078
|
+
if (!pending) return;
|
|
4079
|
+
pending.count -= 1;
|
|
4080
|
+
if (pending.count > 0) return;
|
|
4081
|
+
this.#launching.delete(parentToolCallId);
|
|
4082
|
+
for (const waiter of pending.waiters.splice(0)) waiter();
|
|
3875
4083
|
}
|
|
3876
4084
|
#inFlightCount() {
|
|
3877
4085
|
let count = 0;
|
|
@@ -3890,201 +4098,6 @@ ${bindingToken}`;
|
|
|
3890
4098
|
}
|
|
3891
4099
|
};
|
|
3892
4100
|
|
|
3893
|
-
// src/speculation/partial-json.ts
|
|
3894
|
-
var CODE_KEY_PATTERN = /"code"\s*:\s*"/;
|
|
3895
|
-
var ESCAPES = {
|
|
3896
|
-
'"': '"',
|
|
3897
|
-
"\\": "\\",
|
|
3898
|
-
"/": "/",
|
|
3899
|
-
b: "\b",
|
|
3900
|
-
f: "\f",
|
|
3901
|
-
n: "\n",
|
|
3902
|
-
r: "\r",
|
|
3903
|
-
t: " "
|
|
3904
|
-
};
|
|
3905
|
-
var PartialCodeFieldExtractor = class {
|
|
3906
|
-
#raw = "";
|
|
3907
|
-
#codeStart = -1;
|
|
3908
|
-
#cursor = 0;
|
|
3909
|
-
#decoded = "";
|
|
3910
|
-
#complete = false;
|
|
3911
|
-
#failed = false;
|
|
3912
|
-
#maxBytes;
|
|
3913
|
-
constructor(maxBytes) {
|
|
3914
|
-
this.#maxBytes = maxBytes;
|
|
3915
|
-
}
|
|
3916
|
-
get complete() {
|
|
3917
|
-
return this.#complete;
|
|
3918
|
-
}
|
|
3919
|
-
/** Decoded `code` content so far, or undefined before the key appears. */
|
|
3920
|
-
get code() {
|
|
3921
|
-
return this.#codeStart === -1 ? void 0 : this.#decoded;
|
|
3922
|
-
}
|
|
3923
|
-
push(delta) {
|
|
3924
|
-
if (this.#complete || this.#failed) return;
|
|
3925
|
-
if (this.#raw.length + delta.length > this.#maxBytes) {
|
|
3926
|
-
this.#failed = true;
|
|
3927
|
-
return;
|
|
3928
|
-
}
|
|
3929
|
-
this.#raw += delta;
|
|
3930
|
-
if (this.#codeStart === -1) {
|
|
3931
|
-
const match = CODE_KEY_PATTERN.exec(this.#raw);
|
|
3932
|
-
if (!match) return;
|
|
3933
|
-
this.#codeStart = match.index + match[0].length;
|
|
3934
|
-
this.#cursor = this.#codeStart;
|
|
3935
|
-
}
|
|
3936
|
-
const raw = this.#raw;
|
|
3937
|
-
while (this.#cursor < raw.length) {
|
|
3938
|
-
const ch = raw[this.#cursor];
|
|
3939
|
-
if (ch === '"') {
|
|
3940
|
-
this.#complete = true;
|
|
3941
|
-
this.#cursor = raw.length;
|
|
3942
|
-
return;
|
|
3943
|
-
}
|
|
3944
|
-
if (ch === "\\") {
|
|
3945
|
-
if (this.#cursor + 1 >= raw.length) return;
|
|
3946
|
-
const esc = raw[this.#cursor + 1];
|
|
3947
|
-
if (esc === "u") {
|
|
3948
|
-
if (this.#cursor + 5 >= raw.length) return;
|
|
3949
|
-
const hex = raw.slice(this.#cursor + 2, this.#cursor + 6);
|
|
3950
|
-
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
3951
|
-
this.#failed = true;
|
|
3952
|
-
return;
|
|
3953
|
-
}
|
|
3954
|
-
this.#decoded += String.fromCharCode(parseInt(hex, 16));
|
|
3955
|
-
this.#cursor += 6;
|
|
3956
|
-
continue;
|
|
3957
|
-
}
|
|
3958
|
-
const mapped = ESCAPES[esc];
|
|
3959
|
-
if (mapped === void 0) {
|
|
3960
|
-
this.#failed = true;
|
|
3961
|
-
return;
|
|
3962
|
-
}
|
|
3963
|
-
this.#decoded += mapped;
|
|
3964
|
-
this.#cursor += 2;
|
|
3965
|
-
continue;
|
|
3966
|
-
}
|
|
3967
|
-
if (ch < " ") {
|
|
3968
|
-
this.#failed = true;
|
|
3969
|
-
return;
|
|
3970
|
-
}
|
|
3971
|
-
this.#decoded += ch;
|
|
3972
|
-
this.#cursor += 1;
|
|
3973
|
-
}
|
|
3974
|
-
}
|
|
3975
|
-
};
|
|
3976
|
-
|
|
3977
|
-
// src/speculation/stream-tap.ts
|
|
3978
|
-
var toolCallBlock = (partial, contentIndex) => {
|
|
3979
|
-
const content = partial?.content;
|
|
3980
|
-
if (!Array.isArray(content)) return {};
|
|
3981
|
-
const block = content[contentIndex];
|
|
3982
|
-
if (!block || typeof block !== "object") return {};
|
|
3983
|
-
const record = block;
|
|
3984
|
-
if (record.type !== "toolCall") return {};
|
|
3985
|
-
return {
|
|
3986
|
-
...typeof record.name === "string" && record.name ? { name: record.name } : {},
|
|
3987
|
-
...typeof record.id === "string" && record.id ? { id: record.id } : {}
|
|
3988
|
-
};
|
|
3989
|
-
};
|
|
3990
|
-
var PARSE_INTERVAL_MS = 50;
|
|
3991
|
-
var FabricSpeculationStreamTap = class {
|
|
3992
|
-
#options;
|
|
3993
|
-
#streams = /* @__PURE__ */ new Map();
|
|
3994
|
-
// The scanner depends on the TypeScript compiler; the factory arrives through
|
|
3995
|
-
// a lazy dynamic import so session startup never pays for it. Streams opened
|
|
3996
|
-
// before the factory lands are caught up in full (extractors buffer the
|
|
3997
|
-
// whole decoded prefix, so no candidate is lost, only delayed).
|
|
3998
|
-
#createScanner;
|
|
3999
|
-
#lastParseAt = 0;
|
|
4000
|
-
constructor(options) {
|
|
4001
|
-
this.#options = options;
|
|
4002
|
-
}
|
|
4003
|
-
setScannerFactory(factory) {
|
|
4004
|
-
this.#createScanner = factory;
|
|
4005
|
-
for (const stream of this.#streams.values()) {
|
|
4006
|
-
if (stream.scanner) continue;
|
|
4007
|
-
stream.scanner = factory();
|
|
4008
|
-
const code = stream.extractor.code;
|
|
4009
|
-
if (!stream.isFabricExec || code === void 0) continue;
|
|
4010
|
-
try {
|
|
4011
|
-
for (const candidate of stream.scanner.push(code)) {
|
|
4012
|
-
if (this.#options.isEligible(candidate.ref)) {
|
|
4013
|
-
this.#pendingCatchUp.push({ stream, candidate });
|
|
4014
|
-
}
|
|
4015
|
-
}
|
|
4016
|
-
} catch {
|
|
4017
|
-
}
|
|
4018
|
-
}
|
|
4019
|
-
}
|
|
4020
|
-
#pendingCatchUp = [];
|
|
4021
|
-
/** Drain candidates recovered while the scanner module loaded. */
|
|
4022
|
-
flushCatchUp(context) {
|
|
4023
|
-
const pending = this.#pendingCatchUp.splice(0);
|
|
4024
|
-
for (const { stream, candidate } of pending) {
|
|
4025
|
-
this.#options.launch(stream.toolCallId, candidate, context);
|
|
4026
|
-
}
|
|
4027
|
-
}
|
|
4028
|
-
/** New assistant message: content indices restart. */
|
|
4029
|
-
reset() {
|
|
4030
|
-
this.#streams.clear();
|
|
4031
|
-
}
|
|
4032
|
-
handleMessageUpdate(event, context) {
|
|
4033
|
-
try {
|
|
4034
|
-
if (!this.#options.enabled()) return;
|
|
4035
|
-
if (this.#pendingCatchUp.length > 0) this.flushCatchUp(context);
|
|
4036
|
-
const assistantEvent = event.assistantMessageEvent;
|
|
4037
|
-
if (assistantEvent.type === "toolcall_start") {
|
|
4038
|
-
const block = toolCallBlock(assistantEvent.partial, assistantEvent.contentIndex);
|
|
4039
|
-
this.#streams.set(assistantEvent.contentIndex, {
|
|
4040
|
-
toolCallId: block.id ?? `index-${assistantEvent.contentIndex}`,
|
|
4041
|
-
isFabricExec: block.name !== void 0 ? block.name === "fabric_exec" : true,
|
|
4042
|
-
extractor: new PartialCodeFieldExtractor(this.#options.maxBufferBytes()),
|
|
4043
|
-
...this.#createScanner ? { scanner: this.#createScanner() } : {}
|
|
4044
|
-
});
|
|
4045
|
-
return;
|
|
4046
|
-
}
|
|
4047
|
-
if (assistantEvent.type === "toolcall_delta") {
|
|
4048
|
-
const stream = this.#streams.get(assistantEvent.contentIndex);
|
|
4049
|
-
if (!stream) return;
|
|
4050
|
-
const block = toolCallBlock(assistantEvent.partial, assistantEvent.contentIndex);
|
|
4051
|
-
if (block.id) stream.toolCallId = block.id;
|
|
4052
|
-
if (block.name !== void 0) stream.isFabricExec = block.name === "fabric_exec";
|
|
4053
|
-
stream.extractor.push(assistantEvent.delta);
|
|
4054
|
-
const code = stream.extractor.code;
|
|
4055
|
-
if (!stream.isFabricExec || code === void 0) return;
|
|
4056
|
-
this.#scan(stream, code, context, false);
|
|
4057
|
-
return;
|
|
4058
|
-
}
|
|
4059
|
-
if (assistantEvent.type === "toolcall_end") {
|
|
4060
|
-
const stream = this.#streams.get(assistantEvent.contentIndex);
|
|
4061
|
-
if (!stream) return;
|
|
4062
|
-
this.#streams.delete(assistantEvent.contentIndex);
|
|
4063
|
-
const block = toolCallBlock(assistantEvent.toolCall, assistantEvent.contentIndex);
|
|
4064
|
-
if (block.id) stream.toolCallId = block.id;
|
|
4065
|
-
if (block.name !== void 0) stream.isFabricExec = block.name === "fabric_exec";
|
|
4066
|
-
const code = stream.extractor.code;
|
|
4067
|
-
if (stream.isFabricExec && code !== void 0) {
|
|
4068
|
-
this.#scan(stream, code, context, true);
|
|
4069
|
-
}
|
|
4070
|
-
}
|
|
4071
|
-
} catch {
|
|
4072
|
-
}
|
|
4073
|
-
}
|
|
4074
|
-
#scan(stream, code, context, force) {
|
|
4075
|
-
const now = Date.now();
|
|
4076
|
-
if (!force && now - this.#lastParseAt < PARSE_INTERVAL_MS) return;
|
|
4077
|
-
this.#lastParseAt = now;
|
|
4078
|
-
if (!stream.scanner) return;
|
|
4079
|
-
const candidates = stream.scanner.push(code);
|
|
4080
|
-
for (const candidate of candidates) {
|
|
4081
|
-
if (this.#options.isEligible(candidate.ref)) {
|
|
4082
|
-
this.#options.launch(stream.toolCallId, candidate, context);
|
|
4083
|
-
}
|
|
4084
|
-
}
|
|
4085
|
-
}
|
|
4086
|
-
};
|
|
4087
|
-
|
|
4088
4101
|
// src/lifecycle/delivery-scheduler.ts
|
|
4089
4102
|
var DEFAULT_LIFECYCLE_COALESCE_MS = 2e3;
|
|
4090
4103
|
var LifecycleDeliveryScheduler = class {
|
|
@@ -4829,7 +4842,7 @@ var AGENTS_ACTION_DESCRIPTORS = [
|
|
|
4829
4842
|
// src/residency/client.ts
|
|
4830
4843
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
4831
4844
|
import fs4 from "node:fs";
|
|
4832
|
-
import
|
|
4845
|
+
import path5 from "node:path";
|
|
4833
4846
|
import { fileURLToPath } from "node:url";
|
|
4834
4847
|
var STARTUP_TIMEOUT_MS = 3e4;
|
|
4835
4848
|
var COMMAND_TIMEOUT_MS = 3e4;
|
|
@@ -4849,7 +4862,7 @@ var readJson = (filePath) => {
|
|
|
4849
4862
|
var terminal = (status) => status === "completed" || status === "failed" || status === "stopped" || status === "timed_out";
|
|
4850
4863
|
var samePath = (left, right) => {
|
|
4851
4864
|
try {
|
|
4852
|
-
return
|
|
4865
|
+
return path5.relative(fs4.realpathSync.native(left), fs4.realpathSync.native(right)) === "";
|
|
4853
4866
|
} catch {
|
|
4854
4867
|
return false;
|
|
4855
4868
|
}
|
|
@@ -4878,12 +4891,12 @@ var ResidencyClient = class {
|
|
|
4878
4891
|
constructor(options) {
|
|
4879
4892
|
this.options = options;
|
|
4880
4893
|
this.hostId = residentHostId(options.config.rootId);
|
|
4881
|
-
this.#configPath =
|
|
4882
|
-
this.#ownerPath =
|
|
4883
|
-
this.#errorPath =
|
|
4884
|
-
this.#requestsPath =
|
|
4885
|
-
this.#responsesPath =
|
|
4886
|
-
this.#agentsPath =
|
|
4894
|
+
this.#configPath = path5.join(options.config.residencyRoot, "config.json");
|
|
4895
|
+
this.#ownerPath = path5.join(options.config.residencyRoot, "owner.json");
|
|
4896
|
+
this.#errorPath = path5.join(options.config.residencyRoot, "error.json");
|
|
4897
|
+
this.#requestsPath = path5.join(options.config.residencyRoot, "requests");
|
|
4898
|
+
this.#responsesPath = path5.join(options.config.residencyRoot, "responses");
|
|
4899
|
+
this.#agentsPath = path5.join(options.config.residencyRoot, "agents");
|
|
4887
4900
|
this.#deliveryPrefix = residentDeliveryPrefix(options.config.rootId);
|
|
4888
4901
|
this.#hostPath = options.hostPath ?? fileURLToPath(new URL("./launcher.js", import.meta.url));
|
|
4889
4902
|
}
|
|
@@ -4957,7 +4970,7 @@ var ResidencyClient = class {
|
|
|
4957
4970
|
}
|
|
4958
4971
|
const readIfPresent = (name) => {
|
|
4959
4972
|
try {
|
|
4960
|
-
return fs4.readFileSync(
|
|
4973
|
+
return fs4.readFileSync(path5.join(this.options.config.residencyRoot, name), "utf8").trim();
|
|
4961
4974
|
} catch {
|
|
4962
4975
|
return "";
|
|
4963
4976
|
}
|
|
@@ -5019,13 +5032,13 @@ var ResidencyClient = class {
|
|
|
5019
5032
|
statusAgent(id) {
|
|
5020
5033
|
const metadata = this.#metadata(id);
|
|
5021
5034
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
5022
|
-
const record = readJson(
|
|
5035
|
+
const record = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
5023
5036
|
if (!record || record.id !== metadata.id) return structuredClone(metadata.handle);
|
|
5024
5037
|
return {
|
|
5025
5038
|
...record,
|
|
5026
5039
|
cwd: metadata.handle.cwd,
|
|
5027
5040
|
residency: "durable",
|
|
5028
|
-
logFile:
|
|
5041
|
+
logFile: path5.join(metadata.runDirectory, "events.jsonl"),
|
|
5029
5042
|
...metadata.handle.sessionId ? { sessionId: metadata.handle.sessionId } : {},
|
|
5030
5043
|
...metadata.handle.attachCommand ? { attachCommand: metadata.handle.attachCommand } : {}
|
|
5031
5044
|
};
|
|
@@ -5066,9 +5079,9 @@ var ResidencyClient = class {
|
|
|
5066
5079
|
readAgentLog(id, options = {}) {
|
|
5067
5080
|
const metadata = this.#metadata(id);
|
|
5068
5081
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
5069
|
-
const logFile =
|
|
5082
|
+
const logFile = path5.join(metadata.runDirectory, "events.jsonl");
|
|
5070
5083
|
const page = readJsonlPage(logFile, Math.max(1, Math.min(options.lines ?? 200, 5e3)), options.before);
|
|
5071
|
-
const status = readJson(
|
|
5084
|
+
const status = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
5072
5085
|
return {
|
|
5073
5086
|
id,
|
|
5074
5087
|
runDirectory: metadata.runDirectory,
|
|
@@ -5143,8 +5156,8 @@ var ResidencyClient = class {
|
|
|
5143
5156
|
return { cleaned: true };
|
|
5144
5157
|
}
|
|
5145
5158
|
async #command(command, signal) {
|
|
5146
|
-
const responsePath =
|
|
5147
|
-
atomicWrite2(
|
|
5159
|
+
const responsePath = path5.join(this.#responsesPath, `${command.requestId}.json`);
|
|
5160
|
+
atomicWrite2(path5.join(this.#requestsPath, `${command.requestId}.json`), command);
|
|
5148
5161
|
const deadline = Date.now() + COMMAND_TIMEOUT_MS;
|
|
5149
5162
|
while (Date.now() < deadline) {
|
|
5150
5163
|
if (signal?.aborted) throw new Error("Fabric residency request was aborted");
|
|
@@ -5172,12 +5185,12 @@ var ResidencyClient = class {
|
|
|
5172
5185
|
throw new Error(`Timed out publishing durable Fabric ${kind} ${id} from ${this.hostId}`);
|
|
5173
5186
|
}
|
|
5174
5187
|
#metadataPath(id) {
|
|
5175
|
-
return
|
|
5188
|
+
return path5.join(this.#agentsPath, `${id}.json`);
|
|
5176
5189
|
}
|
|
5177
5190
|
#metadata(id) {
|
|
5178
5191
|
if (!AGENT_ID_PATTERN.test(id)) return void 0;
|
|
5179
5192
|
const metadata = readJson(this.#metadataPath(id));
|
|
5180
|
-
if (metadata?.format !== RESIDENT_HOST_FORMAT || metadata.rootId !== this.options.config.rootId || metadata.id !== id || metadata.handle.id !== id || metadata.worktreeGitRoot !== void 0 && typeof metadata.worktreeGitRoot !== "string" ||
|
|
5193
|
+
if (metadata?.format !== RESIDENT_HOST_FORMAT || metadata.rootId !== this.options.config.rootId || metadata.id !== id || metadata.handle.id !== id || metadata.worktreeGitRoot !== void 0 && typeof metadata.worktreeGitRoot !== "string" || path5.resolve(metadata.runDirectory) !== path5.resolve(this.options.config.residencyRoot, "runs", id)) {
|
|
5181
5194
|
return void 0;
|
|
5182
5195
|
}
|
|
5183
5196
|
if (metadata.handle.worktree && !isFabricWorktreePath(metadata.handle.worktree, id)) {
|
|
@@ -6518,7 +6531,7 @@ var AgentsProvider = class {
|
|
|
6518
6531
|
};
|
|
6519
6532
|
|
|
6520
6533
|
// src/providers/captured-tools-provider.ts
|
|
6521
|
-
import
|
|
6534
|
+
import path6 from "node:path";
|
|
6522
6535
|
|
|
6523
6536
|
// src/core/child-tool-allowlist.ts
|
|
6524
6537
|
function readChildToolAllowlist(raw = process.env.OMP_FABRIC_TOOL_ALLOWLIST) {
|
|
@@ -6544,9 +6557,9 @@ var sourceLabel = (sourceInfo) => {
|
|
|
6544
6557
|
while (index >= 0 && Object.hasOwn(SOURCE_DIRECTORIES, segments[index])) index -= 1;
|
|
6545
6558
|
const owning = index >= 0 ? segments[index] : void 0;
|
|
6546
6559
|
if (owning !== void 0 && PACKAGE_SEGMENT.test(owning)) return owning;
|
|
6547
|
-
const filename =
|
|
6560
|
+
const filename = path6.basename(sourceInfo.path).replace(/\.[^.]+$/, "");
|
|
6548
6561
|
if (filename && filename !== "index") return filename;
|
|
6549
|
-
return
|
|
6562
|
+
return path6.basename(path6.dirname(sourceInfo.path)) || sourceInfo.source;
|
|
6550
6563
|
};
|
|
6551
6564
|
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6552
6565
|
var schemaDocument = (schema) => {
|
|
@@ -6807,7 +6820,7 @@ var descriptors = [
|
|
|
6807
6820
|
},
|
|
6808
6821
|
{
|
|
6809
6822
|
name: "status",
|
|
6810
|
-
description: "Read the pending compaction intent and the last
|
|
6823
|
+
description: "Read context occupancy (context.tokens/percent/contextWindow, context.known=false when the host has not measured yet), the configured engine and targetContextRatio, the pending compaction intent, and the last settled outcome (status committed | skipped | cancelled | failed, with tokensBefore/estimatedTokensAfter)",
|
|
6811
6824
|
inputSchema: emptySchema,
|
|
6812
6825
|
risk: "read"
|
|
6813
6826
|
},
|
|
@@ -6863,7 +6876,7 @@ var CompactProvider = class {
|
|
|
6863
6876
|
return { requested: true, intent };
|
|
6864
6877
|
}
|
|
6865
6878
|
case "status":
|
|
6866
|
-
return this.controller.status();
|
|
6879
|
+
return this.controller.status(context.extensionContext);
|
|
6867
6880
|
case "cancel":
|
|
6868
6881
|
this.controller.cancel();
|
|
6869
6882
|
context.activity?.({ type: "progress", message: "Compaction request cancelled" });
|
|
@@ -6963,7 +6976,7 @@ var ComponentsProvider = class {
|
|
|
6963
6976
|
import fs5 from "node:fs/promises";
|
|
6964
6977
|
import fsSync from "node:fs";
|
|
6965
6978
|
import os from "node:os";
|
|
6966
|
-
import
|
|
6979
|
+
import path7 from "node:path";
|
|
6967
6980
|
var MCP_DESCRIPTOR_CACHE_VERSION = 1;
|
|
6968
6981
|
var homeDir = () => {
|
|
6969
6982
|
const home = process.env.HOME;
|
|
@@ -6974,25 +6987,25 @@ var expandHome = (input) => {
|
|
|
6974
6987
|
const home = homeDir();
|
|
6975
6988
|
if (input === "~") return home;
|
|
6976
6989
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
6977
|
-
return
|
|
6990
|
+
return path7.join(home, input.slice(2));
|
|
6978
6991
|
}
|
|
6979
6992
|
return input;
|
|
6980
6993
|
};
|
|
6981
|
-
var legacyMcporterDir = () =>
|
|
6994
|
+
var legacyMcporterDir = () => path7.join(homeDir(), ".mcporter");
|
|
6982
6995
|
var mcporterConfigDir = () => {
|
|
6983
6996
|
const raw = process.env.XDG_CONFIG_HOME;
|
|
6984
6997
|
if (raw && raw.trim().length > 0) {
|
|
6985
6998
|
const resolved = expandHome(raw.trim());
|
|
6986
|
-
if (
|
|
6999
|
+
if (path7.isAbsolute(resolved)) return path7.join(resolved, "mcporter");
|
|
6987
7000
|
}
|
|
6988
7001
|
return legacyMcporterDir();
|
|
6989
7002
|
};
|
|
6990
7003
|
var mcporterConfigCandidates = () => {
|
|
6991
7004
|
const base = mcporterConfigDir();
|
|
6992
|
-
const candidates = [
|
|
7005
|
+
const candidates = [path7.join(base, "mcporter.json"), path7.join(base, "mcporter.jsonc")];
|
|
6993
7006
|
const legacy = legacyMcporterDir();
|
|
6994
7007
|
if (base !== legacy) {
|
|
6995
|
-
candidates.push(
|
|
7008
|
+
candidates.push(path7.join(legacy, "mcporter.json"), path7.join(legacy, "mcporter.jsonc"));
|
|
6996
7009
|
}
|
|
6997
7010
|
return candidates;
|
|
6998
7011
|
};
|
|
@@ -7007,12 +7020,12 @@ var pathExists = (filePath) => {
|
|
|
7007
7020
|
var mcpConfigLayerPaths = (rootDir, configPath) => {
|
|
7008
7021
|
const explicitRaw = configPath ?? process.env.MCPORTER_CONFIG;
|
|
7009
7022
|
if (explicitRaw && explicitRaw.trim().length > 0) {
|
|
7010
|
-
return [
|
|
7023
|
+
return [path7.resolve(expandHome(explicitRaw.trim()))];
|
|
7011
7024
|
}
|
|
7012
7025
|
const paths = [];
|
|
7013
7026
|
const home = mcporterConfigCandidates().find(pathExists);
|
|
7014
7027
|
if (home) paths.push(home);
|
|
7015
|
-
const projectPath =
|
|
7028
|
+
const projectPath = path7.resolve(rootDir, "config", "mcporter.json");
|
|
7016
7029
|
if (pathExists(projectPath)) paths.push(projectPath);
|
|
7017
7030
|
return paths;
|
|
7018
7031
|
};
|
|
@@ -7063,6 +7076,8 @@ var parseCacheFile = (value) => {
|
|
|
7063
7076
|
servers: value.servers
|
|
7064
7077
|
};
|
|
7065
7078
|
};
|
|
7079
|
+
var projectMcpCachePath = (projectRoot) => path7.join(projectRoot, ".omp", "fabric", "mcp-cache.json");
|
|
7080
|
+
var globalMcpCachePath = (agentDir) => path7.join(agentDir, "fabric", "mcp-descriptors.json");
|
|
7066
7081
|
var tempCounter = 0;
|
|
7067
7082
|
var McpDescriptorCacheStore = class {
|
|
7068
7083
|
constructor(filePath) {
|
|
@@ -7079,9 +7094,9 @@ var McpDescriptorCacheStore = class {
|
|
|
7079
7094
|
// Atomic-ish write: temp file then rename, so a concurrent reader either
|
|
7080
7095
|
// sees the previous cache or the next one, never a torn document.
|
|
7081
7096
|
async save(file) {
|
|
7082
|
-
const directory =
|
|
7097
|
+
const directory = path7.dirname(this.filePath);
|
|
7083
7098
|
await fs5.mkdir(directory, { recursive: true });
|
|
7084
|
-
const tempPath =
|
|
7099
|
+
const tempPath = path7.join(
|
|
7085
7100
|
directory,
|
|
7086
7101
|
`.mcp-cache-${process.pid}-${Date.now()}-${tempCounter++}.tmp`
|
|
7087
7102
|
);
|
|
@@ -7096,13 +7111,14 @@ var McpDescriptorCacheStore = class {
|
|
|
7096
7111
|
};
|
|
7097
7112
|
|
|
7098
7113
|
// src/providers/mcp-provider.ts
|
|
7099
|
-
import
|
|
7114
|
+
import path8 from "node:path";
|
|
7100
7115
|
var TOOL_METADATA_TTL_MS = 6e4;
|
|
7101
7116
|
var REVALIDATE_CONCURRENCY = 3;
|
|
7102
7117
|
var REVALIDATE_SERVER_TIMEOUT_MS = 2e4;
|
|
7103
7118
|
var MIN_REVALIDATE_SERVER_TIMEOUT_MS = 5e3;
|
|
7104
7119
|
var NOTIFY_DEBOUNCE_MS = 100;
|
|
7105
7120
|
var PERSIST_DEBOUNCE_MS = 150;
|
|
7121
|
+
var COLD_LIST_WAIT_MS = 2500;
|
|
7106
7122
|
var emptyObjectSchema = {
|
|
7107
7123
|
type: "object",
|
|
7108
7124
|
properties: {},
|
|
@@ -7177,6 +7193,18 @@ var normalizeMcpResult = (result) => {
|
|
|
7177
7193
|
structuredContent: record.structuredContent ?? null
|
|
7178
7194
|
};
|
|
7179
7195
|
};
|
|
7196
|
+
var delay2 = (ms, signal) => new Promise((resolve2) => {
|
|
7197
|
+
const timer = setTimeout(() => {
|
|
7198
|
+
signal?.removeEventListener("abort", onAbort);
|
|
7199
|
+
resolve2();
|
|
7200
|
+
}, ms);
|
|
7201
|
+
timer.unref?.();
|
|
7202
|
+
const onAbort = () => {
|
|
7203
|
+
clearTimeout(timer);
|
|
7204
|
+
resolve2();
|
|
7205
|
+
};
|
|
7206
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
7207
|
+
});
|
|
7180
7208
|
var withTimeout = (operation, timeoutMs, onTimeout) => new Promise((resolve2, reject) => {
|
|
7181
7209
|
const timer = setTimeout(() => {
|
|
7182
7210
|
onTimeout?.();
|
|
@@ -7199,6 +7227,7 @@ var McpProvider = class {
|
|
|
7199
7227
|
this.cwd = cwd;
|
|
7200
7228
|
this.config = config;
|
|
7201
7229
|
this.#store = options.cache;
|
|
7230
|
+
this.#globalStore = options.globalCache;
|
|
7202
7231
|
this.#hooks = options.hooks ?? {};
|
|
7203
7232
|
}
|
|
7204
7233
|
name = "mcp";
|
|
@@ -7207,6 +7236,7 @@ var McpProvider = class {
|
|
|
7207
7236
|
#runtimeCreation;
|
|
7208
7237
|
#toolMetadata = /* @__PURE__ */ new Map();
|
|
7209
7238
|
#store;
|
|
7239
|
+
#globalStore;
|
|
7210
7240
|
#hooks;
|
|
7211
7241
|
#generation = 0;
|
|
7212
7242
|
#closed = false;
|
|
@@ -7217,8 +7247,10 @@ var McpProvider = class {
|
|
|
7217
7247
|
#revalidateQueue = [];
|
|
7218
7248
|
#revalidateQueued = /* @__PURE__ */ new Set();
|
|
7219
7249
|
#recontacted = /* @__PURE__ */ new Set();
|
|
7250
|
+
#seeded = /* @__PURE__ */ new Set();
|
|
7220
7251
|
#revalidating;
|
|
7221
7252
|
#autoKicked = false;
|
|
7253
|
+
#coldWaited = false;
|
|
7222
7254
|
#dirtyPersist = false;
|
|
7223
7255
|
#dirtyNotify = false;
|
|
7224
7256
|
#persistTimer;
|
|
@@ -7231,6 +7263,7 @@ var McpProvider = class {
|
|
|
7231
7263
|
if (!this.#cacheOn) return this.#listLegacy(request, context);
|
|
7232
7264
|
await this.#hydrate();
|
|
7233
7265
|
this.#kickRevalidation();
|
|
7266
|
+
if (!request.namespace) await this.#awaitColdEnumeration(context.signal);
|
|
7234
7267
|
const query = request.query?.toLowerCase();
|
|
7235
7268
|
const filterQuery = (descriptors6) => query ? descriptors6.filter(
|
|
7236
7269
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
@@ -7298,6 +7331,8 @@ var McpProvider = class {
|
|
|
7298
7331
|
this.#servers.clear();
|
|
7299
7332
|
this.#pending.clear();
|
|
7300
7333
|
this.#recontacted.clear();
|
|
7334
|
+
this.#seeded.clear();
|
|
7335
|
+
this.#coldWaited = false;
|
|
7301
7336
|
this.#hydration = void 0;
|
|
7302
7337
|
await this.#hydrate();
|
|
7303
7338
|
this.#kickRevalidation(true);
|
|
@@ -7347,11 +7382,36 @@ var McpProvider = class {
|
|
|
7347
7382
|
if (this.#dirtyPersist) await this.#persistNow().catch(() => void 0);
|
|
7348
7383
|
await this.#resetRuntime();
|
|
7349
7384
|
}
|
|
7350
|
-
// Fire-and-forget session warm-up: hydrate from the descriptor cache, then
|
|
7351
|
-
// start the background revalidation policy. Never awaited by session start.
|
|
7352
7385
|
warmup() {
|
|
7353
|
-
if (!this.config.enabled || !this.#cacheOn) return;
|
|
7354
|
-
|
|
7386
|
+
if (!this.config.enabled || !this.#cacheOn) return Promise.resolve();
|
|
7387
|
+
return this.#hydrate().then(() => this.#kickRevalidation()).catch(() => void 0);
|
|
7388
|
+
}
|
|
7389
|
+
listCoverage() {
|
|
7390
|
+
if (!this.config.enabled || !this.#cacheOn) return { complete: true, reasons: [] };
|
|
7391
|
+
const pending = [...this.#pending.keys()].sort();
|
|
7392
|
+
if (pending.length === 0) return { complete: true, reasons: [] };
|
|
7393
|
+
return {
|
|
7394
|
+
complete: false,
|
|
7395
|
+
reasons: [
|
|
7396
|
+
"enumeration_pending",
|
|
7397
|
+
...pending.map((server) => `server_pending:${server}`)
|
|
7398
|
+
]
|
|
7399
|
+
};
|
|
7400
|
+
}
|
|
7401
|
+
async #awaitColdEnumeration(signal) {
|
|
7402
|
+
if (this.#coldWaited || this.#closed) return;
|
|
7403
|
+
this.#coldWaited = true;
|
|
7404
|
+
if (this.#pending.size === 0 || this.#servers.size > 0) return;
|
|
7405
|
+
const budget = Math.min(COLD_LIST_WAIT_MS, Math.max(0, this.config.cache.revalidateBudgetMs));
|
|
7406
|
+
if (budget <= 0) return;
|
|
7407
|
+
const deadline = Date.now() + budget;
|
|
7408
|
+
while (!this.#closed && this.#pending.size > 0 && signal?.aborted !== true) {
|
|
7409
|
+
const remaining = deadline - Date.now();
|
|
7410
|
+
if (remaining <= 0) return;
|
|
7411
|
+
const inflight = this.#revalidating;
|
|
7412
|
+
if (!inflight) return;
|
|
7413
|
+
await Promise.race([inflight, delay2(remaining, signal)]);
|
|
7414
|
+
}
|
|
7355
7415
|
}
|
|
7356
7416
|
// Provider-fidelity descriptors for everything currently known, cached or
|
|
7357
7417
|
// ephemeral.
|
|
@@ -7446,10 +7506,13 @@ var McpProvider = class {
|
|
|
7446
7506
|
}
|
|
7447
7507
|
async #hydrateInternal() {
|
|
7448
7508
|
const generation = this.#generation;
|
|
7449
|
-
const snapshot =
|
|
7509
|
+
const [snapshot, globalSnapshot] = await Promise.all([
|
|
7510
|
+
this.#store ? this.#store.load().catch(() => void 0) : Promise.resolve(void 0),
|
|
7511
|
+
this.#globalStore ? this.#globalStore.load().catch(() => void 0) : Promise.resolve(void 0)
|
|
7512
|
+
]);
|
|
7450
7513
|
this.#layerStats = await statConfigLayers(this.cwd, this.config.configPath);
|
|
7451
7514
|
if (generation !== this.#generation) return;
|
|
7452
|
-
if (snapshot && sameConfigLayers(snapshot.layers, this.#layerStats)) {
|
|
7515
|
+
if (snapshot && Object.keys(snapshot.servers).length > 0 && sameConfigLayers(snapshot.layers, this.#layerStats)) {
|
|
7453
7516
|
for (const [name, raw] of Object.entries(snapshot.servers)) {
|
|
7454
7517
|
const parsed = parseCachedServer(raw);
|
|
7455
7518
|
if (parsed) this.#servers.set(name, this.#toWorking(parsed, false));
|
|
@@ -7465,15 +7528,21 @@ var McpProvider = class {
|
|
|
7465
7528
|
const parsed = recorded ? parseCachedServer(recorded) : void 0;
|
|
7466
7529
|
if (parsed && parsed.definitionHash === hash) {
|
|
7467
7530
|
this.#servers.set(definition.name, this.#toWorking(parsed, false));
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
});
|
|
7531
|
+
continue;
|
|
7532
|
+
}
|
|
7533
|
+
const seed = globalSnapshot ? parseCachedServer(globalSnapshot.servers[definition.name]) : void 0;
|
|
7534
|
+
if (seed && seed.definitionHash === hash && seed.tools.length > 0) {
|
|
7535
|
+
this.#servers.set(definition.name, { ...this.#toWorking(seed, false), stale: true });
|
|
7536
|
+
this.#seeded.add(definition.name);
|
|
7537
|
+
continue;
|
|
7476
7538
|
}
|
|
7539
|
+
const existing = this.#pending.get(definition.name);
|
|
7540
|
+
this.#pending.set(definition.name, {
|
|
7541
|
+
definitionHash: hash,
|
|
7542
|
+
transport: definition.command.kind,
|
|
7543
|
+
description: definition.description ?? null,
|
|
7544
|
+
ephemeral: existing?.ephemeral ?? false
|
|
7545
|
+
});
|
|
7477
7546
|
}
|
|
7478
7547
|
this.#dirtyPersist = true;
|
|
7479
7548
|
this.#schedulePersist();
|
|
@@ -7509,7 +7578,7 @@ var McpProvider = class {
|
|
|
7509
7578
|
this.#autoKicked = true;
|
|
7510
7579
|
const policy = this.config.cache.revalidate;
|
|
7511
7580
|
if (policy === "off" && !forceAll) return;
|
|
7512
|
-
const targets = forceAll || policy === "all" ? [...this.#servers.keys(), ...this.#pending.keys()] : [...this.#pending.keys()];
|
|
7581
|
+
const targets = forceAll || policy === "all" ? [...this.#servers.keys(), ...this.#pending.keys()] : [...this.#pending.keys(), ...this.#seeded];
|
|
7513
7582
|
this.#scheduleRevalidate(targets);
|
|
7514
7583
|
}
|
|
7515
7584
|
#scheduleRevalidate(servers) {
|
|
@@ -7616,7 +7685,7 @@ var McpProvider = class {
|
|
|
7616
7685
|
return sanitized.length === 1 ? sanitized[0] : void 0;
|
|
7617
7686
|
}
|
|
7618
7687
|
#schedulePersist() {
|
|
7619
|
-
if (!this.#store || this.#closed) return;
|
|
7688
|
+
if (!this.#store && !this.#globalStore || this.#closed) return;
|
|
7620
7689
|
this.#dirtyPersist = true;
|
|
7621
7690
|
if (this.#persistTimer) return;
|
|
7622
7691
|
this.#persistTimer = setTimeout(() => {
|
|
@@ -7627,7 +7696,7 @@ var McpProvider = class {
|
|
|
7627
7696
|
}
|
|
7628
7697
|
#persistNow() {
|
|
7629
7698
|
this.#dirtyPersist = false;
|
|
7630
|
-
if (!this.#store) return Promise.resolve();
|
|
7699
|
+
if (!this.#store && !this.#globalStore) return Promise.resolve();
|
|
7631
7700
|
const servers = {};
|
|
7632
7701
|
for (const [name, entry] of this.#servers) {
|
|
7633
7702
|
if (entry.ephemeral) continue;
|
|
@@ -7649,11 +7718,36 @@ var McpProvider = class {
|
|
|
7649
7718
|
})
|
|
7650
7719
|
};
|
|
7651
7720
|
}
|
|
7652
|
-
|
|
7721
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7722
|
+
return Promise.all([
|
|
7723
|
+
this.#store?.save({
|
|
7724
|
+
version: MCP_DESCRIPTOR_CACHE_VERSION,
|
|
7725
|
+
layers: this.#layerStats,
|
|
7726
|
+
updatedAt,
|
|
7727
|
+
servers
|
|
7728
|
+
}),
|
|
7729
|
+
this.#persistGlobal(servers, updatedAt)
|
|
7730
|
+
]).then(() => void 0);
|
|
7731
|
+
}
|
|
7732
|
+
async #persistGlobal(servers, updatedAt) {
|
|
7733
|
+
const store = this.#globalStore;
|
|
7734
|
+
if (!store) return;
|
|
7735
|
+
const enumerated = Object.entries(servers).filter(
|
|
7736
|
+
([, entry]) => entry.tools.length > 0 && !entry.stale
|
|
7737
|
+
);
|
|
7738
|
+
if (enumerated.length === 0) return;
|
|
7739
|
+
const existing = await store.load().catch(() => void 0);
|
|
7740
|
+
const merged = {};
|
|
7741
|
+
for (const [name, raw] of Object.entries(existing?.servers ?? {})) {
|
|
7742
|
+
const parsed = parseCachedServer(raw);
|
|
7743
|
+
if (parsed) merged[name] = parsed;
|
|
7744
|
+
}
|
|
7745
|
+
for (const [name, entry] of enumerated) merged[name] = { ...entry };
|
|
7746
|
+
await store.save({
|
|
7653
7747
|
version: MCP_DESCRIPTOR_CACHE_VERSION,
|
|
7654
|
-
layers:
|
|
7655
|
-
updatedAt
|
|
7656
|
-
servers
|
|
7748
|
+
layers: [],
|
|
7749
|
+
updatedAt,
|
|
7750
|
+
servers: merged
|
|
7657
7751
|
});
|
|
7658
7752
|
}
|
|
7659
7753
|
#scheduleNotify() {
|
|
@@ -7728,7 +7822,7 @@ var McpProvider = class {
|
|
|
7728
7822
|
kind: "stdio",
|
|
7729
7823
|
command: args.command,
|
|
7730
7824
|
args: commandArgs,
|
|
7731
|
-
cwd:
|
|
7825
|
+
cwd: path8.resolve(this.cwd, typeof args.cwd === "string" ? args.cwd : ".")
|
|
7732
7826
|
},
|
|
7733
7827
|
...env ? { env } : {}
|
|
7734
7828
|
};
|
|
@@ -8094,13 +8188,16 @@ var MeshProvider = class {
|
|
|
8094
8188
|
};
|
|
8095
8189
|
|
|
8096
8190
|
// src/providers/omp-tools-provider.ts
|
|
8097
|
-
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
|
8191
|
+
import { mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync2, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8192
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8098
8193
|
import os2 from "node:os";
|
|
8099
|
-
import
|
|
8194
|
+
import path11 from "node:path";
|
|
8100
8195
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
8101
8196
|
import { BashTool } from "@oh-my-pi/pi-coding-agent/tools/bash";
|
|
8102
8197
|
import { EditTool } from "@oh-my-pi/pi-coding-agent/edit";
|
|
8198
|
+
import { GrepTool, MULTI_FILE_PER_FILE_MATCHES, SINGLE_FILE_MATCHES } from "@oh-my-pi/pi-coding-agent/tools/grep";
|
|
8103
8199
|
import { ReadTool } from "@oh-my-pi/pi-coding-agent/tools/read";
|
|
8200
|
+
import { piEscapeRegexLiteral, piJoinPath } from "@oh-my-pi/pi-ai/providers/cursor-pi-args";
|
|
8104
8201
|
import { Settings } from "@oh-my-pi/pi-coding-agent";
|
|
8105
8202
|
import {
|
|
8106
8203
|
createFindToolDefinition,
|
|
@@ -8110,7 +8207,7 @@ import {
|
|
|
8110
8207
|
|
|
8111
8208
|
// src/agents/bash-worktree-add.ts
|
|
8112
8209
|
import fs6 from "node:fs";
|
|
8113
|
-
import
|
|
8210
|
+
import path9 from "node:path";
|
|
8114
8211
|
var BARE_SAFE = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
8115
8212
|
var parseGitWorktreeAdd = (command) => {
|
|
8116
8213
|
const trimmed = command.trim();
|
|
@@ -8173,8 +8270,8 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8173
8270
|
if (typeof command !== "string") return void 0;
|
|
8174
8271
|
const parsed = parseGitWorktreeAdd(command);
|
|
8175
8272
|
if (!parsed) return void 0;
|
|
8176
|
-
const gitCwd = parsed.gitCwd ?
|
|
8177
|
-
const dest =
|
|
8273
|
+
const gitCwd = parsed.gitCwd ? path9.resolve(sessionCwd, parsed.gitCwd) : typeof args.cwd === "string" ? args.cwd : sessionCwd;
|
|
8274
|
+
const dest = path9.resolve(gitCwd, parsed.dest);
|
|
8178
8275
|
let gitRoot;
|
|
8179
8276
|
try {
|
|
8180
8277
|
const root = await executeFile("git", ["rev-parse", "--show-toplevel"], {
|
|
@@ -8202,8 +8299,8 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8202
8299
|
};
|
|
8203
8300
|
|
|
8204
8301
|
// src/providers/omp-bash-cwd.ts
|
|
8205
|
-
import { accessSync, constants, statSync } from "node:fs";
|
|
8206
|
-
import
|
|
8302
|
+
import { accessSync, constants, statSync as statSync2 } from "node:fs";
|
|
8303
|
+
import path10 from "node:path";
|
|
8207
8304
|
import { createBashToolDefinition } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-pi-coding-agent-shim";
|
|
8208
8305
|
import { Type as Type2 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8209
8306
|
var OMP_BASH_CWD_KEY = "cwd";
|
|
@@ -8213,9 +8310,9 @@ var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
|
|
|
8213
8310
|
`Invalid omp.${toolName} cwd ${JSON.stringify(requested)}: path must be a non-empty string`
|
|
8214
8311
|
);
|
|
8215
8312
|
}
|
|
8216
|
-
const resolved =
|
|
8313
|
+
const resolved = path10.isAbsolute(requested) ? path10.resolve(requested) : path10.resolve(sessionCwd, requested);
|
|
8217
8314
|
try {
|
|
8218
|
-
if (!
|
|
8315
|
+
if (!statSync2(resolved).isDirectory()) throw new Error("path is not a directory");
|
|
8219
8316
|
accessSync(resolved, constants.R_OK | constants.X_OK);
|
|
8220
8317
|
} catch (error) {
|
|
8221
8318
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -8292,19 +8389,19 @@ import { dirname, isAbsolute, resolve } from "node:path";
|
|
|
8292
8389
|
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
8293
8390
|
import { Type as Type3 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8294
8391
|
var mutationQueues = /* @__PURE__ */ new Map();
|
|
8295
|
-
var withFileMutationQueue = async (
|
|
8296
|
-
const previous = mutationQueues.get(
|
|
8392
|
+
var withFileMutationQueue = async (path17, operation) => {
|
|
8393
|
+
const previous = mutationQueues.get(path17) ?? Promise.resolve();
|
|
8297
8394
|
let release;
|
|
8298
8395
|
const current = new Promise((resolve2) => {
|
|
8299
8396
|
release = resolve2;
|
|
8300
8397
|
});
|
|
8301
|
-
mutationQueues.set(
|
|
8398
|
+
mutationQueues.set(path17, current);
|
|
8302
8399
|
await previous;
|
|
8303
8400
|
try {
|
|
8304
8401
|
return await operation();
|
|
8305
8402
|
} finally {
|
|
8306
8403
|
release();
|
|
8307
|
-
if (mutationQueues.get(
|
|
8404
|
+
if (mutationQueues.get(path17) === current) mutationQueues.delete(path17);
|
|
8308
8405
|
}
|
|
8309
8406
|
};
|
|
8310
8407
|
var resolvePreviewPath = (filePath, cwd) => {
|
|
@@ -8357,14 +8454,14 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8357
8454
|
return {
|
|
8358
8455
|
...original,
|
|
8359
8456
|
async execute(_toolCallId, params, signal) {
|
|
8360
|
-
const { path:
|
|
8361
|
-
const absolutePath = resolvePreviewPath(
|
|
8457
|
+
const { path: path17, content } = params;
|
|
8458
|
+
const absolutePath = resolvePreviewPath(path17, cwd);
|
|
8362
8459
|
return withFileMutationQueue(absolutePath, async () => {
|
|
8363
8460
|
const throwIfAborted2 = () => {
|
|
8364
8461
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
8365
8462
|
};
|
|
8366
8463
|
throwIfAborted2();
|
|
8367
|
-
const before = await readExistingFileForPreview(
|
|
8464
|
+
const before = await readExistingFileForPreview(path17, cwd, content);
|
|
8368
8465
|
throwIfAborted2();
|
|
8369
8466
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
8370
8467
|
throwIfAborted2();
|
|
@@ -8374,7 +8471,7 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8374
8471
|
content: [
|
|
8375
8472
|
{
|
|
8376
8473
|
type: "text",
|
|
8377
|
-
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${
|
|
8474
|
+
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${path17}`
|
|
8378
8475
|
}
|
|
8379
8476
|
],
|
|
8380
8477
|
details: { codePreviewBeforeWrite: before }
|
|
@@ -8386,27 +8483,39 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8386
8483
|
|
|
8387
8484
|
// src/providers/omp-tools-provider.ts
|
|
8388
8485
|
var MAX_RENDERER_ARGUMENT_CHARS = 2e5;
|
|
8486
|
+
var GUEST_READ_LINE_LIMIT = 1e5;
|
|
8389
8487
|
var MAX_REPLACE_ALL_FILE_CHARS = 2e6;
|
|
8390
8488
|
var createNativeSession = (cwd, artifactPaths) => {
|
|
8391
|
-
const artifactRoot = artifactPaths ? mkdtempSync(
|
|
8489
|
+
const artifactRoot = artifactPaths ? mkdtempSync(path11.join(os2.tmpdir(), "omp-fabric-bash-")) : void 0;
|
|
8392
8490
|
return {
|
|
8393
8491
|
cwd,
|
|
8394
8492
|
hasUI: false,
|
|
8395
8493
|
hasEditTool: false,
|
|
8396
8494
|
getSessionFile: () => null,
|
|
8397
8495
|
getSessionSpawns: () => null,
|
|
8398
|
-
settings: Settings.isolated({
|
|
8496
|
+
settings: Settings.isolated({
|
|
8497
|
+
readLineNumbers: false,
|
|
8498
|
+
"read.defaultLimit": GUEST_READ_LINE_LIMIT,
|
|
8499
|
+
"tools.outputMaxColumns": 0
|
|
8500
|
+
}),
|
|
8399
8501
|
...artifactRoot && artifactPaths ? {
|
|
8400
8502
|
allocateOutputArtifact: async (toolType) => {
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8503
|
+
try {
|
|
8504
|
+
mkdirSync2(artifactRoot, { recursive: true, mode: 448 });
|
|
8505
|
+
const id = randomUUID3();
|
|
8506
|
+
const artifactPath = path11.join(artifactRoot, `${toolType}-${id}.log`);
|
|
8507
|
+
writeFileSync2(artifactPath, "", { mode: 384 });
|
|
8508
|
+
artifactPaths.set(id, artifactPath);
|
|
8509
|
+
artifactAllocations.getStore()?.push(artifactPath);
|
|
8510
|
+
return { id, path: artifactPath };
|
|
8511
|
+
} catch {
|
|
8512
|
+
return {};
|
|
8513
|
+
}
|
|
8406
8514
|
}
|
|
8407
8515
|
} : {}
|
|
8408
8516
|
};
|
|
8409
8517
|
};
|
|
8518
|
+
var artifactAllocations = new AsyncLocalStorage();
|
|
8410
8519
|
var nativeDefinition = (tool) => {
|
|
8411
8520
|
const execute = (toolCallId, params, signal, onUpdate, context) => tool.execute(toolCallId, params, signal, onUpdate, context);
|
|
8412
8521
|
return {
|
|
@@ -8420,6 +8529,65 @@ var nativeDefinition = (tool) => {
|
|
|
8420
8529
|
var createNativeBashToolDefinition = (cwd, artifactPaths) => nativeDefinition(new BashTool(createNativeSession(cwd, artifactPaths)));
|
|
8421
8530
|
var createNativeReadToolDefinition = (cwd) => nativeDefinition(new ReadTool(createNativeSession(cwd)));
|
|
8422
8531
|
var createNativeReplaceEditToolDefinition = (cwd) => nativeDefinition(new EditTool(createNativeSession(cwd), "replace"));
|
|
8532
|
+
var normalizeReadArguments = (args) => {
|
|
8533
|
+
const offset = finiteNumber2(args.offset);
|
|
8534
|
+
const limit = finiteNumber2(args.limit);
|
|
8535
|
+
if (offset === void 0 && limit === void 0) return args;
|
|
8536
|
+
const { offset: _offset, limit: _limit, ...rest } = args;
|
|
8537
|
+
const target = parseReadTarget(args.path);
|
|
8538
|
+
if (!target || target.selected) return rest;
|
|
8539
|
+
const start = offset === void 0 ? 1 : Math.max(1, Math.floor(offset));
|
|
8540
|
+
const end = limit === void 0 ? Number.POSITIVE_INFINITY : start + Math.max(1, Math.floor(limit)) - 1;
|
|
8541
|
+
return { ...rest, path: readPageSelector({ ...target, endLimit: end }, start) };
|
|
8542
|
+
};
|
|
8543
|
+
var GREP_SKIP_PROPERTY = {
|
|
8544
|
+
type: "number",
|
|
8545
|
+
description: "Files to skip before collecting results \u2014 paginate when a search hit the file limit"
|
|
8546
|
+
};
|
|
8547
|
+
var withGrepSkipSchema = (document) => {
|
|
8548
|
+
const schema = asRecord(document);
|
|
8549
|
+
const properties = asRecord(schema?.properties);
|
|
8550
|
+
if (!schema || !properties || Object.hasOwn(properties, "skip")) return document;
|
|
8551
|
+
return { ...schema, properties: { ...properties, skip: GREP_SKIP_PROPERTY } };
|
|
8552
|
+
};
|
|
8553
|
+
var grepSession = (cwd, context) => ({
|
|
8554
|
+
cwd,
|
|
8555
|
+
hasUI: false,
|
|
8556
|
+
getSessionFile: () => null,
|
|
8557
|
+
getSessionSpawns: () => null,
|
|
8558
|
+
settings: Settings.isolated(
|
|
8559
|
+
context === void 0 ? void 0 : { "grep.contextBefore": Math.max(0, Math.floor(context)), "grep.contextAfter": Math.max(0, Math.floor(context)) }
|
|
8560
|
+
)
|
|
8561
|
+
});
|
|
8562
|
+
var createGrepDefinitionWithSkip = (cwd) => {
|
|
8563
|
+
const legacy = createGrepToolDefinition(cwd);
|
|
8564
|
+
const defaultTool = new GrepTool(grepSession(cwd));
|
|
8565
|
+
return {
|
|
8566
|
+
...legacy,
|
|
8567
|
+
parameters: withGrepSkipSchema(legacy.parameters),
|
|
8568
|
+
execute: (toolCallId, params, signal, onUpdate, context) => {
|
|
8569
|
+
const record = asRecord(params) ?? {};
|
|
8570
|
+
const rawPattern = typeof record.pattern === "string" ? record.pattern : "";
|
|
8571
|
+
const searchPath = typeof record.path === "string" ? record.path : ".";
|
|
8572
|
+
const glob = typeof record.glob === "string" ? record.glob : void 0;
|
|
8573
|
+
const contextLines = typeof record.context === "number" ? record.context : void 0;
|
|
8574
|
+
const skip = typeof record.skip === "number" ? record.skip : void 0;
|
|
8575
|
+
const tool = contextLines === void 0 ? defaultTool : new GrepTool(grepSession(cwd, contextLines));
|
|
8576
|
+
return tool.execute(
|
|
8577
|
+
toolCallId,
|
|
8578
|
+
{
|
|
8579
|
+
pattern: record.literal === true ? piEscapeRegexLiteral(rawPattern) : rawPattern,
|
|
8580
|
+
path: glob ? piJoinPath(searchPath, glob) : searchPath,
|
|
8581
|
+
case: record.ignoreCase === true ? false : void 0,
|
|
8582
|
+
...skip === void 0 ? {} : { skip }
|
|
8583
|
+
},
|
|
8584
|
+
signal,
|
|
8585
|
+
onUpdate,
|
|
8586
|
+
context
|
|
8587
|
+
);
|
|
8588
|
+
}
|
|
8589
|
+
};
|
|
8590
|
+
};
|
|
8423
8591
|
var normalizeEditArguments = (args, replaceAll, cwd) => {
|
|
8424
8592
|
const filePath = args.path;
|
|
8425
8593
|
if (typeof filePath !== "string") throw new Error("omp.edit requires a path");
|
|
@@ -8442,8 +8610,8 @@ var normalizeEditArguments = (args, replaceAll, cwd) => {
|
|
|
8442
8610
|
...replaceAll || record.all === true || record.replace_all === true ? { replace_all: true } : {}
|
|
8443
8611
|
};
|
|
8444
8612
|
});
|
|
8445
|
-
const resolvedPath =
|
|
8446
|
-
const current =
|
|
8613
|
+
const resolvedPath = path11.resolve(cwd, filePath.startsWith("@") ? filePath.slice(1) : filePath);
|
|
8614
|
+
const current = readFileSync2(resolvedPath, "utf8");
|
|
8447
8615
|
if (current.length > MAX_REPLACE_ALL_FILE_CHARS) {
|
|
8448
8616
|
throw new Error(`omp.edit refuses files over ${MAX_REPLACE_ALL_FILE_CHARS} characters`);
|
|
8449
8617
|
}
|
|
@@ -8503,6 +8671,203 @@ var imageBlocks = (content) => {
|
|
|
8503
8671
|
}
|
|
8504
8672
|
return blocks;
|
|
8505
8673
|
};
|
|
8674
|
+
var TRUNCATION_MARKER = "[[omp-fabric:truncated]]";
|
|
8675
|
+
var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
8676
|
+
var finiteNumber2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8677
|
+
var appendTruncationMarker = (text, signal) => `${text.endsWith("\n") || text.length === 0 ? text : `${text}
|
|
8678
|
+
`}${TRUNCATION_MARKER} ${JSON.stringify(signal)}
|
|
8679
|
+
`;
|
|
8680
|
+
var readTruncationMeta = (details) => {
|
|
8681
|
+
const truncation = asRecord(asRecord(asRecord(details)?.meta)?.truncation);
|
|
8682
|
+
if (!truncation) return void 0;
|
|
8683
|
+
const shown = asRecord(truncation.shownRange);
|
|
8684
|
+
const truncatedBy = typeof truncation.truncatedBy === "string" ? truncation.truncatedBy : void 0;
|
|
8685
|
+
const totalLines = finiteNumber2(truncation.totalLines);
|
|
8686
|
+
const totalBytes = finiteNumber2(truncation.totalBytes);
|
|
8687
|
+
const outputBytes = finiteNumber2(truncation.outputBytes);
|
|
8688
|
+
const nextOffset = finiteNumber2(truncation.nextOffset);
|
|
8689
|
+
const shownStart = finiteNumber2(shown?.start);
|
|
8690
|
+
const shownEnd = finiteNumber2(shown?.end);
|
|
8691
|
+
return {
|
|
8692
|
+
partialLine: truncation.partialLine === true,
|
|
8693
|
+
...truncatedBy === void 0 ? {} : { truncatedBy },
|
|
8694
|
+
...totalLines === void 0 ? {} : { totalLines },
|
|
8695
|
+
...totalBytes === void 0 ? {} : { totalBytes },
|
|
8696
|
+
...outputBytes === void 0 ? {} : { outputBytes },
|
|
8697
|
+
...nextOffset === void 0 ? {} : { nextOffset },
|
|
8698
|
+
...shownStart === void 0 ? {} : { shownStart },
|
|
8699
|
+
...shownEnd === void 0 ? {} : { shownEnd }
|
|
8700
|
+
};
|
|
8701
|
+
};
|
|
8702
|
+
var UNREADABLE_READ_NOTE = /^\[Cannot read (?:binary file '|\.[^\s:]+ file: )/;
|
|
8703
|
+
var REPEAT_READ_HINT_PATTERN = /\n\n\[You have received this identical output \d+ times\. Re-reading '[\s\S]*?' will not change it — use a narrower selector \(path:A-B\), or proceed with the edit\.\]$/;
|
|
8704
|
+
var stripRepeatReadHint = (text) => text.endsWith("]") ? text.replace(REPEAT_READ_HINT_PATTERN, "") : text;
|
|
8705
|
+
var dropLeadingLines = (text, count) => {
|
|
8706
|
+
if (count <= 0) return text;
|
|
8707
|
+
let index = 0;
|
|
8708
|
+
for (let dropped = 0; dropped < count; dropped++) {
|
|
8709
|
+
const newline = text.indexOf("\n", index);
|
|
8710
|
+
if (newline === -1) return "";
|
|
8711
|
+
index = newline + 1;
|
|
8712
|
+
}
|
|
8713
|
+
return text.slice(index);
|
|
8714
|
+
};
|
|
8715
|
+
var keepLeadingLines = (text, count) => {
|
|
8716
|
+
if (count <= 0) return "";
|
|
8717
|
+
let index = 0;
|
|
8718
|
+
for (let kept = 0; kept < count; kept++) {
|
|
8719
|
+
const newline = text.indexOf("\n", index);
|
|
8720
|
+
if (newline === -1) return text;
|
|
8721
|
+
index = newline + 1;
|
|
8722
|
+
}
|
|
8723
|
+
return text.slice(0, index - 1);
|
|
8724
|
+
};
|
|
8725
|
+
var countLines = (text) => {
|
|
8726
|
+
if (text.length === 0) return 0;
|
|
8727
|
+
let lines = 1;
|
|
8728
|
+
for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1)) lines++;
|
|
8729
|
+
return text.endsWith("\n") ? lines - 1 : lines;
|
|
8730
|
+
};
|
|
8731
|
+
var READ_SELECTOR_PATTERN = /:(raw:)?(\d+)(-(\d+)?)?$/i;
|
|
8732
|
+
var READ_RAW_SELECTOR_PATTERN = /:raw$/i;
|
|
8733
|
+
var readPageSelector = (target, offset) => target.endLimit === Number.POSITIVE_INFINITY ? `${target.base}:raw:${offset}-` : `${target.base}:raw:${offset}-${target.endLimit}`;
|
|
8734
|
+
var parseReadTarget = (rawPath) => {
|
|
8735
|
+
if (typeof rawPath !== "string" || rawPath.length === 0 || rawPath.includes("://")) return void 0;
|
|
8736
|
+
const match = READ_SELECTOR_PATTERN.exec(rawPath);
|
|
8737
|
+
if (match) {
|
|
8738
|
+
const end = match[3] === void 0 ? Number.POSITIVE_INFINITY : match[4] === void 0 ? Number.POSITIVE_INFINITY : Number(match[4]);
|
|
8739
|
+
return { base: rawPath.slice(0, match.index), start: Number(match[2]), endLimit: end, pageable: true, selected: true };
|
|
8740
|
+
}
|
|
8741
|
+
if (READ_RAW_SELECTOR_PATTERN.test(rawPath)) {
|
|
8742
|
+
return {
|
|
8743
|
+
base: rawPath.replace(READ_RAW_SELECTOR_PATTERN, ""),
|
|
8744
|
+
start: 1,
|
|
8745
|
+
endLimit: Number.POSITIVE_INFINITY,
|
|
8746
|
+
pageable: true,
|
|
8747
|
+
selected: true
|
|
8748
|
+
};
|
|
8749
|
+
}
|
|
8750
|
+
const lastColon = rawPath.lastIndexOf(":");
|
|
8751
|
+
const suffix = lastColon === -1 ? "" : rawPath.slice(lastColon + 1);
|
|
8752
|
+
const pageable = suffix.length === 0;
|
|
8753
|
+
return { base: rawPath, start: 1, endLimit: Number.POSITIVE_INFINITY, pageable, selected: false };
|
|
8754
|
+
};
|
|
8755
|
+
var unreadableReadMessage = (note, readPath) => {
|
|
8756
|
+
const target = typeof readPath === "string" ? readPath.replace(READ_SELECTOR_PATTERN, "") : void 0;
|
|
8757
|
+
const remedy = target ? ` Read the bytes with omp.read("${target}:raw").` : "";
|
|
8758
|
+
return `omp.read returned no text content: ${note.trim()}${remedy}`;
|
|
8759
|
+
};
|
|
8760
|
+
var restoreBashOutput = (artifactPath, maxChars, delivered) => {
|
|
8761
|
+
if (!artifactPath || maxChars <= 0) return void 0;
|
|
8762
|
+
let size;
|
|
8763
|
+
try {
|
|
8764
|
+
size = statSync3(artifactPath).size;
|
|
8765
|
+
} catch {
|
|
8766
|
+
return void 0;
|
|
8767
|
+
}
|
|
8768
|
+
if (size === 0 || size > maxChars) return void 0;
|
|
8769
|
+
let full;
|
|
8770
|
+
try {
|
|
8771
|
+
full = readFileSync2(artifactPath, "utf8");
|
|
8772
|
+
} catch {
|
|
8773
|
+
return void 0;
|
|
8774
|
+
}
|
|
8775
|
+
if (full.length < delivered.length) return void 0;
|
|
8776
|
+
const ellipsis = delivered.indexOf("\u2026");
|
|
8777
|
+
const prefix = ellipsis === -1 ? delivered : delivered.slice(0, ellipsis);
|
|
8778
|
+
return full.startsWith(prefix) ? full : void 0;
|
|
8779
|
+
};
|
|
8780
|
+
var withoutColumnLimit = (detailRecord, metaRecord) => {
|
|
8781
|
+
const limits = asRecord(metaRecord?.limits);
|
|
8782
|
+
if (!metaRecord || !limits || !Object.hasOwn(limits, "columnTruncated")) return detailRecord;
|
|
8783
|
+
const { columnTruncated: _dropped, ...remainingLimits } = limits;
|
|
8784
|
+
const { limits: _limits, ...remainingMeta } = metaRecord;
|
|
8785
|
+
const nextMeta = Object.keys(remainingLimits).length > 0 ? { ...remainingMeta, limits: remainingLimits } : remainingMeta;
|
|
8786
|
+
if (Object.keys(nextMeta).length > 0) return { ...detailRecord, meta: nextMeta };
|
|
8787
|
+
const { meta: _meta, ...remainingDetails } = detailRecord;
|
|
8788
|
+
return remainingDetails;
|
|
8789
|
+
};
|
|
8790
|
+
var grepTruncationSignal = (details) => {
|
|
8791
|
+
const record = asRecord(details);
|
|
8792
|
+
if (!record || record.truncated !== true) return void 0;
|
|
8793
|
+
const perFile = finiteNumber2(record.perFileLimitReached);
|
|
8794
|
+
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(record.meta)?.limits)?.columnTruncated)?.maxColumn);
|
|
8795
|
+
const fileCount = finiteNumber2(record.fileCount);
|
|
8796
|
+
const reasons = [];
|
|
8797
|
+
const notes = [];
|
|
8798
|
+
let continuation = null;
|
|
8799
|
+
if (perFile !== void 0) {
|
|
8800
|
+
reasons.push("matchLimit");
|
|
8801
|
+
notes.push(
|
|
8802
|
+
perFile <= MULTI_FILE_PER_FILE_MATCHES ? `Only ${perFile} matches per file are returned for a multi-file scope; point path at a single file to raise it to ${SINGLE_FILE_MATCHES}.` : `Only ${perFile} matches per file are returned; grep has no match cursor, so narrow the pattern or split the search by path.`
|
|
8803
|
+
);
|
|
8804
|
+
}
|
|
8805
|
+
if (maxColumn !== void 0) {
|
|
8806
|
+
reasons.push("columnLimit");
|
|
8807
|
+
notes.push(
|
|
8808
|
+
`Match lines are cut at ${maxColumn} bytes by the host, so a reported line need not contain the match; read the full line with omp.read("<file>:<line>").`
|
|
8809
|
+
);
|
|
8810
|
+
}
|
|
8811
|
+
if (reasons.length === 0) {
|
|
8812
|
+
reasons.push("fileLimit");
|
|
8813
|
+
if (fileCount !== void 0) continuation = { skip: fileCount };
|
|
8814
|
+
notes.push(
|
|
8815
|
+
fileCount === void 0 ? "More files matched than were returned; narrow the pattern or path." : `More files matched than were returned; pass skip=${fileCount} for the next page.`
|
|
8816
|
+
);
|
|
8817
|
+
}
|
|
8818
|
+
return {
|
|
8819
|
+
tool: "grep",
|
|
8820
|
+
partial: true,
|
|
8821
|
+
reasons,
|
|
8822
|
+
...finiteNumber2(record.matchCount) === void 0 ? {} : { matchCount: record.matchCount },
|
|
8823
|
+
...fileCount === void 0 ? {} : { fileCount },
|
|
8824
|
+
...perFile === void 0 ? {} : { perFileMatchLimit: perFile },
|
|
8825
|
+
...maxColumn === void 0 ? {} : { maxColumn },
|
|
8826
|
+
continue: continuation,
|
|
8827
|
+
note: notes.join(" ")
|
|
8828
|
+
};
|
|
8829
|
+
};
|
|
8830
|
+
var GUEST_RESULT_CHAR_FALLBACK = 1e6;
|
|
8831
|
+
var READ_MARKER_RESERVE_CHARS = 512;
|
|
8832
|
+
var resultCharBound = (context) => {
|
|
8833
|
+
const value = Reflect.get(context, "maxResultChars");
|
|
8834
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : GUEST_RESULT_CHAR_FALLBACK;
|
|
8835
|
+
};
|
|
8836
|
+
var byteBudgetSignal = (meta) => ({
|
|
8837
|
+
tool: "read",
|
|
8838
|
+
partial: true,
|
|
8839
|
+
reasons: ["byteBudget"],
|
|
8840
|
+
totalBytes: meta.totalBytes ?? null,
|
|
8841
|
+
deliveredBytes: meta.outputBytes ?? null,
|
|
8842
|
+
continue: null,
|
|
8843
|
+
note: "A single line exceeded the host per-read byte budget and no read selector continues a partial line; split the file (omp.bash with fold or split) and read the pieces."
|
|
8844
|
+
});
|
|
8845
|
+
var lineBudgetSignal = (meta, target, progress) => {
|
|
8846
|
+
const nextOffset = progress ? progress.nextOffset : meta.nextOffset;
|
|
8847
|
+
const continuation = target && nextOffset !== void 0 ? readPageSelector(target, nextOffset) : null;
|
|
8848
|
+
return {
|
|
8849
|
+
tool: "read",
|
|
8850
|
+
partial: true,
|
|
8851
|
+
reasons: [progress?.reason ?? "lineBudget"],
|
|
8852
|
+
totalLines: meta.totalLines ?? null,
|
|
8853
|
+
deliveredLines: progress?.delivered ?? null,
|
|
8854
|
+
continue: continuation,
|
|
8855
|
+
note: continuation ? `More lines remain; continue with omp.read("${continuation}").` : "More lines remain and the host offered no continuation offset."
|
|
8856
|
+
};
|
|
8857
|
+
};
|
|
8858
|
+
var findTruncationSignal = (details) => {
|
|
8859
|
+
const record = asRecord(details);
|
|
8860
|
+
if (!record || record.truncated !== true) return void 0;
|
|
8861
|
+
const reached = finiteNumber2(record.resultLimitReached) ?? finiteNumber2(record.fileCount);
|
|
8862
|
+
return {
|
|
8863
|
+
tool: "find",
|
|
8864
|
+
partial: true,
|
|
8865
|
+
reasons: ["resultLimit"],
|
|
8866
|
+
...reached === void 0 ? {} : { resultLimit: reached },
|
|
8867
|
+
continue: null,
|
|
8868
|
+
note: `The host caps find at ${reached ?? "its result limit"} results and clamps any larger limit, so narrow pattern or path, or enumerate with omp.bash.`
|
|
8869
|
+
};
|
|
8870
|
+
};
|
|
8506
8871
|
var resultHasTruncation = (details) => {
|
|
8507
8872
|
if (details === null || typeof details !== "object" || Array.isArray(details)) return false;
|
|
8508
8873
|
const meta = Reflect.get(details, "meta");
|
|
@@ -8516,15 +8881,26 @@ var resultExitCode = (details) => {
|
|
|
8516
8881
|
const exitCode = Reflect.get(details, "exitCode");
|
|
8517
8882
|
return Number.isSafeInteger(exitCode) && exitCode > 0 ? exitCode : void 0;
|
|
8518
8883
|
};
|
|
8519
|
-
var normalizeResult = (name, result, artifactPaths, appendReadNewline = true) => {
|
|
8520
|
-
const
|
|
8884
|
+
var normalizeResult = (name, result, artifactPaths, appendReadNewline = true, extras) => {
|
|
8885
|
+
const readSignal = extras?.read;
|
|
8886
|
+
const text = isOmpShellToolName(name) ? stripOmpBashTiming(textContent(result.content)) : name === "read" ? stripRepeatReadHint(textContent(result.content)) : textContent(result.content);
|
|
8521
8887
|
if (result.isError && !resultHasTruncation(result.details)) throw new Error(text || `${name} failed`);
|
|
8522
8888
|
if (name === "read") {
|
|
8523
|
-
|
|
8889
|
+
const body = appendReadNewline && text.length > 0 && !text.endsWith("\n") ? `${text}
|
|
8524
8890
|
` : text;
|
|
8891
|
+
return readSignal?.signal ? appendTruncationMarker(body, readSignal.signal) : body;
|
|
8892
|
+
}
|
|
8893
|
+
if (name === "grep") {
|
|
8894
|
+
const signal = grepTruncationSignal(result.details);
|
|
8895
|
+
return signal ? appendTruncationMarker(text, signal) : text;
|
|
8525
8896
|
}
|
|
8526
|
-
if (name === "
|
|
8897
|
+
if (name === "find") {
|
|
8898
|
+
const signal = findTruncationSignal(result.details);
|
|
8899
|
+
return signal ? appendTruncationMarker(text, signal) : text;
|
|
8900
|
+
}
|
|
8901
|
+
if (name === "ls") return text;
|
|
8527
8902
|
let details = result.details;
|
|
8903
|
+
let output = text;
|
|
8528
8904
|
if (isOmpShellToolName(name) && details && typeof details === "object" && !Array.isArray(details)) {
|
|
8529
8905
|
const detailRecord = details;
|
|
8530
8906
|
const meta = detailRecord.meta;
|
|
@@ -8533,19 +8909,62 @@ var normalizeResult = (name, result, artifactPaths, appendReadNewline = true) =>
|
|
|
8533
8909
|
if (truncation && typeof truncation === "object" && !Array.isArray(truncation)) {
|
|
8534
8910
|
const truncationRecord = truncation;
|
|
8535
8911
|
const artifactId = truncationRecord.artifactId;
|
|
8536
|
-
const fullOutputPath = typeof artifactId === "string" ? artifactPaths?.get(artifactId) :
|
|
8912
|
+
const fullOutputPath = typeof artifactId === "string" ? artifactPaths?.get(artifactId) ?? extras?.bashArtifactPath : extras?.bashArtifactPath;
|
|
8537
8913
|
details = {
|
|
8538
8914
|
...detailRecord,
|
|
8539
8915
|
truncation: { ...truncationRecord, truncated: true },
|
|
8540
8916
|
...fullOutputPath ? { fullOutputPath } : {}
|
|
8541
8917
|
};
|
|
8918
|
+
if (truncationRecord.truncated !== false) {
|
|
8919
|
+
const columnCap = finiteNumber2(asRecord(asRecord(metaRecord?.limits)?.columnTruncated)?.maxColumn);
|
|
8920
|
+
output = appendTruncationMarker(text, {
|
|
8921
|
+
tool: name,
|
|
8922
|
+
partial: true,
|
|
8923
|
+
reasons: columnCap === void 0 ? ["outputLimit"] : ["outputLimit", "columnLimit"],
|
|
8924
|
+
truncatedBy: truncationRecord.truncatedBy ?? null,
|
|
8925
|
+
totalLines: finiteNumber2(truncationRecord.totalLines) ?? null,
|
|
8926
|
+
totalBytes: finiteNumber2(truncationRecord.totalBytes) ?? null,
|
|
8927
|
+
deliveredBytes: finiteNumber2(truncationRecord.outputBytes) ?? null,
|
|
8928
|
+
...columnCap === void 0 ? {} : { maxColumn: columnCap },
|
|
8929
|
+
fullOutputPath: fullOutputPath ?? null,
|
|
8930
|
+
continue: null,
|
|
8931
|
+
note: fullOutputPath ? `Output exceeded the host bash result budget; the complete stream is on disk at ${fullOutputPath}.` : "Output exceeded the host bash result budget and no full-output artifact was retained."
|
|
8932
|
+
});
|
|
8933
|
+
}
|
|
8934
|
+
} else {
|
|
8935
|
+
const columnCap = finiteNumber2(asRecord(asRecord(metaRecord?.limits)?.columnTruncated)?.maxColumn);
|
|
8936
|
+
if (columnCap !== void 0) {
|
|
8937
|
+
const restored = restoreBashOutput(extras?.bashArtifactPath, extras?.maxResultChars ?? 0, text);
|
|
8938
|
+
if (restored === void 0) {
|
|
8939
|
+
details = {
|
|
8940
|
+
...detailRecord,
|
|
8941
|
+
columnTruncated: { maxColumn: columnCap, restored: false },
|
|
8942
|
+
...extras?.bashArtifactPath ? { fullOutputPath: extras.bashArtifactPath } : {}
|
|
8943
|
+
};
|
|
8944
|
+
output = appendTruncationMarker(text, {
|
|
8945
|
+
tool: name,
|
|
8946
|
+
partial: true,
|
|
8947
|
+
reasons: ["columnLimit"],
|
|
8948
|
+
maxColumn: columnCap,
|
|
8949
|
+
fullOutputPath: extras?.bashArtifactPath ?? null,
|
|
8950
|
+
continue: null,
|
|
8951
|
+
note: `Output lines were cut at ${columnCap} bytes by the host bash executor, which reads global settings and ignores this session's tools.outputMaxColumns.`
|
|
8952
|
+
});
|
|
8953
|
+
} else {
|
|
8954
|
+
output = restored;
|
|
8955
|
+
details = {
|
|
8956
|
+
...withoutColumnLimit(detailRecord, metaRecord),
|
|
8957
|
+
columnTruncated: { maxColumn: columnCap, restored: true }
|
|
8958
|
+
};
|
|
8959
|
+
}
|
|
8960
|
+
}
|
|
8542
8961
|
}
|
|
8543
8962
|
}
|
|
8544
8963
|
if (name === "write" && details && typeof details === "object" && !Array.isArray(details)) {
|
|
8545
8964
|
const { codePreviewBeforeWrite: _before, ...publicDetails } = details;
|
|
8546
8965
|
details = Object.keys(publicDetails).length > 0 ? publicDetails : void 0;
|
|
8547
8966
|
}
|
|
8548
|
-
return { ok: true, output
|
|
8967
|
+
return { ok: true, output, details: details ?? null };
|
|
8549
8968
|
};
|
|
8550
8969
|
var OmpToolsProvider = class _OmpToolsProvider {
|
|
8551
8970
|
static async create(cwd, catalog, capturedTools) {
|
|
@@ -8567,7 +8986,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8567
8986
|
bash: createNativeBashToolDefinition(cwd, this.#artifactPaths),
|
|
8568
8987
|
edit: createNativeReplaceEditToolDefinition(cwd),
|
|
8569
8988
|
write: createPreviewWriteToolDefinition(cwd),
|
|
8570
|
-
grep:
|
|
8989
|
+
grep: createGrepDefinitionWithSkip(cwd),
|
|
8571
8990
|
find: createFindToolDefinition(cwd),
|
|
8572
8991
|
ls: createLsToolDefinition(cwd)
|
|
8573
8992
|
};
|
|
@@ -8608,6 +9027,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8608
9027
|
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...record, [OMP_BASH_CWD_KEY]: args[OMP_BASH_CWD_KEY] } : record;
|
|
8609
9028
|
return resolveShellCwdArgument(actionName, this.#cwd, shellArgs);
|
|
8610
9029
|
}
|
|
9030
|
+
if (actionName === "read") return normalizeReadArguments(record);
|
|
8611
9031
|
return actionName === "edit" ? normalizeEditArguments(record, args.all === true, this.#cwd) : record;
|
|
8612
9032
|
}
|
|
8613
9033
|
#assertAllowed(name) {
|
|
@@ -8638,27 +9058,28 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8638
9058
|
const intercepted = await tryExecuteGitWorktreeAdd(args, this.#cwd);
|
|
8639
9059
|
if (intercepted) {
|
|
8640
9060
|
this.#attachPreview(name, intercepted, args, context);
|
|
8641
|
-
return this.#normalizeResult(name, intercepted, args);
|
|
9061
|
+
return this.#normalizeResult(name, intercepted, args, context);
|
|
8642
9062
|
}
|
|
8643
9063
|
}
|
|
8644
9064
|
if (this.#catalog?.get(name)) {
|
|
8645
9065
|
const result = await this.#capturedTools.invoke(name, args, context);
|
|
8646
9066
|
this.#attachReadMedia(name, result, context);
|
|
8647
9067
|
this.#attachReadNote(name, result, context);
|
|
8648
|
-
return this.#normalizeResult(name, result, args, false);
|
|
9068
|
+
return this.#normalizeResult(name, result, args, context, false);
|
|
8649
9069
|
}
|
|
8650
9070
|
const tool = this.#definitionFor(name, args);
|
|
8651
9071
|
const runner = this.#catalog?.runner;
|
|
8652
9072
|
if (!runner) {
|
|
9073
|
+
const artifacts = [];
|
|
8653
9074
|
const result = await runAbortable(
|
|
8654
9075
|
context.signal,
|
|
8655
|
-
() => tool.execute(
|
|
9076
|
+
() => artifactAllocations.run(artifacts, () => tool.execute(
|
|
8656
9077
|
context.nestedToolCallId,
|
|
8657
9078
|
args,
|
|
8658
9079
|
context.signal,
|
|
8659
9080
|
(partialResult) => this.#attachPartialPreview(name, partialResult, args, context),
|
|
8660
9081
|
this.#executionContextFor(name, args, context.extensionContext)
|
|
8661
|
-
)
|
|
9082
|
+
))
|
|
8662
9083
|
).catch((error) => {
|
|
8663
9084
|
throwIfAborted(context.signal);
|
|
8664
9085
|
throw isOmpShellToolName(name) ? classifyOmpBashError(error) : error;
|
|
@@ -8670,7 +9091,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8670
9091
|
this.#attachReadMedia(name, result, context);
|
|
8671
9092
|
this.#attachReadNote(name, result, context);
|
|
8672
9093
|
this.#attachPreview(name, result, args, context);
|
|
8673
|
-
return this.#normalizeResult(name, result, args);
|
|
9094
|
+
return this.#normalizeResult(name, result, args, context, true, artifacts);
|
|
8674
9095
|
}
|
|
8675
9096
|
return this.#invokeWithEvents(name, tool, args, context, runner);
|
|
8676
9097
|
}
|
|
@@ -8694,6 +9115,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8694
9115
|
let isError = false;
|
|
8695
9116
|
let thrown;
|
|
8696
9117
|
let executionStarted = false;
|
|
9118
|
+
const artifacts = [];
|
|
8697
9119
|
let updateTail = Promise.resolve();
|
|
8698
9120
|
try {
|
|
8699
9121
|
const preflight = await runAbortable(context.signal, () => runner.emitToolCall({
|
|
@@ -8707,7 +9129,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8707
9129
|
throw new Error(preflight.reason || `OMP tool ${name} was blocked`);
|
|
8708
9130
|
}
|
|
8709
9131
|
executionStarted = true;
|
|
8710
|
-
result = await runAbortable(context.signal, () => tool.execute(
|
|
9132
|
+
result = await runAbortable(context.signal, () => artifactAllocations.run(artifacts, () => tool.execute(
|
|
8711
9133
|
toolCallId,
|
|
8712
9134
|
args,
|
|
8713
9135
|
context.signal,
|
|
@@ -8724,7 +9146,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8724
9146
|
).catch(() => void 0);
|
|
8725
9147
|
},
|
|
8726
9148
|
this.#executionContextFor(name, args, context.extensionContext)
|
|
8727
|
-
));
|
|
9149
|
+
)));
|
|
8728
9150
|
isError = result.isError === true;
|
|
8729
9151
|
} catch (error) {
|
|
8730
9152
|
thrown = isOmpShellToolName(name) && executionStarted ? classifyOmpBashError(error) : error;
|
|
@@ -8777,16 +9199,110 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8777
9199
|
throw new Error(text || (thrown instanceof Error ? thrown.message : `OMP tool ${name} failed`));
|
|
8778
9200
|
}
|
|
8779
9201
|
this.#attachPreview(name, result, args, context);
|
|
8780
|
-
return this.#normalizeResult(name, result, args, patch?.content === void 0);
|
|
9202
|
+
return this.#normalizeResult(name, result, args, context, patch?.content === void 0, artifacts);
|
|
8781
9203
|
}
|
|
8782
9204
|
// Schema-enforce and early-startup calls may have no ExtensionRunner, so the
|
|
8783
9205
|
// top-level tool_result marker middleware cannot run. Expand again at the
|
|
8784
9206
|
// provider boundary; replacement is idempotent when middleware already ran.
|
|
8785
|
-
#normalizeResult(name, result, args, appendReadNewline = true) {
|
|
8786
|
-
const
|
|
9207
|
+
async #normalizeResult(name, result, args, context, appendReadNewline = true, artifacts) {
|
|
9208
|
+
const extras = {};
|
|
9209
|
+
if (isOmpShellToolName(name)) {
|
|
9210
|
+
const artifactPath = artifacts?.at(-1);
|
|
9211
|
+
if (artifactPath !== void 0) extras.bashArtifactPath = artifactPath;
|
|
9212
|
+
extras.maxResultChars = resultCharBound(context);
|
|
9213
|
+
}
|
|
9214
|
+
let effective = result;
|
|
9215
|
+
if (name === "read" && !this.#catalog?.get(name)) {
|
|
9216
|
+
const paged = await this.#completeRead(result, args, context);
|
|
9217
|
+
effective = paged.result;
|
|
9218
|
+
extras.read = paged.read;
|
|
9219
|
+
}
|
|
9220
|
+
const normalized = normalizeResult(name, effective, this.#artifactPaths, appendReadNewline, extras);
|
|
8787
9221
|
if (name !== "read" || typeof normalized !== "string") return normalized;
|
|
9222
|
+
if (UNREADABLE_READ_NOTE.test(normalized)) throw new Error(unreadableReadMessage(normalized, extras.read?.path));
|
|
8788
9223
|
return expandSkillDirMarkersForRead(normalized, args, this.#cwd);
|
|
8789
9224
|
}
|
|
9225
|
+
async #completeRead(result, args, context) {
|
|
9226
|
+
const rawPath = args.path;
|
|
9227
|
+
const readPath = typeof rawPath === "string" ? rawPath : void 0;
|
|
9228
|
+
const base = readPath === void 0 ? {} : { path: readPath };
|
|
9229
|
+
const meta = readTruncationMeta(result.details);
|
|
9230
|
+
const target = parseReadTarget(rawPath);
|
|
9231
|
+
if (!meta || !target || result.isError === true) return { result, read: base };
|
|
9232
|
+
if (meta.truncatedBy === "bytes" || meta.partialLine) {
|
|
9233
|
+
return { result, read: { ...base, signal: byteBudgetSignal(meta) } };
|
|
9234
|
+
}
|
|
9235
|
+
const tool = this.#tools.read;
|
|
9236
|
+
if (!tool || !target.pageable || meta.nextOffset === void 0) {
|
|
9237
|
+
return { result, read: { ...base, signal: lineBudgetSignal(meta, target, void 0) } };
|
|
9238
|
+
}
|
|
9239
|
+
const budget = resultCharBound(context) - READ_MARKER_RESERVE_CHARS;
|
|
9240
|
+
let text = stripRepeatReadHint(textContent(result.content));
|
|
9241
|
+
let covered = meta.shownEnd ?? countLines(text);
|
|
9242
|
+
let nextOffset = meta.nextOffset;
|
|
9243
|
+
let stopped;
|
|
9244
|
+
while (nextOffset !== void 0 && covered < target.endLimit) {
|
|
9245
|
+
if (text.length + covered >= budget) {
|
|
9246
|
+
stopped = "budget";
|
|
9247
|
+
break;
|
|
9248
|
+
}
|
|
9249
|
+
const selector = readPageSelector(target, nextOffset);
|
|
9250
|
+
const page = await runAbortable(
|
|
9251
|
+
context.signal,
|
|
9252
|
+
() => tool.execute(
|
|
9253
|
+
context.nestedToolCallId,
|
|
9254
|
+
{ ...args, path: selector },
|
|
9255
|
+
context.signal,
|
|
9256
|
+
() => {
|
|
9257
|
+
},
|
|
9258
|
+
this.#executionContextFor("read", args, context.extensionContext)
|
|
9259
|
+
)
|
|
9260
|
+
);
|
|
9261
|
+
const pageMeta = readTruncationMeta(page.details);
|
|
9262
|
+
const pageText = stripRepeatReadHint(textContent(page.content));
|
|
9263
|
+
const start = pageMeta?.shownStart ?? nextOffset;
|
|
9264
|
+
const body = dropLeadingLines(pageText, Math.max(0, covered - start + 1));
|
|
9265
|
+
const pageEnd = pageMeta?.shownEnd ?? start + countLines(pageText) - 1;
|
|
9266
|
+
if (body.length === 0 || pageEnd <= covered) {
|
|
9267
|
+
nextOffset = void 0;
|
|
9268
|
+
break;
|
|
9269
|
+
}
|
|
9270
|
+
const candidate = `${text.endsWith("\n") ? text : `${text}
|
|
9271
|
+
`}${body}`;
|
|
9272
|
+
if (candidate.length + pageEnd >= budget) {
|
|
9273
|
+
stopped = "budget";
|
|
9274
|
+
break;
|
|
9275
|
+
}
|
|
9276
|
+
text = candidate;
|
|
9277
|
+
covered = pageEnd;
|
|
9278
|
+
nextOffset = pageMeta?.nextOffset;
|
|
9279
|
+
if (pageMeta?.truncatedBy === "bytes" || pageMeta?.partialLine === true) {
|
|
9280
|
+
stopped = "bytes";
|
|
9281
|
+
break;
|
|
9282
|
+
}
|
|
9283
|
+
}
|
|
9284
|
+
if (target.endLimit !== Number.POSITIVE_INFINITY && covered > target.endLimit) {
|
|
9285
|
+
text = keepLeadingLines(text, target.endLimit - target.start + 1);
|
|
9286
|
+
covered = target.endLimit;
|
|
9287
|
+
}
|
|
9288
|
+
const remaining = stopped !== void 0 || nextOffset !== void 0 && covered < target.endLimit;
|
|
9289
|
+
const paged = {
|
|
9290
|
+
content: [{ type: "text", text }],
|
|
9291
|
+
details: result.details
|
|
9292
|
+
};
|
|
9293
|
+
if (!remaining) return { result: paged, read: base };
|
|
9294
|
+
return {
|
|
9295
|
+
result: paged,
|
|
9296
|
+
read: {
|
|
9297
|
+
...base,
|
|
9298
|
+
signal: lineBudgetSignal(meta, target, {
|
|
9299
|
+
nextOffset,
|
|
9300
|
+
delivered: covered,
|
|
9301
|
+
reason: stopped === "bytes" ? "byteBudget" : "resultBudget"
|
|
9302
|
+
})
|
|
9303
|
+
}
|
|
9304
|
+
};
|
|
9305
|
+
}
|
|
8790
9306
|
#attachPartialPreview(name, partialResult, args, context) {
|
|
8791
9307
|
const progress = textContent(partialResult.content).trim();
|
|
8792
9308
|
const boundedProgress = Array.from(progress).slice(-4e3).join("");
|
|
@@ -8876,7 +9392,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8876
9392
|
import { spawn } from "node:child_process";
|
|
8877
9393
|
import { createHash as createHash3, randomBytes, randomUUID as randomUUID4 } from "node:crypto";
|
|
8878
9394
|
import fs8 from "node:fs";
|
|
8879
|
-
import
|
|
9395
|
+
import path13 from "node:path";
|
|
8880
9396
|
|
|
8881
9397
|
// src/schema/types.ts
|
|
8882
9398
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -8885,7 +9401,7 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
8885
9401
|
import { execFileSync } from "node:child_process";
|
|
8886
9402
|
import { createHash as createHash2 } from "node:crypto";
|
|
8887
9403
|
import fs7 from "node:fs";
|
|
8888
|
-
import
|
|
9404
|
+
import path12 from "node:path";
|
|
8889
9405
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
8890
9406
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
8891
9407
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -8903,10 +9419,10 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
8903
9419
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8904
9420
|
});
|
|
8905
9421
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
8906
|
-
var normalizeRelative = (value) => value.split(
|
|
9422
|
+
var normalizeRelative = (value) => value.split(path12.sep).join("/");
|
|
8907
9423
|
var isInside = (root, candidate) => {
|
|
8908
|
-
const relative =
|
|
8909
|
-
return relative === "" || !
|
|
9424
|
+
const relative = path12.relative(root, candidate);
|
|
9425
|
+
return relative === "" || !path12.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path12.sep}`);
|
|
8910
9426
|
};
|
|
8911
9427
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
8912
9428
|
var entryDigest = (absolute) => {
|
|
@@ -8932,12 +9448,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
8932
9448
|
let bytes = 0;
|
|
8933
9449
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
8934
9450
|
for (const relativeInput of unique) {
|
|
8935
|
-
const absolute =
|
|
9451
|
+
const absolute = path12.resolve(cwd, relativeInput);
|
|
8936
9452
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
8937
9453
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
8938
9454
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
8939
9455
|
}
|
|
8940
|
-
const relative = normalizeRelative(
|
|
9456
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8941
9457
|
const entry = entryDigest(absolute);
|
|
8942
9458
|
bytes += entry.bytes;
|
|
8943
9459
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -8966,9 +9482,9 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8966
9482
|
const entries = fs7.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
8967
9483
|
for (const entry of entries) {
|
|
8968
9484
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
8969
|
-
const absolute =
|
|
9485
|
+
const absolute = path12.join(directory, entry.name);
|
|
8970
9486
|
if (excluded(absolute, exclusions)) continue;
|
|
8971
|
-
const relative = normalizeRelative(
|
|
9487
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8972
9488
|
if (entry.isDirectory()) visit(absolute);
|
|
8973
9489
|
else paths.push(relative);
|
|
8974
9490
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -8982,7 +9498,7 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8982
9498
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
8983
9499
|
const cwd = fs7.realpathSync(cwdInput);
|
|
8984
9500
|
const exclusions = excludedRoots.map((root) => {
|
|
8985
|
-
const absolute =
|
|
9501
|
+
const absolute = path12.resolve(root);
|
|
8986
9502
|
try {
|
|
8987
9503
|
return fs7.realpathSync(absolute);
|
|
8988
9504
|
} catch {
|
|
@@ -9020,18 +9536,18 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
9020
9536
|
);
|
|
9021
9537
|
};
|
|
9022
9538
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
9023
|
-
if (!requestedPath.trim() ||
|
|
9539
|
+
if (!requestedPath.trim() || path12.isAbsolute(requestedPath)) {
|
|
9024
9540
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
9025
9541
|
}
|
|
9026
9542
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9027
|
-
const absolute =
|
|
9543
|
+
const absolute = path12.resolve(cwd, requestedPath);
|
|
9028
9544
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
9029
9545
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
9030
9546
|
}
|
|
9031
|
-
const relativeParts =
|
|
9547
|
+
const relativeParts = path12.relative(cwd, absolute).split(path12.sep);
|
|
9032
9548
|
let cursor = cwd;
|
|
9033
9549
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
9034
|
-
cursor =
|
|
9550
|
+
cursor = path12.join(cursor, relativeParts[index]);
|
|
9035
9551
|
let stat2;
|
|
9036
9552
|
try {
|
|
9037
9553
|
stat2 = fs7.lstatSync(cursor);
|
|
@@ -9040,9 +9556,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9040
9556
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
9041
9557
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
9042
9558
|
}
|
|
9043
|
-
const parentReal = fs7.realpathSync(
|
|
9559
|
+
const parentReal = fs7.realpathSync(path12.dirname(cursor));
|
|
9044
9560
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
9045
|
-
return { absolute, relative: normalizeRelative(
|
|
9561
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: false };
|
|
9046
9562
|
}
|
|
9047
9563
|
throw error;
|
|
9048
9564
|
}
|
|
@@ -9054,7 +9570,7 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9054
9570
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
9055
9571
|
}
|
|
9056
9572
|
}
|
|
9057
|
-
return { absolute, relative: normalizeRelative(
|
|
9573
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: true };
|
|
9058
9574
|
};
|
|
9059
9575
|
var sha256File = (absolute) => `sha256:${digest(fs7.readFileSync(absolute))}`;
|
|
9060
9576
|
|
|
@@ -9105,8 +9621,8 @@ var SchemaController = class {
|
|
|
9105
9621
|
this.identity = identity;
|
|
9106
9622
|
this.state = state;
|
|
9107
9623
|
this.cwd = fs8.realpathSync(cwd);
|
|
9108
|
-
this.#journalRoot =
|
|
9109
|
-
this.#lockPath =
|
|
9624
|
+
this.#journalRoot = path13.join(mesh.root, "schema-transactions");
|
|
9625
|
+
this.#lockPath = path13.join(this.#journalRoot, ".commit.lock");
|
|
9110
9626
|
this.#recoverJournals();
|
|
9111
9627
|
}
|
|
9112
9628
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -9305,7 +9821,7 @@ var SchemaController = class {
|
|
|
9305
9821
|
this.#assertPayloadBound(input);
|
|
9306
9822
|
const release = this.#acquireCommitLock();
|
|
9307
9823
|
const transactionId = randomUUID4();
|
|
9308
|
-
const journalPath =
|
|
9824
|
+
const journalPath = path13.join(this.#journalRoot, `${transactionId}.json`);
|
|
9309
9825
|
let journal;
|
|
9310
9826
|
let consumed = false;
|
|
9311
9827
|
let committed = false;
|
|
@@ -9786,7 +10302,7 @@ ${Date.now()}
|
|
|
9786
10302
|
}
|
|
9787
10303
|
for (const name of fs8.readdirSync(this.#journalRoot)) {
|
|
9788
10304
|
if (!name.endsWith(".json")) continue;
|
|
9789
|
-
const filePath =
|
|
10305
|
+
const filePath = path13.join(this.#journalRoot, name);
|
|
9790
10306
|
try {
|
|
9791
10307
|
const journal = JSON.parse(fs8.readFileSync(filePath, "utf8"));
|
|
9792
10308
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
@@ -10040,11 +10556,11 @@ var SchemaProvider = class {
|
|
|
10040
10556
|
|
|
10041
10557
|
// src/state/store.ts
|
|
10042
10558
|
import { createHash as createHash5 } from "node:crypto";
|
|
10043
|
-
import
|
|
10559
|
+
import path15 from "node:path";
|
|
10044
10560
|
|
|
10045
10561
|
// src/state/complexity.ts
|
|
10046
10562
|
import fs9 from "node:fs";
|
|
10047
|
-
import
|
|
10563
|
+
import path14 from "node:path";
|
|
10048
10564
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
10049
10565
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
10050
10566
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -10276,7 +10792,7 @@ var languageComplexities = [
|
|
|
10276
10792
|
typeScriptJavaScriptComplexity
|
|
10277
10793
|
];
|
|
10278
10794
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
10279
|
-
const extension =
|
|
10795
|
+
const extension = path14.extname(file).toLowerCase();
|
|
10280
10796
|
return languages.find((language) => language.extensions.includes(extension));
|
|
10281
10797
|
};
|
|
10282
10798
|
var countFileComplexity = (file) => {
|
|
@@ -11167,7 +11683,7 @@ var StateStore = class {
|
|
|
11167
11683
|
const files = [];
|
|
11168
11684
|
let netDelta = 0;
|
|
11169
11685
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
11170
|
-
const measured = countFileComplexity(
|
|
11686
|
+
const measured = countFileComplexity(path15.resolve(input.cwd, file));
|
|
11171
11687
|
if (!measured) {
|
|
11172
11688
|
files.push({ file, supported: false });
|
|
11173
11689
|
continue;
|
|
@@ -11194,7 +11710,7 @@ var StateStore = class {
|
|
|
11194
11710
|
const updates = [];
|
|
11195
11711
|
let netDelta = 0;
|
|
11196
11712
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
11197
|
-
const measured = countFileComplexity(
|
|
11713
|
+
const measured = countFileComplexity(path15.resolve(cwd, file));
|
|
11198
11714
|
if (!measured) {
|
|
11199
11715
|
deltas.push({ file, supported: false });
|
|
11200
11716
|
continue;
|
|
@@ -11244,11 +11760,11 @@ var StateStore = class {
|
|
|
11244
11760
|
const normalized = /* @__PURE__ */ new Set();
|
|
11245
11761
|
for (const file of files) {
|
|
11246
11762
|
if (!file.trim()) continue;
|
|
11247
|
-
const relative =
|
|
11248
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
11763
|
+
const relative = path15.relative(cwd, path15.resolve(cwd, file));
|
|
11764
|
+
if (relative === ".." || relative.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative)) {
|
|
11249
11765
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
11250
11766
|
}
|
|
11251
|
-
normalized.add(relative.split(
|
|
11767
|
+
normalized.add(relative.split(path15.sep).join("/"));
|
|
11252
11768
|
}
|
|
11253
11769
|
return [...normalized];
|
|
11254
11770
|
}
|
|
@@ -12203,13 +12719,9 @@ var FabricRuntimeState = class {
|
|
|
12203
12719
|
create: () => new McpProvider(context.cwd, this.#config.mcp, {
|
|
12204
12720
|
...this.#config.mcp.cache.enabled ? {
|
|
12205
12721
|
cache: new McpDescriptorCacheStore(
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
"fabric",
|
|
12210
|
-
"mcp-cache.json"
|
|
12211
|
-
)
|
|
12212
|
-
)
|
|
12722
|
+
projectMcpCachePath(process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd)
|
|
12723
|
+
),
|
|
12724
|
+
globalCache: new McpDescriptorCacheStore(globalMcpCachePath(resolveAgentDir()))
|
|
12213
12725
|
} : {},
|
|
12214
12726
|
hooks: {
|
|
12215
12727
|
onSliceChanged: () => {
|
|
@@ -12223,9 +12735,7 @@ var FabricRuntimeState = class {
|
|
|
12223
12735
|
unmounted: (provider) => {
|
|
12224
12736
|
if (this.#mcpProvider === provider) this.#mcpProvider = void 0;
|
|
12225
12737
|
},
|
|
12226
|
-
start: (provider) =>
|
|
12227
|
-
provider.warmup();
|
|
12228
|
-
}
|
|
12738
|
+
start: (provider) => provider.warmup()
|
|
12229
12739
|
}));
|
|
12230
12740
|
if (capturedToolsProvider && !enforceSchema) {
|
|
12231
12741
|
await installBuiltin(createProviderComponent({
|
|
@@ -12248,7 +12758,7 @@ var FabricRuntimeState = class {
|
|
|
12248
12758
|
this.#mainAgent = mainAgent;
|
|
12249
12759
|
const projectRoot = process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
12250
12760
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
12251
|
-
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
12761
|
+
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path16.resolve(projectRoot, configuredMeshRoot) : path16.join(projectRoot, ".omp", "fabric", "mesh"));
|
|
12252
12762
|
this.#mesh = new MeshStore(
|
|
12253
12763
|
meshRoot,
|
|
12254
12764
|
this.#config.mesh.maxEventBytes,
|
|
@@ -12301,6 +12811,12 @@ var FabricRuntimeState = class {
|
|
|
12301
12811
|
this.#compact = new CompactController({
|
|
12302
12812
|
onRequest: (intent) => void this.#publishCompactEvent("requested", intent),
|
|
12303
12813
|
onCommit: (info) => void this.#publishCompactEvent(info.status, info)
|
|
12814
|
+
}, {
|
|
12815
|
+
settings: () => ({
|
|
12816
|
+
engine: this.#config?.compaction.engine ?? DEFAULT_FABRIC_CONFIG.compaction.engine,
|
|
12817
|
+
targetContextRatio: this.#config?.compaction.targetContextRatio ?? DEFAULT_FABRIC_CONFIG.compaction.targetContextRatio
|
|
12818
|
+
}),
|
|
12819
|
+
outcomes: fileCompactOutcomeStore()
|
|
12304
12820
|
});
|
|
12305
12821
|
await installBuiltin(createProviderComponent({
|
|
12306
12822
|
provider: "compact",
|
|
@@ -12403,8 +12919,8 @@ var FabricRuntimeState = class {
|
|
|
12403
12919
|
};
|
|
12404
12920
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
12405
12921
|
const actorRoots = {
|
|
12406
|
-
project:
|
|
12407
|
-
session:
|
|
12922
|
+
project: path16.join(meshRoot, "actors"),
|
|
12923
|
+
session: path16.join(meshRoot, "actors", fabricSessionId)
|
|
12408
12924
|
};
|
|
12409
12925
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
12410
12926
|
cwd: context.cwd,
|