maka-agent 0.2.0-dev.43.20260919 → 0.2.0-dev.45.20260921
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/LICENSE +12 -6
- package/dist/mcp-capability-provider.js +7 -0
- package/dist/runtime-host-service-manager.js +1 -6
- package/dist/runtime-host-tui-command.js +1 -1
- package/dist/runtime-host-update-command.js +39 -27
- 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 +1 -0
- package/node_modules/@maka/core/dist/chat-model-choice.js +3 -0
- package/node_modules/@maka/core/dist/llm-connections.js +3 -21
- package/node_modules/@maka/core/dist/model-catalog.js +8 -20
- package/node_modules/@maka/core/dist/model-metadata.generated.js +304 -304
- package/node_modules/@maka/core/dist/model-metadata.js +1 -2
- package/node_modules/@maka/core/dist/model-thinking.js +16 -1
- package/node_modules/@maka/core/dist/models-dev-projection.js +0 -1
- package/node_modules/@maka/core/dist/provider-auth.js +1 -7
- package/node_modules/@maka/core/dist/provider-registry.js +20 -58
- package/node_modules/@maka/core/dist/recall.js +5 -1
- package/node_modules/@maka/core/dist/runtime-policy/connection-catalog-codec.js +7 -0
- package/node_modules/@maka/core/dist/runtime-policy/model-catalog-entry-codec.js +14 -1
- package/node_modules/@maka/core/dist/session-start-mode.js +2 -5
- package/node_modules/@maka/core/dist/session.js +0 -1
- package/node_modules/@maka/core/dist/settings.js +19 -3
- package/node_modules/@maka/core/dist/tool-quiet-preview.js +2 -16
- package/node_modules/@maka/core/dist/transcript-search.js +46 -0
- package/node_modules/@maka/core/package.json +1 -4
- package/node_modules/@maka/mcp/dist/index.js +22 -0
- package/node_modules/@maka/mcp/dist/oauth.js +4 -2
- package/node_modules/@maka/mcp/dist/tool-progress.js +45 -0
- package/node_modules/@maka/runtime/dist/model-factory.js +0 -16
- package/node_modules/@maka/runtime/dist/model-fetcher.js +1 -4
- package/node_modules/@maka/runtime/dist/model-runtime.js +0 -8
- package/node_modules/@maka/runtime/dist/opencode-session-header.js +2 -3
- package/node_modules/@maka/runtime/dist/recall-tools.js +4 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +5 -57
- package/node_modules/@maka/runtime/dist/subagent-tools.js +69 -11
- package/node_modules/@maka/runtime/dist/test-connection.js +4 -114
- package/node_modules/@maka/runtime/package.json +0 -1
- package/node_modules/@maka/runtime-host/dist/client/client-capability-channel.js +44 -9
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +25 -18
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +3 -1
- package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +33 -3
- package/node_modules/@maka/runtime-host/dist/protocol/connection-effects.js +0 -108
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +12 -1
- package/node_modules/@maka/runtime-host/dist/protocol/message.js +10 -0
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +4 -6
- package/node_modules/@maka/runtime-host/dist/protocol/recall.js +270 -0
- package/node_modules/@maka/runtime-host/dist/protocol/session-catalog.js +1 -1
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -7
- package/node_modules/@maka/runtime-host/dist/protocol/turn.js +0 -33
- package/node_modules/@maka/runtime-host/dist/protocol/usage-screen.js +12 -4
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/bootstrap-runtime-policy.js +31 -104
- package/node_modules/@maka/runtime-host/dist/server/connection-effect-coordinator.js +1 -57
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +11 -35
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +3 -20
- package/node_modules/@maka/runtime-host/dist/server/interactive-turn-coordinator.js +1 -16
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +46 -28
- package/node_modules/@maka/runtime-host/dist/server/recall-coordinator.js +117 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +5 -16
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +21 -12
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +0 -4
- package/node_modules/@maka/runtime-host/dist/server/session-turn-access-request-coordinator.js +7 -17
- package/node_modules/@maka/storage/dist/artifact-metadata-codec.js +4 -3
- package/node_modules/@maka/storage/dist/artifact-store.js +1 -11
- package/node_modules/@maka/storage/dist/process-lifetime-file-update-lock.js +0 -41
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +0 -62
- package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +0 -31
- package/node_modules/@maka/storage/dist/runtime-policy-stores.js +0 -3
- package/node_modules/@maka/storage/dist/sqlite-usage-schema.js +29 -5
- package/node_modules/@maka/storage/dist/sqlite-workflow-schema.js +2 -0
- package/node_modules/@maka/storage/dist/storage-writer-composition.js +0 -3
- package/node_modules/@maka/storage/dist/telemetry-file-schema.js +5 -3
- package/node_modules/@maka/storage/dist/usage-screen.js +5 -6
- package/node_modules/@maka/storage/dist/usage-stores.js +14 -4
- package/node_modules/@maka/storage/package.json +0 -2
- package/package.json +1 -1
- package/node_modules/@maka/core/dist/connection-usage.js +0 -27
- package/node_modules/@maka/core/dist/deep-research-client-progress.js +0 -132
- package/node_modules/@maka/core/dist/deep-research-run.js +0 -625
- package/node_modules/@maka/core/dist/deep-research.js +0 -208
- package/node_modules/@maka/core/dist/thread-search.js +0 -498
- package/node_modules/@maka/runtime/dist/commandcode-cli-language-model.js +0 -837
- package/node_modules/@maka/runtime/dist/connection-usage.js +0 -232
- package/node_modules/@maka/runtime/dist/deep-research-tools.js +0 -732
- package/node_modules/@maka/runtime-host/dist/protocol/deep-research.js +0 -233
- package/node_modules/@maka/runtime-host/dist/server/deep-research-coordinator.js +0 -116
- package/node_modules/@maka/storage/dist/deep-research-authority.js +0 -129
- package/node_modules/@maka/storage/dist/deep-research-store.js +0 -343
|
@@ -28,6 +28,18 @@ export class RuntimeHostSubscriptionError extends Error {
|
|
|
28
28
|
this.name = 'RuntimeHostSubscriptionError';
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
export class SessionRemovedSubscriptionError extends Error {
|
|
32
|
+
name = 'SessionRemovedSubscriptionError';
|
|
33
|
+
}
|
|
34
|
+
export function subscriptionClosedError(reason) {
|
|
35
|
+
if (reason === 'session_removed') {
|
|
36
|
+
return new SessionRemovedSubscriptionError('Runtime Host Session was removed while it was observed');
|
|
37
|
+
}
|
|
38
|
+
if (reason === 'access_revoked') {
|
|
39
|
+
return new SessionRemovedSubscriptionError('Access to the shared Runtime Host Session was revoked');
|
|
40
|
+
}
|
|
41
|
+
return new RuntimeHostSubscriptionError('slow_consumer', 'Runtime Host Session subscription closed for a slow consumer');
|
|
42
|
+
}
|
|
31
43
|
function errorMessage(error) {
|
|
32
44
|
return error instanceof Error ? error.message : String(error);
|
|
33
45
|
}
|
|
@@ -42,6 +54,16 @@ export class ClientSessionSubscription {
|
|
|
42
54
|
#readyTask;
|
|
43
55
|
#readTranscriptPage;
|
|
44
56
|
#expectedSessionId;
|
|
57
|
+
get transcriptWatermark() {
|
|
58
|
+
return this.#latestTranscriptThroughSequence;
|
|
59
|
+
}
|
|
60
|
+
get deathCause() {
|
|
61
|
+
// #closedReason is recorded at accept()-time, before #terminalError can
|
|
62
|
+
// exist — it is always the authoritative death statement.
|
|
63
|
+
return this.#closedReason === undefined
|
|
64
|
+
? this.#terminalError
|
|
65
|
+
: subscriptionClosedError(this.#closedReason);
|
|
66
|
+
}
|
|
45
67
|
#queue = [];
|
|
46
68
|
#ptyListeners = new Set();
|
|
47
69
|
#sessionDomainListeners = new Set();
|
|
@@ -50,6 +72,7 @@ export class ClientSessionSubscription {
|
|
|
50
72
|
#latestProjectionRevision;
|
|
51
73
|
#waiting;
|
|
52
74
|
#terminalError;
|
|
75
|
+
#closedReason;
|
|
53
76
|
#done = false;
|
|
54
77
|
#doneAfterQueue = false;
|
|
55
78
|
#closing = false;
|
|
@@ -237,7 +260,9 @@ export class ClientSessionSubscription {
|
|
|
237
260
|
}
|
|
238
261
|
}
|
|
239
262
|
#assertTranscriptReadable() {
|
|
240
|
-
if (this.#
|
|
263
|
+
if (this.#terminalError)
|
|
264
|
+
throw this.#terminalError;
|
|
265
|
+
if (this.#closing || this.#done) {
|
|
241
266
|
throw new RuntimeHostSubscriptionError('connection_closed', 'Session subscription closed during transcript loading');
|
|
242
267
|
}
|
|
243
268
|
}
|
|
@@ -318,9 +343,14 @@ export class ClientSessionSubscription {
|
|
|
318
343
|
}
|
|
319
344
|
}
|
|
320
345
|
}
|
|
321
|
-
|
|
322
|
-
|
|
346
|
+
if (frame.kind === 'subscription.closed') {
|
|
347
|
+
// Record the reason before the offer: a full client queue makes #offer
|
|
348
|
+
// throw 'slow_consumer', which would otherwise discard the real reason
|
|
349
|
+
// the Host gave for closing this subscription.
|
|
350
|
+
this.#closedReason = frame.reason;
|
|
323
351
|
this.#doneAfterQueue = true;
|
|
352
|
+
}
|
|
353
|
+
this.#offer(frame);
|
|
324
354
|
}
|
|
325
355
|
finish() {
|
|
326
356
|
this.#ptyListeners.clear();
|
|
@@ -29,13 +29,6 @@ const EFFECT_ERRORS = [
|
|
|
29
29
|
'persistence_failed',
|
|
30
30
|
'commit_outcome_unknown',
|
|
31
31
|
];
|
|
32
|
-
/**
|
|
33
|
-
* Upper bound on the quota windows one usage report may carry. The producer
|
|
34
|
-
* emits three today (5-hour, weekly, monthly); the cap exists because a decoder
|
|
35
|
-
* is the boundary that does not trust its producer, matching how every other
|
|
36
|
-
* array in this package is bounded before mapping.
|
|
37
|
-
*/
|
|
38
|
-
const CONNECTION_USAGE_MAX_WINDOWS = 16;
|
|
39
32
|
export const CONNECTION_EFFECT_CHANGED_DOMAINS = [
|
|
40
33
|
'connection',
|
|
41
34
|
'credential',
|
|
@@ -84,13 +77,6 @@ export const CONNECTION_EFFECT_OPERATION_SPECS = {
|
|
|
84
77
|
decodeInput: decodeConnectionTestRunInput,
|
|
85
78
|
decodeOutput: decodeConnectionTestRunResult,
|
|
86
79
|
}),
|
|
87
|
-
'connection.usage.read': defineOperation({
|
|
88
|
-
mode: 'query',
|
|
89
|
-
availability: 'ready',
|
|
90
|
-
errors: EFFECT_ERRORS,
|
|
91
|
-
decodeInput: decodeConnectionUsageReadInput,
|
|
92
|
-
decodeOutput: decodeConnectionUsageReadResult,
|
|
93
|
-
}),
|
|
94
80
|
};
|
|
95
81
|
export function decodeConnectionOnboardingSaveInput(value) {
|
|
96
82
|
const input = requireExactRecord(value, 'connection onboarding save input', [
|
|
@@ -296,100 +282,6 @@ export function decodeConnectionTestRunResult(value) {
|
|
|
296
282
|
}
|
|
297
283
|
return decodeNonEffectResult(result, 'connection test result');
|
|
298
284
|
}
|
|
299
|
-
export function decodeConnectionUsageReadInput(value) {
|
|
300
|
-
const input = requireExactRecord(value, 'connection usage input', ['connectionId']);
|
|
301
|
-
return { connectionId: requireEntityId(input.connectionId, 'connectionId') };
|
|
302
|
-
}
|
|
303
|
-
export function decodeConnectionUsageReadResult(value) {
|
|
304
|
-
const result = requireRecord(value, 'connection usage result');
|
|
305
|
-
if (result.kind === 'report') {
|
|
306
|
-
const report = requireExactRecord(result, 'connection usage report', ['kind', 'report']);
|
|
307
|
-
return { kind: 'report', report: decodeUsageReport(report.report) };
|
|
308
|
-
}
|
|
309
|
-
if (result.kind === 'unavailable') {
|
|
310
|
-
const unavailable = requireExactRecord(result, 'connection usage unavailable', [
|
|
311
|
-
'kind',
|
|
312
|
-
'reason',
|
|
313
|
-
]);
|
|
314
|
-
if (unavailable.reason !== 'unsupported' &&
|
|
315
|
-
unavailable.reason !== 'network' &&
|
|
316
|
-
unavailable.reason !== 'no-credential' &&
|
|
317
|
-
unavailable.reason !== 'unauthorized') {
|
|
318
|
-
throw invalidProtocolFrame('Invalid connection usage unavailable reason');
|
|
319
|
-
}
|
|
320
|
-
return { kind: 'unavailable', reason: unavailable.reason };
|
|
321
|
-
}
|
|
322
|
-
if (result.kind === 'rejected') {
|
|
323
|
-
const rejected = requireExactRecord(result, 'connection usage result', ['kind', 'reason']);
|
|
324
|
-
return { kind: 'rejected', reason: rejectionReason(rejected.reason) };
|
|
325
|
-
}
|
|
326
|
-
throw invalidProtocolFrame('Invalid connection usage result');
|
|
327
|
-
}
|
|
328
|
-
function decodeUsageReport(value) {
|
|
329
|
-
const report = requireExactRecord(value, 'connection usage report body', [
|
|
330
|
-
'accountLabel',
|
|
331
|
-
'planLabel',
|
|
332
|
-
'stats',
|
|
333
|
-
'windows',
|
|
334
|
-
'periodEnd',
|
|
335
|
-
'partiallyUnauthorized',
|
|
336
|
-
'fetchedAt',
|
|
337
|
-
]);
|
|
338
|
-
if (!Array.isArray(report.windows) || report.windows.length > CONNECTION_USAGE_MAX_WINDOWS) {
|
|
339
|
-
throw invalidProtocolFrame('Invalid connection usage windows');
|
|
340
|
-
}
|
|
341
|
-
return {
|
|
342
|
-
accountLabel: optionalText(report.accountLabel, 'account label'),
|
|
343
|
-
planLabel: optionalText(report.planLabel, 'plan label'),
|
|
344
|
-
stats: report.stats === null ? null : decodeUsageStats(report.stats),
|
|
345
|
-
windows: report.windows.map(decodeUsageWindow),
|
|
346
|
-
periodEnd: optionalMillis(report.periodEnd, 'period end'),
|
|
347
|
-
partiallyUnauthorized: requireBoolean(report.partiallyUnauthorized, 'partially unauthorized'),
|
|
348
|
-
fetchedAt: requireCount(report.fetchedAt, 'usage fetchedAt'),
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
function decodeUsageStats(value) {
|
|
352
|
-
const stats = requireExactRecord(value, 'connection usage stats', [
|
|
353
|
-
'requests',
|
|
354
|
-
'failed',
|
|
355
|
-
'successRate',
|
|
356
|
-
'cost',
|
|
357
|
-
'tokensIn',
|
|
358
|
-
'tokensOut',
|
|
359
|
-
]);
|
|
360
|
-
return {
|
|
361
|
-
requests: optionalCount(stats.requests, 'requests'),
|
|
362
|
-
failed: optionalCount(stats.failed, 'failed'),
|
|
363
|
-
successRate: optionalAmount(stats.successRate, 'success rate'),
|
|
364
|
-
cost: optionalAmount(stats.cost, 'cost'),
|
|
365
|
-
tokensIn: optionalCount(stats.tokensIn, 'tokens in'),
|
|
366
|
-
tokensOut: optionalCount(stats.tokensOut, 'tokens out'),
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
function decodeUsageWindow(value) {
|
|
370
|
-
const window = requireExactRecord(value, 'connection usage window', [
|
|
371
|
-
'id',
|
|
372
|
-
'label',
|
|
373
|
-
'used',
|
|
374
|
-
'cap',
|
|
375
|
-
'unit',
|
|
376
|
-
'resetsAt',
|
|
377
|
-
'unlimited',
|
|
378
|
-
]);
|
|
379
|
-
const unit = window.unit;
|
|
380
|
-
if (unit !== 'credits' && unit !== 'usd' && unit !== 'tokens') {
|
|
381
|
-
throw invalidProtocolFrame('Invalid connection usage unit');
|
|
382
|
-
}
|
|
383
|
-
return {
|
|
384
|
-
id: requireUtf8String(window.id, 'usage window id', 64),
|
|
385
|
-
label: optionalText(window.label, 'usage window label'),
|
|
386
|
-
used: requireAmount(window.used, 'usage window used'),
|
|
387
|
-
cap: requireAmount(window.cap, 'usage window cap'),
|
|
388
|
-
unit,
|
|
389
|
-
resetsAt: optionalMillis(window.resetsAt, 'usage window reset'),
|
|
390
|
-
unlimited: window.unlimited === null ? null : requireBoolean(window.unlimited, 'unlimited'),
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
285
|
function optionalText(value, label) {
|
|
394
286
|
return value === null ? null : requireUtf8String(value, label, 256);
|
|
395
287
|
}
|
|
@@ -62,7 +62,18 @@ export const RUNTIME_HOST_REGISTRATION_SCHEMA_VERSION = 1;
|
|
|
62
62
|
export const RUNTIME_HOST_PROTOCOL_VERSION = 0;
|
|
63
63
|
// Increment when the same protocol version no longer guarantees safe Client-Host
|
|
64
64
|
// interoperability. Mismatches are rejected before domain commands are admitted.
|
|
65
|
-
export const RUNTIME_HOST_COMPATIBILITY_EPOCH =
|
|
65
|
+
export const RUNTIME_HOST_COMPATIBILITY_EPOCH = 172;
|
|
66
|
+
// 172: Usage screen requests and results accept fractional timestamps in the
|
|
67
|
+
// persisted domain. Older peers reject these otherwise valid wire values.
|
|
68
|
+
// 171: Removed the `connection.usage.read` operation along with the Command
|
|
69
|
+
// Code GO provider it served. A peer older than this epoch may still advertise
|
|
70
|
+
// or submit that operation, which this Host no longer answers.
|
|
71
|
+
// 169: The message execution query reports an identity the Host can prove was
|
|
72
|
+
// never admitted as a positive `not_admitted` resolution instead of omitting
|
|
73
|
+
// it, so silence stops meaning both "not admitted" and "cannot say yet".
|
|
74
|
+
// Epoch-168 peers reject the new state as an invalid frame.
|
|
75
|
+
// 167: Removed the turn.regenerate operation. Older peers can no longer
|
|
76
|
+
// safely interoperate because they may submit or advertise that operation.
|
|
66
77
|
// 166: Connection usage reads add an operation, an accepted availability reason
|
|
67
78
|
// (`unauthorized`), a report field (`partiallyUnauthorized`), and a bounded
|
|
68
79
|
// window list. Peers older than this epoch take the added operation for an
|
|
@@ -200,6 +200,16 @@ function decodeTurnMessageExecutionQueryResult(value) {
|
|
|
200
200
|
state: 'cancelled',
|
|
201
201
|
};
|
|
202
202
|
}
|
|
203
|
+
if (resolution.state === 'not_admitted') {
|
|
204
|
+
assertExactKeys(resolution, 'turn.message.execution.query not_admitted resolution', [
|
|
205
|
+
'messageId',
|
|
206
|
+
'state',
|
|
207
|
+
]);
|
|
208
|
+
return {
|
|
209
|
+
messageId: requireEntityId(resolution.messageId, 'messageId'),
|
|
210
|
+
state: 'not_admitted',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
203
213
|
if (resolution.state === 'owned') {
|
|
204
214
|
assertExactKeys(resolution, 'turn.message.execution.query owned resolution', [
|
|
205
215
|
'messageId',
|
|
@@ -22,7 +22,6 @@ import { AGENT_GRAPH_OPERATION_SPECS } from './agent-graph.js';
|
|
|
22
22
|
import { requireExactRecord, requireId, requireRecord, requireString } from './codec.js';
|
|
23
23
|
import { CONNECTION_EFFECT_OPERATION_SPECS } from './connection-effects.js';
|
|
24
24
|
import { CONFIGURATION_OPERATION_SPECS } from './configuration.js';
|
|
25
|
-
import { DEEP_RESEARCH_OPERATION_SPECS } from './deep-research.js';
|
|
26
25
|
import { DAILY_REVIEW_OPERATION_SPECS } from './daily-review.js';
|
|
27
26
|
import { CONTEXT_OPERATION_SPECS } from './context.js';
|
|
28
27
|
import { EXECUTION_INSPECT_OPERATION_SPECS } from './execution-inspect.js';
|
|
@@ -61,6 +60,7 @@ import { SKILL_CATALOG_OPERATION_SPECS } from './skill-catalog.js';
|
|
|
61
60
|
import { TURN_OPERATION_SPECS } from './turn.js';
|
|
62
61
|
import { USAGE_PRICING_OPERATION_SPECS } from './usage-pricing.js';
|
|
63
62
|
import { WEB_SEARCH_OPERATION_SPECS } from './web-search.js';
|
|
63
|
+
import { RECALL_OPERATION_SPECS } from './recall.js';
|
|
64
64
|
import { WORKHUB_COORDINATION_OPERATION_SPECS } from './workhub-coordination.js';
|
|
65
65
|
export { isHostActivityIdle } from './host-status.js';
|
|
66
66
|
export { ARTIFACT_CURSOR_MAX_BYTES, ARTIFACT_INGEST_CHUNK_MAX_BYTES, ARTIFACT_INGEST_MIME_TYPE_MAX_BYTES, ARTIFACT_MIME_TYPE_MAX_BYTES, ARTIFACT_NAME_MAX_BYTES, ARTIFACT_PAGE_MAX_ITEMS, ARTIFACT_PREVIEW_MAX_BYTES, ARTIFACT_READ_CHUNK_MAX_BYTES, ARTIFACT_RESULT_MAX_BYTES, ARTIFACT_SUMMARY_MAX_BYTES, decodeArtifactDeleteInput, decodeArtifactDeleteResult, decodeArtifactIngestInput, decodeArtifactIngestResult, decodeArtifactQueryInput, decodeArtifactQueryResult, encodeArtifactDeleteResult, encodeArtifactQueryResult, } from './artifact.js';
|
|
@@ -68,7 +68,6 @@ export { TURN_FAILURE_MESSAGE_MAX_BYTES, TURN_MESSAGE_CONTENT_MAX_BYTES, TURN_ME
|
|
|
68
68
|
export * from './connection-effects.js';
|
|
69
69
|
export * from './access-authority.js';
|
|
70
70
|
export * from './configuration.js';
|
|
71
|
-
export * from './deep-research.js';
|
|
72
71
|
export * from './daily-review.js';
|
|
73
72
|
export * from './context.js';
|
|
74
73
|
export * from './agent-graph.js';
|
|
@@ -97,8 +96,9 @@ export * from './session-effects.js';
|
|
|
97
96
|
export * from './skill-catalog.js';
|
|
98
97
|
export * from './usage-pricing.js';
|
|
99
98
|
export * from './web-search.js';
|
|
99
|
+
export * from './recall.js';
|
|
100
100
|
export * from './workspace.js';
|
|
101
|
-
export const HOST_OPERATION_SPECS = composeOperationSpecMaps(HOST_BOOTSTRAP_OPERATION_SPECS, HOST_RESOURCE_OPERATION_SPECS, PEER_MESH_OPERATION_SPECS, HOSTED_EXECUTION_OPERATION_SPECS, ACCESS_AUTHORITY_OPERATION_SPECS, SESSION_COLLABORATION_OPERATION_SPECS, AGENT_GRAPH_OPERATION_SPECS, GOAL_OPERATION_SPECS, TURN_OPERATION_SPECS, CONTEXT_OPERATION_SPECS, CONNECTION_EFFECT_OPERATION_SPECS,
|
|
101
|
+
export const HOST_OPERATION_SPECS = composeOperationSpecMaps(HOST_BOOTSTRAP_OPERATION_SPECS, HOST_RESOURCE_OPERATION_SPECS, PEER_MESH_OPERATION_SPECS, HOSTED_EXECUTION_OPERATION_SPECS, ACCESS_AUTHORITY_OPERATION_SPECS, SESSION_COLLABORATION_OPERATION_SPECS, AGENT_GRAPH_OPERATION_SPECS, GOAL_OPERATION_SPECS, TURN_OPERATION_SPECS, CONTEXT_OPERATION_SPECS, CONNECTION_EFFECT_OPERATION_SPECS, DAILY_REVIEW_OPERATION_SPECS, EXECUTION_INSPECT_OPERATION_SPECS, EXTERNAL_SESSION_OPERATION_SPECS, RUNTIME_POLICY_OPERATION_SPECS, RUNTIME_RESOURCE_OPERATION_SPECS, SCHEDULED_TASK_OPERATION_SPECS, PLAN_OPERATION_SPECS, PROJECT_CATALOG_OPERATION_SPECS, MESSAGE_OPERATION_SPECS, SESSION_TODO_OPERATION_SPECS, INTERACTION_OPERATION_SPECS, SESSION_CONTINUITY_OPERATION_SPECS, SESSION_TRANSCRIPT_OPERATION_SPECS, SESSION_TURNS_OPERATION_SPECS, SESSION_CATALOG_OPERATION_SPECS, SESSION_EFFECT_OPERATION_SPECS, SESSION_REVISION_OPERATION_SPECS, SESSION_BUNDLE_OPERATION_SPECS, SESSION_RETIREMENT_OPERATION_SPECS, ARTIFACT_OPERATION_SPECS, SKILL_CATALOG_OPERATION_SPECS, USAGE_PRICING_OPERATION_SPECS, MEMORY_OPERATION_SPECS, OAUTH_OPERATION_SPECS, EXTERNAL_AGENT_SETUP_OPERATION_SPECS, CLIENT_CAPABILITY_OPERATION_SPECS, WEB_SEARCH_OPERATION_SPECS, NETWORK_PROXY_OPERATION_SPECS, RECALL_OPERATION_SPECS, CONFIGURATION_OPERATION_SPECS, WORKHUB_COORDINATION_OPERATION_SPECS, PLUGIN_PLATFORM_OPERATION_SPECS);
|
|
102
102
|
// Remote credentials are fail-closed: adding a protocol operation does not
|
|
103
103
|
// grant it to remote owners until this policy is deliberately updated.
|
|
104
104
|
export const REMOTE_OWNER_OPERATION_GRANTS = Object.freeze([
|
|
@@ -131,7 +131,6 @@ export const REMOTE_OWNER_OPERATION_GRANTS = Object.freeze([
|
|
|
131
131
|
'connection.request-headers.query',
|
|
132
132
|
'connection.request-headers.replace',
|
|
133
133
|
'connection.test.run',
|
|
134
|
-
'connection.usage.read',
|
|
135
134
|
'context.compact',
|
|
136
135
|
'context.diagnostics.query',
|
|
137
136
|
'credential.vault.delete',
|
|
@@ -139,7 +138,6 @@ export const REMOTE_OWNER_OPERATION_GRANTS = Object.freeze([
|
|
|
139
138
|
'credential.vault.set',
|
|
140
139
|
'daily-review.mutate',
|
|
141
140
|
'daily-review.query',
|
|
142
|
-
'deep-research.query',
|
|
143
141
|
'execution.inspect.query',
|
|
144
142
|
'external-session.catalog.query',
|
|
145
143
|
'external-session.import',
|
|
@@ -179,6 +177,7 @@ export const REMOTE_OWNER_OPERATION_GRANTS = Object.freeze([
|
|
|
179
177
|
'runtime.policy.mutate',
|
|
180
178
|
'runtime.policy.network-proxy.update',
|
|
181
179
|
'runtime.policy.query',
|
|
180
|
+
'recall.query',
|
|
182
181
|
'runtime.resource.controller.acquire',
|
|
183
182
|
'runtime.resource.controller.control',
|
|
184
183
|
'runtime.resource.controller.release',
|
|
@@ -219,7 +218,6 @@ export const REMOTE_OWNER_OPERATION_GRANTS = Object.freeze([
|
|
|
219
218
|
'turn.message.query',
|
|
220
219
|
'turn.message.submit',
|
|
221
220
|
'turn.query',
|
|
222
|
-
'turn.regenerate',
|
|
223
221
|
'turn.resume.query',
|
|
224
222
|
'turn.resume.start',
|
|
225
223
|
'turn.start',
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
|
4
|
+
* distributed with this work for additional information
|
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
|
7
|
+
* "License"); you may not use this file except in compliance
|
|
8
|
+
* with the License. You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* `recall.query` — the retrieval surface a Client can ask for directly.
|
|
21
|
+
*
|
|
22
|
+
* Recall runs inside the Host because that is where the corpus lives: the
|
|
23
|
+
* Session manager, the distilled-fact store, and the material fetch are all
|
|
24
|
+
* Host-owned. A Client cannot perform it itself without pulling every
|
|
25
|
+
* transcript across the boundary, which is exactly the arrangement this
|
|
26
|
+
* operation replaces.
|
|
27
|
+
*
|
|
28
|
+
* The wire shape mirrors what the model's `Recall` tool already returns
|
|
29
|
+
* (`@maka/runtime/recall-tools`), with this protocol's camelCase field naming.
|
|
30
|
+
* That is deliberate: one recall answer, two presentations. A UI renders
|
|
31
|
+
* passages as navigable results and a model reads them as context, and neither
|
|
32
|
+
* gets a second implementation to drift from.
|
|
33
|
+
*/
|
|
34
|
+
import { RECALL_MAX_LIMIT, RECALL_MAX_TERMS, RECALL_TOTAL_PAYLOAD_CAP_BYTES, } from '@maka/core/recall';
|
|
35
|
+
import { SEARCH_QUERY_MAX_CHARS } from '@maka/core/search';
|
|
36
|
+
import { requireCount, requireEncodedByteLimit, requireEntityId, requireShapedRecord, requireUtf8String, } from './codec.js';
|
|
37
|
+
import { invalidProtocolFrame } from './errors.js';
|
|
38
|
+
import { defineOperation } from './operation-spec.js';
|
|
39
|
+
export const RECALL_QUERY_TERM_MAX_CHARS = SEARCH_QUERY_MAX_CHARS;
|
|
40
|
+
/**
|
|
41
|
+
* Byte ceiling for one term. Core measures a term in code points
|
|
42
|
+
* (`Array.from(term).length`), so the wire bound is that count times the
|
|
43
|
+
* widest UTF-8 encoding of one code point. A term that passes here can still
|
|
44
|
+
* be rejected by core on the character count; this only stops a frame that
|
|
45
|
+
* could not represent a legal term at all.
|
|
46
|
+
*/
|
|
47
|
+
const RECALL_QUERY_TERM_MAX_BYTES = RECALL_QUERY_TERM_MAX_CHARS * 4;
|
|
48
|
+
export const RECALL_QUERY_QUESTION_MAX_BYTES = 2 * 1024;
|
|
49
|
+
export const RECALL_QUERY_TEXT_MAX_BYTES = 32 * 1024;
|
|
50
|
+
export const RECALL_QUERY_MATERIAL_NAME_MAX_BYTES = 1024;
|
|
51
|
+
export const RECALL_QUERY_RESOURCE_MAX_BYTES = 1024;
|
|
52
|
+
/**
|
|
53
|
+
* Encoded ceiling for one envelope. Recall caps its own payload at
|
|
54
|
+
* `RECALL_TOTAL_PAYLOAD_CAP_BYTES`, but that counts passage text only; the
|
|
55
|
+
* envelope adds field names, message ids, timestamps and materials on top.
|
|
56
|
+
* This bound is that cap plus generous structural headroom, so it rejects a
|
|
57
|
+
* frame that no honest Host could have produced without constraining one that
|
|
58
|
+
* did.
|
|
59
|
+
*/
|
|
60
|
+
export const RECALL_QUERY_RESULT_MAX_BYTES = RECALL_TOTAL_PAYLOAD_CAP_BYTES + 64 * 1024;
|
|
61
|
+
const RECALL_FAILURE_REASONS = [
|
|
62
|
+
'invalid_query',
|
|
63
|
+
'incognito_active',
|
|
64
|
+
'not_found',
|
|
65
|
+
'aborted',
|
|
66
|
+
];
|
|
67
|
+
const RECALL_ROLES = ['user', 'assistant', 'tool'];
|
|
68
|
+
const RECALL_MATERIAL_KINDS = ['image', 'pdf', 'doc', 'code', 'other'];
|
|
69
|
+
const ERROR_CODES = [
|
|
70
|
+
'host_not_ready',
|
|
71
|
+
'host_draining',
|
|
72
|
+
'operation_unavailable',
|
|
73
|
+
'invalid_request',
|
|
74
|
+
'internal_failure',
|
|
75
|
+
];
|
|
76
|
+
export const RECALL_OPERATION_SPECS = {
|
|
77
|
+
'recall.query': defineOperation({
|
|
78
|
+
mode: 'query',
|
|
79
|
+
availability: 'ready',
|
|
80
|
+
errors: ERROR_CODES,
|
|
81
|
+
decodeInput: decodeRecallQueryInput,
|
|
82
|
+
decodeOutput: decodeRecallQueryResult,
|
|
83
|
+
}),
|
|
84
|
+
};
|
|
85
|
+
function decodeRecallQueryInput(value) {
|
|
86
|
+
const record = requireShapedRecord(value, 'Recall query input', ['terms'], ['question', 'limit', 'sessionId', 'since', 'until']);
|
|
87
|
+
if (!Array.isArray(record.terms) || record.terms.length === 0) {
|
|
88
|
+
throw invalidProtocolFrame('Invalid Recall terms');
|
|
89
|
+
}
|
|
90
|
+
if (record.terms.length > RECALL_MAX_TERMS) {
|
|
91
|
+
throw invalidProtocolFrame('Too many Recall terms');
|
|
92
|
+
}
|
|
93
|
+
const terms = record.terms.map((term) => requireUtf8String(term, 'Recall term', RECALL_QUERY_TERM_MAX_BYTES));
|
|
94
|
+
const limit = record.limit === undefined ? undefined : requireCount(record.limit, 'Recall limit');
|
|
95
|
+
if (limit !== undefined && (limit < 1 || limit > RECALL_MAX_LIMIT)) {
|
|
96
|
+
throw invalidProtocolFrame('Invalid Recall limit');
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
terms,
|
|
100
|
+
...(record.question === undefined
|
|
101
|
+
? {}
|
|
102
|
+
: {
|
|
103
|
+
question: requireUtf8String(record.question, 'Recall question', RECALL_QUERY_QUESTION_MAX_BYTES),
|
|
104
|
+
}),
|
|
105
|
+
...(limit === undefined ? {} : { limit }),
|
|
106
|
+
...(record.sessionId === undefined
|
|
107
|
+
? {}
|
|
108
|
+
: { sessionId: requireEntityId(record.sessionId, 'Recall sessionId') }),
|
|
109
|
+
...(record.since === undefined ? {} : { since: requireCount(record.since, 'Recall since') }),
|
|
110
|
+
...(record.until === undefined ? {} : { until: requireCount(record.until, 'Recall until') }),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Bounded text that may be empty. Transcript text is legitimately empty when a
|
|
115
|
+
* message carried only files, and a Session title is empty for an unnamed
|
|
116
|
+
* Session; both are legal answers, so they must not be rejected as malformed.
|
|
117
|
+
*/
|
|
118
|
+
function requireBoundedText(value, label, maxBytes) {
|
|
119
|
+
if (typeof value !== 'string' || Buffer.byteLength(value, 'utf8') > maxBytes) {
|
|
120
|
+
throw invalidProtocolFrame(`Invalid ${label}`);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
function decodeRecallQueryResult(value) {
|
|
125
|
+
requireEncodedByteLimit(value, 'Recall query result', RECALL_QUERY_RESULT_MAX_BYTES);
|
|
126
|
+
const record = requireShapedRecord(value, 'Recall query result', ['ok'], ['facts', 'passages', 'gaps', 'searchedEverySession', 'reason', 'message']);
|
|
127
|
+
if (record.ok === false) {
|
|
128
|
+
const exact = requireShapedRecord(record, 'Recall error result', ['ok', 'reason', 'message'], []);
|
|
129
|
+
if (typeof exact.reason !== 'string' ||
|
|
130
|
+
!RECALL_FAILURE_REASONS.includes(exact.reason)) {
|
|
131
|
+
throw invalidProtocolFrame('Invalid Recall failure reason');
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
ok: false,
|
|
135
|
+
reason: exact.reason,
|
|
136
|
+
message: requireUtf8String(exact.message, 'Recall failure message', RECALL_QUERY_TEXT_MAX_BYTES),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (record.ok !== true)
|
|
140
|
+
throw invalidProtocolFrame('Invalid Recall query result kind');
|
|
141
|
+
const exact = requireShapedRecord(record, 'Recall success result', ['ok', 'facts', 'passages', 'gaps', 'searchedEverySession'], []);
|
|
142
|
+
if (!Array.isArray(exact.facts) || !Array.isArray(exact.passages)) {
|
|
143
|
+
throw invalidProtocolFrame('Invalid Recall success result');
|
|
144
|
+
}
|
|
145
|
+
if (typeof exact.searchedEverySession !== 'boolean') {
|
|
146
|
+
throw invalidProtocolFrame('Invalid Recall searchedEverySession');
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
ok: true,
|
|
150
|
+
facts: exact.facts.map((fact) => decodeFact(fact)),
|
|
151
|
+
passages: exact.passages.map((passage) => decodePassage(passage)),
|
|
152
|
+
gaps: requireUtf8String(exact.gaps, 'Recall gaps', RECALL_QUERY_TEXT_MAX_BYTES),
|
|
153
|
+
searchedEverySession: exact.searchedEverySession,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function decodeFact(value) {
|
|
157
|
+
const record = requireShapedRecord(value, 'Recall fact', ['content', 'kind', 'observedAt'], []);
|
|
158
|
+
return {
|
|
159
|
+
content: requireUtf8String(record.content, 'Recall fact content', RECALL_QUERY_TEXT_MAX_BYTES),
|
|
160
|
+
kind: requireUtf8String(record.kind, 'Recall fact kind', RECALL_QUERY_MATERIAL_NAME_MAX_BYTES),
|
|
161
|
+
observedAt: requireCount(record.observedAt, 'Recall fact observedAt'),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function decodePassage(value) {
|
|
165
|
+
const record = requireShapedRecord(value, 'Recall passage', [
|
|
166
|
+
'sessionId',
|
|
167
|
+
'sessionTitle',
|
|
168
|
+
'anchorMessageId',
|
|
169
|
+
'sequence',
|
|
170
|
+
'messages',
|
|
171
|
+
'matchedTerms',
|
|
172
|
+
'score',
|
|
173
|
+
'hasMoreBefore',
|
|
174
|
+
'hasMoreAfter',
|
|
175
|
+
], ['turnId', 'lastMessageAt', 'truncated']);
|
|
176
|
+
if (!Array.isArray(record.messages) || !Array.isArray(record.matchedTerms)) {
|
|
177
|
+
throw invalidProtocolFrame('Invalid Recall passage messages');
|
|
178
|
+
}
|
|
179
|
+
if (typeof record.score !== 'number' || !Number.isFinite(record.score)) {
|
|
180
|
+
throw invalidProtocolFrame('Invalid Recall passage score');
|
|
181
|
+
}
|
|
182
|
+
if (typeof record.hasMoreBefore !== 'boolean' || typeof record.hasMoreAfter !== 'boolean') {
|
|
183
|
+
throw invalidProtocolFrame('Invalid Recall passage continuation flags');
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
sessionId: requireEntityId(record.sessionId, 'Recall passage sessionId'),
|
|
187
|
+
sessionTitle: requireBoundedText(record.sessionTitle, 'Recall passage sessionTitle', RECALL_QUERY_TEXT_MAX_BYTES),
|
|
188
|
+
...(record.turnId === undefined
|
|
189
|
+
? {}
|
|
190
|
+
: { turnId: requireEntityId(record.turnId, 'Recall passage turnId') }),
|
|
191
|
+
anchorMessageId: requireEntityId(record.anchorMessageId, 'Recall passage anchorMessageId'),
|
|
192
|
+
sequence: requireCount(record.sequence, 'Recall passage sequence'),
|
|
193
|
+
messages: record.messages.map((message) => decodePassageMessage(message)),
|
|
194
|
+
matchedTerms: record.matchedTerms.map((term) => requireUtf8String(term, 'Recall matched term', RECALL_QUERY_TERM_MAX_BYTES)),
|
|
195
|
+
score: record.score,
|
|
196
|
+
...(record.lastMessageAt === undefined
|
|
197
|
+
? {}
|
|
198
|
+
: { lastMessageAt: requireCount(record.lastMessageAt, 'Recall passage lastMessageAt') }),
|
|
199
|
+
hasMoreBefore: record.hasMoreBefore,
|
|
200
|
+
hasMoreAfter: record.hasMoreAfter,
|
|
201
|
+
...(record.truncated === undefined
|
|
202
|
+
? {}
|
|
203
|
+
: record.truncated === true
|
|
204
|
+
? { truncated: true }
|
|
205
|
+
: (() => {
|
|
206
|
+
throw invalidProtocolFrame('Invalid Recall passage truncated flag');
|
|
207
|
+
})()),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function decodePassageMessage(value) {
|
|
211
|
+
const record = requireShapedRecord(value, 'Recall passage message', ['messageId', 'role', 'matchKind', 'text', 'timestamp', 'isAnchor'], ['materials']);
|
|
212
|
+
if (typeof record.role !== 'string' ||
|
|
213
|
+
!RECALL_ROLES.includes(record.role)) {
|
|
214
|
+
throw invalidProtocolFrame('Invalid Recall passage message role');
|
|
215
|
+
}
|
|
216
|
+
if (typeof record.isAnchor !== 'boolean') {
|
|
217
|
+
throw invalidProtocolFrame('Invalid Recall passage message anchor flag');
|
|
218
|
+
}
|
|
219
|
+
if (record.materials !== undefined && !Array.isArray(record.materials)) {
|
|
220
|
+
throw invalidProtocolFrame('Invalid Recall passage message materials');
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
messageId: requireEntityId(record.messageId, 'Recall passage messageId'),
|
|
224
|
+
role: record.role,
|
|
225
|
+
matchKind: requireUtf8String(record.matchKind, 'Recall passage message matchKind', RECALL_QUERY_MATERIAL_NAME_MAX_BYTES),
|
|
226
|
+
// A message whose whole content was a pasted file carries no text of its
|
|
227
|
+
// own; the material beside it is the point. Empty is legal here, unlike
|
|
228
|
+
// the identifiers around it.
|
|
229
|
+
text: requireBoundedText(record.text, 'Recall passage message text', RECALL_QUERY_TEXT_MAX_BYTES),
|
|
230
|
+
timestamp: requireCount(record.timestamp, 'Recall passage message timestamp'),
|
|
231
|
+
isAnchor: record.isAnchor,
|
|
232
|
+
...(record.materials === undefined
|
|
233
|
+
? {}
|
|
234
|
+
: { materials: record.materials.map((material) => decodeMaterial(material)) }),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function decodeMaterial(value) {
|
|
238
|
+
const record = requireShapedRecord(value, 'Recall material', ['name', 'kind', 'mimeType', 'bytes'], ['resource', 'sourceSessionId', 'materialId']);
|
|
239
|
+
if (typeof record.kind !== 'string' ||
|
|
240
|
+
!RECALL_MATERIAL_KINDS.includes(record.kind)) {
|
|
241
|
+
throw invalidProtocolFrame('Invalid Recall material kind');
|
|
242
|
+
}
|
|
243
|
+
const resource = record.resource === undefined
|
|
244
|
+
? undefined
|
|
245
|
+
: requireUtf8String(record.resource, 'Recall material resource', RECALL_QUERY_RESOURCE_MAX_BYTES);
|
|
246
|
+
const sourceSessionId = record.sourceSessionId === undefined
|
|
247
|
+
? undefined
|
|
248
|
+
: requireEntityId(record.sourceSessionId, 'Recall material sourceSessionId');
|
|
249
|
+
const materialId = record.materialId === undefined
|
|
250
|
+
? undefined
|
|
251
|
+
: requireEntityId(record.materialId, 'Recall material materialId');
|
|
252
|
+
// An address says "read this now"; a location says "ask for it". Carrying
|
|
253
|
+
// both would offer a caller two answers to one question, so recall never
|
|
254
|
+
// emits both and the decoder refuses the shape rather than picking a winner.
|
|
255
|
+
if (resource !== undefined && (sourceSessionId !== undefined || materialId !== undefined)) {
|
|
256
|
+
throw invalidProtocolFrame('Invalid Recall material location');
|
|
257
|
+
}
|
|
258
|
+
if ((sourceSessionId === undefined) !== (materialId === undefined)) {
|
|
259
|
+
throw invalidProtocolFrame('Incomplete Recall material location');
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
name: requireUtf8String(record.name, 'Recall material name', RECALL_QUERY_MATERIAL_NAME_MAX_BYTES),
|
|
263
|
+
kind: record.kind,
|
|
264
|
+
mimeType: requireUtf8String(record.mimeType, 'Recall material mimeType', RECALL_QUERY_MATERIAL_NAME_MAX_BYTES),
|
|
265
|
+
bytes: requireCount(record.bytes, 'Recall material bytes'),
|
|
266
|
+
...(resource === undefined ? {} : { resource }),
|
|
267
|
+
...(sourceSessionId === undefined ? {} : { sourceSessionId }),
|
|
268
|
+
...(materialId === undefined ? {} : { materialId }),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
@@ -273,7 +273,7 @@ export function decodeSessionCreateInput(value) {
|
|
|
273
273
|
...(target ? { modelTarget: target } : {}),
|
|
274
274
|
...(executorId ? { executorId } : {}),
|
|
275
275
|
...(Object.hasOwn(input, 'thinkingLevel')
|
|
276
|
-
? { thinkingLevel: thinkingLevel(input.thinkingLevel) }
|
|
276
|
+
? { thinkingLevel: input.thinkingLevel === null ? null : thinkingLevel(input.thinkingLevel) }
|
|
277
277
|
: {}),
|
|
278
278
|
...(Object.hasOwn(input, 'toolProfile')
|
|
279
279
|
? { toolProfile: sessionToolProfile(input.toolProfile) }
|
|
@@ -47,13 +47,7 @@ export const SESSION_TOOL_INTENT_MAX_BYTES = 512;
|
|
|
47
47
|
export const SESSION_TOOL_ARGS_PREVIEW_MAX_BYTES = 8 * 1024;
|
|
48
48
|
export const SESSION_SUBSCRIPTION_FRAME_MAX_BYTES = 64 * 1024 - 1;
|
|
49
49
|
export const SESSION_RUNTIME_RESOURCE_PTY_DATA_MAX_BYTES = 48 * 1024;
|
|
50
|
-
export const SESSION_DOMAINS = [
|
|
51
|
-
'todo',
|
|
52
|
-
'plan',
|
|
53
|
-
'deep_research',
|
|
54
|
-
'usage',
|
|
55
|
-
'runtime_resource',
|
|
56
|
-
];
|
|
50
|
+
export const SESSION_DOMAINS = ['todo', 'plan', 'usage', 'runtime_resource'];
|
|
57
51
|
export const SESSION_RUNTIME_RESOURCE_CHANGES_MAX = 64;
|
|
58
52
|
const SUBSCRIPTION_OPEN_ERRORS = [
|
|
59
53
|
'transcript_preparing',
|
|
@@ -96,27 +96,6 @@ export const TURN_OPERATION_SPECS = {
|
|
|
96
96
|
decodeInput: decodeTurnStopInput,
|
|
97
97
|
decodeOutput: decodeTurnSnapshot,
|
|
98
98
|
}),
|
|
99
|
-
'turn.regenerate': defineOperation({
|
|
100
|
-
mode: 'command',
|
|
101
|
-
availability: 'ready',
|
|
102
|
-
errors: [
|
|
103
|
-
'host_not_ready',
|
|
104
|
-
'host_draining',
|
|
105
|
-
'operation_unavailable',
|
|
106
|
-
'not_found',
|
|
107
|
-
'session_archived',
|
|
108
|
-
'session_busy',
|
|
109
|
-
'operation_conflict',
|
|
110
|
-
'internal_failure',
|
|
111
|
-
],
|
|
112
|
-
decodeInput: decodeTurnRegenerateInput,
|
|
113
|
-
decodeOutput: decodeTurnSnapshot,
|
|
114
|
-
assertOutputForInput: (input, output) => {
|
|
115
|
-
if (input.sessionId !== output.sessionId || input.turnId !== output.turnId) {
|
|
116
|
-
throw invalidProtocolFrame('Turn regenerate changed operation identity');
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
}),
|
|
120
99
|
'turn.resume.query': defineOperation({
|
|
121
100
|
mode: 'query',
|
|
122
101
|
availability: 'ready',
|
|
@@ -317,18 +296,6 @@ function decodeTurnStopInput(value) {
|
|
|
317
296
|
runId: requireEntityId(record.runId, 'runId'),
|
|
318
297
|
};
|
|
319
298
|
}
|
|
320
|
-
function decodeTurnRegenerateInput(value) {
|
|
321
|
-
const record = requireExactRecord(value, 'turn.regenerate input', [
|
|
322
|
-
'sessionId',
|
|
323
|
-
'sourceTurnId',
|
|
324
|
-
'turnId',
|
|
325
|
-
]);
|
|
326
|
-
return {
|
|
327
|
-
sessionId: requireEntityId(record.sessionId, 'sessionId'),
|
|
328
|
-
sourceTurnId: requireEntityId(record.sourceTurnId, 'sourceTurnId'),
|
|
329
|
-
turnId: requireEntityId(record.turnId, 'turnId'),
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
299
|
function decodeTurnResumeQueryInput(value) {
|
|
333
300
|
const record = requireShapedRecord(value, 'turn.resume.query input', ['sessionId'], ['sourceRunId', 'expectedRuntimeEventHighWater']);
|
|
334
301
|
if (record.expectedRuntimeEventHighWater !== undefined && record.sourceRunId === undefined) {
|