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
package/dist/tui-copy-catalog.js
CHANGED
|
@@ -17,6 +17,64 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
export const TUI_COPY_RESOURCES = {
|
|
20
|
+
todo: {
|
|
21
|
+
en: {
|
|
22
|
+
title: 'Current Todo',
|
|
23
|
+
markedComplete: 'marked complete',
|
|
24
|
+
open: '/todo to view',
|
|
25
|
+
usage: 'Usage: /todo',
|
|
26
|
+
progress: 'Todo',
|
|
27
|
+
unavailable: 'Todo unavailable',
|
|
28
|
+
empty: 'No Todo items',
|
|
29
|
+
loading: 'Loading Todo…',
|
|
30
|
+
hint: '↑↓/PgUp/PgDn scroll · Home/End · Esc close',
|
|
31
|
+
},
|
|
32
|
+
'zh-CN': {
|
|
33
|
+
title: '当前待办',
|
|
34
|
+
markedComplete: '标记完成',
|
|
35
|
+
open: '/todo 查看',
|
|
36
|
+
usage: '用法:/todo',
|
|
37
|
+
progress: '待办',
|
|
38
|
+
unavailable: '待办不可用',
|
|
39
|
+
empty: '暂无待办',
|
|
40
|
+
loading: '正在加载待办…',
|
|
41
|
+
hint: '↑↓/PgUp/PgDn 滚动 · Home/End · Esc 关闭',
|
|
42
|
+
},
|
|
43
|
+
'zh-TW': {
|
|
44
|
+
title: '目前待辦',
|
|
45
|
+
markedComplete: '標記完成',
|
|
46
|
+
open: '/todo 查看',
|
|
47
|
+
usage: '用法:/todo',
|
|
48
|
+
progress: '待辦',
|
|
49
|
+
unavailable: '待辦不可用',
|
|
50
|
+
empty: '沒有待辦',
|
|
51
|
+
loading: '正在載入待辦…',
|
|
52
|
+
hint: '↑↓/PgUp/PgDn 捲動 · Home/End · Esc 關閉',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
'transcript-reader': {
|
|
56
|
+
en: {
|
|
57
|
+
title: 'DETAILED TRANSCRIPT',
|
|
58
|
+
scope: 'loaded history',
|
|
59
|
+
hint: 'Esc/Ctrl+O close · Ctrl+E details · / search · ↑↓/PgUp/PgDn · Home/End',
|
|
60
|
+
matches: 'matches in displayed text',
|
|
61
|
+
back: 'return',
|
|
62
|
+
},
|
|
63
|
+
'zh-CN': {
|
|
64
|
+
title: '详细记录',
|
|
65
|
+
scope: '已加载历史',
|
|
66
|
+
hint: 'Esc/Ctrl+O 返回 · Ctrl+E 详情 · / 搜索 · ↑↓/PgUp/PgDn · Home/End',
|
|
67
|
+
matches: '处匹配(当前显示内容)',
|
|
68
|
+
back: '回到原位置',
|
|
69
|
+
},
|
|
70
|
+
'zh-TW': {
|
|
71
|
+
title: '詳細記錄',
|
|
72
|
+
scope: '已載入歷史',
|
|
73
|
+
hint: 'Esc/Ctrl+O 返回 · Ctrl+E 詳情 · / 搜尋 · ↑↓/PgUp/PgDn · Home/End',
|
|
74
|
+
matches: '處符合(目前顯示內容)',
|
|
75
|
+
back: '回到原位置',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
20
78
|
'host-owner': {
|
|
21
79
|
en: {
|
|
22
80
|
unavailable: 'Runtime Host owner controls are unavailable.',
|
|
@@ -268,6 +326,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
268
326
|
'credential-cleanup-failed': 'Stored credentials could not be removed; the configuration was not changed.',
|
|
269
327
|
'publication-credential-failed': 'The provider credential could not be stored or applied.',
|
|
270
328
|
'persist-failed': 'The configuration could not be saved.',
|
|
329
|
+
'commit-unknown': 'Configuration published; crash durability is uncertain. Check synchronization before retrying.',
|
|
271
330
|
'manager-failed': 'The MCP connection action failed.',
|
|
272
331
|
turn_active: 'MCP cannot be changed while a turn or another control action is running.',
|
|
273
332
|
invalid: 'Check the value and try again.',
|
|
@@ -366,6 +425,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
366
425
|
'credential-cleanup-failed': '无法删除旧凭据,配置未修改。',
|
|
367
426
|
'publication-credential-failed': '无法保存或应用 Provider 凭据。',
|
|
368
427
|
'persist-failed': '无法保存配置。',
|
|
428
|
+
'commit-unknown': '配置已发布,但无法确认崩溃后的持久性。请先检查同步状态再重试。',
|
|
369
429
|
'manager-failed': 'MCP 连接操作失败。',
|
|
370
430
|
turn_active: 'Turn 或其他控制操作运行期间不能修改 MCP。',
|
|
371
431
|
invalid: '请检查输入后重试。',
|
|
@@ -464,6 +524,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
464
524
|
'credential-cleanup-failed': '無法移除已儲存的認證資料;設定未變更。',
|
|
465
525
|
'publication-credential-failed': '無法儲存或套用 Provider 認證資料。',
|
|
466
526
|
'persist-failed': '無法儲存設定。',
|
|
527
|
+
'commit-unknown': '設定已發布,但無法確認當機後的持久性。請先檢查同步狀態再重試。',
|
|
467
528
|
'manager-failed': 'MCP 連線操作失敗。',
|
|
468
529
|
turn_active: 'Turn 或其他控制操作執行期間無法修改 MCP。',
|
|
469
530
|
invalid: '請檢查輸入後重試。',
|
|
@@ -562,10 +623,15 @@ export const TUI_COPY_RESOURCES = {
|
|
|
562
623
|
pickers: {
|
|
563
624
|
en: {
|
|
564
625
|
modelPickerTitle: 'Select Model',
|
|
565
|
-
modelSwitchCacheWarning: '
|
|
626
|
+
modelSwitchCacheWarning: '\u26a0 Switching models may rebuild the prompt cache; the next request may be slower or cost more.',
|
|
566
627
|
modelSearchHint: 'Search models / providers / connections · ↑↓ select · Enter confirm · Esc cancel',
|
|
567
628
|
searchLabel: 'Search',
|
|
568
629
|
noMatchingModels: 'No matching models',
|
|
630
|
+
resumeSessionTitle: 'Resume Session',
|
|
631
|
+
sessionScopeCurrent: 'Current',
|
|
632
|
+
sessionScopeAll: 'All',
|
|
633
|
+
sessionSearchHint: 'Search name / id / path / model / connection · Tab scope · ↑↓ select · Enter open · Esc close',
|
|
634
|
+
noMatchingSessions: 'No matching sessions',
|
|
569
635
|
selectPickerHint: '↑↓ select · Enter confirm · Esc close',
|
|
570
636
|
providerConfigured: 'configured',
|
|
571
637
|
addAccount: 'add account',
|
|
@@ -652,10 +718,15 @@ export const TUI_COPY_RESOURCES = {
|
|
|
652
718
|
},
|
|
653
719
|
'zh-CN': {
|
|
654
720
|
modelPickerTitle: '选择模型',
|
|
655
|
-
modelSwitchCacheWarning: '
|
|
721
|
+
modelSwitchCacheWarning: '\u26a0 切换模型可能需要重建提示缓存;下一次请求可能更慢或成本更高。',
|
|
656
722
|
modelSearchHint: '搜索模型 / 服务商 / 连接 · ↑↓ 选择 · Enter 确认 · Esc 取消',
|
|
657
723
|
searchLabel: '搜索',
|
|
658
724
|
noMatchingModels: '没有匹配的模型',
|
|
725
|
+
resumeSessionTitle: '恢复会话',
|
|
726
|
+
sessionScopeCurrent: '当前目录',
|
|
727
|
+
sessionScopeAll: '全部',
|
|
728
|
+
sessionSearchHint: '搜索名称 / ID / 路径 / 模型 / 连接 · Tab 切换范围 · ↑↓ 选择 · Enter 打开 · Esc 关闭',
|
|
729
|
+
noMatchingSessions: '没有匹配的会话',
|
|
659
730
|
selectPickerHint: '↑↓ 选择 · Enter 确认 · Esc 关闭',
|
|
660
731
|
providerConfigured: '已设置',
|
|
661
732
|
addAccount: '添加账号',
|
|
@@ -741,10 +812,15 @@ export const TUI_COPY_RESOURCES = {
|
|
|
741
812
|
},
|
|
742
813
|
'zh-TW': {
|
|
743
814
|
modelPickerTitle: '選擇模型',
|
|
744
|
-
modelSwitchCacheWarning: '
|
|
815
|
+
modelSwitchCacheWarning: '\u26a0 切換模型可能需要重建提示快取;下一次請求可能較慢或成本較高。',
|
|
745
816
|
modelSearchHint: '搜尋模型 / 服務商 / 連線 · ↑↓ 選擇 · Enter 確認 · Esc 取消',
|
|
746
817
|
searchLabel: '搜尋',
|
|
747
818
|
noMatchingModels: '沒有符合的模型',
|
|
819
|
+
resumeSessionTitle: '恢復會話',
|
|
820
|
+
sessionScopeCurrent: '目前目錄',
|
|
821
|
+
sessionScopeAll: '全部',
|
|
822
|
+
sessionSearchHint: '搜尋名稱 / ID / 路徑 / 模型 / 連線 · Tab 切換範圍 · ↑↓ 選取 · Enter 開啟 · Esc 關閉',
|
|
823
|
+
noMatchingSessions: '沒有符合的會話',
|
|
748
824
|
selectPickerHint: '↑↓ 選擇 · Enter 確認 · Esc 關閉',
|
|
749
825
|
providerConfigured: '已設定',
|
|
750
826
|
addAccount: '新增帳號',
|
|
@@ -863,6 +939,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
863
939
|
skill: 'Invoke a skill (or type /skill:<name> inline)',
|
|
864
940
|
swarm: 'Show, enable, disable, or run one Swarm turn',
|
|
865
941
|
thinking: 'Set thinking level',
|
|
942
|
+
todo: 'Show the current session Todo list',
|
|
866
943
|
transcript: 'Browse the full transcript inside Maka',
|
|
867
944
|
},
|
|
868
945
|
help: {
|
|
@@ -870,7 +947,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
870
947
|
userCommand: ' !<command> — run one shell command visible only to you',
|
|
871
948
|
keybindingsHeading: 'Keybindings',
|
|
872
949
|
keybindings: [
|
|
873
|
-
' Ctrl+O —
|
|
950
|
+
' Ctrl+O — open detailed transcript (Ctrl+E toggles details inside)',
|
|
874
951
|
' Ctrl+T — expand or collapse all thinking in view',
|
|
875
952
|
' Scroll the transcript with your terminal or trackpad',
|
|
876
953
|
' Enter (during a turn) — steer: inject a message into the running turn',
|
|
@@ -916,6 +993,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
916
993
|
skill: '调用 Skill(也可直接输入 /skill:<name>)',
|
|
917
994
|
swarm: '查看、启用、停用 Swarm 模式,或执行一次 Swarm 任务',
|
|
918
995
|
thinking: '设置思考级别',
|
|
996
|
+
todo: '查看当前会话待办清单',
|
|
919
997
|
transcript: '在 Maka 内浏览完整对话记录',
|
|
920
998
|
},
|
|
921
999
|
help: {
|
|
@@ -923,7 +1001,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
923
1001
|
userCommand: ' !<command> — 执行一次仅用户可见的 shell 命令',
|
|
924
1002
|
keybindingsHeading: '快捷键',
|
|
925
1003
|
keybindings: [
|
|
926
|
-
' Ctrl+O —
|
|
1004
|
+
' Ctrl+O — 打开详细记录(其中 Ctrl+E 切换详情)',
|
|
927
1005
|
' Ctrl+T — 展开或折叠视图中的所有思考块',
|
|
928
1006
|
' 使用终端或触控板滚动对话记录',
|
|
929
1007
|
' Enter(任务运行中)— 将消息注入当前任务',
|
|
@@ -969,6 +1047,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
969
1047
|
skill: '呼叫 Skill(也可直接輸入 /skill:<name>)',
|
|
970
1048
|
swarm: '檢視、啟用、停用 Swarm 模式,或執行一次 Swarm 任務',
|
|
971
1049
|
thinking: '設定思考級別',
|
|
1050
|
+
todo: '檢視目前會話待辦清單',
|
|
972
1051
|
transcript: '在 Maka 內瀏覽完整對話記錄',
|
|
973
1052
|
},
|
|
974
1053
|
help: {
|
|
@@ -976,7 +1055,7 @@ export const TUI_COPY_RESOURCES = {
|
|
|
976
1055
|
userCommand: ' !<command> — 執行一次僅使用者可見的 shell 命令',
|
|
977
1056
|
keybindingsHeading: '快捷鍵',
|
|
978
1057
|
keybindings: [
|
|
979
|
-
' Ctrl+O —
|
|
1058
|
+
' Ctrl+O — 開啟詳細記錄(其中 Ctrl+E 切換詳情)',
|
|
980
1059
|
' Ctrl+T — 展開或摺疊檢視中的所有思考區塊',
|
|
981
1060
|
' 使用終端機或觸控板捲動對話記錄',
|
|
982
1061
|
' Enter(任務執行中)— 將訊息注入目前任務',
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
export function stripUnfocusedCursorStyle(lines, focused) {
|
|
20
|
+
if (focused)
|
|
21
|
+
return lines;
|
|
22
|
+
// pi-tui 0.84.4 paints its cursor even when the editor is unfocused.
|
|
23
|
+
// Remove the reverse-video wrapper, keeping the captured text ($1):
|
|
24
|
+
//
|
|
25
|
+
// Input: \x1b[7mhello\x1b[0m
|
|
26
|
+
// └─────┘└───┘└─────┘
|
|
27
|
+
// reverse text reset
|
|
28
|
+
// remove keep remove
|
|
29
|
+
// $1
|
|
30
|
+
// Output: hello
|
|
31
|
+
//
|
|
32
|
+
// ([^\x1b]*) captures text without ESC, so the match cannot cross another
|
|
33
|
+
// ANSI sequence. Other text using this same wrapper would also lose its
|
|
34
|
+
// reverse styling. Recheck when changing themes or upgrading pi-tui.
|
|
35
|
+
return lines.map((line) => line.replace(/\x1b\[7m([^\x1b]*)\x1b\[0m/gu, '$1'));
|
|
36
|
+
}
|
package/dist/tui-mcp-control.js
CHANGED
|
@@ -20,7 +20,7 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
20
20
|
import { MCP_CONFIG_VERSION, mcpConfigChangeRetiresCredentials, resolveMcpProtocolPreference, } from '@maka/core/mcp';
|
|
21
21
|
import { createCredentialMcpOAuthStorage, McpClientManager } from '@maka/mcp';
|
|
22
22
|
import { createFileCredentialStore } from '@maka/storage/credential-store';
|
|
23
|
-
import { createMcpConfigStore, assertMcpEndpointPolicyOnChanges, McpConfigSourceError, normalizeMcpConfig, normalizeMcpImport, } from '@maka/storage/mcp-config-store';
|
|
23
|
+
import { AtomicFileWriteCommitUnknownError, createMcpConfigStore, assertMcpEndpointPolicyOnChanges, McpConfigSourceError, normalizeMcpConfig, normalizeMcpImport, } from '@maka/storage/mcp-config-store';
|
|
24
24
|
import { createMcpCapabilityProvider } from './mcp-capability-provider.js';
|
|
25
25
|
const RUNTIME_HOST_CREDENTIAL_ENV = 'MAKA_RUNTIME_HOST_ACCESS_CREDENTIAL';
|
|
26
26
|
export function createTuiMcpController(input, overrides = {}) {
|
|
@@ -289,10 +289,45 @@ class TuiMcpControllerImpl {
|
|
|
289
289
|
catch (error) {
|
|
290
290
|
if (error instanceof TuiMcpMutationError)
|
|
291
291
|
return error.result;
|
|
292
|
+
if (error instanceof AtomicFileWriteCommitUnknownError) {
|
|
293
|
+
// The transform has already published, including any credential
|
|
294
|
+
// retirement. Reload its authority; never replay those effects.
|
|
295
|
+
this.#preparedImport = undefined;
|
|
296
|
+
let reconciliationError;
|
|
297
|
+
if (!this.#closed) {
|
|
298
|
+
try {
|
|
299
|
+
({ reconciliationError } = await this.#synchronizeCommittedConfig(await this.#deps.configStore.get()));
|
|
300
|
+
}
|
|
301
|
+
catch (failure) {
|
|
302
|
+
reconciliationError = failure;
|
|
303
|
+
this.#publicationSuppressed = false;
|
|
304
|
+
this.#snapshot = freezeSnapshot({
|
|
305
|
+
...this.#snapshot,
|
|
306
|
+
configuration: 'out_of_sync',
|
|
307
|
+
servers: this.#snapshot.servers.map((server) => ({
|
|
308
|
+
...server,
|
|
309
|
+
synchronized: false,
|
|
310
|
+
})),
|
|
311
|
+
});
|
|
312
|
+
this.#notify();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Reconciliation does not establish the missing durability fence,
|
|
316
|
+
// and its own failure must not replace the original write error.
|
|
317
|
+
return {
|
|
318
|
+
status: 'failed',
|
|
319
|
+
reason: 'commit-unknown',
|
|
320
|
+
cause: error,
|
|
321
|
+
...(reconciliationError === undefined ? {} : { reconciliationError }),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
292
324
|
return { status: 'failed', reason: 'persist-failed' };
|
|
293
325
|
}
|
|
326
|
+
return (await this.#synchronizeCommittedConfig(committed)).result;
|
|
327
|
+
}
|
|
328
|
+
async #synchronizeCommittedConfig(committed) {
|
|
294
329
|
if (this.#closed)
|
|
295
|
-
return { status: 'failed', reason: 'closed' };
|
|
330
|
+
return { result: { status: 'failed', reason: 'closed' } };
|
|
296
331
|
this.#preparedImport = undefined;
|
|
297
332
|
this.#config = cloneConfig(committed);
|
|
298
333
|
this.#updateSnapshot({ configuration: 'synchronizing' });
|
|
@@ -301,19 +336,19 @@ class TuiMcpControllerImpl {
|
|
|
301
336
|
try {
|
|
302
337
|
await this.#deps.manager.sync(committed);
|
|
303
338
|
}
|
|
304
|
-
catch {
|
|
339
|
+
catch (error) {
|
|
305
340
|
this.#publicationSuppressed = false;
|
|
306
341
|
this.#updateSnapshot({ configuration: 'out_of_sync' });
|
|
307
342
|
this.#refreshManagerSnapshot();
|
|
308
343
|
await this.#settlePublication();
|
|
309
|
-
return { status: 'applied', effect: 'sync_failed' };
|
|
344
|
+
return { result: { status: 'applied', effect: 'sync_failed' }, reconciliationError: error };
|
|
310
345
|
}
|
|
311
346
|
this.#publicationSuppressed = false;
|
|
312
347
|
if (this.#closed)
|
|
313
|
-
return { status: 'failed', reason: 'closed' };
|
|
348
|
+
return { result: { status: 'failed', reason: 'closed' } };
|
|
314
349
|
this.#updateSnapshot({ configuration: 'ready' });
|
|
315
350
|
this.#refreshManagerSnapshot();
|
|
316
|
-
return { status: 'applied', effect: await this.#settlePublication() };
|
|
351
|
+
return { result: { status: 'applied', effect: await this.#settlePublication() } };
|
|
317
352
|
}
|
|
318
353
|
#prepareMutation(current, action) {
|
|
319
354
|
const servers = { ...current.mcpServers };
|
|
Binary file
|
|
@@ -65,6 +65,7 @@ export const AGENT_RUN_EVENT_TYPES = [
|
|
|
65
65
|
'sandbox_escalation_applied',
|
|
66
66
|
'sandbox_escalation_failed',
|
|
67
67
|
'sandbox_denial_detected',
|
|
68
|
+
'request_composition_resolved',
|
|
68
69
|
'model_call_attempt_recorded',
|
|
69
70
|
'history_compact_checkpoint_recorded',
|
|
70
71
|
'model_projection_transition_recorded',
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
* Neutral entrypoint for the strict, key-sorted JSON serializer shared by
|
|
21
|
+
* identity and persistence authorities.
|
|
22
|
+
*
|
|
23
|
+
* The implementation remains in `tool-args-identity` so its existing import
|
|
24
|
+
* path and wire behavior stay compatible while other packages use a domain-
|
|
25
|
+
* neutral name.
|
|
26
|
+
*/
|
|
27
|
+
export { stableJsonStringify } from './tool-args-identity.js';
|
|
@@ -75,6 +75,41 @@ export const CAPABILITY_READINESS_STATES = [
|
|
|
75
75
|
'degraded',
|
|
76
76
|
'paused',
|
|
77
77
|
];
|
|
78
|
+
/**
|
|
79
|
+
* Stable machine codes for capability and OS-permission reasons. Producers
|
|
80
|
+
* emit these instead of locale-bound prose; presenters own the code→copy map
|
|
81
|
+
* per locale. Bot capabilities pass their bridge status reasons through as-is
|
|
82
|
+
* (`rate-limited`, `gateway-closed-4004`, …), so signal `reason` fields stay
|
|
83
|
+
* `string` — this union types the desktop producers and the presenter maps.
|
|
84
|
+
*/
|
|
85
|
+
export const CAPABILITY_REASON_CODES = [
|
|
86
|
+
'disabled',
|
|
87
|
+
'platform_credentials_missing',
|
|
88
|
+
'macos_tcc_only',
|
|
89
|
+
'apple_events_tcc_status_unavailable',
|
|
90
|
+
'cu_artifact_missing',
|
|
91
|
+
'cu_backend_status',
|
|
92
|
+
'cu_backend_unavailable',
|
|
93
|
+
'cu_executor_undistributable',
|
|
94
|
+
'cu_executor_stopped',
|
|
95
|
+
'cu_executor_start_failed',
|
|
96
|
+
'cu_executor_recovering',
|
|
97
|
+
'cu_executor_ready',
|
|
98
|
+
'cu_executor_lazy_start',
|
|
99
|
+
'activity_recorder_partial',
|
|
100
|
+
'activity_recorder_probe_hint',
|
|
101
|
+
'memory_partial',
|
|
102
|
+
'memory_no_probe',
|
|
103
|
+
'accessibility_status_ambiguous',
|
|
104
|
+
'screen_recording_status_mac_only',
|
|
105
|
+
'notifications_status_unreadable_macos',
|
|
106
|
+
'notifications_status_unreadable',
|
|
107
|
+
'notifications_unsupported',
|
|
108
|
+
'permission_probe_failed',
|
|
109
|
+
];
|
|
110
|
+
export function isCapabilityReasonCode(value) {
|
|
111
|
+
return (typeof value === 'string' && CAPABILITY_REASON_CODES.includes(value));
|
|
112
|
+
}
|
|
78
113
|
export function isOsPermissionState(value) {
|
|
79
114
|
return typeof value === 'string' && OS_PERMISSION_STATES.includes(value);
|
|
80
115
|
}
|
|
@@ -81,7 +81,6 @@ export function isComputerUseErrorCode(value) {
|
|
|
81
81
|
return (typeof value === 'string' && COMPUTER_USE_ERROR_CODES.includes(value));
|
|
82
82
|
}
|
|
83
83
|
export const CU_ACTION_TYPES = ['screenshot', 'type', 'key', 'wait'];
|
|
84
|
-
export const COMPUTER_USE_ACTION_TYPES = CU_ACTION_TYPES;
|
|
85
84
|
/**
|
|
86
85
|
* The semantic actions, which name an element rather than a pixel. They are not
|
|
87
86
|
* in `CU_ACTION_TYPES` because they are not `CuAction`s — they are dispatched
|
|
@@ -28,6 +28,24 @@ const PATTERNS = [
|
|
|
28
28
|
streamingTerminator: /[\s"'<>]/,
|
|
29
29
|
streamingValueGroup: 3,
|
|
30
30
|
},
|
|
31
|
+
// URL userinfo: https://user:pass@host / https://token@host
|
|
32
|
+
// Structural — any authority that contains `@` is credential-bearing, so
|
|
33
|
+
// this does not depend on a provider prefix list. Runs before the query
|
|
34
|
+
// rule so only the userinfo is replaced and host/path survive.
|
|
35
|
+
// Character class matches streamingTerminator so a bare `https://host`
|
|
36
|
+
// cannot swallow later `@` across whitespace/quotes/angle brackets.
|
|
37
|
+
// Known boundary: punctuation like commas can still join a bare URL to a
|
|
38
|
+
// later `@`; a proper fix would restrict userinfo to the RFC 3986 set.
|
|
39
|
+
// http(s) only for now. Streaming cannot recognize userinfo before `@`
|
|
40
|
+
// arrives (`https://user:pa` stays clear until then); tightening earlier
|
|
41
|
+
// would eat `https://host:8080/`.
|
|
42
|
+
{
|
|
43
|
+
label: 'url userinfo',
|
|
44
|
+
regex: /(https?:\/\/)([^\s"'<>/?#]*@)/gi,
|
|
45
|
+
replacement: (m) => `${m[1]}<redacted>@`,
|
|
46
|
+
streamingTerminator: /[/?#\s"'<>]/,
|
|
47
|
+
streamingValueGroup: 2,
|
|
48
|
+
},
|
|
31
49
|
// URL query secrets: ?key=[redacted] ?token=[redacted] ?api_key=[redacted] &access_token=[redacted]
|
|
32
50
|
// (runs before the api-key-header rule so the URL form isn't mangled.)
|
|
33
51
|
{
|
|
@@ -228,6 +228,19 @@ export function reconcileConnectionAfterModelFetch(connection, models, options)
|
|
|
228
228
|
const previousEnabled = [
|
|
229
229
|
...new Set(connectionEnabledModelIds(connection).map((id) => supersededModelId(id, live, options?.aliases))),
|
|
230
230
|
];
|
|
231
|
+
if (options?.authoritative) {
|
|
232
|
+
// The first account-scoped fetch replaces the provider fallback guess: no
|
|
233
|
+
// user chose those bootstrap ids, and every usable model should be offered.
|
|
234
|
+
// Later refreshes preserve explicit user choices only while they remain in
|
|
235
|
+
// the account catalog; newly introduced models stay opt-in.
|
|
236
|
+
const enabledModelIds = connection.hasModelInventory
|
|
237
|
+
? previousEnabled.filter((id) => live.has(id))
|
|
238
|
+
: liveIds;
|
|
239
|
+
const defaultModel = enabledModelIds.includes(previousDefault)
|
|
240
|
+
? previousDefault
|
|
241
|
+
: (enabledModelIds[0] ?? '');
|
|
242
|
+
return { defaultModel, enabledModelIds };
|
|
243
|
+
}
|
|
231
244
|
// Seed a first choice only for a connection that has never had a list to
|
|
232
245
|
// pick from: four providers ship no `fallbackModels`, so for them discovery
|
|
233
246
|
// is the only place a first default can come from.
|
|
@@ -83,6 +83,7 @@ const MODEL_CALL_ATTEMPT_SHAPE = defineObjectShape()([
|
|
|
83
83
|
], [
|
|
84
84
|
'connectionSlug',
|
|
85
85
|
'historyCompactRoute',
|
|
86
|
+
'requestCompositionId',
|
|
86
87
|
'contextWindow',
|
|
87
88
|
'captureArtifactId',
|
|
88
89
|
'promptComposition',
|
|
@@ -294,6 +295,7 @@ export function decodeModelCallAttempt(value) {
|
|
|
294
295
|
isNonEmptyString(value.runId) &&
|
|
295
296
|
isNonEmptyString(value.turnId) &&
|
|
296
297
|
isNonNegativeInteger(value.step) &&
|
|
298
|
+
isOptionalString(value.requestCompositionId) &&
|
|
297
299
|
isNonNegativeInteger(value.attempt) &&
|
|
298
300
|
MODEL_CALL_KINDS.includes(value.callKind) &&
|
|
299
301
|
(value.historyCompactRoute === undefined ||
|
|
@@ -48,6 +48,10 @@ const GENERATED_METADATA_PROVIDER_ALIASES = {
|
|
|
48
48
|
function generatedMetadataProviderType(providerType) {
|
|
49
49
|
return GENERATED_METADATA_PROVIDER_ALIASES[providerType] ?? providerType;
|
|
50
50
|
}
|
|
51
|
+
/** Whether discovery is the complete usable model catalog for this account. */
|
|
52
|
+
export function providerReportsCompleteModelCatalog(providerType) {
|
|
53
|
+
return providerType === 'github-copilot';
|
|
54
|
+
}
|
|
51
55
|
/**
|
|
52
56
|
* Whether the active metadata describes this model at all. `lookupModelMetadata`
|
|
53
57
|
* answers "no" with an empty object, and callers were reading that sentinel by
|
|
@@ -53,6 +53,7 @@ export function redactSecrets(value) {
|
|
|
53
53
|
}
|
|
54
54
|
function redactTextSecrets(value) {
|
|
55
55
|
let next = value;
|
|
56
|
+
next = redactUrlUserinfoSecrets(next);
|
|
56
57
|
next = redactUrlQuerySecrets(next);
|
|
57
58
|
next = next.replace(QUOTED_SECRET_KEY_VALUE_PATTERN, (match, prefix, key) => isSensitiveKey(key) ? `${prefix}[redacted]` : match);
|
|
58
59
|
next = next.replace(AUTHORIZATION_HEADER_PATTERN, (_match, boundary, prefix) => `${boundary}${prefix}[redacted]`);
|
|
@@ -134,6 +135,17 @@ function redactJsonValue(value) {
|
|
|
134
135
|
}
|
|
135
136
|
return { value: next, changed };
|
|
136
137
|
}
|
|
138
|
+
function redactUrlUserinfoSecrets(value) {
|
|
139
|
+
// Authority runs through the first `/`, `?`, `#`, whitespace, quote, or
|
|
140
|
+
// angle bracket. If it contains `@`, everything from the host-start through
|
|
141
|
+
// the last `@` is userinfo. The class matches display-redaction's
|
|
142
|
+
// streamingTerminator so a bare `https://host` followed later by an
|
|
143
|
+
// email/`@package` (including across JSON quotes) cannot swallow the gap.
|
|
144
|
+
// Known boundary: punctuation like commas can still join a bare URL to a
|
|
145
|
+
// later `@` into one fake credentialed match; a proper fix would restrict
|
|
146
|
+
// userinfo to the RFC 3986 set instead of exclusion. http(s) only for now.
|
|
147
|
+
return value.replace(/(https?:\/\/)[^\s"'<>/?#]*@/gi, '$1[redacted]@');
|
|
148
|
+
}
|
|
137
149
|
function redactUrlQuerySecrets(value) {
|
|
138
150
|
return value.replace(/([?&])([^=\s&?#]+)=([^&\s#]*)/g, (match, sep, key) => {
|
|
139
151
|
if (!isSensitiveKey(key))
|
|
@@ -191,6 +203,10 @@ export function classifyGeneralizedError(error) {
|
|
|
191
203
|
return 'provider_error';
|
|
192
204
|
if (lower.includes('network') ||
|
|
193
205
|
lower.includes('fetch') ||
|
|
206
|
+
// Chromium network stack error codes (`net::ERR_CONNECTION_RESET`,
|
|
207
|
+
// `net::ERR_NAME_NOT_RESOLVED`, ...) never match the Node errno
|
|
208
|
+
// spellings below.
|
|
209
|
+
lower.includes('net::err') ||
|
|
194
210
|
lower.includes('econn') ||
|
|
195
211
|
lower.includes('enotfound'))
|
|
196
212
|
return 'network_error';
|
|
@@ -231,3 +247,22 @@ export function generalizedErrorMessage(error, fallback = 'Operation failed') {
|
|
|
231
247
|
export function isAuthenticationErrorText(message) {
|
|
232
248
|
return message.replace(/\bauthorit\w*/g, '').includes('auth');
|
|
233
249
|
}
|
|
250
|
+
const reportedFailures = new WeakSet();
|
|
251
|
+
/** Redacted diagnostics channel for unexpected operation failures. Copy
|
|
252
|
+
* catalogs live here (bare-importable) because a depended-on copy catalog may
|
|
253
|
+
* only hold bare package runtime imports. */
|
|
254
|
+
export function reportUnexpectedOperation(scope, error) {
|
|
255
|
+
// One failure, one diagnostic: a rejection formatted again by an outer layer
|
|
256
|
+
// is the same defect, not a second one.
|
|
257
|
+
if (typeof error === 'object' && error !== null) {
|
|
258
|
+
if (reportedFailures.has(error))
|
|
259
|
+
return;
|
|
260
|
+
reportedFailures.add(error);
|
|
261
|
+
}
|
|
262
|
+
const detail = error instanceof Error ? (error.stack ?? `${error.name}: ${error.message}`) : String(error);
|
|
263
|
+
console.error(`[${scope}] operation failed:`, redactSecrets(detail));
|
|
264
|
+
}
|
|
265
|
+
export function unexpectedOperationFallback(error, fallback, scope) {
|
|
266
|
+
reportUnexpectedOperation(scope, error);
|
|
267
|
+
return fallback;
|
|
268
|
+
}
|
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { defineObjectShape, hasExactShape, isRecord } from './record-schema.js';
|
|
20
20
|
export const RUN_COMPOSITION_SCHEMA_VERSION = 1;
|
|
21
|
+
export const REQUEST_COMPOSITION_SCHEMA_VERSION = 1;
|
|
22
|
+
// Composition evidence is exact: reject an over-bound provider surface rather
|
|
23
|
+
// than silently truncating the resolved snapshot.
|
|
24
|
+
export const COMPOSITION_MAX_TOOLS = 256;
|
|
25
|
+
export const COMPOSITION_MAX_TOOL_NAME_LENGTH = 128;
|
|
26
|
+
export const REQUEST_COMPOSITION_MAX_TOOL_DESCRIPTION_LENGTH = 16_384;
|
|
21
27
|
const RUN_COMPOSITION_SHAPE = defineObjectShape()([
|
|
22
28
|
'schemaVersion',
|
|
23
29
|
'composerId',
|
|
@@ -30,6 +36,20 @@ const RUN_COMPOSITION_SHAPE = defineObjectShape()([
|
|
|
30
36
|
'toolNames',
|
|
31
37
|
'contextWindow',
|
|
32
38
|
], []);
|
|
39
|
+
const REQUEST_COMPOSITION_SHAPE = defineObjectShape()([
|
|
40
|
+
'schemaVersion',
|
|
41
|
+
'compositionId',
|
|
42
|
+
'step',
|
|
43
|
+
'reason',
|
|
44
|
+
'sourceRevisions',
|
|
45
|
+
'systemPromptHash',
|
|
46
|
+
'toolCatalogHash',
|
|
47
|
+
'toolAvailabilityHash',
|
|
48
|
+
'providerOptionsHash',
|
|
49
|
+
'toolNames',
|
|
50
|
+
'toolSchemas',
|
|
51
|
+
], []);
|
|
52
|
+
const REQUEST_COMPOSITION_TOOL_SCHEMA_SHAPE = defineObjectShape()(['name', 'description', 'inputSchema'], ['providerTool']);
|
|
33
53
|
const ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/;
|
|
34
54
|
const HASH_PATTERN = /^sha256:[a-f0-9]{64}$/;
|
|
35
55
|
const SOURCE_REVISION_SHAPE = defineObjectShape()(['id', 'revision'], []);
|
|
@@ -64,6 +84,41 @@ export function createRunCompositionSnapshot(input) {
|
|
|
64
84
|
toolNames: [...input.toolNames].sort(compareExactString),
|
|
65
85
|
});
|
|
66
86
|
}
|
|
87
|
+
export function createRequestCompositionSnapshot(input, reason) {
|
|
88
|
+
return decodeRequestCompositionSnapshot({
|
|
89
|
+
schemaVersion: REQUEST_COMPOSITION_SCHEMA_VERSION,
|
|
90
|
+
...input,
|
|
91
|
+
reason,
|
|
92
|
+
sourceRevisions: [...input.sourceRevisions].sort((left, right) => compareExactString(left.id, right.id)),
|
|
93
|
+
toolNames: [...input.toolNames].sort(compareExactString),
|
|
94
|
+
toolSchemas: [...input.toolSchemas].sort((left, right) => compareExactString(left.name, right.name)),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
export function decodeRequestCompositionSnapshot(value) {
|
|
98
|
+
if (!isRecord(value) || !hasExactShape(value, REQUEST_COMPOSITION_SHAPE)) {
|
|
99
|
+
throw new Error('Invalid Request Composition snapshot schema');
|
|
100
|
+
}
|
|
101
|
+
const valid = value.schemaVersion === REQUEST_COMPOSITION_SCHEMA_VERSION &&
|
|
102
|
+
boundedString(value.compositionId, 128) &&
|
|
103
|
+
Number.isSafeInteger(value.step) &&
|
|
104
|
+
value.step >= 0 &&
|
|
105
|
+
(value.reason === 'initial' || value.reason === 'change') &&
|
|
106
|
+
canonicalSourceRevisions(value.sourceRevisions) &&
|
|
107
|
+
hash(value.systemPromptHash) &&
|
|
108
|
+
hash(value.toolCatalogHash) &&
|
|
109
|
+
hash(value.toolAvailabilityHash) &&
|
|
110
|
+
hash(value.providerOptionsHash) &&
|
|
111
|
+
canonicalToolNames(value.toolNames) &&
|
|
112
|
+
canonicalToolSchemas(value.toolSchemas);
|
|
113
|
+
if (!valid)
|
|
114
|
+
throw new Error('Invalid Request Composition snapshot schema');
|
|
115
|
+
return Object.freeze({
|
|
116
|
+
...value,
|
|
117
|
+
sourceRevisions: Object.freeze(value.sourceRevisions.map((source) => Object.freeze({ ...source }))),
|
|
118
|
+
toolNames: Object.freeze([...value.toolNames]),
|
|
119
|
+
toolSchemas: Object.freeze(value.toolSchemas.map((schema) => Object.freeze(structuredClone(schema)))),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
67
122
|
function compareExactString(left, right) {
|
|
68
123
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
69
124
|
}
|
|
@@ -84,16 +139,36 @@ function canonicalSourceRevisions(value) {
|
|
|
84
139
|
return true;
|
|
85
140
|
}
|
|
86
141
|
function canonicalToolNames(value) {
|
|
87
|
-
if (!Array.isArray(value) || value.length >
|
|
142
|
+
if (!Array.isArray(value) || value.length > COMPOSITION_MAX_TOOLS)
|
|
88
143
|
return false;
|
|
89
144
|
let previous;
|
|
90
145
|
for (const name of value) {
|
|
91
|
-
if (!boundedString(name,
|
|
146
|
+
if (!boundedString(name, COMPOSITION_MAX_TOOL_NAME_LENGTH) ||
|
|
147
|
+
(previous !== undefined && previous >= name)) {
|
|
92
148
|
return false;
|
|
149
|
+
}
|
|
93
150
|
previous = name;
|
|
94
151
|
}
|
|
95
152
|
return true;
|
|
96
153
|
}
|
|
154
|
+
function canonicalToolSchemas(value) {
|
|
155
|
+
if (!Array.isArray(value) || value.length > COMPOSITION_MAX_TOOLS)
|
|
156
|
+
return false;
|
|
157
|
+
let previous;
|
|
158
|
+
for (const schema of value) {
|
|
159
|
+
if (!isRecord(schema) ||
|
|
160
|
+
!hasExactShape(schema, REQUEST_COMPOSITION_TOOL_SCHEMA_SHAPE) ||
|
|
161
|
+
!boundedString(schema.name, COMPOSITION_MAX_TOOL_NAME_LENGTH) ||
|
|
162
|
+
!boundedString(schema.description, REQUEST_COMPOSITION_MAX_TOOL_DESCRIPTION_LENGTH) ||
|
|
163
|
+
!isRecord(schema.inputSchema) ||
|
|
164
|
+
(schema.providerTool !== undefined && !isRecord(schema.providerTool)) ||
|
|
165
|
+
(previous !== undefined && previous >= schema.name)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
previous = schema.name;
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
97
172
|
function hash(value) {
|
|
98
173
|
return typeof value === 'string' && HASH_PATTERN.test(value);
|
|
99
174
|
}
|