@inflexa-ai/harness 0.18.0 → 0.19.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.
- package/dist/agents/report-session-agent.d.ts +56 -0
- package/dist/agents/report-session-agent.js +72 -0
- package/dist/app/report-session-runtime.d.ts +72 -0
- package/dist/app/report-session-runtime.js +157 -0
- package/dist/memory/thread-store.d.ts +4 -4
- package/dist/memory/thread-store.js +18 -9
- package/dist/prompts/report-session.d.ts +1 -0
- package/dist/prompts/report-session.js +89 -0
- package/dist/providers/ai-sdk.d.ts +77 -0
- package/dist/providers/ai-sdk.js +149 -19
- package/dist/providers/errors.d.ts +14 -0
- package/dist/providers/errors.js +103 -18
- package/dist/providers/types.d.ts +16 -0
- package/dist/providers/types.js +10 -1
- package/dist/report-model/{mint-snapshot.d.ts → pin-snapshot.d.ts} +7 -7
- package/dist/report-model/{mint-snapshot.js → pin-snapshot.js} +7 -7
- package/dist/report-model/reference-resolver.d.ts +1 -1
- package/dist/report-model/validate.d.ts +34 -2
- package/dist/report-model/validate.js +32 -17
- package/dist/report-render/value-bridge.d.ts +62 -0
- package/dist/report-render/value-bridge.js +82 -0
- package/dist/runtime/assemble.d.ts +15 -0
- package/dist/runtime/assemble.js +28 -6
- package/dist/state/init.js +23 -0
- package/dist/state/purge-analysis.js +1 -0
- package/dist/state/report-session-state.d.ts +112 -0
- package/dist/state/report-session-state.js +150 -0
- package/dist/state/report-versions.d.ts +3 -6
- package/dist/state/report-versions.js +11 -38
- package/dist/state/snapshot-parse.d.ts +34 -0
- package/dist/state/snapshot-parse.js +82 -0
- package/dist/tools/ad-hoc-router.d.ts +7 -2
- package/dist/tools/ad-hoc-router.js +2 -1
- package/dist/tools/report-authoring/authoring-tools.d.ts +131 -24
- package/dist/tools/report-authoring/authoring-tools.js +152 -44
- package/dist/tools/report-session/index.d.ts +8 -0
- package/dist/tools/report-session/index.js +8 -0
- package/dist/tools/report-session/preview-report.d.ts +90 -0
- package/dist/tools/report-session/preview-report.js +245 -0
- package/dist/tools/research/generate-plan.js +4 -2
- package/package.json +1 -1
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The authoring tool surface over the draft operations.
|
|
3
3
|
*
|
|
4
|
-
* The factory
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The factory takes a session-state gateway, and it holds no draft. Each tool reads the thread id from the
|
|
5
|
+
* scope of the call, loads the state of that thread, applies the pure operation, and persists the new
|
|
6
|
+
* document. Thus two threads never share one draft, and a landed document outlives a host restart.
|
|
7
7
|
*
|
|
8
|
-
* Each tool maps its flat input onto a core operation, and it applies the pure operation.
|
|
9
|
-
*
|
|
10
|
-
* error channel stays for an unexpected failure.
|
|
8
|
+
* Each tool maps its flat input onto a core operation, and it applies the pure operation. A landed
|
|
9
|
+
* document persists before the tool reports `applied: true`. A refused operation returns typed data in the
|
|
10
|
+
* ok channel, and the error channel stays for an unexpected failure.
|
|
11
|
+
*
|
|
12
|
+
* A call with no report thread in its scope, a thread with no stored state, and a gateway fault each
|
|
13
|
+
* refuse as typed data too. That refusal sits beside the core refusal, and it names the absent thread
|
|
14
|
+
* scope or the absent state.
|
|
11
15
|
*
|
|
12
16
|
* The primitive admits a flat object input only. Thus a destination is four optional fields, and not a
|
|
13
17
|
* nested union. A conflict between the flat fields refuses before the core runs.
|
|
14
18
|
*/
|
|
15
19
|
import { err, ok } from "neverthrow";
|
|
16
20
|
import { z } from "zod";
|
|
21
|
+
import { isSafeId } from "../../workspace/paths.js";
|
|
17
22
|
import { addBlock, changeBlock, locate, moveBlock, removeBlock, setTitle, } from "../../report-model/draft-operations.js";
|
|
18
23
|
import { buildOutline, childOutline, readBlock } from "../../report-model/draft-read.js";
|
|
19
24
|
import { finishDraft } from "../../report-model/draft-finish.js";
|
|
@@ -78,6 +83,44 @@ const setTitleInput = z.object({
|
|
|
78
83
|
title: z.string().min(1),
|
|
79
84
|
});
|
|
80
85
|
const finishDraftInput = z.object({});
|
|
86
|
+
/**
|
|
87
|
+
* Resolve the report thread of a call, and load its state through the gateway.
|
|
88
|
+
*
|
|
89
|
+
* The report thread and its analysis ride on the analysis scope. The thread id becomes one segment of a
|
|
90
|
+
* session directory, thus the safe-id check sits here beside the shape check: a scope whose id carries a
|
|
91
|
+
* separator or a traversal segment names no thread that a tool can write under.
|
|
92
|
+
*
|
|
93
|
+
* The stored analysis of the thread must match the scope. A mismatch reads one analysis's draft and writes
|
|
94
|
+
* into another analysis's workspace, thus the resolution refuses it with a permanent reason that names the
|
|
95
|
+
* two ids. A scope of a different kind, an unsafe id, an absent thread, a wrong thread type, and a gateway
|
|
96
|
+
* fault each refuse as a typed `SessionRefusal` too.
|
|
97
|
+
*
|
|
98
|
+
* The authoring tools and the preview tool share this one resolution, thus the two surfaces accept the
|
|
99
|
+
* same thread id and map a load outcome onto a refusal the same way.
|
|
100
|
+
*/
|
|
101
|
+
export async function openReportThread(gateway, scope) {
|
|
102
|
+
if (scope.kind !== "analysis" || scope.threadId === undefined || !isSafeId(scope.threadId)) {
|
|
103
|
+
return err({ reason: "no-thread-scope", detail: "the scope of the call names no usable report thread id" });
|
|
104
|
+
}
|
|
105
|
+
const { threadId, analysisId } = scope;
|
|
106
|
+
const loaded = await gateway.load(threadId);
|
|
107
|
+
if (loaded.outcome === "absent") {
|
|
108
|
+
return err({ reason: "absent-state", detail: `no report session exists for the thread ${threadId}, and this condition is permanent` });
|
|
109
|
+
}
|
|
110
|
+
if (loaded.outcome === "wrong-type") {
|
|
111
|
+
return err({ reason: "wrong-thread-type", detail: `${loaded.detail}, and this condition is permanent` });
|
|
112
|
+
}
|
|
113
|
+
if (loaded.outcome === "failed") {
|
|
114
|
+
return err({ reason: "state-unavailable", detail: loaded.detail });
|
|
115
|
+
}
|
|
116
|
+
if (loaded.analysisId !== analysisId) {
|
|
117
|
+
return err({
|
|
118
|
+
reason: "scope-analysis-mismatch",
|
|
119
|
+
detail: `the scope names the analysis ${analysisId}, but the thread ${threadId} belongs to the analysis ${loaded.analysisId}`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return ok({ threadId, analysisId, state: loaded.state, token: loaded.token });
|
|
123
|
+
}
|
|
81
124
|
/** Read an absentable field. An explicit `null` and an omitted key both mean that the model gave no value. */
|
|
82
125
|
function given(value) {
|
|
83
126
|
return value ?? undefined;
|
|
@@ -197,37 +240,59 @@ function containerIn(document, parentId) {
|
|
|
197
240
|
/**
|
|
198
241
|
* Every tool of this surface runs inline.
|
|
199
242
|
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
243
|
+
* A tool loads the state of its thread, applies the pure operation, and persists the result in one body.
|
|
244
|
+
* The reported outline must agree with the row that the body just wrote. A step-mode tool goes through
|
|
245
|
+
* `DBOS.runStep`, which caches the result of a step and replays it without a fresh load. A replay could
|
|
246
|
+
* then report an outline that the current row no longer holds. Inline mode reads and writes the row in one
|
|
247
|
+
* lifetime, thus the outline never drifts from the state.
|
|
205
248
|
*/
|
|
206
249
|
const AUTHORING_EXECUTION_MODE = "inline";
|
|
207
250
|
/**
|
|
208
|
-
* Make the eight authoring tools over
|
|
251
|
+
* Make the eight authoring tools over a session-state gateway.
|
|
209
252
|
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
253
|
+
* Each tool reads the thread id from the scope of the call, and it loads the state of that thread through
|
|
254
|
+
* the gateway. Thus one factory serves every thread, and two threads never share one draft. A mutation
|
|
255
|
+
* persists the new document before it reports `applied: true`, thus a reported landing is never lost.
|
|
213
256
|
*/
|
|
214
|
-
export function createReportAuthoringTools(
|
|
215
|
-
|
|
216
|
-
|
|
257
|
+
export function createReportAuthoringTools(gateway) {
|
|
258
|
+
/**
|
|
259
|
+
* Resolve the thread of the call, and load its state.
|
|
260
|
+
*
|
|
261
|
+
* The shared `openReportThread` holds the one resolution. A scope of a different kind, an unsafe or
|
|
262
|
+
* absent thread id, an absent row, and a gateway fault each refuse before the call reaches a core
|
|
263
|
+
* operation.
|
|
264
|
+
*/
|
|
265
|
+
const openThread = (ctx) => openReportThread(gateway, ctx.session.scope);
|
|
217
266
|
/**
|
|
218
|
-
*
|
|
267
|
+
* Persist a landing, and report the containers that the operation changed.
|
|
219
268
|
*
|
|
220
|
-
* `holders` names them by id, and it reads the
|
|
221
|
-
* removed block has a holder only in the first and an added block has one only in the second. The
|
|
222
|
-
*
|
|
269
|
+
* `holders` names them by id, and it reads the previous document and the next document, because a
|
|
270
|
+
* removed block has a holder only in the first and an added block has one only in the second. The child
|
|
271
|
+
* order comes out of `next` in either case. A persist fault refuses with `state-unavailable`, thus the
|
|
272
|
+
* tool reports `applied: true` only after the row holds the new document.
|
|
273
|
+
*
|
|
274
|
+
* The persist is a compare-and-swap against the token that the load read. A concurrent turn that landed
|
|
275
|
+
* first turns the persist into a conflict, and the tool refuses with `stale-state`.
|
|
223
276
|
*/
|
|
224
|
-
const land = (
|
|
225
|
-
|
|
226
|
-
|
|
277
|
+
const land = async (threadId, token, previous, result, holders) => {
|
|
278
|
+
if (result.isErr()) {
|
|
279
|
+
return { applied: false, refusal: result.error };
|
|
280
|
+
}
|
|
281
|
+
const next = result.value;
|
|
282
|
+
const persisted = await gateway.persist(threadId, next, token);
|
|
283
|
+
if (persisted.outcome === "conflict") {
|
|
284
|
+
return {
|
|
285
|
+
applied: false,
|
|
286
|
+
refusal: { reason: "stale-state", detail: "another turn changed the report since this turn read it, thus read the state again" },
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
if (persisted.outcome === "failed") {
|
|
290
|
+
return { applied: false, refusal: { reason: "state-unavailable", detail: persisted.detail } };
|
|
291
|
+
}
|
|
227
292
|
// A move inside one container names the same holder two times.
|
|
228
293
|
const unique = [...new Set(holders(previous, next))];
|
|
229
294
|
return { applied: true, changed: unique.map((parentId) => containerIn(next, parentId)) };
|
|
230
|
-
}
|
|
295
|
+
};
|
|
231
296
|
const refuse = (refusal) => ({ applied: false, refusal });
|
|
232
297
|
const add_block = defineTool({
|
|
233
298
|
id: "add_block",
|
|
@@ -241,16 +306,19 @@ export function createReportAuthoringTools(state) {
|
|
|
241
306
|
const kind = readKind(decodeBlockPayload(input.block));
|
|
242
307
|
return kind !== undefined ? `add ${kind}` : "add a block";
|
|
243
308
|
},
|
|
244
|
-
execute: async (input) => {
|
|
309
|
+
execute: async (input, ctx) => {
|
|
310
|
+
const opened = await openThread(ctx);
|
|
311
|
+
if (opened.isErr()) {
|
|
312
|
+
return ok(refuse(opened.error));
|
|
313
|
+
}
|
|
314
|
+
const { threadId, state, token } = opened.value;
|
|
245
315
|
const destination = toDestination(input);
|
|
246
316
|
if (destination.isErr()) {
|
|
247
317
|
return ok(refuse(destination.error));
|
|
248
318
|
}
|
|
249
319
|
const block = decodeBlockPayload(input.block);
|
|
250
320
|
const addedId = readId(block);
|
|
251
|
-
return ok(land(addBlock(
|
|
252
|
-
addedId === undefined ? undefined : holderIdOf(next, addedId),
|
|
253
|
-
]));
|
|
321
|
+
return ok(await land(threadId, token, state.document, addBlock(state.document, { block, destination: destination.value }, state.snapshot), (_previous, next) => [addedId === undefined ? undefined : holderIdOf(next, addedId)]));
|
|
254
322
|
},
|
|
255
323
|
});
|
|
256
324
|
const change_block = defineTool({
|
|
@@ -260,12 +328,19 @@ export function createReportAuthoringTools(state) {
|
|
|
260
328
|
inputSchema: changeBlockInput,
|
|
261
329
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
262
330
|
describeCall: (input) => `change ${input.targetId}`,
|
|
263
|
-
execute: async (input) => {
|
|
331
|
+
execute: async (input, ctx) => {
|
|
332
|
+
const opened = await openThread(ctx);
|
|
333
|
+
if (opened.isErr()) {
|
|
334
|
+
return ok(refuse(opened.error));
|
|
335
|
+
}
|
|
336
|
+
const { threadId, state, token } = opened.value;
|
|
264
337
|
const operation = toChangeOperation(input);
|
|
265
338
|
if (operation.isErr()) {
|
|
266
339
|
return ok(refuse(operation.error));
|
|
267
340
|
}
|
|
268
|
-
return ok(land(changeBlock(
|
|
341
|
+
return ok(await land(threadId, token, state.document, changeBlock(state.document, operation.value, state.snapshot), (_previous, next) => [
|
|
342
|
+
holderIdOf(next, input.targetId),
|
|
343
|
+
]));
|
|
269
344
|
},
|
|
270
345
|
});
|
|
271
346
|
const remove_block = defineTool({
|
|
@@ -274,7 +349,16 @@ export function createReportAuthoringTools(state) {
|
|
|
274
349
|
inputSchema: removeBlockInput,
|
|
275
350
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
276
351
|
describeCall: (input) => `remove ${input.targetId}`,
|
|
277
|
-
execute: async (input
|
|
352
|
+
execute: async (input, ctx) => {
|
|
353
|
+
const opened = await openThread(ctx);
|
|
354
|
+
if (opened.isErr()) {
|
|
355
|
+
return ok(refuse(opened.error));
|
|
356
|
+
}
|
|
357
|
+
const { threadId, state, token } = opened.value;
|
|
358
|
+
return ok(await land(threadId, token, state.document, removeBlock(state.document, { targetId: input.targetId }, state.snapshot), (previous) => [
|
|
359
|
+
holderIdOf(previous, input.targetId),
|
|
360
|
+
]));
|
|
361
|
+
},
|
|
278
362
|
});
|
|
279
363
|
const move_block = defineTool({
|
|
280
364
|
id: "move_block",
|
|
@@ -283,15 +367,17 @@ export function createReportAuthoringTools(state) {
|
|
|
283
367
|
inputSchema: moveBlockInput,
|
|
284
368
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
285
369
|
describeCall: (input) => `move ${input.targetId}`,
|
|
286
|
-
execute: async (input) => {
|
|
370
|
+
execute: async (input, ctx) => {
|
|
371
|
+
const opened = await openThread(ctx);
|
|
372
|
+
if (opened.isErr()) {
|
|
373
|
+
return ok(refuse(opened.error));
|
|
374
|
+
}
|
|
375
|
+
const { threadId, state, token } = opened.value;
|
|
287
376
|
const destination = toDestination(input);
|
|
288
377
|
if (destination.isErr()) {
|
|
289
378
|
return ok(refuse(destination.error));
|
|
290
379
|
}
|
|
291
|
-
return ok(land(moveBlock(
|
|
292
|
-
holderIdOf(previous, input.targetId),
|
|
293
|
-
holderIdOf(next, input.targetId),
|
|
294
|
-
]));
|
|
380
|
+
return ok(await land(threadId, token, state.document, moveBlock(state.document, { targetId: input.targetId, destination: destination.value }, state.snapshot), (previous, next) => [holderIdOf(previous, input.targetId), holderIdOf(next, input.targetId)]));
|
|
295
381
|
},
|
|
296
382
|
});
|
|
297
383
|
const set_title = defineTool({
|
|
@@ -302,7 +388,14 @@ export function createReportAuthoringTools(state) {
|
|
|
302
388
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
303
389
|
describeCall: (input) => `title the report ${input.title}`,
|
|
304
390
|
// The title sits on the document, thus no container changes its child order.
|
|
305
|
-
execute: async (input
|
|
391
|
+
execute: async (input, ctx) => {
|
|
392
|
+
const opened = await openThread(ctx);
|
|
393
|
+
if (opened.isErr()) {
|
|
394
|
+
return ok(refuse(opened.error));
|
|
395
|
+
}
|
|
396
|
+
const { threadId, state, token } = opened.value;
|
|
397
|
+
return ok(await land(threadId, token, state.document, ok(setTitle(state.document, input.title)), () => []));
|
|
398
|
+
},
|
|
306
399
|
});
|
|
307
400
|
const read_outline = defineTool({
|
|
308
401
|
id: "read_outline",
|
|
@@ -313,7 +406,13 @@ export function createReportAuthoringTools(state) {
|
|
|
313
406
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
314
407
|
// The input carries no field, thus a hook can only restate the name of the tool.
|
|
315
408
|
describeCall: "none",
|
|
316
|
-
execute: async () =>
|
|
409
|
+
execute: async (_input, ctx) => {
|
|
410
|
+
const opened = await openThread(ctx);
|
|
411
|
+
if (opened.isErr()) {
|
|
412
|
+
return ok({ refused: opened.error });
|
|
413
|
+
}
|
|
414
|
+
return ok({ outline: buildOutline(opened.value.state.document) });
|
|
415
|
+
},
|
|
317
416
|
});
|
|
318
417
|
const read_block = defineTool({
|
|
319
418
|
id: "read_block",
|
|
@@ -322,8 +421,12 @@ export function createReportAuthoringTools(state) {
|
|
|
322
421
|
inputSchema: readBlockInput,
|
|
323
422
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
324
423
|
describeCall: (input) => `read ${input.targetId}`,
|
|
325
|
-
execute: async (input) => {
|
|
326
|
-
const
|
|
424
|
+
execute: async (input, ctx) => {
|
|
425
|
+
const opened = await openThread(ctx);
|
|
426
|
+
if (opened.isErr()) {
|
|
427
|
+
return ok({ refused: opened.error });
|
|
428
|
+
}
|
|
429
|
+
const block = readBlock(opened.value.state.document, input.targetId);
|
|
327
430
|
const result = block !== undefined ? { found: true, block } : { found: false };
|
|
328
431
|
return ok(result);
|
|
329
432
|
},
|
|
@@ -336,7 +439,13 @@ export function createReportAuthoringTools(state) {
|
|
|
336
439
|
executionMode: AUTHORING_EXECUTION_MODE,
|
|
337
440
|
// The input carries no field, thus a hook can only restate the name of the tool.
|
|
338
441
|
describeCall: "none",
|
|
339
|
-
execute: async () =>
|
|
442
|
+
execute: async (_input, ctx) => {
|
|
443
|
+
const opened = await openThread(ctx);
|
|
444
|
+
if (opened.isErr()) {
|
|
445
|
+
return ok({ refused: opened.error });
|
|
446
|
+
}
|
|
447
|
+
return ok(finishDraft(opened.value.state.document, opened.value.state.snapshot));
|
|
448
|
+
},
|
|
340
449
|
});
|
|
341
450
|
return {
|
|
342
451
|
add_block,
|
|
@@ -347,6 +456,5 @@ export function createReportAuthoringTools(state) {
|
|
|
347
456
|
read_outline,
|
|
348
457
|
read_block,
|
|
349
458
|
finish_draft,
|
|
350
|
-
currentDraft: () => draft,
|
|
351
459
|
};
|
|
352
460
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report-session tool barrel.
|
|
3
|
+
*
|
|
4
|
+
* These tools serve a `report` thread. The runtime constructs them over the session-state gateway and the
|
|
5
|
+
* render seams, thus each tool binds the per-session state to the thread of the call. The barrel exports
|
|
6
|
+
* the factories and their public types for the composition root.
|
|
7
|
+
*/
|
|
8
|
+
export { createPreviewReportTool, type PreviewReportInput, type PreviewReportResult, type PreviewReportToolDeps } from "./preview-report.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report-session tool barrel.
|
|
3
|
+
*
|
|
4
|
+
* These tools serve a `report` thread. The runtime constructs them over the session-state gateway and the
|
|
5
|
+
* render seams, thus each tool binds the per-session state to the thread of the call. The barrel exports
|
|
6
|
+
* the factories and their public types for the composition root.
|
|
7
|
+
*/
|
|
8
|
+
export { createPreviewReportTool } from "./preview-report.js";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The render-and-preview tool of a report session.
|
|
3
|
+
*
|
|
4
|
+
* The tool renders the current draft of a thread. It runs the finish first, because a mid-composition
|
|
5
|
+
* draft is not a `ReportDocument`. A gap list returns as data, and no render runs. On a pass the tool
|
|
6
|
+
* resolves each reference through the injected resolver, bridges the resolved values into the render model,
|
|
7
|
+
* and renders the page.
|
|
8
|
+
*
|
|
9
|
+
* The page and its staged image assets land in `report-sessions/{threadId}/` under the workspace root. That
|
|
10
|
+
* namespace belongs to this path alone, thus the tool never writes under the old `previews/` or `reports/`
|
|
11
|
+
* trees. The result carries the absolute page path, thus a local host shows the page with no seam.
|
|
12
|
+
*
|
|
13
|
+
* The result carries no access grant. `PreviewPublisher` authorizes the URL space
|
|
14
|
+
* `previews/{analysisId}/{previewId}` (`contracts/content-url.ts`), and that space cannot name a page of
|
|
15
|
+
* this tree. A hosted view of a session page is a later capability, with a URL space of its own.
|
|
16
|
+
*
|
|
17
|
+
* Each degraded condition is a typed outcome in the ok channel: a session refusal, a gap list, a resolver
|
|
18
|
+
* absence, an unresolved reference, a bridge mismatch, a render problem, a figure that escapes the
|
|
19
|
+
* workspace root, and a write failure. The tool never throws for one of them. The filesystem speaks the
|
|
20
|
+
* throw protocol, and the workspace-root seam signals an unresolvable resource the same way. Thus the
|
|
21
|
+
* write runs through the `tryFs` glue, which turns a genuine fault into the ok-channel outcome and lets a
|
|
22
|
+
* control-flow exception propagate.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from "zod";
|
|
25
|
+
import { type ResolveWorkspaceRoot } from "../../workspace/paths.js";
|
|
26
|
+
import { type Logger } from "../../lib/logger.js";
|
|
27
|
+
import { type FinishGap } from "../../report-model/draft-finish.js";
|
|
28
|
+
import type { ReferenceResolver } from "../../report-model/reference-resolver.js";
|
|
29
|
+
import { type ResolutionFailure } from "../../report-model/validate.js";
|
|
30
|
+
import { type BridgeMismatch } from "../../report-render/value-bridge.js";
|
|
31
|
+
import type { RenderProblem } from "../../report-render/types.js";
|
|
32
|
+
import { type Tool } from "../define-tool.js";
|
|
33
|
+
import { type ReportSessionStateGateway, type SessionRefusal } from "../report-authoring/authoring-tools.js";
|
|
34
|
+
/** The empty input. The tool renders the current draft of the thread, thus it needs no field. */
|
|
35
|
+
declare const previewReportInput: z.ZodObject<{}, z.core.$strip>;
|
|
36
|
+
export type PreviewReportInput = z.infer<typeof previewReportInput>;
|
|
37
|
+
/**
|
|
38
|
+
* The typed outcome of the preview tool. Each arm is ok-channel data, thus the tool never throws for a
|
|
39
|
+
* degraded condition. `rendered` carries the absolute page path.
|
|
40
|
+
*/
|
|
41
|
+
export type PreviewReportResult = {
|
|
42
|
+
outcome: "refused";
|
|
43
|
+
refusal: SessionRefusal;
|
|
44
|
+
} | {
|
|
45
|
+
outcome: "gaps";
|
|
46
|
+
gaps: FinishGap[];
|
|
47
|
+
} | {
|
|
48
|
+
outcome: "resolver-unavailable";
|
|
49
|
+
} | {
|
|
50
|
+
outcome: "unresolved-references";
|
|
51
|
+
unresolved: ResolutionFailure[];
|
|
52
|
+
} | {
|
|
53
|
+
outcome: "bridge-mismatch";
|
|
54
|
+
mismatches: BridgeMismatch[];
|
|
55
|
+
} | {
|
|
56
|
+
outcome: "render-problems";
|
|
57
|
+
problems: RenderProblem[];
|
|
58
|
+
} | {
|
|
59
|
+
outcome: "figure-out-of-scope";
|
|
60
|
+
blockId: string;
|
|
61
|
+
path: string;
|
|
62
|
+
} | {
|
|
63
|
+
outcome: "write-failed";
|
|
64
|
+
detail: string;
|
|
65
|
+
} | {
|
|
66
|
+
outcome: "rendered";
|
|
67
|
+
pagePath: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* The construction deps of the preview tool.
|
|
71
|
+
*
|
|
72
|
+
* `resolveWorkspaceRoot` maps the analysis of the call onto its workspace root, thus one singleton tool
|
|
73
|
+
* serves every analysis and it resolves the root per call from the scope. `resolver` is optional, because a
|
|
74
|
+
* resolver realization can be absent.
|
|
75
|
+
*/
|
|
76
|
+
export interface PreviewReportToolDeps {
|
|
77
|
+
readonly gateway: ReportSessionStateGateway;
|
|
78
|
+
readonly resolver?: ReferenceResolver;
|
|
79
|
+
readonly resolveWorkspaceRoot: ResolveWorkspaceRoot;
|
|
80
|
+
readonly logger?: Logger;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Make the render-and-preview tool over the session-state gateway and the render seams.
|
|
84
|
+
*
|
|
85
|
+
* The tool reads the thread id from the scope of the call, and it loads the state through the gateway. Thus
|
|
86
|
+
* one factory serves every thread. The tool holds no per-session value, and it resolves the root of the
|
|
87
|
+
* analysis of the call.
|
|
88
|
+
*/
|
|
89
|
+
export declare function createPreviewReportTool(deps: PreviewReportToolDeps): Tool<PreviewReportInput, PreviewReportResult>;
|
|
90
|
+
export {};
|