omp-fabric 1.18.4 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +2 -1
  3. package/dist/chunks/{chunk-N5DHCLLX.js → chunk-4J65SMNI.js} +4 -4
  4. package/dist/chunks/{chunk-T5ZA5YRU.js → chunk-52JBWP2C.js} +2 -2
  5. package/dist/chunks/{chunk-GIBZGL4G.js → chunk-5FYSQRJ4.js} +44 -2
  6. package/dist/chunks/chunk-5FYSQRJ4.js.map +7 -0
  7. package/dist/chunks/{chunk-YOAZ5SO7.js → chunk-BAHZYDFD.js} +66 -1
  8. package/dist/chunks/{chunk-YOAZ5SO7.js.map → chunk-BAHZYDFD.js.map} +2 -2
  9. package/dist/chunks/{chunk-6QBPSZJ5.js → chunk-BPMSLBX4.js} +2 -2
  10. package/dist/chunks/{chunk-BMIE4PIL.js → chunk-DTG3DYVC.js} +3 -3
  11. package/dist/chunks/{chunk-X3XY6SAU.js → chunk-LNP6JVCZ.js} +4 -4
  12. package/dist/chunks/{chunk-FX3XLQYI.js → chunk-MQSRZC2O.js} +2 -2
  13. package/dist/chunks/{chunk-VYB7ROEH.js → chunk-NP5U3BJZ.js} +3 -3
  14. package/dist/chunks/{chunk-7OAFYAJC.js → chunk-PUGB6NGD.js} +3 -3
  15. package/dist/chunks/{chunk-2LGLDM34.js → chunk-R4EFMCIY.js} +5 -3
  16. package/dist/chunks/{chunk-2LGLDM34.js.map → chunk-R4EFMCIY.js.map} +2 -2
  17. package/dist/chunks/{chunk-C5JMLDIM.js → chunk-RA2IB2QT.js} +2 -2
  18. package/dist/chunks/{chunk-QNRGTJGE.js → chunk-RAWYAQQJ.js} +2 -1
  19. package/dist/chunks/chunk-RAWYAQQJ.js.map +7 -0
  20. package/dist/chunks/{chunk-2KEWFW56.js → chunk-SDZXNTBF.js} +2 -2
  21. package/dist/chunks/{chunk-RBA54WC7.js → chunk-X2SKPWJA.js} +1 -1
  22. package/dist/chunks/{chunk-RBA54WC7.js.map → chunk-X2SKPWJA.js.map} +1 -1
  23. package/dist/chunks/{chunk-4HQDSTHN.js → chunk-YBNCEX5E.js} +2 -2
  24. package/dist/chunks/{chunk-6N4XGAZY.js → chunk-ZFMSJLQE.js} +6 -2
  25. package/dist/chunks/{chunk-6N4XGAZY.js.map → chunk-ZFMSJLQE.js.map} +2 -2
  26. package/dist/chunks/{chunk-WMB6QCWX.js → chunk-ZQ72MAHY.js} +41 -15
  27. package/dist/chunks/chunk-ZQ72MAHY.js.map +7 -0
  28. package/dist/compaction/hook.js +4 -4
  29. package/dist/compaction/lcm-runtime.js +5 -5
  30. package/dist/config.d.ts +15 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/core/action-registry.d.ts.map +1 -1
  33. package/dist/core/action-registry.js +4 -4
  34. package/dist/core/omp-tools.d.ts +3 -0
  35. package/dist/core/omp-tools.d.ts.map +1 -1
  36. package/dist/core/system-guidance.d.ts +1 -1
  37. package/dist/core/system-guidance.d.ts.map +1 -1
  38. package/dist/core/token-math.d.ts +12 -0
  39. package/dist/core/token-math.d.ts.map +1 -1
  40. package/dist/core/tool-ownership.d.ts +2 -0
  41. package/dist/core/tool-ownership.d.ts.map +1 -1
  42. package/dist/entropy/index.js +6 -6
  43. package/dist/fabric-runtime-state.d.ts +2 -0
  44. package/dist/fabric-runtime-state.d.ts.map +1 -1
  45. package/dist/fabric-runtime-state.js +512 -91
  46. package/dist/fabric-runtime-state.js.map +4 -4
  47. package/dist/fabric-state.d.ts +1 -0
  48. package/dist/fabric-state.d.ts.map +1 -1
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +39 -20
  51. package/dist/index.js.map +2 -2
  52. package/dist/judgment/host-judge.d.ts +12 -0
  53. package/dist/judgment/host-judge.d.ts.map +1 -0
  54. package/dist/judgment/lane.d.ts +43 -0
  55. package/dist/judgment/lane.d.ts.map +1 -0
  56. package/dist/memory/discovery.js +5 -5
  57. package/dist/memory/normalize.js +4 -4
  58. package/dist/memory/search.js +5 -5
  59. package/dist/protocol.d.ts +2 -0
  60. package/dist/protocol.d.ts.map +1 -1
  61. package/dist/protocol.js +1 -1
  62. package/dist/providers/judgment-provider.d.ts +13 -0
  63. package/dist/providers/judgment-provider.d.ts.map +1 -0
  64. package/dist/providers/memory-provider.js +7 -7
  65. package/dist/providers/omp-tools-provider.d.ts +5 -2
  66. package/dist/providers/omp-tools-provider.d.ts.map +1 -1
  67. package/dist/residency/host.js +8 -8
  68. package/dist/residency/omp-entry.js +8 -8
  69. package/dist/runtime/core-override-guest-types.js +2 -2
  70. package/dist/runtime/guest-types.d.ts +1 -1
  71. package/dist/runtime/guest-types.d.ts.map +1 -1
  72. package/dist/runtime/guest-types.js +1 -1
  73. package/dist/runtime/node-process-runtime.js +2 -2
  74. package/dist/runtime/quickjs-runtime.d.ts +1 -1
  75. package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
  76. package/dist/runtime/quickjs-runtime.js +1 -1
  77. package/dist/ui/conversation.js +1 -1
  78. package/dist/ui/conversation.js.map +2 -2
  79. package/dist/ui/dashboard.js.map +1 -1
  80. package/dist/ui/settings.d.ts +1 -1
  81. package/dist/ui/settings.d.ts.map +1 -1
  82. package/dist/ui/settings.js +76 -3
  83. package/dist/ui/settings.js.map +2 -2
  84. package/docs/architecture.md +1 -1
  85. package/docs/configuration.md +14 -1
  86. package/docs/judgment.md +57 -0
  87. package/package.json +8 -8
  88. package/dist/chunks/chunk-GIBZGL4G.js.map +0 -7
  89. package/dist/chunks/chunk-QNRGTJGE.js.map +0 -7
  90. package/dist/chunks/chunk-WMB6QCWX.js.map +0 -7
  91. /package/dist/chunks/{chunk-N5DHCLLX.js.map → chunk-4J65SMNI.js.map} +0 -0
  92. /package/dist/chunks/{chunk-T5ZA5YRU.js.map → chunk-52JBWP2C.js.map} +0 -0
  93. /package/dist/chunks/{chunk-6QBPSZJ5.js.map → chunk-BPMSLBX4.js.map} +0 -0
  94. /package/dist/chunks/{chunk-BMIE4PIL.js.map → chunk-DTG3DYVC.js.map} +0 -0
  95. /package/dist/chunks/{chunk-X3XY6SAU.js.map → chunk-LNP6JVCZ.js.map} +0 -0
  96. /package/dist/chunks/{chunk-FX3XLQYI.js.map → chunk-MQSRZC2O.js.map} +0 -0
  97. /package/dist/chunks/{chunk-VYB7ROEH.js.map → chunk-NP5U3BJZ.js.map} +0 -0
  98. /package/dist/chunks/{chunk-7OAFYAJC.js.map → chunk-PUGB6NGD.js.map} +0 -0
  99. /package/dist/chunks/{chunk-C5JMLDIM.js.map → chunk-RA2IB2QT.js.map} +0 -0
  100. /package/dist/chunks/{chunk-2KEWFW56.js.map → chunk-SDZXNTBF.js.map} +0 -0
  101. /package/dist/chunks/{chunk-4HQDSTHN.js.map → chunk-YBNCEX5E.js.map} +0 -0
@@ -11,8 +11,8 @@ import {
11
11
  MemoryProvider,
12
12
  actionArgNormalizer,
13
13
  uniqueDeclaredKeyForSpelling
14
- } from "./chunks/chunk-N5DHCLLX.js";
15
- import "./chunks/chunk-2KEWFW56.js";
14
+ } from "./chunks/chunk-4J65SMNI.js";
15
+ import "./chunks/chunk-SDZXNTBF.js";
16
16
  import "./chunks/chunk-U5FYOMG5.js";
17
17
  import {
18
18
  ApprovalController,
@@ -33,7 +33,7 @@ import {
33
33
  repairFabricGuestCode,
34
34
  resolveFabricIdentity,
35
35
  runFabricHandoffAtBoundary
36
- } from "./chunks/chunk-X3XY6SAU.js";
36
+ } from "./chunks/chunk-LNP6JVCZ.js";
37
37
  import "./chunks/chunk-7VIQNUPS.js";
38
38
  import {
39
39
  AgentTranscriptReader,
@@ -50,7 +50,7 @@ import {
50
50
  repairActionName,
51
51
  setActiveCompiledSurface,
52
52
  setActiveRepairCompiler
53
- } from "./chunks/chunk-2LGLDM34.js";
53
+ } from "./chunks/chunk-R4EFMCIY.js";
54
54
  import {
55
55
  formatFabricEffectConflict
56
56
  } from "./chunks/chunk-LMAVZN7J.js";
@@ -63,14 +63,14 @@ import {
63
63
  withExclusiveFileLockAsync
64
64
  } from "./chunks/chunk-YWEXP724.js";
65
65
  import "./chunks/chunk-4A4MVZQW.js";
66
- import "./chunks/chunk-FX3XLQYI.js";
67
- import "./chunks/chunk-6QBPSZJ5.js";
66
+ import "./chunks/chunk-MQSRZC2O.js";
67
+ import "./chunks/chunk-BPMSLBX4.js";
68
68
  import {
69
69
  FABRIC_COMPONENT_DISCOVER_EVENT,
70
70
  FABRIC_PROVIDER_DISCOVER_EVENT,
71
71
  FABRIC_TOOL_RESULT_PROXY_KIND,
72
72
  readFabricToolResultProxyDetailsV1
73
- } from "./chunks/chunk-RBA54WC7.js";
73
+ } from "./chunks/chunk-X2SKPWJA.js";
74
74
  import {
75
75
  ActorDirectory,
76
76
  ActorRegistryOwnershipError,
@@ -94,7 +94,7 @@ import {
94
94
  resolveAgentCwd,
95
95
  resolveOmpBinary,
96
96
  validateAgentCwdRequest
97
- } from "./chunks/chunk-VYB7ROEH.js";
97
+ } from "./chunks/chunk-NP5U3BJZ.js";
98
98
  import "./chunks/chunk-VPPIJRNZ.js";
99
99
  import {
100
100
  executeFile,
@@ -104,7 +104,7 @@ import {
104
104
  import "./chunks/chunk-CT2AJ2UI.js";
105
105
  import {
106
106
  checkedHandoffCompaction
107
- } from "./chunks/chunk-C5JMLDIM.js";
107
+ } from "./chunks/chunk-RA2IB2QT.js";
108
108
  import {
109
109
  DEFAULT_FABRIC_CONFIG,
110
110
  FUZZY_RESOLUTION_MARKERS,
@@ -114,7 +114,7 @@ import {
114
114
  resolveAgentDir,
115
115
  resolveAvailableOmpModel,
116
116
  resolveFabricModel
117
- } from "./chunks/chunk-GIBZGL4G.js";
117
+ } from "./chunks/chunk-5FYSQRJ4.js";
118
118
  import {
119
119
  FABRIC_ACTOR_HOST_EVENTS,
120
120
  isFabricActorHostEvent,
@@ -154,7 +154,7 @@ import {
154
154
  import {
155
155
  estimateTokens,
156
156
  fabricExecTitleHintCached
157
- } from "./chunks/chunk-WMB6QCWX.js";
157
+ } from "./chunks/chunk-ZQ72MAHY.js";
158
158
  import "./chunks/chunk-3J7BKUNG.js";
159
159
  import {
160
160
  MAX_COMPACTION_INSTRUCTIONS_CHARS,
@@ -164,17 +164,19 @@ import {
164
164
  encodeCompactionRequest
165
165
  } from "./chunks/chunk-E4HNDTLM.js";
166
166
  import "./chunks/chunk-3XPR2AZL.js";
167
- import "./chunks/chunk-4HQDSTHN.js";
167
+ import "./chunks/chunk-YBNCEX5E.js";
168
168
  import {
169
169
  FabricExecutionTraceRecorder,
170
170
  FabricTraceSafeError,
171
171
  executionOutcomeFromError
172
- } from "./chunks/chunk-T5ZA5YRU.js";
172
+ } from "./chunks/chunk-52JBWP2C.js";
173
173
  import {
174
174
  OMP_CORE_TOOL_NAMES,
175
+ OMP_CORE_TOOL_NAME_SET,
175
176
  isOmpShellRef,
176
- isOmpShellToolName
177
- } from "./chunks/chunk-6N4XGAZY.js";
177
+ isOmpShellToolName,
178
+ ompCoreToolDenied
179
+ } from "./chunks/chunk-ZFMSJLQE.js";
178
180
 
179
181
  // src/fabric-runtime-state.ts
180
182
  import path19 from "node:path";
@@ -2976,7 +2978,7 @@ var FabricExecutionService = class {
2976
2978
  })) ?? []
2977
2979
  ) : void 0;
2978
2980
  const code = repairFabricGuestCode(options.code);
2979
- const checked2 = dependencies.typeCheckFabricCode(
2981
+ const checked3 = dependencies.typeCheckFabricCode(
2980
2982
  code,
2981
2983
  dependencies.guestTypeDeclarations(effectiveFullCodeMode, {
2982
2984
  excludeGlobals: [...unavailable.keys()],
@@ -2984,8 +2986,8 @@ var FabricExecutionService = class {
2984
2986
  ...coreOverrideDeclarations ? { coreOverrides: coreOverrideDeclarations } : {}
2985
2987
  })
2986
2988
  );
2987
- if (checked2.errors.length > 0) {
2988
- for (const error of checked2.errors) {
2989
+ if (checked3.errors.length > 0) {
2990
+ for (const error of checked3.errors) {
2989
2991
  const missing = /^Cannot find name '([^']+)'/.exec(error.message);
2990
2992
  const reason = missing?.[1] ? unavailable.get(missing[1]) : void 0;
2991
2993
  if (missing && reason) {
@@ -3002,10 +3004,10 @@ var FabricExecutionService = class {
3002
3004
  trace: traceRecorder.seal(
3003
3005
  "failed",
3004
3006
  [],
3005
- `Type checking failed (${checked2.errors.length} ${checked2.errors.length === 1 ? "error" : "errors"})`
3007
+ `Type checking failed (${checked3.errors.length} ${checked3.errors.length === 1 ? "error" : "errors"})`
3006
3008
  ),
3007
3009
  elapsedMs: performance.now() - startedAt,
3008
- typeErrors: checked2.errors
3010
+ typeErrors: checked3.errors
3009
3011
  };
3010
3012
  }
3011
3013
  const classifierUsages = [];
@@ -3436,8 +3438,8 @@ var FabricExecutionService = class {
3436
3438
  memoryLimitBytes: this.config.executor.memoryLimitBytes,
3437
3439
  maxLogChars: this.config.executor.maxOutputChars,
3438
3440
  minimumTimeoutMsForHostCall,
3439
- ...checked2.javascript ? { transpiledCode: checked2.javascript } : {},
3440
- ...checked2.sourceMap ? { transpiledSourceMap: checked2.sourceMap } : {},
3441
+ ...checked3.javascript ? { transpiledCode: checked3.javascript } : {},
3442
+ ...checked3.sourceMap ? { transpiledSourceMap: checked3.sourceMap } : {},
3441
3443
  ...options.payloads ? { payloads: options.payloads } : {},
3442
3444
  ...Object.keys(proxyNames).length > 0 ? { proxyNames } : {},
3443
3445
  ...options.tokenBudget !== void 0 ? { tokenBudget: options.tokenBudget } : {},
@@ -6676,9 +6678,9 @@ var CapturedToolsProvider = class {
6676
6678
  #allowedTools = readChildToolAllowlist();
6677
6679
  async list(request, _context) {
6678
6680
  const query = request.query?.trim().toLowerCase();
6679
- const descriptors7 = this.catalog.list().filter((entry) => !this.#allowedTools || this.#allowedTools.has(entry.name)).map(descriptorFrom);
6680
- if (!query) return descriptors7;
6681
- return descriptors7.filter(
6681
+ const descriptors8 = this.catalog.list().filter((entry) => !this.#allowedTools || this.#allowedTools.has(entry.name)).map(descriptorFrom);
6682
+ if (!query) return descriptors8;
6683
+ return descriptors8.filter(
6682
6684
  (descriptor) => `${descriptor.name} ${descriptor.description} ${descriptor.namespace ?? ""}`.toLowerCase().includes(query)
6683
6685
  );
6684
6686
  }
@@ -8114,32 +8116,420 @@ var CodemapProvider = class {
8114
8116
  }
8115
8117
  };
8116
8118
 
8117
- // src/providers/compact-provider.ts
8119
+ // src/providers/judgment-provider.ts
8118
8120
  import { Type as Type2 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
8119
8121
  import { validateJsonSchemaValue as validateJsonSchemaValue2 } from "@oh-my-pi/pi-ai/utils/schema";
8120
- var requestSchema = Type2.Object({
8121
- reason: Type2.Optional(Type2.String({
8122
+ var askSchema = Type2.Object({
8123
+ state: Type2.Any({
8124
+ description: "Evidence every question is answered against: a string, or a JSON object/array of named parts."
8125
+ }),
8126
+ questions: Type2.Record(Type2.String(), Type2.Any(), {
8127
+ description: 'Questions keyed by id. Each is { type: "choice", instructions, criteria: { label: rubric | null } }, { type: "bool", instructions, criteria?: { true?, false? } }, or { type: "score", instructions, criteria: [lowest, ..., highest] }.'
8128
+ })
8129
+ }, { additionalProperties: false });
8130
+ var statsSchema = Type2.Object({}, { additionalProperties: false });
8131
+ var descriptors2 = [
8132
+ {
8133
+ name: "ask",
8134
+ description: "Answer typed questions about one state with calibrated probabilities: choice (one label plus its distribution), bool (probability of yes), score (weighted position on ordered levels). Questions asked about the same state within the coalesce window travel as one backend request. Returns { ok: false, reason } instead of throwing when no backend is configured, the budget refuses, or the request fails.",
8135
+ inputSchema: askSchema.toJsonSchema(),
8136
+ risk: "network"
8137
+ },
8138
+ {
8139
+ name: "stats",
8140
+ description: "Counters for this session's judgment lane: requests, batched requests, merged callers, questions asked, refusals, failures, timeouts, and the backend and error seen last.",
8141
+ inputSchema: statsSchema.toJsonSchema(),
8142
+ risk: "read"
8143
+ }
8144
+ ];
8145
+ var normalizeJudgmentArgs = actionArgNormalizer(() => descriptors2);
8146
+ var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
8147
+ var instructionsOf = (id, value) => {
8148
+ if (typeof value !== "string" || value.length === 0) {
8149
+ throw new Error(`judgment.ask question "${id}" needs non-empty string instructions`);
8150
+ }
8151
+ return value;
8152
+ };
8153
+ var parseChoice = (id, value) => {
8154
+ const instructions = instructionsOf(id, value.instructions);
8155
+ if (!isRecord3(value.criteria)) {
8156
+ throw new Error(`judgment.ask choice question "${id}" needs criteria: { label: rubric | null }`);
8157
+ }
8158
+ const criteria = {};
8159
+ for (const label in value.criteria) {
8160
+ const rubric = value.criteria[label];
8161
+ if (rubric !== null && typeof rubric !== "string") {
8162
+ throw new Error(`judgment.ask choice question "${id}" criteria "${label}" must be a string or null`);
8163
+ }
8164
+ criteria[label] = rubric;
8165
+ }
8166
+ if (Object.keys(criteria).length < 2) {
8167
+ throw new Error(`judgment.ask choice question "${id}" needs at least two options`);
8168
+ }
8169
+ return { type: "choice", instructions, criteria };
8170
+ };
8171
+ var parseBool = (id, value) => {
8172
+ const instructions = instructionsOf(id, value.instructions);
8173
+ if (value.criteria === void 0) return { type: "noul", instructions };
8174
+ if (!isRecord3(value.criteria)) {
8175
+ throw new Error(`judgment.ask bool question "${id}" criteria must be { true?: string, false?: string }`);
8176
+ }
8177
+ const criteria = {};
8178
+ for (const side of ["true", "false"]) {
8179
+ const description = value.criteria[side];
8180
+ if (description === void 0) continue;
8181
+ if (typeof description !== "string") {
8182
+ throw new Error(`judgment.ask bool question "${id}" criteria.${side} must be a string`);
8183
+ }
8184
+ criteria[side] = description;
8185
+ }
8186
+ return { type: "noul", instructions, criteria };
8187
+ };
8188
+ var parseScore = (id, value) => {
8189
+ const instructions = instructionsOf(id, value.instructions);
8190
+ const levels = value.criteria;
8191
+ if (!Array.isArray(levels) || !levels.every((level) => typeof level === "string")) {
8192
+ throw new Error(`judgment.ask score question "${id}" needs criteria: [lowest, ..., highest]`);
8193
+ }
8194
+ const [lowest, second, ...rest] = levels;
8195
+ if (lowest === void 0 || second === void 0) {
8196
+ throw new Error(`judgment.ask score question "${id}" needs at least two levels`);
8197
+ }
8198
+ return { type: "score", instructions, criteria: [lowest, second, ...rest] };
8199
+ };
8200
+ var parseQuestion = (id, value) => {
8201
+ if (!isRecord3(value)) throw new Error(`judgment.ask question "${id}" must be an object`);
8202
+ switch (value.type) {
8203
+ case "choice":
8204
+ return parseChoice(id, value);
8205
+ case "bool":
8206
+ return parseBool(id, value);
8207
+ case "score":
8208
+ return parseScore(id, value);
8209
+ default:
8210
+ throw new Error(`judgment.ask question "${id}" type must be "choice", "bool", or "score"`);
8211
+ }
8212
+ };
8213
+ var parseState = (value) => {
8214
+ if (typeof value === "string") {
8215
+ if (value.length === 0) throw new Error("judgment.ask state must not be empty");
8216
+ return value;
8217
+ }
8218
+ if (Array.isArray(value) || isRecord3(value)) return value;
8219
+ throw new Error("judgment.ask state must be a string, a JSON object, or a JSON array");
8220
+ };
8221
+ var checked2 = (action, schema, args) => {
8222
+ const validation = validateJsonSchemaValue2(schema.toJsonSchema(), args);
8223
+ if (!validation.success) {
8224
+ const message2 = validation.issues.slice(0, 5).map((issue) => issue.path.length > 0 ? `${issue.path.join(".")} ${issue.message}` : issue.message).join("; ");
8225
+ throw new Error(`Invalid judgment.${action} arguments: ${message2}`);
8226
+ }
8227
+ return args;
8228
+ };
8229
+ var JudgmentProvider = class {
8230
+ constructor(lane) {
8231
+ this.lane = lane;
8232
+ }
8233
+ name = "judgment";
8234
+ description = "Typed judgments over one state: calibrated choice, bool, and score answers batched into one backend request";
8235
+ async list(request, _context) {
8236
+ const query = request.query?.toLowerCase();
8237
+ return query ? descriptors2.filter(
8238
+ (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
8239
+ ) : descriptors2;
8240
+ }
8241
+ async describe(actionName, _context) {
8242
+ return descriptors2.find((descriptor) => descriptor.name === actionName);
8243
+ }
8244
+ prepareArguments(actionName, args) {
8245
+ return normalizeJudgmentArgs(actionName, args);
8246
+ }
8247
+ async invoke(actionName, args, context) {
8248
+ switch (actionName) {
8249
+ case "ask": {
8250
+ const input = checked2("ask", askSchema, args);
8251
+ const state = parseState(input.state);
8252
+ const questions = {};
8253
+ for (const id in input.questions) questions[id] = parseQuestion(id, input.questions[id]);
8254
+ const outcome = await this.lane.ask(state, questions, {
8255
+ ...context.signal !== void 0 ? { signal: context.signal } : {}
8256
+ });
8257
+ if (!outcome.ok) return outcome;
8258
+ const answers = {};
8259
+ for (const id in outcome.answers) {
8260
+ const answer = outcome.answers[id];
8261
+ answers[id] = answer.type === "noul" ? { type: "bool", bool: answer.noul } : answer;
8262
+ }
8263
+ return { ok: true, backend: outcome.backend, answers };
8264
+ }
8265
+ case "stats":
8266
+ return { enabled: this.lane.enabled, ...this.lane.stats() };
8267
+ default:
8268
+ throw new Error(`Unknown judgment action: ${actionName}`);
8269
+ }
8270
+ }
8271
+ };
8272
+
8273
+ // src/judgment/lane.ts
8274
+ var DeadlineError = class extends Error {
8275
+ };
8276
+ var measure = (state) => {
8277
+ try {
8278
+ const serialized = typeof state === "string" ? state : JSON.stringify(state);
8279
+ if (typeof serialized !== "string") return void 0;
8280
+ return { key: typeof state === "string" ? `s:${serialized}` : `j:${serialized}`, bytes: Buffer.byteLength(serialized, "utf-8") };
8281
+ } catch {
8282
+ return void 0;
8283
+ }
8284
+ };
8285
+ var errorText2 = (error) => error instanceof Error ? error.message : String(error);
8286
+ var FabricJudgmentLane = class {
8287
+ #config;
8288
+ #resolve;
8289
+ #pending = /* @__PURE__ */ new Map();
8290
+ #waiting = [];
8291
+ #stats = {
8292
+ requests: 0,
8293
+ batched: 0,
8294
+ questions: 0,
8295
+ merged: 0,
8296
+ failures: 0,
8297
+ refusals: 0,
8298
+ timeouts: 0
8299
+ };
8300
+ #sequence = 0;
8301
+ #inFlight = 0;
8302
+ #judge;
8303
+ #judgeResolved = false;
8304
+ #judgePromise;
8305
+ #resolveError;
8306
+ constructor(config, resolve2) {
8307
+ this.#config = config;
8308
+ this.#resolve = resolve2;
8309
+ }
8310
+ get enabled() {
8311
+ return this.#config.enabled;
8312
+ }
8313
+ stats() {
8314
+ return { ...this.#stats };
8315
+ }
8316
+ async ask(state, questions, options) {
8317
+ const ids = Object.keys(questions);
8318
+ if (!this.#config.enabled) return { ok: false, reason: "disabled" };
8319
+ if (ids.length === 0) return this.#refuse("no questions");
8320
+ if (ids.length > this.#config.maxQuestionsPerRequest) {
8321
+ return this.#refuse(
8322
+ `${ids.length} questions exceeds maxQuestionsPerRequest=${this.#config.maxQuestionsPerRequest}`
8323
+ );
8324
+ }
8325
+ const measured = measure(state);
8326
+ if (!measured) return this.#refuse("state is not JSON-encodable");
8327
+ if (measured.bytes > this.#config.maxStateBytes) {
8328
+ return this.#refuse(
8329
+ `state of ${measured.bytes} bytes exceeds maxStateBytes=${this.#config.maxStateBytes}`
8330
+ );
8331
+ }
8332
+ if (options?.signal?.aborted === true) return { ok: false, reason: "aborted" };
8333
+ const outcome = await new Promise((settle) => {
8334
+ this.#enqueue(measured.key, state, questions, settle, options?.signal);
8335
+ });
8336
+ return outcome;
8337
+ }
8338
+ #refuse(detail) {
8339
+ this.#stats.refusals++;
8340
+ return { ok: false, reason: "refused", detail };
8341
+ }
8342
+ #enqueue(key, state, questions, settle, signal) {
8343
+ const asked = Object.keys(questions).length;
8344
+ const existing = this.#pending.get(key);
8345
+ if (existing && existing.questionCount + asked > this.#config.maxQuestionsPerRequest) {
8346
+ this.#flush(key);
8347
+ }
8348
+ const batch = this.#pending.get(key) ?? { state, entries: [], questionCount: 0 };
8349
+ const entry = { prefix: `q${this.#sequence++}`, questions, settle, done: false };
8350
+ if (signal) {
8351
+ const onAbort = () => this.#settle(entry, { ok: false, reason: "aborted" });
8352
+ entry.detach = () => signal.removeEventListener("abort", onAbort);
8353
+ signal.addEventListener("abort", onAbort, { once: true });
8354
+ }
8355
+ batch.entries.push(entry);
8356
+ batch.questionCount += asked;
8357
+ this.#pending.set(key, batch);
8358
+ if (batch.questionCount >= this.#config.maxQuestionsPerRequest) {
8359
+ this.#flush(key);
8360
+ return;
8361
+ }
8362
+ batch.timer ??= setTimeout(() => this.#flush(key), this.#config.coalesceMs);
8363
+ }
8364
+ #flush(key) {
8365
+ const batch = this.#pending.get(key);
8366
+ if (!batch) return;
8367
+ this.#pending.delete(key);
8368
+ if (batch.timer !== void 0) clearTimeout(batch.timer);
8369
+ const live = batch.entries.filter((entry) => !entry.done);
8370
+ if (live.length === 0) return;
8371
+ void this.#schedule(batch.state, live);
8372
+ }
8373
+ /** Holds a slot for the whole run and hands it to the next waiter, so a flush cannot take one mid-release. */
8374
+ async #schedule(state, entries) {
8375
+ if (this.#inFlight >= this.#config.maxConcurrent) {
8376
+ await new Promise((release) => this.#waiting.push(release));
8377
+ } else {
8378
+ this.#inFlight++;
8379
+ }
8380
+ try {
8381
+ const live = entries.filter((entry) => !entry.done);
8382
+ if (live.length > 0) await this.#run(state, live);
8383
+ } finally {
8384
+ const next = this.#waiting.shift();
8385
+ if (next) next();
8386
+ else this.#inFlight--;
8387
+ }
8388
+ }
8389
+ async #run(state, entries) {
8390
+ const merged = {};
8391
+ for (const entry of entries) {
8392
+ for (const id in entry.questions) {
8393
+ merged[`${entry.prefix}_${id}`] = entry.questions[id];
8394
+ }
8395
+ }
8396
+ const controller = new AbortController();
8397
+ let timer;
8398
+ let timedOut = false;
8399
+ const deadline = new Promise((_settle, fail) => {
8400
+ timer = setTimeout(() => {
8401
+ timedOut = true;
8402
+ fail(new DeadlineError(`no answer within ${this.#config.timeoutMs}ms`));
8403
+ controller.abort();
8404
+ }, this.#config.timeoutMs);
8405
+ });
8406
+ deadline.catch(() => {
8407
+ });
8408
+ try {
8409
+ const judge = await Promise.race([this.#backend(), deadline]);
8410
+ if (!judge) {
8411
+ this.#settleAll(entries, {
8412
+ ok: false,
8413
+ reason: "unsupported",
8414
+ ...this.#resolveError !== void 0 ? { detail: this.#resolveError } : {}
8415
+ });
8416
+ return;
8417
+ }
8418
+ this.#stats.requests++;
8419
+ this.#stats.questions += Object.keys(merged).length;
8420
+ if (entries.length > 1) {
8421
+ this.#stats.batched++;
8422
+ this.#stats.merged += entries.length;
8423
+ }
8424
+ const pending = judge.judge({ state, questions: merged }, { signal: controller.signal });
8425
+ pending.catch(() => {
8426
+ });
8427
+ const result = await Promise.race([pending, deadline]);
8428
+ const backend = `${result.provider}/${result.model}`;
8429
+ this.#stats.lastBackend = backend;
8430
+ for (const entry of entries) {
8431
+ const answers = {};
8432
+ let missing;
8433
+ for (const id in entry.questions) {
8434
+ const answer = result.answers[`${entry.prefix}_${id}`];
8435
+ if (answer === void 0) {
8436
+ missing = id;
8437
+ break;
8438
+ }
8439
+ answers[id] = answer;
8440
+ }
8441
+ this.#settle(
8442
+ entry,
8443
+ missing === void 0 ? { ok: true, answers, backend } : { ok: false, reason: "failed", detail: `no answer for "${missing}"` }
8444
+ );
8445
+ }
8446
+ } catch (error) {
8447
+ const detail = timedOut ? `no answer within ${this.#config.timeoutMs}ms` : errorText2(error);
8448
+ if (timedOut) this.#stats.timeouts++;
8449
+ else this.#stats.failures++;
8450
+ this.#stats.lastError = detail;
8451
+ this.#settleAll(entries, { ok: false, reason: timedOut ? "timeout" : "failed", detail });
8452
+ } finally {
8453
+ if (timer !== void 0) clearTimeout(timer);
8454
+ }
8455
+ }
8456
+ #settle(entry, outcome) {
8457
+ if (entry.done) return;
8458
+ entry.done = true;
8459
+ entry.detach?.();
8460
+ entry.settle(outcome);
8461
+ }
8462
+ #settleAll(entries, outcome) {
8463
+ for (const entry of entries) this.#settle(entry, outcome);
8464
+ }
8465
+ /** Resolves once per session, including a host that offers no judge; only a thrown resolver is retried. */
8466
+ async #backend() {
8467
+ if (this.#judgeResolved) return this.#judge;
8468
+ this.#judgePromise ??= this.#resolve().then(
8469
+ (judge) => {
8470
+ this.#judge = judge;
8471
+ this.#judgeResolved = true;
8472
+ this.#resolveError = void 0;
8473
+ this.#judgePromise = void 0;
8474
+ return judge;
8475
+ },
8476
+ (error) => {
8477
+ this.#resolveError = errorText2(error);
8478
+ this.#stats.lastError = this.#resolveError;
8479
+ this.#judgePromise = void 0;
8480
+ return void 0;
8481
+ }
8482
+ );
8483
+ return this.#judgePromise;
8484
+ }
8485
+ };
8486
+
8487
+ // src/judgment/host-judge.ts
8488
+ var ONLINE_JUDGMENT_BACKEND = "online";
8489
+ var resolveHostJudge = async (context) => {
8490
+ if (context.modelRegistry === void 0) return void 0;
8491
+ const [judgment, settingsModule] = await Promise.all([
8492
+ import("@oh-my-pi/pi-coding-agent/judgment"),
8493
+ import("@oh-my-pi/pi-coding-agent/config/settings")
8494
+ ]);
8495
+ const resolveJudge = judgment.resolveJudge;
8496
+ const settings = settingsModule.settings;
8497
+ if (typeof resolveJudge !== "function" || settings === void 0) return void 0;
8498
+ return resolveJudge({
8499
+ settings,
8500
+ registry: context.modelRegistry,
8501
+ backend: ONLINE_JUDGMENT_BACKEND,
8502
+ ...context.model !== void 0 ? { sessionModel: context.model } : {},
8503
+ ...context.sessionId !== void 0 ? { sessionId: context.sessionId } : {}
8504
+ });
8505
+ };
8506
+
8507
+ // src/providers/compact-provider.ts
8508
+ import { Type as Type3 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
8509
+ import { validateJsonSchemaValue as validateJsonSchemaValue3 } from "@oh-my-pi/pi-ai/utils/schema";
8510
+ var requestSchema = Type3.Object({
8511
+ reason: Type3.Optional(Type3.String({
8122
8512
  maxLength: 1024,
8123
8513
  description: "Short human-readable reason for the compaction"
8124
8514
  })),
8125
- instructions: Type2.Optional(Type2.String({
8515
+ instructions: Type3.Optional(Type3.String({
8126
8516
  maxLength: MAX_COMPACTION_INSTRUCTIONS_CHARS,
8127
8517
  description: "Custom compaction instructions forwarded to OMP core"
8128
8518
  })),
8129
- preserve: Type2.Optional(Type2.Array(
8130
- Type2.String({ maxLength: MAX_PRESERVE_ITEM_CHARS }),
8519
+ preserve: Type3.Optional(Type3.Array(
8520
+ Type3.String({ maxLength: MAX_PRESERVE_ITEM_CHARS }),
8131
8521
  {
8132
8522
  maxItems: MAX_PRESERVE_ITEMS,
8133
8523
  description: "Explicit bounded facts to preserve, encoded as a typed Fabric compaction request"
8134
8524
  }
8135
8525
  )),
8136
- requestedBy: Type2.Optional(Type2.String({
8526
+ requestedBy: Type3.Optional(Type3.String({
8137
8527
  maxLength: 256,
8138
8528
  description: "Who requested the compaction (default: model)"
8139
8529
  }))
8140
8530
  }, { additionalProperties: false });
8141
8531
  var checkedRequestArguments = (args) => {
8142
- const validation = validateJsonSchemaValue2(requestSchema.toJsonSchema(), args);
8532
+ const validation = validateJsonSchemaValue3(requestSchema.toJsonSchema(), args);
8143
8533
  if (!validation.success) {
8144
8534
  const message2 = validation.issues.slice(0, 5).map((error) => error.message).join("; ");
8145
8535
  throw new Error(`Invalid compact.request arguments: ${message2}`);
@@ -8163,7 +8553,7 @@ var emptySchema = {
8163
8553
  properties: {},
8164
8554
  additionalProperties: false
8165
8555
  };
8166
- var descriptors2 = [
8556
+ var descriptors3 = [
8167
8557
  {
8168
8558
  name: "request",
8169
8559
  description: "Request an advisory compaction of the host session's context at the next safe boundary (agent_end). The host commits it only between turns, never mid-turn. A new request replaces any pending one.",
@@ -8186,7 +8576,7 @@ var descriptors2 = [
8186
8576
  risk: "write"
8187
8577
  }
8188
8578
  ];
8189
- var normalizeCompactArgs = actionArgNormalizer(() => descriptors2);
8579
+ var normalizeCompactArgs = actionArgNormalizer(() => descriptors3);
8190
8580
  var CompactProvider = class {
8191
8581
  constructor(controller) {
8192
8582
  this.controller = controller;
@@ -8195,12 +8585,12 @@ var CompactProvider = class {
8195
8585
  description = "Programmatic, advisory-then-committed context compaction for the host OMP session";
8196
8586
  async list(request, _context) {
8197
8587
  const query = request.query?.toLowerCase();
8198
- return query ? descriptors2.filter(
8588
+ return query ? descriptors3.filter(
8199
8589
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
8200
- ) : descriptors2;
8590
+ ) : descriptors3;
8201
8591
  }
8202
8592
  async describe(actionName, _context) {
8203
- return descriptors2.find((descriptor) => descriptor.name === actionName);
8593
+ return descriptors3.find((descriptor) => descriptor.name === actionName);
8204
8594
  }
8205
8595
  prepareArguments(actionName, args) {
8206
8596
  return normalizeCompactArgs(actionName, args);
@@ -8240,7 +8630,7 @@ var CompactProvider = class {
8240
8630
  };
8241
8631
 
8242
8632
  // src/providers/components-provider.ts
8243
- var descriptors3 = [
8633
+ var descriptors4 = [
8244
8634
  {
8245
8635
  name: "list",
8246
8636
  description: "List registered component definitions and configured component instances.",
@@ -8287,13 +8677,13 @@ var ComponentsProvider = class {
8287
8677
  description = "Supervised component lifecycle, exact capability dependencies, effect cleanup, and reload diagnostics.";
8288
8678
  async list(request, _context) {
8289
8679
  const query = request.query?.normalize("NFKC").trim().toLowerCase();
8290
- const filtered = query ? descriptors3.filter(
8680
+ const filtered = query ? descriptors4.filter(
8291
8681
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
8292
- ) : descriptors3;
8682
+ ) : descriptors4;
8293
8683
  return filtered.slice(0, Math.max(1, Math.min(request.limit ?? 100, 100)));
8294
8684
  }
8295
8685
  async describe(actionName, _context) {
8296
- return descriptors3.find((descriptor) => descriptor.name === actionName);
8686
+ return descriptors4.find((descriptor) => descriptor.name === actionName);
8297
8687
  }
8298
8688
  async invoke(actionName, args, _context) {
8299
8689
  switch (actionName) {
@@ -8399,11 +8789,11 @@ var sameConfigLayers = (left, right) => left.length === right.length && left.eve
8399
8789
  return other !== void 0 && layer.path === other.path && layer.size === other.size && Math.abs(layer.mtimeMs - other.mtimeMs) <= 1;
8400
8790
  });
8401
8791
  var hashServerDefinition = (definition) => stableJsonHash(definition);
8402
- var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
8792
+ var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
8403
8793
  var parseCachedServer = (value) => {
8404
- if (!isRecord3(value)) return void 0;
8794
+ if (!isRecord4(value)) return void 0;
8405
8795
  const tools = Array.isArray(value.tools) ? value.tools.filter(
8406
- (tool) => isRecord3(tool) && typeof tool.name === "string"
8796
+ (tool) => isRecord4(tool) && typeof tool.name === "string"
8407
8797
  ) : void 0;
8408
8798
  if (typeof value.definitionHash !== "string" || tools === void 0) return void 0;
8409
8799
  return {
@@ -8416,10 +8806,10 @@ var parseCachedServer = (value) => {
8416
8806
  };
8417
8807
  };
8418
8808
  var parseCacheFile = (value) => {
8419
- if (!isRecord3(value) || value.version !== MCP_DESCRIPTOR_CACHE_VERSION) return void 0;
8420
- if (!Array.isArray(value.layers) || !isRecord3(value.servers)) return void 0;
8809
+ if (!isRecord4(value) || value.version !== MCP_DESCRIPTOR_CACHE_VERSION) return void 0;
8810
+ if (!Array.isArray(value.layers) || !isRecord4(value.servers)) return void 0;
8421
8811
  const layers = value.layers.filter(
8422
- (layer) => isRecord3(layer) && typeof layer.path === "string" && typeof layer.mtimeMs === "number" && typeof layer.size === "number"
8812
+ (layer) => isRecord4(layer) && typeof layer.path === "string" && typeof layer.mtimeMs === "number" && typeof layer.size === "number"
8423
8813
  );
8424
8814
  return {
8425
8815
  version: MCP_DESCRIPTOR_CACHE_VERSION,
@@ -8624,9 +9014,9 @@ var McpProvider = class {
8624
9014
  this.#kickRevalidation();
8625
9015
  if (!request.namespace) await this.#awaitColdEnumeration(context.signal);
8626
9016
  const query = request.query?.toLowerCase();
8627
- const filterQuery = (descriptors7) => query ? descriptors7.filter(
9017
+ const filterQuery = (descriptors8) => query ? descriptors8.filter(
8628
9018
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
8629
- ) : descriptors7;
9019
+ ) : descriptors8;
8630
9020
  if (request.namespace) {
8631
9021
  const server = await this.#resolveKnownServer(request.namespace);
8632
9022
  if (!server) return [];
@@ -8781,11 +9171,11 @@ var McpProvider = class {
8781
9171
  // Provider-fidelity descriptors for everything currently known, cached or
8782
9172
  // ephemeral.
8783
9173
  sliceDescriptors() {
8784
- const descriptors7 = [];
9174
+ const descriptors8 = [];
8785
9175
  for (const [server, entry] of this.#servers) {
8786
- for (const tool of entry.tools) descriptors7.push(this.#toolDescriptor(server, tool));
9176
+ for (const tool of entry.tools) descriptors8.push(this.#toolDescriptor(server, tool));
8787
9177
  }
8788
- return descriptors7;
9178
+ return descriptors8;
8789
9179
  }
8790
9180
  // Test/ops hook: await hydration and any in-flight background revalidation,
8791
9181
  // then flush pending persistence and notifications.
@@ -9252,13 +9642,13 @@ var McpProvider = class {
9252
9642
  return tools.map((tool) => this.#toolDescriptor(server, tool));
9253
9643
  })
9254
9644
  );
9255
- const descriptors7 = settled.flatMap(
9645
+ const descriptors8 = settled.flatMap(
9256
9646
  (entry) => entry.status === "fulfilled" ? entry.value : []
9257
9647
  );
9258
9648
  const query = request.query?.toLowerCase();
9259
- const filtered = query ? descriptors7.filter(
9649
+ const filtered = query ? descriptors8.filter(
9260
9650
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
9261
- ) : descriptors7;
9651
+ ) : descriptors8;
9262
9652
  return request.namespace ? filtered : [...managementDescriptors, ...filtered];
9263
9653
  }
9264
9654
  async #describeLegacy(actionName, _context) {
@@ -9330,7 +9720,7 @@ var assertReadableStateKey = (key) => {
9330
9720
  throw new Error(`Fabric mesh key is private host state: ${key}`);
9331
9721
  }
9332
9722
  };
9333
- var descriptors4 = [
9723
+ var descriptors5 = [
9334
9724
  {
9335
9725
  name: "self",
9336
9726
  description: "Return this Fabric participant's mesh identity",
@@ -9457,7 +9847,7 @@ var descriptors4 = [
9457
9847
  namespace: "coordination"
9458
9848
  }
9459
9849
  ];
9460
- var normalizeMeshArgs = actionArgNormalizer(() => descriptors4);
9850
+ var normalizeMeshArgs = actionArgNormalizer(() => descriptors5);
9461
9851
  var MeshProvider = class {
9462
9852
  constructor(store, identity, participants) {
9463
9853
  this.store = store;
@@ -9468,12 +9858,12 @@ var MeshProvider = class {
9468
9858
  description = "Durable topics and compare-and-swap shared state for emergent agent coordination";
9469
9859
  async list(request, _context) {
9470
9860
  const query = request.query?.toLowerCase();
9471
- return query ? descriptors4.filter(
9861
+ return query ? descriptors5.filter(
9472
9862
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
9473
- ) : descriptors4;
9863
+ ) : descriptors5;
9474
9864
  }
9475
9865
  async describe(actionName, _context) {
9476
- return descriptors4.find((descriptor) => descriptor.name === actionName);
9866
+ return descriptors5.find((descriptor) => descriptor.name === actionName);
9477
9867
  }
9478
9868
  prepareArguments(actionName, args) {
9479
9869
  return normalizeMeshArgs(actionName, args);
@@ -9680,7 +10070,7 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
9680
10070
  import { accessSync, constants, statSync as statSync3 } from "node:fs";
9681
10071
  import path13 from "node:path";
9682
10072
  import { createBashToolDefinition } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-pi-coding-agent-shim";
9683
- import { Type as Type3 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
10073
+ import { Type as Type4 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
9684
10074
  var OMP_BASH_CWD_KEY = "cwd";
9685
10075
  var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
9686
10076
  if (typeof requested !== "string" || requested.trim().length === 0) {
@@ -9708,27 +10098,27 @@ var resolveShellCwdArgument = (toolName, sessionCwd, args) => Object.hasOwn(args
9708
10098
  args[OMP_BASH_CWD_KEY]
9709
10099
  )
9710
10100
  } : args;
9711
- var CWD_PROPERTY = Type3.Optional(
9712
- Type3.String({
10101
+ var CWD_PROPERTY = Type4.Optional(
10102
+ Type4.String({
9713
10103
  description: "Execution directory for this command; relative paths resolve from the session cwd."
9714
10104
  })
9715
10105
  );
9716
- var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
10106
+ var isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9717
10107
  var schemaDocument2 = (schema) => {
9718
- if (isRecord4(schema)) return schema;
10108
+ if (isRecord5(schema)) return schema;
9719
10109
  if (typeof schema !== "function" || !("toJsonSchema" in schema)) return void 0;
9720
10110
  const toJsonSchema = schema.toJsonSchema;
9721
10111
  if (typeof toJsonSchema !== "function") return void 0;
9722
10112
  const document = toJsonSchema.call(schema);
9723
- return isRecord4(document) ? document : void 0;
10113
+ return isRecord5(document) ? document : void 0;
9724
10114
  };
9725
10115
  var withShellCwdSchema = (schema) => {
9726
10116
  const document = schemaDocument2(schema);
9727
- if (!document || !isRecord4(document.properties)) return schema;
10117
+ if (!document || !isRecord5(document.properties)) return schema;
9728
10118
  if (Object.hasOwn(document.properties, OMP_BASH_CWD_KEY)) return schema;
9729
10119
  const cwdSchema = schemaDocument2(CWD_PROPERTY);
9730
10120
  if (!cwdSchema) return schema;
9731
- return Type3.Unsafe({
10121
+ return Type4.Unsafe({
9732
10122
  ...document,
9733
10123
  properties: { ...document.properties, [OMP_BASH_CWD_KEY]: cwdSchema }
9734
10124
  });
@@ -9765,7 +10155,7 @@ var BashCwdDefinitions = class extends ShellCwdDefinitions {
9765
10155
  import { homedir } from "node:os";
9766
10156
  import { dirname, isAbsolute, resolve, win32 } from "node:path";
9767
10157
  import { mkdir, readFile as readFile2, stat, writeFile } from "node:fs/promises";
9768
- import { Type as Type4 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
10158
+ import { Type as Type5 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
9769
10159
  import { WriteTool } from "@oh-my-pi/pi-coding-agent/tools/write";
9770
10160
  var mutationQueues = /* @__PURE__ */ new Map();
9771
10161
  var withFileMutationQueue = async (path20, operation) => {
@@ -9837,7 +10227,7 @@ var createPreviewWriteToolDefinition = (cwd, session) => {
9837
10227
  name: "write",
9838
10228
  label: "Write",
9839
10229
  description: "Write a file",
9840
- parameters: Type4.Object({ path: Type4.String(), content: Type4.String() }),
10230
+ parameters: Type5.Object({ path: Type5.String(), content: Type5.String() }),
9841
10231
  execute: async () => ({ content: [{ type: "text", text: "" }] })
9842
10232
  };
9843
10233
  return {
@@ -10442,19 +10832,21 @@ var normalizeResult = (name, result, artifactPaths, appendReadNewline = true, ex
10442
10832
  return { ok: true, output, details: details ?? null };
10443
10833
  };
10444
10834
  var OmpToolsProvider = class _OmpToolsProvider {
10445
- static async create(cwd, catalog, capturedTools) {
10446
- return new _OmpToolsProvider(cwd, catalog, capturedTools);
10835
+ static async create(cwd, catalog, capturedTools, hostActiveTools) {
10836
+ return new _OmpToolsProvider(cwd, catalog, capturedTools, hostActiveTools);
10447
10837
  }
10448
10838
  name = "omp";
10449
10839
  description = "OMP's built-in coding tools";
10450
10840
  #allowedTools = readChildToolAllowlist();
10841
+ #hostActiveTools;
10451
10842
  #tools;
10452
10843
  #catalog;
10453
10844
  #capturedTools;
10454
10845
  #cwd;
10455
10846
  #artifactPaths = /* @__PURE__ */ new Map();
10456
10847
  #bashDefinitions = new BashCwdDefinitions();
10457
- constructor(cwd, catalog, capturedTools) {
10848
+ constructor(cwd, catalog, capturedTools, hostActiveTools) {
10849
+ this.#hostActiveTools = hostActiveTools;
10458
10850
  this.#cwd = cwd;
10459
10851
  this.#tools = {
10460
10852
  read: createNativeReadToolDefinition(cwd),
@@ -10470,16 +10862,16 @@ var OmpToolsProvider = class _OmpToolsProvider {
10470
10862
  }
10471
10863
  async list(request, _context) {
10472
10864
  const query = request.query?.toLowerCase();
10473
- const descriptors7 = await Promise.all(
10865
+ const descriptors8 = await Promise.all(
10474
10866
  OMP_CORE_TOOL_NAMES.map((name) => this.describe(name, _context))
10475
10867
  );
10476
- return descriptors7.filter((descriptor) => descriptor !== void 0).filter(
10868
+ return descriptors8.filter((descriptor) => descriptor !== void 0).filter(
10477
10869
  (descriptor) => query ? `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query) : true
10478
10870
  );
10479
10871
  }
10480
10872
  async describe(actionName, _context) {
10481
10873
  const name = actionName;
10482
- if (this.#allowedTools && !this.#allowedTools.has(name)) return void 0;
10874
+ if (this.denialMessage(name)) return void 0;
10483
10875
  const tool = this.#tools[name];
10484
10876
  if (!tool) return void 0;
10485
10877
  const override = await this.#capturedTools?.describe(name, _context);
@@ -10506,9 +10898,17 @@ var OmpToolsProvider = class _OmpToolsProvider {
10506
10898
  return actionName === "edit" ? normalizeEditArguments(record2, args.all === true, this.#cwd) : record2;
10507
10899
  }
10508
10900
  #assertAllowed(name) {
10509
- if (this.#allowedTools && !this.#allowedTools.has(name)) {
10510
- throw new Error(`OMP tool ${name} is not permitted by this child's tool allowlist`);
10511
- }
10901
+ const message2 = this.denialMessage(name);
10902
+ if (message2) throw new Error(message2);
10903
+ }
10904
+ denialMessage(actionName) {
10905
+ const source = this.#denialSource(actionName);
10906
+ return source ? `OMP tool ${actionName} is not permitted by ${source}` : void 0;
10907
+ }
10908
+ #denialSource(name) {
10909
+ if (!OMP_CORE_TOOL_NAME_SET.has(name)) return void 0;
10910
+ if (this.#allowedTools && !this.#allowedTools.has(name)) return "this child's tool allowlist";
10911
+ return ompCoreToolDenied(name, this.#hostActiveTools?.()) ? "OMP's active tool selection" : void 0;
10512
10912
  }
10513
10913
  // Keep a cwd-bound definition for hosts without argument preparation, while newer hosts receive the
10514
10914
  // same directory through ExtensionContext.cwd. `cwd` also stays in the
@@ -11897,7 +12297,7 @@ var operationSchema = {
11897
12297
  }
11898
12298
  ]
11899
12299
  };
11900
- var descriptors5 = [
12300
+ var descriptors6 = [
11901
12301
  {
11902
12302
  name: "status",
11903
12303
  description: "Read the fixed session Schema mode, transaction bounds, generation, and invocation hypotheses",
@@ -11967,7 +12367,7 @@ var descriptors5 = [
11967
12367
  namespace: "schema"
11968
12368
  }
11969
12369
  ];
11970
- var normalizeSchemaArgs = actionArgNormalizer(() => descriptors5);
12370
+ var normalizeSchemaArgs = actionArgNormalizer(() => descriptors6);
11971
12371
  var SchemaProvider = class {
11972
12372
  constructor(controller) {
11973
12373
  this.controller = controller;
@@ -11976,12 +12376,12 @@ var SchemaProvider = class {
11976
12376
  description = "Host-owned, opt-in Schema verification and bounded local-file transaction control plane";
11977
12377
  async list(request, _context) {
11978
12378
  const query = request.query?.toLowerCase();
11979
- return query ? descriptors5.filter(
12379
+ return query ? descriptors6.filter(
11980
12380
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
11981
- ) : descriptors5;
12381
+ ) : descriptors6;
11982
12382
  }
11983
12383
  async describe(actionName, _context) {
11984
- return descriptors5.find((descriptor) => descriptor.name === actionName);
12384
+ return descriptors6.find((descriptor) => descriptor.name === actionName);
11985
12385
  }
11986
12386
  prepareArguments(actionName, args) {
11987
12387
  return normalizeSchemaArgs(actionName, args);
@@ -13681,7 +14081,7 @@ var checkGoalSchema = {
13681
14081
  additionalProperties: false
13682
14082
  };
13683
14083
  var emptySchema3 = { type: "object", properties: {}, additionalProperties: false };
13684
- var descriptors6 = [
14084
+ var descriptors7 = [
13685
14085
  {
13686
14086
  name: "transition",
13687
14087
  description: "Append a labeled, validated state transition and compare-and-swap advance the head",
@@ -13732,7 +14132,7 @@ var descriptors6 = [
13732
14132
  namespace: "state"
13733
14133
  }
13734
14134
  ];
13735
- var normalizeStateArgs = actionArgNormalizer(() => descriptors6);
14135
+ var normalizeStateArgs = actionArgNormalizer(() => descriptors7);
13736
14136
  var StateProvider = class {
13737
14137
  name = "state";
13738
14138
  description = "Schema-style labeled transition layer: an append-only timeline of validated transitions with a compare-and-swap head and evidence-based certification over mesh storage";
@@ -13747,12 +14147,12 @@ var StateProvider = class {
13747
14147
  }
13748
14148
  async list(request, _context) {
13749
14149
  const query = request.query?.toLowerCase();
13750
- return query ? descriptors6.filter(
14150
+ return query ? descriptors7.filter(
13751
14151
  (descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
13752
- ) : descriptors6;
14152
+ ) : descriptors7;
13753
14153
  }
13754
14154
  async describe(actionName, _context) {
13755
- return descriptors6.find((descriptor) => descriptor.name === actionName);
14155
+ return descriptors7.find((descriptor) => descriptor.name === actionName);
13756
14156
  }
13757
14157
  prepareArguments(actionName, args) {
13758
14158
  return normalizeStateArgs(actionName, args);
@@ -13900,6 +14300,7 @@ var FabricRuntimeState = class {
13900
14300
  this.sessionApprovals = options.sessionApprovals ?? new FabricSessionApprovals();
13901
14301
  this.#lcmContext = options.lcmContext;
13902
14302
  this.#lcmRuntime = options.lcmRuntime;
14303
+ this.#hostActiveTools = options.hostActiveTools;
13903
14304
  this.#paths = options.paths;
13904
14305
  }
13905
14306
  #registry;
@@ -13938,6 +14339,7 @@ var FabricRuntimeState = class {
13938
14339
  sessionApprovals;
13939
14340
  #lcmContext;
13940
14341
  #lcmRuntime;
14342
+ #hostActiveTools;
13941
14343
  #paths;
13942
14344
  #widgetDismissedAt = 0;
13943
14345
  #suppressResidentGuidanceSync = false;
@@ -14196,7 +14598,8 @@ var FabricRuntimeState = class {
14196
14598
  create: () => OmpToolsProvider.create(
14197
14599
  context.cwd,
14198
14600
  this.capturedTools,
14199
- capturedToolsProvider
14601
+ capturedToolsProvider,
14602
+ this.#hostActiveTools
14200
14603
  )
14201
14604
  }));
14202
14605
  }
@@ -14323,6 +14726,23 @@ var FabricRuntimeState = class {
14323
14726
  'disabled by configuration (codemap.enabled=false); set "codemap": { "enabled": true } in .omp/fabric.json or the agent fabric.json to enable codemap.* actions'
14324
14727
  );
14325
14728
  }
14729
+ if (this.#config.judgment.enabled) {
14730
+ const judgmentConfig = this.#config.judgment;
14731
+ await installBuiltin(createProviderComponent({
14732
+ provider: "judgment",
14733
+ description: "Typed judgments with calibrated probabilities",
14734
+ create: () => new JudgmentProvider(new FabricJudgmentLane(judgmentConfig, () => resolveHostJudge({
14735
+ modelRegistry: context.modelRegistry,
14736
+ ...context.model !== void 0 ? { model: context.model } : {},
14737
+ sessionId: context.sessionManager.getSessionId()
14738
+ })))
14739
+ }));
14740
+ } else {
14741
+ this.#registry.markUnavailable(
14742
+ "judgment",
14743
+ 'disabled by configuration (judgment.enabled=false); set "judgment": { "enabled": true } in .omp/fabric.json or the agent fabric.json to enable judgment.* actions'
14744
+ );
14745
+ }
14326
14746
  const agentConfig = enforceSchema ? { ...this.#config.agents, enabled: false } : this.#config.agents;
14327
14747
  const modelsConfig = this.#config.models;
14328
14748
  const visibleOmpModels = () => {
@@ -14623,6 +15043,7 @@ ${escapeXmlText(text)}
14623
15043
  "schema",
14624
15044
  "compact",
14625
15045
  ...this.#config.codemap.enabled ? ["codemap"] : [],
15046
+ ...this.#config.judgment.enabled ? ["judgment"] : [],
14626
15047
  "agents",
14627
15048
  ...this.#config.memory.enabled ? ["memory"] : []
14628
15049
  ]);