@hraness/sponge 0.2.5 → 0.3.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/README.md +23 -10
- package/bin/sponge.js +8 -7
- package/dist/contracts/index.js +24 -6
- package/dist/contracts/validate.js +106 -29
- package/dist/migrations/008.d.ts +3 -0
- package/dist/migrations/008.js +5 -0
- package/dist/migrations/009.d.ts +3 -0
- package/dist/migrations/009.js +8 -0
- package/dist/migrations/010.d.ts +3 -0
- package/dist/migrations/010.js +11 -0
- package/dist/migrations/index.d.ts +15 -0
- package/dist/migrations/index.js +39 -0
- package/dist/src/acquisition/capture.js +87 -28
- package/dist/src/acquisition/cleanup.d.ts +0 -4
- package/dist/src/acquisition/cleanup.js +3 -5
- package/dist/src/acquisition/errors.js +17 -2
- package/dist/src/acquisition/files.d.ts +0 -1
- package/dist/src/acquisition/files.js +14 -11
- package/dist/src/acquisition/index.d.ts +2 -3
- package/dist/src/acquisition/index.js +1 -2
- package/dist/src/acquisition/lock.js +1 -1
- package/dist/src/acquisition/normalize.js +57 -18
- package/dist/src/acquisition/pins.js +22 -4
- package/dist/src/acquisition/process.js +67 -29
- package/dist/src/acquisition/runtime.d.ts +5 -7
- package/dist/src/acquisition/runtime.js +129 -68
- package/dist/src/acquisition/verify-helper.js +10 -3
- package/dist/src/annotations/quote.js +40 -12
- package/dist/src/annotations/store.d.ts +0 -1
- package/dist/src/annotations/store.js +66 -14
- package/dist/src/app/article.d.ts +2 -1
- package/dist/src/app/article.js +66 -70
- package/dist/src/app/bundle-files.d.ts +0 -4
- package/dist/src/app/bundle-files.js +11 -14
- package/dist/src/app/markdown.js +18 -6
- package/dist/src/app/source.d.ts +0 -4
- package/dist/src/app/source.js +18 -14
- package/dist/src/cli/arguments.d.ts +2 -8
- package/dist/src/cli/arguments.js +67 -80
- package/dist/src/cli/commands.d.ts +42 -0
- package/dist/src/cli/commands.js +795 -0
- package/dist/src/cli/config.js +12 -9
- package/dist/src/cli/digest.d.ts +1 -1
- package/dist/src/cli/digest.js +39 -17
- package/dist/src/cli/import.js +25 -4
- package/dist/src/cli/indexing.d.ts +2 -0
- package/dist/src/cli/indexing.js +26 -9
- package/dist/src/cli/main.js +47 -386
- package/dist/src/cli/portability.d.ts +0 -2
- package/dist/src/cli/portability.js +13 -8
- package/dist/src/cli/queue.js +12 -8
- package/dist/src/cli/runtimes.d.ts +1 -3
- package/dist/src/cli/runtimes.js +13 -6
- package/dist/src/cli/terminal.js +1 -1
- package/dist/src/cli/worker.d.ts +7 -0
- package/dist/src/cli/worker.js +54 -15
- package/dist/src/derivations/kinds.d.ts +34 -0
- package/dist/src/derivations/kinds.js +14 -0
- package/dist/src/derivations/types.d.ts +48 -0
- package/dist/src/derivations/types.js +1 -0
- package/dist/src/digest/derivation.d.ts +25 -0
- package/dist/src/digest/derivation.js +124 -0
- package/dist/src/digest/editorial.d.ts +10 -46
- package/dist/src/digest/editorial.js +73 -59
- package/dist/src/digest/endpoint.js +63 -27
- package/dist/src/digest/pipeline.d.ts +53 -32
- package/dist/src/digest/pipeline.js +357 -125
- package/dist/src/digest/schema.d.ts +44 -17
- package/dist/src/digest/schema.js +132 -44
- package/dist/src/errors.d.ts +46 -0
- package/dist/src/errors.js +117 -0
- package/dist/src/identity/query-policy.d.ts +0 -5
- package/dist/src/identity/query-policy.js +61 -9
- package/dist/src/identity/uri.d.ts +6 -5
- package/dist/src/identity/uri.js +37 -18
- package/dist/src/identity/visibility.d.ts +11 -1
- package/dist/src/identity/visibility.js +81 -17
- package/dist/src/importers/apply.js +104 -36
- package/dist/src/importers/custody.js +27 -9
- package/dist/src/importers/inspect.js +125 -38
- package/dist/src/importers/jungle-digest.d.ts +31 -24
- package/dist/src/importers/jungle-digest.js +217 -115
- package/dist/src/importers/jungle-store.d.ts +20 -11
- package/dist/src/importers/jungle-store.js +136 -41
- package/dist/src/importers/jungle.d.ts +32 -16
- package/dist/src/importers/jungle.js +145 -32
- package/dist/src/importers/manifest.js +57 -21
- package/dist/src/importers/verify-helper.js +18 -4
- package/dist/src/indexing/image.js +29 -10
- package/dist/src/indexing/index.d.ts +37 -6
- package/dist/src/indexing/index.js +360 -124
- package/dist/src/indexing/jobs.js +156 -47
- package/dist/src/indexing/prune-run.d.ts +2 -0
- package/dist/src/indexing/prune-run.js +69 -26
- package/dist/src/indexing/prune.d.ts +12 -3
- package/dist/src/indexing/prune.js +85 -35
- package/dist/src/indexing/runner.d.ts +2 -1
- package/dist/src/indexing/runner.js +83 -40
- package/dist/src/indexing/upgrade.d.ts +9 -0
- package/dist/src/indexing/upgrade.js +79 -0
- package/dist/src/inference/asr/bridge.js +6 -2
- package/dist/src/inference/asr/protocol.js +109 -19
- package/dist/src/inference/asr/runtime.js +58 -21
- package/dist/src/inference/asr/windows.js +9 -5
- package/dist/src/inference/embedding/index.d.ts +2 -6
- package/dist/src/inference/embedding/index.js +89 -29
- package/dist/src/ingest/attempt.d.ts +29 -0
- package/dist/src/ingest/attempt.js +55 -0
- package/dist/src/media/capture-helper.js +7 -2
- package/dist/src/media/capture.d.ts +2 -1
- package/dist/src/media/capture.js +124 -43
- package/dist/src/media/handler.d.ts +4 -2
- package/dist/src/media/handler.js +88 -70
- package/dist/src/media/transcribe.js +63 -21
- package/dist/src/metadata/article.js +49 -17
- package/dist/src/models/artifacts.d.ts +10 -8
- package/dist/src/models/artifacts.js +237 -106
- package/dist/src/models/catalog.d.ts +2 -5
- package/dist/src/models/catalog.js +94 -25
- package/dist/src/models/download.js +55 -15
- package/dist/src/models/runtime.d.ts +0 -2
- package/dist/src/models/runtime.js +69 -33
- package/dist/src/pdf/capture-helper.js +3 -1
- package/dist/src/pdf/capture.d.ts +2 -1
- package/dist/src/pdf/capture.js +95 -27
- package/dist/src/pdf/errors.js +12 -1
- package/dist/src/pdf/handler.d.ts +2 -1
- package/dist/src/pdf/handler.js +70 -71
- package/dist/src/pdf/index.d.ts +1 -3
- package/dist/src/pdf/index.js +0 -2
- package/dist/src/pdf/input.js +12 -7
- package/dist/src/pdf/normalize.js +80 -21
- package/dist/src/pdf/source-identity.js +3 -2
- package/dist/src/pdf/source.js +12 -8
- package/dist/src/pdf/verify-helper.js +15 -3
- package/dist/src/portability/backup.d.ts +2 -9
- package/dist/src/portability/backup.js +108 -22
- package/dist/src/portability/database.js +51 -17
- package/dist/src/portability/export.js +35 -9
- package/dist/src/portability/files.d.ts +1 -4
- package/dist/src/portability/files.js +127 -67
- package/dist/src/portability/gc.js +65 -22
- package/dist/src/publish/component.js +1 -1
- package/dist/src/publish/feed.d.ts +2 -2
- package/dist/src/publish/feed.js +75 -29
- package/dist/src/publish/identity.d.ts +5 -1
- package/dist/src/publish/identity.js +31 -11
- package/dist/src/publish/index.d.ts +2 -3
- package/dist/src/publish/index.js +34 -21
- package/dist/src/publish/projection.d.ts +2 -9
- package/dist/src/publish/projection.js +21 -14
- package/dist/src/search/extension.js +3 -1
- package/dist/src/search/hybrid.d.ts +3 -8
- package/dist/src/search/hybrid.js +45 -11
- package/dist/src/search/lexical.js +18 -4
- package/dist/src/search/query.js +56 -25
- package/dist/src/search/vector.js +37 -10
- package/dist/src/service/launch-agent.d.ts +5 -3
- package/dist/src/service/launch-agent.js +272 -83
- package/dist/src/service/lifetime.js +47 -14
- package/dist/src/service/loop.d.ts +3 -3
- package/dist/src/service/loop.js +47 -19
- package/dist/src/store/annotations.d.ts +32 -0
- package/dist/src/store/annotations.js +44 -0
- package/dist/src/store/backups.d.ts +18 -0
- package/dist/src/store/backups.js +110 -0
- package/dist/src/store/blobs.d.ts +24 -0
- package/dist/src/store/blobs.js +139 -0
- package/dist/src/store/changes.d.ts +5 -12
- package/dist/src/store/changes.js +108 -56
- package/dist/src/store/context.d.ts +15 -0
- package/dist/src/store/context.js +19 -0
- package/dist/src/store/derivations.d.ts +42 -0
- package/dist/src/store/derivations.js +104 -0
- package/dist/src/store/files.d.ts +0 -2
- package/dist/src/store/files.js +19 -24
- package/dist/src/store/ids.d.ts +30 -0
- package/dist/src/store/ids.js +34 -0
- package/dist/src/store/imports.d.ts +26 -0
- package/dist/src/store/imports.js +57 -0
- package/dist/src/store/index.d.ts +3 -186
- package/dist/src/store/index.js +2 -809
- package/dist/src/store/lease.d.ts +20 -0
- package/dist/src/store/lease.js +62 -0
- package/dist/src/store/library.d.ts +75 -0
- package/dist/src/store/library.js +174 -0
- package/dist/src/store/open.d.ts +7 -0
- package/dist/src/store/open.js +183 -0
- package/dist/src/store/queue.d.ts +65 -0
- package/dist/src/store/queue.js +327 -0
- package/dist/src/store/revisions.d.ts +12 -0
- package/dist/src/store/revisions.js +189 -0
- package/dist/src/store/search-index.d.ts +63 -0
- package/dist/src/store/search-index.js +190 -0
- package/dist/src/store/sync-ready.d.ts +6 -0
- package/dist/src/store/sync-ready.js +121 -0
- package/dist/src/store/types.d.ts +1 -5
- package/dist/src/store/types.js +1 -8
- package/dist/src/util/canonical.d.ts +2 -0
- package/dist/src/util/canonical.js +17 -0
- package/dist/src/util/exact.d.ts +2 -0
- package/dist/src/util/exact.js +9 -0
- package/dist/src/util/fsync.d.ts +4 -0
- package/dist/src/util/fsync.js +22 -0
- package/dist/src/util/hash.d.ts +4 -0
- package/dist/src/util/hash.js +8 -0
- package/dist/src/worker/basic.d.ts +0 -1
- package/dist/src/worker/basic.js +23 -7
- package/dist/src/worker/custody.d.ts +4 -1
- package/dist/src/worker/custody.js +111 -38
- package/dist/src/worker/engine.d.ts +2 -1
- package/dist/src/worker/engine.js +42 -20
- package/dist/src/worker/identity.js +13 -5
- package/dist/src/worker/journal.d.ts +1 -1
- package/dist/src/worker/journal.js +54 -24
- package/dist/src/worker/lock.d.ts +18 -0
- package/dist/src/worker/lock.js +196 -0
- package/dist/src/worker/runtime-gc.d.ts +4 -3
- package/dist/src/worker/runtime-gc.js +68 -41
- package/dist/src/worker/supervisor-child.js +19 -6
- package/dist/src/worker/supervisor.js +41 -8
- package/native/runtime-manifest.json +4 -4
- package/package.json +10 -2
- package/dist/src/digest/store.d.ts +0 -57
- package/dist/src/digest/store.js +0 -77
- package/dist/src/store/foundation.d.ts +0 -7
- package/dist/src/store/foundation.js +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpongeError } from '../errors.js';
|
|
2
2
|
/**
|
|
3
3
|
* A user-started local OpenAI-compatible server (llama.cpp `llama-server`, LM Studio, Ollama). Captured text must not
|
|
4
4
|
* leave the machine, so only literal loopback HTTP origins are accepted, redirects are refused, and Sponge never starts a server.
|
|
@@ -9,17 +9,23 @@ export function loopbackEndpoint(value) {
|
|
|
9
9
|
url = new URL(value);
|
|
10
10
|
}
|
|
11
11
|
catch {
|
|
12
|
-
throw new
|
|
12
|
+
throw new SpongeError('invalid-input');
|
|
13
13
|
}
|
|
14
14
|
// A hostname such as `localhost` resolves through configuration Sponge does not control; only literal addresses pass.
|
|
15
|
-
if (url.protocol !== 'http:' ||
|
|
16
|
-
|
|
15
|
+
if (url.protocol !== 'http:' ||
|
|
16
|
+
!['127.0.0.1', '[::1]'].includes(url.hostname) ||
|
|
17
|
+
url.username ||
|
|
18
|
+
url.password ||
|
|
19
|
+
url.search ||
|
|
20
|
+
url.hash ||
|
|
21
|
+
!['', '/', '/v1', '/v1/'].includes(url.pathname))
|
|
22
|
+
throw new SpongeError('invalid-input');
|
|
17
23
|
return new URL(url.origin);
|
|
18
24
|
}
|
|
19
25
|
async function readCapped(response, max) {
|
|
20
26
|
const reader = response.body?.getReader(), chunks = [];
|
|
21
27
|
if (!reader)
|
|
22
|
-
throw new
|
|
28
|
+
throw new SpongeError('unavailable');
|
|
23
29
|
let size = 0;
|
|
24
30
|
for (;;) {
|
|
25
31
|
const { done, value } = await reader.read();
|
|
@@ -28,7 +34,7 @@ async function readCapped(response, max) {
|
|
|
28
34
|
size += value.byteLength;
|
|
29
35
|
if (size > max) {
|
|
30
36
|
await reader.cancel().catch(() => undefined);
|
|
31
|
-
throw new
|
|
37
|
+
throw new SpongeError('limit-exceeded');
|
|
32
38
|
}
|
|
33
39
|
chunks.push(value);
|
|
34
40
|
}
|
|
@@ -37,7 +43,9 @@ async function readCapped(response, max) {
|
|
|
37
43
|
const label = (v, max = 128) => typeof v === 'string' && v.trim() && v.length <= max && !/[\u0000-\u001f\u007f]/.test(v) ? v.trim() : undefined;
|
|
38
44
|
/** GGUF quantization from a model filename, e.g. `gemma-4-12b-it-Q4_K_M.gguf` → `Q4_K_M`. */
|
|
39
45
|
export function quantizationOf(path) {
|
|
40
|
-
return /(?:^|[-_.])((?:IQ|Q)\d(?:_[A-Z0-9]+)*|BF16|F16|F32)(?=\.gguf$|[-_.])/i
|
|
46
|
+
return /(?:^|[-_.])((?:IQ|Q)\d(?:_[A-Z0-9]+)*|BF16|F16|F32)(?=\.gguf$|[-_.])/i
|
|
47
|
+
.exec(path.split('/').pop() ?? '')?.[1]
|
|
48
|
+
?.toUpperCase();
|
|
41
49
|
}
|
|
42
50
|
/**
|
|
43
51
|
* Confirm the server lists `model`, read what identity it exposes (llama.cpp `/props`, Ollama `/api/version`),
|
|
@@ -46,58 +54,86 @@ export function quantizationOf(path) {
|
|
|
46
54
|
export async function connectEndpoint(options) {
|
|
47
55
|
const origin = loopbackEndpoint(options.endpoint), request = options.fetch ?? fetch, model = label(options.model, 256);
|
|
48
56
|
if (!model)
|
|
49
|
-
throw new
|
|
57
|
+
throw new SpongeError('invalid-input');
|
|
50
58
|
const get = async (path) => {
|
|
51
|
-
const signal = AbortSignal.any([
|
|
59
|
+
const signal = AbortSignal.any([
|
|
60
|
+
options.signal ?? new AbortController().signal,
|
|
61
|
+
AbortSignal.timeout(options.probeTimeoutMs ?? 10000),
|
|
62
|
+
]);
|
|
52
63
|
try {
|
|
53
|
-
const r = await request(new URL(path, origin), {
|
|
64
|
+
const r = await request(new URL(path, origin), {
|
|
65
|
+
signal,
|
|
66
|
+
redirect: 'error',
|
|
67
|
+
headers: { accept: 'application/json' },
|
|
68
|
+
});
|
|
54
69
|
return r.ok ? JSON.parse(await readCapped(r, 1 << 20)) : undefined;
|
|
55
70
|
}
|
|
56
71
|
catch (error) {
|
|
57
72
|
if (options.signal?.aborted)
|
|
58
|
-
throw new
|
|
59
|
-
if (error instanceof
|
|
73
|
+
throw new SpongeError('cancelled');
|
|
74
|
+
if (error instanceof SpongeError)
|
|
60
75
|
throw error;
|
|
61
76
|
return undefined;
|
|
62
77
|
}
|
|
63
78
|
};
|
|
64
|
-
const models = await get('/v1/models');
|
|
79
|
+
const models = (await get('/v1/models'));
|
|
65
80
|
if (!Array.isArray(models?.data))
|
|
66
|
-
throw new
|
|
67
|
-
if (!models.data.some(m => m?.id === model))
|
|
68
|
-
throw new
|
|
69
|
-
const props = await get('/props'), build = label(props?.build_info);
|
|
81
|
+
throw new SpongeError('unavailable');
|
|
82
|
+
if (!models.data.some((m) => m?.id === model))
|
|
83
|
+
throw new SpongeError('invalid-input');
|
|
84
|
+
const props = (await get('/props')), build = label(props?.build_info);
|
|
70
85
|
let runtime = build ? `llama.cpp ${build}` : undefined;
|
|
71
86
|
if (!runtime) {
|
|
72
87
|
const ollama = label((await get('/api/version'))?.version);
|
|
73
88
|
runtime = ollama ? `ollama ${ollama}` : 'openai-compatible';
|
|
74
89
|
}
|
|
75
|
-
const identity = {
|
|
76
|
-
|
|
90
|
+
const identity = {
|
|
91
|
+
model,
|
|
92
|
+
quantization: (typeof props?.model_path === 'string' && quantizationOf(props.model_path)) || quantizationOf(model) || 'unknown',
|
|
93
|
+
runtime,
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
identity,
|
|
97
|
+
generate: (messages, schema, generate) => complete(origin, request, model, messages, schema, generate),
|
|
98
|
+
};
|
|
77
99
|
}
|
|
78
100
|
async function complete(origin, request, model, messages, schema, o) {
|
|
79
|
-
const body = JSON.stringify({
|
|
80
|
-
|
|
101
|
+
const body = JSON.stringify({
|
|
102
|
+
model,
|
|
103
|
+
messages,
|
|
104
|
+
stream: false,
|
|
105
|
+
temperature: o.temperature,
|
|
106
|
+
seed: o.seed,
|
|
107
|
+
max_tokens: o.maxTokens,
|
|
108
|
+
response_format: { type: 'json_schema', json_schema: { name: 'sponge_digest', strict: true, schema } },
|
|
109
|
+
});
|
|
110
|
+
const response = await request(new URL('/v1/chat/completions', origin), {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
signal: o.signal,
|
|
113
|
+
redirect: 'error',
|
|
114
|
+
headers: { 'content-type': 'application/json', accept: 'application/json' },
|
|
115
|
+
body,
|
|
116
|
+
});
|
|
81
117
|
if (!response.ok) {
|
|
82
118
|
await response.body?.cancel().catch(() => undefined);
|
|
83
|
-
throw new
|
|
119
|
+
throw new SpongeError('unavailable');
|
|
84
120
|
}
|
|
85
121
|
let parsed;
|
|
86
122
|
try {
|
|
87
123
|
parsed = JSON.parse(await readCapped(response, o.maxOutputBytes * 2 + 65536));
|
|
88
124
|
}
|
|
89
125
|
catch (error) {
|
|
90
|
-
if (error instanceof
|
|
126
|
+
if (error instanceof SpongeError)
|
|
91
127
|
throw error;
|
|
92
|
-
throw new
|
|
128
|
+
throw new SpongeError('unavailable');
|
|
93
129
|
}
|
|
94
130
|
const choice = parsed?.choices?.[0];
|
|
95
131
|
if (choice?.finish_reason === 'length')
|
|
96
|
-
throw new
|
|
132
|
+
throw new SpongeError('limit-exceeded');
|
|
97
133
|
const content = choice?.message?.content;
|
|
98
134
|
if (typeof content !== 'string' || !content.trim())
|
|
99
|
-
throw new
|
|
135
|
+
throw new SpongeError('unavailable');
|
|
100
136
|
if (Buffer.byteLength(content) > o.maxOutputBytes)
|
|
101
|
-
throw new
|
|
137
|
+
throw new SpongeError('limit-exceeded');
|
|
102
138
|
return content;
|
|
103
139
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { forms, type DigestIssue, type DigestOptions, type
|
|
2
|
-
import type {
|
|
3
|
-
import type { Derivation } from '../store/foundation.js';
|
|
1
|
+
import { forms, type DigestIssue, type DigestOptions, type DigestV2 } from './schema.js';
|
|
2
|
+
import type { Derivation, DigestCandidate } from './derivation.js';
|
|
4
3
|
/**
|
|
5
|
-
* Model-agnostic Digest
|
|
6
|
-
* span; code snaps,
|
|
4
|
+
* Model-agnostic Digest v2 drafting. The model sees numbered passages and cites a passage id plus a short exact
|
|
5
|
+
* span; code snaps, prunes and checks. Nothing leaves this module except through the injected model.
|
|
7
6
|
*/
|
|
8
|
-
export declare const PROMPT_VERSION = "sponge-digest-prompt-
|
|
7
|
+
export declare const PROMPT_VERSION = "sponge-digest-prompt-v4";
|
|
9
8
|
export type ChatMessage = {
|
|
10
9
|
role: 'system' | 'user' | 'assistant';
|
|
11
10
|
content: string;
|
|
@@ -29,7 +28,7 @@ export interface DigestModel {
|
|
|
29
28
|
generate(messages: ChatMessage[], schema: JsonSchema, options: GenerateOptions): Promise<string>;
|
|
30
29
|
}
|
|
31
30
|
/** Output-shaping parameters are hashed; time and byte bounds are not, because they only decide whether a run finishes. */
|
|
32
|
-
|
|
31
|
+
interface DigestParams {
|
|
33
32
|
temperature: number;
|
|
34
33
|
seed: number;
|
|
35
34
|
maxTokens: number;
|
|
@@ -39,17 +38,7 @@ export interface DigestParams {
|
|
|
39
38
|
deadlineMs: number;
|
|
40
39
|
maxOutputBytes: number;
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
export declare const defaultDigestParams: DigestParams;
|
|
44
|
-
export type DigestErrorCode = 'invalid-input' | 'unavailable' | 'cancelled' | 'limit-exceeded';
|
|
45
|
-
export declare class DigestError extends Error {
|
|
46
|
-
readonly code: DigestErrorCode;
|
|
47
|
-
readonly issues?: DigestIssue[] | undefined;
|
|
48
|
-
constructor(code: DigestErrorCode, issues?: DigestIssue[] | undefined);
|
|
49
|
-
}
|
|
50
|
-
export type Form = typeof forms[number];
|
|
51
|
-
/** Quotes under this many words carry no evidence; the checker is gaining the same floor. */
|
|
52
|
-
export declare const minQuoteWords = 4;
|
|
41
|
+
export type Form = (typeof forms)[number];
|
|
53
42
|
export interface Passage {
|
|
54
43
|
id: number;
|
|
55
44
|
start: number;
|
|
@@ -57,30 +46,29 @@ export interface Passage {
|
|
|
57
46
|
heading: string;
|
|
58
47
|
text: string;
|
|
59
48
|
}
|
|
60
|
-
|
|
49
|
+
interface Highlight {
|
|
61
50
|
text: string;
|
|
62
51
|
start?: number;
|
|
63
52
|
}
|
|
64
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Sorted-key JSON; the only serialization that enters input hashes. Deliberately not `util/canonical.ts`: this one
|
|
55
|
+
* accepts finite non-integer numbers (temperature) and writes `undefined` array entries as null, so merging would
|
|
56
|
+
* change digest input hashes.
|
|
57
|
+
*/
|
|
65
58
|
export declare function canonicalJson(value: unknown): string;
|
|
66
59
|
/** Paragraph-level passages with raw offsets. Headings label passages; code fences and image-only blocks are not quotable. */
|
|
67
60
|
export declare function passages(markdown: string, maxChars?: number): Passage[];
|
|
68
61
|
/** Pack passages into sections of at most `budget` display characters, preferring heading boundaries past half a budget. */
|
|
69
62
|
export declare function sectionsOf(list: Passage[], budget: number): Passage[][];
|
|
70
|
-
export declare const quoteBudget: (markdown: string) => number;
|
|
71
63
|
/** JSON Schema for the model's draft. Tags become an enum when a vocabulary is given. */
|
|
72
64
|
export declare function draftSchema(passageCount: number, vocabulary?: readonly string[]): JsonSchema;
|
|
73
|
-
export declare function notesSchema(first: number, last: number): JsonSchema;
|
|
74
|
-
interface Draft {
|
|
75
|
-
digest: DigestV1;
|
|
76
|
-
cites: (number | undefined)[][];
|
|
77
|
-
}
|
|
78
65
|
export interface QuoteStats {
|
|
79
66
|
exact: number;
|
|
80
67
|
folded: number;
|
|
81
68
|
snapped: number;
|
|
82
69
|
missing: number;
|
|
83
70
|
short: number;
|
|
71
|
+
trimmed?: number;
|
|
84
72
|
}
|
|
85
73
|
export type QuoteMatch = 'exact' | 'folded' | 'snapped' | 'missing';
|
|
86
74
|
/**
|
|
@@ -94,8 +82,11 @@ export declare function snapQuote(source: string, text: string, within?: {
|
|
|
94
82
|
text: string;
|
|
95
83
|
match: QuoteMatch;
|
|
96
84
|
};
|
|
97
|
-
/**
|
|
98
|
-
|
|
85
|
+
/**
|
|
86
|
+
* A located quote over the word limit keeps its leading words: a prefix of a source span is still verbatim. Trailing
|
|
87
|
+
* clause punctuation goes; unlocated quotes are left for the checker.
|
|
88
|
+
*/
|
|
89
|
+
export declare function trimQuote(text: string, max?: number): string;
|
|
99
90
|
export interface DraftInput {
|
|
100
91
|
revisionId: string;
|
|
101
92
|
markdown: string;
|
|
@@ -126,7 +117,7 @@ export interface DraftTrace {
|
|
|
126
117
|
};
|
|
127
118
|
}
|
|
128
119
|
export interface DraftResult {
|
|
129
|
-
output:
|
|
120
|
+
output: DigestV2;
|
|
130
121
|
inputHash: string;
|
|
131
122
|
producer: Record<string, unknown>;
|
|
132
123
|
options: DigestOptions;
|
|
@@ -136,11 +127,41 @@ export interface DraftResult {
|
|
|
136
127
|
export declare function digestInputHash(input: Pick<DraftInput, 'revisionId' | 'markdown' | 'form' | 'highlights' | 'vocabulary' | 'params' | 'supportThreshold' | 'embed'> & {
|
|
137
128
|
model: ModelIdentity;
|
|
138
129
|
}): string;
|
|
139
|
-
/** Unqualified on real claims: a deliberately low bar that only catches quotes unrelated to their claim. */
|
|
140
|
-
export declare const defaultSupportThreshold = 0.35;
|
|
141
130
|
export declare function draftDigest(input: DraftInput): Promise<DraftResult>;
|
|
131
|
+
/**
|
|
132
|
+
* What `createDigest` needs from a library (a `LibraryStore` satisfies it). Declared here, not imported, so drafting
|
|
133
|
+
* never depends on the store.
|
|
134
|
+
*/
|
|
135
|
+
export interface DigestStore {
|
|
136
|
+
read(itemId: string): {
|
|
137
|
+
revisionId: string;
|
|
138
|
+
markdown: string;
|
|
139
|
+
title: string;
|
|
140
|
+
kind: string;
|
|
141
|
+
} | null;
|
|
142
|
+
annotations: {
|
|
143
|
+
list(itemId: string): {
|
|
144
|
+
kind: string;
|
|
145
|
+
revisionId: string | null;
|
|
146
|
+
anchored?: boolean;
|
|
147
|
+
anchor: unknown;
|
|
148
|
+
}[];
|
|
149
|
+
};
|
|
150
|
+
derivations: {
|
|
151
|
+
find(kind: 'digest', revisionId: string, inputHash: string): Derivation | undefined;
|
|
152
|
+
put(kind: 'digest', input: {
|
|
153
|
+
itemId: string;
|
|
154
|
+
revisionId: string;
|
|
155
|
+
producer: Record<string, unknown>;
|
|
156
|
+
} & DigestCandidate): {
|
|
157
|
+
id: string;
|
|
158
|
+
duplicate: boolean;
|
|
159
|
+
};
|
|
160
|
+
read(kind: 'digest', id: string): Derivation | undefined;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
142
163
|
/** Draft and store a digest for the item's current revision. A matching input hash returns the stored draft without calling the model. */
|
|
143
|
-
export declare function createDigest(store:
|
|
164
|
+
export declare function createDigest(store: DigestStore, itemId: string, model: DigestModel, options?: Omit<DraftInput, 'revisionId' | 'markdown' | 'title' | 'form' | 'model' | 'highlights'>): Promise<{
|
|
144
165
|
derivation: Derivation;
|
|
145
166
|
duplicate: boolean;
|
|
146
167
|
trace?: DraftTrace;
|