@beyondwork/docx-react-component 1.0.105 → 1.0.106
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/package.json +1 -1
- package/src/api/v3/_create.ts +9 -2
- package/src/api/v3/ai/_audit-reference.ts +28 -0
- package/src/api/v3/ai/_pe2-evidence.ts +272 -6
- package/src/api/v3/ai/attach.ts +22 -2
- package/src/api/v3/ai/bundle.ts +6 -2
- package/src/api/v3/ai/inspect.ts +6 -2
- package/src/api/v3/ai/replacement.ts +11 -0
- package/src/api/v3/index.ts +7 -0
- package/src/api/v3/ui/_types.ts +53 -0
- package/src/api/v3/ui/index.ts +4 -0
- package/src/api/v3/ui/viewport.ts +97 -0
- package/src/model/layout/page-graph-types.ts +29 -0
- package/src/runtime/document-runtime.ts +39 -18
- package/src/runtime/geometry/geometry-index.ts +74 -0
- package/src/runtime/layout/layout-engine-version.ts +8 -1
- package/src/runtime/layout/page-graph.ts +2 -0
- package/src/runtime/layout/paginated-layout-engine.ts +10 -0
- package/src/runtime/layout/project-block-fragments.ts +86 -7
- package/src/runtime/layout/public-facet.ts +84 -0
- package/src/runtime/workflow/index.ts +1 -0
- package/src/runtime/workflow/overlay-lanes.ts +228 -0
- package/src/ui/presence-overlay-lane.ts +131 -0
- package/src/ui/ui-controller-factory.ts +10 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.106",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
package/src/api/v3/_create.ts
CHANGED
|
@@ -41,6 +41,7 @@ import { createReviewFamily as createAiReviewFamily } from "./ai/review.ts";
|
|
|
41
41
|
import { createEvaluateFamily } from "./ai/evaluate.ts";
|
|
42
42
|
import { createStatsFamily } from "./ai/stats.ts";
|
|
43
43
|
import { createOutlineFamily } from "./ai/outline.ts";
|
|
44
|
+
import type { AiPe2EvidenceOptions } from "./ai/_pe2-evidence.ts";
|
|
44
45
|
|
|
45
46
|
import { createUiApi } from "./ui/_create.ts";
|
|
46
47
|
import type { ApiV3Ui, UiControllerFactory } from "./ui/_types.ts";
|
|
@@ -108,6 +109,12 @@ export interface ApiV3 {
|
|
|
108
109
|
*/
|
|
109
110
|
export interface CreateApiV3Opts {
|
|
110
111
|
readonly ui?: UiControllerFactory;
|
|
112
|
+
/**
|
|
113
|
+
* Optional PE2 evidence bridge. Hosts/debug services that already have
|
|
114
|
+
* truth-oracle run metadata can inject it here; omitted means AI reads
|
|
115
|
+
* report `pe2Evidence.oracle.status: "not-wired"`.
|
|
116
|
+
*/
|
|
117
|
+
readonly pe2Evidence?: AiPe2EvidenceOptions;
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
/**
|
|
@@ -119,9 +126,9 @@ export interface CreateApiV3Opts {
|
|
|
119
126
|
*/
|
|
120
127
|
export function createApiV3(handle: RuntimeApiHandle, opts?: CreateApiV3Opts): ApiV3 {
|
|
121
128
|
const ai: ApiV3Ai = {
|
|
122
|
-
...createInspectFamily(handle),
|
|
129
|
+
...createInspectFamily(handle, opts?.pe2Evidence),
|
|
123
130
|
...createResolveFamily(handle),
|
|
124
|
-
...createBundleFamily(handle),
|
|
131
|
+
...createBundleFamily(handle, opts?.pe2Evidence),
|
|
125
132
|
...createReplacementFamily(handle),
|
|
126
133
|
...createAttachFamily(handle),
|
|
127
134
|
...createExportFamily(handle),
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact AI-facing pointer to an emitted ScopeActionAudit.
|
|
3
|
+
*
|
|
4
|
+
* The full audit bundle remains on the `scope` telemetry channel. Mutation
|
|
5
|
+
* return values expose only enough provenance for agents to cite the action
|
|
6
|
+
* and correlate it with telemetry.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ScopeActionAudit } from "../../../runtime/scopes/index.ts";
|
|
10
|
+
|
|
11
|
+
export interface AiActionAuditReference {
|
|
12
|
+
readonly actionId: string;
|
|
13
|
+
readonly actorId: string;
|
|
14
|
+
readonly origin: ScopeActionAudit["origin"];
|
|
15
|
+
readonly emittedAtUtc: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function projectAuditReference(
|
|
19
|
+
audit: ScopeActionAudit | null | undefined,
|
|
20
|
+
): AiActionAuditReference | undefined {
|
|
21
|
+
if (!audit) return undefined;
|
|
22
|
+
return {
|
|
23
|
+
actionId: audit.actionId,
|
|
24
|
+
actorId: audit.actorId,
|
|
25
|
+
origin: audit.origin,
|
|
26
|
+
emittedAtUtc: audit.emittedAtUtc,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { RuntimeApiHandle } from "../_runtime-handle.ts";
|
|
11
|
+
import type { ScopeHandle } from "../../../runtime/scopes/index.ts";
|
|
11
12
|
import type {
|
|
12
13
|
GeometryIndexCoverage,
|
|
13
14
|
GeometryPrecision,
|
|
@@ -15,6 +16,12 @@ import type {
|
|
|
15
16
|
GeometryReplacementEnvelopeEntry,
|
|
16
17
|
GeometrySourceIdentity,
|
|
17
18
|
} from "../../../runtime/geometry/index.ts";
|
|
19
|
+
import type { PublicLayoutDivergence } from "../../../runtime/layout/public-facet.ts";
|
|
20
|
+
import {
|
|
21
|
+
createHeaderFooterStoryKey,
|
|
22
|
+
createNoteStoryKey,
|
|
23
|
+
MAIN_STORY_KEY,
|
|
24
|
+
} from "../../../model/canonical-layout-inputs.ts";
|
|
18
25
|
|
|
19
26
|
export interface AiPe2GeometryCoverageEvidence {
|
|
20
27
|
readonly status: GeometryRehydrationStatus;
|
|
@@ -36,6 +43,8 @@ export interface AiPe2GeometryCoverageEvidence {
|
|
|
36
43
|
|
|
37
44
|
export interface AiPe2DocumentEvidence {
|
|
38
45
|
readonly geometry: AiPe2GeometryCoverageEvidence;
|
|
46
|
+
readonly layout: AiPe2LayoutEvidence;
|
|
47
|
+
readonly oracle: AiPe2OracleEvidence;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
export interface AiPe2ScopeReplacementEnvelopeEvidence {
|
|
@@ -52,6 +61,58 @@ export interface AiPe2ScopeEvidence {
|
|
|
52
61
|
readonly replacementEnvelope?: AiPe2ScopeReplacementEnvelopeEvidence;
|
|
53
62
|
readonly reason?: "geometry-index-unavailable" | "scope-envelope-not-found";
|
|
54
63
|
};
|
|
64
|
+
readonly layout: AiPe2LayoutEvidence;
|
|
65
|
+
readonly oracle: AiPe2OracleEvidence;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface AiPe2LayoutDivergenceEvidence {
|
|
69
|
+
readonly divergenceId: string;
|
|
70
|
+
readonly kind: string;
|
|
71
|
+
readonly source: string;
|
|
72
|
+
readonly severity: string;
|
|
73
|
+
readonly message: string;
|
|
74
|
+
readonly regionKinds?: readonly string[];
|
|
75
|
+
readonly fragmentIds?: readonly string[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface AiPe2LayoutEvidence {
|
|
79
|
+
readonly status: "realized" | "unavailable";
|
|
80
|
+
readonly pageCount: number;
|
|
81
|
+
readonly pageIds: readonly string[];
|
|
82
|
+
readonly pagesWithDivergences: readonly string[];
|
|
83
|
+
readonly divergenceIds: readonly string[];
|
|
84
|
+
readonly divergences: readonly AiPe2LayoutDivergenceEvidence[];
|
|
85
|
+
readonly reason?: "scope-page-evidence-not-found";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type AiPe2OracleVerdict =
|
|
89
|
+
| "match"
|
|
90
|
+
| "divergent"
|
|
91
|
+
| "blocked"
|
|
92
|
+
| "oracle-incomplete"
|
|
93
|
+
| "runtime-projection-not-wired"
|
|
94
|
+
| "not-compared";
|
|
95
|
+
|
|
96
|
+
export interface AiPe2OracleEvidence {
|
|
97
|
+
readonly status: "available" | "not-wired";
|
|
98
|
+
readonly runIds: readonly string[];
|
|
99
|
+
readonly divergenceIds: readonly string[];
|
|
100
|
+
readonly verdict?: AiPe2OracleVerdict;
|
|
101
|
+
readonly reason?: "truth-adapter-unavailable" | "truth-adapter-error";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface AiPe2OracleEvidenceProviderInput {
|
|
105
|
+
readonly documentId: string;
|
|
106
|
+
readonly scopeId?: string;
|
|
107
|
+
readonly pageIds: readonly string[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type AiPe2OracleEvidenceProvider = (
|
|
111
|
+
input: AiPe2OracleEvidenceProviderInput,
|
|
112
|
+
) => AiPe2OracleEvidence | null | undefined;
|
|
113
|
+
|
|
114
|
+
export interface AiPe2EvidenceOptions {
|
|
115
|
+
readonly oracle?: AiPe2OracleEvidenceProvider;
|
|
55
116
|
}
|
|
56
117
|
|
|
57
118
|
function copyCoverage(coverage: GeometryIndexCoverage): AiPe2GeometryCoverageEvidence {
|
|
@@ -100,54 +161,259 @@ const UNAVAILABLE_COVERAGE: AiPe2GeometryCoverageEvidence = {
|
|
|
100
161
|
precision: { exact: 0, "within-tolerance": 0, heuristic: 0 },
|
|
101
162
|
};
|
|
102
163
|
|
|
164
|
+
function copyLayoutDivergence(
|
|
165
|
+
divergence: PublicLayoutDivergence,
|
|
166
|
+
): AiPe2LayoutDivergenceEvidence {
|
|
167
|
+
return {
|
|
168
|
+
divergenceId: divergence.divergenceId,
|
|
169
|
+
kind: divergence.kind,
|
|
170
|
+
source: divergence.source,
|
|
171
|
+
severity: divergence.severity,
|
|
172
|
+
message: divergence.message,
|
|
173
|
+
...(divergence.regionKinds ? { regionKinds: [...divergence.regionKinds] } : {}),
|
|
174
|
+
...(divergence.fragmentIds ? { fragmentIds: [...divergence.fragmentIds] } : {}),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function projectLayoutEvidence(
|
|
179
|
+
runtime: RuntimeApiHandle,
|
|
180
|
+
pageIds?: readonly string[],
|
|
181
|
+
): AiPe2LayoutEvidence {
|
|
182
|
+
if (typeof runtime.layout?.getPageCount !== "function") {
|
|
183
|
+
return {
|
|
184
|
+
status: "unavailable",
|
|
185
|
+
pageCount: 0,
|
|
186
|
+
pageIds: [],
|
|
187
|
+
pagesWithDivergences: [],
|
|
188
|
+
divergenceIds: [],
|
|
189
|
+
divergences: [],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const pageCount = runtime.layout.getPageCount();
|
|
193
|
+
const selectedPageIds = pageIds ? new Set(pageIds) : null;
|
|
194
|
+
const pageIdOut: string[] = [];
|
|
195
|
+
const pagesWithDivergences: string[] = [];
|
|
196
|
+
const divergenceIds = new Set<string>();
|
|
197
|
+
const divergencesById = new Map<string, AiPe2LayoutDivergenceEvidence>();
|
|
198
|
+
|
|
199
|
+
for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
|
|
200
|
+
const page = runtime.layout.getPage(pageIndex);
|
|
201
|
+
if (!page) continue;
|
|
202
|
+
if (selectedPageIds && !selectedPageIds.has(page.pageId)) continue;
|
|
203
|
+
pageIdOut.push(page.pageId);
|
|
204
|
+
|
|
205
|
+
for (const divergenceId of page.frame?.divergenceIds ?? []) {
|
|
206
|
+
divergenceIds.add(divergenceId);
|
|
207
|
+
}
|
|
208
|
+
for (const divergence of page.divergences ?? []) {
|
|
209
|
+
divergenceIds.add(divergence.divergenceId);
|
|
210
|
+
divergencesById.set(divergence.divergenceId, copyLayoutDivergence(divergence));
|
|
211
|
+
}
|
|
212
|
+
if ((page.frame?.divergenceIds.length ?? 0) > 0 || (page.divergences?.length ?? 0) > 0) {
|
|
213
|
+
pagesWithDivergences.push(page.pageId);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
status: pageIdOut.length > 0 ? "realized" : "unavailable",
|
|
219
|
+
pageCount: pageIdOut.length,
|
|
220
|
+
pageIds: pageIdOut,
|
|
221
|
+
pagesWithDivergences,
|
|
222
|
+
divergenceIds: [...divergenceIds],
|
|
223
|
+
divergences: [...divergencesById.values()],
|
|
224
|
+
...(selectedPageIds && pageIdOut.length === 0
|
|
225
|
+
? { reason: "scope-page-evidence-not-found" as const }
|
|
226
|
+
: {}),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function copyOracleEvidence(evidence: AiPe2OracleEvidence): AiPe2OracleEvidence {
|
|
231
|
+
return {
|
|
232
|
+
status: evidence.status,
|
|
233
|
+
runIds: [...evidence.runIds],
|
|
234
|
+
divergenceIds: [...evidence.divergenceIds],
|
|
235
|
+
...(evidence.verdict ? { verdict: evidence.verdict } : {}),
|
|
236
|
+
...(evidence.reason ? { reason: evidence.reason } : {}),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function canonicalStoryKeyForHandle(handle: ScopeHandle): string {
|
|
241
|
+
const target = handle.storyTarget;
|
|
242
|
+
switch (target.kind) {
|
|
243
|
+
case "main":
|
|
244
|
+
return MAIN_STORY_KEY;
|
|
245
|
+
case "header":
|
|
246
|
+
return createHeaderFooterStoryKey({
|
|
247
|
+
kind: "header",
|
|
248
|
+
relationshipId: target.relationshipId,
|
|
249
|
+
variant: target.variant,
|
|
250
|
+
...(target.sectionIndex !== undefined ? { sectionIndex: target.sectionIndex } : {}),
|
|
251
|
+
});
|
|
252
|
+
case "footer":
|
|
253
|
+
return createHeaderFooterStoryKey({
|
|
254
|
+
kind: "footer",
|
|
255
|
+
relationshipId: target.relationshipId,
|
|
256
|
+
variant: target.variant,
|
|
257
|
+
...(target.sectionIndex !== undefined ? { sectionIndex: target.sectionIndex } : {}),
|
|
258
|
+
});
|
|
259
|
+
case "footnote":
|
|
260
|
+
return createNoteStoryKey("footnote", target.noteId);
|
|
261
|
+
case "endnote":
|
|
262
|
+
return createNoteStoryKey("endnote", target.noteId);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function semanticMainBlockPath(handle: ScopeHandle): string | null {
|
|
267
|
+
const path = handle.semanticPath;
|
|
268
|
+
if (path[0] !== "body") return null;
|
|
269
|
+
if (path[1] === "paragraph" || path[1] === "heading" || path[1] === "list-item") {
|
|
270
|
+
const blockIndex = path[path.length - 1];
|
|
271
|
+
return typeof blockIndex === "string" && /^\d+$/u.test(blockIndex)
|
|
272
|
+
? `${MAIN_STORY_KEY}/block[${blockIndex}]`
|
|
273
|
+
: null;
|
|
274
|
+
}
|
|
275
|
+
if (path[1] === "table" && typeof path[2] === "string" && /^\d+$/u.test(path[2])) {
|
|
276
|
+
return `${MAIN_STORY_KEY}/block[${path[2]}]`;
|
|
277
|
+
}
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function scoreEnvelopeForHandle(
|
|
282
|
+
envelope: GeometryReplacementEnvelopeEntry,
|
|
283
|
+
handle: ScopeHandle,
|
|
284
|
+
storyKey: string,
|
|
285
|
+
): number {
|
|
286
|
+
if (envelope.scopeId !== handle.scopeId) return -1;
|
|
287
|
+
const source = envelope.sourceIdentity;
|
|
288
|
+
if (!source) return 0;
|
|
289
|
+
|
|
290
|
+
let score = 1;
|
|
291
|
+
if (source.scopeId === handle.scopeId) score += 2;
|
|
292
|
+
if (source.storyKey === storyKey) score += 8;
|
|
293
|
+
if (source.scopeKey === `${storyKey}:scope:${handle.scopeId}` ||
|
|
294
|
+
source.scopeKey?.startsWith(`${storyKey}:scope:${handle.scopeId}:`)) {
|
|
295
|
+
score += 4;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const blockPath = semanticMainBlockPath(handle);
|
|
299
|
+
if (blockPath && source.blockPath === blockPath) score += 2;
|
|
300
|
+
|
|
301
|
+
return score;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function findReplacementEnvelopeForHandle(
|
|
305
|
+
envelopes: readonly GeometryReplacementEnvelopeEntry[],
|
|
306
|
+
handle: ScopeHandle,
|
|
307
|
+
): GeometryReplacementEnvelopeEntry | undefined {
|
|
308
|
+
const storyKey = canonicalStoryKeyForHandle(handle);
|
|
309
|
+
let best: GeometryReplacementEnvelopeEntry | undefined;
|
|
310
|
+
let bestScore = -1;
|
|
311
|
+
for (const envelope of envelopes) {
|
|
312
|
+
const score = scoreEnvelopeForHandle(envelope, handle, storyKey);
|
|
313
|
+
if (score > bestScore) {
|
|
314
|
+
best = envelope;
|
|
315
|
+
bestScore = score;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return bestScore >= 0 ? best : undefined;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function projectOracleEvidence(
|
|
322
|
+
runtime: RuntimeApiHandle,
|
|
323
|
+
options: AiPe2EvidenceOptions | undefined,
|
|
324
|
+
input: Omit<AiPe2OracleEvidenceProviderInput, "documentId">,
|
|
325
|
+
): AiPe2OracleEvidence {
|
|
326
|
+
const provider = options?.oracle;
|
|
327
|
+
if (provider) {
|
|
328
|
+
try {
|
|
329
|
+
const evidence = provider({
|
|
330
|
+
documentId: runtime.getSessionState().documentId,
|
|
331
|
+
...input,
|
|
332
|
+
});
|
|
333
|
+
if (evidence) return copyOracleEvidence(evidence);
|
|
334
|
+
} catch {
|
|
335
|
+
return {
|
|
336
|
+
status: "not-wired",
|
|
337
|
+
runIds: [],
|
|
338
|
+
divergenceIds: [],
|
|
339
|
+
reason: "truth-adapter-error",
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return {
|
|
344
|
+
status: "not-wired",
|
|
345
|
+
runIds: [],
|
|
346
|
+
divergenceIds: [],
|
|
347
|
+
reason: "truth-adapter-unavailable",
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
103
351
|
export function projectDocumentPe2Evidence(
|
|
104
352
|
runtime: RuntimeApiHandle,
|
|
353
|
+
options?: AiPe2EvidenceOptions,
|
|
105
354
|
): AiPe2DocumentEvidence {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
355
|
+
const layout = projectLayoutEvidence(runtime);
|
|
356
|
+
const geometry = runtime.geometry
|
|
357
|
+
? copyCoverage(runtime.geometry.getGeometryCoverage())
|
|
358
|
+
: UNAVAILABLE_COVERAGE;
|
|
109
359
|
return {
|
|
110
|
-
geometry
|
|
360
|
+
geometry,
|
|
361
|
+
layout,
|
|
362
|
+
oracle: projectOracleEvidence(runtime, options, { pageIds: layout.pageIds }),
|
|
111
363
|
};
|
|
112
364
|
}
|
|
113
365
|
|
|
114
366
|
export function projectScopePe2Evidence(
|
|
115
367
|
runtime: RuntimeApiHandle,
|
|
116
|
-
|
|
368
|
+
handle: ScopeHandle,
|
|
369
|
+
options?: AiPe2EvidenceOptions,
|
|
117
370
|
): AiPe2ScopeEvidence {
|
|
371
|
+
const { scopeId } = handle;
|
|
118
372
|
if (!runtime.geometry) {
|
|
373
|
+
const layout = projectLayoutEvidence(runtime, []);
|
|
119
374
|
return {
|
|
120
375
|
geometry: {
|
|
121
376
|
coverage: UNAVAILABLE_COVERAGE,
|
|
122
377
|
reason: "geometry-index-unavailable",
|
|
123
378
|
},
|
|
379
|
+
layout,
|
|
380
|
+
oracle: projectOracleEvidence(runtime, options, { scopeId, pageIds: layout.pageIds }),
|
|
124
381
|
};
|
|
125
382
|
}
|
|
126
383
|
const coverage = copyCoverage(runtime.geometry.getGeometryCoverage());
|
|
127
384
|
const index = runtime.geometry.getGeometryIndex();
|
|
128
385
|
if (!index) {
|
|
386
|
+
const layout = projectLayoutEvidence(runtime, []);
|
|
129
387
|
return {
|
|
130
388
|
geometry: {
|
|
131
389
|
coverage,
|
|
132
390
|
reason: "geometry-index-unavailable",
|
|
133
391
|
},
|
|
392
|
+
layout,
|
|
393
|
+
oracle: projectOracleEvidence(runtime, options, { scopeId, pageIds: layout.pageIds }),
|
|
134
394
|
};
|
|
135
395
|
}
|
|
136
396
|
|
|
137
|
-
const envelope = index.replacementEnvelopes
|
|
397
|
+
const envelope = findReplacementEnvelopeForHandle(index.replacementEnvelopes, handle);
|
|
138
398
|
if (!envelope) {
|
|
399
|
+
const layout = projectLayoutEvidence(runtime, []);
|
|
139
400
|
return {
|
|
140
401
|
geometry: {
|
|
141
402
|
coverage,
|
|
142
403
|
reason: "scope-envelope-not-found",
|
|
143
404
|
},
|
|
405
|
+
layout,
|
|
406
|
+
oracle: projectOracleEvidence(runtime, options, { scopeId, pageIds: layout.pageIds }),
|
|
144
407
|
};
|
|
145
408
|
}
|
|
146
409
|
|
|
410
|
+
const layout = projectLayoutEvidence(runtime, envelope.pageIds);
|
|
147
411
|
return {
|
|
148
412
|
geometry: {
|
|
149
413
|
coverage,
|
|
150
414
|
replacementEnvelope: copyEnvelope(envelope),
|
|
151
415
|
},
|
|
416
|
+
layout,
|
|
417
|
+
oracle: projectOracleEvidence(runtime, options, { scopeId, pageIds: layout.pageIds }),
|
|
152
418
|
};
|
|
153
419
|
}
|
package/src/api/v3/ai/attach.ts
CHANGED
|
@@ -37,15 +37,22 @@ import {
|
|
|
37
37
|
emitScopeMetadataAudit,
|
|
38
38
|
snapshotDocumentHash,
|
|
39
39
|
} from "./_metadata-audit.ts";
|
|
40
|
+
import {
|
|
41
|
+
projectAuditReference,
|
|
42
|
+
type AiActionAuditReference,
|
|
43
|
+
} from "./_audit-reference.ts";
|
|
40
44
|
|
|
41
45
|
export interface AttachExplanationInput {
|
|
42
46
|
readonly scopeId: string;
|
|
43
47
|
readonly explanation: string;
|
|
48
|
+
readonly actorId?: string;
|
|
49
|
+
readonly origin?: "ui" | "agent" | "host";
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
export interface AttachExplanationResult {
|
|
47
53
|
readonly explanationId: string;
|
|
48
54
|
readonly attached: boolean;
|
|
55
|
+
readonly auditReference?: AiActionAuditReference;
|
|
49
56
|
/**
|
|
50
57
|
* Present when `attached: false`. Mirrors the primitive's refusal
|
|
51
58
|
* reason (`scope-not-resolvable:<scopeId>` post-coord-06 §13c;
|
|
@@ -85,11 +92,14 @@ export interface CreateIssueInput {
|
|
|
85
92
|
readonly scopeId: string;
|
|
86
93
|
readonly summary: string;
|
|
87
94
|
readonly severity?: "info" | "warning" | "error";
|
|
95
|
+
readonly actorId?: string;
|
|
96
|
+
readonly origin?: "ui" | "agent" | "host";
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
export interface CreateIssueResult {
|
|
91
100
|
readonly issueId: string;
|
|
92
101
|
readonly created: boolean;
|
|
102
|
+
readonly auditReference?: AiActionAuditReference;
|
|
93
103
|
readonly reason?: string;
|
|
94
104
|
}
|
|
95
105
|
|
|
@@ -141,10 +151,13 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
141
151
|
explanation: input.explanation,
|
|
142
152
|
explanationId,
|
|
143
153
|
});
|
|
154
|
+
let auditReference: AiActionAuditReference | undefined;
|
|
144
155
|
if (primitiveResult.attached && preScope) {
|
|
145
|
-
emitScopeMetadataAudit({
|
|
156
|
+
const audit = emitScopeMetadataAudit({
|
|
146
157
|
runtime,
|
|
147
158
|
actionId: attachExplanationMetadata.name,
|
|
159
|
+
...(input.actorId ? { actorId: input.actorId } : {}),
|
|
160
|
+
...(input.origin ? { origin: input.origin } : {}),
|
|
148
161
|
scopeId: input.scopeId,
|
|
149
162
|
targetScopeSnapshot: preScope,
|
|
150
163
|
proposedContent: {
|
|
@@ -159,6 +172,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
159
172
|
emittedAtUtc: new Date(0).toISOString(),
|
|
160
173
|
documentHashBefore,
|
|
161
174
|
});
|
|
175
|
+
auditReference = projectAuditReference(audit);
|
|
162
176
|
}
|
|
163
177
|
emitUxResponse(runtime, {
|
|
164
178
|
apiFn: attachExplanationMetadata.name,
|
|
@@ -170,6 +184,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
170
184
|
return {
|
|
171
185
|
explanationId: primitiveResult.explanationId,
|
|
172
186
|
attached: primitiveResult.attached,
|
|
187
|
+
...(auditReference ? { auditReference } : {}),
|
|
173
188
|
// §1.17 — surface primitive's reason on refusal for symmetry
|
|
174
189
|
// with CreateIssueResult. The primitive returns `reason` only
|
|
175
190
|
// when `attached: false`; passthrough preserves that contract.
|
|
@@ -197,10 +212,13 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
197
212
|
...(input.severity ? { severity: input.severity } : {}),
|
|
198
213
|
issueId,
|
|
199
214
|
});
|
|
215
|
+
let auditReference: AiActionAuditReference | undefined;
|
|
200
216
|
if (primitiveResult.created && preScope) {
|
|
201
|
-
emitScopeMetadataAudit({
|
|
217
|
+
const audit = emitScopeMetadataAudit({
|
|
202
218
|
runtime,
|
|
203
219
|
actionId: createIssueMetadata.name,
|
|
220
|
+
...(input.actorId ? { actorId: input.actorId } : {}),
|
|
221
|
+
...(input.origin ? { origin: input.origin } : {}),
|
|
204
222
|
scopeId: input.scopeId,
|
|
205
223
|
targetScopeSnapshot: preScope,
|
|
206
224
|
proposedContent: {
|
|
@@ -216,6 +234,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
216
234
|
emittedAtUtc: new Date(0).toISOString(),
|
|
217
235
|
documentHashBefore,
|
|
218
236
|
});
|
|
237
|
+
auditReference = projectAuditReference(audit);
|
|
219
238
|
}
|
|
220
239
|
emitUxResponse(runtime, {
|
|
221
240
|
apiFn: createIssueMetadata.name,
|
|
@@ -227,6 +246,7 @@ export function createAttachFamily(runtime: RuntimeApiHandle) {
|
|
|
227
246
|
const out: CreateIssueResult = {
|
|
228
247
|
issueId: primitiveResult.issueId,
|
|
229
248
|
created: primitiveResult.created,
|
|
249
|
+
...(auditReference ? { auditReference } : {}),
|
|
230
250
|
...(primitiveResult.created ? {} : { reason: primitiveResult.reason }),
|
|
231
251
|
};
|
|
232
252
|
return out;
|
package/src/api/v3/ai/bundle.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
27
27
|
import {
|
|
28
28
|
projectScopePe2Evidence,
|
|
29
|
+
type AiPe2EvidenceOptions,
|
|
29
30
|
type AiPe2ScopeEvidence,
|
|
30
31
|
} from "./_pe2-evidence.ts";
|
|
31
32
|
|
|
@@ -103,7 +104,10 @@ export const getScopeBundleMetadata: ApiV3FnMetadata = {
|
|
|
103
104
|
rwdReference: "§AI API § ai.getScopeBundle",
|
|
104
105
|
};
|
|
105
106
|
|
|
106
|
-
export function createBundleFamily(
|
|
107
|
+
export function createBundleFamily(
|
|
108
|
+
runtime: RuntimeApiHandle,
|
|
109
|
+
pe2Evidence?: AiPe2EvidenceOptions,
|
|
110
|
+
) {
|
|
107
111
|
const compiler = createScopeCompilerService(runtime);
|
|
108
112
|
return {
|
|
109
113
|
getScope(input: GetScopeInput): SemanticScope | null {
|
|
@@ -133,7 +137,7 @@ export function createBundleFamily(runtime: RuntimeApiHandle) {
|
|
|
133
137
|
}
|
|
134
138
|
return {
|
|
135
139
|
...bundle,
|
|
136
|
-
pe2Evidence: projectScopePe2Evidence(runtime,
|
|
140
|
+
pe2Evidence: projectScopePe2Evidence(runtime, input.handle, pe2Evidence),
|
|
137
141
|
};
|
|
138
142
|
},
|
|
139
143
|
};
|
package/src/api/v3/ai/inspect.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
import type { ApiV3FnMetadata } from "../_layer-metadata.ts";
|
|
19
19
|
import {
|
|
20
20
|
projectDocumentPe2Evidence,
|
|
21
|
+
type AiPe2EvidenceOptions,
|
|
21
22
|
type AiPe2DocumentEvidence,
|
|
22
23
|
} from "./_pe2-evidence.ts";
|
|
23
24
|
|
|
@@ -84,7 +85,10 @@ function buildKindDistribution(
|
|
|
84
85
|
return out;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
export function createInspectFamily(
|
|
88
|
+
export function createInspectFamily(
|
|
89
|
+
runtime: RuntimeApiHandle,
|
|
90
|
+
pe2Evidence?: AiPe2EvidenceOptions,
|
|
91
|
+
) {
|
|
88
92
|
const compiler = createScopeCompilerService(runtime);
|
|
89
93
|
return {
|
|
90
94
|
inspectDocument(): InspectDocumentResult {
|
|
@@ -102,7 +106,7 @@ export function createInspectFamily(runtime: RuntimeApiHandle) {
|
|
|
102
106
|
scopeCount: scopes.length,
|
|
103
107
|
semanticSummary: summary,
|
|
104
108
|
kindDistribution,
|
|
105
|
-
pe2Evidence: projectDocumentPe2Evidence(runtime),
|
|
109
|
+
pe2Evidence: projectDocumentPe2Evidence(runtime, pe2Evidence),
|
|
106
110
|
};
|
|
107
111
|
},
|
|
108
112
|
|
|
@@ -33,6 +33,10 @@ import type {
|
|
|
33
33
|
} from "../../../runtime/scopes/index.ts";
|
|
34
34
|
import type { AIAction } from "../../../runtime/workflow/ai-action-policy.ts";
|
|
35
35
|
import type { TextFormattingDirective } from "../../public-types.ts";
|
|
36
|
+
import {
|
|
37
|
+
projectAuditReference,
|
|
38
|
+
type AiActionAuditReference,
|
|
39
|
+
} from "./_audit-reference.ts";
|
|
36
40
|
|
|
37
41
|
export interface ReplacementProposalInput {
|
|
38
42
|
readonly targetScopeId: string;
|
|
@@ -125,6 +129,7 @@ export interface ApplyResult {
|
|
|
125
129
|
readonly blockers?: readonly string[];
|
|
126
130
|
readonly blockerDetails?: readonly ActionBlockerDetail[];
|
|
127
131
|
readonly auditHint?: string;
|
|
132
|
+
readonly auditReference?: AiActionAuditReference;
|
|
128
133
|
/**
|
|
129
134
|
* Gap A (post-Slice-7 integration) — revision IDs authored during
|
|
130
135
|
* the apply. Populated for suggest-mode (tracked insert + delete);
|
|
@@ -488,6 +493,9 @@ export function createReplacementFamily(runtime: RuntimeApiHandle) {
|
|
|
488
493
|
: {}),
|
|
489
494
|
...(blockerDetails ? { blockerDetails } : {}),
|
|
490
495
|
...(result.audit ? { auditHint: result.audit.actionId } : {}),
|
|
496
|
+
...(result.audit
|
|
497
|
+
? { auditReference: projectAuditReference(result.audit) }
|
|
498
|
+
: {}),
|
|
491
499
|
authoredRevisionIds: result.authoredRevisionIds,
|
|
492
500
|
};
|
|
493
501
|
},
|
|
@@ -533,6 +541,9 @@ export function createReplacementFamily(runtime: RuntimeApiHandle) {
|
|
|
533
541
|
: {}),
|
|
534
542
|
...(blockerDetails ? { blockerDetails } : {}),
|
|
535
543
|
...(result.audit ? { auditHint: result.audit.actionId } : {}),
|
|
544
|
+
...(result.audit
|
|
545
|
+
? { auditReference: projectAuditReference(result.audit) }
|
|
546
|
+
: {}),
|
|
536
547
|
authoredRevisionIds: result.authoredRevisionIds,
|
|
537
548
|
};
|
|
538
549
|
},
|
package/src/api/v3/index.ts
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
export { createApiV3 } from "./_create.ts";
|
|
16
16
|
export type { ApiV3, CreateApiV3Opts } from "./_create.ts";
|
|
17
|
+
export type {
|
|
18
|
+
AiPe2EvidenceOptions,
|
|
19
|
+
AiPe2OracleEvidence,
|
|
20
|
+
AiPe2OracleEvidenceProvider,
|
|
21
|
+
AiPe2OracleEvidenceProviderInput,
|
|
22
|
+
AiPe2OracleVerdict,
|
|
23
|
+
} from "./ai/_pe2-evidence.ts";
|
|
17
24
|
|
|
18
25
|
export type {
|
|
19
26
|
ApiStatus,
|