maka-agent 0.2.0-dev.30.20260912 → 0.2.0-dev.31.20260913
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/THIRD_PARTY_NOTICES.txt +392 -0
- package/dist/acp/maka-acp-agent.js +8 -2
- package/dist/acp/prompt-content.js +225 -0
- package/dist/acp/session-event-mapper.js +103 -0
- package/dist/acp/session-registry.js +654 -17
- package/dist/acp/stdio-server.js +10 -1
- package/dist/cli-core.js +1 -1
- package/dist/pi-transcript-tools.js +3 -2
- package/dist/pi-transcript.js +12 -2
- package/dist/runtime-host-session-channel.js +63 -9
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/artifacts.js +6 -0
- package/node_modules/@maka/core/dist/attachments.js +7 -2
- package/node_modules/@maka/core/dist/durable-tool-result-projection.js +3 -1
- package/node_modules/@maka/core/dist/events.js +21 -0
- package/node_modules/@maka/core/dist/goal.js +44 -2
- package/node_modules/@maka/core/dist/permission.js +0 -1
- package/node_modules/@maka/core/dist/runtime-boundary.js +73 -29
- package/node_modules/@maka/core/dist/runtime-event.js +6 -3
- package/node_modules/@maka/core/dist/runtime-handoff.js +10 -2
- package/node_modules/@maka/core/dist/runtime-logical-execution.js +39 -14
- package/node_modules/@maka/core/dist/tool-result-archive-evidence.js +3 -1
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/unified-diff.js +33 -26
- package/node_modules/@maka/runtime/dist/ai-sdk-compaction.js +49 -178
- package/node_modules/@maka/runtime/dist/ai-sdk-message-projection.js +7 -2
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +15 -53
- package/node_modules/@maka/runtime/dist/bash-model-output.js +7 -1
- package/node_modules/@maka/runtime/dist/bash-tail-buffer.js +13 -52
- package/node_modules/@maka/runtime/dist/builtin-tools.js +59 -111
- package/node_modules/@maka/runtime/dist/child-fd-input.js +3 -2
- package/node_modules/@maka/runtime/dist/context-budget-policy.js +1 -11
- package/node_modules/@maka/runtime/dist/context-budget.js +12 -1
- package/node_modules/@maka/runtime/dist/conversation-copy.js +104 -9
- package/node_modules/@maka/runtime/dist/filesystem-executor.js +10 -6
- package/node_modules/@maka/runtime/dist/filesystem-worker/client.js +77 -19
- package/node_modules/@maka/runtime/dist/filesystem-worker/launch-spec.js +66 -55
- package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +34 -97
- package/node_modules/@maka/runtime/dist/filesystem-worker/protocol.js +25 -10
- package/node_modules/@maka/runtime/dist/filesystem-worker/worker-entry.js +2 -0
- package/node_modules/@maka/runtime/dist/glob-search.js +74 -0
- package/node_modules/@maka/runtime/dist/goal-continuation.js +78 -8
- package/node_modules/@maka/runtime/dist/goal-state.js +7 -0
- package/node_modules/@maka/runtime/dist/grep-search.js +155 -0
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +84 -94
- package/node_modules/@maka/runtime/dist/model-history.js +25 -3
- package/node_modules/@maka/runtime/dist/pipe-tail-collector.js +6 -9
- package/node_modules/@maka/runtime/dist/read-page.js +231 -0
- package/node_modules/@maka/runtime/dist/request-projection.js +2 -15
- package/node_modules/@maka/runtime/dist/ripgrep-executable.js +62 -0
- package/node_modules/@maka/runtime/dist/ripgrep-guidance.js +81 -0
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +187 -20
- package/node_modules/@maka/runtime/dist/runtime-read-model.js +2 -1
- package/node_modules/@maka/runtime/dist/sandbox/linux-profile-path.js +7 -1
- package/node_modules/@maka/runtime/dist/sandbox/linux-sandbox.js +20 -5
- package/node_modules/@maka/runtime/dist/session-manager.js +6 -6
- package/node_modules/@maka/runtime/dist/session-recap.js +9 -5
- package/node_modules/@maka/runtime/dist/shell-exec.js +7 -25
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +1 -1
- package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +1 -1
- package/node_modules/@maka/runtime/dist/shell-tools.js +6 -12
- package/node_modules/@maka/runtime/dist/tool-availability.js +0 -1
- package/node_modules/@maka/runtime/dist/tool-output.js +1 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-capability.js +24 -36
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +32 -527
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +17 -119
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +7 -25
- package/node_modules/@maka/runtime/dist/tool-runtime.js +7 -5
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +6933 -3681
- package/node_modules/@maka/runtime/dist/workspace-executor.js +20 -24
- package/node_modules/@maka/runtime/package.json +2 -0
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +185 -191
- package/node_modules/@maka/runtime-host/dist/client/reconnecting-connection.js +3 -0
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +5 -1
- package/node_modules/@maka/runtime-host/dist/protocol/message.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/turn.js +10 -2
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +38 -0
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +2 -8
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +81 -7
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +13 -13
- package/node_modules/@maka/runtime-host/dist/server/interaction-coordinator.js +65 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +1 -0
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +88 -72
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +21 -4
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +145 -1
- package/node_modules/@maka/storage/dist/agent-run-store.js +5 -2
- package/node_modules/@maka/storage/dist/execution-stores.js +2 -1
- package/node_modules/@maka/storage/dist/runtime-transcript-query.js +27 -14
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +69 -3
- package/node_modules/balanced-match/LICENSE.md +23 -0
- package/node_modules/balanced-match/README.md +57 -0
- package/node_modules/balanced-match/dist/commonjs/index.js +59 -0
- package/node_modules/balanced-match/dist/commonjs/package.json +3 -0
- package/node_modules/balanced-match/dist/esm/index.js +54 -0
- package/node_modules/balanced-match/dist/esm/package.json +3 -0
- package/node_modules/balanced-match/package.json +68 -0
- package/node_modules/brace-expansion/LICENSE +23 -0
- package/node_modules/brace-expansion/README.md +105 -0
- package/node_modules/brace-expansion/dist/commonjs/index.js +289 -0
- package/node_modules/brace-expansion/dist/commonjs/package.json +3 -0
- package/node_modules/brace-expansion/dist/esm/index.js +285 -0
- package/node_modules/brace-expansion/dist/esm/package.json +3 -0
- package/node_modules/brace-expansion/package.json +64 -0
- package/node_modules/glob/LICENSE.md +63 -0
- package/node_modules/glob/README.md +1203 -0
- package/node_modules/glob/dist/commonjs/glob.js +248 -0
- package/node_modules/glob/dist/commonjs/has-magic.js +27 -0
- package/node_modules/glob/dist/commonjs/ignore.js +119 -0
- package/node_modules/glob/dist/commonjs/index.js +68 -0
- package/node_modules/glob/dist/commonjs/index.min.js +4 -0
- package/node_modules/glob/dist/commonjs/package.json +3 -0
- package/node_modules/glob/dist/commonjs/pattern.js +223 -0
- package/node_modules/glob/dist/commonjs/processor.js +301 -0
- package/node_modules/glob/dist/commonjs/walker.js +387 -0
- package/node_modules/glob/dist/esm/glob.js +244 -0
- package/node_modules/glob/dist/esm/has-magic.js +23 -0
- package/node_modules/glob/dist/esm/ignore.js +115 -0
- package/node_modules/glob/dist/esm/index.js +55 -0
- package/node_modules/glob/dist/esm/index.min.js +4 -0
- package/node_modules/glob/dist/esm/package.json +3 -0
- package/node_modules/glob/dist/esm/pattern.js +219 -0
- package/node_modules/glob/dist/esm/processor.js +294 -0
- package/node_modules/glob/dist/esm/walker.js +381 -0
- package/node_modules/glob/package.json +98 -0
- package/node_modules/minimatch/LICENSE.md +55 -0
- package/node_modules/minimatch/README.md +528 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
- package/node_modules/minimatch/dist/commonjs/ast.js +845 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js +150 -0
- package/node_modules/minimatch/dist/commonjs/escape.js +30 -0
- package/node_modules/minimatch/dist/commonjs/index.js +1127 -0
- package/node_modules/minimatch/dist/commonjs/package.json +3 -0
- package/node_modules/minimatch/dist/commonjs/unescape.js +38 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
- package/node_modules/minimatch/dist/esm/ast.js +841 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.js +146 -0
- package/node_modules/minimatch/dist/esm/escape.js +26 -0
- package/node_modules/minimatch/dist/esm/index.js +1114 -0
- package/node_modules/minimatch/dist/esm/package.json +3 -0
- package/node_modules/minimatch/dist/esm/unescape.js +34 -0
- package/node_modules/minimatch/package.json +73 -0
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/README.md +825 -0
- package/node_modules/minipass/dist/commonjs/index.js +1038 -0
- package/node_modules/minipass/dist/commonjs/package.json +3 -0
- package/node_modules/minipass/dist/esm/index.js +1020 -0
- package/node_modules/minipass/dist/esm/package.json +3 -0
- package/node_modules/minipass/package.json +77 -0
- package/node_modules/path-scurry/LICENSE.md +55 -0
- package/node_modules/path-scurry/README.md +636 -0
- package/node_modules/path-scurry/dist/commonjs/index.js +2018 -0
- package/node_modules/path-scurry/dist/commonjs/package.json +3 -0
- package/node_modules/path-scurry/dist/esm/index.js +1983 -0
- package/node_modules/path-scurry/dist/esm/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/LICENSE.md +55 -0
- package/node_modules/path-scurry/node_modules/lru-cache/README.md +469 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/package.json +3 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/package.json +154 -0
- package/node_modules/path-scurry/package.json +72 -0
- package/package.json +1 -1
- package/node_modules/@maka/runtime/dist/active-tool-result-prune.js +0 -248
- package/node_modules/@maka/runtime/dist/active-tool-result-working-set.js +0 -218
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +0 -115
|
@@ -16,25 +16,12 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { TOOL_RESULT_ARCHIVE_EVIDENCE_MAX_BYTES } from '@maka/core/tool-result-archive-evidence';
|
|
20
|
+
import { readToolResultPage, resolveReadInput } from './read-page.js';
|
|
19
21
|
export const TOOL_RESULT_ARCHIVE_RESOURCE_PROTOCOL = 'maka:';
|
|
20
22
|
export const TOOL_RESULT_ARCHIVE_RESOURCE_HOST = 'archive';
|
|
21
|
-
export const
|
|
22
|
-
export const TOOL_RESULT_ARCHIVE_MAX_LIMIT = 6_000;
|
|
23
|
-
export const TOOL_RESULT_ARCHIVE_MAX_BYTES = 4 * 1024 * 1024;
|
|
24
|
-
export const TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS = 7_500;
|
|
23
|
+
export const TOOL_RESULT_ARCHIVE_MAX_BYTES = TOOL_RESULT_ARCHIVE_EVIDENCE_MAX_BYTES;
|
|
25
24
|
const ARCHIVE_ARTIFACT_ID_PATTERN = /^[A-Za-z0-9._-]{1,160}$/;
|
|
26
|
-
const MAX_MANIFEST_ITEMS = 100;
|
|
27
|
-
const MAX_METADATA_STRING_CHARS = 160;
|
|
28
|
-
/** Upper bound on matches returned by a single search page. */
|
|
29
|
-
export const TOOL_RESULT_ARCHIVE_MAX_SEARCH_MATCHES = 50;
|
|
30
|
-
/** Characters of surrounding context kept on each side of a search match. */
|
|
31
|
-
const SEARCH_SNIPPET_RADIUS = 80;
|
|
32
|
-
/** Longest search snippet retained, so many matches still fit one response. */
|
|
33
|
-
const MAX_SEARCH_SNIPPET_CHARS = 240;
|
|
34
|
-
/** Maximum pattern length accepted by the ArchiveRead tool schema. */
|
|
35
|
-
const MAX_SEARCH_PATTERN_CHARS = 256;
|
|
36
|
-
/** Preview length surfaced by inspect for text/object payloads. */
|
|
37
|
-
const INSPECT_PREVIEW_CHARS = 600;
|
|
38
25
|
export function isLedgerArchiveIdentity(value) {
|
|
39
26
|
if (!isRecord(value))
|
|
40
27
|
return false;
|
|
@@ -139,523 +126,41 @@ export function parseToolResultArchiveResourceRef(ref) {
|
|
|
139
126
|
return null;
|
|
140
127
|
return { artifactId, bodySha256, originalBytes };
|
|
141
128
|
}
|
|
142
|
-
export
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (abortSignal?.aborted)
|
|
154
|
-
throw new Error('ArchiveRead aborted');
|
|
155
|
-
const read = await Promise.resolve(reader.readArchivedToolResultResource({
|
|
156
|
-
...identity,
|
|
157
|
-
sessionId,
|
|
158
|
-
maxBytes: identity.originalBytes,
|
|
159
|
-
}));
|
|
160
|
-
if (!read.ok)
|
|
161
|
-
return archiveFailure(request.ref, read.reason);
|
|
162
|
-
if (abortSignal?.aborted)
|
|
163
|
-
throw new Error('ArchiveRead aborted');
|
|
164
|
-
const operation = request.operation ?? 'inspect';
|
|
165
|
-
const limit = normalizeLimit(request.limit);
|
|
166
|
-
const offset = normalizeOffset(request.offset);
|
|
167
|
-
const parsed = deserializeArchive(read.serializedResult);
|
|
168
|
-
if (operation === 'search') {
|
|
169
|
-
const text = resolveArchiveText(parsed, read.serializedResult);
|
|
170
|
-
return searchArchive(request.ref, text, request.pattern, offset);
|
|
171
|
-
}
|
|
172
|
-
if (operation === 'read') {
|
|
173
|
-
// Page the decoded text for string payloads so offsets land on real
|
|
174
|
-
// characters, not JSON escape bytes; structured payloads still page their
|
|
175
|
-
// canonical JSON serialization.
|
|
176
|
-
const text = resolveArchiveText(parsed, read.serializedResult);
|
|
177
|
-
if (request.unit === 'line') {
|
|
178
|
-
return pagedLines(request.ref, text, offset, limit);
|
|
179
|
-
}
|
|
180
|
-
return pagedContent({ ref: request.ref, operation, content: text, offset, limit });
|
|
181
|
-
}
|
|
182
|
-
if (operation === 'query') {
|
|
183
|
-
return queryArchiveItem(request.ref, parsed, request.itemId, offset, limit);
|
|
184
|
-
}
|
|
185
|
-
return inspectArchive(request.ref, identity, parsed, read.serializedResult);
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* The text an archive should page/search over. String payloads decode to their
|
|
189
|
-
* raw content, and terminal/shell-run payloads project their stdout/stderr;
|
|
190
|
-
* everything else pages its canonical JSON serialization.
|
|
191
|
-
*/
|
|
192
|
-
function resolveArchiveText(parsed, serializedResult) {
|
|
193
|
-
if (typeof parsed === 'string')
|
|
194
|
-
return parsed;
|
|
195
|
-
if (!isTerminalArchivePayload(parsed))
|
|
196
|
-
return serializedResult;
|
|
197
|
-
// Bash archives retain the canonical terminal/shell-run object. Search and
|
|
198
|
-
// line reads should operate on the human-readable streams, not JSON-escaped
|
|
199
|
-
// `\\n` sequences in that object.
|
|
200
|
-
const output = isRecord(parsed.output) ? parsed.output : undefined;
|
|
201
|
-
if (output?.mode === 'pty') {
|
|
202
|
-
const ptyParts = [output.scrollback, output.screen, output.lastAlternateScreen].filter((part) => typeof part === 'string' && part.length > 0);
|
|
203
|
-
return ptyParts.join('\n');
|
|
204
|
-
}
|
|
205
|
-
const stdout = output && typeof output.stdout === 'string' ? output.stdout : undefined;
|
|
206
|
-
const stderr = output && typeof output.stderr === 'string' ? output.stderr : undefined;
|
|
207
|
-
if (stdout !== undefined || stderr !== undefined) {
|
|
208
|
-
const parts = [stdout, stderr].filter((s) => typeof s === 'string' && s.length > 0);
|
|
209
|
-
return parts.join('\n');
|
|
210
|
-
}
|
|
211
|
-
return serializedResult;
|
|
212
|
-
}
|
|
213
|
-
function isTerminalArchivePayload(value) {
|
|
214
|
-
return (isRecord(value) &&
|
|
215
|
-
(value.kind === 'terminal' || value.kind === 'shell_run') &&
|
|
216
|
-
isRecord(value.output));
|
|
217
|
-
}
|
|
218
|
-
export const TOOL_RESULT_ARCHIVE_READ_INSTRUCTIONS = 'This result is archived but still readable. Call ArchiveRead with the provided ref and operation "inspect"; use operation "query" with itemId for one structured item, or operation "read" with offset/limit for a bounded page. Do not use Glob to find the archive.';
|
|
219
|
-
function inspectArchive(ref, identity, value, serializedResult) {
|
|
220
|
-
const base = {
|
|
221
|
-
ok: true,
|
|
222
|
-
kind: 'tool_result_archive',
|
|
223
|
-
operation: 'inspect',
|
|
224
|
-
ref,
|
|
225
|
-
...(identity.storage === 'ledger'
|
|
226
|
-
? { storage: 'ledger', runtimeEventId: identity.runtimeEventId }
|
|
227
|
-
: { artifactId: identity.artifactId }),
|
|
228
|
-
originalBytes: identity.originalBytes,
|
|
229
|
-
};
|
|
230
|
-
const readHint = 'Call ArchiveRead with operation "read" (unit "char" or "line"), offset, and limit for bounded pages, or operation "search" with a pattern to locate text.';
|
|
231
|
-
if (isTerminalArchivePayload(value)) {
|
|
232
|
-
const text = resolveArchiveText(value, serializedResult);
|
|
233
|
-
return {
|
|
234
|
-
...base,
|
|
235
|
-
valueType: 'terminal',
|
|
236
|
-
totalChars: text.length,
|
|
237
|
-
totalLines: countLines(text),
|
|
238
|
-
preview: boundedString(text, INSPECT_PREVIEW_CHARS),
|
|
239
|
-
readHint,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
if (typeof value === 'string') {
|
|
243
|
-
// A plain-text/terminal payload: report the char/line coordinate space plus
|
|
244
|
-
// a short preview so the model can page or search without a blind first read.
|
|
245
|
-
return {
|
|
246
|
-
...base,
|
|
247
|
-
valueType: 'text',
|
|
248
|
-
totalChars: value.length,
|
|
249
|
-
totalLines: countLines(value),
|
|
250
|
-
preview: boundedString(value, INSPECT_PREVIEW_CHARS),
|
|
251
|
-
readHint,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
if (isRecord(value)) {
|
|
255
|
-
const items = Array.isArray(value.items) ? value.items : undefined;
|
|
256
|
-
let objectKeys = Object.keys(value)
|
|
257
|
-
.slice(0, 25)
|
|
258
|
-
.map((key) => boundedString(key));
|
|
259
|
-
const buildObjectBase = () => ({
|
|
260
|
-
...base,
|
|
261
|
-
valueType: 'object',
|
|
262
|
-
totalChars: serializedResult.length,
|
|
263
|
-
keys: objectKeys,
|
|
264
|
-
...(typeof value.kind === 'string' ? { archivedKind: boundedString(value.kind) } : {}),
|
|
265
|
-
...(typeof value.status === 'string' ? { status: boundedString(value.status) } : {}),
|
|
266
|
-
});
|
|
267
|
-
if (items) {
|
|
268
|
-
const queryHint = 'Call ArchiveRead with operation "query" and one of the listed itemId values.';
|
|
269
|
-
const projectedItems = items.slice(0, MAX_MANIFEST_ITEMS).map(inspectItem);
|
|
270
|
-
let manifestItems = projectedItems;
|
|
271
|
-
const buildManifest = () => ({
|
|
272
|
-
...buildObjectBase(),
|
|
273
|
-
itemCount: items.length,
|
|
274
|
-
items: manifestItems,
|
|
275
|
-
queryHint,
|
|
276
|
-
readHint,
|
|
277
|
-
...(manifestItems.length < items.length
|
|
278
|
-
? { itemsTruncated: true, listedItemCount: manifestItems.length }
|
|
279
|
-
: {}),
|
|
280
|
-
});
|
|
281
|
-
// Keep one actionable itemId when it can fit, then trade keys for more
|
|
282
|
-
// manifest entries and re-add entries against the complete envelope.
|
|
283
|
-
while (JSON.stringify(buildManifest()).length > TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
284
|
-
if (manifestItems.length > 1) {
|
|
285
|
-
manifestItems = manifestItems.slice(0, -1);
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
if (objectKeys.length > 0) {
|
|
289
|
-
objectKeys = objectKeys.slice(0, -1);
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
if (manifestItems.length > 0) {
|
|
293
|
-
manifestItems = [];
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
for (const projectedItem of projectedItems.slice(manifestItems.length)) {
|
|
299
|
-
const next = [...manifestItems, projectedItem];
|
|
300
|
-
manifestItems = next;
|
|
301
|
-
if (JSON.stringify(buildManifest()).length > TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
302
|
-
manifestItems = next.slice(0, -1);
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return buildManifest();
|
|
307
|
-
}
|
|
308
|
-
const buildObject = () => ({
|
|
309
|
-
...buildObjectBase(),
|
|
310
|
-
preview: boundedString(serializedResult, INSPECT_PREVIEW_CHARS),
|
|
311
|
-
readHint,
|
|
312
|
-
});
|
|
313
|
-
while (objectKeys.length > 0 &&
|
|
314
|
-
JSON.stringify(buildObject()).length > TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
315
|
-
objectKeys = objectKeys.slice(0, -1);
|
|
316
|
-
}
|
|
317
|
-
return buildObject();
|
|
318
|
-
}
|
|
319
|
-
if (Array.isArray(value)) {
|
|
320
|
-
return {
|
|
321
|
-
...base,
|
|
322
|
-
valueType: 'array',
|
|
323
|
-
itemCount: value.length,
|
|
324
|
-
totalChars: serializedResult.length,
|
|
325
|
-
preview: boundedString(serializedResult, INSPECT_PREVIEW_CHARS),
|
|
326
|
-
readHint,
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
return {
|
|
330
|
-
...base,
|
|
331
|
-
valueType: value === null ? 'null' : typeof value,
|
|
332
|
-
totalChars: serializedResult.length,
|
|
333
|
-
preview: boundedString(serializedResult, INSPECT_PREVIEW_CHARS),
|
|
334
|
-
readHint,
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
function queryArchiveItem(ref, value, itemId, offset, limit) {
|
|
338
|
-
if (!itemId)
|
|
339
|
-
return archiveFailure(ref, 'item_id_required');
|
|
340
|
-
const items = isRecord(value) && Array.isArray(value.items) ? value.items : undefined;
|
|
341
|
-
if (!items)
|
|
342
|
-
return archiveFailure(ref, 'not_queryable');
|
|
343
|
-
const item = items.find((candidate) => isRecord(candidate) && String(candidate.itemId ?? candidate.item_id ?? '') === itemId);
|
|
344
|
-
if (!isRecord(item)) {
|
|
345
|
-
return archiveFailure(ref, 'item_not_found', {
|
|
346
|
-
itemId,
|
|
347
|
-
availableItemIds: items
|
|
348
|
-
.map((candidate) => isRecord(candidate)
|
|
349
|
-
? boundedString(String(candidate.itemId ?? candidate.item_id ?? ''))
|
|
350
|
-
: '')
|
|
351
|
-
.filter(Boolean)
|
|
352
|
-
.slice(0, 25),
|
|
353
|
-
});
|
|
129
|
+
export const TOOL_RESULT_ARCHIVE_READ_INSTRUCTIONS = 'Use Read with the next parameters to continue this result.';
|
|
130
|
+
/** A complete canonical event address, including when read from untrusted history. */
|
|
131
|
+
export function parseToolResultEventAddress(path) {
|
|
132
|
+
const prefix = 'maka://runtime/tool-results/';
|
|
133
|
+
if (!path.startsWith(prefix))
|
|
134
|
+
return null;
|
|
135
|
+
try {
|
|
136
|
+
const id = decodeURIComponent(path.slice(prefix.length));
|
|
137
|
+
return id.length > 0 && id.length <= 512 && `${prefix}${encodeURIComponent(id)}` === path
|
|
138
|
+
? id
|
|
139
|
+
: null;
|
|
354
140
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
: typeof item.result === 'string'
|
|
358
|
-
? item.result
|
|
359
|
-
: JSON.stringify(item);
|
|
360
|
-
return pagedContent({
|
|
361
|
-
ref,
|
|
362
|
-
operation: 'query',
|
|
363
|
-
content,
|
|
364
|
-
offset,
|
|
365
|
-
limit,
|
|
366
|
-
extra: {
|
|
367
|
-
itemId,
|
|
368
|
-
item: inspectItem(item),
|
|
369
|
-
},
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
function pagedContent(input) {
|
|
373
|
-
const offset = Math.min(input.offset, input.content.length);
|
|
374
|
-
const requestedEnd = Math.min(input.content.length, offset + input.limit);
|
|
375
|
-
const buildPage = (end) => ({
|
|
376
|
-
ok: true,
|
|
377
|
-
kind: 'tool_result_archive',
|
|
378
|
-
operation: input.operation,
|
|
379
|
-
ref: input.ref,
|
|
380
|
-
offset,
|
|
381
|
-
limit: end - offset,
|
|
382
|
-
totalChars: input.content.length,
|
|
383
|
-
nextOffset: end < input.content.length ? end : null,
|
|
384
|
-
hasMore: end < input.content.length,
|
|
385
|
-
content: input.content.slice(offset, end),
|
|
386
|
-
...(input.extra ?? {}),
|
|
387
|
-
});
|
|
388
|
-
let low = offset;
|
|
389
|
-
let high = requestedEnd;
|
|
390
|
-
while (low < high) {
|
|
391
|
-
const candidateEnd = Math.ceil((low + high) / 2);
|
|
392
|
-
if (JSON.stringify(buildPage(candidateEnd)).length <= TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
393
|
-
low = candidateEnd;
|
|
394
|
-
}
|
|
395
|
-
else {
|
|
396
|
-
high = candidateEnd - 1;
|
|
397
|
-
}
|
|
141
|
+
catch {
|
|
142
|
+
return null;
|
|
398
143
|
}
|
|
399
|
-
return buildPage(low);
|
|
400
144
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
// Escape the user pattern before using a Unicode-aware literal regex. This
|
|
413
|
-
// preserves original source indices while retaining contextual case folding
|
|
414
|
-
// (for example, Greek final sigma), and remains safe from regex injection or
|
|
415
|
-
// pathological backtracking because the pattern is literal.
|
|
416
|
-
const matcher = new RegExp(escapeRegExp(pattern), 'giu');
|
|
417
|
-
const base = {
|
|
418
|
-
ok: true,
|
|
419
|
-
kind: 'tool_result_archive',
|
|
420
|
-
operation: 'search',
|
|
421
|
-
ref,
|
|
422
|
-
pattern: boundedString(pattern, MAX_SEARCH_PATTERN_CHARS),
|
|
423
|
-
totalChars: text.length,
|
|
424
|
-
};
|
|
425
|
-
const buildResponse = (matches, nextOffset) => ({
|
|
426
|
-
...base,
|
|
427
|
-
matchCount: matches.length,
|
|
428
|
-
matches,
|
|
429
|
-
nextOffset,
|
|
430
|
-
hasMore: nextOffset !== null,
|
|
145
|
+
export async function readToolResultArchiveResource(reader, sessionId, input, abortSignal) {
|
|
146
|
+
const { path } = resolveReadInput(input);
|
|
147
|
+
const runtimeEventId = parseToolResultEventAddress(path);
|
|
148
|
+
if (!runtimeEventId)
|
|
149
|
+
throw new Error('Invalid Maka address. Copy the complete path returned by the tool.');
|
|
150
|
+
abortSignal?.throwIfAborted();
|
|
151
|
+
const result = await reader.readArchivedToolResultResource({
|
|
152
|
+
sessionId,
|
|
153
|
+
storage: 'event',
|
|
154
|
+
runtimeEventId,
|
|
155
|
+
maxBytes: TOOL_RESULT_ARCHIVE_MAX_BYTES,
|
|
431
156
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
// increase, so total work stays linear in the text length.
|
|
435
|
-
let scanChar = 0;
|
|
436
|
-
let scanLine = 1;
|
|
437
|
-
const lineAt = (index) => {
|
|
438
|
-
while (scanChar < index && scanChar < text.length) {
|
|
439
|
-
if (text.charCodeAt(scanChar) === 10)
|
|
440
|
-
scanLine++;
|
|
441
|
-
scanChar++;
|
|
442
|
-
}
|
|
443
|
-
return scanLine;
|
|
444
|
-
};
|
|
445
|
-
let from = normalizeSearchOffset(text, offset);
|
|
446
|
-
while (matches.length < TOOL_RESULT_ARCHIVE_MAX_SEARCH_MATCHES) {
|
|
447
|
-
matcher.lastIndex = from;
|
|
448
|
-
const match = matcher.exec(text);
|
|
449
|
-
if (!match)
|
|
450
|
-
return buildResponse(matches, null);
|
|
451
|
-
const index = match.index;
|
|
452
|
-
const matchEnd = index + match[0].length;
|
|
453
|
-
// Keep the complete match representable when the accepted pattern is
|
|
454
|
-
// longer than the normal snippet budget; trim surrounding context first.
|
|
455
|
-
const snippetLimit = Math.min(MAX_SEARCH_PATTERN_CHARS + SEARCH_SNIPPET_RADIUS * 2, Math.max(MAX_SEARCH_SNIPPET_CHARS, matchEnd - index));
|
|
456
|
-
const contextBudget = Math.max(0, snippetLimit - (matchEnd - index));
|
|
457
|
-
const before = Math.min(SEARCH_SNIPPET_RADIUS, Math.floor(contextBudget / 2));
|
|
458
|
-
const after = Math.min(SEARCH_SNIPPET_RADIUS, contextBudget - before);
|
|
459
|
-
const snippetStart = Math.max(0, index - before);
|
|
460
|
-
const snippetEnd = Math.min(text.length, matchEnd + after);
|
|
461
|
-
const candidate = {
|
|
462
|
-
offset: index,
|
|
463
|
-
line: lineAt(index),
|
|
464
|
-
snippetStart,
|
|
465
|
-
snippet: text.slice(snippetStart, snippetEnd),
|
|
466
|
-
};
|
|
467
|
-
if (JSON.stringify(buildResponse([...matches, candidate], index)).length >
|
|
468
|
-
TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
469
|
-
// This match would overflow the budget; resume here next call.
|
|
470
|
-
return buildResponse(matches, index);
|
|
471
|
-
}
|
|
472
|
-
matches.push(candidate);
|
|
473
|
-
from = index + Math.max(1, match[0].length);
|
|
474
|
-
}
|
|
475
|
-
// Hit the per-page match cap; report where an unread match still waits.
|
|
476
|
-
matcher.lastIndex = from;
|
|
477
|
-
const more = matcher.exec(text);
|
|
478
|
-
return buildResponse(matches, more === null ? null : more.index);
|
|
479
|
-
}
|
|
480
|
-
function escapeRegExp(value) {
|
|
481
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
482
|
-
}
|
|
483
|
-
function normalizeSearchOffset(text, offset) {
|
|
484
|
-
const clamped = Math.min(Math.max(0, offset), text.length);
|
|
485
|
-
if (clamped > 0 &&
|
|
486
|
-
clamped < text.length &&
|
|
487
|
-
isLowSurrogate(text.charCodeAt(clamped)) &&
|
|
488
|
-
isHighSurrogate(text.charCodeAt(clamped - 1))) {
|
|
489
|
-
return clamped + 1;
|
|
490
|
-
}
|
|
491
|
-
return clamped;
|
|
492
|
-
}
|
|
493
|
-
function isHighSurrogate(value) {
|
|
494
|
-
return value >= 0xd800 && value <= 0xdbff;
|
|
495
|
-
}
|
|
496
|
-
function isLowSurrogate(value) {
|
|
497
|
-
return value >= 0xdc00 && value <= 0xdfff;
|
|
498
|
-
}
|
|
499
|
-
/** Count 1-based lines in text (an empty string has zero lines). */
|
|
500
|
-
function countLines(text) {
|
|
501
|
-
if (text.length === 0)
|
|
502
|
-
return 0;
|
|
503
|
-
let count = 1;
|
|
504
|
-
for (let i = 0; i < text.length; i++) {
|
|
505
|
-
if (text.charCodeAt(i) === 10)
|
|
506
|
-
count++;
|
|
507
|
-
}
|
|
508
|
-
return count;
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Collect up to `maxLines` lines starting at the zero-based `lineOffset` without
|
|
512
|
-
* materializing the whole text as an array — the scan stops after the window,
|
|
513
|
-
* so cost is bounded by the requested window, not the archive size.
|
|
514
|
-
*/
|
|
515
|
-
function collectLineWindow(text, lineOffset, maxLines) {
|
|
516
|
-
if (text.length === 0)
|
|
517
|
-
return { lines: [], startChar: 0 };
|
|
518
|
-
let cursor = 0;
|
|
519
|
-
let line = 0;
|
|
520
|
-
while (line < lineOffset && cursor <= text.length) {
|
|
521
|
-
const nl = text.indexOf('\n', cursor);
|
|
522
|
-
if (nl === -1)
|
|
523
|
-
return { lines: [], startChar: text.length };
|
|
524
|
-
cursor = nl + 1;
|
|
525
|
-
line++;
|
|
526
|
-
}
|
|
527
|
-
const startChar = cursor;
|
|
528
|
-
const lines = [];
|
|
529
|
-
while (lines.length < maxLines && cursor <= text.length) {
|
|
530
|
-
const nl = text.indexOf('\n', cursor);
|
|
531
|
-
if (nl === -1) {
|
|
532
|
-
lines.push(text.slice(cursor));
|
|
533
|
-
break;
|
|
534
|
-
}
|
|
535
|
-
lines.push(text.slice(cursor, nl));
|
|
536
|
-
cursor = nl + 1;
|
|
537
|
-
if (cursor > text.length)
|
|
538
|
-
break;
|
|
539
|
-
}
|
|
540
|
-
return { lines, startChar };
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Read a bounded window of whole lines. offset/limit count lines; the returned
|
|
544
|
-
* line count is trimmed by binary search so the response never exceeds
|
|
545
|
-
* TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS, and `nextLineOffset` resumes paging.
|
|
546
|
-
*/
|
|
547
|
-
function pagedLines(ref, text, lineOffset, lineLimit) {
|
|
548
|
-
const totalLines = countLines(text);
|
|
549
|
-
const { lines } = collectLineWindow(text, lineOffset, lineLimit);
|
|
550
|
-
const buildPage = (count) => {
|
|
551
|
-
const endLine = lineOffset + count;
|
|
552
|
-
const hasMore = endLine < totalLines;
|
|
157
|
+
abortSignal?.throwIfAborted();
|
|
158
|
+
if (!result.ok)
|
|
553
159
|
return {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
operation: 'read',
|
|
557
|
-
ref,
|
|
558
|
-
unit: 'line',
|
|
559
|
-
lineOffset,
|
|
560
|
-
lineLimit: count,
|
|
561
|
-
totalLines,
|
|
562
|
-
nextLineOffset: hasMore ? endLine : null,
|
|
563
|
-
hasMore,
|
|
564
|
-
content: lines.slice(0, count).join('\n'),
|
|
160
|
+
error: result.reason,
|
|
161
|
+
message: 'This Maka content could not be read. Changing offset or limit will not restore it. Use the original source if it is still available.',
|
|
565
162
|
};
|
|
566
|
-
|
|
567
|
-
let low = 0;
|
|
568
|
-
let high = lines.length;
|
|
569
|
-
while (low < high) {
|
|
570
|
-
const candidate = Math.ceil((low + high) / 2);
|
|
571
|
-
if (JSON.stringify(buildPage(candidate)).length <= TOOL_RESULT_ARCHIVE_MAX_RESPONSE_CHARS) {
|
|
572
|
-
low = candidate;
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
high = candidate - 1;
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
if (low === 0 && lines.length > 0) {
|
|
579
|
-
return archiveFailure(ref, 'line_too_large', {
|
|
580
|
-
unit: 'line',
|
|
581
|
-
lineOffset,
|
|
582
|
-
totalLines,
|
|
583
|
-
lineChars: lines[0].length,
|
|
584
|
-
readHint: 'Retry with operation "read" and unit "char" to page this oversized line.',
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
return buildPage(low);
|
|
588
|
-
}
|
|
589
|
-
function inspectItem(value) {
|
|
590
|
-
if (!isRecord(value))
|
|
591
|
-
return { valueType: value === null ? 'null' : typeof value };
|
|
592
|
-
return {
|
|
593
|
-
...(typeof value.itemId === 'string' ? { itemId: boundedString(value.itemId) } : {}),
|
|
594
|
-
...(typeof value.item_id === 'string' ? { itemId: boundedString(value.item_id) } : {}),
|
|
595
|
-
...(typeof value.index === 'number' ? { index: value.index } : {}),
|
|
596
|
-
...(typeof value.started === 'boolean' ? { started: value.started } : {}),
|
|
597
|
-
...(typeof value.status === 'string' ? { status: boundedString(value.status) } : {}),
|
|
598
|
-
...(typeof value.profile === 'string' ? { profile: boundedString(value.profile) } : {}),
|
|
599
|
-
...(typeof value.agentId === 'string' ? { agentId: boundedString(value.agentId) } : {}),
|
|
600
|
-
...(typeof value.agentName === 'string' ? { agentName: boundedString(value.agentName) } : {}),
|
|
601
|
-
...(typeof value.childSessionId === 'string'
|
|
602
|
-
? { childSessionId: boundedString(value.childSessionId) }
|
|
603
|
-
: {}),
|
|
604
|
-
...(typeof value.turnId === 'string' ? { turnId: boundedString(value.turnId) } : {}),
|
|
605
|
-
...(typeof value.runId === 'string' ? { runId: boundedString(value.runId) } : {}),
|
|
606
|
-
...(typeof value.resumedFromRunId === 'string'
|
|
607
|
-
? { resumedFromRunId: boundedString(value.resumedFromRunId) }
|
|
608
|
-
: {}),
|
|
609
|
-
...(Array.isArray(value.artifactIds)
|
|
610
|
-
? {
|
|
611
|
-
artifactIds: value.artifactIds
|
|
612
|
-
.filter((artifactId) => typeof artifactId === 'string')
|
|
613
|
-
.slice(0, 8)
|
|
614
|
-
.map(boundedString),
|
|
615
|
-
artifactCount: value.artifactIds.length,
|
|
616
|
-
}
|
|
617
|
-
: {}),
|
|
618
|
-
...(typeof value.startedAt === 'number' ? { startedAt: value.startedAt } : {}),
|
|
619
|
-
...(typeof value.completedAt === 'number' ? { completedAt: value.completedAt } : {}),
|
|
620
|
-
...(typeof value.durationMs === 'number' ? { durationMs: value.durationMs } : {}),
|
|
621
|
-
...(typeof value.failureClass === 'string'
|
|
622
|
-
? { failureClass: boundedString(value.failureClass) }
|
|
623
|
-
: {}),
|
|
624
|
-
...(typeof value.summary === 'string' ? { summaryChars: value.summary.length } : {}),
|
|
625
|
-
...(typeof value.result === 'string' ? { resultChars: value.result.length } : {}),
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
function boundedString(value, max = MAX_METADATA_STRING_CHARS) {
|
|
629
|
-
return value.length <= max ? value : `${value.slice(0, Math.max(0, max - 1))}…`;
|
|
630
|
-
}
|
|
631
|
-
function deserializeArchive(serialized) {
|
|
632
|
-
if (serialized === 'undefined')
|
|
633
|
-
return undefined;
|
|
634
|
-
try {
|
|
635
|
-
return JSON.parse(serialized);
|
|
636
|
-
}
|
|
637
|
-
catch {
|
|
638
|
-
return serialized;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
function normalizeLimit(value) {
|
|
642
|
-
if (!Number.isFinite(value))
|
|
643
|
-
return TOOL_RESULT_ARCHIVE_DEFAULT_LIMIT;
|
|
644
|
-
return Math.max(1, Math.min(TOOL_RESULT_ARCHIVE_MAX_LIMIT, Math.floor(value)));
|
|
645
|
-
}
|
|
646
|
-
function normalizeOffset(value) {
|
|
647
|
-
if (!Number.isFinite(value))
|
|
648
|
-
return 0;
|
|
649
|
-
return Math.max(0, Math.floor(value));
|
|
650
|
-
}
|
|
651
|
-
function archiveFailure(ref, reason, detail) {
|
|
652
|
-
return {
|
|
653
|
-
ok: false,
|
|
654
|
-
kind: 'tool_result_archive',
|
|
655
|
-
ref,
|
|
656
|
-
reason,
|
|
657
|
-
...(detail ?? {}),
|
|
658
|
-
};
|
|
163
|
+
return readToolResultPage(result.serializedResult, input);
|
|
659
164
|
}
|
|
660
165
|
function isRecord(value) {
|
|
661
166
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|