@inflexa-ai/harness 0.18.0 → 0.19.1
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 +72 -0
- package/dist/agents/report-session-agent.js +87 -0
- package/dist/app/report-session-runtime.d.ts +72 -0
- package/dist/app/report-session-runtime.js +183 -0
- package/dist/app/spawn-report-session.d.ts +32 -5
- package/dist/app/spawn-report-session.js +19 -0
- package/dist/config/environment-stores.d.ts +12 -7
- package/dist/config/resource-limits.d.ts +6 -10
- package/dist/config/resource-limits.js +6 -44
- package/dist/contracts/report-reference.d.ts +4 -0
- package/dist/contracts/report-reference.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/lib/chrome.d.ts +14 -0
- package/dist/lib/chrome.js +7 -0
- package/dist/lib/page-capture.d.ts +47 -0
- package/dist/lib/page-capture.js +83 -0
- package/dist/loop/run-agent.js +104 -15
- package/dist/memory/ai-sdk-message-storage.d.ts +9 -4
- package/dist/memory/ai-sdk-message-storage.js +9 -4
- package/dist/memory/count-tokens.js +34 -5
- 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 +110 -0
- package/dist/providers/ai-sdk.d.ts +158 -3
- package/dist/providers/ai-sdk.js +234 -23
- package/dist/providers/errors.d.ts +14 -0
- package/dist/providers/errors.js +103 -18
- package/dist/providers/types.d.ts +33 -0
- package/dist/providers/types.js +10 -1
- package/dist/report-model/assert-rules.d.ts +44 -0
- package/dist/report-model/assert-rules.js +97 -0
- package/dist/report-model/draft-hash.d.ts +14 -0
- package/dist/report-model/draft-hash.js +36 -0
- package/dist/report-model/fixture-resolver.js +2 -71
- 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/production-resolver.d.ts +124 -0
- package/dist/report-model/production-resolver.js +801 -0
- package/dist/report-model/reference-resolver.d.ts +7 -1
- package/dist/report-model/validate.d.ts +34 -2
- package/dist/report-model/validate.js +37 -17
- package/dist/report-render/page.d.ts +23 -0
- package/dist/report-render/page.js +36 -3
- 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 +39 -0
- package/dist/runtime/assemble.js +67 -6
- package/dist/sandbox/mount-plan.d.ts +7 -0
- package/dist/sandbox/mount-plan.js +7 -2
- package/dist/state/init.js +36 -0
- package/dist/state/purge-analysis.js +1 -0
- package/dist/state/report-session-state.d.ts +139 -0
- package/dist/state/report-session-state.js +177 -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/tasks/extract-values-script.d.ts +64 -0
- package/dist/tasks/extract-values-script.js +180 -0
- package/dist/tasks/extract-values.d.ts +124 -0
- package/dist/tasks/extract-values.js +193 -0
- package/dist/tools/ad-hoc-router.d.ts +7 -2
- package/dist/tools/ad-hoc-router.js +2 -1
- package/dist/tools/define-tool.d.ts +29 -0
- package/dist/tools/define-tool.js +26 -0
- package/dist/tools/report/preview-snapshot.d.ts +1 -1
- package/dist/tools/report/preview-snapshot.js +11 -50
- package/dist/tools/report-authoring/authoring-tools.d.ts +181 -24
- package/dist/tools/report-authoring/authoring-tools.js +152 -44
- package/dist/tools/report-session/examine-page.d.ts +90 -0
- package/dist/tools/report-session/examine-page.js +136 -0
- package/dist/tools/report-session/index.d.ts +10 -0
- package/dist/tools/report-session/index.js +10 -0
- package/dist/tools/report-session/preview-report.d.ts +105 -0
- package/dist/tools/report-session/preview-report.js +269 -0
- package/dist/tools/report-session/record-version.d.ts +102 -0
- package/dist/tools/report-session/record-version.js +139 -0
- package/dist/tools/research/generate-plan.js +4 -2
- package/dist/tools/sandbox/list-available-packages.js +2 -1
- package/dist/tools/sandbox/list-available-refs.d.ts +5 -1
- package/dist/tools/sandbox/list-available-refs.js +13 -6
- package/package.json +10 -8
|
@@ -20,6 +20,32 @@ import { z } from "zod";
|
|
|
20
20
|
export function isToolError(value) {
|
|
21
21
|
return typeof value === "object" && value !== null && typeof value.error === "string" && typeof value.retryable === "boolean";
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* The reserved key that carries a picture on a tool ok value. It is a symbol,
|
|
25
|
+
* thus it never collides with a data field. `JSON.stringify` also omits a symbol
|
|
26
|
+
* key, thus the bytes never reach the JSON text by accident.
|
|
27
|
+
*/
|
|
28
|
+
export const toolResultImageKey = Symbol("toolResultImage");
|
|
29
|
+
/**
|
|
30
|
+
* Attach a picture to a tool ok value. The value keeps its own fields, and the
|
|
31
|
+
* picture rides under the reserved key. The loop reads the key, and it moves the
|
|
32
|
+
* bytes into an image content block on the tool result.
|
|
33
|
+
*/
|
|
34
|
+
export function withToolResultImage(value, image) {
|
|
35
|
+
return { ...value, [toolResultImageKey]: image };
|
|
36
|
+
}
|
|
37
|
+
/** Read the picture that a tool ok value carries, or undefined when it carries none. */
|
|
38
|
+
export function readToolResultImage(value) {
|
|
39
|
+
if (typeof value !== "object" || value === null)
|
|
40
|
+
return undefined;
|
|
41
|
+
const image = value[toolResultImageKey];
|
|
42
|
+
if (typeof image !== "object" || image === null)
|
|
43
|
+
return undefined;
|
|
44
|
+
const { base64, mediaType } = image;
|
|
45
|
+
if (typeof base64 !== "string" || typeof mediaType !== "string")
|
|
46
|
+
return undefined;
|
|
47
|
+
return { base64, mediaType };
|
|
48
|
+
}
|
|
23
49
|
/**
|
|
24
50
|
* Package a `Tool`. The emitted JSON Schema must have a top-level
|
|
25
51
|
* `"type": "object"` — model tool calling rejects anything else. A `z.discriminatedUnion`
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* has to be able to see without reading the model transcript.
|
|
18
18
|
*/
|
|
19
19
|
import { type Tool } from "../define-tool.js";
|
|
20
|
-
import {
|
|
20
|
+
import type { ChromeConfig } from "../../lib/chrome.js";
|
|
21
21
|
import type { Logger } from "../../lib/logger.js";
|
|
22
22
|
import { type PreviewPublisher } from "./preview-publisher.js";
|
|
23
23
|
import type { PreviewUrlCell } from "./mint-preview-url.js";
|
|
@@ -19,11 +19,9 @@
|
|
|
19
19
|
import { ok } from "neverthrow";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import { defineTool } from "../define-tool.js";
|
|
22
|
-
import {
|
|
22
|
+
import { capturePage } from "../../lib/page-capture.js";
|
|
23
23
|
import { createNoopLogger } from "../../lib/console-logger.js";
|
|
24
24
|
import { describeMintFailure } from "./preview-publisher.js";
|
|
25
|
-
const NAV_TIMEOUT_MS = 20_000;
|
|
26
|
-
const READY_TIMEOUT_MS = 8_000;
|
|
27
25
|
const WAIT_MS_CAP = 30_000;
|
|
28
26
|
export function createPreviewSnapshotTool(state) {
|
|
29
27
|
const logger = (state.logger ?? createNoopLogger()).named("preview-snapshot").with({ previewId: state.previewId });
|
|
@@ -75,53 +73,16 @@ export function createPreviewSnapshotTool(state) {
|
|
|
75
73
|
state.urlCell.expiresAt = result.data.expiresAt;
|
|
76
74
|
}
|
|
77
75
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
url: req.url(),
|
|
89
|
-
reason: req.failure()?.errorText ?? "unknown",
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
await page.goto(url, {
|
|
93
|
-
waitUntil: "networkidle2",
|
|
94
|
-
timeout: NAV_TIMEOUT_MS,
|
|
95
|
-
});
|
|
96
|
-
// Wait for the inflexa-theme-ready event (fired after echarts theme
|
|
97
|
-
// registers). Check the `__inflexaThemeReady` sentinel first because
|
|
98
|
-
// the page already deferred its dispatch — by the time we get here
|
|
99
|
-
// via networkidle2, the event has likely already fired and a plain
|
|
100
|
-
// addEventListener would block forever. The callback runs in the
|
|
101
|
-
// browser context.
|
|
102
|
-
await page
|
|
103
|
-
.evaluate(new Function("timeout", "return new Promise(function(resolve){if(window.__inflexaThemeReady){resolve();return;}var t=setTimeout(resolve,timeout);document.addEventListener('inflexa-theme-ready',function(){clearTimeout(t);resolve();},{once:true});});"), READY_TIMEOUT_MS)
|
|
104
|
-
.catch(() => {
|
|
105
|
-
/* fall through — capture state as-is */
|
|
106
|
-
});
|
|
107
|
-
if (input.waitForSelector) {
|
|
108
|
-
await page.waitForSelector(input.waitForSelector, { timeout: 5_000 }).catch(() => {
|
|
109
|
-
/* not fatal */
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
if (input.waitMs)
|
|
113
|
-
await new Promise((r) => setTimeout(r, input.waitMs));
|
|
114
|
-
const screenshot = await page.screenshot({
|
|
115
|
-
encoding: "base64",
|
|
116
|
-
fullPage: false,
|
|
117
|
-
});
|
|
118
|
-
return {
|
|
119
|
-
ok: true,
|
|
120
|
-
screenshotBase64: typeof screenshot === "string" ? screenshot : Buffer.from(screenshot).toString("base64"),
|
|
121
|
-
consoleErrors,
|
|
122
|
-
failedRequests,
|
|
123
|
-
};
|
|
124
|
-
}));
|
|
76
|
+
const captured = await capturePage(state.chrome, url, {
|
|
77
|
+
...(input.waitForSelector !== undefined ? { waitForSelector: input.waitForSelector } : {}),
|
|
78
|
+
...(input.waitMs !== undefined ? { waitMs: input.waitMs } : {}),
|
|
79
|
+
});
|
|
80
|
+
return ok({
|
|
81
|
+
ok: true,
|
|
82
|
+
screenshotBase64: captured.screenshotBase64,
|
|
83
|
+
consoleErrors: captured.consoleErrors,
|
|
84
|
+
failedRequests: captured.failedRequests,
|
|
85
|
+
});
|
|
125
86
|
}
|
|
126
87
|
catch (err) {
|
|
127
88
|
return ok({
|
|
@@ -1,18 +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
|
*/
|
|
19
|
+
import { type Result } from "neverthrow";
|
|
15
20
|
import { z } from "zod";
|
|
21
|
+
import type { Scope } from "../../auth/types.js";
|
|
16
22
|
import { type DraftRefusal } from "../../report-model/draft-operations.js";
|
|
17
23
|
import { type OutlineEntry, type ReadableBlock } from "../../report-model/draft-read.js";
|
|
18
24
|
import { type FinishResult } from "../../report-model/draft-finish.js";
|
|
@@ -77,7 +83,30 @@ export interface ChangedContainer {
|
|
|
77
83
|
children: OutlineEntry[];
|
|
78
84
|
}
|
|
79
85
|
/**
|
|
80
|
-
* The
|
|
86
|
+
* The closed set of tool-layer refusal reasons.
|
|
87
|
+
*
|
|
88
|
+
* `no-thread-scope` means that the scope of the call names no report thread. `absent-state` means that no
|
|
89
|
+
* report session exists for the thread, and it is permanent. `wrong-thread-type` means that the thread is
|
|
90
|
+
* not a report thread, and it is permanent. `scope-analysis-mismatch` means that the scope names one
|
|
91
|
+
* analysis and the thread belongs to another, and it is permanent. `stale-state` means that a concurrent
|
|
92
|
+
* turn landed first, and the agent must read the state again. `state-unavailable` means that the gateway
|
|
93
|
+
* cannot serve or store the state, and it is transient. The set is disjoint from the core
|
|
94
|
+
* `DraftRefusalReason`, thus a reader tells a core refusal from a tool-layer refusal by the reason alone.
|
|
95
|
+
*/
|
|
96
|
+
export type SessionRefusalReason = "no-thread-scope" | "absent-state" | "wrong-thread-type" | "scope-analysis-mismatch" | "stale-state" | "state-unavailable";
|
|
97
|
+
/**
|
|
98
|
+
* A refusal that the tool layer raises before the core runs.
|
|
99
|
+
*
|
|
100
|
+
* The core refuses a bad edit. This layer refuses a call that names no thread, a thread with no stored
|
|
101
|
+
* state, or a gateway that cannot give the state. It sits beside the core `DraftRefusal`, and it never
|
|
102
|
+
* widens the closed reason set of the core.
|
|
103
|
+
*/
|
|
104
|
+
export interface SessionRefusal {
|
|
105
|
+
reason: SessionRefusalReason;
|
|
106
|
+
detail: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The result of a mutation tool. A refusal carries the typed reason, from the core or from the tool layer.
|
|
81
110
|
*
|
|
82
111
|
* A landing carries the child order of each container that it changed, and not the whole outline. A whole
|
|
83
112
|
* outline costs the size of the draft on every landing, thus composing a report of n blocks would spend
|
|
@@ -92,26 +121,155 @@ export type MutationResult = {
|
|
|
92
121
|
changed: ChangedContainer[];
|
|
93
122
|
} | {
|
|
94
123
|
applied: false;
|
|
95
|
-
refusal: DraftRefusal;
|
|
124
|
+
refusal: DraftRefusal | SessionRefusal;
|
|
96
125
|
};
|
|
97
|
-
/** The result of `read_outline`. */
|
|
98
|
-
export
|
|
126
|
+
/** The result of `read_outline`. A load that gives no state refuses instead of an outline. */
|
|
127
|
+
export type OutlineResult = {
|
|
99
128
|
outline: OutlineEntry[];
|
|
100
|
-
}
|
|
101
|
-
|
|
129
|
+
} | {
|
|
130
|
+
refused: SessionRefusal;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* The result of `read_block`. An absent block is an expected outcome, thus it stays in the ok channel. A
|
|
134
|
+
* load that gives no state refuses instead of a block.
|
|
135
|
+
*/
|
|
102
136
|
export type ReadBlockResult = {
|
|
103
137
|
found: true;
|
|
104
138
|
block: ReadableBlock;
|
|
105
139
|
} | {
|
|
106
140
|
found: false;
|
|
141
|
+
} | {
|
|
142
|
+
refused: SessionRefusal;
|
|
143
|
+
};
|
|
144
|
+
/** The result of `finish_draft`. A load that gives no state refuses instead of a finish outcome. */
|
|
145
|
+
export type FinishToolResult = FinishResult | {
|
|
146
|
+
refused: SessionRefusal;
|
|
107
147
|
};
|
|
108
|
-
/** The state
|
|
109
|
-
export interface
|
|
148
|
+
/** The state of one report thread: the document under composition, and the frozen snapshot. */
|
|
149
|
+
export interface ReportSessionState {
|
|
150
|
+
readonly document: DraftDocument;
|
|
110
151
|
readonly snapshot: ReportSnapshot;
|
|
111
|
-
/** The draft to start from. The default is an empty draft. */
|
|
112
|
-
readonly initialDraft?: DraftDocument;
|
|
113
152
|
}
|
|
114
|
-
/**
|
|
153
|
+
/**
|
|
154
|
+
* The concurrency token that a load hands out and a persist compares against. It is the prior document
|
|
155
|
+
* that the load read, or `null` before the first document lands. The persist lands only when the row still
|
|
156
|
+
* holds it, thus a concurrent turn that landed first turns the next persist into a conflict.
|
|
157
|
+
*/
|
|
158
|
+
export type SessionStateToken = DraftDocument | null;
|
|
159
|
+
/**
|
|
160
|
+
* The outcome of a gateway load. `found` carries the state, the analysis that owns the thread, the
|
|
161
|
+
* concurrency token, and the seen-document hash of the look-before-record rule. `absent` and `wrong-type`
|
|
162
|
+
* are permanent conditions, and `failed` is a transient fault that names its cause.
|
|
163
|
+
*
|
|
164
|
+
* `seenDocumentHash` is the hash that the last eyes capture saw, or `null` before the first look. The record
|
|
165
|
+
* tool compares it against the hash of the current draft, thus a never-seen page and a stale look each
|
|
166
|
+
* refuse.
|
|
167
|
+
*/
|
|
168
|
+
export type SessionStateLoad = {
|
|
169
|
+
outcome: "found";
|
|
170
|
+
state: ReportSessionState;
|
|
171
|
+
analysisId: string;
|
|
172
|
+
token: SessionStateToken;
|
|
173
|
+
seenDocumentHash: string | null;
|
|
174
|
+
} | {
|
|
175
|
+
outcome: "absent";
|
|
176
|
+
} | {
|
|
177
|
+
outcome: "wrong-type";
|
|
178
|
+
detail: string;
|
|
179
|
+
} | {
|
|
180
|
+
outcome: "failed";
|
|
181
|
+
detail: string;
|
|
182
|
+
};
|
|
183
|
+
/** The outcome of a gateway persist. `conflict` means that a concurrent turn landed first. */
|
|
184
|
+
export type SessionStatePersist = {
|
|
185
|
+
outcome: "persisted";
|
|
186
|
+
} | {
|
|
187
|
+
outcome: "conflict";
|
|
188
|
+
} | {
|
|
189
|
+
outcome: "failed";
|
|
190
|
+
detail: string;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* The outcome of a gateway stamp. `stamped` wrote the marker. `absent` means that no row holds the thread.
|
|
194
|
+
* `failed` is a transient store fault that names its cause. Each arm is plain data, thus a stamp never
|
|
195
|
+
* throws for one of them.
|
|
196
|
+
*/
|
|
197
|
+
export type StampResult = {
|
|
198
|
+
outcome: "stamped";
|
|
199
|
+
} | {
|
|
200
|
+
outcome: "absent";
|
|
201
|
+
} | {
|
|
202
|
+
outcome: "failed";
|
|
203
|
+
detail: string;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* The outcome of the seen stamp through the gateway. `stamped` copied a rendered hash onto the seen hash.
|
|
207
|
+
* `no-rendered` means that the row holds no rendered hash to copy, thus no preview stamped one. `absent`
|
|
208
|
+
* means that no row holds the thread. `failed` is a transient store fault that names its cause. Each arm is
|
|
209
|
+
* plain data, thus a stamp never throws for one of them.
|
|
210
|
+
*/
|
|
211
|
+
export type SeenStampResult = {
|
|
212
|
+
outcome: "stamped";
|
|
213
|
+
} | {
|
|
214
|
+
outcome: "no-rendered";
|
|
215
|
+
} | {
|
|
216
|
+
outcome: "absent";
|
|
217
|
+
} | {
|
|
218
|
+
outcome: "failed";
|
|
219
|
+
detail: string;
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* The session-state gateway that the tools read and write.
|
|
223
|
+
*
|
|
224
|
+
* The tool layer is the one consumer, thus the interface lives here. The interface speaks a plain
|
|
225
|
+
* discriminated value, not a `Result`, because the tools read the outcome as data. The runtime realizes
|
|
226
|
+
* the gateway over the durable store. A load gives the state, a typed absence, or a typed failure. A
|
|
227
|
+
* persist gives success, or a typed failure.
|
|
228
|
+
*/
|
|
229
|
+
export interface ReportSessionStateGateway {
|
|
230
|
+
load(threadId: string): Promise<SessionStateLoad>;
|
|
231
|
+
persist(threadId: string, document: DraftDocument, expected: SessionStateToken): Promise<SessionStatePersist>;
|
|
232
|
+
/**
|
|
233
|
+
* Stamp the hash of the rendered draft on the session state. The preview calls it when the page lands,
|
|
234
|
+
* thus the runtime knows which draft the page shows.
|
|
235
|
+
*/
|
|
236
|
+
stampRendered(threadId: string, hash: string): Promise<StampResult>;
|
|
237
|
+
/**
|
|
238
|
+
* Copy the rendered hash onto the seen hash. The eyes call it after a capture, thus the seen hash holds
|
|
239
|
+
* the hash of the draft that the picture shows, and never the current one. The outcome names whether a
|
|
240
|
+
* rendered hash existed to copy, thus the eyes tell a real stamp from a missed one.
|
|
241
|
+
*/
|
|
242
|
+
stampSeen(threadId: string): Promise<SeenStampResult>;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The thread of a call, its analysis, the loaded state, the concurrency token that the persist compares
|
|
246
|
+
* against, and the seen-document hash of the look-before-record rule.
|
|
247
|
+
*/
|
|
248
|
+
export interface OpenedThread {
|
|
249
|
+
readonly threadId: string;
|
|
250
|
+
readonly analysisId: string;
|
|
251
|
+
readonly state: ReportSessionState;
|
|
252
|
+
readonly token: SessionStateToken;
|
|
253
|
+
/** The hash that the last eyes capture saw, or `null` before the first look. */
|
|
254
|
+
readonly seenDocumentHash: string | null;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Resolve the report thread of a call, and load its state through the gateway.
|
|
258
|
+
*
|
|
259
|
+
* The report thread and its analysis ride on the analysis scope. The thread id becomes one segment of a
|
|
260
|
+
* session directory, thus the safe-id check sits here beside the shape check: a scope whose id carries a
|
|
261
|
+
* separator or a traversal segment names no thread that a tool can write under.
|
|
262
|
+
*
|
|
263
|
+
* The stored analysis of the thread must match the scope. A mismatch reads one analysis's draft and writes
|
|
264
|
+
* into another analysis's workspace, thus the resolution refuses it with a permanent reason that names the
|
|
265
|
+
* two ids. A scope of a different kind, an unsafe id, an absent thread, a wrong thread type, and a gateway
|
|
266
|
+
* fault each refuse as a typed `SessionRefusal` too.
|
|
267
|
+
*
|
|
268
|
+
* The authoring tools and the preview tool share this one resolution, thus the two surfaces accept the
|
|
269
|
+
* same thread id and map a load outcome onto a refusal the same way.
|
|
270
|
+
*/
|
|
271
|
+
export declare function openReportThread(gateway: ReportSessionStateGateway, scope: Scope): Promise<Result<OpenedThread, SessionRefusal>>;
|
|
272
|
+
/** The eight authoring tools. */
|
|
115
273
|
export interface ReportAuthoringTools {
|
|
116
274
|
readonly add_block: Tool<AddBlockInput, MutationResult>;
|
|
117
275
|
readonly change_block: Tool<ChangeBlockInput, MutationResult>;
|
|
@@ -120,15 +278,14 @@ export interface ReportAuthoringTools {
|
|
|
120
278
|
readonly set_title: Tool<SetTitleInput, MutationResult>;
|
|
121
279
|
readonly read_outline: Tool<ReadOutlineInput, OutlineResult>;
|
|
122
280
|
readonly read_block: Tool<ReadBlockInput, ReadBlockResult>;
|
|
123
|
-
readonly finish_draft: Tool<FinishDraftInput,
|
|
124
|
-
currentDraft(): DraftDocument;
|
|
281
|
+
readonly finish_draft: Tool<FinishDraftInput, FinishToolResult>;
|
|
125
282
|
}
|
|
126
283
|
/**
|
|
127
|
-
* Make the eight authoring tools over
|
|
284
|
+
* Make the eight authoring tools over a session-state gateway.
|
|
128
285
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
286
|
+
* Each tool reads the thread id from the scope of the call, and it loads the state of that thread through
|
|
287
|
+
* the gateway. Thus one factory serves every thread, and two threads never share one draft. A mutation
|
|
288
|
+
* persists the new document before it reports `applied: true`, thus a reported landing is never lost.
|
|
132
289
|
*/
|
|
133
|
-
export declare function createReportAuthoringTools(
|
|
290
|
+
export declare function createReportAuthoringTools(gateway: ReportSessionStateGateway): ReportAuthoringTools;
|
|
134
291
|
export {};
|