omp-fabric 0.85.1 → 1.0.3
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 +64 -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 +886 -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,206 @@ 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 WINDOWS_PATH_ROOT_PATTERN = /^(?:\\\\[?.]\\)?[A-Za-z]:(?=[\\/])/;
|
|
8734
|
+
var withoutWindowsRoot = (rawPath) => rawPath.slice(WINDOWS_PATH_ROOT_PATTERN.exec(rawPath)?.[0].length ?? 0);
|
|
8735
|
+
var readPageSelector = (target, offset) => target.endLimit === Number.POSITIVE_INFINITY ? `${target.base}:raw:${offset}-` : `${target.base}:raw:${offset}-${target.endLimit}`;
|
|
8736
|
+
var parseReadTarget = (rawPath) => {
|
|
8737
|
+
if (typeof rawPath !== "string" || rawPath.length === 0 || rawPath.includes("://")) return void 0;
|
|
8738
|
+
const match = READ_SELECTOR_PATTERN.exec(rawPath);
|
|
8739
|
+
if (match) {
|
|
8740
|
+
const end = match[3] === void 0 ? Number.POSITIVE_INFINITY : match[4] === void 0 ? Number.POSITIVE_INFINITY : Number(match[4]);
|
|
8741
|
+
return { base: rawPath.slice(0, match.index), start: Number(match[2]), endLimit: end, pageable: true, selected: true };
|
|
8742
|
+
}
|
|
8743
|
+
if (READ_RAW_SELECTOR_PATTERN.test(rawPath)) {
|
|
8744
|
+
return {
|
|
8745
|
+
base: rawPath.replace(READ_RAW_SELECTOR_PATTERN, ""),
|
|
8746
|
+
start: 1,
|
|
8747
|
+
endLimit: Number.POSITIVE_INFINITY,
|
|
8748
|
+
pageable: true,
|
|
8749
|
+
selected: true
|
|
8750
|
+
};
|
|
8751
|
+
}
|
|
8752
|
+
const body = withoutWindowsRoot(rawPath);
|
|
8753
|
+
const lastColon = body.lastIndexOf(":");
|
|
8754
|
+
const suffix = lastColon === -1 ? "" : body.slice(lastColon + 1);
|
|
8755
|
+
const pageable = suffix.length === 0;
|
|
8756
|
+
return { base: rawPath, start: 1, endLimit: Number.POSITIVE_INFINITY, pageable, selected: false };
|
|
8757
|
+
};
|
|
8758
|
+
var unreadableReadMessage = (note, readPath) => {
|
|
8759
|
+
const target = typeof readPath === "string" ? readPath.replace(READ_SELECTOR_PATTERN, "") : void 0;
|
|
8760
|
+
const remedy = target ? ` Read the bytes with omp.read("${target}:raw").` : "";
|
|
8761
|
+
return `omp.read returned no text content: ${note.trim()}${remedy}`;
|
|
8762
|
+
};
|
|
8763
|
+
var restoreBashOutput = (artifactPath, maxChars, delivered) => {
|
|
8764
|
+
if (!artifactPath || maxChars <= 0) return void 0;
|
|
8765
|
+
let size;
|
|
8766
|
+
try {
|
|
8767
|
+
size = statSync3(artifactPath).size;
|
|
8768
|
+
} catch {
|
|
8769
|
+
return void 0;
|
|
8770
|
+
}
|
|
8771
|
+
if (size === 0 || size > maxChars) return void 0;
|
|
8772
|
+
let full;
|
|
8773
|
+
try {
|
|
8774
|
+
full = readFileSync2(artifactPath, "utf8");
|
|
8775
|
+
} catch {
|
|
8776
|
+
return void 0;
|
|
8777
|
+
}
|
|
8778
|
+
if (full.length < delivered.length) return void 0;
|
|
8779
|
+
const ellipsis = delivered.indexOf("\u2026");
|
|
8780
|
+
const prefix = ellipsis === -1 ? delivered : delivered.slice(0, ellipsis);
|
|
8781
|
+
return full.startsWith(prefix) ? full : void 0;
|
|
8782
|
+
};
|
|
8783
|
+
var withoutColumnLimit = (detailRecord, metaRecord) => {
|
|
8784
|
+
const limits = asRecord(metaRecord?.limits);
|
|
8785
|
+
if (!metaRecord || !limits || !Object.hasOwn(limits, "columnTruncated")) return detailRecord;
|
|
8786
|
+
const { columnTruncated: _dropped, ...remainingLimits } = limits;
|
|
8787
|
+
const { limits: _limits, ...remainingMeta } = metaRecord;
|
|
8788
|
+
const nextMeta = Object.keys(remainingLimits).length > 0 ? { ...remainingMeta, limits: remainingLimits } : remainingMeta;
|
|
8789
|
+
if (Object.keys(nextMeta).length > 0) return { ...detailRecord, meta: nextMeta };
|
|
8790
|
+
const { meta: _meta, ...remainingDetails } = detailRecord;
|
|
8791
|
+
return remainingDetails;
|
|
8792
|
+
};
|
|
8793
|
+
var grepTruncationSignal = (details) => {
|
|
8794
|
+
const record = asRecord(details);
|
|
8795
|
+
if (!record || record.truncated !== true) return void 0;
|
|
8796
|
+
const perFile = finiteNumber2(record.perFileLimitReached);
|
|
8797
|
+
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(record.meta)?.limits)?.columnTruncated)?.maxColumn);
|
|
8798
|
+
const fileCount = finiteNumber2(record.fileCount);
|
|
8799
|
+
const reasons = [];
|
|
8800
|
+
const notes = [];
|
|
8801
|
+
let continuation = null;
|
|
8802
|
+
if (perFile !== void 0) {
|
|
8803
|
+
reasons.push("matchLimit");
|
|
8804
|
+
notes.push(
|
|
8805
|
+
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.`
|
|
8806
|
+
);
|
|
8807
|
+
}
|
|
8808
|
+
if (maxColumn !== void 0) {
|
|
8809
|
+
reasons.push("columnLimit");
|
|
8810
|
+
notes.push(
|
|
8811
|
+
`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>").`
|
|
8812
|
+
);
|
|
8813
|
+
}
|
|
8814
|
+
if (reasons.length === 0) {
|
|
8815
|
+
reasons.push("fileLimit");
|
|
8816
|
+
if (fileCount !== void 0) continuation = { skip: fileCount };
|
|
8817
|
+
notes.push(
|
|
8818
|
+
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.`
|
|
8819
|
+
);
|
|
8820
|
+
}
|
|
8821
|
+
return {
|
|
8822
|
+
tool: "grep",
|
|
8823
|
+
partial: true,
|
|
8824
|
+
reasons,
|
|
8825
|
+
...finiteNumber2(record.matchCount) === void 0 ? {} : { matchCount: record.matchCount },
|
|
8826
|
+
...fileCount === void 0 ? {} : { fileCount },
|
|
8827
|
+
...perFile === void 0 ? {} : { perFileMatchLimit: perFile },
|
|
8828
|
+
...maxColumn === void 0 ? {} : { maxColumn },
|
|
8829
|
+
continue: continuation,
|
|
8830
|
+
note: notes.join(" ")
|
|
8831
|
+
};
|
|
8832
|
+
};
|
|
8833
|
+
var GUEST_RESULT_CHAR_FALLBACK = 1e6;
|
|
8834
|
+
var READ_MARKER_RESERVE_CHARS = 512;
|
|
8835
|
+
var resultCharBound = (context) => {
|
|
8836
|
+
const value = Reflect.get(context, "maxResultChars");
|
|
8837
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : GUEST_RESULT_CHAR_FALLBACK;
|
|
8838
|
+
};
|
|
8839
|
+
var byteBudgetSignal = (meta) => ({
|
|
8840
|
+
tool: "read",
|
|
8841
|
+
partial: true,
|
|
8842
|
+
reasons: ["byteBudget"],
|
|
8843
|
+
totalBytes: meta.totalBytes ?? null,
|
|
8844
|
+
deliveredBytes: meta.outputBytes ?? null,
|
|
8845
|
+
continue: null,
|
|
8846
|
+
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."
|
|
8847
|
+
});
|
|
8848
|
+
var lineBudgetSignal = (meta, target, progress) => {
|
|
8849
|
+
const nextOffset = progress ? progress.nextOffset : meta.nextOffset;
|
|
8850
|
+
const continuation = target && nextOffset !== void 0 ? readPageSelector(target, nextOffset) : null;
|
|
8851
|
+
return {
|
|
8852
|
+
tool: "read",
|
|
8853
|
+
partial: true,
|
|
8854
|
+
reasons: [progress?.reason ?? "lineBudget"],
|
|
8855
|
+
totalLines: meta.totalLines ?? null,
|
|
8856
|
+
deliveredLines: progress?.delivered ?? null,
|
|
8857
|
+
continue: continuation,
|
|
8858
|
+
note: continuation ? `More lines remain; continue with omp.read("${continuation}").` : "More lines remain and the host offered no continuation offset."
|
|
8859
|
+
};
|
|
8860
|
+
};
|
|
8861
|
+
var findTruncationSignal = (details) => {
|
|
8862
|
+
const record = asRecord(details);
|
|
8863
|
+
if (!record || record.truncated !== true) return void 0;
|
|
8864
|
+
const reached = finiteNumber2(record.resultLimitReached) ?? finiteNumber2(record.fileCount);
|
|
8865
|
+
return {
|
|
8866
|
+
tool: "find",
|
|
8867
|
+
partial: true,
|
|
8868
|
+
reasons: ["resultLimit"],
|
|
8869
|
+
...reached === void 0 ? {} : { resultLimit: reached },
|
|
8870
|
+
continue: null,
|
|
8871
|
+
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.`
|
|
8872
|
+
};
|
|
8873
|
+
};
|
|
8506
8874
|
var resultHasTruncation = (details) => {
|
|
8507
8875
|
if (details === null || typeof details !== "object" || Array.isArray(details)) return false;
|
|
8508
8876
|
const meta = Reflect.get(details, "meta");
|
|
@@ -8516,15 +8884,26 @@ var resultExitCode = (details) => {
|
|
|
8516
8884
|
const exitCode = Reflect.get(details, "exitCode");
|
|
8517
8885
|
return Number.isSafeInteger(exitCode) && exitCode > 0 ? exitCode : void 0;
|
|
8518
8886
|
};
|
|
8519
|
-
var normalizeResult = (name, result, artifactPaths, appendReadNewline = true) => {
|
|
8520
|
-
const
|
|
8887
|
+
var normalizeResult = (name, result, artifactPaths, appendReadNewline = true, extras) => {
|
|
8888
|
+
const readSignal = extras?.read;
|
|
8889
|
+
const text = isOmpShellToolName(name) ? stripOmpBashTiming(textContent(result.content)) : name === "read" ? stripRepeatReadHint(textContent(result.content)) : textContent(result.content);
|
|
8521
8890
|
if (result.isError && !resultHasTruncation(result.details)) throw new Error(text || `${name} failed`);
|
|
8522
8891
|
if (name === "read") {
|
|
8523
|
-
|
|
8892
|
+
const body = appendReadNewline && text.length > 0 && !text.endsWith("\n") ? `${text}
|
|
8524
8893
|
` : text;
|
|
8894
|
+
return readSignal?.signal ? appendTruncationMarker(body, readSignal.signal) : body;
|
|
8895
|
+
}
|
|
8896
|
+
if (name === "grep") {
|
|
8897
|
+
const signal = grepTruncationSignal(result.details);
|
|
8898
|
+
return signal ? appendTruncationMarker(text, signal) : text;
|
|
8525
8899
|
}
|
|
8526
|
-
if (name === "
|
|
8900
|
+
if (name === "find") {
|
|
8901
|
+
const signal = findTruncationSignal(result.details);
|
|
8902
|
+
return signal ? appendTruncationMarker(text, signal) : text;
|
|
8903
|
+
}
|
|
8904
|
+
if (name === "ls") return text;
|
|
8527
8905
|
let details = result.details;
|
|
8906
|
+
let output = text;
|
|
8528
8907
|
if (isOmpShellToolName(name) && details && typeof details === "object" && !Array.isArray(details)) {
|
|
8529
8908
|
const detailRecord = details;
|
|
8530
8909
|
const meta = detailRecord.meta;
|
|
@@ -8533,19 +8912,62 @@ var normalizeResult = (name, result, artifactPaths, appendReadNewline = true) =>
|
|
|
8533
8912
|
if (truncation && typeof truncation === "object" && !Array.isArray(truncation)) {
|
|
8534
8913
|
const truncationRecord = truncation;
|
|
8535
8914
|
const artifactId = truncationRecord.artifactId;
|
|
8536
|
-
const fullOutputPath = typeof artifactId === "string" ? artifactPaths?.get(artifactId) :
|
|
8915
|
+
const fullOutputPath = typeof artifactId === "string" ? artifactPaths?.get(artifactId) ?? extras?.bashArtifactPath : extras?.bashArtifactPath;
|
|
8537
8916
|
details = {
|
|
8538
8917
|
...detailRecord,
|
|
8539
8918
|
truncation: { ...truncationRecord, truncated: true },
|
|
8540
8919
|
...fullOutputPath ? { fullOutputPath } : {}
|
|
8541
8920
|
};
|
|
8921
|
+
if (truncationRecord.truncated !== false) {
|
|
8922
|
+
const columnCap = finiteNumber2(asRecord(asRecord(metaRecord?.limits)?.columnTruncated)?.maxColumn);
|
|
8923
|
+
output = appendTruncationMarker(text, {
|
|
8924
|
+
tool: name,
|
|
8925
|
+
partial: true,
|
|
8926
|
+
reasons: columnCap === void 0 ? ["outputLimit"] : ["outputLimit", "columnLimit"],
|
|
8927
|
+
truncatedBy: truncationRecord.truncatedBy ?? null,
|
|
8928
|
+
totalLines: finiteNumber2(truncationRecord.totalLines) ?? null,
|
|
8929
|
+
totalBytes: finiteNumber2(truncationRecord.totalBytes) ?? null,
|
|
8930
|
+
deliveredBytes: finiteNumber2(truncationRecord.outputBytes) ?? null,
|
|
8931
|
+
...columnCap === void 0 ? {} : { maxColumn: columnCap },
|
|
8932
|
+
fullOutputPath: fullOutputPath ?? null,
|
|
8933
|
+
continue: null,
|
|
8934
|
+
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."
|
|
8935
|
+
});
|
|
8936
|
+
}
|
|
8937
|
+
} else {
|
|
8938
|
+
const columnCap = finiteNumber2(asRecord(asRecord(metaRecord?.limits)?.columnTruncated)?.maxColumn);
|
|
8939
|
+
if (columnCap !== void 0) {
|
|
8940
|
+
const restored = restoreBashOutput(extras?.bashArtifactPath, extras?.maxResultChars ?? 0, text);
|
|
8941
|
+
if (restored === void 0) {
|
|
8942
|
+
details = {
|
|
8943
|
+
...detailRecord,
|
|
8944
|
+
columnTruncated: { maxColumn: columnCap, restored: false },
|
|
8945
|
+
...extras?.bashArtifactPath ? { fullOutputPath: extras.bashArtifactPath } : {}
|
|
8946
|
+
};
|
|
8947
|
+
output = appendTruncationMarker(text, {
|
|
8948
|
+
tool: name,
|
|
8949
|
+
partial: true,
|
|
8950
|
+
reasons: ["columnLimit"],
|
|
8951
|
+
maxColumn: columnCap,
|
|
8952
|
+
fullOutputPath: extras?.bashArtifactPath ?? null,
|
|
8953
|
+
continue: null,
|
|
8954
|
+
note: `Output lines were cut at ${columnCap} bytes by the host bash executor, which reads global settings and ignores this session's tools.outputMaxColumns.`
|
|
8955
|
+
});
|
|
8956
|
+
} else {
|
|
8957
|
+
output = restored;
|
|
8958
|
+
details = {
|
|
8959
|
+
...withoutColumnLimit(detailRecord, metaRecord),
|
|
8960
|
+
columnTruncated: { maxColumn: columnCap, restored: true }
|
|
8961
|
+
};
|
|
8962
|
+
}
|
|
8963
|
+
}
|
|
8542
8964
|
}
|
|
8543
8965
|
}
|
|
8544
8966
|
if (name === "write" && details && typeof details === "object" && !Array.isArray(details)) {
|
|
8545
8967
|
const { codePreviewBeforeWrite: _before, ...publicDetails } = details;
|
|
8546
8968
|
details = Object.keys(publicDetails).length > 0 ? publicDetails : void 0;
|
|
8547
8969
|
}
|
|
8548
|
-
return { ok: true, output
|
|
8970
|
+
return { ok: true, output, details: details ?? null };
|
|
8549
8971
|
};
|
|
8550
8972
|
var OmpToolsProvider = class _OmpToolsProvider {
|
|
8551
8973
|
static async create(cwd, catalog, capturedTools) {
|
|
@@ -8567,7 +8989,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8567
8989
|
bash: createNativeBashToolDefinition(cwd, this.#artifactPaths),
|
|
8568
8990
|
edit: createNativeReplaceEditToolDefinition(cwd),
|
|
8569
8991
|
write: createPreviewWriteToolDefinition(cwd),
|
|
8570
|
-
grep:
|
|
8992
|
+
grep: createGrepDefinitionWithSkip(cwd),
|
|
8571
8993
|
find: createFindToolDefinition(cwd),
|
|
8572
8994
|
ls: createLsToolDefinition(cwd)
|
|
8573
8995
|
};
|
|
@@ -8608,6 +9030,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8608
9030
|
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...record, [OMP_BASH_CWD_KEY]: args[OMP_BASH_CWD_KEY] } : record;
|
|
8609
9031
|
return resolveShellCwdArgument(actionName, this.#cwd, shellArgs);
|
|
8610
9032
|
}
|
|
9033
|
+
if (actionName === "read") return normalizeReadArguments(record);
|
|
8611
9034
|
return actionName === "edit" ? normalizeEditArguments(record, args.all === true, this.#cwd) : record;
|
|
8612
9035
|
}
|
|
8613
9036
|
#assertAllowed(name) {
|
|
@@ -8638,27 +9061,28 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8638
9061
|
const intercepted = await tryExecuteGitWorktreeAdd(args, this.#cwd);
|
|
8639
9062
|
if (intercepted) {
|
|
8640
9063
|
this.#attachPreview(name, intercepted, args, context);
|
|
8641
|
-
return this.#normalizeResult(name, intercepted, args);
|
|
9064
|
+
return this.#normalizeResult(name, intercepted, args, context);
|
|
8642
9065
|
}
|
|
8643
9066
|
}
|
|
8644
9067
|
if (this.#catalog?.get(name)) {
|
|
8645
9068
|
const result = await this.#capturedTools.invoke(name, args, context);
|
|
8646
9069
|
this.#attachReadMedia(name, result, context);
|
|
8647
9070
|
this.#attachReadNote(name, result, context);
|
|
8648
|
-
return this.#normalizeResult(name, result, args, false);
|
|
9071
|
+
return this.#normalizeResult(name, result, args, context, false);
|
|
8649
9072
|
}
|
|
8650
9073
|
const tool = this.#definitionFor(name, args);
|
|
8651
9074
|
const runner = this.#catalog?.runner;
|
|
8652
9075
|
if (!runner) {
|
|
9076
|
+
const artifacts = [];
|
|
8653
9077
|
const result = await runAbortable(
|
|
8654
9078
|
context.signal,
|
|
8655
|
-
() => tool.execute(
|
|
9079
|
+
() => artifactAllocations.run(artifacts, () => tool.execute(
|
|
8656
9080
|
context.nestedToolCallId,
|
|
8657
9081
|
args,
|
|
8658
9082
|
context.signal,
|
|
8659
9083
|
(partialResult) => this.#attachPartialPreview(name, partialResult, args, context),
|
|
8660
9084
|
this.#executionContextFor(name, args, context.extensionContext)
|
|
8661
|
-
)
|
|
9085
|
+
))
|
|
8662
9086
|
).catch((error) => {
|
|
8663
9087
|
throwIfAborted(context.signal);
|
|
8664
9088
|
throw isOmpShellToolName(name) ? classifyOmpBashError(error) : error;
|
|
@@ -8670,7 +9094,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8670
9094
|
this.#attachReadMedia(name, result, context);
|
|
8671
9095
|
this.#attachReadNote(name, result, context);
|
|
8672
9096
|
this.#attachPreview(name, result, args, context);
|
|
8673
|
-
return this.#normalizeResult(name, result, args);
|
|
9097
|
+
return this.#normalizeResult(name, result, args, context, true, artifacts);
|
|
8674
9098
|
}
|
|
8675
9099
|
return this.#invokeWithEvents(name, tool, args, context, runner);
|
|
8676
9100
|
}
|
|
@@ -8694,6 +9118,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8694
9118
|
let isError = false;
|
|
8695
9119
|
let thrown;
|
|
8696
9120
|
let executionStarted = false;
|
|
9121
|
+
const artifacts = [];
|
|
8697
9122
|
let updateTail = Promise.resolve();
|
|
8698
9123
|
try {
|
|
8699
9124
|
const preflight = await runAbortable(context.signal, () => runner.emitToolCall({
|
|
@@ -8707,7 +9132,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8707
9132
|
throw new Error(preflight.reason || `OMP tool ${name} was blocked`);
|
|
8708
9133
|
}
|
|
8709
9134
|
executionStarted = true;
|
|
8710
|
-
result = await runAbortable(context.signal, () => tool.execute(
|
|
9135
|
+
result = await runAbortable(context.signal, () => artifactAllocations.run(artifacts, () => tool.execute(
|
|
8711
9136
|
toolCallId,
|
|
8712
9137
|
args,
|
|
8713
9138
|
context.signal,
|
|
@@ -8724,7 +9149,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8724
9149
|
).catch(() => void 0);
|
|
8725
9150
|
},
|
|
8726
9151
|
this.#executionContextFor(name, args, context.extensionContext)
|
|
8727
|
-
));
|
|
9152
|
+
)));
|
|
8728
9153
|
isError = result.isError === true;
|
|
8729
9154
|
} catch (error) {
|
|
8730
9155
|
thrown = isOmpShellToolName(name) && executionStarted ? classifyOmpBashError(error) : error;
|
|
@@ -8777,16 +9202,110 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8777
9202
|
throw new Error(text || (thrown instanceof Error ? thrown.message : `OMP tool ${name} failed`));
|
|
8778
9203
|
}
|
|
8779
9204
|
this.#attachPreview(name, result, args, context);
|
|
8780
|
-
return this.#normalizeResult(name, result, args, patch?.content === void 0);
|
|
9205
|
+
return this.#normalizeResult(name, result, args, context, patch?.content === void 0, artifacts);
|
|
8781
9206
|
}
|
|
8782
9207
|
// Schema-enforce and early-startup calls may have no ExtensionRunner, so the
|
|
8783
9208
|
// top-level tool_result marker middleware cannot run. Expand again at the
|
|
8784
9209
|
// provider boundary; replacement is idempotent when middleware already ran.
|
|
8785
|
-
#normalizeResult(name, result, args, appendReadNewline = true) {
|
|
8786
|
-
const
|
|
9210
|
+
async #normalizeResult(name, result, args, context, appendReadNewline = true, artifacts) {
|
|
9211
|
+
const extras = {};
|
|
9212
|
+
if (isOmpShellToolName(name)) {
|
|
9213
|
+
const artifactPath = artifacts?.at(-1);
|
|
9214
|
+
if (artifactPath !== void 0) extras.bashArtifactPath = artifactPath;
|
|
9215
|
+
extras.maxResultChars = resultCharBound(context);
|
|
9216
|
+
}
|
|
9217
|
+
let effective = result;
|
|
9218
|
+
if (name === "read" && !this.#catalog?.get(name)) {
|
|
9219
|
+
const paged = await this.#completeRead(result, args, context);
|
|
9220
|
+
effective = paged.result;
|
|
9221
|
+
extras.read = paged.read;
|
|
9222
|
+
}
|
|
9223
|
+
const normalized = normalizeResult(name, effective, this.#artifactPaths, appendReadNewline, extras);
|
|
8787
9224
|
if (name !== "read" || typeof normalized !== "string") return normalized;
|
|
9225
|
+
if (UNREADABLE_READ_NOTE.test(normalized)) throw new Error(unreadableReadMessage(normalized, extras.read?.path));
|
|
8788
9226
|
return expandSkillDirMarkersForRead(normalized, args, this.#cwd);
|
|
8789
9227
|
}
|
|
9228
|
+
async #completeRead(result, args, context) {
|
|
9229
|
+
const rawPath = args.path;
|
|
9230
|
+
const readPath = typeof rawPath === "string" ? rawPath : void 0;
|
|
9231
|
+
const base = readPath === void 0 ? {} : { path: readPath };
|
|
9232
|
+
const meta = readTruncationMeta(result.details);
|
|
9233
|
+
const target = parseReadTarget(rawPath);
|
|
9234
|
+
if (!meta || !target || result.isError === true) return { result, read: base };
|
|
9235
|
+
if (meta.truncatedBy === "bytes" || meta.partialLine) {
|
|
9236
|
+
return { result, read: { ...base, signal: byteBudgetSignal(meta) } };
|
|
9237
|
+
}
|
|
9238
|
+
const tool = this.#tools.read;
|
|
9239
|
+
if (!tool || !target.pageable || meta.nextOffset === void 0) {
|
|
9240
|
+
return { result, read: { ...base, signal: lineBudgetSignal(meta, target, void 0) } };
|
|
9241
|
+
}
|
|
9242
|
+
const budget = resultCharBound(context) - READ_MARKER_RESERVE_CHARS;
|
|
9243
|
+
let text = stripRepeatReadHint(textContent(result.content));
|
|
9244
|
+
let covered = meta.shownEnd ?? countLines(text);
|
|
9245
|
+
let nextOffset = meta.nextOffset;
|
|
9246
|
+
let stopped;
|
|
9247
|
+
while (nextOffset !== void 0 && covered < target.endLimit) {
|
|
9248
|
+
if (text.length + covered >= budget) {
|
|
9249
|
+
stopped = "budget";
|
|
9250
|
+
break;
|
|
9251
|
+
}
|
|
9252
|
+
const selector = readPageSelector(target, nextOffset);
|
|
9253
|
+
const page = await runAbortable(
|
|
9254
|
+
context.signal,
|
|
9255
|
+
() => tool.execute(
|
|
9256
|
+
context.nestedToolCallId,
|
|
9257
|
+
{ ...args, path: selector },
|
|
9258
|
+
context.signal,
|
|
9259
|
+
() => {
|
|
9260
|
+
},
|
|
9261
|
+
this.#executionContextFor("read", args, context.extensionContext)
|
|
9262
|
+
)
|
|
9263
|
+
);
|
|
9264
|
+
const pageMeta = readTruncationMeta(page.details);
|
|
9265
|
+
const pageText = stripRepeatReadHint(textContent(page.content));
|
|
9266
|
+
const start = pageMeta?.shownStart ?? nextOffset;
|
|
9267
|
+
const body = dropLeadingLines(pageText, Math.max(0, covered - start + 1));
|
|
9268
|
+
const pageEnd = pageMeta?.shownEnd ?? start + countLines(pageText) - 1;
|
|
9269
|
+
if (body.length === 0 || pageEnd <= covered) {
|
|
9270
|
+
nextOffset = void 0;
|
|
9271
|
+
break;
|
|
9272
|
+
}
|
|
9273
|
+
const candidate = `${text.endsWith("\n") ? text : `${text}
|
|
9274
|
+
`}${body}`;
|
|
9275
|
+
if (candidate.length + pageEnd >= budget) {
|
|
9276
|
+
stopped = "budget";
|
|
9277
|
+
break;
|
|
9278
|
+
}
|
|
9279
|
+
text = candidate;
|
|
9280
|
+
covered = pageEnd;
|
|
9281
|
+
nextOffset = pageMeta?.nextOffset;
|
|
9282
|
+
if (pageMeta?.truncatedBy === "bytes" || pageMeta?.partialLine === true) {
|
|
9283
|
+
stopped = "bytes";
|
|
9284
|
+
break;
|
|
9285
|
+
}
|
|
9286
|
+
}
|
|
9287
|
+
if (target.endLimit !== Number.POSITIVE_INFINITY && covered > target.endLimit) {
|
|
9288
|
+
text = keepLeadingLines(text, target.endLimit - target.start + 1);
|
|
9289
|
+
covered = target.endLimit;
|
|
9290
|
+
}
|
|
9291
|
+
const remaining = stopped !== void 0 || nextOffset !== void 0 && covered < target.endLimit;
|
|
9292
|
+
const paged = {
|
|
9293
|
+
content: [{ type: "text", text }],
|
|
9294
|
+
details: result.details
|
|
9295
|
+
};
|
|
9296
|
+
if (!remaining) return { result: paged, read: base };
|
|
9297
|
+
return {
|
|
9298
|
+
result: paged,
|
|
9299
|
+
read: {
|
|
9300
|
+
...base,
|
|
9301
|
+
signal: lineBudgetSignal(meta, target, {
|
|
9302
|
+
nextOffset,
|
|
9303
|
+
delivered: covered,
|
|
9304
|
+
reason: stopped === "bytes" ? "byteBudget" : "resultBudget"
|
|
9305
|
+
})
|
|
9306
|
+
}
|
|
9307
|
+
};
|
|
9308
|
+
}
|
|
8790
9309
|
#attachPartialPreview(name, partialResult, args, context) {
|
|
8791
9310
|
const progress = textContent(partialResult.content).trim();
|
|
8792
9311
|
const boundedProgress = Array.from(progress).slice(-4e3).join("");
|
|
@@ -8876,7 +9395,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
8876
9395
|
import { spawn } from "node:child_process";
|
|
8877
9396
|
import { createHash as createHash3, randomBytes, randomUUID as randomUUID4 } from "node:crypto";
|
|
8878
9397
|
import fs8 from "node:fs";
|
|
8879
|
-
import
|
|
9398
|
+
import path13 from "node:path";
|
|
8880
9399
|
|
|
8881
9400
|
// src/schema/types.ts
|
|
8882
9401
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -8885,7 +9404,7 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
8885
9404
|
import { execFileSync } from "node:child_process";
|
|
8886
9405
|
import { createHash as createHash2 } from "node:crypto";
|
|
8887
9406
|
import fs7 from "node:fs";
|
|
8888
|
-
import
|
|
9407
|
+
import path12 from "node:path";
|
|
8889
9408
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
8890
9409
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
8891
9410
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -8903,10 +9422,10 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
8903
9422
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8904
9423
|
});
|
|
8905
9424
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
8906
|
-
var normalizeRelative = (value) => value.split(
|
|
9425
|
+
var normalizeRelative = (value) => value.split(path12.sep).join("/");
|
|
8907
9426
|
var isInside = (root, candidate) => {
|
|
8908
|
-
const relative =
|
|
8909
|
-
return relative === "" || !
|
|
9427
|
+
const relative = path12.relative(root, candidate);
|
|
9428
|
+
return relative === "" || !path12.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path12.sep}`);
|
|
8910
9429
|
};
|
|
8911
9430
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
8912
9431
|
var entryDigest = (absolute) => {
|
|
@@ -8932,12 +9451,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
8932
9451
|
let bytes = 0;
|
|
8933
9452
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
8934
9453
|
for (const relativeInput of unique) {
|
|
8935
|
-
const absolute =
|
|
9454
|
+
const absolute = path12.resolve(cwd, relativeInput);
|
|
8936
9455
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
8937
9456
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
8938
9457
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
8939
9458
|
}
|
|
8940
|
-
const relative = normalizeRelative(
|
|
9459
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8941
9460
|
const entry = entryDigest(absolute);
|
|
8942
9461
|
bytes += entry.bytes;
|
|
8943
9462
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -8966,9 +9485,9 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8966
9485
|
const entries = fs7.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
8967
9486
|
for (const entry of entries) {
|
|
8968
9487
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
8969
|
-
const absolute =
|
|
9488
|
+
const absolute = path12.join(directory, entry.name);
|
|
8970
9489
|
if (excluded(absolute, exclusions)) continue;
|
|
8971
|
-
const relative = normalizeRelative(
|
|
9490
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8972
9491
|
if (entry.isDirectory()) visit(absolute);
|
|
8973
9492
|
else paths.push(relative);
|
|
8974
9493
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -8982,7 +9501,7 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8982
9501
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
8983
9502
|
const cwd = fs7.realpathSync(cwdInput);
|
|
8984
9503
|
const exclusions = excludedRoots.map((root) => {
|
|
8985
|
-
const absolute =
|
|
9504
|
+
const absolute = path12.resolve(root);
|
|
8986
9505
|
try {
|
|
8987
9506
|
return fs7.realpathSync(absolute);
|
|
8988
9507
|
} catch {
|
|
@@ -9020,18 +9539,18 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
9020
9539
|
);
|
|
9021
9540
|
};
|
|
9022
9541
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
9023
|
-
if (!requestedPath.trim() ||
|
|
9542
|
+
if (!requestedPath.trim() || path12.isAbsolute(requestedPath)) {
|
|
9024
9543
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
9025
9544
|
}
|
|
9026
9545
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9027
|
-
const absolute =
|
|
9546
|
+
const absolute = path12.resolve(cwd, requestedPath);
|
|
9028
9547
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
9029
9548
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
9030
9549
|
}
|
|
9031
|
-
const relativeParts =
|
|
9550
|
+
const relativeParts = path12.relative(cwd, absolute).split(path12.sep);
|
|
9032
9551
|
let cursor = cwd;
|
|
9033
9552
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
9034
|
-
cursor =
|
|
9553
|
+
cursor = path12.join(cursor, relativeParts[index]);
|
|
9035
9554
|
let stat2;
|
|
9036
9555
|
try {
|
|
9037
9556
|
stat2 = fs7.lstatSync(cursor);
|
|
@@ -9040,9 +9559,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9040
9559
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
9041
9560
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
9042
9561
|
}
|
|
9043
|
-
const parentReal = fs7.realpathSync(
|
|
9562
|
+
const parentReal = fs7.realpathSync(path12.dirname(cursor));
|
|
9044
9563
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
9045
|
-
return { absolute, relative: normalizeRelative(
|
|
9564
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: false };
|
|
9046
9565
|
}
|
|
9047
9566
|
throw error;
|
|
9048
9567
|
}
|
|
@@ -9054,7 +9573,7 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9054
9573
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
9055
9574
|
}
|
|
9056
9575
|
}
|
|
9057
|
-
return { absolute, relative: normalizeRelative(
|
|
9576
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: true };
|
|
9058
9577
|
};
|
|
9059
9578
|
var sha256File = (absolute) => `sha256:${digest(fs7.readFileSync(absolute))}`;
|
|
9060
9579
|
|
|
@@ -9105,8 +9624,8 @@ var SchemaController = class {
|
|
|
9105
9624
|
this.identity = identity;
|
|
9106
9625
|
this.state = state;
|
|
9107
9626
|
this.cwd = fs8.realpathSync(cwd);
|
|
9108
|
-
this.#journalRoot =
|
|
9109
|
-
this.#lockPath =
|
|
9627
|
+
this.#journalRoot = path13.join(mesh.root, "schema-transactions");
|
|
9628
|
+
this.#lockPath = path13.join(this.#journalRoot, ".commit.lock");
|
|
9110
9629
|
this.#recoverJournals();
|
|
9111
9630
|
}
|
|
9112
9631
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -9305,7 +9824,7 @@ var SchemaController = class {
|
|
|
9305
9824
|
this.#assertPayloadBound(input);
|
|
9306
9825
|
const release = this.#acquireCommitLock();
|
|
9307
9826
|
const transactionId = randomUUID4();
|
|
9308
|
-
const journalPath =
|
|
9827
|
+
const journalPath = path13.join(this.#journalRoot, `${transactionId}.json`);
|
|
9309
9828
|
let journal;
|
|
9310
9829
|
let consumed = false;
|
|
9311
9830
|
let committed = false;
|
|
@@ -9786,7 +10305,7 @@ ${Date.now()}
|
|
|
9786
10305
|
}
|
|
9787
10306
|
for (const name of fs8.readdirSync(this.#journalRoot)) {
|
|
9788
10307
|
if (!name.endsWith(".json")) continue;
|
|
9789
|
-
const filePath =
|
|
10308
|
+
const filePath = path13.join(this.#journalRoot, name);
|
|
9790
10309
|
try {
|
|
9791
10310
|
const journal = JSON.parse(fs8.readFileSync(filePath, "utf8"));
|
|
9792
10311
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
@@ -10040,11 +10559,11 @@ var SchemaProvider = class {
|
|
|
10040
10559
|
|
|
10041
10560
|
// src/state/store.ts
|
|
10042
10561
|
import { createHash as createHash5 } from "node:crypto";
|
|
10043
|
-
import
|
|
10562
|
+
import path15 from "node:path";
|
|
10044
10563
|
|
|
10045
10564
|
// src/state/complexity.ts
|
|
10046
10565
|
import fs9 from "node:fs";
|
|
10047
|
-
import
|
|
10566
|
+
import path14 from "node:path";
|
|
10048
10567
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
10049
10568
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
10050
10569
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -10276,7 +10795,7 @@ var languageComplexities = [
|
|
|
10276
10795
|
typeScriptJavaScriptComplexity
|
|
10277
10796
|
];
|
|
10278
10797
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
10279
|
-
const extension =
|
|
10798
|
+
const extension = path14.extname(file).toLowerCase();
|
|
10280
10799
|
return languages.find((language) => language.extensions.includes(extension));
|
|
10281
10800
|
};
|
|
10282
10801
|
var countFileComplexity = (file) => {
|
|
@@ -11167,7 +11686,7 @@ var StateStore = class {
|
|
|
11167
11686
|
const files = [];
|
|
11168
11687
|
let netDelta = 0;
|
|
11169
11688
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
11170
|
-
const measured = countFileComplexity(
|
|
11689
|
+
const measured = countFileComplexity(path15.resolve(input.cwd, file));
|
|
11171
11690
|
if (!measured) {
|
|
11172
11691
|
files.push({ file, supported: false });
|
|
11173
11692
|
continue;
|
|
@@ -11194,7 +11713,7 @@ var StateStore = class {
|
|
|
11194
11713
|
const updates = [];
|
|
11195
11714
|
let netDelta = 0;
|
|
11196
11715
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
11197
|
-
const measured = countFileComplexity(
|
|
11716
|
+
const measured = countFileComplexity(path15.resolve(cwd, file));
|
|
11198
11717
|
if (!measured) {
|
|
11199
11718
|
deltas.push({ file, supported: false });
|
|
11200
11719
|
continue;
|
|
@@ -11244,11 +11763,11 @@ var StateStore = class {
|
|
|
11244
11763
|
const normalized = /* @__PURE__ */ new Set();
|
|
11245
11764
|
for (const file of files) {
|
|
11246
11765
|
if (!file.trim()) continue;
|
|
11247
|
-
const relative =
|
|
11248
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
11766
|
+
const relative = path15.relative(cwd, path15.resolve(cwd, file));
|
|
11767
|
+
if (relative === ".." || relative.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative)) {
|
|
11249
11768
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
11250
11769
|
}
|
|
11251
|
-
normalized.add(relative.split(
|
|
11770
|
+
normalized.add(relative.split(path15.sep).join("/"));
|
|
11252
11771
|
}
|
|
11253
11772
|
return [...normalized];
|
|
11254
11773
|
}
|
|
@@ -12203,13 +12722,9 @@ var FabricRuntimeState = class {
|
|
|
12203
12722
|
create: () => new McpProvider(context.cwd, this.#config.mcp, {
|
|
12204
12723
|
...this.#config.mcp.cache.enabled ? {
|
|
12205
12724
|
cache: new McpDescriptorCacheStore(
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
"fabric",
|
|
12210
|
-
"mcp-cache.json"
|
|
12211
|
-
)
|
|
12212
|
-
)
|
|
12725
|
+
projectMcpCachePath(process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd)
|
|
12726
|
+
),
|
|
12727
|
+
globalCache: new McpDescriptorCacheStore(globalMcpCachePath(resolveAgentDir()))
|
|
12213
12728
|
} : {},
|
|
12214
12729
|
hooks: {
|
|
12215
12730
|
onSliceChanged: () => {
|
|
@@ -12223,9 +12738,7 @@ var FabricRuntimeState = class {
|
|
|
12223
12738
|
unmounted: (provider) => {
|
|
12224
12739
|
if (this.#mcpProvider === provider) this.#mcpProvider = void 0;
|
|
12225
12740
|
},
|
|
12226
|
-
start: (provider) =>
|
|
12227
|
-
provider.warmup();
|
|
12228
|
-
}
|
|
12741
|
+
start: (provider) => provider.warmup()
|
|
12229
12742
|
}));
|
|
12230
12743
|
if (capturedToolsProvider && !enforceSchema) {
|
|
12231
12744
|
await installBuiltin(createProviderComponent({
|
|
@@ -12248,7 +12761,7 @@ var FabricRuntimeState = class {
|
|
|
12248
12761
|
this.#mainAgent = mainAgent;
|
|
12249
12762
|
const projectRoot = process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
12250
12763
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
12251
|
-
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
12764
|
+
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path16.resolve(projectRoot, configuredMeshRoot) : path16.join(projectRoot, ".omp", "fabric", "mesh"));
|
|
12252
12765
|
this.#mesh = new MeshStore(
|
|
12253
12766
|
meshRoot,
|
|
12254
12767
|
this.#config.mesh.maxEventBytes,
|
|
@@ -12301,6 +12814,12 @@ var FabricRuntimeState = class {
|
|
|
12301
12814
|
this.#compact = new CompactController({
|
|
12302
12815
|
onRequest: (intent) => void this.#publishCompactEvent("requested", intent),
|
|
12303
12816
|
onCommit: (info) => void this.#publishCompactEvent(info.status, info)
|
|
12817
|
+
}, {
|
|
12818
|
+
settings: () => ({
|
|
12819
|
+
engine: this.#config?.compaction.engine ?? DEFAULT_FABRIC_CONFIG.compaction.engine,
|
|
12820
|
+
targetContextRatio: this.#config?.compaction.targetContextRatio ?? DEFAULT_FABRIC_CONFIG.compaction.targetContextRatio
|
|
12821
|
+
}),
|
|
12822
|
+
outcomes: fileCompactOutcomeStore()
|
|
12304
12823
|
});
|
|
12305
12824
|
await installBuiltin(createProviderComponent({
|
|
12306
12825
|
provider: "compact",
|
|
@@ -12403,8 +12922,8 @@ var FabricRuntimeState = class {
|
|
|
12403
12922
|
};
|
|
12404
12923
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
12405
12924
|
const actorRoots = {
|
|
12406
|
-
project:
|
|
12407
|
-
session:
|
|
12925
|
+
project: path16.join(meshRoot, "actors"),
|
|
12926
|
+
session: path16.join(meshRoot, "actors", fabricSessionId)
|
|
12408
12927
|
};
|
|
12409
12928
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
12410
12929
|
cwd: context.cwd,
|