maka-agent 0.2.0-dev.24.20260907 → 0.2.0-dev.26.20260909
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -19
- package/README.zh-CN.md +34 -19
- package/dist/mcp-capability-provider.js +4 -1
- package/dist/pi-transcript-tools.js +6 -0
- package/dist/pi-tui-layout.js +56 -10
- package/dist/pi-tui-mcp-status.js +2 -2
- package/dist/pi-tui-pickers.js +121 -30
- package/dist/pi-tui-runner.js +156 -42
- package/dist/pi-tui-todo.js +221 -0
- package/dist/pi-tui-transcript-viewer.js +134 -7
- package/dist/runtime-host-cli-context.js +70 -13
- package/dist/runtime-host-handoff-surface.js +51 -26
- package/dist/runtime-host-local-handoff.js +11 -1
- package/dist/runtime-host-service-manager.js +0 -3
- package/dist/runtime-host-session-channel.js +13 -0
- package/dist/runtime-host-session-driver.js +42 -1
- package/dist/tui-autocomplete-layout.js +3 -1
- package/dist/tui-copy-catalog.js +85 -6
- package/dist/tui-editor-render.js +36 -0
- package/dist/tui-mcp-control.js +41 -6
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@maka/core/dist/agent-run.js +1 -0
- package/node_modules/@maka/core/dist/attachments.js +3 -0
- package/node_modules/@maka/core/dist/canonical-json.js +27 -0
- package/node_modules/@maka/core/dist/capabilities.js +35 -0
- package/node_modules/@maka/core/dist/computer-use.js +0 -1
- package/node_modules/@maka/core/dist/display-redaction.js +18 -0
- package/node_modules/@maka/core/dist/llm-connections.js +13 -0
- package/node_modules/@maka/core/dist/model-call-attempt.js +2 -0
- package/node_modules/@maka/core/dist/model-metadata.js +4 -0
- package/node_modules/@maka/core/dist/redaction.js +35 -0
- package/node_modules/@maka/core/dist/run-composition.js +77 -2
- package/node_modules/@maka/core/dist/runtime-event.js +3 -0
- package/node_modules/@maka/core/dist/session.js +57 -6
- package/node_modules/@maka/core/dist/slash-command-catalog.js +1 -0
- package/node_modules/@maka/core/dist/tool-result-record-schema.js +2 -1
- package/node_modules/@maka/core/dist/workhub-action-result.js +68 -0
- package/node_modules/@maka/core/package.json +3 -3
- package/node_modules/@maka/eval/dist/experiment-directory.js +4 -13
- package/node_modules/@maka/eval/dist/toolchain-verification.js +1 -1
- package/node_modules/@maka/mcp/dist/form-elicitation.js +213 -0
- package/node_modules/@maka/mcp/dist/index.js +337 -71
- package/node_modules/@maka/runtime/dist/agent-run-inspect.js +0 -13
- package/node_modules/@maka/runtime/dist/agent-run.js +90 -2
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +16 -8
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +57 -50
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +2 -2
- package/node_modules/@maka/runtime/dist/context-budget-helpers.js +0 -16
- package/node_modules/@maka/runtime/dist/conversation-copy.js +153 -11
- package/node_modules/@maka/runtime/dist/github-copilot-oauth-enrollment.js +3 -3
- package/node_modules/@maka/runtime/dist/goal-continuation.js +5 -1
- package/node_modules/@maka/runtime/dist/ledger-tool-result-archive-reader.js +69 -1
- package/node_modules/@maka/runtime/dist/mcp-tools.js +7 -2
- package/node_modules/@maka/runtime/dist/model-fetcher.js +42 -2
- package/node_modules/@maka/runtime/dist/model-history.js +0 -112
- package/node_modules/@maka/runtime/dist/plugin-runtime.js +20 -10
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +205 -0
- package/node_modules/@maka/runtime/dist/provider-request-telemetry.js +8 -1
- package/node_modules/@maka/runtime/dist/request-shape.js +23 -0
- package/node_modules/@maka/runtime/dist/runtime-event-backfill.js +1 -1
- package/node_modules/@maka/runtime/dist/runtime-event-read-model.js +24 -1
- package/node_modules/@maka/runtime/dist/runtime-kernel.js +127 -13
- package/node_modules/@maka/runtime/dist/session-manager.js +20 -36
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +21 -0
- package/node_modules/@maka/runtime/dist/stream-graph-supervisor-tools.js +0 -5
- package/node_modules/@maka/runtime/dist/test-connection.js +0 -1
- package/node_modules/@maka/runtime/dist/tool-activation-identity.js +41 -0
- package/node_modules/@maka/runtime/dist/tool-availability.js +11 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-resource.js +63 -1
- package/node_modules/@maka/runtime/dist/tool-result-archive-transition.js +42 -12
- package/node_modules/@maka/runtime/dist/tool-result-archive.js +27 -4
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/client/connection.js +30 -5
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +52 -13
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +2 -0
- package/node_modules/@maka/runtime-host/dist/client/host-retirement.js +4 -2
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +18 -1
- package/node_modules/@maka/runtime-host/dist/client/session-subscription.js +19 -0
- package/node_modules/@maka/runtime-host/dist/control/endpoint.js +1 -3
- package/node_modules/@maka/runtime-host/dist/node-error.js +22 -0
- package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +1 -3
- package/node_modules/@maka/runtime-host/dist/peer-mesh/limits.js +0 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/model.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +1 -3
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +9 -1
- package/node_modules/@maka/runtime-host/dist/protocol/operations.js +3 -2
- package/node_modules/@maka/runtime-host/dist/protocol/plan.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +27 -5
- package/node_modules/@maka/runtime-host/dist/protocol/project-catalog.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/session-continuity.js +1 -0
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +86 -157
- package/node_modules/@maka/runtime-host/dist/server/access-credential-store.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/agent-graph-coordinator.js +0 -3
- package/node_modules/@maka/runtime-host/dist/server/canonical-session-projection.js +2 -1
- package/node_modules/@maka/runtime-host/dist/server/connection-session.js +28 -8
- package/node_modules/@maka/runtime-host/dist/server/daily-review-coordinator.js +112 -56
- package/node_modules/@maka/runtime-host/dist/server/execution-artifacts.js +32 -32
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +85 -25
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +42 -14
- package/node_modules/@maka/runtime-host/dist/server/failure-diagnostic.js +24 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +7 -3
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +3 -3
- package/node_modules/@maka/runtime-host/dist/server/host-session-availability.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +3 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +34 -4
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +51 -23
- package/node_modules/@maka/runtime-host/dist/server/operation-dispatcher.js +2 -7
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +110 -14
- package/node_modules/@maka/runtime-host/dist/server/runtime-resource-coordinator.js +11 -8
- package/node_modules/@maka/runtime-host/dist/server/scheduled-task-coordinator.js +31 -21
- package/node_modules/@maka/runtime-host/dist/server/serial-outbound-writer.js +1 -1
- package/node_modules/@maka/runtime-host/dist/server/session-catalog-coordinator.js +20 -8
- package/node_modules/@maka/runtime-host/dist/server/session-retirement-coordinator.js +5 -2
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-reader.js +15 -104
- package/node_modules/@maka/runtime-host/dist/server/shared-session-transcript.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +59 -82
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +132 -139
- package/node_modules/@maka/runtime-host/dist/server/workhub-message-attachments.js +46 -0
- package/node_modules/@maka/storage/dist/agent-run-store.js +14 -1
- package/node_modules/@maka/storage/dist/artifact-store.js +40 -3
- package/node_modules/@maka/storage/dist/atomic-file-write.js +74 -0
- package/node_modules/@maka/storage/dist/claude-code-session-adapter.js +0 -1
- package/node_modules/@maka/storage/dist/codex-session-adapter.js +284 -196
- package/node_modules/@maka/storage/dist/credential-store.js +12 -63
- package/node_modules/@maka/storage/dist/execution-stores.js +4 -1
- package/node_modules/@maka/storage/dist/git-exec.js +61 -0
- package/node_modules/@maka/storage/dist/git-worktree-child-executor.js +8 -35
- package/node_modules/@maka/storage/dist/goal-authority.js +2 -2
- package/node_modules/@maka/storage/dist/interaction-store.js +2 -2
- package/node_modules/@maka/storage/dist/mcp-config-store.js +10 -25
- package/node_modules/@maka/storage/dist/project-catalog.js +2 -23
- package/node_modules/@maka/storage/dist/runtime-event-invariants.js +2 -2
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +8 -3
- package/node_modules/@maka/storage/dist/scheduled-task-store.js +249 -283
- package/node_modules/@maka/storage/dist/session-bundle-manifest.js +5 -17
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +2 -1
- package/node_modules/@maka/storage/dist/session-copy-cleanup.js +2 -1
- package/node_modules/@maka/storage/dist/session-store.js +14 -2
- package/node_modules/@maka/storage/dist/settings-store.js +8 -4
- package/node_modules/@maka/storage/dist/sqlite-artifact-metadata.js +11 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +1 -2
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-schema.js +12 -1
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +67 -3
- package/node_modules/@maka/storage/dist/stable-storage.js +14 -1
- package/node_modules/@maka/storage/dist/storage-id.js +28 -0
- package/node_modules/@maka/storage/dist/tool-result-archive-evidence.js +31 -4
- package/node_modules/@maka/storage/dist/workspace-identity.js +2 -15
- package/node_modules/@maka/storage/dist/workspace-version-authority-internal.js +1 -8
- package/package.json +1 -1
- package/node_modules/@maka/core/dist/workhub-creation-intent.js +0 -990
- package/node_modules/@maka/core/dist/workhub-session-resolver.js +0 -50
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
* Phase 1 scope: types + small pure helpers only. No storage, runner,
|
|
32
32
|
* projection, or ledger logic lives here. Those arrive in later nodes.
|
|
33
33
|
*/
|
|
34
|
+
import { isWorkHubActionReceipt } from './workhub-action-result.js';
|
|
34
35
|
import { isModelRetryDecision } from './model-failure.js';
|
|
35
36
|
import { isRuntimeHandoffPause, runtimeHandoffPause, } from './runtime-handoff.js';
|
|
36
37
|
import { isMessageContent, normalizeMessageContent, } from './events.js';
|
|
@@ -229,6 +230,7 @@ const INVOCATION_ROOT_SHAPES = {
|
|
|
229
230
|
};
|
|
230
231
|
const RUNTIME_ACTIONS_SHAPE = defineObjectShape()([], [
|
|
231
232
|
'handoffPause',
|
|
233
|
+
'coordination',
|
|
232
234
|
'stateDelta',
|
|
233
235
|
'artifactDelta',
|
|
234
236
|
'permissionRequest',
|
|
@@ -583,6 +585,7 @@ function isRuntimeEventActions(value) {
|
|
|
583
585
|
return false;
|
|
584
586
|
}
|
|
585
587
|
return ((value.handoffPause === undefined || isRuntimeHandoffPause(value.handoffPause)) &&
|
|
588
|
+
(value.coordination === undefined || isWorkHubActionReceipt(value.coordination)) &&
|
|
586
589
|
(value.stateDelta === undefined || isRecord(value.stateDelta)) &&
|
|
587
590
|
(value.artifactDelta === undefined ||
|
|
588
591
|
(isRecord(value.artifactDelta) &&
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
* specific language governing permissions and limitations
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
|
+
import { isWorkHubActionReceipt } from './workhub-action-result.js';
|
|
19
20
|
import { MODEL_FAILURE_MESSAGE_MAX_BYTES, isModelRetryDecision, } from './model-failure.js';
|
|
20
21
|
import { decodeMessageContent, TOOL_ACTIVITY_KINDS, } from './events.js';
|
|
21
|
-
import { isToolCategory, } from './permission.js';
|
|
22
|
+
import { isPermissionMode, isToolCategory, } from './permission.js';
|
|
22
23
|
import { defineObjectShape, hasExactShape, isFiniteNumber, isOptionalString, isRecord, pickShape, } from './record-schema.js';
|
|
23
24
|
import { isPermissionDecisionFields } from './interaction-record-schema.js';
|
|
24
25
|
import { isTokenUsageFields } from './usage-record-schema.js';
|
|
@@ -64,7 +65,11 @@ export function isTurnStatus(value) {
|
|
|
64
65
|
// ============================================================================
|
|
65
66
|
// Header (JSONL line 1)
|
|
66
67
|
// ============================================================================
|
|
67
|
-
export const SESSION_TOOL_PROFILES = [
|
|
68
|
+
export const SESSION_TOOL_PROFILES = [
|
|
69
|
+
'headless-coding-v1',
|
|
70
|
+
'workhub-coordination-v1',
|
|
71
|
+
'workhub-coordination-v2',
|
|
72
|
+
];
|
|
68
73
|
export function isSessionToolProfile(value) {
|
|
69
74
|
return typeof value === 'string' && SESSION_TOOL_PROFILES.includes(value);
|
|
70
75
|
}
|
|
@@ -283,6 +288,19 @@ export function isUserVisibleSessionSystemNote(kind) {
|
|
|
283
288
|
export const WORKHUB_COORDINATION_RECORD_SCHEMA_VERSION = 1;
|
|
284
289
|
export const WORKHUB_COORDINATION_REPLACEMENT_SCHEMA_VERSION = 2;
|
|
285
290
|
export const WORKHUB_COORDINATION_STOP_SCHEMA_VERSION = 3;
|
|
291
|
+
export function isWorkHubCreateDefaults(value) {
|
|
292
|
+
if (!isRecord(value) ||
|
|
293
|
+
Object.keys(value).some((key) => key !== 'model' && key !== 'permissionMode'))
|
|
294
|
+
return false;
|
|
295
|
+
if (value.permissionMode !== undefined && !isPermissionMode(value.permissionMode))
|
|
296
|
+
return false;
|
|
297
|
+
if (value.model === undefined)
|
|
298
|
+
return true;
|
|
299
|
+
const model = value.model;
|
|
300
|
+
return (isRecord(model) &&
|
|
301
|
+
Object.keys(model).length === 3 &&
|
|
302
|
+
['llmConnectionId', 'llmConnectionSlug', 'model'].every((key) => typeof model[key] === 'string' && model[key].trim().length > 0 && model[key].length <= 512));
|
|
303
|
+
}
|
|
286
304
|
function isWorkHubDelegationStopResolution(outcome, targetTurnId) {
|
|
287
305
|
const hasTargetTurnId = typeof targetTurnId === 'string' && targetTurnId.length > 0;
|
|
288
306
|
if (outcome === 'stop_delivered' || outcome === 'not_owned')
|
|
@@ -328,6 +346,7 @@ const USER_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 't
|
|
|
328
346
|
'quotes',
|
|
329
347
|
'inlineReferences',
|
|
330
348
|
'steeringEventId',
|
|
349
|
+
'coordinationActionId',
|
|
331
350
|
'origin',
|
|
332
351
|
]);
|
|
333
352
|
const ASSISTANT_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'turnId', 'ts', 'text', 'modelId'], ['thinking', 'contentOrder', 'providerOptions']);
|
|
@@ -405,7 +424,15 @@ const WORKHUB_DELEGATION_ASSIGNED_MESSAGE_SHAPE = defineObjectShape()([
|
|
|
405
424
|
'targetTurnId',
|
|
406
425
|
'targetMessageId',
|
|
407
426
|
'targetSessionName',
|
|
408
|
-
], [
|
|
427
|
+
], [
|
|
428
|
+
'attachments',
|
|
429
|
+
'targetAttachments',
|
|
430
|
+
'create',
|
|
431
|
+
'steered',
|
|
432
|
+
'replacesActionId',
|
|
433
|
+
'replacesDelegationId',
|
|
434
|
+
'delegationText',
|
|
435
|
+
]);
|
|
409
436
|
const WORKHUB_DELEGATION_REPLACEMENT_REQUESTED_MESSAGE_SHAPE = defineObjectShape()([
|
|
410
437
|
'type',
|
|
411
438
|
'id',
|
|
@@ -424,7 +451,7 @@ const WORKHUB_DELEGATION_REPLACEMENT_REQUESTED_MESSAGE_SHAPE = defineObjectShape
|
|
|
424
451
|
'replacedTargetSessionId',
|
|
425
452
|
'replacedTargetMessageId',
|
|
426
453
|
'targetSessionName',
|
|
427
|
-
], ['create']);
|
|
454
|
+
], ['attachments', 'create', 'delegationText']);
|
|
428
455
|
const WORKHUB_DELEGATION_SUPERSEDED_MESSAGE_SHAPE = defineObjectShape()([
|
|
429
456
|
'type',
|
|
430
457
|
'id',
|
|
@@ -486,7 +513,7 @@ const WORKHUB_DELEGATION_STOP_RESOLVED_MESSAGE_SHAPE = defineObjectShape()([
|
|
|
486
513
|
'targetSessionId',
|
|
487
514
|
'outcome',
|
|
488
515
|
], ['targetTurnId']);
|
|
489
|
-
const WORKHUB_DELEGATION_CREATE_SHAPE = defineObjectShape()(['title', 'workspace'], []);
|
|
516
|
+
const WORKHUB_DELEGATION_CREATE_SHAPE = defineObjectShape()(['title', 'workspace'], ['defaults']);
|
|
490
517
|
const WORKHUB_DELEGATION_PROJECT_WORKSPACE_SHAPE = defineObjectShape()(['kind', 'projectId'], []);
|
|
491
518
|
const WORKHUB_DELEGATION_HOST_PATH_WORKSPACE_SHAPE = defineObjectShape()(['kind', 'path'], []);
|
|
492
519
|
const SYSTEM_NOTE_MESSAGE_SHAPE = defineObjectShape()(['type', 'id', 'ts', 'kind'], ['turnId', 'data']);
|
|
@@ -510,7 +537,10 @@ function decodeMessage(value, decodeToolResultContent) {
|
|
|
510
537
|
case 'user':
|
|
511
538
|
if (hasExactShape(message, USER_MESSAGE_SHAPE) &&
|
|
512
539
|
hasMessageEnvelope(message, true) &&
|
|
513
|
-
(message.origin === undefined || decodeTurnOrigin(message.origin) !== undefined)
|
|
540
|
+
(message.origin === undefined || decodeTurnOrigin(message.origin) !== undefined) &&
|
|
541
|
+
(message.coordinationActionId === undefined ||
|
|
542
|
+
(typeof message.coordinationActionId === 'string' &&
|
|
543
|
+
message.coordinationActionId.length > 0))) {
|
|
514
544
|
const { displayText, attachments, directoryReferences, quotes, inlineReferences, origin, ...envelope } = message;
|
|
515
545
|
const decodedOrigin = origin === undefined ? undefined : decodeTurnOrigin(origin);
|
|
516
546
|
try {
|
|
@@ -619,6 +649,11 @@ function decodeMessage(value, decodeToolResultContent) {
|
|
|
619
649
|
throw new Error('Invalid stored message schema');
|
|
620
650
|
}
|
|
621
651
|
function isWorkHubCoordinationMessage(message) {
|
|
652
|
+
if (message.kind === 'action_receipt')
|
|
653
|
+
return (hasMessageEnvelope(message, true) &&
|
|
654
|
+
message.schemaVersion === 1 &&
|
|
655
|
+
Object.keys(message).every((k) => ['type', 'kind', 'schemaVersion', 'id', 'turnId', 'ts', 'receipt'].includes(k)) &&
|
|
656
|
+
isWorkHubActionReceipt(message.receipt));
|
|
622
657
|
if (message.kind === 'delegation_stop_requested') {
|
|
623
658
|
return (hasMessageEnvelope(message, true) &&
|
|
624
659
|
hasExactShape(message, WORKHUB_DELEGATION_STOP_REQUESTED_MESSAGE_SHAPE) &&
|
|
@@ -694,6 +729,9 @@ function isWorkHubCoordinationMessage(message) {
|
|
|
694
729
|
typeof message.targetSessionId === 'string' &&
|
|
695
730
|
typeof message.userText === 'string' &&
|
|
696
731
|
message.userText.trim().length > 0 &&
|
|
732
|
+
isWorkHubMessageAttachments(message.attachments) &&
|
|
733
|
+
(message.delegationText === undefined ||
|
|
734
|
+
(typeof message.delegationText === 'string' && message.delegationText.trim().length > 0)) &&
|
|
697
735
|
((message.disposition === 'delegate_existing' && message.create === undefined) ||
|
|
698
736
|
(message.disposition === 'create_new' && isWorkHubDelegationCreateSpec(message.create))) &&
|
|
699
737
|
(message.disposition === 'delegate_existing' || message.disposition === 'create_new');
|
|
@@ -715,6 +753,7 @@ function isWorkHubCoordinationMessage(message) {
|
|
|
715
753
|
}
|
|
716
754
|
return (message.kind === 'delegation_assigned' &&
|
|
717
755
|
hasExactShape(message, WORKHUB_DELEGATION_ASSIGNED_MESSAGE_SHAPE) &&
|
|
756
|
+
isWorkHubMessageAttachments(message.targetAttachments) &&
|
|
718
757
|
typeof message.delegationId === 'string' &&
|
|
719
758
|
typeof message.targetTurnId === 'string' &&
|
|
720
759
|
typeof message.targetMessageId === 'string' &&
|
|
@@ -739,9 +778,21 @@ function isWorkHubActionIdentity(message) {
|
|
|
739
778
|
message.coordinationTurnId.length > 0 &&
|
|
740
779
|
message.turnId === message.coordinationTurnId);
|
|
741
780
|
}
|
|
781
|
+
function isWorkHubMessageAttachments(value) {
|
|
782
|
+
if (value === undefined)
|
|
783
|
+
return true;
|
|
784
|
+
try {
|
|
785
|
+
decodeMessageContent({ text: '', attachments: value });
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
catch {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
742
792
|
function isWorkHubDelegationCreateSpec(value) {
|
|
743
793
|
if (!isRecord(value) ||
|
|
744
794
|
!hasExactShape(value, WORKHUB_DELEGATION_CREATE_SHAPE) ||
|
|
795
|
+
(value.defaults !== undefined && !isWorkHubCreateDefaults(value.defaults)) ||
|
|
745
796
|
typeof value.title !== 'string' ||
|
|
746
797
|
value.title.trim().length === 0 ||
|
|
747
798
|
!isRecord(value.workspace)) {
|
|
@@ -40,6 +40,7 @@ export const SLASH_COMMAND_CATALOG = [
|
|
|
40
40
|
{ id: 'skill', session: 'required', surfaces: ['tui'] },
|
|
41
41
|
{ id: 'swarm', session: 'none', surfaces: ['desktop', 'tui'] },
|
|
42
42
|
{ id: 'thinking', session: 'required', surfaces: ['tui'] },
|
|
43
|
+
{ id: 'todo', session: 'required', surfaces: ['tui'] },
|
|
43
44
|
{ id: 'transcript', session: 'required', surfaces: ['tui'] },
|
|
44
45
|
{ id: 'update', session: 'none', surfaces: ['tui'] },
|
|
45
46
|
];
|
|
@@ -37,7 +37,7 @@ const ARCHIVED_SHAPE = defineObjectShape()([
|
|
|
37
37
|
'originalBytes',
|
|
38
38
|
'rewriteVersion',
|
|
39
39
|
'reason',
|
|
40
|
-
], ['artifactId', 'bodySha256']);
|
|
40
|
+
], ['artifactId', 'resourceRef', 'bodySha256']);
|
|
41
41
|
const IMAGE_SHAPE = defineObjectShape()(['kind', 'mimeType', 'ref'], []);
|
|
42
42
|
const SUMMARY_SHAPE = defineObjectShape()(['kind', 'original', 'summarized', 'reason'], []);
|
|
43
43
|
const WEB_SEARCH_SHAPE = defineObjectShape()(['kind', 'provider', 'query', 'rows'], []);
|
|
@@ -157,6 +157,7 @@ function isNonShellToolResultContent(value) {
|
|
|
157
157
|
typeof value.toolCallId === 'string' &&
|
|
158
158
|
typeof value.toolName === 'string' &&
|
|
159
159
|
isOptionalString(value.artifactId) &&
|
|
160
|
+
isOptionalString(value.resourceRef) &&
|
|
160
161
|
isOptionalString(value.bodySha256) &&
|
|
161
162
|
isFiniteNumber(value.originalEstimatedTokens) &&
|
|
162
163
|
isFiniteNumber(value.originalBytes) &&
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
import { isRecord } from './record-schema.js';
|
|
20
|
+
export function isWorkHubActionReceipt(value) {
|
|
21
|
+
if (!isRecord(value) ||
|
|
22
|
+
Object.keys(value).some((k) => !['actionId', 'userText', 'result', 'clarification'].includes(k)) ||
|
|
23
|
+
typeof value.actionId !== 'string' ||
|
|
24
|
+
!value.actionId ||
|
|
25
|
+
typeof value.userText !== 'string' ||
|
|
26
|
+
!value.userText.trim() ||
|
|
27
|
+
(value.clarification !== undefined && typeof value.clarification !== 'string'))
|
|
28
|
+
return false;
|
|
29
|
+
return isWorkHubActionResult(value.result);
|
|
30
|
+
}
|
|
31
|
+
/** Shared closed result contract for Runtime receipts and Host protocol replies. */
|
|
32
|
+
export function isWorkHubActionResult(r) {
|
|
33
|
+
if (!isRecord(r))
|
|
34
|
+
return false;
|
|
35
|
+
const text = (k) => typeof r[k] === 'string' && /^[A-Za-z0-9_-]{1,128}$/u.test(r[k]);
|
|
36
|
+
const keys = (allowed) => Object.keys(r).every((k) => allowed.includes(k));
|
|
37
|
+
if (r.disposition === 'answer_here' || r.disposition === 'clarify')
|
|
38
|
+
return keys(['disposition', 'coordinationTurnId']) && text('coordinationTurnId');
|
|
39
|
+
if (r.disposition === 'delegate_existing' ||
|
|
40
|
+
r.disposition === 'create_new' ||
|
|
41
|
+
r.disposition === 'replace')
|
|
42
|
+
return (keys([
|
|
43
|
+
'disposition',
|
|
44
|
+
'targetSessionId',
|
|
45
|
+
'targetTurnId',
|
|
46
|
+
'steered',
|
|
47
|
+
...(r.disposition === 'replace' ? ['replacementDisposition'] : []),
|
|
48
|
+
]) &&
|
|
49
|
+
text('targetSessionId') &&
|
|
50
|
+
text('targetTurnId') &&
|
|
51
|
+
(r.steered === undefined || r.steered === true) &&
|
|
52
|
+
(r.disposition !== 'replace' ||
|
|
53
|
+
r.replacementDisposition === 'delegate_existing' ||
|
|
54
|
+
r.replacementDisposition === 'create_new'));
|
|
55
|
+
if (r.disposition === 'stop_work' || r.disposition === 'resume_work')
|
|
56
|
+
return ((r.disposition === 'stop_work'
|
|
57
|
+
? ((r.outcome !== 'stop_delivered' && r.outcome !== 'not_owned') ||
|
|
58
|
+
r.targetTurnId !== undefined) &&
|
|
59
|
+
(r.outcome !== 'cancelled_pending' || r.targetTurnId === undefined)
|
|
60
|
+
: (r.outcome === 'resume_started') === (r.targetTurnId !== undefined)) &&
|
|
61
|
+
keys(['disposition', 'outcome', 'targetSessionId', 'targetTurnId']) &&
|
|
62
|
+
text('targetSessionId') &&
|
|
63
|
+
(r.targetTurnId === undefined || text('targetTurnId')) &&
|
|
64
|
+
(r.disposition === 'stop_work'
|
|
65
|
+
? ['cancelled_pending', 'stop_delivered', 'already_terminal', 'not_owned']
|
|
66
|
+
: ['resume_started', 'already_running']).includes(String(r.outcome)));
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"./durable-tool-result-projection": "./dist/durable-tool-result-projection.js",
|
|
10
10
|
"./model-projection-transition": "./dist/model-projection-transition.js",
|
|
11
11
|
"./canonical-runtime-event": "./dist/canonical-runtime-event.js",
|
|
12
|
+
"./canonical-json": "./dist/canonical-json.js",
|
|
12
13
|
"./runtime-boundary": "./dist/runtime-boundary.js",
|
|
13
14
|
"./runtime-handoff": "./dist/runtime-handoff.js",
|
|
14
15
|
"./runtime-logical-execution": "./dist/runtime-logical-execution.js",
|
|
@@ -82,8 +83,6 @@
|
|
|
82
83
|
"./deep-research-client-progress": "./dist/deep-research-client-progress.js",
|
|
83
84
|
"./daily-review": "./dist/daily-review.js",
|
|
84
85
|
"./work-board": "./dist/work-board.js",
|
|
85
|
-
"./workhub-creation-intent": "./dist/workhub-creation-intent.js",
|
|
86
|
-
"./workhub-session-resolver": "./dist/workhub-session-resolver.js",
|
|
87
86
|
"./deep-research": "./dist/deep-research.js",
|
|
88
87
|
"./session-start-mode": "./dist/session-start-mode.js",
|
|
89
88
|
"./long-term-memory": "./dist/long-term-memory.js",
|
|
@@ -155,7 +154,8 @@
|
|
|
155
154
|
"./ui-locale": "./dist/ui-locale.js",
|
|
156
155
|
"./unified-diff": "./dist/unified-diff.js",
|
|
157
156
|
"./dev-single-instance": "./dist/dev-single-instance.js",
|
|
158
|
-
"./maka-wordmark": "./dist/maka-wordmark.js"
|
|
157
|
+
"./maka-wordmark": "./dist/maka-wordmark.js",
|
|
158
|
+
"./workhub-action-result": "./dist/workhub-action-result.js"
|
|
159
159
|
},
|
|
160
160
|
"dependencies": {
|
|
161
161
|
"intl-messageformat": "11.2.14"
|
|
@@ -19,13 +19,14 @@
|
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
20
|
import { link, mkdir, open, readFile, unlink } from 'node:fs/promises';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
|
+
import { stableJsonStringify } from '@maka/core/canonical-json';
|
|
22
23
|
import { FileAttemptStore } from './attempt-store.js';
|
|
23
24
|
import { parseExperimentSpec } from './spec.js';
|
|
24
25
|
export async function openExperimentDirectory(root, spec) {
|
|
25
26
|
await mkdir(root, { recursive: true });
|
|
26
27
|
const specPath = join(root, 'experiment.json');
|
|
27
28
|
const temporaryPath = join(root, `.experiment-${randomUUID()}.tmp`);
|
|
28
|
-
const canonical = `${
|
|
29
|
+
const canonical = `${stableJsonStringify(spec)}\n`;
|
|
29
30
|
const temporary = await open(temporaryPath, 'wx', 0o600);
|
|
30
31
|
try {
|
|
31
32
|
await temporary.writeFile(canonical);
|
|
@@ -37,8 +38,9 @@ export async function openExperimentDirectory(root, spec) {
|
|
|
37
38
|
if (error.code !== 'EEXIST')
|
|
38
39
|
throw error;
|
|
39
40
|
const existing = parseExperimentSpec(JSON.parse(await readFile(specPath, 'utf8')));
|
|
40
|
-
if (
|
|
41
|
+
if (stableJsonStringify(existing) !== stableJsonStringify(spec)) {
|
|
41
42
|
throw new Error('experiment spec differs');
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
finally {
|
|
44
46
|
await temporary.close().catch(() => undefined);
|
|
@@ -46,14 +48,3 @@ export async function openExperimentDirectory(root, spec) {
|
|
|
46
48
|
}
|
|
47
49
|
return { root, specPath, attempts: new FileAttemptStore(join(root, 'attempts')) };
|
|
48
50
|
}
|
|
49
|
-
function canonicalJson(value) {
|
|
50
|
-
if (Array.isArray(value))
|
|
51
|
-
return `[${value.map(canonicalJson).join(',')}]`;
|
|
52
|
-
if (value && typeof value === 'object') {
|
|
53
|
-
return `{${Object.entries(value)
|
|
54
|
-
.sort(([left], [right]) => left.localeCompare(right))
|
|
55
|
-
.map(([key, child]) => `${JSON.stringify(key)}:${canonicalJson(child)}`)
|
|
56
|
-
.join(',')}}`;
|
|
57
|
-
}
|
|
58
|
-
return JSON.stringify(value);
|
|
59
|
-
}
|
|
@@ -60,7 +60,7 @@ export const TOOLCHAIN_IDENTITIES = {
|
|
|
60
60
|
'deepseek-harness': {
|
|
61
61
|
root: '/opt/maka-deepseek-harness-toolchain',
|
|
62
62
|
version: '0.1.0-rc.6',
|
|
63
|
-
fingerprint: 'sha256:
|
|
63
|
+
fingerprint: 'sha256:5314e15659d4c35381ce15ca4802933d61bc3af718d7eeb8260f4fa32ccf5860',
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
// The identity table is the profile registry: a profile without a pinned
|
|
@@ -0,0 +1,213 @@
|
|
|
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
|
+
import { decodeInteractionAnswer, decodeInteractionRequest, interactionFormAnswerMatchesRequest, projectInteractionFormRequest, } from '@maka/core/interaction';
|
|
20
|
+
// Unbounded protocol strings need a visible client input limit: Core reserves
|
|
21
|
+
// the worst-case JSON-escaped answer within its serialized interaction budget.
|
|
22
|
+
// Explicit server bounds are preserved and still checked by Core admission.
|
|
23
|
+
const DEFAULT_STRING_MAX_LENGTH = 256;
|
|
24
|
+
/** Inspect raw keys and values before projection can escape control characters.
|
|
25
|
+
* This is a containment check, not a comparison with redacted output: a state
|
|
26
|
+
* may itself be identical to the redaction marker.
|
|
27
|
+
*/
|
|
28
|
+
export function containsMcpFormState(value, states) {
|
|
29
|
+
const pending = [value];
|
|
30
|
+
while (pending.length) {
|
|
31
|
+
const item = pending.pop();
|
|
32
|
+
if (typeof item === 'string') {
|
|
33
|
+
if (states.some((state) => state.length > 0 && item.includes(state)))
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
else if (item !== null && typeof item === 'object') {
|
|
37
|
+
for (const [key, child] of Object.entries(item))
|
|
38
|
+
pending.push(key, child);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
function record(value) {
|
|
44
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
45
|
+
throw new Error();
|
|
46
|
+
const prototype = Object.getPrototypeOf(value);
|
|
47
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
48
|
+
throw new Error();
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
function keys(value, allowed) {
|
|
52
|
+
if (Object.keys(value).some((key) => !allowed.includes(key)))
|
|
53
|
+
throw new Error();
|
|
54
|
+
}
|
|
55
|
+
function select(value, names) {
|
|
56
|
+
return Object.fromEntries(names.filter((name) => Object.hasOwn(value, name)).map((name) => [name, value[name]]));
|
|
57
|
+
}
|
|
58
|
+
function options(value, titles) {
|
|
59
|
+
if (!Array.isArray(value) ||
|
|
60
|
+
(titles !== undefined && (!Array.isArray(titles) || titles.length !== value.length)))
|
|
61
|
+
throw new Error();
|
|
62
|
+
return value.map((entry, index) => ({
|
|
63
|
+
value: entry,
|
|
64
|
+
label: Array.isArray(titles) ? titles[index] : entry,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
function titledOptions(value) {
|
|
68
|
+
if (!Array.isArray(value))
|
|
69
|
+
throw new Error();
|
|
70
|
+
return value.map((entry) => {
|
|
71
|
+
const option = record(entry);
|
|
72
|
+
keys(option, ['const', 'title']);
|
|
73
|
+
return { value: option.const, label: option.title };
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function field(name, value, required) {
|
|
77
|
+
const schema = record(value);
|
|
78
|
+
const sharedKeys = ['type', 'title', 'description', 'default'];
|
|
79
|
+
const shared = {
|
|
80
|
+
name,
|
|
81
|
+
label: Object.hasOwn(schema, 'title') ? schema.title : name,
|
|
82
|
+
required,
|
|
83
|
+
...select(schema, ['description', 'default']),
|
|
84
|
+
};
|
|
85
|
+
if (schema.type === 'string') {
|
|
86
|
+
if (Object.hasOwn(schema, 'enum')) {
|
|
87
|
+
keys(schema, [...sharedKeys, 'enum', 'enumNames']);
|
|
88
|
+
return { ...shared, kind: 'single_select', options: options(schema.enum, schema.enumNames) };
|
|
89
|
+
}
|
|
90
|
+
if (Object.hasOwn(schema, 'oneOf')) {
|
|
91
|
+
keys(schema, [...sharedKeys, 'oneOf']);
|
|
92
|
+
return { ...shared, kind: 'single_select', options: titledOptions(schema.oneOf) };
|
|
93
|
+
}
|
|
94
|
+
keys(schema, [...sharedKeys, 'minLength', 'maxLength', 'format']);
|
|
95
|
+
return {
|
|
96
|
+
...shared,
|
|
97
|
+
kind: 'string',
|
|
98
|
+
...select(schema, ['minLength', 'maxLength', 'format']),
|
|
99
|
+
...(schema.maxLength === undefined ? { maxLength: DEFAULT_STRING_MAX_LENGTH } : {}),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (schema.type === 'number' || schema.type === 'integer') {
|
|
103
|
+
keys(schema, [...sharedKeys, 'minimum', 'maximum']);
|
|
104
|
+
// Core validates numeric ranges; an integer-only interval may additionally be empty.
|
|
105
|
+
if (schema.type === 'integer' &&
|
|
106
|
+
typeof schema.minimum === 'number' &&
|
|
107
|
+
typeof schema.maximum === 'number' &&
|
|
108
|
+
Math.ceil(schema.minimum) > Math.floor(schema.maximum))
|
|
109
|
+
throw new Error();
|
|
110
|
+
return { ...shared, kind: schema.type, ...select(schema, ['minimum', 'maximum']) };
|
|
111
|
+
}
|
|
112
|
+
if (schema.type === 'boolean') {
|
|
113
|
+
keys(schema, sharedKeys);
|
|
114
|
+
return { ...shared, kind: 'boolean' };
|
|
115
|
+
}
|
|
116
|
+
if (schema.type === 'array') {
|
|
117
|
+
keys(schema, [...sharedKeys, 'items', 'minItems', 'maxItems']);
|
|
118
|
+
const items = record(schema.items);
|
|
119
|
+
let choices;
|
|
120
|
+
if (Object.hasOwn(items, 'anyOf')) {
|
|
121
|
+
keys(items, ['anyOf']);
|
|
122
|
+
choices = titledOptions(items.anyOf);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
keys(items, ['type', 'enum']);
|
|
126
|
+
if (items.type !== 'string')
|
|
127
|
+
throw new Error();
|
|
128
|
+
choices = options(items.enum);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
...shared,
|
|
132
|
+
kind: 'multi_select',
|
|
133
|
+
options: choices,
|
|
134
|
+
...select(schema, ['minItems', 'maxItems']),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
throw new Error();
|
|
138
|
+
}
|
|
139
|
+
/** Adapt one embedded MCP form request without exposing protocol state to the UI. */
|
|
140
|
+
export function prepareMcpForm(request, requester) {
|
|
141
|
+
try {
|
|
142
|
+
const embedded = record(request);
|
|
143
|
+
keys(embedded, ['method', 'params']);
|
|
144
|
+
if (embedded.method !== 'elicitation/create')
|
|
145
|
+
throw new Error();
|
|
146
|
+
const params = record(embedded.params);
|
|
147
|
+
keys(params, ['mode', 'message', 'requestedSchema', '_meta']);
|
|
148
|
+
if (params.mode !== undefined && params.mode !== 'form')
|
|
149
|
+
throw new Error();
|
|
150
|
+
const schema = record(params.requestedSchema);
|
|
151
|
+
keys(schema, [
|
|
152
|
+
'type',
|
|
153
|
+
'properties',
|
|
154
|
+
'required',
|
|
155
|
+
'$schema',
|
|
156
|
+
'title',
|
|
157
|
+
'description',
|
|
158
|
+
'additionalProperties',
|
|
159
|
+
]);
|
|
160
|
+
if (schema.type !== 'object' ||
|
|
161
|
+
(schema.additionalProperties !== undefined && schema.additionalProperties !== false))
|
|
162
|
+
throw new Error();
|
|
163
|
+
for (const annotation of ['$schema', 'title', 'description']) {
|
|
164
|
+
if (schema[annotation] !== undefined && typeof schema[annotation] !== 'string')
|
|
165
|
+
throw new Error();
|
|
166
|
+
}
|
|
167
|
+
const properties = record(schema.properties);
|
|
168
|
+
const required = schema.required === undefined ? [] : schema.required;
|
|
169
|
+
if (!Array.isArray(required) ||
|
|
170
|
+
required.some((name) => typeof name !== 'string' || !Object.hasOwn(properties, name)) ||
|
|
171
|
+
new Set(required).size !== required.length)
|
|
172
|
+
throw new Error();
|
|
173
|
+
const decoded = decodeInteractionRequest({
|
|
174
|
+
kind: 'form',
|
|
175
|
+
toolUseId: 'mcp-form',
|
|
176
|
+
message: params.message,
|
|
177
|
+
requester,
|
|
178
|
+
fields: Object.entries(properties).map(([name, schema]) => field(name, schema, required.includes(name))),
|
|
179
|
+
});
|
|
180
|
+
if (decoded.kind !== 'form')
|
|
181
|
+
throw new Error();
|
|
182
|
+
const projected = projectInteractionFormRequest(decoded);
|
|
183
|
+
return {
|
|
184
|
+
form: {
|
|
185
|
+
message: projected.message,
|
|
186
|
+
requester: projected.requester,
|
|
187
|
+
fields: projected.fields,
|
|
188
|
+
},
|
|
189
|
+
respond(result) {
|
|
190
|
+
try {
|
|
191
|
+
const answer = decodeInteractionAnswer({ ...result, kind: 'form' });
|
|
192
|
+
if (answer.kind !== 'form' || !interactionFormAnswerMatchesRequest(projected, answer))
|
|
193
|
+
throw new Error();
|
|
194
|
+
if (answer.action !== 'accept')
|
|
195
|
+
return { action: answer.action };
|
|
196
|
+
return {
|
|
197
|
+
action: 'accept',
|
|
198
|
+
content: Object.fromEntries(Object.entries(answer.values).map(([name, value]) => [
|
|
199
|
+
name,
|
|
200
|
+
typeof value === 'object' ? [...value] : value,
|
|
201
|
+
])),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
throw new Error('Invalid MCP form response');
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
throw new Error('Unsupported or invalid MCP form request');
|
|
212
|
+
}
|
|
213
|
+
}
|