evolcore 0.0.1 → 0.0.3

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 (379) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +21 -0
  3. package/MIGRATION-0.5.0.md +378 -0
  4. package/README.md +318 -14
  5. package/ROLE_ACCESS_CONTROL.md +174 -0
  6. package/assets/.env.template +4 -0
  7. package/bin/ec-safe-output.js +161 -0
  8. package/bin/ec.js +29 -0
  9. package/dist/agents/baseagent.js +163 -0
  10. package/dist/agents/claude-runner.js +2565 -0
  11. package/dist/agents/codex-app-server-client.js +448 -0
  12. package/dist/agents/codex-runner.js +2682 -0
  13. package/dist/agents/gemini-runner.js +666 -0
  14. package/dist/agents/runner-types.js +75 -0
  15. package/dist/aun/aid/agentmd.js +216 -0
  16. package/dist/aun/aid/client.js +132 -0
  17. package/dist/aun/aid/control-aid.js +91 -0
  18. package/dist/aun/aid/identity.js +518 -0
  19. package/dist/aun/aid/index.js +4 -0
  20. package/dist/aun/aid/store.js +74 -0
  21. package/dist/aun/aid/types.js +1 -0
  22. package/dist/aun/aid/validation.js +21 -0
  23. package/dist/aun/group-identity.js +10 -0
  24. package/dist/aun/msg/group-index.js +6 -0
  25. package/dist/aun/msg/group.js +1231 -0
  26. package/dist/aun/msg/history.js +123 -0
  27. package/dist/aun/msg/index.js +5 -0
  28. package/dist/aun/msg/p2p.js +393 -0
  29. package/dist/aun/msg/payload-type.js +27 -0
  30. package/dist/aun/msg/upload.js +137 -0
  31. package/dist/aun/outbox.js +168 -0
  32. package/dist/aun/rpc/caller.js +42 -0
  33. package/dist/aun/rpc/connection.js +25 -0
  34. package/dist/aun/rpc/index.js +2 -0
  35. package/dist/aun/service-proxy.js +225 -0
  36. package/dist/aun/storage/download.js +29 -0
  37. package/dist/aun/storage/index.js +3 -0
  38. package/dist/aun/storage/manage.js +10 -0
  39. package/dist/aun/storage/upload.js +68 -0
  40. package/dist/channels/aun.js +4164 -0
  41. package/dist/channels/contact-bind-code.js +134 -0
  42. package/dist/channels/daemon.js +422 -0
  43. package/dist/channels/dingtalk.js +1479 -0
  44. package/dist/channels/feishu.js +1865 -0
  45. package/dist/channels/qqbot.js +409 -0
  46. package/dist/channels/wechat.js +817 -0
  47. package/dist/channels/wecom-card.js +101 -0
  48. package/dist/channels/wecom-onboarding.js +82 -0
  49. package/dist/channels/wecom-state.js +191 -0
  50. package/dist/channels/wecom.js +1157 -0
  51. package/dist/cli/agent-command.js +642 -0
  52. package/dist/cli/agent.js +1059 -0
  53. package/dist/cli/aun-commands.js +2003 -0
  54. package/dist/cli/bench.js +1228 -0
  55. package/dist/cli/cli-argv.js +66 -0
  56. package/dist/cli/code-stats.js +329 -0
  57. package/dist/cli/command-log.js +82 -0
  58. package/dist/cli/config-selector.js +69 -0
  59. package/dist/cli/config.js +261 -0
  60. package/dist/cli/contact.js +71 -0
  61. package/dist/cli/ctl-command.js +62 -0
  62. package/dist/cli/daemon-commands.js +2750 -0
  63. package/dist/cli/fs-command.js +1447 -0
  64. package/dist/cli/handoff-command.js +302 -0
  65. package/dist/cli/help.js +35 -0
  66. package/dist/cli/index.js +374 -0
  67. package/dist/cli/init-channel.js +1372 -0
  68. package/dist/cli/init.js +590 -0
  69. package/dist/cli/link-rules.js +240 -0
  70. package/dist/cli/model.js +591 -0
  71. package/dist/cli/net-check.js +723 -0
  72. package/dist/cli/queue-command.js +150 -0
  73. package/dist/cli/raw-key-input.js +25 -0
  74. package/dist/cli/response.js +344 -0
  75. package/dist/cli/restart-monitor.js +480 -0
  76. package/dist/cli/stats.js +609 -0
  77. package/dist/cli/task-context.js +80 -0
  78. package/dist/cli/trigger-command.js +545 -0
  79. package/dist/cli/version.js +93 -0
  80. package/dist/cli/watch-logs.js +33 -0
  81. package/dist/cli/watch-msg.js +673 -0
  82. package/dist/config/boot-log.js +266 -0
  83. package/dist/config/builtin-role-templates.js +42 -0
  84. package/dist/config/builtin-roles.js +91 -0
  85. package/dist/config/config-batch-get.js +11 -0
  86. package/dist/config/config-field-policy.js +261 -0
  87. package/dist/config/config-manager.js +1120 -0
  88. package/dist/config/config-operation-service.js +384 -0
  89. package/dist/config/contact-alias.js +68 -0
  90. package/dist/config/contact-book-store.js +454 -0
  91. package/dist/config/contact-book-v2-startup.js +35 -0
  92. package/dist/config/contact-book.js +224 -0
  93. package/dist/config/contact-operation-service.js +110 -0
  94. package/dist/config/gateway-config.js +858 -0
  95. package/dist/config/lifecycle.js +17 -0
  96. package/dist/config/mention-mode.js +27 -0
  97. package/dist/config/merge.js +161 -0
  98. package/dist/config/owner-policy.js +4 -0
  99. package/dist/config/peer-role-resolver.js +218 -0
  100. package/dist/config/resolved-config-op.js +483 -0
  101. package/dist/config/role-config-v4-startup.js +32 -0
  102. package/dist/config/role-config-v5-startup.js +27 -0
  103. package/dist/config/role-ranks.js +18 -0
  104. package/dist/config/role-schema.js +105 -0
  105. package/dist/config/role-service.js +156 -0
  106. package/dist/config/role-store.js +215 -0
  107. package/dist/config/roles.js +64 -0
  108. package/dist/config/schema-registry.js +154 -0
  109. package/dist/config/snapshot.js +598 -0
  110. package/dist/config-store.js +501 -0
  111. package/dist/core/auth/agent-delegation.js +111 -0
  112. package/dist/core/auth/auth-gateway.js +166 -0
  113. package/dist/core/auth/authenticated-actor.js +6 -0
  114. package/dist/core/auth/authorization-audit.js +119 -0
  115. package/dist/core/auth/operation-authorizer.js +720 -0
  116. package/dist/core/auth/operation-catalog.js +731 -0
  117. package/dist/core/baseagent-loader.js +54 -0
  118. package/dist/core/bootstrap-service.js +175 -0
  119. package/dist/core/capability/capability-manager.js +316 -0
  120. package/dist/core/capability/providers/claude-capability-provider.js +176 -0
  121. package/dist/core/capability/providers/codex-capability-provider.js +148 -0
  122. package/dist/core/capability/providers/gemini-capability-provider.js +10 -0
  123. package/dist/core/capability/types.js +27 -0
  124. package/dist/core/causation/audit.js +103 -0
  125. package/dist/core/causation/aun-association.js +111 -0
  126. package/dist/core/causation/context.js +93 -0
  127. package/dist/core/causation/index.js +4 -0
  128. package/dist/core/causation/types.js +2 -0
  129. package/dist/core/channel-loader.js +277 -0
  130. package/dist/core/command/agent-control.js +616 -0
  131. package/dist/core/command/cli-intent-parser.js +225 -0
  132. package/dist/core/command/command-handler.js +1733 -0
  133. package/dist/core/command/connect-menu.js +374 -0
  134. package/dist/core/command/menu-handler.js +3452 -0
  135. package/dist/core/command/menu-protocol.js +247 -0
  136. package/dist/core/command/role-menu.js +1623 -0
  137. package/dist/core/command/slash-gate.js +148 -0
  138. package/dist/core/command/slash-handler.js +3066 -0
  139. package/dist/core/daemon-file-cache.js +222 -0
  140. package/dist/core/event-bus.js +32 -0
  141. package/dist/core/event-catalog.js +810 -0
  142. package/dist/core/evolagent-registry.js +545 -0
  143. package/dist/core/evolagent.js +342 -0
  144. package/dist/core/handoff/dispatcher.js +229 -0
  145. package/dist/core/handoff/mutex.js +46 -0
  146. package/dist/core/handoff/runtime.js +324 -0
  147. package/dist/core/handoff/store.js +537 -0
  148. package/dist/core/handoff/types.js +12 -0
  149. package/dist/core/inference/text-inference.js +173 -0
  150. package/dist/core/interaction-registration.js +10 -0
  151. package/dist/core/interaction-router.js +278 -0
  152. package/dist/core/message/create-status.js +67 -0
  153. package/dist/core/message/im-renderer.js +659 -0
  154. package/dist/core/message/items-formatter.js +76 -0
  155. package/dist/core/message/logical-queue-bridge.js +123 -0
  156. package/dist/core/message/message-bridge.js +874 -0
  157. package/dist/core/message/message-cache.js +56 -0
  158. package/dist/core/message/message-log.js +339 -0
  159. package/dist/core/message/message-processor.js +4 -0
  160. package/dist/core/message/message-queue.js +1446 -0
  161. package/dist/core/message/message-utils.js +76 -0
  162. package/dist/core/message/peer-mode.js +105 -0
  163. package/dist/core/message/pending-hints.js +232 -0
  164. package/dist/core/message/response-depth.js +33 -0
  165. package/dist/core/message/response-engine.js +4020 -0
  166. package/dist/core/message/response-snapshot.js +83 -0
  167. package/dist/core/message/send-receipt.js +24 -0
  168. package/dist/core/message/stream-debouncer.js +139 -0
  169. package/dist/core/message/stream-idle-monitor.js +124 -0
  170. package/dist/core/model/config-scope.js +162 -0
  171. package/dist/core/model/field-scope.js +78 -0
  172. package/dist/core/model/model-catalog.js +227 -0
  173. package/dist/core/model/model-diagnostics.js +182 -0
  174. package/dist/core/model/model-permission.js +90 -0
  175. package/dist/core/permission/approval-gateway.js +1017 -0
  176. package/dist/core/permission/ec-command-parser.js +347 -0
  177. package/dist/core/permission/execution-sandbox.js +16 -0
  178. package/dist/core/permission/index.js +6 -0
  179. package/dist/core/permission/mode.js +24 -0
  180. package/dist/core/permission/sandbox-runtime.js +265 -0
  181. package/dist/core/permission/tool-policy.js +1019 -0
  182. package/dist/core/permission/unix-socket-policy.js +99 -0
  183. package/dist/core/protected-paths.js +332 -0
  184. package/dist/core/relation/peer-identity.js +222 -0
  185. package/dist/core/relation/peer-key.js +1 -0
  186. package/dist/core/role/runtime-policy.js +141 -0
  187. package/dist/core/session/adapters/claude-session-file-adapter.js +218 -0
  188. package/dist/core/session/adapters/codex-session-file-adapter.js +333 -0
  189. package/dist/core/session/adapters/gemini-session-file-adapter.js +181 -0
  190. package/dist/core/session/session-file-adapter.js +7 -0
  191. package/dist/core/session/session-file-health.js +45 -0
  192. package/dist/core/session/session-fs-store.js +273 -0
  193. package/dist/core/session/session-key.js +24 -0
  194. package/dist/core/session/session-manager.js +1643 -0
  195. package/dist/core/session/session-mapper.js +100 -0
  196. package/dist/core/session/session-renew.js +314 -0
  197. package/dist/core/session/session-title.js +128 -0
  198. package/dist/core/session/session-turn-coordinator.js +205 -0
  199. package/dist/core/session/session-turns.js +67 -0
  200. package/dist/core/system-channels.js +29 -0
  201. package/dist/eck/baseagent-caps.js +18 -0
  202. package/dist/eck/detect.js +47 -0
  203. package/dist/eck/group-rules-sync.js +345 -0
  204. package/dist/eck/init.js +77 -0
  205. package/dist/eck/kit-renderer.js +359 -0
  206. package/dist/eck/manifest-engine.js +446 -0
  207. package/dist/eck/message-renderer.js +199 -0
  208. package/dist/eck/rules-loader.js +28 -0
  209. package/dist/index.js +2926 -4
  210. package/dist/ipc.js +777 -0
  211. package/dist/paths.js +262 -0
  212. package/dist/product.js +18 -0
  213. package/dist/response-system/context-builder.js +71 -0
  214. package/dist/response-system/coordinator.js +117 -0
  215. package/dist/response-system/decision-executor.js +86 -0
  216. package/dist/response-system/engines/v1/index.js +21 -0
  217. package/dist/response-system/engines/v1/interactive-flow.js +27 -0
  218. package/dist/response-system/engines/v1/proactive-flow.js +137 -0
  219. package/dist/response-system/engines/v1/types.js +1 -0
  220. package/dist/response-system/extensions.js +41 -0
  221. package/dist/response-system/index.js +6 -0
  222. package/dist/response-system/modes/index.js +7 -0
  223. package/dist/response-system/modes/single-session/index.js +72 -0
  224. package/dist/response-system/queues/fifo-queue.js +44 -0
  225. package/dist/response-system/queues/index.js +6 -0
  226. package/dist/response-system/queues/lifo-queue.js +42 -0
  227. package/dist/response-system/queues/priority-queue.js +63 -0
  228. package/dist/response-system/registry.js +97 -0
  229. package/dist/response-system/resolver.js +37 -0
  230. package/dist/response-system/selector.js +23 -0
  231. package/dist/response-system/types.js +7 -0
  232. package/dist/stats/billing.js +163 -0
  233. package/dist/stats/budget.js +93 -0
  234. package/dist/stats/db.js +403 -0
  235. package/dist/stats/eck-vars.js +89 -0
  236. package/dist/stats/index.js +11 -0
  237. package/dist/stats/normalizer.js +80 -0
  238. package/dist/stats/price-resolver.js +138 -0
  239. package/dist/stats/query.js +763 -0
  240. package/dist/stats/role-budget.js +168 -0
  241. package/dist/stats/writer.js +151 -0
  242. package/dist/trigger/anomaly-store.js +258 -0
  243. package/dist/trigger/audit.js +152 -0
  244. package/dist/trigger/event-source.js +119 -0
  245. package/dist/trigger/feedback.js +685 -0
  246. package/dist/trigger/history.js +290 -0
  247. package/dist/trigger/manager.js +294 -0
  248. package/dist/trigger/parser.js +595 -0
  249. package/dist/trigger/patch.js +155 -0
  250. package/dist/trigger/scheduler.js +1602 -0
  251. package/dist/trigger/script-executor.js +155 -0
  252. package/dist/trigger/state.js +145 -0
  253. package/dist/trigger/types.js +1 -0
  254. package/dist/trigger/validation.js +634 -0
  255. package/dist/types.js +12 -0
  256. package/dist/utils/aid-bind.js +313 -0
  257. package/dist/utils/atomic-write.js +95 -0
  258. package/dist/utils/avatar-upload.js +123 -0
  259. package/dist/utils/cross-platform.js +297 -0
  260. package/dist/utils/ecweb-utils.js +73 -0
  261. package/dist/utils/error-dict.json +153 -0
  262. package/dist/utils/error-utils.js +349 -0
  263. package/dist/utils/instance-registry.js +444 -0
  264. package/dist/utils/locale.js +21 -0
  265. package/dist/utils/log-writer.js +270 -0
  266. package/dist/utils/logger.js +89 -0
  267. package/dist/utils/markdown-to-plain-text.js +20 -0
  268. package/dist/utils/media-cache.js +274 -0
  269. package/dist/utils/model-prices.jsonl +20 -0
  270. package/dist/utils/npm-ops.js +210 -0
  271. package/dist/utils/process-introspect.js +133 -0
  272. package/dist/utils/process-tree-stats.js +271 -0
  273. package/dist/utils/project-path.js +74 -0
  274. package/dist/utils/restart-safety.js +31 -0
  275. package/dist/utils/stats.js +410 -0
  276. package/dist/utils/system-memory.js +62 -0
  277. package/dist/utils/tool-summary.js +284 -0
  278. package/dist/utils/welcome.js +268 -0
  279. package/kits/docs/GUIDE.md +20 -0
  280. package/kits/docs/INDEX.md +66 -0
  281. package/kits/docs/aun/CHEATSHEET.md +19 -0
  282. package/kits/docs/aun/SYNC_PROTOCOL.md +15 -0
  283. package/kits/docs/channels/aun.md +65 -0
  284. package/kits/docs/channels/feishu.md +56 -0
  285. package/kits/docs/context-assembly.md +366 -0
  286. package/kits/docs/eck_templates/GUIDE.template.md +22 -0
  287. package/kits/docs/eck_templates/INDEX.template.md +28 -0
  288. package/kits/docs/eck_templates/path-registry.template.md +33 -0
  289. package/kits/docs/eck_templates/runtime.template.md +19 -0
  290. package/kits/docs/evolcore/INDEX.md +68 -0
  291. package/kits/docs/evolcore/agent.md +77 -0
  292. package/kits/docs/evolcore/aid.md +52 -0
  293. package/kits/docs/evolcore/config.md +149 -0
  294. package/kits/docs/evolcore/contact.md +57 -0
  295. package/kits/docs/evolcore/ctl.md +46 -0
  296. package/kits/docs/evolcore/event.md +216 -0
  297. package/kits/docs/evolcore/fs-architecture.md +1215 -0
  298. package/kits/docs/evolcore/fs.md +110 -0
  299. package/kits/docs/evolcore/group-fs.md +17 -0
  300. package/kits/docs/evolcore/group-rules.md +226 -0
  301. package/kits/docs/evolcore/group.md +150 -0
  302. package/kits/docs/evolcore/model.md +50 -0
  303. package/kits/docs/evolcore/msg.md +136 -0
  304. package/kits/docs/evolcore/response.md +75 -0
  305. package/kits/docs/evolcore/rpc.md +37 -0
  306. package/kits/docs/evolcore/self-summary.md +29 -0
  307. package/kits/docs/evolcore/stats.md +83 -0
  308. package/kits/docs/evolcore/storage.md +50 -0
  309. package/kits/docs/evolcore/trigger.md +539 -0
  310. package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -0
  311. package/kits/docs/identity/PATH_OPS.md +16 -0
  312. package/kits/docs/identity/ROLE_DETAIL.md +23 -0
  313. package/kits/docs/identity/identity-tools.md +26 -0
  314. package/kits/docs/path-registry.md +43 -0
  315. package/kits/docs/prompt-loading-architecture.md +266 -0
  316. package/kits/docs/venues/aun-group.md +45 -0
  317. package/kits/docs/venues/aun-private.md +10 -0
  318. package/kits/docs/venues/client-desktop.md +10 -0
  319. package/kits/docs/venues/client-mobile.md +10 -0
  320. package/kits/docs/venues/feishu-group.md +13 -0
  321. package/kits/docs/venues/feishu-private.md +9 -0
  322. package/kits/docs/venues/group.md +25 -0
  323. package/kits/docs/venues/private.md +10 -0
  324. package/kits/eck_manifest.auxiliary.json +43 -0
  325. package/kits/eck_manifest.json +203 -0
  326. package/kits/eck_message_manifest.json +63 -0
  327. package/kits/migrations/README-role-config-v4.md +32 -0
  328. package/kits/migrations/migrate-contact-book-v2.mjs +747 -0
  329. package/kits/migrations/migrate-role-config-v4.mjs +623 -0
  330. package/kits/migrations/migrate-role-config-v5.mjs +346 -0
  331. package/kits/migrations/rename-config-file.mjs +99 -0
  332. package/kits/rules/01-overview.md +142 -0
  333. package/kits/rules/02-navigation.md +76 -0
  334. package/kits/rules/03-identity.md +34 -0
  335. package/kits/rules/04-relation.md +59 -0
  336. package/kits/rules/05-venue.md +44 -0
  337. package/kits/rules/06-channel.md +59 -0
  338. package/kits/schemas/_meta.json +32 -0
  339. package/kits/schemas/agent-config.schema.1.json +177 -0
  340. package/kits/schemas/agent-config.schema.2.json +239 -0
  341. package/kits/schemas/agent-config.schema.3.json +119 -0
  342. package/kits/schemas/agent-config.schema.4.json +208 -0
  343. package/kits/schemas/agent-config.schema.5.json +326 -0
  344. package/kits/schemas/agent-config.schema.6.json +322 -0
  345. package/kits/schemas/contact-book.schema.1.json +36 -0
  346. package/kits/schemas/contact-book.schema.2.json +43 -0
  347. package/kits/schemas/daemon.schema.1.json +90 -0
  348. package/kits/schemas/defaults.schema.1.json +81 -0
  349. package/kits/schemas/menu-exec-schema-commands.md +208 -0
  350. package/kits/schemas/migrations/README.md +28 -0
  351. package/kits/schemas/relation-config.schema.1.json +158 -0
  352. package/kits/schemas/relation-config.schema.2.json +73 -0
  353. package/kits/schemas/relation-config.schema.3.json +50 -0
  354. package/kits/schemas/relation-config.schema.4.json +47 -0
  355. package/kits/schemas/relation-config.schema.5.json +47 -0
  356. package/kits/schemas/role-config.schema.1.json +201 -0
  357. package/kits/schemas/role-registry.schema.1.json +35 -0
  358. package/kits/schemas/single-session.schema.1.json +31 -0
  359. package/kits/templates/bootstrap-welcome.md +15 -0
  360. package/kits/templates/message-fragments/handoff-request-to-target.md +13 -0
  361. package/kits/templates/message-fragments/handoff-response-to-origin.md +10 -0
  362. package/kits/templates/message-fragments/inject-default.md +2 -0
  363. package/kits/templates/message-fragments/item.md +2 -0
  364. package/kits/templates/roles/admin.json +9 -0
  365. package/kits/templates/roles/member.json +41 -0
  366. package/kits/templates/roles/owner.json +9 -0
  367. package/kits/templates/roles/visitor.json +40 -0
  368. package/kits/templates/system-fragments/baseagent.md +14 -0
  369. package/kits/templates/system-fragments/bootstrap.md +16 -0
  370. package/kits/templates/system-fragments/channel.md +48 -0
  371. package/kits/templates/system-fragments/commands.md +28 -0
  372. package/kits/templates/system-fragments/identity.md +11 -0
  373. package/kits/templates/system-fragments/relation.md +19 -0
  374. package/kits/templates/system-fragments/session.md +53 -0
  375. package/kits/templates/system-fragments/venue.md +31 -0
  376. package/package.json +50 -15
  377. package/dist/index.d.ts +0 -7
  378. package/dist/index.d.ts.map +0 -1
  379. package/dist/index.js.map +0 -1
@@ -0,0 +1,591 @@
1
+ /**
2
+ * `ec model` —— 面向 agent 的模型管理命令集。
3
+ *
4
+ * 可写作用域由参数决定:
5
+ * --self → agent config.json
6
+ * --self --peer → 关系 relations/<peerKey>/config.json
7
+ * 角色模型策略由角色策略编辑器管理;--role 仅用于过滤和预览有效模型。
8
+ *
9
+ * 改某作用域后,对应范围所有会话的下一条消息即时生效(运行时按 关系>角色>agent>defaults 解析)。
10
+ * 与对话内 slash(/model /effort /baseagent)互不影响。
11
+ * 设计见 docs/model-command-design.md。
12
+ */
13
+ import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
14
+ import { ModelScopeError, normalizePeer, determineScope, activeBaseagent, writeScope, clearScope, } from '../core/model/config-scope.js';
15
+ import { resolveEffectiveFieldWithSource } from '../config/config-manager.js';
16
+ import { getCatalog, getModelInfo } from '../core/model/model-catalog.js';
17
+ import { constrainResolvedModelForRole, filterModelsForRole, validateModelSelectionForRole, } from '../core/model/model-permission.js';
18
+ import { resolvePaths } from '../paths.js';
19
+ import { ipcQuery } from '../ipc.js';
20
+ import { parsePeerKey } from '../core/relation/peer-identity.js';
21
+ import { resolvePeerRoleDetail } from '../config/peer-role-resolver.js';
22
+ import { getFieldPermission } from '../config/roles.js';
23
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
24
+ import { formatModelCheck, runModelCheck } from '../core/model/model-diagnostics.js';
25
+ import { validateRuntimeStringFieldOverride } from '../core/role/runtime-policy.js';
26
+ const ALL_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max', 'auto'];
27
+ const SCOPE_LABEL = {
28
+ global: '全局', agent: 'agent级', role: '角色级', relation: '关系级',
29
+ };
30
+ /** 输出 JSON 并退出(success=false 时 exit 1)。 */
31
+ function emit(formatJson, payload, textFn) {
32
+ if (formatJson) {
33
+ console.log(JSON.stringify(payload, null, 2));
34
+ }
35
+ else {
36
+ console.log(textFn());
37
+ }
38
+ }
39
+ function fail(formatJson, code, message, data) {
40
+ if (formatJson) {
41
+ console.log(JSON.stringify({ ok: false, code, error: message, ...(data !== undefined ? { data } : {}) }, null, 2));
42
+ }
43
+ else {
44
+ console.error(`❌ ${message} (${code})`);
45
+ }
46
+ process.exit(1);
47
+ }
48
+ function isManagedSessionEnv(args) {
49
+ return !!process.env.EVOLCORE_SESSION_ID
50
+ && !getArgValue(args, '--self')
51
+ && !getArgValue(args, '--peer')
52
+ && !getArgValue(args, '--role');
53
+ }
54
+ function isManagedTargetedWriteEnv(args) {
55
+ return !!process.env.EVOLCORE_SESSION_ID
56
+ && !isManagedSessionEnv(args);
57
+ }
58
+ async function runCtlCommand(cmd, formatJson, timeoutMs = 10_000) {
59
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
60
+ if (!sessionId)
61
+ fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID 未设置');
62
+ const result = await ipcQuery(resolvePaths().socket, {
63
+ type: 'ctl',
64
+ cmd,
65
+ sessionId,
66
+ delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
67
+ }, timeoutMs);
68
+ if (!result)
69
+ fail(formatJson, 'DAEMON_UNAVAILABLE', '无法连接 evolcore 服务');
70
+ if (!result.ok)
71
+ fail(formatJson, 'CTL_FAILED', result.error || 'ctl 执行失败');
72
+ return { text: String(result.result || ''), data: result.data };
73
+ }
74
+ function printCtlResult(result, formatJson) {
75
+ if (formatJson) {
76
+ console.log(JSON.stringify(result.data ?? { ok: true, result: result.text }, null, 2));
77
+ return;
78
+ }
79
+ console.log(result.text);
80
+ }
81
+ async function runManagedConfigOperation(args, formatJson) {
82
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
83
+ if (!sessionId)
84
+ fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID 未设置');
85
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
86
+ if (!delegationToken) {
87
+ fail(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} 未设置`);
88
+ }
89
+ let response;
90
+ try {
91
+ response = await ipcQuery(resolvePaths().socket, {
92
+ type: 'config.op',
93
+ argv: ['config', ...args],
94
+ sessionId,
95
+ delegationToken,
96
+ }, 10_000);
97
+ }
98
+ catch {
99
+ response = null;
100
+ }
101
+ if (!response)
102
+ fail(formatJson, 'DAEMON_UNAVAILABLE', '无法连接 evolcore 服务');
103
+ if (!response.ok || !response.result?.ok) {
104
+ fail(formatJson, response.code || 'CONFIG_AUTH_FAILED', response.error || 'config 操作失败', response.data);
105
+ }
106
+ }
107
+ function configSelectorArgs(sel) {
108
+ const args = ['--self', sel.self];
109
+ if (sel.peerKey)
110
+ args.push('--peer', sel.peerKey);
111
+ return args;
112
+ }
113
+ async function setManagedModelField(sel, field, value, formatJson) {
114
+ const subcommand = value === null ? ['unset', field] : ['set', field, value];
115
+ await runManagedConfigOperation([...subcommand, ...configSelectorArgs(sel)], formatJson);
116
+ }
117
+ function preflightManagedFieldOverride(sel, role, field, value, formatJson) {
118
+ if (!role)
119
+ return;
120
+ const policy = getFieldPermission(role, field, sel.self);
121
+ if (policy?.allowOverride === false) {
122
+ fail(formatJson, 'ROLE_OVERRIDE_DISABLED', `Role ${role} cannot override ${field}`);
123
+ }
124
+ if (value === null)
125
+ return;
126
+ const decision = validateRuntimeStringFieldOverride({ selfAid: sel.self, role, field, value });
127
+ if (!decision.ok) {
128
+ fail(formatJson, decision.code || 'ROLE_VALUE_NOT_ALLOWED', decision.message || `Value ${value} is not allowed for ${field}`);
129
+ }
130
+ }
131
+ /**
132
+ * 解析 --self / --peer 为作用域选择器。
133
+ */
134
+ function parseSelector(args, formatJson) {
135
+ const self = getArgValue(args, '--self');
136
+ const peerRaw = getArgValue(args, '--peer');
137
+ const role = getArgValue(args, '--role');
138
+ let peerKey;
139
+ if (peerRaw !== undefined) {
140
+ try {
141
+ peerKey = normalizePeer(peerRaw);
142
+ }
143
+ catch (e) {
144
+ if (e instanceof ModelScopeError)
145
+ fail(formatJson, e.code, e.message);
146
+ throw e;
147
+ }
148
+ }
149
+ const sel = { self, peerKey, role };
150
+ // 触发依赖校验(PEER_WITHOUT_SELF)
151
+ try {
152
+ determineScope(sel);
153
+ }
154
+ catch (e) {
155
+ if (e instanceof ModelScopeError)
156
+ fail(formatJson, e.code, e.message);
157
+ throw e;
158
+ }
159
+ return sel;
160
+ }
161
+ function explicitOrDerivedRole(args, sel) {
162
+ if (sel.role)
163
+ return sel.role;
164
+ if (!sel.self || !sel.peerKey)
165
+ return undefined;
166
+ try {
167
+ const peer = parsePeerKey(sel.peerKey);
168
+ const detail = resolvePeerRoleDetail({
169
+ selfAid: sel.self,
170
+ channelKey: sel.peerKey,
171
+ channelType: peer.channelType,
172
+ chatType: 'private',
173
+ actorId: peer.channelId,
174
+ conversationId: peer.channelId,
175
+ });
176
+ return detail.effectiveRole ?? undefined;
177
+ }
178
+ catch {
179
+ return undefined;
180
+ }
181
+ }
182
+ function determineWriteScope(sel, formatJson) {
183
+ const scope = determineScope(sel);
184
+ if (scope === 'global') {
185
+ fail(formatJson, 'NO_GLOBAL_SCOPE', '全局 model 作用域已退役;请用 --self 选择 agent');
186
+ }
187
+ if (scope === 'role') {
188
+ fail(formatJson, 'ROLE_POLICY_MANAGED', '角色策略只能通过角色策略编辑器修改');
189
+ }
190
+ return scope;
191
+ }
192
+ function selectorWithRole(sel, role) {
193
+ return role ? { ...sel, role } : sel;
194
+ }
195
+ function modelScopeFromSource(source) {
196
+ const layer = typeof source === 'string'
197
+ ? source
198
+ : source && typeof source === 'object' && 'target' in source
199
+ ? String(source.target ?? '')
200
+ : undefined;
201
+ if (layer === 'defaults' || layer === 'global')
202
+ return 'global';
203
+ if (layer === 'relation' || layer === 'role' || layer === 'agent')
204
+ return layer;
205
+ return undefined;
206
+ }
207
+ function resolveModelConfig(sel, baseagent) {
208
+ const effortKey = baseagent === 'codex' ? 'reasoning' : 'effort';
209
+ const model = resolveEffectiveFieldWithSource(`baseagents.${baseagent}.model`, sel, { cache: true });
210
+ const effort = resolveEffectiveFieldWithSource(`baseagents.${baseagent}.${effortKey}`, sel, { cache: true });
211
+ const modelDecision = sel.role
212
+ ? constrainResolvedModelForRole({
213
+ role: sel.role,
214
+ baseagent,
215
+ model: model.value,
216
+ selfAid: sel.self,
217
+ })
218
+ : { model: model.value, constrained: false };
219
+ const effectiveModel = modelDecision.model;
220
+ const modelSource = modelDecision.constrained ? 'role' : modelScopeFromSource(model.source);
221
+ const source = effectiveModel !== undefined ? modelSource : modelScopeFromSource(effort.source);
222
+ const scopes = ['relation', 'role', 'agent', 'global'];
223
+ return {
224
+ model: effectiveModel,
225
+ effort: effort.value,
226
+ source,
227
+ chain: scopes.map(scope => ({
228
+ scope,
229
+ hit: scope === source,
230
+ ...(scope === source && effectiveModel ? { model: effectiveModel } : {}),
231
+ })),
232
+ };
233
+ }
234
+ const HELP = `用法: ec model <command> [options]
235
+
236
+ Commands:
237
+ list 列出可用模型,标注各作用域命中
238
+ current 显示按优先级解析后实际生效的模型 + 来源
239
+ info <model-id> 查看单个模型详情(厂商/上下文/价格/模态/effort/状态)
240
+ use <model-id> 设置模型(作用域由 --self/--peer 决定)
241
+ reset 清除指定作用域的设置,回落上一级
242
+ effort <level> 设置推理强度(low|medium|high|xhigh|max|auto)
243
+ check 诊断网关连通性与模型可用性(分阶段输出进度)
244
+
245
+ 作用域(越具体越优先:关系 > 角色 > agent > defaults):
246
+ (无参数) 本机 CLI 只读 catalog/defaults,不允许写入
247
+ --self <aid> agent级 → config.json
248
+ --self <aid> --role <role> 角色策略预览(只读)
249
+ --self <aid> --peer <X> 关系级 → relations/<peerKey>/config.json
250
+
251
+ 修改 agent/关系作用域后,对应范围所有会话的下一条消息即时生效。
252
+ 角色策略请通过角色策略编辑器修改。
253
+ 托管会话内省略 --self/--peer/--role 时,命令作用于当前会话。
254
+
255
+ Options:
256
+ --self <aid> 本端 AID
257
+ --peer <X> 对端:channelType#channelId 或裸 aid(裸 aid 视为 aun#<aid>)
258
+ --role <role> 按角色过滤列表或预览有效模型(只读)
259
+ --effort <level> (use 专用)同时设置推理强度
260
+ --format json 输出 JSON
261
+ --help, -h 各子命令均支持
262
+
263
+ 示例:
264
+ ec model list
265
+ ec model current --self bot.agentid.pub --peer aun#alice.agentid.pub
266
+ ec model info deepseek-v4-pro
267
+ ec model use opus --self bot.agentid.pub
268
+ ec model use deepseek-v4-pro --self bot.agentid.pub --peer alice.agentid.pub
269
+ ec model effort high --self bot.agentid.pub
270
+ ec model reset --self bot.agentid.pub --peer alice.agentid.pub
271
+ ec model check --self bot.agentid.pub`;
272
+ async function dispatch(sub, args, formatJson) {
273
+ switch (sub) {
274
+ case 'list': return await cmdList(args, formatJson);
275
+ case 'current': return await cmdCurrent(args, formatJson);
276
+ case 'info': return await cmdInfo(args, formatJson);
277
+ case 'use': return await cmdUse(args, formatJson);
278
+ case 'reset': return await cmdReset(args, formatJson);
279
+ case 'effort': return await cmdEffort(args, formatJson);
280
+ case 'check': return await cmdCheck(args, formatJson);
281
+ default:
282
+ fail(formatJson, 'UNKNOWN_SUBCOMMAND', `未知子命令: ${sub}(model --help 查看用法)`);
283
+ }
284
+ }
285
+ // ── list ──────────────────────────────────────────────────────────────
286
+ async function cmdList(args, formatJson) {
287
+ if (wantsHelp(args)) {
288
+ console.log(HELP);
289
+ return;
290
+ }
291
+ if (isManagedSessionEnv(args)) {
292
+ const out = await runCtlCommand('/model list', formatJson);
293
+ printCtlResult(out, formatJson);
294
+ return;
295
+ }
296
+ const sel = parseSelector(args, formatJson);
297
+ const role = explicitOrDerivedRole(args, sel);
298
+ const effectiveSel = selectorWithRole(sel, role);
299
+ const ba = activeBaseagent(sel.self);
300
+ const cat = await getCatalog(sel.self, ba);
301
+ const resolved = resolveModelConfig(effectiveSel, ba);
302
+ const allowedModelIds = role
303
+ ? filterModelsForRole(role, ba, cat.models.map(m => m.id), undefined, sel.self)
304
+ : null;
305
+ const models = allowedModelIds
306
+ ? allowedModelIds.map(id => cat.models.find(m => m.id === id) ?? { id })
307
+ : cat.models;
308
+ emit(formatJson, {
309
+ ok: true,
310
+ effective: { model: resolved.model ?? null, source: resolved.source ?? null },
311
+ role: role ?? null,
312
+ catalogSource: cat.source,
313
+ models,
314
+ }, () => {
315
+ const lines = [];
316
+ lines.push(`当前生效: ${resolved.model ?? '(未设置,回落 SDK 默认)'}` +
317
+ (resolved.source ? ` (来源: ${SCOPE_LABEL[resolved.source]})` : ''));
318
+ lines.push('');
319
+ const srcTag = cat.source === 'mock' ? ' [mock]'
320
+ : cat.source === 'remote' ? ' [remote]'
321
+ : '';
322
+ lines.push(`可用模型 (${models.length})${srcTag}:`);
323
+ for (const e of models) {
324
+ const live = resolved.model === e.id ? '✓' : ' ';
325
+ lines.push(` ${live} ${e.id}`);
326
+ }
327
+ return lines.join('\n');
328
+ });
329
+ }
330
+ // ── current ───────────────────────────────────────────────────────────
331
+ async function cmdCurrent(args, formatJson) {
332
+ if (wantsHelp(args)) {
333
+ console.log(HELP);
334
+ return;
335
+ }
336
+ if (isManagedSessionEnv(args)) {
337
+ const out = await runCtlCommand('/model current', formatJson);
338
+ printCtlResult(out, formatJson);
339
+ return;
340
+ }
341
+ const sel = parseSelector(args, formatJson);
342
+ const ba = activeBaseagent(sel.self);
343
+ const role = explicitOrDerivedRole(args, sel);
344
+ const resolved = resolveModelConfig(selectorWithRole(sel, role), ba);
345
+ emit(formatJson, {
346
+ ok: true,
347
+ model: resolved.model ?? null,
348
+ effort: resolved.effort ?? null,
349
+ source: resolved.source ?? null,
350
+ role: role ?? null,
351
+ chain: resolved.chain.map((c) => ({ scope: c.scope, model: c.model ?? null, hit: c.hit })),
352
+ }, () => {
353
+ const lines = [];
354
+ lines.push(`当前生效模型: ${resolved.model ?? '(未设置,回落 SDK 默认)'}`);
355
+ lines.push(`推理强度: ${resolved.effort ?? 'auto'}`);
356
+ lines.push(`来源: ${resolved.source ? SCOPE_LABEL[resolved.source] : '无'}`);
357
+ const chain = resolved.chain.map((c) => `${SCOPE_LABEL[c.scope]}${c.hit ? ' ✓' : ''}${c.model ? `(${c.model})` : ''}`).join(' > ');
358
+ lines.push(`解析链: ${chain}`);
359
+ return lines.join('\n');
360
+ });
361
+ }
362
+ // ── info ──────────────────────────────────────────────────────────────
363
+ async function cmdInfo(args, formatJson) {
364
+ if (wantsHelp(args)) {
365
+ console.log(HELP);
366
+ return;
367
+ }
368
+ const modelId = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
369
+ if (!modelId)
370
+ fail(formatJson, 'MISSING_MODEL_ID', 'info 需要 <model-id>');
371
+ const sel = parseSelector(args, formatJson);
372
+ const self = getArgValue(args, '--self');
373
+ const info = await getModelInfo(modelId, self);
374
+ emit(formatJson, { ok: true, ...info }, () => {
375
+ const price = info.pricing;
376
+ const fmtPrice = (v) => v === null ? '— (mock)' : `$${v} / 1M tokens`;
377
+ return [
378
+ `模型: ${info.id}`,
379
+ ` 厂商: ${info.owned_by}`,
380
+ ` 上下文窗口: ${info.context_window ?? '—'} tokens`,
381
+ ` 最大输出: ${info.max_output_tokens ?? '—'} tokens`,
382
+ ` 输入价格: ${fmtPrice(price?.input_per_mtok ?? null)}`,
383
+ ` 输出价格: ${fmtPrice(price?.output_per_mtok ?? null)}`,
384
+ ` 支持模态: ${info.modalities.join(', ')}${info.mocked ? ' (mock)' : ''}`,
385
+ ` 推理强度: ${info.supports_effort ? '支持' : '不支持'}`,
386
+ ` 状态: ${info.status === 'available' ? '✓ 可用' : info.status}`,
387
+ ].join('\n');
388
+ });
389
+ }
390
+ // ── use / effort / reset 共用写入逻辑 ───────────────────────────────────
391
+ function describeWrite(scope, sel, model, effort, formatJson) {
392
+ emit(formatJson, {
393
+ ok: true,
394
+ scope,
395
+ self: sel.self ?? null,
396
+ peerKey: sel.peerKey ?? null,
397
+ model: model ?? undefined,
398
+ effort: effort ?? undefined,
399
+ }, () => {
400
+ const lines = ['✓ 已设置', ` 作用域: ${SCOPE_LABEL[scope]}` +
401
+ (sel.peerKey ? ` (${sel.peerKey})` : '') + (sel.self ? ` [self=${sel.self}]` : '')];
402
+ if (model !== null)
403
+ lines.push(` 模型: ${model}`);
404
+ if (effort !== null)
405
+ lines.push(` 推理强度: ${effort}`);
406
+ lines.push(' 生效: 该范围所有会话的下一条消息起生效。');
407
+ return lines.join('\n');
408
+ });
409
+ }
410
+ async function cmdUse(args, formatJson) {
411
+ if (wantsHelp(args)) {
412
+ console.log(HELP);
413
+ return;
414
+ }
415
+ const modelId = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
416
+ if (!modelId)
417
+ fail(formatJson, 'MISSING_MODEL_ID', 'use 需要 <model-id>');
418
+ if (isManagedSessionEnv(args)) {
419
+ const effort = getArgValue(args, '--effort');
420
+ const out = await runCtlCommand(`/model ${modelId}${effort ? ` ${effort}` : ''}`, formatJson);
421
+ printCtlResult(out, formatJson);
422
+ return;
423
+ }
424
+ const sel = parseSelector(args, formatJson);
425
+ const role = explicitOrDerivedRole(args, sel);
426
+ const scope = determineWriteScope(sel, formatJson);
427
+ const ba = activeBaseagent(sel.self);
428
+ // 校验模型在 catalog 中
429
+ const cat = await getCatalog(sel.self, ba);
430
+ if (!cat.models.some(m => m.id === modelId)) {
431
+ fail(formatJson, 'UNKNOWN_MODEL', `模型不在目录中: ${modelId}(model list 查看可用模型)`);
432
+ }
433
+ if (role) {
434
+ const decision = validateModelSelectionForRole({
435
+ role,
436
+ baseagent: ba,
437
+ requestedModel: modelId,
438
+ models: cat.models.map(m => m.id),
439
+ selfAid: sel.self,
440
+ });
441
+ if (!decision.ok)
442
+ fail(formatJson, decision.code || 'MODEL_NOT_ALLOWED', decision.message || `model not allowed: ${modelId}`);
443
+ }
444
+ const effort = getArgValue(args, '--effort');
445
+ if (effort !== undefined && !ALL_EFFORTS.includes(effort)) {
446
+ fail(formatJson, 'INVALID_EFFORT', `无效推理强度: ${effort}(${ALL_EFFORTS.join('/')})`);
447
+ }
448
+ const effortVal = effort === 'auto' ? null : (effort ?? undefined);
449
+ if (isManagedTargetedWriteEnv(args)) {
450
+ if (effortVal !== undefined) {
451
+ const effortKey = ba === 'codex' ? 'reasoning' : 'effort';
452
+ preflightManagedFieldOverride(sel, role, `baseagents.${ba}.${effortKey}`, effortVal, formatJson);
453
+ }
454
+ await setManagedModelField(sel, `baseagents.${ba}.model`, modelId, formatJson);
455
+ if (effortVal !== undefined) {
456
+ const effortKey = ba === 'codex' ? 'reasoning' : 'effort';
457
+ await setManagedModelField(sel, `baseagents.${ba}.${effortKey}`, effortVal, formatJson);
458
+ }
459
+ describeWrite(scope, sel, modelId, effort ?? null, formatJson);
460
+ return;
461
+ }
462
+ try {
463
+ writeScope(scope, sel, ba, { model: modelId, effort: effortVal });
464
+ }
465
+ catch (e) {
466
+ if (e instanceof ModelScopeError)
467
+ fail(formatJson, e.code, e.message);
468
+ throw e;
469
+ }
470
+ describeWrite(scope, sel, modelId, effort ?? null, formatJson);
471
+ }
472
+ async function cmdEffort(args, formatJson) {
473
+ if (wantsHelp(args)) {
474
+ console.log(HELP);
475
+ return;
476
+ }
477
+ const level = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
478
+ if (!level)
479
+ fail(formatJson, 'INVALID_EFFORT', 'effort 需要 <level>(low|medium|high|xhigh|max|auto)');
480
+ if (!ALL_EFFORTS.includes(level)) {
481
+ fail(formatJson, 'INVALID_EFFORT', `无效推理强度: ${level}(${ALL_EFFORTS.join('/')})`);
482
+ }
483
+ if (isManagedSessionEnv(args)) {
484
+ const out = await runCtlCommand(`/effort ${level}`, formatJson);
485
+ printCtlResult(out, formatJson);
486
+ return;
487
+ }
488
+ const sel = parseSelector(args, formatJson);
489
+ const scope = determineWriteScope(sel, formatJson);
490
+ const ba = activeBaseagent(sel.self);
491
+ const val = level === 'auto' ? null : level;
492
+ if (isManagedTargetedWriteEnv(args)) {
493
+ const effortKey = ba === 'codex' ? 'reasoning' : 'effort';
494
+ preflightManagedFieldOverride(sel, explicitOrDerivedRole(args, sel), `baseagents.${ba}.${effortKey}`, val, formatJson);
495
+ await setManagedModelField(sel, `baseagents.${ba}.${effortKey}`, val, formatJson);
496
+ describeWrite(scope, sel, null, level, formatJson);
497
+ return;
498
+ }
499
+ try {
500
+ writeScope(scope, sel, ba, { effort: val });
501
+ }
502
+ catch (e) {
503
+ if (e instanceof ModelScopeError)
504
+ fail(formatJson, e.code, e.message);
505
+ throw e;
506
+ }
507
+ describeWrite(scope, sel, null, level, formatJson);
508
+ }
509
+ async function cmdReset(args, formatJson) {
510
+ if (wantsHelp(args)) {
511
+ console.log(HELP);
512
+ return;
513
+ }
514
+ if (isManagedSessionEnv(args)) {
515
+ const out = await runCtlCommand('/model reset', formatJson);
516
+ printCtlResult(out, formatJson);
517
+ return;
518
+ }
519
+ const sel = parseSelector(args, formatJson);
520
+ const scope = determineWriteScope(sel, formatJson);
521
+ const ba = activeBaseagent(sel.self);
522
+ if (isManagedTargetedWriteEnv(args)) {
523
+ const effortKey = ba === 'codex' ? 'reasoning' : 'effort';
524
+ const role = explicitOrDerivedRole(args, sel);
525
+ preflightManagedFieldOverride(sel, role, `baseagents.${ba}.model`, null, formatJson);
526
+ preflightManagedFieldOverride(sel, role, `baseagents.${ba}.${effortKey}`, null, formatJson);
527
+ await setManagedModelField(sel, `baseagents.${ba}.model`, null, formatJson);
528
+ await setManagedModelField(sel, `baseagents.${ba}.${effortKey}`, null, formatJson);
529
+ emit(formatJson, {
530
+ ok: true, scope, self: sel.self ?? null, peerKey: sel.peerKey ?? null,
531
+ }, () => `✓ 已清除 ${SCOPE_LABEL[scope]} 设置,回落上一级(该范围所有会话下条消息生效)`);
532
+ return;
533
+ }
534
+ try {
535
+ clearScope(scope, sel, ba);
536
+ }
537
+ catch (e) {
538
+ if (e instanceof ModelScopeError)
539
+ fail(formatJson, e.code, e.message);
540
+ throw e;
541
+ }
542
+ emit(formatJson, {
543
+ ok: true, scope, self: sel.self ?? null, peerKey: sel.peerKey ?? null,
544
+ }, () => {
545
+ return `✓ 已清除 ${SCOPE_LABEL[scope]} 设置,回落上一级(该范围所有会话下条消息生效)`;
546
+ });
547
+ }
548
+ async function cmdCheck(args, formatJson) {
549
+ if (wantsHelp(args)) {
550
+ console.log(HELP);
551
+ return;
552
+ }
553
+ if (isManagedSessionEnv(args)) {
554
+ const out = await runCtlCommand('/model check', formatJson, 60_000);
555
+ printCtlResult(out, formatJson);
556
+ return;
557
+ }
558
+ const sel = parseSelector(args, formatJson);
559
+ const role = explicitOrDerivedRole(args, sel);
560
+ const ba = activeBaseagent(sel.self);
561
+ const steps = [];
562
+ const result = await runModelCheck({
563
+ self: sel.self,
564
+ peerKey: sel.peerKey,
565
+ role,
566
+ baseagent: ba,
567
+ onStep: step => steps.push(step),
568
+ });
569
+ if (formatJson) {
570
+ emit(true, {
571
+ ok: true,
572
+ steps,
573
+ configuredModel: result.configuredModel ?? null,
574
+ configModelAvailable: result.configModelAvailable ?? null,
575
+ availableModels: result.availableModels,
576
+ role: role ?? null,
577
+ catalogSource: result.catalogSource,
578
+ }, () => '');
579
+ return;
580
+ }
581
+ console.log(formatModelCheck(result));
582
+ }
583
+ export async function cmdModel(args) {
584
+ const sub = args[0];
585
+ const formatJson = getArgValue(args, '--format') === 'json';
586
+ if (!sub || isHelpFlag(sub)) {
587
+ console.log(HELP);
588
+ return;
589
+ }
590
+ await dispatch(sub, args, formatJson);
591
+ }