@qvac/harness 0.4.0 → 0.5.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/CHANGELOG.md +689 -141
- package/README.md +29 -7
- package/dist/harness.bundle +71 -50
- package/dist-lib/index.d.ts +36 -39
- package/dist-lib/index.js +279 -114
- package/dist-lib/lib/audio-transcode-bare.d.ts +2 -2
- package/dist-lib/lib/audio-transcode-bare.js +28 -18
- package/dist-lib/lib/audio-transcode-node.d.ts +2 -2
- package/dist-lib/lib/capabilities/audio-resample.d.ts +7 -6
- package/dist-lib/lib/capabilities/audio-resample.js +30 -18
- package/dist-lib/lib/capabilities/completion.d.ts +20 -19
- package/dist-lib/lib/capabilities/completion.js +193 -132
- package/dist-lib/lib/capabilities/download.d.ts +6 -6
- package/dist-lib/lib/capabilities/download.js +15 -8
- package/dist-lib/lib/capabilities/embed.js +2 -1
- package/dist-lib/lib/capabilities/enhance.d.ts +6 -1
- package/dist-lib/lib/capabilities/enhance.js +7 -4
- package/dist-lib/lib/capabilities/invoke.js +7 -4
- package/dist-lib/lib/capabilities/kv-cache.js +2 -1
- package/dist-lib/lib/capabilities/preview-model-source.d.ts +9 -7
- package/dist-lib/lib/capabilities/preview-model-source.js +80 -28
- package/dist-lib/lib/capabilities/speech-text.js +5 -4
- package/dist-lib/lib/capabilities/tool-selection.js +10 -9
- package/dist-lib/lib/capabilities/tool-turns.js +30 -16
- package/dist-lib/lib/capabilities/usage-breakdown.js +2 -1
- package/dist-lib/lib/capabilities/voice.d.ts +5 -1
- package/dist-lib/lib/capabilities/voice.js +22 -12
- package/dist-lib/lib/connect.d.ts +11 -32
- package/dist-lib/lib/connect.js +152 -112
- package/dist-lib/lib/context-window.js +25 -21
- package/dist-lib/lib/contract-types.d.ts +22 -15
- package/dist-lib/lib/diagram-repair.d.ts +4 -4
- package/dist-lib/lib/diagram-repair.js +6 -3
- package/dist-lib/lib/docx/index.d.ts +3 -2
- package/dist-lib/lib/{error-fields.d.ts → guards.d.ts} +1 -0
- package/dist-lib/lib/{error-fields.js → guards.js} +3 -0
- package/dist-lib/lib/hardware/capability-probe.js +20 -10
- package/dist-lib/lib/hardware/gpu-classify.js +6 -3
- package/dist-lib/lib/hardware/gpu-probe-addon.js +8 -4
- package/dist-lib/lib/hardware/gpu-probe.js +4 -2
- package/dist-lib/lib/hardware/gpu-stats.native.cjs +8 -9
- package/dist-lib/lib/hardware/parsers.js +8 -4
- package/dist-lib/lib/helpers/buffer-burst.js +4 -2
- package/dist-lib/lib/helpers/control-tokens.js +4 -2
- package/dist-lib/lib/helpers/join-guard.d.ts +2 -2
- package/dist-lib/lib/helpers/join-guard.js +4 -2
- package/dist-lib/lib/helpers/load-stall.js +4 -2
- package/dist-lib/lib/helpers/markup-stream-filter.d.ts +2 -2
- package/dist-lib/lib/helpers/markup-stream-filter.js +6 -3
- package/dist-lib/lib/helpers/race-abort.js +2 -1
- package/dist-lib/lib/helpers/race-timeout.d.ts +5 -0
- package/dist-lib/lib/helpers/race-timeout.js +14 -0
- package/dist-lib/lib/helpers/run-outcome.d.ts +6 -8
- package/dist-lib/lib/helpers/run-outcome.js +36 -20
- package/dist-lib/lib/helpers/spawn-path.js +6 -3
- package/dist-lib/lib/helpers/text-coalescer.js +6 -3
- package/dist-lib/lib/helpers/thinking.js +38 -45
- package/dist-lib/lib/helpers/tool-call-markup.d.ts +9 -7
- package/dist-lib/lib/helpers/tool-call-markup.js +36 -20
- package/dist-lib/lib/helpers/tool-intent.d.ts +3 -2
- package/dist-lib/lib/helpers/tool-intent.js +4 -2
- package/dist-lib/lib/helpers/tool-label.js +18 -9
- package/dist-lib/lib/hooks/built-in/arg-repair.js +23 -13
- package/dist-lib/lib/hooks/built-in/egress.js +2 -1
- package/dist-lib/lib/hooks/built-in/skill-catalog.js +2 -1
- package/dist-lib/lib/hooks/pipeline.d.ts +5 -4
- package/dist-lib/lib/hooks/pipeline.js +6 -3
- package/dist-lib/lib/hooks/run.js +12 -8
- package/dist-lib/lib/model-download-progress.js +10 -8
- package/dist-lib/lib/models/context.d.ts +1 -1
- package/dist-lib/lib/models/context.js +5 -1
- package/dist-lib/lib/models/custom-model-cache.d.ts +10 -1
- package/dist-lib/lib/models/custom-model-cache.js +43 -15
- package/dist-lib/lib/models/gguf-header.d.ts +3 -2
- package/dist-lib/lib/models/gguf-header.js +44 -22
- package/dist-lib/lib/models/idle-unload.d.ts +14 -0
- package/dist-lib/lib/models/idle-unload.js +51 -0
- package/dist-lib/lib/models/kv-cache.d.ts +3 -2
- package/dist-lib/lib/models/kv-cache.js +4 -3
- package/dist-lib/lib/models/llm-presets.d.ts +2 -2
- package/dist-lib/lib/models/llm-presets.js +4 -2
- package/dist-lib/lib/models/model-catalog-constants.js +3 -2
- package/dist-lib/lib/models/model-catalog.d.ts +13 -20
- package/dist-lib/lib/models/model-catalog.js +59 -31
- package/dist-lib/lib/models/model-delete.js +18 -8
- package/dist-lib/lib/models/model-handle.js +2 -1
- package/dist-lib/lib/models/model-list.d.ts +8 -3
- package/dist-lib/lib/models/model-list.js +11 -6
- package/dist-lib/lib/models/model-pool.d.ts +44 -10
- package/dist-lib/lib/models/model-pool.js +47 -42
- package/dist-lib/lib/models/model-source.js +10 -5
- package/dist-lib/lib/models/music-catalog.d.ts +2 -2
- package/dist-lib/lib/models/nmt-catalog.d.ts +4 -3
- package/dist-lib/lib/models/nmt-catalog.js +10 -5
- package/dist-lib/lib/models/opencl-cache.d.ts +6 -1
- package/dist-lib/lib/models/opencl-cache.js +5 -3
- package/dist-lib/lib/models/sdk-faults.d.ts +11 -8
- package/dist-lib/lib/models/sdk-faults.js +9 -6
- package/dist-lib/lib/models/shards.d.ts +11 -0
- package/dist-lib/lib/models/shards.js +15 -0
- package/dist-lib/lib/models/tool-dialect.js +10 -5
- package/dist-lib/lib/no-redirect-fetch-bare.d.ts +3 -3
- package/dist-lib/lib/no-redirect-fetch-bare.js +1 -1
- package/dist-lib/lib/no-redirect-fetch-impl.js +6 -3
- package/dist-lib/lib/no-redirect-fetch-node.d.ts +1 -1
- package/dist-lib/lib/no-redirect-fetch-node.js +9 -9
- package/dist-lib/lib/office/index.d.ts +3 -2
- package/dist-lib/lib/office/python.d.ts +3 -2
- package/dist-lib/lib/office/python.js +2 -1
- package/dist-lib/lib/prompt.d.ts +5 -4
- package/dist-lib/lib/prompt.js +8 -4
- package/dist-lib/lib/queue.js +10 -5
- package/dist-lib/lib/resolution-detector.js +21 -11
- package/dist-lib/lib/rpc-session.js +2 -1
- package/dist-lib/lib/sdk-loader.js +2 -1
- package/dist-lib/lib/sdk-storage.js +4 -2
- package/dist-lib/lib/serve.js +110 -66
- package/dist-lib/lib/spawn.js +7 -4
- package/dist-lib/lib/tmp-path.d.ts +7 -6
- package/dist-lib/lib/tool-call-display.d.ts +2 -2
- package/dist-lib/lib/tools/create-documents.js +18 -10
- package/dist-lib/lib/tools/edit-documents.js +23 -13
- package/dist-lib/lib/tools/edit-image.d.ts +2 -2
- package/dist-lib/lib/tools/edit-image.js +60 -36
- package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +10 -10
- package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +17 -11
- package/dist-lib/lib/tools/exec/adapters/python/attachments.js +53 -40
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +60 -32
- package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.d.ts +33 -22
- package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.js +58 -29
- package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +23 -12
- package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +13 -11
- package/dist-lib/lib/tools/exec/adapters/python/memfs.js +10 -5
- package/dist-lib/lib/tools/exec/adapters/python/net-shim.js +3 -1
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +6 -4
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +20 -10
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +14 -7
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +41 -34
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +316 -166
- package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +9 -8
- package/dist-lib/lib/tools/exec/adapters/python/run-session.js +56 -28
- package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +8 -10
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +22 -11
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +3 -2
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +41 -26
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +27 -18
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +14 -13
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +4 -4
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +10 -5
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +4 -4
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +6 -1
- package/dist-lib/lib/tools/exec/obsidian/cli-process.js +8 -5
- package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +6 -6
- package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
- package/dist-lib/lib/tools/exec/obsidian/command.d.ts +3 -2
- package/dist-lib/lib/tools/exec/obsidian/command.js +6 -3
- package/dist-lib/lib/tools/exec/obsidian/output.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/route.d.ts +4 -6
- package/dist-lib/lib/tools/exec/obsidian/route.js +17 -11
- package/dist-lib/lib/tools/exec/obsidian/safe-path.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/vault-create.js +15 -7
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +2 -2
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +20 -10
- package/dist-lib/lib/tools/exec/obsidian/vault-read.js +20 -13
- package/dist-lib/lib/tools/exec/obsidian/vault-write.js +24 -12
- package/dist-lib/lib/tools/exec/runner.d.ts +14 -14
- package/dist-lib/lib/tools/exec/runner.js +5 -3
- package/dist-lib/lib/tools/exec/scope.js +52 -28
- package/dist-lib/lib/tools/exec/shell-argv.js +31 -18
- package/dist-lib/lib/tools/exec/shell-guidance.d.ts +6 -1
- package/dist-lib/lib/tools/exec/shell-guidance.js +35 -20
- package/dist-lib/lib/tools/exec/video-tools.js +2 -2
- package/dist-lib/lib/tools/exec.d.ts +6 -8
- package/dist-lib/lib/tools/exec.js +113 -54
- package/dist-lib/lib/tools/file-glob.d.ts +4 -5
- package/dist-lib/lib/tools/file-glob.js +16 -11
- package/dist-lib/lib/tools/fs/glob.js +13 -18
- package/dist-lib/lib/tools/fs/remote-protocol.d.ts +10 -10
- package/dist-lib/lib/tools/fs/remote.d.ts +3 -2
- package/dist-lib/lib/tools/fs/remote.js +13 -7
- package/dist-lib/lib/tools/fs/scope.d.ts +8 -3
- package/dist-lib/lib/tools/fs/scope.js +20 -12
- package/dist-lib/lib/tools/fs/walk.js +6 -3
- package/dist-lib/lib/tools/fs/write.d.ts +3 -2
- package/dist-lib/lib/tools/generate-image.d.ts +11 -9
- package/dist-lib/lib/tools/generate-image.js +73 -37
- package/dist-lib/lib/tools/generate-music.d.ts +22 -11
- package/dist-lib/lib/tools/generate-music.js +79 -48
- package/dist-lib/lib/tools/grep.js +66 -41
- package/dist-lib/lib/tools/http-request/encode-fields.js +18 -9
- package/dist-lib/lib/tools/http-request/{utils.js → request.js} +20 -11
- package/dist-lib/lib/tools/http-request/truncate-response.js +57 -46
- package/dist-lib/lib/tools/http-request.d.ts +1 -1
- package/dist-lib/lib/tools/http-request.js +33 -18
- package/dist-lib/lib/tools/mcp/protocol.d.ts +53 -0
- package/dist-lib/lib/tools/mcp/{utils.js → protocol.js} +45 -23
- package/dist-lib/lib/tools/mcp-call.d.ts +1 -1
- package/dist-lib/lib/tools/mcp-call.js +37 -16
- package/dist-lib/lib/tools/operations/builders.js +10 -6
- package/dist-lib/lib/tools/operations/compile.js +20 -10
- package/dist-lib/lib/tools/operations/decoders.js +12 -6
- package/dist-lib/lib/tools/operations/gmail-message.js +3 -2
- package/dist-lib/lib/tools/outbound-guard.d.ts +4 -3
- package/dist-lib/lib/tools/outbound-guard.js +14 -8
- package/dist-lib/lib/tools/private-ip.js +8 -7
- package/dist-lib/lib/tools/rag-search.js +14 -7
- package/dist-lib/lib/tools/read-files.js +23 -20
- package/dist-lib/lib/tools/skill.js +19 -10
- package/dist-lib/lib/tools/skills/auth-resolver.d.ts +11 -18
- package/dist-lib/lib/tools/skills/auth-resolver.js +30 -18
- package/dist-lib/lib/tools/skills/bin-check.d.ts +3 -2
- package/dist-lib/lib/tools/skills/bin-check.js +10 -3
- package/dist-lib/lib/tools/skills/bundled-dir.js +20 -10
- package/dist-lib/lib/tools/skills/bundled-hash.d.ts +3 -2
- package/dist-lib/lib/tools/skills/bundled-hash.js +6 -1
- package/dist-lib/lib/tools/skills/catalog.d.ts +3 -2
- package/dist-lib/lib/tools/skills/catalog.js +33 -28
- package/dist-lib/lib/tools/skills/cli-argv.d.ts +3 -2
- package/dist-lib/lib/tools/skills/cli-argv.js +55 -52
- package/dist-lib/lib/tools/skills/cli-schema-check.js +21 -10
- package/dist-lib/lib/tools/skills/cli-schema-load.js +28 -20
- package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +6 -6
- package/dist-lib/lib/tools/skills/cli-schema.js +2 -1
- package/dist-lib/lib/tools/skills/credential-check.d.ts +6 -3
- package/dist-lib/lib/tools/skills/credential-check.js +24 -12
- package/dist-lib/lib/tools/skills/credential-grants.js +1 -6
- package/dist-lib/lib/tools/skills/credential-health.d.ts +5 -1
- package/dist-lib/lib/tools/skills/credential-health.js +5 -3
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +10 -5
- package/dist-lib/lib/tools/skills/manifest-parse.js +84 -64
- package/dist-lib/lib/tools/skills/mention.js +7 -6
- package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +2 -2
- package/dist-lib/lib/tools/skills/obsidian-readiness.js +11 -3
- package/dist-lib/lib/tools/skills/overlay-crud.d.ts +6 -4
- package/dist-lib/lib/tools/skills/overlay-crud.js +12 -6
- package/dist-lib/lib/tools/skills/overlay-dir.js +4 -2
- package/dist-lib/lib/tools/skills/overlay-watch.d.ts +3 -2
- package/dist-lib/lib/tools/skills/overlay-watch.js +8 -4
- package/dist-lib/lib/tools/skills/setup-routes.js +1 -3
- package/dist-lib/lib/tools/skills/skill-settings.js +4 -1
- package/dist-lib/lib/tools/skills/skill-state.d.ts +6 -11
- package/dist-lib/lib/tools/skills/skill-state.js +48 -29
- package/dist-lib/lib/tools/skills/tool-grants.js +6 -3
- package/dist-lib/lib/tools/toolsets.js +2 -1
- package/dist-lib/lib/tools/translate.d.ts +4 -5
- package/dist-lib/lib/tools/translate.js +31 -14
- package/dist-lib/lib/tools/url-guard.js +2 -1
- package/dist-lib/lib/tools/weather-lookup/place.js +8 -4
- package/dist-lib/lib/tools/weather-lookup/report.d.ts +7 -1
- package/dist-lib/lib/tools/weather-lookup/report.js +46 -9
- package/dist-lib/lib/tools/weather-lookup.js +18 -12
- package/dist-lib/lib/tools/web-fetch.js +47 -24
- package/dist-lib/lib/tools/web-search.js +8 -3
- package/dist-lib/lib/validating-lookup.d.ts +4 -4
- package/dist-lib/lib/wav-encode.d.ts +1 -1
- package/dist-lib/lib/wav-encode.js +11 -10
- package/dist-lib/lib/web-fetch/embedded-state.js +24 -12
- package/dist-lib/lib/web-fetch/extract.js +4 -2
- package/dist-lib/lib/web-fetch/images.js +8 -4
- package/dist-lib/lib/web-fetch/video.d.ts +2 -2
- package/dist-lib/lib/web-fetch/video.js +8 -4
- package/dist-lib/lib/web-search/engine-registry.d.ts +2 -2
- package/dist-lib/lib/web-search/engines/aol.js +1 -1
- package/dist-lib/lib/web-search/engines/bing.js +1 -1
- package/dist-lib/lib/web-search/engines/brave.js +4 -1
- package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -2
- package/dist-lib/lib/web-search/engines/google.js +7 -3
- package/dist-lib/lib/web-search/engines/wikipedia.js +5 -4
- package/dist-lib/lib/web-search/engines/yahoo.js +1 -1
- package/dist-lib/lib/web-search/fetch-html.d.ts +5 -4
- package/dist-lib/lib/web-search/fetch-html.js +13 -7
- package/dist-lib/lib/web-search/orchestrator.d.ts +9 -5
- package/dist-lib/lib/web-search/orchestrator.js +3 -3
- package/dist-lib/lib/wire.d.ts +3 -2
- package/dist-lib/lib/wire.js +23 -15
- package/dist-lib/schema/baseline.js +10 -5
- package/dist-lib/schema/build.js +2 -1
- package/dist-lib/schema/harness.d.ts +15 -2
- package/dist-lib/schema/harness.js +14 -2
- package/dist-lib/schema/release-tags.d.ts +3 -2
- package/dist-lib/schema/release-tags.js +6 -3
- package/dist-lib/spec/bind.js +3 -0
- package/dist-lib/spec/calls.js +1 -0
- package/dist-lib/spec/hrpc/hrpc.json +13 -0
- package/dist-lib/spec/hrpc/index.js +15 -3
- package/dist-lib/spec/hrpc/messages.js +39 -8
- package/dist-lib/spec/hyperschema/index.js +39 -8
- package/dist-lib/spec/hyperschema/schema.json +30 -1
- package/dist-lib/spec/hyperschema/types.d.ts +9 -1
- package/package.json +13 -14
- package/worker/harness-sidecar.mjs +15 -22
- package/worker/stow-entry.mjs +7 -4
- package/dist-lib/lib/tools/mcp/utils.d.ts +0 -47
- /package/dist-lib/lib/tools/http-request/{utils.d.ts → request.d.ts} +0 -0
|
@@ -5,8 +5,9 @@ function isTurnBoundary(message) {
|
|
|
5
5
|
}
|
|
6
6
|
export function contextCandidates(history) {
|
|
7
7
|
const { prefix, turns } = splitTurns(history);
|
|
8
|
-
if (!turns.length)
|
|
8
|
+
if (!turns.length) {
|
|
9
9
|
return [{ history, droppedTurns: 0 }];
|
|
10
|
+
}
|
|
10
11
|
const maxDropped = Math.max(0, turns.length - 1);
|
|
11
12
|
const candidates = dropCounts(maxDropped).map((droppedTurns) => ({
|
|
12
13
|
history: droppedTurns ? [...prefix, ...turns.slice(droppedTurns).flat()] : history,
|
|
@@ -17,57 +18,60 @@ export function contextCandidates(history) {
|
|
|
17
18
|
}
|
|
18
19
|
function splitTurns(history) {
|
|
19
20
|
const firstUser = history.findIndex(isTurnBoundary);
|
|
20
|
-
if (firstUser === -1)
|
|
21
|
+
if (firstUser === -1) {
|
|
21
22
|
return { prefix: history, turns: [] };
|
|
23
|
+
}
|
|
22
24
|
const prefix = history.slice(0, firstUser);
|
|
23
25
|
const starts = [];
|
|
24
|
-
for (
|
|
25
|
-
if (isTurnBoundary(
|
|
26
|
+
for (const [i, message] of history.entries()) {
|
|
27
|
+
if (i >= firstUser && isTurnBoundary(message)) {
|
|
26
28
|
starts.push(i);
|
|
29
|
+
}
|
|
27
30
|
}
|
|
28
31
|
const turns = starts.map((start, index) => history.slice(start, starts[index + 1]));
|
|
29
32
|
return { prefix, turns };
|
|
30
33
|
}
|
|
31
34
|
function dropCounts(max) {
|
|
32
35
|
const counts = [0];
|
|
33
|
-
|
|
36
|
+
let last = 0;
|
|
37
|
+
for (let step = 1; last < max; step *= 2) {
|
|
34
38
|
const next = Math.min(max, step);
|
|
35
|
-
if (next
|
|
36
|
-
|
|
39
|
+
if (next === last) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
counts.push(next);
|
|
43
|
+
last = next;
|
|
37
44
|
}
|
|
38
45
|
return counts;
|
|
39
46
|
}
|
|
40
47
|
function appendToolCompactions(candidates) {
|
|
41
48
|
const last = candidates[candidates.length - 1];
|
|
42
|
-
if (!last)
|
|
49
|
+
if (!last) {
|
|
43
50
|
return;
|
|
51
|
+
}
|
|
44
52
|
const tools = compactableTools(last.history);
|
|
45
53
|
let history = last.history;
|
|
46
54
|
while (true) {
|
|
47
55
|
const selected = longestTool(tools);
|
|
48
|
-
if (!selected)
|
|
56
|
+
if (!selected) {
|
|
49
57
|
return;
|
|
58
|
+
}
|
|
50
59
|
selected.target = Math.max(TOOL_RESULT_TRUNCATION_MARKER.length, Math.floor(selected.target / 2));
|
|
51
60
|
history = history.map(compactTool.bind(null, selected));
|
|
52
61
|
candidates.push({ history, droppedTurns: last.droppedTurns });
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
function compactableTools(history) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!isTurnBoundary(history[index]))
|
|
59
|
-
continue;
|
|
60
|
-
newestUser = index;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
if (newestUser === -1)
|
|
65
|
+
const newestUser = history.findLastIndex(isTurnBoundary);
|
|
66
|
+
if (newestUser === -1) {
|
|
64
67
|
return [];
|
|
68
|
+
}
|
|
65
69
|
const tools = [];
|
|
66
|
-
for (
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
for (const [index, message] of history.entries()) {
|
|
71
|
+
if (index <= newestUser || message.role !== 'tool')
|
|
72
|
+
continue;
|
|
73
|
+
if (message.content.length <= TOOL_RESULT_TRUNCATION_MARKER.length)
|
|
69
74
|
continue;
|
|
70
|
-
}
|
|
71
75
|
tools.push({ index, original: message.content, target: message.content.length });
|
|
72
76
|
}
|
|
73
77
|
return tools;
|
|
@@ -165,6 +165,24 @@ export interface CapabilityInfo {
|
|
|
165
165
|
recommendedModelName: string;
|
|
166
166
|
memoryBudget?: MemoryBudget;
|
|
167
167
|
}
|
|
168
|
+
export interface CredentialEntry {
|
|
169
|
+
key: string;
|
|
170
|
+
token?: string | null;
|
|
171
|
+
expiresAt?: number | null;
|
|
172
|
+
agentId?: string | null;
|
|
173
|
+
skill?: string | null;
|
|
174
|
+
}
|
|
175
|
+
export interface SkillsOptions {
|
|
176
|
+
readonly refresh?: boolean;
|
|
177
|
+
readonly skipCredentialProbe?: boolean;
|
|
178
|
+
}
|
|
179
|
+
export interface SkillWriteResult {
|
|
180
|
+
ok: boolean;
|
|
181
|
+
}
|
|
182
|
+
export interface InfraModel {
|
|
183
|
+
name: string;
|
|
184
|
+
addon: string;
|
|
185
|
+
}
|
|
168
186
|
export interface HarnessContract {
|
|
169
187
|
completion(context: CompletionContext): AsyncIterable<HarnessEvent>;
|
|
170
188
|
invoke?(context: InvokeContext): AsyncIterable<HarnessEvent>;
|
|
@@ -183,24 +201,16 @@ export interface HarnessContract {
|
|
|
183
201
|
suspend?(): Promise<void> | void;
|
|
184
202
|
wakeup?(): Promise<void> | void;
|
|
185
203
|
resume?(): Promise<void> | void;
|
|
186
|
-
skills?(agentId?: string | null, modelName?: string | null, options?:
|
|
187
|
-
readonly refresh?: boolean;
|
|
188
|
-
readonly skipCredentialProbe?: boolean;
|
|
189
|
-
}): Promise<ResolvedSkillCatalogEntry[]>;
|
|
204
|
+
skills?(agentId?: string | null, modelName?: string | null, options?: SkillsOptions): Promise<ResolvedSkillCatalogEntry[]>;
|
|
190
205
|
tools?(): Promise<ToolCatalogEntry[]>;
|
|
191
|
-
setCredentials?(entries: ReadonlyArray<
|
|
192
|
-
key: string;
|
|
193
|
-
token?: string | null;
|
|
194
|
-
expiresAt?: number | null;
|
|
195
|
-
agentId?: string | null;
|
|
196
|
-
skill?: string | null;
|
|
197
|
-
}>): void | Promise<void>;
|
|
206
|
+
setCredentials?(entries: ReadonlyArray<CredentialEntry>): void | Promise<void>;
|
|
198
207
|
setSkillSettings?(entries: ReadonlyArray<{
|
|
199
208
|
skill: string;
|
|
200
209
|
key: string;
|
|
201
210
|
value: string;
|
|
202
211
|
agentId?: string | null;
|
|
203
212
|
}>): void | Promise<void>;
|
|
213
|
+
setModelIdleTimeout?(ms: number): void | Promise<void>;
|
|
204
214
|
listManagedSkills?(): Promise<ManagedSkill[]>;
|
|
205
215
|
readSkillFile?(name: string): Promise<SkillFileContent | null>;
|
|
206
216
|
writeSkillFile?(name: string, content: string): Promise<{
|
|
@@ -217,10 +227,7 @@ export interface HarnessContract {
|
|
|
217
227
|
deleteModel?(name: string): Promise<DeleteModelSummary>;
|
|
218
228
|
clearKvCache?(): Promise<KvCacheDeletionResult>;
|
|
219
229
|
deleteKvCache?(kvCacheKey: string): Promise<KvCacheDeletionResult>;
|
|
220
|
-
infraModels?(profile: string): Promise<ReadonlyArray<
|
|
221
|
-
name: string;
|
|
222
|
-
addon: string;
|
|
223
|
-
}>>;
|
|
230
|
+
infraModels?(profile: string): Promise<ReadonlyArray<InfraModel>>;
|
|
224
231
|
setCustomModels?(entries: ReadonlyArray<CustomModelEntry>): void | Promise<void>;
|
|
225
232
|
previewModelSource?(context: PreviewModelSourceContext): Promise<ModelSourcePreview>;
|
|
226
233
|
capability?(): Promise<CapabilityInfo>;
|
|
@@ -4,18 +4,18 @@ export declare function diagramRepairPromptCount(content: string, parentRunId?:
|
|
|
4
4
|
export declare function isDiagramRepairPrompt(content: string): boolean;
|
|
5
5
|
export declare function completeMermaidDiagramCount(content: string): number;
|
|
6
6
|
export declare function diagramRepairAccepted(text: string): boolean;
|
|
7
|
-
|
|
7
|
+
interface DiagramRepairRecord {
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly seq: number;
|
|
10
10
|
readonly runId?: string | null;
|
|
11
11
|
readonly parentId?: string | null;
|
|
12
|
-
}
|
|
13
|
-
export
|
|
12
|
+
}
|
|
13
|
+
export interface DiagramRepairLink {
|
|
14
14
|
readonly expectedCount: number;
|
|
15
15
|
readonly parentId: string;
|
|
16
16
|
readonly promptId: string;
|
|
17
17
|
readonly promptText: string;
|
|
18
18
|
readonly runId: string;
|
|
19
|
-
}
|
|
19
|
+
}
|
|
20
20
|
export declare function diagramRepairLinks<T extends DiagramRepairRecord>(records: ReadonlyArray<T>, textOf: (record: T) => string | null): ReadonlyArray<DiagramRepairLink>;
|
|
21
21
|
export {};
|
|
@@ -3,8 +3,9 @@ export const DIAGRAM_REPAIR_PROMPT_SUFFIX = 'Rewrite the complete previous answe
|
|
|
3
3
|
'Common fixes: put every label with spaces or punctuation in double quotes like A["Send (HTTP)"]; never use lowercase end as a node label - write "End"; the first line inside the fence must be the diagram type; close the fence before any prose - never leave a sentence inside it; give every node a unique id.';
|
|
4
4
|
export function diagramRepairPromptCount(content, parentRunId) {
|
|
5
5
|
const match = /^<!-- qvac:diagram-repair:(\d+):([^\s>]+) -->\n(\d+) Mermaid diagram(?:s)? in your previous answer fail(?:s)? to render\.\n/.exec(content);
|
|
6
|
-
if (!match || !content.endsWith(`\n\n${DIAGRAM_REPAIR_PROMPT_SUFFIX}`))
|
|
6
|
+
if (!match || !content.endsWith(`\n\n${DIAGRAM_REPAIR_PROMPT_SUFFIX}`)) {
|
|
7
7
|
return null;
|
|
8
|
+
}
|
|
8
9
|
const expected = Number(match[1]);
|
|
9
10
|
return Number.isSafeInteger(expected) &&
|
|
10
11
|
expected > 0 &&
|
|
@@ -31,8 +32,9 @@ export function diagramRepairLinks(records, textOf) {
|
|
|
31
32
|
if (!child.runId || !child.parentId)
|
|
32
33
|
return [];
|
|
33
34
|
const parent = byId.get(child.parentId);
|
|
34
|
-
if (!parent?.runId)
|
|
35
|
+
if (!parent?.runId) {
|
|
35
36
|
return [];
|
|
37
|
+
}
|
|
36
38
|
const prompt = [...ordered]
|
|
37
39
|
.reverse()
|
|
38
40
|
.find((candidate) => candidate.seq > parent.seq &&
|
|
@@ -41,8 +43,9 @@ export function diagramRepairLinks(records, textOf) {
|
|
|
41
43
|
diagramRepairPromptCount(textOf(candidate) ?? '', parent.runId ?? undefined) !== null);
|
|
42
44
|
const promptText = prompt ? textOf(prompt) : null;
|
|
43
45
|
const expectedCount = diagramRepairPromptCount(promptText ?? '', parent.runId);
|
|
44
|
-
if (prompt)
|
|
46
|
+
if (prompt) {
|
|
45
47
|
used.add(prompt.id);
|
|
48
|
+
}
|
|
46
49
|
return prompt && promptText && expectedCount
|
|
47
50
|
? [
|
|
48
51
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AbortSignal } from 'bare-abort-controller';
|
|
2
2
|
export { closePythonWorker as closeDocxWorker } from '../tools/exec/adapters/python/worker/client.ts';
|
|
3
|
-
export
|
|
3
|
+
export interface DocxExtractOptions {
|
|
4
4
|
readonly signal?: AbortSignal;
|
|
5
|
-
}
|
|
5
|
+
}
|
|
6
|
+
export declare function extractDocxText(bytes: Uint8Array, fileName: string, options?: DocxExtractOptions): Promise<string>;
|
|
@@ -13,8 +13,9 @@ function pickTier(availableBytes) {
|
|
|
13
13
|
return 'xhigh';
|
|
14
14
|
if (availableBytes >= 30 * GIB)
|
|
15
15
|
return 'high';
|
|
16
|
-
if (availableBytes >= 8 * GIB)
|
|
16
|
+
if (availableBytes >= 8 * GIB) {
|
|
17
17
|
return 'mid';
|
|
18
|
+
}
|
|
18
19
|
return 'low';
|
|
19
20
|
}
|
|
20
21
|
function tierProfile(budget) {
|
|
@@ -38,8 +39,9 @@ function recommend(budget) {
|
|
|
38
39
|
async function probeSysfs(reads) {
|
|
39
40
|
for (const path of SYSFS_VRAM_PATHS) {
|
|
40
41
|
const raw = await reads.readFile(path);
|
|
41
|
-
if (!raw)
|
|
42
|
+
if (!raw) {
|
|
42
43
|
continue;
|
|
44
|
+
}
|
|
43
45
|
const bytes = Number.parseInt(raw.trim(), 10);
|
|
44
46
|
if (!Number.isNaN(bytes) && bytes > 0) {
|
|
45
47
|
return { totalBytes: bytes, availableBytes: bytes, source: 'vram' };
|
|
@@ -50,25 +52,31 @@ async function probeSysfs(reads) {
|
|
|
50
52
|
async function probeDesktop(reads) {
|
|
51
53
|
const ram = reads.totalmem();
|
|
52
54
|
const addon = probeWithAddon(await reads.readGpuStats(), ram);
|
|
53
|
-
if (addon && addon.source === 'vram')
|
|
55
|
+
if (addon && addon.source === 'vram') {
|
|
54
56
|
return addon;
|
|
57
|
+
}
|
|
55
58
|
const nvidia = await reads.run('nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits');
|
|
56
59
|
const nvidiaBudget = nvidia ? parseNvidiaSmiOutput(nvidia) : null;
|
|
57
|
-
if (nvidiaBudget)
|
|
60
|
+
if (nvidiaBudget) {
|
|
58
61
|
return nvidiaBudget;
|
|
62
|
+
}
|
|
59
63
|
const rocm = await reads.run('rocm-smi --showmeminfo vram');
|
|
60
64
|
const rocmBudget = rocm ? parseRocmSmiOutput(rocm) : null;
|
|
61
|
-
if (rocmBudget)
|
|
65
|
+
if (rocmBudget) {
|
|
62
66
|
return rocmBudget;
|
|
67
|
+
}
|
|
63
68
|
const sysfs = await probeSysfs(reads);
|
|
64
|
-
if (sysfs)
|
|
69
|
+
if (sysfs) {
|
|
65
70
|
return sysfs;
|
|
71
|
+
}
|
|
66
72
|
const registry = await reads.run(`powershell -Command "${WINDOWS_REGISTRY_QUERY}"`);
|
|
67
73
|
const registryBudget = registry ? parseWindowsRegistryOutput(registry, ram) : null;
|
|
68
|
-
if (registryBudget)
|
|
74
|
+
if (registryBudget) {
|
|
69
75
|
return registryBudget;
|
|
70
|
-
|
|
76
|
+
}
|
|
77
|
+
if (addon) {
|
|
71
78
|
return addon;
|
|
79
|
+
}
|
|
72
80
|
return { ...sharedRamBudget(ram), source: 'no-gpu' };
|
|
73
81
|
}
|
|
74
82
|
async function isPixel(reads) {
|
|
@@ -77,10 +85,12 @@ async function isPixel(reads) {
|
|
|
77
85
|
}
|
|
78
86
|
async function probeMemoryBudget(reads) {
|
|
79
87
|
const os = reads.platform();
|
|
80
|
-
if (os === 'android' || os === 'ios')
|
|
88
|
+
if (os === 'android' || os === 'ios') {
|
|
81
89
|
return mobileBudget(reads.totalmem(), await isPixel(reads));
|
|
82
|
-
|
|
90
|
+
}
|
|
91
|
+
if (os === 'darwin') {
|
|
83
92
|
return sharedRamBudget(reads.totalmem());
|
|
93
|
+
}
|
|
84
94
|
return probeDesktop(reads);
|
|
85
95
|
}
|
|
86
96
|
function forcedProfile() {
|
|
@@ -19,14 +19,17 @@ const INTEGRATED_GPU = [
|
|
|
19
19
|
];
|
|
20
20
|
const SOFTWARE_GPU = [/llvmpipe/i, /swrast/i, /mesa/i];
|
|
21
21
|
export function classifyGpu(name) {
|
|
22
|
-
for (const re of DISCRETE_GPU)
|
|
22
|
+
for (const re of DISCRETE_GPU) {
|
|
23
23
|
if (re.test(name))
|
|
24
24
|
return 'discrete';
|
|
25
|
-
|
|
25
|
+
}
|
|
26
|
+
for (const re of INTEGRATED_GPU) {
|
|
26
27
|
if (re.test(name))
|
|
27
28
|
return 'integrated';
|
|
28
|
-
|
|
29
|
+
}
|
|
30
|
+
for (const re of SOFTWARE_GPU) {
|
|
29
31
|
if (re.test(name))
|
|
30
32
|
return 'software';
|
|
33
|
+
}
|
|
31
34
|
return 'integrated';
|
|
32
35
|
}
|
|
@@ -12,8 +12,9 @@ const StatsSchema = z.object({
|
|
|
12
12
|
function classifyBestDevice(devices, systemRamBytes) {
|
|
13
13
|
for (const device of devices) {
|
|
14
14
|
const cls = classifyGpu(device.name);
|
|
15
|
-
if (cls === 'software')
|
|
15
|
+
if (cls === 'software') {
|
|
16
16
|
continue;
|
|
17
|
+
}
|
|
17
18
|
if (cls === 'discrete') {
|
|
18
19
|
const vram = device.videoMemoryBytes;
|
|
19
20
|
if (vram > systemRamBytes * IGPU_LIE_THRESHOLD) {
|
|
@@ -26,15 +27,18 @@ function classifyBestDevice(devices, systemRamBytes) {
|
|
|
26
27
|
}
|
|
27
28
|
export function probeWithAddon(rawStats, systemRamBytes) {
|
|
28
29
|
const parsed = StatsSchema.safeParse(rawStats);
|
|
29
|
-
if (!parsed.success)
|
|
30
|
+
if (!parsed.success) {
|
|
30
31
|
return null;
|
|
32
|
+
}
|
|
31
33
|
const devices = parsed.data.gpu?.devices ?? [];
|
|
32
|
-
if (devices.length === 0)
|
|
34
|
+
if (devices.length === 0) {
|
|
33
35
|
return null;
|
|
36
|
+
}
|
|
34
37
|
const totalRamBytes = parsed.data.memory?.totalBytes ?? systemRamBytes;
|
|
35
38
|
const best = classifyBestDevice(devices, totalRamBytes);
|
|
36
|
-
if (best)
|
|
39
|
+
if (best) {
|
|
37
40
|
return best;
|
|
41
|
+
}
|
|
38
42
|
if (devices.every((device) => classifyGpu(device.name) === 'software')) {
|
|
39
43
|
return { ...sharedRamBudget(totalRamBytes), source: 'software' };
|
|
40
44
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import b4a from 'b4a';
|
|
1
2
|
import { spawn } from 'child_process';
|
|
2
3
|
import os from 'os';
|
|
3
4
|
import { readSystemStats } from '#hw-gpu-stats';
|
|
@@ -11,8 +12,9 @@ export function runGpuProbeIfRequested() {
|
|
|
11
12
|
}
|
|
12
13
|
export function parseGpuProbeOutput(output) {
|
|
13
14
|
const line = output.trim().split('\n').at(-1) ?? '';
|
|
14
|
-
if (line.length === 0)
|
|
15
|
+
if (line.length === 0) {
|
|
15
16
|
return null;
|
|
17
|
+
}
|
|
16
18
|
try {
|
|
17
19
|
const parsed = JSON.parse(line);
|
|
18
20
|
return typeof parsed === 'object' ? parsed : null;
|
|
@@ -32,7 +34,7 @@ export function spawnGpuProbe(entry = Bare.argv[1]) {
|
|
|
32
34
|
resolve({ ok: false, stats: null });
|
|
33
35
|
}, TIMEOUT_MS);
|
|
34
36
|
child.stdout?.on('data', (chunk) => {
|
|
35
|
-
output +=
|
|
37
|
+
output += b4a.toString(chunk);
|
|
36
38
|
});
|
|
37
39
|
child.stderr?.on('data', () => { });
|
|
38
40
|
child.on('error', () => {
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
const os = require('os')
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
// second LLVM) into whichever process imports it
|
|
3
|
+
// lazy: the addon drags the graphics stack (and on Linux a second LLVM) into its importer
|
|
5
4
|
let GPUInfo
|
|
6
5
|
|
|
7
|
-
//
|
|
8
|
-
// device's name and VRAM total, plus system RAM to catch integrated-GPU lies.
|
|
6
|
+
// system RAM is here to catch integrated-GPU lies
|
|
9
7
|
exports.readSystemStats = function readSystemStats() {
|
|
10
8
|
try {
|
|
11
9
|
GPUInfo ??= require('bare-gpu-info')
|
|
12
10
|
const info = new GPUInfo()
|
|
13
11
|
try {
|
|
14
|
-
const devices = []
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
const devices = [...info]
|
|
13
|
+
.filter((gpu) => typeof gpu.memory === 'number' && gpu.name)
|
|
14
|
+
.map((gpu) => ({ name: gpu.name, videoMemoryBytes: gpu.memory }))
|
|
15
|
+
if (devices.length === 0) {
|
|
16
|
+
return null
|
|
18
17
|
}
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
return { memory: { totalBytes: os.totalmem() }, gpu: { devices } }
|
|
21
20
|
} finally {
|
|
22
21
|
info.destroy()
|
|
@@ -7,25 +7,29 @@ export const IGPU_LIE_THRESHOLD = 0.9;
|
|
|
7
7
|
export function parseNvidiaSmiOutput(stdout) {
|
|
8
8
|
const firstLine = stdout.split('\n')[0] ?? '';
|
|
9
9
|
const mib = Number.parseInt(firstLine, 10);
|
|
10
|
-
if (Number.isNaN(mib) || mib <= 0)
|
|
10
|
+
if (Number.isNaN(mib) || mib <= 0) {
|
|
11
11
|
return null;
|
|
12
|
+
}
|
|
12
13
|
const bytes = mib * 1024 * 1024;
|
|
13
14
|
return { totalBytes: bytes, availableBytes: bytes, source: 'vram', gpuClass: 'discrete' };
|
|
14
15
|
}
|
|
15
16
|
export function parseRocmSmiOutput(stdout) {
|
|
16
17
|
const match = /Total.*?:\s*(\d+)/i.exec(stdout);
|
|
17
|
-
if (!match)
|
|
18
|
+
if (!match) {
|
|
18
19
|
return null;
|
|
20
|
+
}
|
|
19
21
|
const bytes = Number.parseInt(match[1] ?? '', 10);
|
|
20
|
-
if (Number.isNaN(bytes) || bytes <= 0)
|
|
22
|
+
if (Number.isNaN(bytes) || bytes <= 0) {
|
|
21
23
|
return null;
|
|
24
|
+
}
|
|
22
25
|
return { totalBytes: bytes, availableBytes: bytes, source: 'vram' };
|
|
23
26
|
}
|
|
24
27
|
export function parseWindowsRegistryOutput(stdout, systemRamBytes) {
|
|
25
28
|
const firstLine = stdout.split('\n')[0] ?? '';
|
|
26
29
|
const bytes = Number.parseInt(firstLine, 10);
|
|
27
|
-
if (Number.isNaN(bytes) || bytes <= 0)
|
|
30
|
+
if (Number.isNaN(bytes) || bytes <= 0) {
|
|
28
31
|
return null;
|
|
32
|
+
}
|
|
29
33
|
if (bytes > systemRamBytes * IGPU_LIE_THRESHOLD) {
|
|
30
34
|
return { ...sharedRamBudget(systemRamBytes), source: 'integrated' };
|
|
31
35
|
}
|
|
@@ -7,14 +7,16 @@ export async function* bufferBurst(tokens, ms) {
|
|
|
7
7
|
continue;
|
|
8
8
|
}
|
|
9
9
|
if (Date.now() >= deadline) {
|
|
10
|
-
if (burst)
|
|
10
|
+
if (burst) {
|
|
11
11
|
yield burst;
|
|
12
|
+
}
|
|
12
13
|
burst = null;
|
|
13
14
|
yield token;
|
|
14
15
|
continue;
|
|
15
16
|
}
|
|
16
17
|
burst += token;
|
|
17
18
|
}
|
|
18
|
-
if (burst)
|
|
19
|
+
if (burst) {
|
|
19
20
|
yield burst;
|
|
21
|
+
}
|
|
20
22
|
}
|
|
@@ -19,14 +19,16 @@ export async function* stopAtControlToken(tokens, onStop) {
|
|
|
19
19
|
const safe = scanner({ stop: STOP_MARKERS });
|
|
20
20
|
for await (const token of tokens) {
|
|
21
21
|
const shown = safe.push(token);
|
|
22
|
-
if (shown)
|
|
22
|
+
if (shown) {
|
|
23
23
|
yield shown;
|
|
24
|
+
}
|
|
24
25
|
if (safe.stopped !== null) {
|
|
25
26
|
onStop?.(safe.stopped);
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
const rest = safe.flush();
|
|
30
|
-
if (rest)
|
|
31
|
+
if (rest) {
|
|
31
32
|
yield rest;
|
|
33
|
+
}
|
|
32
34
|
}
|
|
@@ -30,8 +30,9 @@ export function createJoinGuard(markers) {
|
|
|
30
30
|
function mend(text, at, markers) {
|
|
31
31
|
for (;;) {
|
|
32
32
|
const found = spanning(text, at, markers);
|
|
33
|
-
if (found === null)
|
|
33
|
+
if (found === null) {
|
|
34
34
|
return { text, at };
|
|
35
|
+
}
|
|
35
36
|
text = text.slice(0, found.index) + text.slice(found.index + found.marker.length);
|
|
36
37
|
at = found.index;
|
|
37
38
|
}
|
|
@@ -39,8 +40,9 @@ function mend(text, at, markers) {
|
|
|
39
40
|
function spanning(text, at, markers) {
|
|
40
41
|
for (const marker of markers) {
|
|
41
42
|
const index = text.indexOf(marker, Math.max(0, at - marker.length + 1));
|
|
42
|
-
if (index !== -1 && index < at)
|
|
43
|
+
if (index !== -1 && index < at) {
|
|
43
44
|
return { index, marker };
|
|
45
|
+
}
|
|
44
46
|
}
|
|
45
47
|
return null;
|
|
46
48
|
}
|
|
@@ -5,8 +5,9 @@ export function createLoadStall(ms, message) {
|
|
|
5
5
|
rejectStall = reject;
|
|
6
6
|
});
|
|
7
7
|
const arm = () => {
|
|
8
|
-
if (timer !== null)
|
|
8
|
+
if (timer !== null) {
|
|
9
9
|
clearTimeout(timer);
|
|
10
|
+
}
|
|
10
11
|
timer = setTimeout(() => {
|
|
11
12
|
rejectStall?.(new Error(message));
|
|
12
13
|
}, ms);
|
|
@@ -15,8 +16,9 @@ export function createLoadStall(ms, message) {
|
|
|
15
16
|
return {
|
|
16
17
|
bump: arm,
|
|
17
18
|
clear: () => {
|
|
18
|
-
if (timer !== null)
|
|
19
|
+
if (timer !== null) {
|
|
19
20
|
clearTimeout(timer);
|
|
21
|
+
}
|
|
20
22
|
timer = null;
|
|
21
23
|
},
|
|
22
24
|
promise
|
|
@@ -22,8 +22,9 @@ export function createMarkupStreamFilter() {
|
|
|
22
22
|
for (;;) {
|
|
23
23
|
const step = state.closer ? consumeSuppressed(state) : emitUntilOpener(state);
|
|
24
24
|
out += step.out;
|
|
25
|
-
if (step.done)
|
|
25
|
+
if (step.done) {
|
|
26
26
|
return out;
|
|
27
|
+
}
|
|
27
28
|
}
|
|
28
29
|
},
|
|
29
30
|
flush() {
|
|
@@ -52,8 +53,9 @@ function dropResumeNewline(state) {
|
|
|
52
53
|
if (!state.stripNewline || state.buffer.length === 0)
|
|
53
54
|
return;
|
|
54
55
|
state.stripNewline = false;
|
|
55
|
-
if (state.buffer[0] === '\n')
|
|
56
|
+
if (state.buffer[0] === '\n') {
|
|
56
57
|
state.buffer = state.buffer.slice(1);
|
|
58
|
+
}
|
|
57
59
|
}
|
|
58
60
|
function emitUntilOpener(state) {
|
|
59
61
|
dropResumeNewline(state);
|
|
@@ -63,8 +65,9 @@ function emitUntilOpener(state) {
|
|
|
63
65
|
state.guard.cut();
|
|
64
66
|
state.buffer = state.buffer.slice(marker.index + marker.marker.length);
|
|
65
67
|
const closer = MARKUP_CLOSERS[marker.marker];
|
|
66
|
-
if (closer === undefined)
|
|
68
|
+
if (closer === undefined) {
|
|
67
69
|
state.stripNewline = true;
|
|
70
|
+
}
|
|
68
71
|
state.closer = closer ?? null;
|
|
69
72
|
return { out, done: false };
|
|
70
73
|
}
|
|
@@ -8,8 +8,9 @@ export class AbortedError extends Error {
|
|
|
8
8
|
export function raceAbort(promise, signal) {
|
|
9
9
|
if (!signal)
|
|
10
10
|
return promise;
|
|
11
|
-
if (signal.aborted)
|
|
11
|
+
if (signal.aborted) {
|
|
12
12
|
return Promise.reject(new AbortedError());
|
|
13
|
+
}
|
|
13
14
|
return new Promise((resolve, reject) => {
|
|
14
15
|
const onAbort = () => reject(new AbortedError());
|
|
15
16
|
signal.addEventListener('abort', onAbort, { once: true });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export async function raceTimeout(pending, { ms, fallback }) {
|
|
2
|
+
let timer = null;
|
|
3
|
+
const expired = new Promise((resolve) => {
|
|
4
|
+
timer = setTimeout(() => resolve(fallback), ms);
|
|
5
|
+
});
|
|
6
|
+
try {
|
|
7
|
+
return await Promise.race([pending, expired]);
|
|
8
|
+
}
|
|
9
|
+
finally {
|
|
10
|
+
if (timer !== null) {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -9,6 +9,10 @@ export interface RunOutcomeFacts {
|
|
|
9
9
|
readonly latestFailure: string | null;
|
|
10
10
|
readonly confirmedWrites: ReadonlyArray<string>;
|
|
11
11
|
}
|
|
12
|
+
export interface HistoryTurn {
|
|
13
|
+
readonly role: string;
|
|
14
|
+
readonly content: string;
|
|
15
|
+
}
|
|
12
16
|
export interface RunOutcomeTracker {
|
|
13
17
|
readonly confirmedWrites: string[];
|
|
14
18
|
beginRound(): void;
|
|
@@ -20,14 +24,8 @@ export interface RunOutcomeTracker {
|
|
|
20
24
|
export declare function createRunOutcomeTracker(): RunOutcomeTracker;
|
|
21
25
|
export declare function normalizeToolExecutionOutcome(result: unknown, outcome: ToolExecutionOutcome): ToolExecutionOutcome;
|
|
22
26
|
export declare function failureFromToolExecution(result: unknown, outcome: ToolExecutionOutcome): string | null;
|
|
23
|
-
export declare function degenerateAnswer(outcome: Exclude<RunOutcome, 'answered'>, history: ReadonlyArray<
|
|
24
|
-
|
|
25
|
-
content: string;
|
|
26
|
-
}>, facts?: RunOutcomeFacts): string;
|
|
27
|
-
export declare function lastFailedToolAnswer(history: ReadonlyArray<{
|
|
28
|
-
role: string;
|
|
29
|
-
content: string;
|
|
30
|
-
}>): string | null;
|
|
27
|
+
export declare function degenerateAnswer(outcome: Exclude<RunOutcome, 'answered'>, history: ReadonlyArray<HistoryTurn>, facts?: RunOutcomeFacts): string;
|
|
28
|
+
export declare function lastFailedToolAnswer(history: ReadonlyArray<HistoryTurn>): string | null;
|
|
31
29
|
export declare function writeResult(output: unknown): string | null;
|
|
32
30
|
export declare function unnamedWrites(answer: string, landed: ReadonlyArray<string>): ReadonlyArray<string>;
|
|
33
31
|
export declare function writeReport(landed: ReadonlyArray<string>): string | null;
|