@buildaharness/aielia 0.3.8 → 0.3.10
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/README.md +6 -3
- package/dist/_memory-core-generated.d.ts +6 -0
- package/dist/action-approval-service.d.ts +2 -0
- package/dist/ask-draft.d.ts +22 -0
- package/dist/assistant-options.d.ts +35 -0
- package/dist/assistant-session.d.ts +1 -1
- package/dist/assistant.d.ts +11 -0
- package/dist/{bin-DETwedpj.js → bin-Cz3FY6Ew.js} +144 -254
- package/dist/bin-Cz3FY6Ew.js.map +1 -0
- package/dist/claude-cli-llm-client.d.ts +2 -0
- package/dist/claude-cli-prompt.d.ts +7 -0
- package/dist/cli-config.d.ts +2 -2
- package/dist/cli-session.d.ts +2 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1 -1
- package/dist/commands.d.ts +32 -0
- package/dist/config-keys.d.ts +43 -0
- package/dist/doctor-checks.d.ts +1 -2
- package/dist/fact-extraction.d.ts +4 -0
- package/dist/fact-repository.contract.d.ts +2 -0
- package/dist/fact-repository.d.ts +44 -0
- package/dist/file-tools-mcp-server.mjs +29 -0
- package/dist/goal-graph-store.d.ts +6 -0
- package/dist/harness-bridge.d.ts +5 -5
- package/dist/html-to-markdown.d.ts +11 -0
- package/dist/index.d.ts +98 -3
- package/dist/index.js +5003 -150
- package/dist/index.js.map +1 -1
- package/dist/layer-settings.d.ts +16 -3
- package/dist/llm-client-factory.d.ts +13 -0
- package/dist/memory-events.d.ts +177 -0
- package/dist/memory-service.d.ts +17 -0
- package/dist/model-pricing.d.ts +15 -9
- package/dist/node-display-names.d.ts +1 -1
- package/dist/project-command.d.ts +16 -0
- package/dist/{provider-setup-wX2IBw2X.js → provider-setup-DG8iYm_F.js} +14471 -13032
- package/dist/provider-setup-DG8iYm_F.js.map +1 -0
- package/dist/proxy-health.d.ts +8 -0
- package/dist/redact-url.d.ts +2 -0
- package/dist/reply-audit.d.ts +2 -0
- package/dist/response-service.d.ts +10 -0
- package/dist/run-explain.d.ts +58 -0
- package/dist/scripted-llm-client.d.ts +1 -1
- package/dist/{tui-app-CcxiwZyM.js → tui-app-oWbIUcBW.js} +3 -3
- package/dist/{tui-app-CcxiwZyM.js.map → tui-app-oWbIUcBW.js.map} +1 -1
- package/dist/turn-abort.d.ts +5 -0
- package/dist/turn-cost.d.ts +12 -0
- package/dist/turn-presentation.d.ts +86 -0
- package/dist/undo-action-command.d.ts +12 -0
- package/dist/undo-plan.d.ts +13 -0
- package/dist/version.d.ts +1 -1
- package/dist/web-fetch-core.d.ts +0 -14
- package/dist/writer/article-autosave.d.ts +12 -0
- package/dist/writer/article-change-summary.d.ts +28 -0
- package/dist/writer/article-claims.d.ts +49 -0
- package/dist/writer/article-comments.d.ts +20 -0
- package/dist/writer/article-consistency.d.ts +27 -0
- package/dist/writer/article-decorations.d.ts +23 -0
- package/dist/writer/article-dependencies.d.ts +44 -0
- package/dist/writer/article-draft.d.ts +23 -0
- package/dist/writer/article-edit-outline.d.ts +16 -0
- package/dist/writer/article-edit-suggest.d.ts +30 -0
- package/dist/writer/article-folder.d.ts +29 -0
- package/dist/writer/article-history.d.ts +73 -0
- package/dist/writer/article-ideas.d.ts +34 -0
- package/dist/writer/article-issues.d.ts +47 -0
- package/dist/writer/article-marks.d.ts +25 -0
- package/dist/writer/article-memory-store.d.ts +3 -0
- package/dist/writer/article-model.d.ts +1337 -0
- package/dist/writer/article-outline.d.ts +43 -0
- package/dist/writer/article-resolver.d.ts +55 -0
- package/dist/writer/article-revisions.d.ts +30 -0
- package/dist/writer/article-rules.d.ts +60 -0
- package/dist/writer/article-sections.d.ts +26 -0
- package/dist/writer/article-selection.d.ts +26 -0
- package/dist/writer/article-service.d.ts +542 -0
- package/dist/writer/article-source-links.d.ts +42 -0
- package/dist/writer/article-sources.d.ts +82 -0
- package/dist/writer/article-style-derive.d.ts +26 -0
- package/dist/writer/article-style.d.ts +31 -0
- package/dist/writer/article-suggestions.d.ts +33 -0
- package/dist/writer/article-support.d.ts +33 -0
- package/dist/writer/article-verify.d.ts +42 -0
- package/dist/writer/local-folder.d.ts +49 -0
- package/dist/writer/model-failure-hint.d.ts +7 -0
- package/dist/writer/repo-reader.d.ts +29 -0
- package/dist/writer/repo-search.d.ts +33 -0
- package/dist/writer/repo-verify-loop.d.ts +61 -0
- package/dist/writer/text-tool-calls.d.ts +11 -0
- package/dist/writer/work-progress.d.ts +51 -0
- package/dist/writer/write-activity.d.ts +61 -0
- package/dist/writer/write-models.d.ts +12 -0
- package/dist/writer/write-parameters.d.ts +31 -0
- package/dist/writer/write-permissions.d.ts +89 -0
- package/dist/writer/write-spend.d.ts +16 -0
- package/dist/writer/writer-chat-capture.d.ts +25 -0
- package/dist/writer/writer-chat-history.d.ts +17 -0
- package/dist/writer/writer-chat-state.d.ts +358 -0
- package/dist/writer/writer-chat-turn.d.ts +52 -0
- package/dist/writer/writer-intent.d.ts +20 -0
- package/package.json +3 -3
- package/dist/bin-DETwedpj.js.map +0 -1
- package/dist/provider-setup-wX2IBw2X.js.map +0 -1
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import { SectionChange } from './article-change-summary.js';
|
|
2
|
+
import { ILLMClient, TokenUsage } from '@buildaharness/runtime';
|
|
3
|
+
import { ExtractionResult } from './article-claims.js';
|
|
4
|
+
import { ArticleBundle, ArticleFolder } from './article-folder.js';
|
|
5
|
+
import { Claim, Idea, Source, Brief, StyleProfile } from './article-model.js';
|
|
6
|
+
import { ResolveResult, SourceImpact } from './article-resolver.js';
|
|
7
|
+
import { IssueCategory } from './article-issues.js';
|
|
8
|
+
import { IdeaSuggestion } from './article-ideas.js';
|
|
9
|
+
import { SourceLinkProposal, TextRange } from './article-source-links.js';
|
|
10
|
+
import { DependencyKind, DependencyProposal } from './article-dependencies.js';
|
|
11
|
+
import { ChatTurn } from './writer-chat-history.js';
|
|
12
|
+
import { ChangeSummary, VersionComparison } from './article-history.js';
|
|
13
|
+
import { Problem, Readiness, Snapshot } from './article-rules.js';
|
|
14
|
+
import { EditSuggestResult } from './article-edit-suggest.js';
|
|
15
|
+
import { VerifyEntry, VerifyReport } from './article-verify.js';
|
|
16
|
+
import { FolderReader } from './local-folder.js';
|
|
17
|
+
import { RepoReader } from './repo-reader.js';
|
|
18
|
+
import { LoopStep } from './repo-verify-loop.js';
|
|
19
|
+
import { ConsistencyResult } from './article-consistency.js';
|
|
20
|
+
import { LineRange } from './article-sources.js';
|
|
21
|
+
import { SupportCheck } from './article-support.js';
|
|
22
|
+
import { WriterChatPort } from './writer-chat-turn.js';
|
|
23
|
+
import { ArticleRef } from './writer-chat-state.js';
|
|
24
|
+
/**
|
|
25
|
+
* The article service: the operations the /write page and the terminal runner need, built from the pure pieces. Storage is
|
|
26
|
+
* a port (the browser supplies IndexedDB, tests and the runner an in-memory store). The model clients are injected.
|
|
27
|
+
*/
|
|
28
|
+
export interface ArticleStore {
|
|
29
|
+
list(): Promise<ArticleRef[]>;
|
|
30
|
+
load(id: string): Promise<ArticleBundle | undefined>;
|
|
31
|
+
save(id: string, bundle: ArticleBundle): Promise<void>;
|
|
32
|
+
remove(id: string): Promise<void>;
|
|
33
|
+
getSetting(key: string): Promise<unknown>;
|
|
34
|
+
setSetting(key: string, value: unknown): Promise<void>;
|
|
35
|
+
/** Deletes every article and every setting this store holds. Optional: a store that cannot do it leaves the host to remove the articles one by one. */
|
|
36
|
+
clearAll?(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export declare function createMemoryArticleStore(): ArticleStore;
|
|
39
|
+
/** The phases of a chat edit or draft after the version is saved: the model is asked, then the result is applied (with a short note of how much). */
|
|
40
|
+
export type ChatStageListener = (stage: 'asking' | 'applying', detail?: string) => void;
|
|
41
|
+
export interface ArticleServiceOptions {
|
|
42
|
+
store: ArticleStore;
|
|
43
|
+
llm: ILLMClient;
|
|
44
|
+
/** Model for every call when `modelFor` is not given. */
|
|
45
|
+
model?: string;
|
|
46
|
+
/** The model for each role, read at call time so the writer can change it between calls: the writer model drafts edit suggestions; the checker model runs claim extraction, support checks, link finding and the effects check. */
|
|
47
|
+
modelFor?: (role: 'writer' | 'checker') => string | undefined;
|
|
48
|
+
/** The name stored with a check result ("which model ran it"); defaults to the checker model. */
|
|
49
|
+
modelName?: string;
|
|
50
|
+
/** Reads a web page as plain text. Absent where the browser cannot reach pages (no proxy and no desktop shell); links are then stored without a passage and the writer pastes it. */
|
|
51
|
+
fetchWeb?: (url: string) => Promise<string>;
|
|
52
|
+
/** Searches the web for pages that might back a claim. Absent where no search is set up. */
|
|
53
|
+
searchWeb?: (query: string) => Promise<{
|
|
54
|
+
title: string;
|
|
55
|
+
url: string;
|
|
56
|
+
snippet: string;
|
|
57
|
+
}[]>;
|
|
58
|
+
onUsage?: (usage: TokenUsage) => void;
|
|
59
|
+
now?: () => string;
|
|
60
|
+
newId?: () => string;
|
|
61
|
+
}
|
|
62
|
+
export interface UpdateOutcome {
|
|
63
|
+
bundle: ArticleBundle;
|
|
64
|
+
changedSectionIds: string[];
|
|
65
|
+
removedSections: string[];
|
|
66
|
+
extraction?: ExtractionResult;
|
|
67
|
+
resolution?: ResolveResult;
|
|
68
|
+
autoChecks: {
|
|
69
|
+
claimId: string;
|
|
70
|
+
status: SupportCheck['status'];
|
|
71
|
+
}[];
|
|
72
|
+
/** The pass over the whole article for conflicts and overreach (one model call); absent when extraction did not run. */
|
|
73
|
+
consistency?: ConsistencyResult;
|
|
74
|
+
}
|
|
75
|
+
export interface SourceCandidate {
|
|
76
|
+
title: string;
|
|
77
|
+
url: string;
|
|
78
|
+
snippet: string;
|
|
79
|
+
}
|
|
80
|
+
export interface SourceRecheckReport {
|
|
81
|
+
read: number;
|
|
82
|
+
unchanged: number;
|
|
83
|
+
/** Addresses whose page text differs from what was stored. */
|
|
84
|
+
changed: string[];
|
|
85
|
+
unreachable: string[];
|
|
86
|
+
/** Web sources not read: no page reader here, or past the limit. */
|
|
87
|
+
skipped: number;
|
|
88
|
+
}
|
|
89
|
+
export interface ResolveReport {
|
|
90
|
+
category: IssueCategory;
|
|
91
|
+
/** How many items the action dealt with. */
|
|
92
|
+
done: number;
|
|
93
|
+
/** One plain sentence saying what happened. */
|
|
94
|
+
note: string;
|
|
95
|
+
}
|
|
96
|
+
export declare class ArticleService {
|
|
97
|
+
private readonly opts;
|
|
98
|
+
private readonly store;
|
|
99
|
+
private readonly now;
|
|
100
|
+
private readonly newId;
|
|
101
|
+
constructor(opts: ArticleServiceOptions);
|
|
102
|
+
private checker;
|
|
103
|
+
private writer;
|
|
104
|
+
list(): Promise<ArticleRef[]>;
|
|
105
|
+
get(id: string): Promise<ArticleBundle>;
|
|
106
|
+
create(title: string, markdown?: string): Promise<string>;
|
|
107
|
+
/** The short name the writer files the article under. It does not change the text or the title. */
|
|
108
|
+
rename(id: string, name: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* The writer's text changed. Structure first (no model): re-anchor sections and refresh suggestions, then save. Then, unless
|
|
111
|
+
* `analyze` is false, the model judgements: extract claims, run the automatic checks on text the model wrote, and judge what
|
|
112
|
+
* the edit means for the other sections. A failed model step leaves its part as it was and is reported in the outcome.
|
|
113
|
+
*/
|
|
114
|
+
updateText(id: string, markdown: string, options?: {
|
|
115
|
+
analyze?: boolean;
|
|
116
|
+
model?: string;
|
|
117
|
+
}): Promise<UpdateOutcome>;
|
|
118
|
+
/** Claim extraction and the automatic checks over the whole article: the first pass for a new article, or on request. Model steps that fail are reported and leave their part as it was. */
|
|
119
|
+
analyze(id: string, model?: string): Promise<UpdateOutcome>;
|
|
120
|
+
private extractAndCheck;
|
|
121
|
+
addSource(id: string, input: {
|
|
122
|
+
kind: Source['kind'];
|
|
123
|
+
address?: string;
|
|
124
|
+
passage?: string;
|
|
125
|
+
note?: string;
|
|
126
|
+
lines?: LineRange;
|
|
127
|
+
}): Promise<string>;
|
|
128
|
+
/**
|
|
129
|
+
* Reads a web source's address. First read: the page text becomes the stored passage. Later reads: same text keeps it current;
|
|
130
|
+
* different text is held as `fetchedPassage` (the stored passage and every check stay as they were), the source is marked
|
|
131
|
+
* changed and a model judges which citing claims it touches. The writer accepts the new text with acceptSourceChange.
|
|
132
|
+
*/
|
|
133
|
+
readSource(id: string, sourceId: string, modelOverride?: string): Promise<{
|
|
134
|
+
status: 'read' | 'unchanged' | 'changed' | 'unreachable' | 'unavailable' | 'not_a_link';
|
|
135
|
+
impacts: SourceImpact[];
|
|
136
|
+
reason?: string;
|
|
137
|
+
}>;
|
|
138
|
+
private saveSource;
|
|
139
|
+
/** New text for a source: the first text becomes the passage; the same text keeps it current; different text is held until accepted, and a model judges which citing claims it touches. */
|
|
140
|
+
private receiveText;
|
|
141
|
+
/**
|
|
142
|
+
* The writer gives a new version of a file already stored as a source (dropped again). Same text keeps it current; different text is held
|
|
143
|
+
* like a changed page, with the same impact judgement, until the writer accepts it. Without a stored file of that name the file is not matched.
|
|
144
|
+
*/
|
|
145
|
+
offerFileVersion(id: string, name: string, text: string, modelOverride?: string): Promise<{
|
|
146
|
+
status: 'read' | 'unchanged' | 'changed' | 'no_match';
|
|
147
|
+
sourceId?: string;
|
|
148
|
+
impacts: SourceImpact[];
|
|
149
|
+
}>;
|
|
150
|
+
/**
|
|
151
|
+
* Pulls a web page (or a repository file, by its GitHub link) in as a new article to edit: the page text becomes the article text, and the address is kept
|
|
152
|
+
* as a source marked as where it came from. Nothing in the text is treated as checked.
|
|
153
|
+
*/
|
|
154
|
+
importPage(address: string): Promise<{
|
|
155
|
+
ok: true;
|
|
156
|
+
id: string;
|
|
157
|
+
} | {
|
|
158
|
+
ok: false;
|
|
159
|
+
reason: string;
|
|
160
|
+
}>;
|
|
161
|
+
/** A text, markdown, MDX or HTML file the writer opens to edit becomes a new article (HTML is turned into markdown). */
|
|
162
|
+
importTextFile(name: string, text: string): Promise<{
|
|
163
|
+
ok: true;
|
|
164
|
+
id: string;
|
|
165
|
+
} | {
|
|
166
|
+
ok: false;
|
|
167
|
+
reason: string;
|
|
168
|
+
}>;
|
|
169
|
+
/**
|
|
170
|
+
* Uses a file from a folder the writer allowed: stored as a code or text source under the address `<folder>/<path>`. A file already stored
|
|
171
|
+
* under that address is compared instead, like a new version of a dropped file.
|
|
172
|
+
*/
|
|
173
|
+
addFolderFile(id: string, folder: FolderReader, path: string, modelOverride?: string): Promise<{
|
|
174
|
+
status: 'added' | 'read' | 'unchanged' | 'changed' | 'missing' | 'unsupported';
|
|
175
|
+
sourceId?: string;
|
|
176
|
+
impacts: SourceImpact[];
|
|
177
|
+
}>;
|
|
178
|
+
/** Reads again every source stored from this folder, before publishing or when asked. Changed files wait for the writer; files that are gone are reported. */
|
|
179
|
+
recheckFolder(id: string, folder: FolderReader, modelOverride?: string): Promise<{
|
|
180
|
+
unchanged: number;
|
|
181
|
+
changed: string[];
|
|
182
|
+
missing: string[];
|
|
183
|
+
}>;
|
|
184
|
+
/**
|
|
185
|
+
* Keeps only some lines of a source. A source with an address is read again to take them (or to widen them); a dropped file can be narrowed
|
|
186
|
+
* from the text stored, but not widened (drop the file again). The new passage replaces the old one, as an edit by the writer does.
|
|
187
|
+
* `undefined` clears the range.
|
|
188
|
+
*/
|
|
189
|
+
setSourceLines(id: string, sourceId: string, range: LineRange | undefined, modelOverride?: string): Promise<{
|
|
190
|
+
ok: boolean;
|
|
191
|
+
reason?: string;
|
|
192
|
+
}>;
|
|
193
|
+
/**
|
|
194
|
+
* Looks for pages that might back a claim: a web search on the claim's own words (no model call). Pages already stored as sources are left out.
|
|
195
|
+
* Nothing is stored until the writer picks one with useSourceCandidate.
|
|
196
|
+
*/
|
|
197
|
+
findSourceCandidates(id: string, claimId: string): Promise<{
|
|
198
|
+
status: 'found' | 'unavailable' | 'failed';
|
|
199
|
+
results: SourceCandidate[];
|
|
200
|
+
reason?: string;
|
|
201
|
+
}>;
|
|
202
|
+
/** The writer picks a found page: it is stored as a web source, read, and tied to the claim by a link the writer drew. A model checks it only when asked. */
|
|
203
|
+
useSourceCandidate(id: string, claimId: string, url: string): Promise<{
|
|
204
|
+
ok: boolean;
|
|
205
|
+
reason?: string;
|
|
206
|
+
read: 'read' | 'unreachable' | 'unavailable' | 'not_a_link' | 'unchanged' | 'changed';
|
|
207
|
+
}>;
|
|
208
|
+
/** Reads every web source again (at most 30, one after another). Used before publishing; nothing is blocked, the report says what to look at. */
|
|
209
|
+
recheckSources(id: string, modelOverride?: string): Promise<SourceRecheckReport>;
|
|
210
|
+
/** The writer takes the new text a re-read found: it becomes the stored passage, so checks made on the old text stop counting until run again. */
|
|
211
|
+
acceptSourceChange(id: string, sourceId: string): Promise<{
|
|
212
|
+
ok: boolean;
|
|
213
|
+
reason?: string;
|
|
214
|
+
}>;
|
|
215
|
+
/** The writer ties a claim to a source: a hand-drawn supported_by link, which the assistant can never remove. */
|
|
216
|
+
attachSource(id: string, claimId: string, sourceId: string): Promise<void>;
|
|
217
|
+
checkClaim(id: string, claimId: string, modelOverride?: string): Promise<SupportCheck>;
|
|
218
|
+
/**
|
|
219
|
+
* Verifies factual claims: a claim with sources that have passages is checked against them; a claim with none is searched for (the web search on
|
|
220
|
+
* the claim's own words), the first few pages are read and kept as proposed sources, and one check says whether they back it. If none does, the
|
|
221
|
+
* pages are dropped and the claim records that it was looked for and not backed. Nothing in the text changes. At most `limit` claims per run.
|
|
222
|
+
*/
|
|
223
|
+
/** Repositories the writer handed over for this session, per article. Readers hold browser handles and tokens, so they are never stored in the article. */
|
|
224
|
+
private readonly repos;
|
|
225
|
+
/** Hands a repository to the article for verifying claims. The same repository (by name) replaces the earlier reader. */
|
|
226
|
+
attachRepo(id: string, reader: RepoReader): void;
|
|
227
|
+
detachRepo(id: string, name: string): void;
|
|
228
|
+
attachedRepos(id: string): string[];
|
|
229
|
+
verifyClaims(id: string, opts?: {
|
|
230
|
+
claimIds?: string[];
|
|
231
|
+
limit?: number;
|
|
232
|
+
pages?: number;
|
|
233
|
+
model?: string;
|
|
234
|
+
repoOnly?: boolean;
|
|
235
|
+
batchSize?: number;
|
|
236
|
+
maxToolCalls?: number;
|
|
237
|
+
onStep?: (step: LoopStep) => void;
|
|
238
|
+
onProgress?: (done: number, total: number) => void;
|
|
239
|
+
onEntry?: (entry: VerifyEntry) => void;
|
|
240
|
+
shouldStop?: () => boolean;
|
|
241
|
+
}): Promise<VerifyReport>;
|
|
242
|
+
private readonly repoIndexes;
|
|
243
|
+
/** Claims in batches, each checked by a model that can search the first attached repository. Settled claims keep the lines they rest on as code sources and a recorded check. */
|
|
244
|
+
private verifyBySearch;
|
|
245
|
+
private recordSearchResult;
|
|
246
|
+
private verifyOne;
|
|
247
|
+
private setLookup;
|
|
248
|
+
/** A page found by search is tied to the claim by a proposed link, which the writer can confirm or dismiss like any other proposal. */
|
|
249
|
+
private attachProposed;
|
|
250
|
+
/** Removes sources this run added and the links to them; a claim left with none goes back to having no source. */
|
|
251
|
+
private dropFoundSources;
|
|
252
|
+
/** The writer confirms a claim (and may change its kind). A confirmed claim is matched first on re-extraction and never dropped silently. */
|
|
253
|
+
confirmClaim(id: string, claimId: string, kind?: Claim['kind']): Promise<void>;
|
|
254
|
+
/** The assistant turns the writer\'s instruction into suggestions; nothing is applied until the writer accepts. */
|
|
255
|
+
suggest(id: string, instruction: string, modelOverride?: string, refs?: {
|
|
256
|
+
ideaIds?: string[];
|
|
257
|
+
commentIds?: string[];
|
|
258
|
+
sectionIds?: string[];
|
|
259
|
+
focus?: {
|
|
260
|
+
start: number;
|
|
261
|
+
end: number;
|
|
262
|
+
};
|
|
263
|
+
history?: readonly ChatTurn[];
|
|
264
|
+
}, signal?: AbortSignal): Promise<EditSuggestResult>;
|
|
265
|
+
/** The writer asks for the passage under the cursor or selection to be revised: the result is suggested changes inside that passage only. */
|
|
266
|
+
reviseText(id: string, range: TextRange, instruction: string, modelOverride?: string): Promise<EditSuggestResult | {
|
|
267
|
+
status: 'failed';
|
|
268
|
+
reason: string;
|
|
269
|
+
}>;
|
|
270
|
+
/**
|
|
271
|
+
* The chat edits the article itself. The text as it is now is saved as a version first, always, so the edit can be undone from History; then
|
|
272
|
+
* the edit is made, and only the changes this request produced are applied (suggestions waiting from before stay as they are).
|
|
273
|
+
*/
|
|
274
|
+
editFromChat(id: string, instruction: string, modelOverride?: string, signal?: AbortSignal, onStage?: ChatStageListener, history?: readonly ChatTurn[]): Promise<ChatEditResult>;
|
|
275
|
+
/**
|
|
276
|
+
* The chat writes the text of an article that has none: a version is saved first (as for any chat edit), then the draft becomes the text.
|
|
277
|
+
* With `nameIt`, the article is also given the name the draft came with (for an article the chat has just made, which has no name of its own yet).
|
|
278
|
+
* With `rewrite`, the model is given the current text and reworks all of it as the instruction says (a change too wide for edits that quote text).
|
|
279
|
+
*/
|
|
280
|
+
draftFromChat(id: string, instruction: string, modelOverride?: string, nameIt?: boolean, signal?: AbortSignal, onText?: (markdownSoFar: string) => void, onStage?: ChatStageListener, rewrite?: boolean, history?: readonly ChatTurn[]): Promise<{
|
|
281
|
+
status: 'drafted' | 'failed';
|
|
282
|
+
savedAs: string;
|
|
283
|
+
name?: string;
|
|
284
|
+
reason?: string;
|
|
285
|
+
change?: SectionChange;
|
|
286
|
+
}>;
|
|
287
|
+
/** The same for the outline: saved first, then the headings are reworked (reworded, added, removed, moved) and each section's text follows its heading. */
|
|
288
|
+
editOutlineFromChat(id: string, instruction: string, modelOverride?: string, signal?: AbortSignal, onStage?: ChatStageListener, history?: readonly ChatTurn[]): Promise<OutlineEditResult>;
|
|
289
|
+
/** Accepts a suggestion (optionally with the writer\'s own wording): the Markdown changes, then the usual update runs. */
|
|
290
|
+
acceptSuggestionAndUpdate(id: string, suggestionId: string, edited?: string, options?: {
|
|
291
|
+
analyze?: boolean;
|
|
292
|
+
}): Promise<{
|
|
293
|
+
ok: true;
|
|
294
|
+
outcome: UpdateOutcome;
|
|
295
|
+
} | {
|
|
296
|
+
ok: false;
|
|
297
|
+
reason: string;
|
|
298
|
+
}>;
|
|
299
|
+
rejectSuggestionById(id: string, suggestionId: string): Promise<{
|
|
300
|
+
ok: boolean;
|
|
301
|
+
reason?: string;
|
|
302
|
+
}>;
|
|
303
|
+
/** Only the writer clears a section\'s needs-review (or sets it held / clean). */
|
|
304
|
+
setReview(id: string, sectionId: string, state: 'clean' | 'held' | 'needs_review'): Promise<{
|
|
305
|
+
ok: boolean;
|
|
306
|
+
reason?: string;
|
|
307
|
+
}>;
|
|
308
|
+
setCommentState(id: string, commentId: string, state: 'open' | 'addressed' | 'dismissed'): Promise<void>;
|
|
309
|
+
/** Saves the article as it is now as a named version the writer can come back to. */
|
|
310
|
+
saveVersion(id: string, label?: string): Promise<void>;
|
|
311
|
+
/**
|
|
312
|
+
* A version the page saves by itself (a sentence finished, a section started, the writer moved on to another sentence). The working text is set to
|
|
313
|
+
* `markdown` first so the version's text and its sections agree; nothing is saved when it is the same text as the latest version.
|
|
314
|
+
*/
|
|
315
|
+
autosave(id: string, markdown: string): Promise<boolean>;
|
|
316
|
+
/** Every version, newest first, each with what changed since the version before it (the oldest has nothing to compare with). */
|
|
317
|
+
history(id: string): Promise<{
|
|
318
|
+
index: number;
|
|
319
|
+
kind: Snapshot['kind'];
|
|
320
|
+
label?: string;
|
|
321
|
+
at: string;
|
|
322
|
+
readiness: Snapshot['readiness'];
|
|
323
|
+
change: ChangeSummary;
|
|
324
|
+
}[]>;
|
|
325
|
+
/** What the working article has changed since the latest saved version; undefined when nothing was saved yet. */
|
|
326
|
+
changeSinceLastVersion(id: string): Promise<ChangeSummary | undefined>;
|
|
327
|
+
/** What changed between a stored version and the article now (text, claim status, sources, readiness). */
|
|
328
|
+
compareWithCurrent(id: string, index: number): Promise<VersionComparison>;
|
|
329
|
+
getVersion(id: string, index: number): Promise<Snapshot>;
|
|
330
|
+
/**
|
|
331
|
+
* Restoring makes a new working version from an old one and rewrites no history. The present article is saved as a checkpoint first,
|
|
332
|
+
* so nothing is lost. Reviewer comments and the writer's corrections are the record of the conversation, not of the text, so they stay as they are.
|
|
333
|
+
*/
|
|
334
|
+
restore(id: string, index: number): Promise<ArticleBundle>;
|
|
335
|
+
/** The assistant reads the whole article and proposes dependencies between sections. Proposals wait for the writer to confirm them. */
|
|
336
|
+
findDependencies(id: string, modelOverride?: string): Promise<DependencyProposal>;
|
|
337
|
+
/**
|
|
338
|
+
* A first style sheet from the article's own text (brief fields and a writing profile), filling only what the writer has not set. One model call.
|
|
339
|
+
* Returns the names of what was filled in; an empty list means there was nothing to add or the call failed.
|
|
340
|
+
*/
|
|
341
|
+
deriveStyleFromText(id: string, modelOverride?: string): Promise<{
|
|
342
|
+
status: 'derived' | 'not_derived';
|
|
343
|
+
filled: string[];
|
|
344
|
+
reason?: string;
|
|
345
|
+
}>;
|
|
346
|
+
/** The writer draws a link by hand. */
|
|
347
|
+
addDependency(id: string, from: string, to: string, kind: DependencyKind): Promise<{
|
|
348
|
+
ok: true;
|
|
349
|
+
} | {
|
|
350
|
+
ok: false;
|
|
351
|
+
reason: string;
|
|
352
|
+
}>;
|
|
353
|
+
/** Only the writer confirms a proposed link, or removes any link. */
|
|
354
|
+
confirmDependency(id: string, linkId: string): Promise<{
|
|
355
|
+
ok: boolean;
|
|
356
|
+
reason?: string;
|
|
357
|
+
}>;
|
|
358
|
+
removeDependency(id: string, linkId: string): Promise<{
|
|
359
|
+
ok: boolean;
|
|
360
|
+
reason?: string;
|
|
361
|
+
}>;
|
|
362
|
+
/** Attaches a stored source to the text in a range (a phrase, a sentence or what is selected), creating a claim for that text if there is none. */
|
|
363
|
+
attachSourceToText(id: string, range: TextRange, sourceId: string): Promise<{
|
|
364
|
+
ok: true;
|
|
365
|
+
claimIds: string[];
|
|
366
|
+
createdClaim: boolean;
|
|
367
|
+
} | {
|
|
368
|
+
ok: false;
|
|
369
|
+
reason: string;
|
|
370
|
+
}>;
|
|
371
|
+
/** A source stored without saying what it is for: the assistant proposes which claims it bears on, and the writer confirms. */
|
|
372
|
+
proposeLinksForSource(id: string, sourceId: string, modelOverride?: string): Promise<SourceLinkProposal>;
|
|
373
|
+
/** The writer removes a source from a claim (the link only; the stored source stays). Proposals and drawn links alike. */
|
|
374
|
+
detachSource(id: string, claimId: string, sourceId: string): Promise<{
|
|
375
|
+
ok: boolean;
|
|
376
|
+
reason?: string;
|
|
377
|
+
}>;
|
|
378
|
+
addIdea(id: string, input: {
|
|
379
|
+
text: string;
|
|
380
|
+
origin?: Idea['origin'];
|
|
381
|
+
model?: string;
|
|
382
|
+
sectionId?: string;
|
|
383
|
+
}): Promise<{
|
|
384
|
+
ok: true;
|
|
385
|
+
idea: Idea;
|
|
386
|
+
} | {
|
|
387
|
+
ok: false;
|
|
388
|
+
reason: string;
|
|
389
|
+
}>;
|
|
390
|
+
updateIdea(id: string, ideaId: string, patch: {
|
|
391
|
+
text?: string;
|
|
392
|
+
sectionId?: string | null;
|
|
393
|
+
state?: Idea['state'];
|
|
394
|
+
}): Promise<{
|
|
395
|
+
ok: boolean;
|
|
396
|
+
reason?: string;
|
|
397
|
+
}>;
|
|
398
|
+
/** The scratchpad: the writer's free notes, kept as one block of text and given to the chat and the assistant as the ideas to draw on. */
|
|
399
|
+
setScratchpad(id: string, text: string): Promise<void>;
|
|
400
|
+
/** Adds a line to the end of the scratchpad (a chat answer worth keeping). */
|
|
401
|
+
appendToScratchpad(id: string, text: string): Promise<void>;
|
|
402
|
+
deleteIdea(id: string, ideaId: string): Promise<void>;
|
|
403
|
+
/** The assistant proposes new ideas from the article, the sources and what the writer asked for. They are added as open ideas, marked with the model. */
|
|
404
|
+
suggestIdeas(id: string, request?: string, modelOverride?: string): Promise<IdeaSuggestion>;
|
|
405
|
+
/** Writes the chosen ideas into the article as suggestions the writer accepts; each idea is marked used when its suggestion is accepted. */
|
|
406
|
+
writeIdeasIn(id: string, ideaIds: string[], instruction?: string, modelOverride?: string): Promise<EditSuggestResult>;
|
|
407
|
+
setBrief(id: string, brief: Brief): Promise<void>;
|
|
408
|
+
/** Saves a profile in the writer's settings (new, or replacing one with the same id). Returns it, or undefined when it has no name. */
|
|
409
|
+
saveProfile(profile: {
|
|
410
|
+
id?: string;
|
|
411
|
+
name: string;
|
|
412
|
+
voice?: string;
|
|
413
|
+
terms?: {
|
|
414
|
+
use: string;
|
|
415
|
+
instead?: string;
|
|
416
|
+
}[];
|
|
417
|
+
}): Promise<StyleProfile | undefined>;
|
|
418
|
+
profiles(): Promise<StyleProfile[]>;
|
|
419
|
+
deleteProfile(profileId: string): Promise<void>;
|
|
420
|
+
/** Gives the article a copy of a saved profile (null removes it). A later edit of the saved profile does not change articles that already use it until the writer applies it again. */
|
|
421
|
+
useProfile(id: string, profileId: string | null): Promise<{
|
|
422
|
+
ok: boolean;
|
|
423
|
+
reason?: string;
|
|
424
|
+
}>;
|
|
425
|
+
/** Renames a section by changing its heading line in the text, which is where the heading lives. The section keeps its identity. */
|
|
426
|
+
renameSection(id: string, sectionId: string, heading: string): Promise<{
|
|
427
|
+
ok: true;
|
|
428
|
+
} | {
|
|
429
|
+
ok: false;
|
|
430
|
+
reason: string;
|
|
431
|
+
}>;
|
|
432
|
+
/** The one-line purpose the outline shows under a section. An empty text removes it. */
|
|
433
|
+
setSectionPurpose(id: string, sectionId: string, purpose: string): Promise<void>;
|
|
434
|
+
addComment(id: string, range: TextRange, text: string): Promise<{
|
|
435
|
+
ok: true;
|
|
436
|
+
} | {
|
|
437
|
+
ok: false;
|
|
438
|
+
reason: string;
|
|
439
|
+
}>;
|
|
440
|
+
editComment(id: string, commentId: string, patch: {
|
|
441
|
+
text?: string;
|
|
442
|
+
decision?: string;
|
|
443
|
+
}): Promise<{
|
|
444
|
+
ok: boolean;
|
|
445
|
+
reason?: string;
|
|
446
|
+
}>;
|
|
447
|
+
deleteComment(id: string, commentId: string): Promise<void>;
|
|
448
|
+
editCorrection(id: string, correctionId: string, patch: {
|
|
449
|
+
note?: string;
|
|
450
|
+
supersedes?: string;
|
|
451
|
+
}): Promise<{
|
|
452
|
+
ok: boolean;
|
|
453
|
+
reason?: string;
|
|
454
|
+
}>;
|
|
455
|
+
/** Editing a source's passage replaces it as the writer's own new text, so checks made against the old passage stop counting until they are run again. */
|
|
456
|
+
editSource(id: string, sourceId: string, patch: {
|
|
457
|
+
address?: string;
|
|
458
|
+
note?: string;
|
|
459
|
+
passage?: string;
|
|
460
|
+
}): Promise<{
|
|
461
|
+
ok: boolean;
|
|
462
|
+
reason?: string;
|
|
463
|
+
}>;
|
|
464
|
+
/** Renames a saved version. A published version is frozen, label included. */
|
|
465
|
+
renameVersion(id: string, index: number, label: string): Promise<{
|
|
466
|
+
ok: boolean;
|
|
467
|
+
reason?: string;
|
|
468
|
+
}>;
|
|
469
|
+
/** Accepts every pending suggestion in one go: one checkpoint first, then from the end of the text to the start so earlier ones keep their place. */
|
|
470
|
+
acceptAllSuggestions(id: string): Promise<{
|
|
471
|
+
accepted: number;
|
|
472
|
+
skipped: number;
|
|
473
|
+
}>;
|
|
474
|
+
/**
|
|
475
|
+
* The one action for each category of issues (see article-issues.ts). Where the answer is a change to the text it is a set of suggestions,
|
|
476
|
+
* never an edit: suggested changes are accepted (all at once) from the "suggestions" category.
|
|
477
|
+
*/
|
|
478
|
+
resolveCategory(id: string, category: IssueCategory, options?: {
|
|
479
|
+
model?: string;
|
|
480
|
+
}): Promise<ResolveReport>;
|
|
481
|
+
/** Every category in a sensible order, one action each. It prepares suggestions but does not apply them; `accept` also applies them at the end. */
|
|
482
|
+
resolveAll(id: string, options?: {
|
|
483
|
+
model?: string;
|
|
484
|
+
categories?: IssueCategory[];
|
|
485
|
+
accept?: boolean;
|
|
486
|
+
onProgress?: (done: number, total: number, category: IssueCategory) => void;
|
|
487
|
+
shouldStop?: () => boolean;
|
|
488
|
+
}): Promise<ResolveReport[]>;
|
|
489
|
+
/** The writer changes the replacement text of a waiting suggestion before accepting it. */
|
|
490
|
+
editSuggestion(id: string, suggestionId: string, replacement: string): Promise<{
|
|
491
|
+
ok: boolean;
|
|
492
|
+
reason?: string;
|
|
493
|
+
}>;
|
|
494
|
+
readiness(bundle: ArticleBundle): {
|
|
495
|
+
readiness: Readiness;
|
|
496
|
+
problems: Problem[];
|
|
497
|
+
};
|
|
498
|
+
/** A dated, frozen snapshot (D4). Publishing is always allowed (D3); the snapshot records the readiness counts at that moment. */
|
|
499
|
+
publish(id: string, label?: string): Promise<ArticleBundle>;
|
|
500
|
+
exportArticle(id: string): Promise<ArticleFolder>;
|
|
501
|
+
/** Imports a folder under its own id. Refuses a folder it cannot read completely, and refuses to overwrite an existing article. */
|
|
502
|
+
importArticle(folder: ArticleFolder): Promise<{
|
|
503
|
+
ok: true;
|
|
504
|
+
id: string;
|
|
505
|
+
} | {
|
|
506
|
+
ok: false;
|
|
507
|
+
reason: string;
|
|
508
|
+
}>;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* The chat-held state port backed by the article store: each article's comments and corrections live in its own
|
|
512
|
+
* metadata (so they travel with an export), the active article and any held items in the store's settings.
|
|
513
|
+
*/
|
|
514
|
+
export declare function createArticleChatPort(store: ArticleStore): WriterChatPort;
|
|
515
|
+
/**
|
|
516
|
+
* The service with each article's calls run one after another. A step reads the article, waits for the model and saves, so two steps on the same
|
|
517
|
+
* article at once would each save from the text they first read and the later save would erase the earlier one (found in pilot P1: three
|
|
518
|
+
* source-link proposals started together left only one set of links). Calls on different articles still run together, and reads never wait.
|
|
519
|
+
* The calls the service makes on itself are not queued again, so a step that calls another cannot wait on itself.
|
|
520
|
+
*/
|
|
521
|
+
export declare function serializeByArticle<T extends object>(service: T): T;
|
|
522
|
+
/** What a chat edit of the text did: the version saved before it, and each change made. */
|
|
523
|
+
export interface ChatEditResult {
|
|
524
|
+
status: 'applied' | 'nothing' | 'failed';
|
|
525
|
+
savedAs: string;
|
|
526
|
+
applied: {
|
|
527
|
+
quote: string;
|
|
528
|
+
replacement: string;
|
|
529
|
+
}[];
|
|
530
|
+
/** Changes that no longer fitted the text when they were made. */
|
|
531
|
+
skipped: number;
|
|
532
|
+
/** What the edit did to the outline and to the wording, section by section. */
|
|
533
|
+
change?: SectionChange;
|
|
534
|
+
}
|
|
535
|
+
export interface OutlineEditResult {
|
|
536
|
+
status: 'applied' | 'nothing' | 'failed';
|
|
537
|
+
savedAs: string;
|
|
538
|
+
before?: string;
|
|
539
|
+
after?: string;
|
|
540
|
+
reason?: string;
|
|
541
|
+
change?: SectionChange;
|
|
542
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ILLMClient, TokenUsage } from '@buildaharness/runtime';
|
|
2
|
+
import { ArticleMeta, Claim, Link } from './article-model.js';
|
|
3
|
+
/**
|
|
4
|
+
* Sources for the text under the cursor. The writer clicks in the text or selects a phrase; the unit is the selection, or else the
|
|
5
|
+
* sentence around the cursor. Claims whose text overlaps the unit are the ones whose sources are shown, and a source dropped there is
|
|
6
|
+
* attached to them (a claim is created for the sentence when there is none). A source dropped elsewhere (the chat, or with no
|
|
7
|
+
* cursor) is only stored; a model then proposes which claims it bears on, and the writer confirms.
|
|
8
|
+
*/
|
|
9
|
+
export interface TextRange {
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
}
|
|
13
|
+
export interface TextUnit extends TextRange {
|
|
14
|
+
quote: string;
|
|
15
|
+
}
|
|
16
|
+
/** The selection (trimmed) if there is one, else the sentence around the cursor, never crossing a blank line. A heading line is its own unit. */
|
|
17
|
+
export declare function textUnitAt(markdown: string, start: number, end?: number): TextUnit | undefined;
|
|
18
|
+
/** Factual claims whose text overlaps the range. */
|
|
19
|
+
export declare function claimsInRange(meta: ArticleMeta, range: TextRange): Claim[];
|
|
20
|
+
export type AttachResult = {
|
|
21
|
+
ok: true;
|
|
22
|
+
meta: ArticleMeta;
|
|
23
|
+
claimIds: string[];
|
|
24
|
+
createdClaim: boolean;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
reason: string;
|
|
28
|
+
};
|
|
29
|
+
/** Attaches a source to the text in the range: to the claims there, or to a new claim for that text. The links are hand-drawn, so the assistant cannot remove them. */
|
|
30
|
+
export declare function attachSourceToText(meta: ArticleMeta, markdown: string, range: TextRange, sourceId: string, now: string): AttachResult;
|
|
31
|
+
export interface SourceLinkProposal {
|
|
32
|
+
status: 'proposed' | 'failed';
|
|
33
|
+
meta: ArticleMeta;
|
|
34
|
+
added: Link[];
|
|
35
|
+
skipped: string[];
|
|
36
|
+
}
|
|
37
|
+
/** A source that was stored without saying what it is for: a model proposes which claims it bears on. Proposals wait for the writer. */
|
|
38
|
+
export declare function proposeSourceLinks(input: {
|
|
39
|
+
meta: ArticleMeta;
|
|
40
|
+
sourceId: string;
|
|
41
|
+
now: string;
|
|
42
|
+
}, llmClient: ILLMClient, model?: string, onUsage?: (usage: TokenUsage) => void): Promise<SourceLinkProposal>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Source } from './article-model.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stored source passages (T6): the passage as read, its address, the date and a fingerprint, so a later recheck can tell
|
|
4
|
+
* whether the source changed. Whether a difference MATTERS is a model judgement and is not made here.
|
|
5
|
+
* Source text is data, never instructions; callers must wrap it as untrusted before showing it to a model.
|
|
6
|
+
*/
|
|
7
|
+
/** A fast, stable 53-bit hash (cyrb53) as hex. Not cryptographic: it only detects change. Whitespace differences do not count as change. */
|
|
8
|
+
export declare function fingerprintPassage(passage: string): string;
|
|
9
|
+
export type LineRange = {
|
|
10
|
+
from: number;
|
|
11
|
+
to: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A line range from the text a writer types into a field or from a link fragment: "40-60", "40–60", "L40-L60", "lines 40 to 60", "40".
|
|
15
|
+
* It reads the numbers only; the first is the start and the second (if any) the end. Nothing is parsed from the meaning of words.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseLineRange(text: string): LineRange | undefined;
|
|
18
|
+
/** Only the given lines (1-based, inclusive) of a text; a range past the end is cut at the end, and an empty result means the range misses the text. */
|
|
19
|
+
export declare function sliceLines(text: string, range: LineRange): string;
|
|
20
|
+
/** What a stored passage holds when the source keeps only some lines: the whole text otherwise. */
|
|
21
|
+
export declare function excerptFor(source: Pick<Source, 'lines'>, text: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* A link to one file in a GitHub repository (github.com/o/r/blob/ref/path, or raw.githubusercontent.com), with the line range of an #L10-L20 fragment.
|
|
24
|
+
* `rawUrl` is where the file's text is fetched from. Anything else is undefined: such a link is an ordinary web page.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseRepoFileLink(address: string): {
|
|
27
|
+
rawUrl: string;
|
|
28
|
+
path: string;
|
|
29
|
+
lines?: LineRange;
|
|
30
|
+
} | undefined;
|
|
31
|
+
export declare function createSource(input: {
|
|
32
|
+
id: string;
|
|
33
|
+
kind: Source['kind'];
|
|
34
|
+
address?: string;
|
|
35
|
+
passage?: string;
|
|
36
|
+
note?: string;
|
|
37
|
+
lines?: LineRange;
|
|
38
|
+
now: string;
|
|
39
|
+
}): Source;
|
|
40
|
+
/**
|
|
41
|
+
* Records the result of reading a source again. Same fingerprint: current. Different: changed (the stored passage is
|
|
42
|
+
* kept as read until the writer accepts the new one, so a check never silently moves to new text). Unreadable: unreachable.
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyRecheck(source: Source, result: {
|
|
45
|
+
passage: string;
|
|
46
|
+
} | {
|
|
47
|
+
unreachable: true;
|
|
48
|
+
}, now: string): Source;
|
|
49
|
+
/** The writer accepts the newly read text: it replaces the stored passage and the fingerprint. */
|
|
50
|
+
export declare function acceptNewPassage(source: Source, passage: string, now: string): Source;
|
|
51
|
+
/** A PDF or Word file: not text, so the page has to extract its text before it is stored (the extraction needs the browser, so it is not done here). */
|
|
52
|
+
export declare function documentFormatForFile(file: {
|
|
53
|
+
name: string;
|
|
54
|
+
type?: string;
|
|
55
|
+
}): 'pdf' | 'docx' | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* What kind of source a dropped file is, from its name and type: code (program text, so claims about what it does are checked against the
|
|
58
|
+
* code itself), an uploaded text document, or undefined when it cannot be read as text. PDF and Word files count as uploaded documents; the caller reads the file's text (see `documentFormatForFile`).
|
|
59
|
+
*/
|
|
60
|
+
export declare function sourceKindForFile(file: {
|
|
61
|
+
name: string;
|
|
62
|
+
type?: string;
|
|
63
|
+
}): 'code' | 'upload' | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* The text of a fetched page made ready to edit: line endings normalised, runs of blank lines cut to one, trailing spaces dropped. The title is the first
|
|
66
|
+
* heading or, failing that, the first short line; the page's host if there is no text line to use.
|
|
67
|
+
*/
|
|
68
|
+
export declare function pageToArticle(text: string, address: string): {
|
|
69
|
+
title: string;
|
|
70
|
+
markdown: string;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* The stored sources of an article as text for a model: each one's address and the passage as read, cut to its share of a fixed budget so a
|
|
74
|
+
* few large documents cannot crowd out the rest. Empty when no source has text. The passages are data, never instructions.
|
|
75
|
+
*/
|
|
76
|
+
export declare function renderSourcesForModel(meta: {
|
|
77
|
+
sources: {
|
|
78
|
+
kind: string;
|
|
79
|
+
address?: string;
|
|
80
|
+
passage?: string;
|
|
81
|
+
}[];
|
|
82
|
+
}, budget?: number): string;
|