@kafca/agentdock 0.1.44 → 0.1.46

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.
Files changed (126) hide show
  1. package/README.md +76 -11
  2. package/bin/agentdock.mjs +5 -5
  3. package/dist/renderer/assets/{Badge-Qk9qHovH.js → Badge-BIesaDYG.js} +1 -1
  4. package/dist/renderer/assets/Chat-CpataoDh.js +2 -0
  5. package/dist/renderer/assets/{ChatMarkdown-BKdW8OON.js → ChatMarkdown-_Mdmltgv.js} +1 -1
  6. package/dist/renderer/assets/Config-Pe5-zKZk.js +21 -0
  7. package/dist/renderer/assets/CronList-BnaOSPT8.js +1 -0
  8. package/dist/renderer/assets/Dashboard-D05l8GKE.js +26 -0
  9. package/dist/renderer/assets/{EmptyState-kD9yAwtw.js → EmptyState-BDBavDll.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeDetail-BAMCLrjz.js → KnowledgeDetail-DvR798l_.js} +2 -2
  11. package/dist/renderer/assets/KnowledgeHome-r2ZuvU8-.js +11 -0
  12. package/dist/renderer/assets/Logs-BaljtmAV.js +1 -0
  13. package/dist/renderer/assets/{Modal-DwY4lecS.js → Modal-CXhD_OWR.js} +1 -1
  14. package/dist/renderer/assets/MonitorList-D7tyipbx.js +1 -0
  15. package/dist/renderer/assets/{Page-CnB9ePsb.js → Page-KUuFYgjg.js} +1 -1
  16. package/dist/renderer/assets/ProjectDetail-Ddq94-yu.js +11 -0
  17. package/dist/renderer/assets/ProjectList-CbdHd5Ev.js +1 -0
  18. package/dist/renderer/assets/{Select-zfoksLGB.js → Select-Djc8BXMC.js} +1 -1
  19. package/dist/renderer/assets/SessionChat-DOy0iKQR.js +1 -0
  20. package/dist/renderer/assets/SessionList-DHgl1s1D.js +1 -0
  21. package/dist/renderer/assets/ThreadChat-I7dYibDc.js +23 -0
  22. package/dist/renderer/assets/Workspace-DTocqY-F.js +19 -0
  23. package/dist/renderer/assets/{arrow-left-CNEAuElg.js → arrow-left-CXyya3hP.js} +1 -1
  24. package/dist/renderer/assets/{book-open-BNJMhNI-.js → book-open-9n4Kxc7E.js} +1 -1
  25. package/dist/renderer/assets/bot-C9HBk5XH.js +6 -0
  26. package/dist/renderer/assets/{check-BnclClRU.js → check-CutSg9a5.js} +1 -1
  27. package/dist/renderer/assets/{chevron-down-Bh53e0O-.js → chevron-down-DrydR4i3.js} +1 -1
  28. package/dist/renderer/assets/{circle-ClZTWCWO.js → circle-BEjtahw6.js} +1 -1
  29. package/dist/renderer/assets/desktop-DATgk_ka.js +1 -0
  30. package/dist/renderer/assets/{desktop-C6q6wBae.js → desktop-JQkhNOF4.js} +5 -5
  31. package/dist/renderer/assets/en-CmAr_0e6.js +1 -0
  32. package/dist/renderer/assets/es-Cs9x52ca.js +1 -0
  33. package/dist/renderer/assets/{funnel-_5hsz0xI.js → funnel-BhqZpS4f.js} +1 -1
  34. package/dist/renderer/assets/{heart-u4Q1aOqj.js → heart-Dp8Vs-7_.js} +1 -1
  35. package/dist/renderer/assets/{index-BNFx4uYv.js → index-BKpv0P0s.js} +2 -2
  36. package/dist/renderer/assets/index-CO4fGqmv.css +11 -0
  37. package/dist/renderer/assets/{index-B36eowj-.js → index-cI3pWBnN.js} +36 -36
  38. package/dist/renderer/assets/ja-DtvtBRTW.js +1 -0
  39. package/dist/renderer/assets/{pencil-DLh9QNmT.js → pencil-ywcJzeOo.js} +1 -1
  40. package/dist/renderer/assets/{play-BDTk9Scm.js → play-AtN492Cx.js} +1 -1
  41. package/dist/renderer/assets/{plus-BSc8POsz.js → plus-BEj14BBV.js} +1 -1
  42. package/dist/renderer/assets/projects-Clar8lgb.js +1 -0
  43. package/dist/renderer/assets/save-D6ov4CNv.js +11 -0
  44. package/dist/renderer/assets/{search-CniPk7Ey.js → search-C3bvw7AR.js} +1 -1
  45. package/dist/renderer/assets/{server-GsXyQAZm.js → server-C1Uyedyx.js} +1 -1
  46. package/dist/renderer/assets/{session-utils-BDxzgTBC.js → session-utils-DpRwJ6Nh.js} +1 -1
  47. package/dist/renderer/assets/{sessions-CLcKA1Tt.js → sessions-BWmAppwK.js} +1 -1
  48. package/dist/renderer/assets/{shield-check-4i0E3hmf.js → shield-check-CVx1mEs2.js} +1 -1
  49. package/dist/renderer/assets/{trash-2-DhtOCsO5.js → trash-2-o-heXOgs.js} +1 -1
  50. package/dist/renderer/assets/user-dPOzUqIc.js +6 -0
  51. package/dist/renderer/assets/{wifi-off-BHPzPY_B.js → wifi-off-Fz5c3_x_.js} +1 -1
  52. package/dist/renderer/assets/zh-CcJ9vBZj.js +1 -0
  53. package/dist/renderer/assets/zh-TW-elI72AC1.js +1 -0
  54. package/dist/renderer/index.html +2 -2
  55. package/dist-electron/electron/main.js +26 -1
  56. package/dist-electron/packages/core-sdk/src/index.js +28 -0
  57. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +111 -62
  58. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +80 -7
  59. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-transport.js +78 -5
  60. package/dist-electron/services/local-ai-core/src/acp/store/external-store.js +98 -0
  61. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +33 -0
  62. package/dist-electron/services/local-ai-core/src/acp/store/model-provider-store.js +88 -0
  63. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +43 -0
  64. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +2 -119
  65. package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +148 -0
  66. package/dist-electron/services/local-ai-core/src/channel/lark/inbound.js +55 -1
  67. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +65 -10
  68. package/dist-electron/services/local-ai-core/src/channel/shared/session-command-runtime.js +4 -2
  69. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +139 -29
  70. package/dist-electron/services/local-ai-core/src/execution/agent-execution-backend.js +56 -0
  71. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +18 -57
  72. package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +255 -0
  73. package/dist-electron/services/local-ai-core/src/plugins/builtin/catalog.js +78 -0
  74. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +3 -1
  75. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +64 -9
  76. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -2
  77. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +152 -0
  78. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +175 -0
  79. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +330 -3
  80. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +11 -2
  81. package/dist-electron/services/local-ai-core/src/runtime/provider-config-migration.js +32 -0
  82. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +76 -8
  83. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +62 -0
  84. package/dist-electron/services/local-ai-core/src/runtime/server.js +708 -4
  85. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -3
  86. package/dist-electron/services/local-ai-core/src/sandbox/opensandbox-client.js +113 -0
  87. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +273 -0
  88. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-manager.js +215 -0
  89. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-stdio-proxy.js +188 -0
  90. package/dist-electron/services/local-ai-core/src/thread/slash-command-registry.js +3 -0
  91. package/dist-electron/services/local-ai-core/src/thread/thread-command-service.js +32 -0
  92. package/dist-electron/services/local-ai-core/src/thread/thread-slash-command-dispatcher.js +71 -0
  93. package/dist-electron/shared/desktop.js +85 -1
  94. package/dist-electron/tests/contracts/architecture-docs.test.js +83 -0
  95. package/dist-electron/tests/electron/plugin-kernel.test.js +225 -18
  96. package/dist-electron/tests/electron/runtime-detection-service.test.js +57 -5
  97. package/dist-electron/tests/electron/sandbox-config.test.js +541 -0
  98. package/dist-electron/tests/electron/workspace-task-store.test.js +257 -0
  99. package/dist-electron/tests/integration/lark-gateway.test.js +139 -0
  100. package/dist-electron/tests/integration/local-core-refactor.test.js +183 -20
  101. package/dist-electron/tests/integration/local-core-routes.test.js +34 -0
  102. package/package.json +2 -3
  103. package/dist/renderer/assets/Chat-BK-fm0Xr.js +0 -2
  104. package/dist/renderer/assets/Config-B93CQGvY.js +0 -16
  105. package/dist/renderer/assets/CronList-Z3TvSRKP.js +0 -1
  106. package/dist/renderer/assets/Dashboard-Ch3QkWwf.js +0 -26
  107. package/dist/renderer/assets/KnowledgeHome-ChvjOfrc.js +0 -11
  108. package/dist/renderer/assets/Logs-Cv0nth3j.js +0 -1
  109. package/dist/renderer/assets/MonitorList-JEvMoWUm.js +0 -1
  110. package/dist/renderer/assets/ProjectDetail-DJa3sMmU.js +0 -11
  111. package/dist/renderer/assets/ProjectList-D6CXumR_.js +0 -1
  112. package/dist/renderer/assets/SessionChat-DUTh4WoM.js +0 -1
  113. package/dist/renderer/assets/SessionList-D9o-lUst.js +0 -1
  114. package/dist/renderer/assets/ThreadChat-BYXlT-Kc.js +0 -23
  115. package/dist/renderer/assets/Workspace-BrhSwRQ-.js +0 -14
  116. package/dist/renderer/assets/desktop-C5vBT0yM.js +0 -1
  117. package/dist/renderer/assets/en-D2SkCrhG.js +0 -1
  118. package/dist/renderer/assets/es-C8UBPhxM.js +0 -1
  119. package/dist/renderer/assets/index-CaQZSRbg.css +0 -11
  120. package/dist/renderer/assets/ja-ChF4vbBL.js +0 -1
  121. package/dist/renderer/assets/plug-BG0JHW6B.js +0 -6
  122. package/dist/renderer/assets/projects-DwfZwxDW.js +0 -1
  123. package/dist/renderer/assets/save-D5AO_G6a.js +0 -6
  124. package/dist/renderer/assets/user-BtC_pVXV.js +0 -11
  125. package/dist/renderer/assets/zh-DIcdHycM.js +0 -1
  126. package/dist/renderer/assets/zh-TW-BtRwreY_.js +0 -1
@@ -0,0 +1 @@
1
+ const e={dashboard:"ダッシュボード",chat:"チャット",chatDesktop:"デスクトップチャット",chatWeb:"チャット",workspace:"ワークスペース",knowledge:"ナレッジ",projects:"プロジェクト",sessions:"セッション",cron:"Cron",bridge:"ブリッジ",system:"システム"},t={title:"ダッシュボード",version:"バージョン",uptime:"稼働時間",platforms:"プラットフォーム",projects:"プロジェクト",bridgeAdapters:"ブリッジアダプター",noData:"データがありません"},s={title:"プロジェクト",name:"名前",agent:"エージェント",platforms:"プラットフォーム",sessions:"セッション",heartbeat:"ハートビート",settings:"設定",quiet:"サイレントモード",language:"言語",adminFrom:"管理元",disabledCommands:"無効化したコマンド",save:"保存",detail:"詳細",noProjects:"プロジェクトが設定されていません",tabs:{overview:"概要",providers:"プロバイダー",sandbox:"サンドボックス",heartbeat:"ハートビート",settings:"設定"}},o={title:"セッション",id:"ID",sessionKey:"セッションキー",name:"名前",platform:"プラットフォーム",active:"アクティブ",createdAt:"作成日時",history:"履歴",send:"送信",messageInput:"メッセージ",delete:"削除",noSessions:"セッションがありません",noMessages:"メッセージはまだありません",notLiveHint:"この相手は現在オフラインのため、今は返信できません。新しいアクティビティが届くと送信可能に戻ります。",offline:"オフライン",justNow:"たった今",allProjects:"すべてのプロジェクト",chat:"チャット",enterSession:"セッションを開く",newChat:"新しいチャット",selectProject:"プロジェクトを選択",projectRequired:"チャットを開始する前にプロジェクトを選択してください。",noAvailableChatTarget:"このプロジェクトにはまだすぐ使える会話がありません。先にセッション一覧から利用可能な会話を開いてください。",noReadyChats:"すぐに使える会話はありません。履歴はセッション一覧で確認してください。",emptyProject:"このプロジェクトにはまだセッションがありません。",emptySelection:"プロジェクトを選び、新しいチャットを開始してください。",activeChat:"現在のチャット",sendHint:"メッセージは選択中のプロジェクトに送信されます。",waitingForReply:"アシスタントの返信を待っています…",preparingChat:"チャットを準備しています…",pollTimeout:"更新のタイムアウト前に応答が完了しませんでした。",createFailed:"新しいチャットセッションの作成に失敗しました。",loadFailed:"選択したセッションの読み込みに失敗しました。",sendFailed:"メッセージの送信に失敗しました。",sessionUnavailable:"この相手は現在オフラインのため、今は返信できません。新しいアクティビティが届いてから再試行してください。",deleteConfirmTitle:"セッションを削除",deleteConfirmBody:"選択したセッションの保存済み会話履歴を削除します。",renameTitle:"セッション名を変更",renamePlaceholder:"セッション名",loadSession:"開く",historyTitle:"会話履歴",availableNow:"送信可能",waitingActivation:"利用可能になるのを待機中"},a={title:"プロバイダー",name:"名前",model:"モデル",baseUrl:"ベース URL",active:"有効",add:"プロバイダーを追加",remove:"削除",activate:"有効化",setModel:"モデルを設定",models:"利用可能なモデル"},n={title:"スケジュールジョブ",expression:"Cron 式",prompt:"プロンプト",exec:"実行",description:"説明",enabled:"有効",silent:"サイレント",lastRun:"最終実行",lastError:"最後のエラー",add:"ジョブを追加",delete:"削除",noJobs:"スケジュールジョブがありません",workDir:"作業ディレクトリ",sessionKey:"セッションキー",project:"プロジェクト"},i={title:"ハートビート",status:"状態",interval:"間隔",paused:"一時停止",running:"実行中",pause:"一時停止",resume:"再開",trigger:"今すぐ実行",setInterval:"間隔を設定",runCount:"実行回数",errorCount:"エラー回数",skippedBusy:"スキップ(ビジー)",lastRun:"最終実行"},r={title:"ブリッジ",platform:"プラットフォーム",capabilities:"機能",connectedAt:"接続日時",noAdapters:"ブリッジアダプターがありません"},l={title:"システム",config:"設定",logs:"ログ",restart:"再起動",reload:"設定の再読み込み",restartConfirm:"サービスを再起動しますか?アクティブなセッションが中断される場合があります。",reloadConfirm:"ディスクから設定を再読み込みしますか?",level:"ログレベル",limit:"行数の上限"},c={title:"AgentDock",subtitle:"AgentDock インスタンスに接続",token:"API トークン",serverUrl:"サーバー URL",connect:"接続",invalidToken:"トークンが無効または期限切れです",logout:"ログアウト"},d={loading:"読み込み中…",error:"エラー",success:"成功",confirm:"確認",cancel:"キャンセル",save:"保存",delete:"削除",back:"戻る",refresh:"更新",search:"検索",noData:"データなし",actions:"操作",viewAll:"すべて表示",optional:"任意",confirmDelete:"本当に削除しますか?"},m={light:"ライト",dark:"ダーク",system:"システムに合わせる"},p={nav:e,dashboard:t,projects:s,sessions:o,providers:a,cron:n,heartbeat:i,bridge:r,system:l,login:c,common:d,theme:m};export{r as bridge,d as common,n as cron,t as dashboard,p as default,i as heartbeat,c as login,e as nav,s as projects,a as providers,o as sessions,l as system,m as theme};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-B36eowj-.js";/**
1
+ import{c as a}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-B36eowj-.js";/**
1
+ import{c as o}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-B36eowj-.js";/**
1
+ import{c as e}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ import{A as t}from"./index-cI3pWBnN.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};
@@ -0,0 +1,11 @@
1
+ import{c as a}from"./index-cI3pWBnN.js";/**
2
+ * @license lucide-react v0.487.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const t=[["path",{d:"M12 22v-5",key:"1ega77"}],["path",{d:"M9 8V2",key:"14iosj"}],["path",{d:"M15 8V2",key:"18g5xt"}],["path",{d:"M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z",key:"osxo6l"}]],c=a("plug",t);/**
7
+ * @license lucide-react v0.487.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const e=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],d=a("save",e);export{c as P,d as S};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-B36eowj-.js";/**
1
+ import{c}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-B36eowj-.js";/**
1
+ import{c as e}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as o}from"./index-B36eowj-.js";/**
1
+ import{c as o}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{A as o}from"./index-B36eowj-.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
1
+ import{A as o}from"./index-cI3pWBnN.js";const i=s=>o.get(`/projects/${s}/sessions`),c=(s,e,t)=>o.get(`/projects/${s}/sessions/${e}`,{history_limit:String(t)}),r=(s,e,t)=>o.patch(`/projects/${s}/sessions/${e}`,t),a=(s,e)=>o.delete(`/projects/${s}/sessions/${e}`),p=(s,e)=>o.post(`/projects/${s}/sessions/switch`,e),$=(s,e)=>o.post(`/projects/${s}/send`,e);export{$ as a,a as d,c as g,i as l,r,p as s};
@@ -1,4 +1,4 @@
1
- import{c}from"./index-B36eowj-.js";/**
1
+ import{c}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as e}from"./index-B36eowj-.js";/**
1
+ import{c as e}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1,6 @@
1
+ import{c}from"./index-cI3pWBnN.js";/**
2
+ * @license lucide-react v0.487.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const e=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],r=c("user",e);export{r as U};
@@ -1,4 +1,4 @@
1
- import{c as a}from"./index-B36eowj-.js";/**
1
+ import{c as a}from"./index-cI3pWBnN.js";/**
2
2
  * @license lucide-react v0.487.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -0,0 +1 @@
1
+ const e={dashboard:"概览",chat:"聊天",chatDesktop:"桌面聊天",chatWeb:"聊天",workspace:"工作区",knowledge:"知识库",projects:"项目",sessions:"会话",cron:"定时任务",monitors:"监控任务",bridge:"桥接",system:"系统"},t={title:"概览",version:"版本",uptime:"运行时间",platforms:"平台",projects:"项目",bridgeAdapters:"桥接适配器",noData:"暂无数据"},o={title:"项目",name:"名称",agent:"智能体",platforms:"平台",sessions:"会话",heartbeat:"心跳",settings:"设置",quiet:"静默模式",language:"语言",adminFrom:"管理来源",disabledCommands:"已禁用命令",save:"保存",detail:"详情",noProjects:"尚未配置项目",tabs:{overview:"概览",providers:"服务商",sandbox:"沙箱",heartbeat:"心跳",settings:"设置"}},s={title:"会话",id:"编号",sessionKey:"会话键",name:"名称",platform:"平台",active:"活跃",createdAt:"创建时间",history:"历史",send:"发送",messageInput:"消息",delete:"删除",noSessions:"暂无会话",noMessages:"暂无消息",notLiveHint:"当前聊天对象现在不在线,暂时不能继续回复。等有新消息进来后,这里会自动恢复可发送。",offline:"离线",justNow:"刚刚",allProjects:"全部项目",chat:"对话",enterSession:"进入会话",newChat:"新建聊天",selectProject:"选择项目",projectRequired:"开始聊天前请先选择一个项目。",noAvailableChatTarget:"当前项目还没有可直接聊天的会话,请先从会话列表打开一个可用会话。",noReadyChats:"当前没有可立即聊天的会话,请到“会话”页查看历史记录。",emptyProject:"这个项目下还没有任何会话。",emptySelection:"选择一个项目,然后开始新的聊天。",activeChat:"当前聊天",sendHint:"消息会发送到当前选中的项目。",waitingForReply:"正在等待助手回复…",preparingChat:"正在准备聊天…",pollTimeout:"刷新超时前未收到完整回复。",createFailed:"创建新聊天会话失败。",loadFailed:"加载所选会话失败。",sendFailed:"发送消息失败。",sessionUnavailable:"当前聊天对象现在不在线,暂时不能继续回复。等有新消息进来后再试。",deleteConfirmTitle:"删除会话",deleteConfirmBody:"这会移除该会话保存的历史对话。",renameTitle:"重命名会话",renamePlaceholder:"会话名称",loadSession:"打开",historyTitle:"历史会话",availableNow:"可发送消息",waitingActivation:"等待激活"},n={title:"模型提供方",name:"名称",model:"模型",baseUrl:"基础 URL",active:"当前使用",add:"添加提供方",remove:"移除",activate:"启用",setModel:"设置模型",models:"可用模型"},a={title:"定时任务",expression:"Cron 表达式",prompt:"提示词",exec:"执行",description:"描述",enabled:"已启用",silent:"静默",lastRun:"上次运行",lastError:"上次错误",add:"添加任务",delete:"删除",noJobs:"暂无定时任务",workDir:"工作目录",sessionKey:"会话键",project:"项目"},i={title:"监控任务",prompt:"提示词",condition:"触发条件",cooldown:"冷却时间(分钟)",enabled:"已启用",lastRun:"上次触发",add:"添加监控",edit:"编辑监控",run:"立即执行",noMonitors:"暂无监控任务",monitorTitle:"标题"},r={title:"心跳",status:"状态",interval:"间隔",paused:"已暂停",running:"运行中",pause:"暂停",resume:"恢复",trigger:"立即执行",setInterval:"设置间隔",runCount:"执行次数",errorCount:"错误次数",skippedBusy:"跳过(忙碌)",lastRun:"上次运行"},l={title:"桥接",platform:"平台",capabilities:"能力",connectedAt:"连接时间",noAdapters:"暂无桥接适配器"},c={title:"系统",config:"配置",logs:"日志",restart:"重启",reload:"重载配置",restartConfirm:"确定要重启服务吗?进行中的会话可能会中断。",reloadConfirm:"从磁盘重新加载配置?",level:"日志级别",limit:"行数限制"},d={title:"AgentDock",subtitle:"连接到您的 AgentDock 实例",token:"API 令牌",serverUrl:"服务器地址",connect:"连接",invalidToken:"令牌无效或已过期",logout:"退出登录"},m={loading:"加载中…",error:"错误",success:"成功",confirm:"确认",cancel:"取消",save:"保存",delete:"删除",back:"返回",refresh:"刷新",search:"搜索",noData:"无数据",actions:"操作",viewAll:"查看全部",optional:"可选",confirmDelete:"确定要删除吗?"},p={light:"浅色",dark:"深色",system:"跟随系统"},g={nav:e,dashboard:t,projects:o,sessions:s,providers:n,cron:a,monitors:i,heartbeat:r,bridge:l,system:c,login:d,common:m,theme:p};export{l as bridge,m as common,a as cron,t as dashboard,g as default,r as heartbeat,d as login,i as monitors,e as nav,o as projects,n as providers,s as sessions,c as system,p as theme};
@@ -0,0 +1 @@
1
+ const e={dashboard:"總覽",chat:"聊天",chatDesktop:"桌面聊天",chatWeb:"聊天",workspace:"工作區",knowledge:"知識庫",projects:"專案",sessions:"工作階段",cron:"排程工作",bridge:"橋接",system:"系統"},t={title:"總覽",version:"版本",uptime:"運作時間",platforms:"平台",projects:"專案",bridgeAdapters:"橋接介接器",noData:"尚無資料"},s={title:"專案",name:"名稱",agent:"智慧代理",platforms:"平台",sessions:"工作階段",heartbeat:"心跳",settings:"設定",quiet:"靜音模式",language:"語言",adminFrom:"管理來源",disabledCommands:"已停用指令",save:"儲存",detail:"詳細資料",noProjects:"尚未設定專案",tabs:{overview:"總覽",providers:"供應商",sandbox:"沙箱",heartbeat:"心跳",settings:"設定"}},o={title:"工作階段",id:"編號",sessionKey:"工作階段金鑰",name:"名稱",platform:"平台",active:"使用中",createdAt:"建立時間",history:"歷程",send:"傳送",messageInput:"訊息",delete:"刪除",noSessions:"尚無工作階段",noMessages:"暫無訊息",notLiveHint:"目前這個聊天對象不在線上,暫時無法繼續回覆。等有新訊息進來後,這裡會自動恢復可傳送。",offline:"離線",justNow:"剛剛",allProjects:"全部專案",chat:"對話",enterSession:"進入工作階段",newChat:"新增聊天",selectProject:"選擇專案",projectRequired:"開始聊天前請先選擇一個專案。",noAvailableChatTarget:"這個專案目前還沒有可直接聊天的對話,請先從工作階段頁面開啟一個可用對話。",noReadyChats:"目前沒有可立即聊天的對話,請到「工作階段」頁面查看歷史記錄。",emptyProject:"這個專案下還沒有任何工作階段。",emptySelection:"選擇一個專案,然後開始新的聊天。",activeChat:"目前聊天",sendHint:"訊息會傳送到目前選取的專案。",waitingForReply:"正在等待助手回覆…",preparingChat:"正在準備聊天…",pollTimeout:"在重新整理逾時前尚未收到完整回覆。",createFailed:"建立新聊天工作階段失敗。",loadFailed:"載入所選工作階段失敗。",sendFailed:"傳送訊息失敗。",sessionUnavailable:"目前這個聊天對象不在線上,暫時無法繼續回覆。等有新訊息進來後再試一次。",deleteConfirmTitle:"刪除工作階段",deleteConfirmBody:"這會移除該工作階段儲存的歷史對話。",renameTitle:"重新命名工作階段",renamePlaceholder:"工作階段名稱",loadSession:"開啟",historyTitle:"歷史工作階段",availableNow:"可傳送訊息",waitingActivation:"等待啟用"},a={title:"模型供應商",name:"名稱",model:"模型",baseUrl:"基礎 URL",active:"使用中",add:"新增供應商",remove:"移除",activate:"啟用",setModel:"設定模型",models:"可用模型"},n={title:"排程工作",expression:"Cron 運算式",prompt:"提示詞",exec:"執行",description:"說明",enabled:"已啟用",silent:"靜音",lastRun:"上次執行",lastError:"上次錯誤",add:"新增工作",delete:"刪除",noJobs:"尚無排程工作",workDir:"工作目錄",sessionKey:"工作階段金鑰",project:"專案"},i={title:"心跳",status:"狀態",interval:"間隔",paused:"已暫停",running:"執行中",pause:"暫停",resume:"繼續",trigger:"立即執行",setInterval:"設定間隔",runCount:"執行次數",errorCount:"錯誤次數",skippedBusy:"略過(忙碌)",lastRun:"上次執行"},r={title:"橋接",platform:"平台",capabilities:"能力",connectedAt:"連線時間",noAdapters:"尚無橋接介接器"},l={title:"系統",config:"設定",logs:"記錄",restart:"重新啟動",reload:"重新載入設定",restartConfirm:"確定要重新啟動服務嗎?進行中的工作階段可能會中斷。",reloadConfirm:"從磁碟重新載入設定?",level:"記錄層級",limit:"筆數上限"},c={title:"AgentDock",subtitle:"連線至您的 AgentDock 執行個體",token:"API 權杖",serverUrl:"伺服器位址",connect:"連線",invalidToken:"權杖無效或已過期",logout:"登出"},d={loading:"載入中…",error:"錯誤",success:"成功",confirm:"確認",cancel:"取消",save:"儲存",delete:"刪除",back:"返回",refresh:"重新整理",search:"搜尋",noData:"無資料",actions:"操作",viewAll:"檢視全部",optional:"選填",confirmDelete:"確定要刪除嗎?"},m={light:"淺色",dark:"深色",system:"跟隨系統"},p={nav:e,dashboard:t,projects:s,sessions:o,providers:a,cron:n,heartbeat:i,bridge:r,system:l,login:c,common:d,theme:m};export{r as bridge,d as common,n as cron,t as dashboard,p as default,i as heartbeat,c as login,e as nav,s as projects,a as providers,o as sessions,l as system,m as theme};
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>AgentDock</title>
8
- <script type="module" crossorigin src="./assets/index-B36eowj-.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-CaQZSRbg.css">
8
+ <script type="module" crossorigin src="./assets/index-cI3pWBnN.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-CO4fGqmv.css">
10
10
  </head>
11
11
  <body class="bg-[#f5f5f7] dark:bg-[#151516]">
12
12
  <div id="root"></div>
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const electron_1 = require("electron");
4
4
  const node_child_process_1 = require("node:child_process");
5
5
  const node_fs_1 = require("node:fs");
6
+ const node_net_1 = require("node:net");
6
7
  const node_path_1 = require("node:path");
7
8
  let mainWindow = null;
8
9
  let localCoreProcess = null;
@@ -38,7 +39,24 @@ async function isLocalCoreHealthy(timeoutMs = 350) {
38
39
  clearTimeout(timer);
39
40
  }
40
41
  }
41
- async function waitForLocalCoreHealthy(timeoutMs = 15000) {
42
+ async function isLocalCorePortListening(timeoutMs = 350) {
43
+ return new Promise((resolve) => {
44
+ const socket = (0, node_net_1.createConnection)({ host: '127.0.0.1', port: 9831 });
45
+ let settled = false;
46
+ const finish = (listening) => {
47
+ if (settled) {
48
+ return;
49
+ }
50
+ settled = true;
51
+ socket.destroy();
52
+ resolve(listening);
53
+ };
54
+ socket.setTimeout(timeoutMs, () => finish(false));
55
+ socket.once('connect', () => finish(true));
56
+ socket.once('error', () => finish(false));
57
+ });
58
+ }
59
+ async function waitForLocalCoreHealthy(timeoutMs = 60000) {
42
60
  const startedAt = Date.now();
43
61
  while (Date.now() - startedAt < timeoutMs) {
44
62
  if (await isLocalCoreHealthy(500)) {
@@ -63,6 +81,10 @@ async function ensureLocalCoreProcess() {
63
81
  return localCoreStartupPromise;
64
82
  }
65
83
  localCoreStartupPromise = (async () => {
84
+ if (await isLocalCorePortListening()) {
85
+ await waitForLocalCoreHealthy();
86
+ return;
87
+ }
66
88
  if (!localCoreProcess) {
67
89
  const entry = localCoreEntryPath();
68
90
  if (!(0, node_fs_1.existsSync)(entry)) {
@@ -152,6 +174,9 @@ electron_1.app.whenReady().then(async () => {
152
174
  createWindow();
153
175
  }
154
176
  });
177
+ }).catch((error) => {
178
+ console.error(error instanceof Error ? error.stack || error.message : String(error));
179
+ electron_1.app.quit();
155
180
  });
156
181
  electron_1.app.on('window-all-closed', () => {
157
182
  if (process.platform !== 'darwin') {
@@ -13,10 +13,17 @@ exports.listRuntimeDetections = listRuntimeDetections;
13
13
  exports.getRuntimeDetection = getRuntimeDetection;
14
14
  exports.refreshRuntimeDetections = refreshRuntimeDetections;
15
15
  exports.refreshRuntimeDetection = refreshRuntimeDetection;
16
+ exports.listDiagnosticErrors = listDiagnosticErrors;
17
+ exports.runDiagnosticsDoctor = runDiagnosticsDoctor;
18
+ exports.runDeploymentDiagnostics = runDeploymentDiagnostics;
16
19
  exports.readCoreConfigFile = readCoreConfigFile;
17
20
  exports.saveCoreRawConfigFile = saveCoreRawConfigFile;
18
21
  exports.saveCoreStructuredConfigFile = saveCoreStructuredConfigFile;
19
22
  exports.saveCoreSettings = saveCoreSettings;
23
+ exports.listModelProviders = listModelProviders;
24
+ exports.createModelProvider = createModelProvider;
25
+ exports.updateModelProvider = updateModelProvider;
26
+ exports.deleteModelProvider = deleteModelProvider;
20
27
  exports.listChannelGateways = listChannelGateways;
21
28
  exports.getChannelGatewayStatus = getChannelGatewayStatus;
22
29
  exports.testChannelConnection = testChannelConnection;
@@ -235,6 +242,15 @@ async function refreshRuntimeDetections() {
235
242
  async function refreshRuntimeDetection(runtimeId) {
236
243
  return coreRequest('POST', `/runtimes/${encodeURIComponent(runtimeId)}/refresh`);
237
244
  }
245
+ async function listDiagnosticErrors() {
246
+ return coreRequest('GET', '/diagnostics/errors');
247
+ }
248
+ async function runDiagnosticsDoctor() {
249
+ return coreRequest('POST', '/diagnostics/doctor');
250
+ }
251
+ async function runDeploymentDiagnostics() {
252
+ return coreRequest('POST', '/diagnostics/deployment');
253
+ }
238
254
  async function readCoreConfigFile() {
239
255
  return coreRequest('GET', '/runtime/config');
240
256
  }
@@ -247,6 +263,18 @@ async function saveCoreStructuredConfigFile(config) {
247
263
  async function saveCoreSettings(input) {
248
264
  return coreRequest('POST', '/runtime/settings', input);
249
265
  }
266
+ async function listModelProviders() {
267
+ return coreRequest('GET', '/providers');
268
+ }
269
+ async function createModelProvider(input) {
270
+ return coreRequest('POST', '/providers', input);
271
+ }
272
+ async function updateModelProvider(providerId, input) {
273
+ return coreRequest('PUT', `/providers/${encodeURIComponent(providerId)}`, input);
274
+ }
275
+ async function deleteModelProvider(providerId) {
276
+ return coreRequest('DELETE', `/providers/${encodeURIComponent(providerId)}`);
277
+ }
250
278
  async function listChannelGateways(platform) {
251
279
  return coreRequest('GET', `/platforms/${encodeURIComponent(platform)}`);
252
280
  }
@@ -13,8 +13,8 @@ const local_core_slash_commands_js_1 = require("./local-core-slash-commands.js")
13
13
  const local_core_acp_progress_js_1 = require("./local-core-acp-progress.js");
14
14
  const index_js_1 = require("../agents/index.js");
15
15
  const scheduled_job_route_js_1 = require("../scheduler/scheduled-job-route.js");
16
- const thread_command_service_js_1 = require("../thread/thread-command-service.js");
17
- const session_command_service_js_1 = require("../thread/session-command-service.js");
16
+ const thread_slash_command_dispatcher_js_1 = require("../thread/thread-slash-command-dispatcher.js");
17
+ const local_core_errors_js_1 = require("../kernel/local-core-errors.js");
18
18
  const ACP_PROMPT_TIMEOUT_MS = 15 * 60 * 1000;
19
19
  class LocalCoreAcpBackend {
20
20
  options;
@@ -22,8 +22,7 @@ class LocalCoreAcpBackend {
22
22
  turnCoordinator;
23
23
  sessionCoordinator;
24
24
  responseProcessor;
25
- commandService;
26
- sessionCommandService;
25
+ slashCommands;
27
26
  constructor(options) {
28
27
  this.options = options;
29
28
  this.transport = new local_core_acp_transport_js_1.LocalCoreAcpTransport({
@@ -91,25 +90,28 @@ class LocalCoreAcpBackend {
91
90
  emitBridge: (event) => this.emitBridgeEvent(event),
92
91
  log: options.log,
93
92
  });
94
- this.commandService = new thread_command_service_js_1.ThreadCommandService({
95
- getThreadRow: (threadId) => this.options.store.getThreadRow(threadId),
96
- updateThreadAgentMode: (threadId, mode) => this.options.store.updateThreadAgentMode(threadId, mode),
97
- updateThreadAgentType: (threadId, agentType) => this.options.store.updateThreadAgentType(threadId, agentType),
98
- getLatestRunForThread: (threadId) => this.options.store.getLatestRunForThread(threadId),
99
- createAuditEvent: (input) => {
100
- this.options.store.createAuditEvent(input);
93
+ this.slashCommands = new thread_slash_command_dispatcher_js_1.ThreadSlashCommandDispatcher({
94
+ session: {
95
+ listThreads: (workspaceId) => this.listThreads(workspaceId),
96
+ getThread: (targetThreadId) => this.getThread(targetThreadId),
97
+ createThread: (workspaceId, title) => this.createThread(workspaceId, title),
98
+ renameThread: (targetThreadId, title) => this.renameThread(targetThreadId, title),
99
+ deleteThread: (targetThreadId) => this.deleteThread(targetThreadId),
100
+ },
101
+ thread: {
102
+ getThreadRow: (threadId) => this.options.store.getThreadRow(threadId),
103
+ updateThreadAgentMode: (threadId, mode) => this.options.store.updateThreadAgentMode(threadId, mode),
104
+ updateThreadAgentType: (threadId, agentType) => this.options.store.updateThreadAgentType(threadId, agentType),
105
+ getLatestRunForThread: (threadId) => this.options.store.getLatestRunForThread(threadId),
106
+ createAuditEvent: (input) => {
107
+ this.options.store.createAuditEvent(input);
108
+ },
109
+ getAgentTypes: options.getAgentTypes,
110
+ setThreadMode: (threadId, mode) => this.sessionCoordinator.setThreadMode(threadId, mode),
111
+ closeThreadSession: (threadId) => this.sessionCoordinator.closeThreadSession(threadId),
112
+ interruptRun: (runId) => this.sessionCoordinator.interruptRun(runId),
113
+ log: options.log,
101
114
  },
102
- getAgentTypes: options.getAgentTypes,
103
- setThreadMode: (threadId, mode) => this.sessionCoordinator.setThreadMode(threadId, mode),
104
- closeThreadSession: (threadId) => this.sessionCoordinator.closeThreadSession(threadId),
105
- log: options.log,
106
- });
107
- this.sessionCommandService = new session_command_service_js_1.SessionCommandService({
108
- listThreads: (workspaceId) => this.listThreads(workspaceId),
109
- getThread: (targetThreadId) => this.getThread(targetThreadId),
110
- createThread: (workspaceId, title) => this.createThread(workspaceId, title),
111
- renameThread: (targetThreadId, title) => this.renameThread(targetThreadId, title),
112
- deleteThread: (targetThreadId) => this.deleteThread(targetThreadId),
113
115
  });
114
116
  this.responseProcessor = new local_core_acp_response_processor_js_1.LocalCoreAcpResponseProcessor({
115
117
  getScheduledDeliveryBinding: (threadId) => {
@@ -173,22 +175,24 @@ class LocalCoreAcpBackend {
173
175
  source: 'user',
174
176
  },
175
177
  });
176
- const sessionCommandResult = await this.sessionCommandService.execute(content, {
177
- currentThreadId: threadId,
178
+ const slashCommandResult = await this.slashCommands.execute({
179
+ threadId,
178
180
  workspaceId: row.workspace_id,
181
+ content,
182
+ defaultAgentType: config.agentType,
179
183
  defaultTitle: `New thread ${new Date().toLocaleTimeString()}`,
180
184
  });
181
- if (sessionCommandResult.handled) {
182
- const activeThreadEffect = (sessionCommandResult.effects || [])
185
+ if (slashCommandResult.handled) {
186
+ const activeThreadEffect = (slashCommandResult.effects || [])
183
187
  .find((effect) => effect.type === 'activate_thread');
184
- this.options.store.appendMessage(threadId, 'assistant', sessionCommandResult.displayText, 'final');
188
+ this.options.store.appendMessage(threadId, 'assistant', slashCommandResult.displayText, 'final');
185
189
  this.options.eventBus.emit({
186
190
  type: 'thread.message.accepted',
187
191
  payload: {
188
192
  threadId,
189
193
  workspaceId: row.workspace_id,
190
194
  role: 'assistant',
191
- content: sessionCommandResult.displayText,
195
+ content: slashCommandResult.displayText,
192
196
  kind: 'final',
193
197
  source: 'system',
194
198
  },
@@ -207,37 +211,7 @@ class LocalCoreAcpBackend {
207
211
  this.emitBridgeEvent({
208
212
  type: 'reply',
209
213
  sessionKey: row.bridge_session_key,
210
- content: sessionCommandResult.displayText,
211
- });
212
- this.emitBridgeEvent({
213
- type: 'typing_stop',
214
- sessionKey: row.bridge_session_key,
215
- });
216
- return { runId: '' };
217
- }
218
- const commandResult = await this.commandService.execute({
219
- threadId,
220
- workspaceId: row.workspace_id,
221
- content,
222
- defaultAgentType: config.agentType,
223
- });
224
- if (commandResult.handled) {
225
- this.options.store.appendMessage(threadId, 'assistant', commandResult.displayText, 'final');
226
- this.options.eventBus.emit({
227
- type: 'thread.message.accepted',
228
- payload: {
229
- threadId,
230
- workspaceId: row.workspace_id,
231
- role: 'assistant',
232
- content: commandResult.displayText,
233
- kind: 'final',
234
- source: 'system',
235
- },
236
- });
237
- this.emitBridgeEvent({
238
- type: 'reply',
239
- sessionKey: row.bridge_session_key,
240
- content: commandResult.displayText,
214
+ content: slashCommandResult.displayText,
241
215
  });
242
216
  this.emitBridgeEvent({
243
217
  type: 'typing_stop',
@@ -257,6 +231,24 @@ class LocalCoreAcpBackend {
257
231
  title: content.trim().slice(0, 80) || row.title || 'Agent task',
258
232
  prompt: content,
259
233
  status: 'running',
234
+ metadata: {
235
+ execution: config.execution || {
236
+ mode: config.sandbox?.enabled ? 'sandbox' : 'local',
237
+ transport: config.sandbox?.enabled ? `sandbox-${config.sandbox.transport}-stdio-proxy` : 'stdio',
238
+ },
239
+ ...(config.sandbox?.enabled
240
+ ? {
241
+ sandbox: {
242
+ provider: config.sandbox.provider,
243
+ image: config.sandbox.image,
244
+ transport: config.sandbox.transport,
245
+ acpPort: config.sandbox.acpPort,
246
+ stateScope: config.sandbox.stateScope,
247
+ stateMount: config.sandbox.stateMount || null,
248
+ },
249
+ }
250
+ : {}),
251
+ },
260
252
  });
261
253
  this.options.eventBus.emit({
262
254
  type: 'run.started',
@@ -320,6 +312,12 @@ class LocalCoreAcpBackend {
320
312
  async interruptRun(runId) {
321
313
  return this.sessionCoordinator.interruptRun(runId);
322
314
  }
315
+ async setThreadMode(threadId, mode) {
316
+ return this.sessionCoordinator.setThreadMode(threadId, mode);
317
+ }
318
+ closeThreadSession(threadId) {
319
+ this.sessionCoordinator.closeThreadSession(threadId);
320
+ }
323
321
  async runPrompt(threadId, runId, bridgeSessionKey, config, input, options = {}) {
324
322
  const row = this.options.store.getThreadRow(threadId);
325
323
  if (!row) {
@@ -333,11 +331,14 @@ class LocalCoreAcpBackend {
333
331
  const message = (0, local_core_acp_content_js_1.normalizeThreadMessageInput)(input);
334
332
  const content = message.displayText;
335
333
  let session = null;
334
+ const runStartedAt = Date.now();
336
335
  try {
337
336
  session = await this.sessionCoordinator.ensureSession(threadId, bridgeSessionKey, config, {
338
337
  permissionMode: options.permissionMode,
339
338
  runtimeEnv: options.runtimeEnv,
339
+ runId,
340
340
  });
341
+ this.options.log?.(`[acp.run:${runId}] session ready in ${Date.now() - runStartedAt}ms`);
341
342
  const priorAssistantFinalMessages = this.options.store
342
343
  .getThread(threadId, [])
343
344
  .messages
@@ -385,8 +386,10 @@ class LocalCoreAcpBackend {
385
386
  messageId: (0, node_crypto_1.randomUUID)(),
386
387
  prompt: message.contentParts,
387
388
  }, ACP_PROMPT_TIMEOUT_MS);
389
+ this.options.log?.(`[acp.run:${runId}] prompt sent in ${Date.now() - runStartedAt}ms`);
388
390
  session.promptPromise = promptPromise;
389
391
  const result = await promptPromise;
392
+ this.options.log?.(`[acp.run:${runId}] prompt completed in ${Date.now() - runStartedAt}ms`);
390
393
  const currentTurn = session.currentTurn;
391
394
  if (!currentTurn || currentTurn.runId !== runId) {
392
395
  return;
@@ -492,13 +495,18 @@ class LocalCoreAcpBackend {
492
495
  });
493
496
  }
494
497
  catch (error) {
495
- const errorContent = `Agent error: ${error instanceof Error ? error.message : String(error)}`;
498
+ const errorInfo = (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error, 'internal_error', {
499
+ threadId,
500
+ workspaceId: row.workspace_id,
501
+ runtimeId: config.agentType,
502
+ });
503
+ const errorContent = (0, local_core_errors_js_1.formatUserError)(errorInfo);
496
504
  this.options.store.updateRun(runId, threadId, 'failed');
497
505
  const task = this.options.store.getAgentTaskByRunId(runId);
498
506
  if (task) {
499
507
  this.options.store.updateAgentTask(task.taskId, {
500
508
  status: 'failed',
501
- error: error instanceof Error ? error.message : String(error),
509
+ error: errorInfo.message,
502
510
  });
503
511
  }
504
512
  this.options.store.appendMessage(threadId, 'assistant', errorContent, 'final');
@@ -519,7 +527,21 @@ class LocalCoreAcpBackend {
519
527
  runId,
520
528
  threadId,
521
529
  workspaceId: row.workspace_id,
522
- error: error instanceof Error ? error.message : String(error),
530
+ error: errorInfo.message,
531
+ errorInfo,
532
+ },
533
+ });
534
+ this.options.eventBus.emit({
535
+ type: 'localcore.error',
536
+ payload: {
537
+ scope: 'acp.run',
538
+ errorInfo,
539
+ context: {
540
+ threadId,
541
+ workspaceId: row.workspace_id,
542
+ runtimeId: config.agentType,
543
+ runId,
544
+ },
523
545
  },
524
546
  });
525
547
  this.emitBridgeEvent({
@@ -544,16 +566,43 @@ class LocalCoreAcpBackend {
544
566
  if (session) {
545
567
  session.promptPromise = null;
546
568
  }
569
+ if (config.sandbox?.enabled) {
570
+ this.sessionCoordinator.releaseThreadSession(threadId, config);
571
+ }
547
572
  }
548
573
  }
549
574
  handleAgentRequest(session, payload) {
550
575
  this.turnCoordinator.handleAgentRequest(session, payload);
551
576
  }
552
577
  handleAgentNotification(session, payload) {
578
+ if (session.currentTurn && !session.currentTurn.firstAgentUpdateLogged) {
579
+ session.currentTurn.firstAgentUpdateLogged = true;
580
+ this.options.log?.(`[acp.run:${session.currentTurn.runId}] first agent update received`);
581
+ }
553
582
  this.turnCoordinator.handleAgentNotification(session, payload);
554
583
  }
555
584
  handleTransportSessionClosed(session, error) {
585
+ const row = this.options.store.getThreadRow(session.threadId);
586
+ const runtimeId = session.currentTurn?.agentType || row?.agent_type || '';
587
+ const errorInfo = (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error, 'runtime_exited', {
588
+ threadId: session.threadId,
589
+ workspaceId: row?.workspace_id || '',
590
+ runtimeId,
591
+ });
556
592
  this.sessionCoordinator.handleTransportSessionClosed(session, error);
593
+ this.options.eventBus.emit({
594
+ type: 'localcore.error',
595
+ payload: {
596
+ scope: 'acp.session',
597
+ errorInfo,
598
+ context: {
599
+ threadId: session.threadId,
600
+ workspaceId: row?.workspace_id || '',
601
+ runtimeId,
602
+ runId: session.currentRunId || '',
603
+ },
604
+ },
605
+ });
557
606
  }
558
607
  emitBridgeEvent(event) {
559
608
  if (event.replyCtx) {