@kafca/agentdock 0.1.55 → 0.1.57

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 (185) hide show
  1. package/README.md +14 -0
  2. package/dist/renderer/assets/{Badge-Bg_nNvBL.js → Badge-CDTbmw1h.js} +1 -1
  3. package/dist/renderer/assets/Card-DayUo35w.js +1 -0
  4. package/dist/renderer/assets/Config-ByGMQuzR.js +21 -0
  5. package/dist/renderer/assets/CronList-XqHdVlgu.js +1 -0
  6. package/dist/renderer/assets/Dashboard-CZj-oANw.js +41 -0
  7. package/dist/renderer/assets/{EmptyState-C60g3RMj.js → EmptyState-EFMkOjZO.js} +1 -1
  8. package/dist/renderer/assets/HighlightedMarkdown-DyvF3DHK.js +12 -0
  9. package/dist/renderer/assets/Input-DxoWVc9d.js +1 -0
  10. package/dist/renderer/assets/{KnowledgeDetail-CC5C7JYe.js → KnowledgeDetail-CbUb2tG7.js} +2 -2
  11. package/dist/renderer/assets/{KnowledgeHome-3rlvxgWf.js → KnowledgeHome-BWV1gz4f.js} +3 -3
  12. package/dist/renderer/assets/Logs-DqnanQTc.js +6 -0
  13. package/dist/renderer/assets/{Modal-BQUW9LSf.js → Modal-yY7TzR0x.js} +3 -3
  14. package/dist/renderer/assets/MonitorList-CIjGQkFs.js +1 -0
  15. package/dist/renderer/assets/Page-vwHNUdoj.js +1 -0
  16. package/dist/renderer/assets/{Select-CfRkos3z.js → Select-CmbK36pN.js} +2 -2
  17. package/dist/renderer/assets/ThreadChat-4OceMgM4.js +86 -0
  18. package/dist/renderer/assets/Workspace-DplPJOjJ.js +19 -0
  19. package/dist/renderer/assets/{arrow-left-D1DbXrLA.js → arrow-left-C8HfBt2K.js} +1 -1
  20. package/dist/renderer/assets/{book-open-BxC1z1C1.js → book-open-BCdZWncQ.js} +1 -1
  21. package/dist/renderer/assets/channels-hgO3cAIx.js +6 -0
  22. package/dist/renderer/assets/chevron-down-BPk77tqY.js +11 -0
  23. package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
  24. package/dist/renderer/assets/index-BlA4xPdd.js +41 -0
  25. package/dist/renderer/assets/index-wYpjqVqC.js +167 -0
  26. package/dist/renderer/assets/knowledge-7pl06KuH.js +1 -0
  27. package/dist/renderer/assets/{pencil-X44UaxwR.js → pencil-CB1SWZ9A.js} +1 -1
  28. package/dist/renderer/assets/{play-ujo-De38.js → play-BvsoXUrM.js} +1 -1
  29. package/dist/renderer/assets/{plus-BHgVdG_A.js → plus-CokBDnaL.js} +1 -1
  30. package/dist/renderer/assets/{save-Cz6giKrE.js → save-D-w4kATO.js} +1 -1
  31. package/dist/renderer/assets/{search-DKWvTqi5.js → search-Cnsn6i4Q.js} +1 -1
  32. package/dist/renderer/assets/{shield-check-V82O8AC1.js → shield-check-Cjja2Gh6.js} +1 -1
  33. package/dist/renderer/assets/threads-BCm6j4eI.js +1 -0
  34. package/dist/renderer/assets/{trash-2-_Fgwk8mc.js → trash-2-CIxz9qYY.js} +1 -1
  35. package/dist/renderer/index.html +2 -2
  36. package/dist-electron/packages/contracts/src/automation.js +2 -0
  37. package/dist-electron/packages/contracts/src/channels.js +2 -0
  38. package/dist-electron/packages/contracts/src/knowledge.js +2 -0
  39. package/dist-electron/packages/contracts/src/local-core.js +15 -0
  40. package/dist-electron/packages/contracts/src/runtime.js +2 -0
  41. package/dist-electron/packages/contracts/src/scheduler.js +2 -0
  42. package/dist-electron/packages/contracts/src/threads.js +2 -0
  43. package/dist-electron/packages/core-sdk/src/automation.js +32 -0
  44. package/dist-electron/packages/core-sdk/src/channels.js +121 -0
  45. package/dist-electron/packages/core-sdk/src/client.js +455 -0
  46. package/dist-electron/packages/core-sdk/src/index.js +43 -607
  47. package/dist-electron/packages/core-sdk/src/knowledge.js +85 -0
  48. package/dist-electron/packages/core-sdk/src/request.js +22 -0
  49. package/dist-electron/packages/core-sdk/src/runtime.js +214 -0
  50. package/dist-electron/packages/core-sdk/src/scheduler.js +32 -0
  51. package/dist-electron/packages/core-sdk/src/threads.js +67 -0
  52. package/dist-electron/packages/plugin-sdk/src/agents.js +2 -0
  53. package/dist-electron/packages/plugin-sdk/src/automation.js +2 -0
  54. package/dist-electron/packages/plugin-sdk/src/channels.js +2 -0
  55. package/dist-electron/packages/plugin-sdk/src/index.js +21 -0
  56. package/dist-electron/packages/plugin-sdk/src/knowledge.js +2 -0
  57. package/dist-electron/packages/plugin-sdk/src/runtime.js +2 -0
  58. package/dist-electron/packages/plugin-sdk/src/scheduler.js +2 -0
  59. package/dist-electron/packages/plugin-sdk/src/threads.js +2 -0
  60. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +6 -9
  61. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +2 -2
  62. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +3 -3
  63. package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +5 -5
  64. package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +12 -12
  65. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +2 -2
  66. package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +11 -11
  67. package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +3 -3
  68. package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +7 -7
  69. package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +2 -2
  70. package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +3 -3
  71. package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +3 -3
  72. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +2 -2
  73. package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +4 -4
  74. package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +2 -2
  75. package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +2 -2
  76. package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +3 -3
  77. package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +1 -1
  78. package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +4 -4
  79. package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +33 -18
  80. package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -2
  81. package/dist-electron/services/local-ai-core/src/channel/lark/gateway-utils.js +91 -0
  82. package/dist-electron/services/local-ai-core/src/channel/lark/inbound-handler.js +180 -0
  83. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +52 -456
  84. package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +124 -0
  85. package/dist-electron/services/local-ai-core/src/channel/shared/inbound-attachment-store.js +93 -0
  86. package/dist-electron/services/local-ai-core/src/channel/shared/inbound-authorization.js +54 -0
  87. package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +2 -2
  88. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-media.js +21 -0
  89. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +167 -0
  90. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +98 -483
  91. package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +156 -0
  92. package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +100 -0
  93. package/dist-electron/services/local-ai-core/src/cli/lac.js +6 -6
  94. package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
  95. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
  96. package/dist-electron/services/local-ai-core/src/kernel/local-core-errors.js +33 -5
  97. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +2 -2
  98. package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +2 -2
  99. package/dist-electron/services/local-ai-core/src/router/workspace-bridge-event-stream.js +29 -0
  100. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +5 -5
  101. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +47 -60
  102. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -5
  103. package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +6 -6
  104. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +3 -3
  105. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +3 -1
  106. package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +11 -2
  107. package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +12 -6
  108. package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +10 -2
  109. package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +18 -6
  110. package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +7 -2
  111. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +28 -3
  112. package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +10 -2
  113. package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +18 -5
  114. package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +14 -2
  115. package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +18 -15
  116. package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +13 -2
  117. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +35 -8
  118. package/dist-electron/services/local-ai-core/src/runtime/request-validation.js +79 -0
  119. package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +9 -9
  120. package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +10 -1
  121. package/dist-electron/services/local-ai-core/src/runtime/server.js +2 -1
  122. package/dist-electron/services/local-ai-core/src/runtime/workspace-project-registry.js +76 -0
  123. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
  124. package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +75 -0
  125. package/dist-electron/shared/desktop.js +1 -64
  126. package/dist-electron/src/components/chat/chat-controller-state.js +60 -0
  127. package/dist-electron/src/components/chat/chat-event-gate.js +146 -0
  128. package/dist-electron/src/components/chat/markdown-code-block.js +8 -0
  129. package/dist-electron/src/pages/Desktop/workspace-model.js +212 -0
  130. package/dist-electron/src/pages/Threads/thread-chat-model.js +50 -51
  131. package/dist-electron/tests/contracts/agent-message-policy.test.js +21 -0
  132. package/dist-electron/tests/contracts/architecture-docs.test.js +56 -33
  133. package/dist-electron/tests/contracts/chat-event-gate.test.js +114 -0
  134. package/dist-electron/tests/contracts/chat-markdown.test.js +16 -0
  135. package/dist-electron/tests/contracts/thread-task-state.test.js +32 -0
  136. package/dist-electron/tests/contracts/workspace-identity.test.js +23 -0
  137. package/dist-electron/tests/electron/core-client.test.js +284 -0
  138. package/dist-electron/tests/electron/plugin-kernel.test.js +54 -0
  139. package/dist-electron/tests/electron/renderer-packaging.test.js +9 -0
  140. package/dist-electron/tests/electron/workspace-task-store.test.js +31 -0
  141. package/dist-electron/tests/integration/channel-inbound-attachment-store.test.js +117 -0
  142. package/dist-electron/tests/integration/channel-inbound-authorization.test.js +80 -0
  143. package/dist-electron/tests/integration/lark-gateway-utils.test.js +13 -0
  144. package/dist-electron/tests/integration/lark-gateway.test.js +58 -4
  145. package/dist-electron/tests/integration/local-core-errors.test.js +41 -0
  146. package/dist-electron/tests/integration/weixin-gateway.test.js +36 -0
  147. package/dist-electron/tests/integration/weixin-runtime-state.test.js +32 -0
  148. package/dist-electron/tests/integration/weixin-text-utils.test.js +15 -0
  149. package/package.json +9 -4
  150. package/dist/renderer/assets/Chat-BJveQQKu.js +0 -2
  151. package/dist/renderer/assets/ChatMarkdown-Bqn2HJ6f.js +0 -45
  152. package/dist/renderer/assets/Config-CMtZDRAE.js +0 -21
  153. package/dist/renderer/assets/CronList-C-ILB_Ae.js +0 -1
  154. package/dist/renderer/assets/Dashboard-CsKBSQIe.js +0 -26
  155. package/dist/renderer/assets/Logs-CktemGN0.js +0 -1
  156. package/dist/renderer/assets/MonitorList-B0hxjuOZ.js +0 -1
  157. package/dist/renderer/assets/Page-DL_Nv2i5.js +0 -1
  158. package/dist/renderer/assets/ProjectDetail-Djr9-MyT.js +0 -11
  159. package/dist/renderer/assets/ProjectList-BKl4eW7q.js +0 -1
  160. package/dist/renderer/assets/SessionChat-Dxv8D5DW.js +0 -1
  161. package/dist/renderer/assets/SessionList-BJ2GjXvR.js +0 -1
  162. package/dist/renderer/assets/ThreadChat-CAsIl9qf.js +0 -28
  163. package/dist/renderer/assets/Workspace-CaUhiGBX.js +0 -19
  164. package/dist/renderer/assets/bot-Fw3IzhJA.js +0 -6
  165. package/dist/renderer/assets/check-5zCTgp3A.js +0 -6
  166. package/dist/renderer/assets/chevron-down-N3PxTNxH.js +0 -6
  167. package/dist/renderer/assets/circle-C_chUflo.js +0 -6
  168. package/dist/renderer/assets/desktop-DkQTZNhe.js +0 -1
  169. package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
  170. package/dist/renderer/assets/funnel-B8ZAv6I7.js +0 -6
  171. package/dist/renderer/assets/heart-M9A3E4Ed.js +0 -6
  172. package/dist/renderer/assets/index-Bwv855ID.js +0 -41
  173. package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
  174. package/dist/renderer/assets/index-DJ8w4e0l.js +0 -182
  175. package/dist/renderer/assets/projects-DB1FLZ3A.js +0 -1
  176. package/dist/renderer/assets/server-BsuHcYl4.js +0 -11
  177. package/dist/renderer/assets/session-utils-DnAWL3eo.js +0 -6
  178. package/dist/renderer/assets/sessions-DptxO_BE.js +0 -1
  179. package/dist/renderer/assets/user-DQKTaUcR.js +0 -6
  180. package/dist/renderer/assets/wifi-off-vjH-MD2w.js +0 -11
  181. package/dist-electron/src/api/client.js +0 -73
  182. package/dist-electron/src/api/sessions.js +0 -21
  183. package/dist-electron/src/lib/session-utils.js +0 -51
  184. package/dist-electron/src/pages/Projects/project-provider-config.js +0 -75
  185. package/dist-electron/tests/electron/project-provider-config.test.js +0 -71
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.composeAgentMessage = composeAgentMessage;
4
+ const SCHEDULER_INSTRUCTION = [
5
+ '[Scheduler Tools]',
6
+ 'If the user asks to create, view, edit, delete, or manually run a scheduled task for this conversation, use the Bash tool to run the local scheduler CLI.',
7
+ 'Use these commands:',
8
+ 'lac scheduler add --cron "<5-field cron>" --message "<exact message to send>" --desc "<short label>" [--execution-mode same-thread|side-thread]',
9
+ 'lac scheduler list',
10
+ 'lac scheduler list --thread',
11
+ 'lac scheduler info <short-job-id>',
12
+ 'lac scheduler edit <short-job-id> [--cron "<5-field cron>"] [--message "<exact message>"] [--desc "<short label>"] [--enabled true|false] [--execution-mode same-thread|side-thread]',
13
+ 'lac scheduler del <short-job-id>',
14
+ 'lac scheduler run <short-job-id>',
15
+ 'Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.',
16
+ 'Prefer relying on those variables instead of inventing your own route or creating session-only cron jobs.',
17
+ 'By default, `lac scheduler list` shows all scheduled tasks in the current workspace. Use `lac scheduler list --thread` to show only the current conversation thread.',
18
+ 'Use the short job id shown by `lac scheduler list`; do not add a `job:` prefix or expand it to a full UUID.',
19
+ 'Use `--execution-mode same-thread` to reuse the current thread, or `--execution-mode side-thread` to run in a dedicated scheduled thread.',
20
+ 'Only use the scheduler CLI when the user explicitly asks for scheduled automation.',
21
+ '[/Scheduler Tools]',
22
+ ].join('\n');
23
+ const MONITOR_INSTRUCTION = [
24
+ '[Monitor Tools]',
25
+ 'If the user asks to create, view, edit, delete, or manually run an event monitor for this conversation, use the Bash tool to run the local monitor CLI.',
26
+ 'Use these commands:',
27
+ 'lac monitor add --title "<short title>" --source stock.quote --symbol "<ticker>" --condition "<metric operator value>" --message "<exact analysis prompt>" [--cooldown 15m] [--execution-mode same-thread|side-thread]',
28
+ 'lac monitor list',
29
+ 'lac monitor list --thread',
30
+ 'lac monitor info <short-monitor-id>',
31
+ 'lac monitor edit <short-monitor-id> [--title "<title>"] [--condition "<expr>"] [--message "<exact prompt>"] [--enabled true|false] [--cooldown 15m] [--execution-mode same-thread|side-thread]',
32
+ 'lac monitor del <short-monitor-id>',
33
+ 'lac monitor run <short-monitor-id>',
34
+ 'Supported stock metrics include latestPrice, change_percent, changePercent, and abs_change_percent. Example condition: "abs_change_percent >= 3".',
35
+ 'Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.',
36
+ 'Prefer relying on those variables instead of inventing your own route.',
37
+ 'Use --execution-mode side-thread by default so monitor analysis does not interrupt the current conversation.',
38
+ 'Only use the monitor CLI when the user explicitly asks for event monitoring automation.',
39
+ '[/Monitor Tools]',
40
+ ].join('\n');
41
+ const CHANNEL_INSTRUCTION = [
42
+ '[Channel Tools]',
43
+ 'If the user asks you to send a local file back through the current channel conversation, use the Bash tool to run the local channel CLI.',
44
+ 'Use this command:',
45
+ 'lac channel send-file --path "<absolute-or-workdir-relative-file-path>" [--target "<channel-chat-or-user-id>"]',
46
+ 'By default, the file is sent to the current platform conversation from LOCAL_AI_CHAT_ID.',
47
+ 'Use --target only when the user explicitly names a different channel chat or user id.',
48
+ 'The CLI accepts absolute paths. Check that the file exists before sending when practical.',
49
+ 'Only use the channel CLI when the user explicitly asks to send a file through the channel.',
50
+ '[/Channel Tools]',
51
+ ].join('\n');
52
+ function composeAgentMessage(content, knowledgeBases = []) {
53
+ if (content.trim().startsWith('/')) {
54
+ return content;
55
+ }
56
+ const knowledgeBlock = knowledgeBases.length
57
+ ? [
58
+ '[Selected Knowledge Bases]',
59
+ ...knowledgeBases.map((base) => `- id: ${base.id} | name: ${base.name}`),
60
+ '[/Selected Knowledge Bases]',
61
+ ].join('\n')
62
+ : '';
63
+ return [
64
+ SCHEDULER_INSTRUCTION,
65
+ '',
66
+ MONITOR_INSTRUCTION,
67
+ '',
68
+ CHANNEL_INSTRUCTION,
69
+ ...(knowledgeBlock ? ['', knowledgeBlock] : []),
70
+ '',
71
+ '[User Message]',
72
+ content,
73
+ '[/User Message]',
74
+ ].join('\n');
75
+ }
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_SANDBOX_RUNTIME_IMAGES = exports.DESKTOP_DEPLOYMENT_PROFILES = exports.DEFAULT_SANDBOX_STATE_MOUNT_PATH = exports.DEFAULT_SANDBOX_WORKSPACE_MOUNT_PATH = exports.DEFAULT_SANDBOX_RUNTIME_IMAGE_ID = exports.DEFAULT_SANDBOX_PROVIDER_ID = exports.CHANNEL_PROTOCOL_INSTRUCTION = exports.MONITOR_PROTOCOL_INSTRUCTION = exports.SCHEDULER_PROTOCOL_INSTRUCTION = exports.LOCALCORE_ACP_AGENT_TYPE = exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = exports.DESKTOP_PROVIDER_THINKING_OPTIONS = exports.DESKTOP_PROVIDER_PRESET_OPTIONS = exports.DESKTOP_PLATFORM_TYPE_OPTIONS = exports.DESKTOP_AGENT_TYPE_OPTIONS = exports.DESKTOP_LARK_SDK_PACKAGE = exports.DESKTOP_CLAUDECODE_ACP_PACKAGE = exports.DESKTOP_CODEX_ACP_PACKAGE = exports.DESKTOP_PI_CODING_AGENT_PACKAGE = exports.DESKTOP_PI_ACP_PACKAGE = exports.DEFAULT_DESKTOP_CLAUDECODE_MODEL = exports.DEFAULT_DESKTOP_OPENCODE_MODEL = exports.DEFAULT_DESKTOP_AGENT_TYPE = void 0;
3
+ exports.DEFAULT_SANDBOX_RUNTIME_IMAGES = exports.DESKTOP_DEPLOYMENT_PROFILES = exports.DEFAULT_SANDBOX_STATE_MOUNT_PATH = exports.DEFAULT_SANDBOX_WORKSPACE_MOUNT_PATH = exports.DEFAULT_SANDBOX_RUNTIME_IMAGE_ID = exports.DEFAULT_SANDBOX_PROVIDER_ID = exports.LOCALCORE_ACP_AGENT_TYPE = exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = exports.DESKTOP_PROVIDER_THINKING_OPTIONS = exports.DESKTOP_PROVIDER_PRESET_OPTIONS = exports.DESKTOP_PLATFORM_TYPE_OPTIONS = exports.DESKTOP_AGENT_TYPE_OPTIONS = exports.DESKTOP_LARK_SDK_PACKAGE = exports.DESKTOP_CLAUDECODE_ACP_PACKAGE = exports.DESKTOP_CODEX_ACP_PACKAGE = exports.DESKTOP_PI_CODING_AGENT_PACKAGE = exports.DESKTOP_PI_ACP_PACKAGE = exports.DEFAULT_DESKTOP_CLAUDECODE_MODEL = exports.DEFAULT_DESKTOP_OPENCODE_MODEL = exports.DEFAULT_DESKTOP_AGENT_TYPE = void 0;
4
4
  exports.deriveDesktopRuntimePhase = deriveDesktopRuntimePhase;
5
5
  exports.deriveDesktopRuntimeRoles = deriveDesktopRuntimeRoles;
6
6
  exports.normalizeDesktopPlatformType = normalizeDesktopPlatformType;
7
- exports.wrapUserMessageWithSchedulerProtocol = wrapUserMessageWithSchedulerProtocol;
8
7
  exports.getDefaultDesktopAgentModel = getDefaultDesktopAgentModel;
9
8
  exports.normalizeDesktopAgentModel = normalizeDesktopAgentModel;
10
9
  exports.normalizePermissionResponse = normalizePermissionResponse;
@@ -62,54 +61,6 @@ exports.DESKTOP_PROVIDER_PRESET_OPTIONS = [
62
61
  exports.DESKTOP_PROVIDER_THINKING_OPTIONS = ['', 'enabled', 'disabled'];
63
62
  exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = ['pi', 'opencode', 'codex', 'claudecode', 'hermes', 'acp', 'localcore-acp'];
64
63
  exports.LOCALCORE_ACP_AGENT_TYPE = 'localcore-acp';
65
- exports.SCHEDULER_PROTOCOL_INSTRUCTION = [
66
- '[Scheduler Tools]',
67
- 'If the user asks to create, view, edit, delete, or manually run a scheduled task for this conversation, use the Bash tool to run the local scheduler CLI.',
68
- 'Use these commands:',
69
- 'lac scheduler add --cron "<5-field cron>" --message "<exact message to send>" --desc "<short label>" [--execution-mode same-thread|side-thread]',
70
- 'lac scheduler list',
71
- 'lac scheduler list --thread',
72
- 'lac scheduler info <short-job-id>',
73
- 'lac scheduler edit <short-job-id> [--cron "<5-field cron>"] [--message "<exact message>"] [--desc "<short label>"] [--enabled true|false] [--execution-mode same-thread|side-thread]',
74
- 'lac scheduler del <short-job-id>',
75
- 'lac scheduler run <short-job-id>',
76
- 'Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.',
77
- 'Prefer relying on those variables instead of inventing your own route or creating session-only cron jobs.',
78
- 'By default, `lac scheduler list` shows all scheduled tasks in the current workspace. Use `lac scheduler list --thread` to show only the current conversation thread.',
79
- 'Use the short job id shown by `lac scheduler list`; do not add a `job:` prefix or expand it to a full UUID.',
80
- 'Use `--execution-mode same-thread` to reuse the current thread, or `--execution-mode side-thread` to run in a dedicated scheduled thread.',
81
- 'Only use the scheduler CLI when the user explicitly asks for scheduled automation.',
82
- '[/Scheduler Tools]',
83
- ].join('\n');
84
- exports.MONITOR_PROTOCOL_INSTRUCTION = [
85
- '[Monitor Tools]',
86
- 'If the user asks to create, view, edit, delete, or manually run an event monitor for this conversation, use the Bash tool to run the local monitor CLI.',
87
- 'Use these commands:',
88
- 'lac monitor add --title "<short title>" --source stock.quote --symbol "<ticker>" --condition "<metric operator value>" --message "<exact analysis prompt>" [--cooldown 15m] [--execution-mode same-thread|side-thread]',
89
- 'lac monitor list',
90
- 'lac monitor list --thread',
91
- 'lac monitor info <short-monitor-id>',
92
- 'lac monitor edit <short-monitor-id> [--title "<title>"] [--condition "<expr>"] [--message "<exact prompt>"] [--enabled true|false] [--cooldown 15m] [--execution-mode same-thread|side-thread]',
93
- 'lac monitor del <short-monitor-id>',
94
- 'lac monitor run <short-monitor-id>',
95
- 'Supported stock metrics include latestPrice, change_percent, changePercent, and abs_change_percent. Example condition: "abs_change_percent >= 3".',
96
- 'Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.',
97
- 'Prefer relying on those variables instead of inventing your own route.',
98
- 'Use --execution-mode side-thread by default so monitor analysis does not interrupt the current conversation.',
99
- 'Only use the monitor CLI when the user explicitly asks for event monitoring automation.',
100
- '[/Monitor Tools]',
101
- ].join('\n');
102
- exports.CHANNEL_PROTOCOL_INSTRUCTION = [
103
- '[Channel Tools]',
104
- 'If the user asks you to send a local file back through the current channel conversation, use the Bash tool to run the local channel CLI.',
105
- 'Use this command:',
106
- 'lac channel send-file --path "<absolute-or-workdir-relative-file-path>" [--target "<channel-chat-or-user-id>"]',
107
- 'By default, the file is sent to the current platform conversation from LOCAL_AI_CHAT_ID.',
108
- 'Use --target only when the user explicitly names a different channel chat or user id.',
109
- 'The CLI accepts absolute paths. Check that the file exists before sending when practical.',
110
- 'Only use the channel CLI when the user explicitly asks to send a file through the channel.',
111
- '[/Channel Tools]',
112
- ].join('\n');
113
64
  const PERMISSION_RESPONSE_MAP = {
114
65
  allow: 'allow',
115
66
  deny: 'deny',
@@ -155,20 +106,6 @@ function normalizeDesktopPlatformType(platformType) {
155
106
  }
156
107
  return normalized;
157
108
  }
158
- function wrapUserMessageWithSchedulerProtocol(content, extraBlocks = []) {
159
- return [
160
- exports.SCHEDULER_PROTOCOL_INSTRUCTION,
161
- '',
162
- exports.MONITOR_PROTOCOL_INSTRUCTION,
163
- '',
164
- exports.CHANNEL_PROTOCOL_INSTRUCTION,
165
- ...extraBlocks.flatMap((block) => (block ? ['', block] : [])),
166
- '',
167
- '[User Message]',
168
- content,
169
- '[/User Message]',
170
- ].join('\n');
171
- }
172
109
  function getDefaultDesktopAgentModel(agentType) {
173
110
  switch (String(agentType || '').trim().toLowerCase()) {
174
111
  case 'opencode':
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initialChatControllerState = void 0;
4
+ exports.isChatControllerInputLocked = isChatControllerInputLocked;
5
+ exports.chatControllerActionForSessionOutcome = chatControllerActionForSessionOutcome;
6
+ exports.chatControllerReducer = chatControllerReducer;
7
+ exports.initialChatControllerState = { status: 'idle' };
8
+ function isChatControllerInputLocked(status) {
9
+ return status === 'activating' ||
10
+ status === 'sending' ||
11
+ status === 'waiting' ||
12
+ status === 'polling' ||
13
+ status === 'running' ||
14
+ status === 'stopping' ||
15
+ status === 'permission_submitted';
16
+ }
17
+ function chatControllerActionForSessionOutcome(outcome, failedError) {
18
+ switch (outcome) {
19
+ case 'running':
20
+ return { type: 'stream_started' };
21
+ case 'settled':
22
+ return { type: 'settled' };
23
+ case 'failed':
24
+ return { type: 'failed', error: failedError };
25
+ case 'awaiting_input':
26
+ return { type: 'input_requested' };
27
+ case 'awaiting_permission':
28
+ return { type: 'permission_requested' };
29
+ }
30
+ }
31
+ function chatControllerReducer(state, action) {
32
+ switch (action.type) {
33
+ case 'activate_started':
34
+ return { status: 'activating' };
35
+ case 'send_started':
36
+ return { status: 'sending' };
37
+ case 'send_accepted':
38
+ return state.status === 'sending' ? { status: 'waiting' } : state;
39
+ case 'stream_started':
40
+ return { status: 'running' };
41
+ case 'input_requested':
42
+ return { status: 'awaiting_input' };
43
+ case 'permission_requested':
44
+ return { status: 'awaiting_permission' };
45
+ case 'permission_submitted':
46
+ return { status: 'permission_submitted' };
47
+ case 'stop_started':
48
+ return { status: 'stopping' };
49
+ case 'failed':
50
+ return { status: 'failed', error: action.error };
51
+ case 'timed_out':
52
+ return { status: 'timed_out', error: action.error };
53
+ case 'settled':
54
+ return exports.initialChatControllerState;
55
+ case 'transition':
56
+ return { status: action.status, error: action.error };
57
+ default:
58
+ return state;
59
+ }
60
+ }
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldAcceptRunScopedEvent = shouldAcceptRunScopedEvent;
4
+ exports.createChatEventGate = createChatEventGate;
5
+ const lateStreamingEventTypes = new Set([
6
+ 'buttons',
7
+ 'reply',
8
+ 'preview_start',
9
+ 'status',
10
+ 'update_message',
11
+ 'typing_start',
12
+ ]);
13
+ // Stateless signals re-arm reply timeouts or re-promote task state on every
14
+ // emission, so a legitimately repeated one (e.g. a re-delivery after a brief
15
+ // transport blip, or two genuine identical status lines) must NOT be dropped by
16
+ // the echo dedup. Content-bearing events keep full fingerprint dedup.
17
+ const statelessSignalTypes = new Set(['typing_start', 'status']);
18
+ function isStatelessSignalType(type) {
19
+ return statelessSignalTypes.has(type);
20
+ }
21
+ function shouldAcceptRunScopedEvent(event, context) {
22
+ const replyCtx = String(event.replyCtx || '').trim();
23
+ if (!replyCtx) {
24
+ return true;
25
+ }
26
+ const activeRunId = String(context.activeRunId || '').trim();
27
+ const pendingTurn = context.pendingTurn;
28
+ if (pendingTurn && pendingTurn.sessionKey === event.sessionKey) {
29
+ const pendingRunId = String(pendingTurn.runId || '').trim();
30
+ if (pendingRunId) {
31
+ return replyCtx === pendingRunId;
32
+ }
33
+ const supersededRunId = String(pendingTurn.supersededRunId || '').trim();
34
+ if (supersededRunId && replyCtx === supersededRunId) {
35
+ return false;
36
+ }
37
+ }
38
+ return !activeRunId || replyCtx === activeRunId;
39
+ }
40
+ function bridgeEventFingerprint(event) {
41
+ return JSON.stringify([
42
+ event.type,
43
+ event.sessionKey || '',
44
+ event.replyCtx || '',
45
+ event.previewHandle || '',
46
+ event.messageId || '',
47
+ event.bridgeKind || '',
48
+ event.bridgeStatus || '',
49
+ event.content || '',
50
+ event.toolCall || null,
51
+ event.buttonRows || event.buttons || null,
52
+ ]);
53
+ }
54
+ function coreEventFingerprint(event) {
55
+ return JSON.stringify(event);
56
+ }
57
+ function streamFromCoreEvent(event) {
58
+ return 'stream' in event ? event.stream : undefined;
59
+ }
60
+ function createChatEventGate(maxRememberedEvents = 256) {
61
+ const fingerprints = new Set();
62
+ const fingerprintOrder = [];
63
+ const settledTurns = new Set();
64
+ const settledTurnOrder = [];
65
+ const remember = (fingerprint) => {
66
+ if (fingerprints.has(fingerprint)) {
67
+ return false;
68
+ }
69
+ fingerprints.add(fingerprint);
70
+ fingerprintOrder.push(fingerprint);
71
+ while (fingerprintOrder.length > maxRememberedEvents) {
72
+ const oldest = fingerprintOrder.shift();
73
+ if (oldest) {
74
+ fingerprints.delete(oldest);
75
+ }
76
+ }
77
+ return true;
78
+ };
79
+ const rememberSettledTurn = (turnKey) => {
80
+ if (settledTurns.has(turnKey)) {
81
+ return;
82
+ }
83
+ settledTurns.add(turnKey);
84
+ settledTurnOrder.push(turnKey);
85
+ while (settledTurnOrder.length > maxRememberedEvents) {
86
+ const oldest = settledTurnOrder.shift();
87
+ if (oldest) {
88
+ settledTurns.delete(oldest);
89
+ }
90
+ }
91
+ };
92
+ return {
93
+ acceptBridgeEvent(event, context = {}) {
94
+ if (!shouldAcceptRunScopedEvent(event, context)) {
95
+ return false;
96
+ }
97
+ const turnKey = event.replyCtx
98
+ ? `${event.sessionKey || ''}:${event.replyCtx}`
99
+ : '';
100
+ if (turnKey && settledTurns.has(turnKey) && lateStreamingEventTypes.has(event.type)) {
101
+ return false;
102
+ }
103
+ if (!isStatelessSignalType(event.type) && !remember(`bridge:${bridgeEventFingerprint(event)}`)) {
104
+ return false;
105
+ }
106
+ if (turnKey && (event.type === 'typing_stop' || event.type === 'card')) {
107
+ rememberSettledTurn(turnKey);
108
+ }
109
+ return true;
110
+ },
111
+ acceptCoreEvent(event) {
112
+ const runTurnKey = event.type === 'run.updated' ? `run:${event.run.id}` : '';
113
+ if (event.type === 'run.updated' &&
114
+ settledTurns.has(runTurnKey) &&
115
+ (event.run.status === 'queued' || event.run.status === 'running' || event.run.status === 'awaiting_input')) {
116
+ return false;
117
+ }
118
+ const stream = streamFromCoreEvent(event);
119
+ const turnKey = stream?.replyCtx
120
+ ? `${stream.sessionKey || ''}:${stream.replyCtx}`
121
+ : '';
122
+ if (turnKey && settledTurns.has(turnKey) && lateStreamingEventTypes.has(stream.type)) {
123
+ return false;
124
+ }
125
+ const isStatelessStream = stream ? isStatelessSignalType(stream.type) : false;
126
+ if (!isStatelessStream && !remember(`core:${coreEventFingerprint(event)}`)) {
127
+ return false;
128
+ }
129
+ if (turnKey && (stream?.type === 'typing_stop' || stream?.type === 'card')) {
130
+ rememberSettledTurn(turnKey);
131
+ }
132
+ if (runTurnKey &&
133
+ event.type === 'run.updated' &&
134
+ (event.run.status === 'completed' || event.run.status === 'failed' || event.run.status === 'interrupted')) {
135
+ rememberSettledTurn(runTurnKey);
136
+ }
137
+ return true;
138
+ },
139
+ reset() {
140
+ fingerprints.clear();
141
+ fingerprintOrder.length = 0;
142
+ settledTurns.clear();
143
+ settledTurnOrder.length = 0;
144
+ },
145
+ };
146
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasMarkdownCodeBlock = hasMarkdownCodeBlock;
4
+ const FENCED_CODE_BLOCK_RE = /(^|\n) {0,3}(?:`{3,}|~{3,})[^\n]*(?:\n|$)/;
5
+ const INDENTED_CODE_BLOCK_RE = /(^|\n)(?: {4}|\t)\S/;
6
+ function hasMarkdownCodeBlock(content) {
7
+ return FENCED_CODE_BLOCK_RE.test(content) || INDENTED_CODE_BLOCK_RE.test(content);
8
+ }
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultSandboxForm = exports.PROVIDER_PRESETS = exports.PLATFORM_TYPE_OPTIONS = exports.CUSTOM_SELECT_VALUE = void 0;
4
+ exports.desktopProjectWorkspaceId = desktopProjectWorkspaceId;
5
+ exports.clone = clone;
6
+ exports.ensureProjects = ensureProjects;
7
+ exports.createProjectDialogDraft = createProjectDialogDraft;
8
+ exports.normalizeProject = normalizeProject;
9
+ exports.providerToDraft = providerToDraft;
10
+ exports.getSelectValue = getSelectValue;
11
+ exports.getProviderPresetValue = getProviderPresetValue;
12
+ exports.applyProviderPreset = applyProviderPreset;
13
+ exports.createPlatformDraft = createPlatformDraft;
14
+ exports.getPlatformInstanceId = getPlatformInstanceId;
15
+ exports.normalizePlatformDraft = normalizePlatformDraft;
16
+ exports.platformSummary = platformSummary;
17
+ exports.workDirLabel = workDirLabel;
18
+ exports.noticeClass = noticeClass;
19
+ exports.toSandboxForm = toSandboxForm;
20
+ exports.fromSandboxForm = fromSandboxForm;
21
+ const superai_contracts_1 = require("../../../packages/contracts/src/index.js");
22
+ exports.CUSTOM_SELECT_VALUE = '__custom__';
23
+ exports.PLATFORM_TYPE_OPTIONS = ['weixin', 'lark'];
24
+ function desktopProjectWorkspaceId(project) {
25
+ return String(project.workspace_id || project.name || '').trim();
26
+ }
27
+ exports.PROVIDER_PRESETS = [
28
+ { id: 'openai', label: 'OpenAI', name: 'openai', base_url: 'https://api.openai.com/v1', model: 'gpt-4.1-mini' },
29
+ { id: 'openrouter', label: 'OpenRouter', name: 'openrouter', base_url: 'https://openrouter.ai/api/v1', model: 'openai/gpt-4.1-mini' },
30
+ { id: 'anthropic', label: 'Anthropic', name: 'anthropic', base_url: 'https://api.anthropic.com/v1', model: 'claude-3-5-haiku-latest' },
31
+ { id: 'deepseek', label: 'DeepSeek', name: 'deepseek', base_url: 'https://api.deepseek.com', model: 'deepseek-v4-flash' },
32
+ { id: 'minimax', label: 'Minimax', name: 'minimax', base_url: 'https://api.minimax.chat/v1', model: 'MiniMax-M2.5' },
33
+ { id: 'ollama', label: 'Ollama', name: 'ollama', base_url: 'http://127.0.0.1:11434/v1', model: 'qwen2.5-coder:7b' },
34
+ ];
35
+ exports.defaultSandboxForm = {
36
+ enabled: false,
37
+ provider_id: superai_contracts_1.DEFAULT_SANDBOX_PROVIDER_ID,
38
+ runtime_image_id: (0, superai_contracts_1.defaultSandboxRuntimeImage)('pi').id,
39
+ server_url: 'http://127.0.0.1:8080',
40
+ image: 'agentdock/pi-acp:local',
41
+ api_key_env: 'OPEN_SANDBOX_API_KEY',
42
+ acp_port: '8080',
43
+ state_scope: 'project',
44
+ timeout_seconds: '7200',
45
+ sandbox_lifecycle: 'per_thread',
46
+ idle_seconds: '900',
47
+ warm_pool_size: '0',
48
+ cpu: '1000m',
49
+ memory: '2Gi',
50
+ workspace_mount_path: '/workspace',
51
+ state_mount_path: '/agent-state',
52
+ };
53
+ function clone(value) {
54
+ return JSON.parse(JSON.stringify(value));
55
+ }
56
+ function ensureProjects(config) {
57
+ if (!Array.isArray(config.projects))
58
+ config.projects = [];
59
+ return config.projects;
60
+ }
61
+ function createProjectDialogDraft(projects) {
62
+ const projectNames = new Set(projects.map((project) => project.name).filter(Boolean));
63
+ let index = projects.length + 1;
64
+ while (projectNames.has(`project-${index}`)) {
65
+ index += 1;
66
+ }
67
+ return {
68
+ name: `project-${index}`,
69
+ agentType: superai_contracts_1.DEFAULT_DESKTOP_AGENT_TYPE,
70
+ workDir: '',
71
+ model: '',
72
+ };
73
+ }
74
+ function normalizeProject(project) {
75
+ return {
76
+ ...project,
77
+ agent: {
78
+ ...project.agent,
79
+ options: {
80
+ ...(project.agent?.options || {}),
81
+ model: (0, superai_contracts_1.normalizeDesktopAgentModel)(project.agent?.type, String(project.agent?.options?.model || '')),
82
+ },
83
+ },
84
+ platforms: project.platforms || [],
85
+ };
86
+ }
87
+ function providerToDraft(provider) {
88
+ return {
89
+ id: provider.id,
90
+ name: provider.name,
91
+ api_key: provider.api_key || '',
92
+ base_url: provider.base_url || '',
93
+ model: provider.model || '',
94
+ models: provider.models || [],
95
+ thinking: provider.thinking || '',
96
+ env: provider.env || {},
97
+ };
98
+ }
99
+ function getSelectValue(value, options) {
100
+ return options.includes(value) ? value : exports.CUSTOM_SELECT_VALUE;
101
+ }
102
+ function getProviderPresetValue(provider) {
103
+ return exports.PROVIDER_PRESETS.find((preset) => provider.name === preset.name ||
104
+ (preset.base_url && provider.base_url === preset.base_url) ||
105
+ (preset.model && provider.model === preset.model && provider.name === preset.name))?.id || exports.CUSTOM_SELECT_VALUE;
106
+ }
107
+ function applyProviderPreset(provider, presetId) {
108
+ const preset = exports.PROVIDER_PRESETS.find((item) => item.id === presetId);
109
+ if (!preset)
110
+ return provider;
111
+ return {
112
+ ...provider,
113
+ name: preset.name,
114
+ base_url: preset.base_url,
115
+ model: preset.model,
116
+ };
117
+ }
118
+ function createPlatformDraft(type = 'weixin') {
119
+ return {
120
+ type,
121
+ options: {
122
+ instance_id: `${type}-${crypto.randomUUID?.() || Date.now().toString(36)}`,
123
+ },
124
+ };
125
+ }
126
+ function getPlatformInstanceId(platform) {
127
+ return String(platform?.options?.instance_id || '').trim() || 'default';
128
+ }
129
+ function normalizePlatformDraft(platform) {
130
+ const type = platform.type === 'feishu' ? 'lark' : platform.type;
131
+ const options = platform.options && typeof platform.options === 'object' ? { ...platform.options } : {};
132
+ if (type === 'weixin') {
133
+ return {
134
+ type,
135
+ options: {
136
+ ...options,
137
+ instance_id: String(options.instance_id || '').trim(),
138
+ },
139
+ };
140
+ }
141
+ if (type === 'lark') {
142
+ return {
143
+ type,
144
+ options: {
145
+ ...options,
146
+ instance_id: String(options.instance_id || '').trim(),
147
+ app_id: String(options.app_id || '').trim(),
148
+ app_secret: String(options.app_secret || '').trim(),
149
+ downloads_dir: String(options.downloads_dir || '').trim(),
150
+ card_actions: options.card_actions === true,
151
+ },
152
+ };
153
+ }
154
+ return { type, options };
155
+ }
156
+ function platformSummary(platform) {
157
+ if (platform.type === 'weixin')
158
+ return 'WeChat QR login';
159
+ if (platform.type === 'lark') {
160
+ const appId = String(platform.options?.app_id || '').trim();
161
+ return appId ? `App ID ${appId}` : 'App ID and secret required';
162
+ }
163
+ return 'Custom platform';
164
+ }
165
+ function workDirLabel(project) {
166
+ const workDir = String(project.agent?.options?.work_dir || '').trim();
167
+ if (!workDir)
168
+ return 'No work directory';
169
+ const normalized = workDir.replace(/\/+$/, '');
170
+ return normalized.split('/').filter(Boolean).pop() || workDir;
171
+ }
172
+ function noticeClass(tone) {
173
+ if (tone === 'success')
174
+ return 'border-primary/20 bg-primary/10 text-primary dark:border-primary/25 dark:bg-primary/10 dark:text-blue-200';
175
+ if (tone === 'warning')
176
+ return 'border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-200';
177
+ return 'border-red-200 bg-red-50 text-red-700 dark:border-red-400/20 dark:bg-red-500/10 dark:text-red-200';
178
+ }
179
+ function toSandboxForm(input) {
180
+ return {
181
+ enabled: Boolean(input?.enabled),
182
+ provider_id: input?.provider_id || superai_contracts_1.DEFAULT_SANDBOX_PROVIDER_ID,
183
+ runtime_image_id: input?.runtime_image_id || exports.defaultSandboxForm.runtime_image_id,
184
+ server_url: input?.server_url || exports.defaultSandboxForm.server_url,
185
+ image: input?.image || exports.defaultSandboxForm.image,
186
+ api_key_env: input?.api_key_env || exports.defaultSandboxForm.api_key_env,
187
+ acp_port: String(input?.acp_port || exports.defaultSandboxForm.acp_port),
188
+ state_scope: input?.state_scope || exports.defaultSandboxForm.state_scope,
189
+ timeout_seconds: String(input?.timeout_seconds || exports.defaultSandboxForm.timeout_seconds),
190
+ sandbox_lifecycle: input?.sandbox_lifecycle || exports.defaultSandboxForm.sandbox_lifecycle,
191
+ idle_seconds: String(input?.idle_seconds || exports.defaultSandboxForm.idle_seconds),
192
+ warm_pool_size: String(input?.warm_pool_size ?? exports.defaultSandboxForm.warm_pool_size),
193
+ cpu: input?.cpu || exports.defaultSandboxForm.cpu,
194
+ memory: input?.memory || exports.defaultSandboxForm.memory,
195
+ workspace_mount_path: input?.workspace_mount_path || exports.defaultSandboxForm.workspace_mount_path,
196
+ state_mount_path: input?.state_mount_path || exports.defaultSandboxForm.state_mount_path,
197
+ };
198
+ }
199
+ function fromSandboxForm(input) {
200
+ return {
201
+ enabled: input.enabled,
202
+ provider_id: input.provider_id.trim() || superai_contracts_1.DEFAULT_SANDBOX_PROVIDER_ID,
203
+ runtime_image_id: input.runtime_image_id.trim() || exports.defaultSandboxForm.runtime_image_id,
204
+ state_scope: input.state_scope,
205
+ timeout_seconds: Number(input.timeout_seconds) || Number(exports.defaultSandboxForm.timeout_seconds),
206
+ sandbox_lifecycle: input.sandbox_lifecycle,
207
+ idle_seconds: Number(input.idle_seconds) || Number(exports.defaultSandboxForm.idle_seconds),
208
+ warm_pool_size: Math.max(0, Number(input.warm_pool_size) || 0),
209
+ cpu: input.cpu.trim() || exports.defaultSandboxForm.cpu,
210
+ memory: input.memory.trim() || exports.defaultSandboxForm.memory,
211
+ };
212
+ }