@downcity/city 1.1.24 → 1.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -11
- package/bin/cli/Index.d.ts +1 -1
- package/bin/cli/Index.js +4 -6
- package/bin/cli/Index.js.map +1 -1
- package/bin/cli/agent/AgentChat.js +1 -1
- package/bin/cli/agent/AgentChat.js.map +1 -1
- package/bin/cli/agent/AgentHistory.d.ts.map +1 -1
- package/bin/cli/agent/AgentHistory.js +2 -1
- package/bin/cli/agent/AgentHistory.js.map +1 -1
- package/bin/cli/agent/AgentManager.js +3 -3
- package/bin/cli/agent/AgentManager.js.map +1 -1
- package/bin/cli/agent/Init.js +6 -6
- package/bin/cli/agent/Init.js.map +1 -1
- package/bin/cli/agent/Restart.js +1 -1
- package/bin/cli/agent/Restart.js.map +1 -1
- package/bin/cli/agent/Run.d.ts.map +1 -1
- package/bin/cli/agent/Run.js +6 -7
- package/bin/cli/agent/Run.js.map +1 -1
- package/bin/cli/agent/Start.js +1 -1
- package/bin/cli/agent/Start.js.map +1 -1
- package/bin/cli/control-plane/ControlPlaneCommand.d.ts.map +1 -1
- package/bin/cli/control-plane/ControlPlaneCommand.js +19 -1
- package/bin/cli/control-plane/ControlPlaneCommand.js.map +1 -1
- package/bin/cli/control-plane/ControlPlanePublicManager.d.ts +17 -0
- package/bin/cli/control-plane/ControlPlanePublicManager.d.ts.map +1 -0
- package/bin/cli/control-plane/ControlPlanePublicManager.js +229 -0
- package/bin/cli/control-plane/ControlPlanePublicManager.js.map +1 -0
- package/bin/cli/control-plane/ControlPlanePublicMode.d.ts +53 -0
- package/bin/cli/control-plane/ControlPlanePublicMode.d.ts.map +1 -0
- package/bin/cli/control-plane/ControlPlanePublicMode.js +106 -0
- package/bin/cli/control-plane/ControlPlanePublicMode.js.map +1 -0
- package/bin/cli/control-plane/ControlPlaneRuntime.d.ts.map +1 -1
- package/bin/cli/control-plane/ControlPlaneRuntime.js +8 -6
- package/bin/cli/control-plane/ControlPlaneRuntime.js.map +1 -1
- package/bin/cli/control-plane/ControlPlaneStatus.d.ts.map +1 -1
- package/bin/cli/control-plane/ControlPlaneStatus.js +22 -8
- package/bin/cli/control-plane/ControlPlaneStatus.js.map +1 -1
- package/bin/cli/model/ModelManageCommand.d.ts.map +1 -1
- package/bin/cli/model/ModelManageCommand.js +22 -18
- package/bin/cli/model/ModelManageCommand.js.map +1 -1
- package/bin/cli/model/ModelManager.d.ts +1 -1
- package/bin/cli/model/ModelManager.d.ts.map +1 -1
- package/bin/cli/model/ModelManager.js +378 -76
- package/bin/cli/model/ModelManager.js.map +1 -1
- package/bin/cli/model/ModelManagerTypes.d.ts +97 -3
- package/bin/cli/model/ModelManagerTypes.d.ts.map +1 -1
- package/bin/cli/model/ModelSupport.d.ts +1 -1
- package/bin/cli/model/ModelSupport.d.ts.map +1 -1
- package/bin/cli/model/ModelSupport.js +1 -1
- package/bin/cli/model/ModelSupport.js.map +1 -1
- package/bin/cli/shared/Chat.d.ts +1 -1
- package/bin/cli/shared/Chat.js +2 -2
- package/bin/cli/shared/Chat.js.map +1 -1
- package/bin/cli/shared/ChatManager.d.ts +1 -1
- package/bin/cli/shared/ChatManager.js +27 -27
- package/bin/cli/shared/ChatManager.js.map +1 -1
- package/bin/cli/shared/Config.js +1 -1
- package/bin/cli/shared/Config.js.map +1 -1
- package/bin/cli/shared/ManagedPluginActionCommands.d.ts +14 -0
- package/bin/cli/shared/ManagedPluginActionCommands.d.ts.map +1 -0
- package/bin/cli/{service/ServiceActionCommands.js → shared/ManagedPluginActionCommands.js} +60 -60
- package/bin/cli/shared/ManagedPluginActionCommands.js.map +1 -0
- package/bin/cli/shared/ManagedPluginRemote.d.ts +30 -0
- package/bin/cli/shared/ManagedPluginRemote.d.ts.map +1 -0
- package/bin/cli/{service/ServiceCommandRemote.js → shared/ManagedPluginRemote.js} +34 -34
- package/bin/cli/shared/ManagedPluginRemote.js.map +1 -0
- package/bin/cli/shared/PluginScheduleCommand.d.ts +36 -0
- package/bin/cli/shared/PluginScheduleCommand.d.ts.map +1 -0
- package/bin/cli/{service/ServiceScheduleCommand.js → shared/PluginScheduleCommand.js} +41 -41
- package/bin/cli/shared/PluginScheduleCommand.js.map +1 -0
- package/bin/cli/{service/ServiceCommandSupport.d.ts → shared/PluginTargetSupport.d.ts} +12 -12
- package/bin/cli/shared/PluginTargetSupport.d.ts.map +1 -0
- package/bin/cli/{service/ServiceCommandSupport.js → shared/PluginTargetSupport.js} +14 -14
- package/bin/cli/shared/PluginTargetSupport.js.map +1 -0
- package/bin/cli/shared/Plugins.d.ts.map +1 -1
- package/bin/cli/shared/Plugins.js +159 -30
- package/bin/cli/shared/Plugins.js.map +1 -1
- package/bin/cli/shared/PortHints.js +1 -1
- package/bin/cli/shared/PortHints.js.map +1 -1
- package/bin/config/DowncitySchema.d.ts.map +1 -1
- package/bin/config/DowncitySchema.js +2 -8
- package/bin/config/DowncitySchema.js.map +1 -1
- package/bin/config/Paths.d.ts +12 -10
- package/bin/config/Paths.d.ts.map +1 -1
- package/bin/config/Paths.js +23 -17
- package/bin/config/Paths.js.map +1 -1
- package/bin/control/AgentStatusApiRoutes.js +30 -30
- package/bin/control/AgentStatusApiRoutes.js.map +1 -1
- package/bin/control/ChannelAccountApiRoutes.js +6 -6
- package/bin/control/ControlGateway.js +2 -2
- package/bin/control/ControlGateway.js.map +1 -1
- package/bin/control/ModelApiRoutes.d.ts +1 -1
- package/bin/control/ModelApiRoutes.d.ts.map +1 -1
- package/bin/control/ModelApiRoutes.js +1 -1
- package/bin/control/ModelApiRoutes.js.map +1 -1
- package/bin/control/ModelPoolService.d.ts +4 -121
- package/bin/control/ModelPoolService.d.ts.map +1 -1
- package/bin/control/ModelPoolService.js +4 -322
- package/bin/control/ModelPoolService.js.map +1 -1
- package/bin/control/PluginApiRoutes.js +5 -5
- package/bin/control/PluginApiRoutes.js.map +1 -1
- package/bin/control/gateway/AgentActions.d.ts.map +1 -1
- package/bin/control/gateway/AgentActions.js +18 -3
- package/bin/control/gateway/AgentActions.js.map +1 -1
- package/bin/control/gateway/AgentCatalog.js +2 -2
- package/bin/control/gateway/AgentCatalog.js.map +1 -1
- package/bin/control/instant/InstantApiRoutes.d.ts +3 -3
- package/bin/control/instant/InstantApiRoutes.d.ts.map +1 -1
- package/bin/control/instant/InstantApiRoutes.js +5 -5
- package/bin/control/instant/InstantApiRoutes.js.map +1 -1
- package/bin/control/instant/{InstantSessionService.d.ts → InstantSessionRunner.d.ts} +7 -7
- package/bin/control/instant/InstantSessionRunner.d.ts.map +1 -0
- package/bin/control/instant/{InstantSessionService.js → InstantSessionRunner.js} +4 -4
- package/bin/control/instant/InstantSessionRunner.js.map +1 -0
- package/bin/http/auth/RoutePolicy.js +7 -7
- package/bin/http/auth/RoutePolicy.js.map +1 -1
- package/bin/model/service/ModelPoolService.d.ts +145 -0
- package/bin/model/service/ModelPoolService.d.ts.map +1 -0
- package/bin/model/service/ModelPoolService.js +424 -0
- package/bin/model/service/ModelPoolService.js.map +1 -0
- package/bin/process/daemon/Api.d.ts +2 -2
- package/bin/process/daemon/Api.js +1 -1
- package/bin/process/registry/AgentHostRuntime.d.ts +1 -1
- package/bin/process/registry/AgentHostRuntime.d.ts.map +1 -1
- package/bin/process/registry/AgentHostRuntime.js +85 -4
- package/bin/process/registry/AgentHostRuntime.js.map +1 -1
- package/package.json +2 -2
- package/src/cli/Index.ts +4 -6
- package/src/cli/agent/AgentChat.ts +1 -1
- package/src/cli/agent/AgentHistory.ts +6 -1
- package/src/cli/agent/AgentManager.ts +3 -3
- package/src/cli/agent/Init.ts +6 -6
- package/src/cli/agent/Restart.ts +1 -1
- package/src/cli/agent/Run.ts +6 -7
- package/src/cli/agent/Start.ts +1 -1
- package/src/cli/control-plane/ControlPlaneCommand.ts +28 -1
- package/src/cli/control-plane/ControlPlanePublicManager.ts +280 -0
- package/src/cli/control-plane/ControlPlanePublicMode.ts +141 -0
- package/src/cli/control-plane/ControlPlaneRuntime.ts +8 -6
- package/src/cli/control-plane/ControlPlaneStatus.ts +22 -8
- package/src/cli/model/ModelManageCommand.ts +23 -19
- package/src/cli/model/ModelManager.ts +419 -76
- package/src/cli/model/ModelManagerTypes.ts +82 -0
- package/src/cli/model/ModelSupport.ts +1 -1
- package/src/cli/shared/Chat.ts +2 -2
- package/src/cli/shared/ChatManager.ts +27 -27
- package/src/cli/shared/Config.ts +1 -1
- package/src/cli/{service/ServiceActionCommands.ts → shared/ManagedPluginActionCommands.ts} +75 -75
- package/src/cli/{service/ServiceCommandRemote.ts → shared/ManagedPluginRemote.ts} +47 -47
- package/src/cli/{service/ServiceScheduleCommand.ts → shared/PluginScheduleCommand.ts} +49 -49
- package/src/cli/{service/ServiceCommandSupport.ts → shared/PluginTargetSupport.ts} +14 -14
- package/src/cli/shared/Plugins.ts +195 -35
- package/src/cli/shared/PortHints.ts +1 -1
- package/src/config/DowncitySchema.ts +2 -8
- package/src/config/Paths.ts +55 -14
- package/src/control/AgentStatusApiRoutes.ts +35 -35
- package/src/control/ChannelAccountApiRoutes.ts +6 -6
- package/src/control/ControlGateway.ts +2 -2
- package/src/control/ModelApiRoutes.ts +1 -1
- package/src/control/ModelPoolService.ts +4 -390
- package/src/control/PluginApiRoutes.ts +5 -5
- package/src/control/gateway/AgentActions.ts +20 -5
- package/src/control/gateway/AgentCatalog.ts +2 -2
- package/src/control/instant/InstantApiRoutes.ts +8 -8
- package/src/control/instant/{InstantSessionService.ts → InstantSessionRunner.ts} +7 -7
- package/src/http/auth/RoutePolicy.ts +7 -7
- package/src/model/service/ModelPoolService.ts +525 -0
- package/src/process/daemon/Api.ts +2 -2
- package/src/process/registry/AgentHostRuntime.ts +95 -5
- package/bin/cli/service/ServiceActionCommands.d.ts +0 -14
- package/bin/cli/service/ServiceActionCommands.d.ts.map +0 -1
- package/bin/cli/service/ServiceActionCommands.js.map +0 -1
- package/bin/cli/service/ServiceCommandRemote.d.ts +0 -30
- package/bin/cli/service/ServiceCommandRemote.d.ts.map +0 -1
- package/bin/cli/service/ServiceCommandRemote.js.map +0 -1
- package/bin/cli/service/ServiceCommandSupport.d.ts.map +0 -1
- package/bin/cli/service/ServiceCommandSupport.js.map +0 -1
- package/bin/cli/service/ServiceScheduleCommand.d.ts +0 -36
- package/bin/cli/service/ServiceScheduleCommand.d.ts.map +0 -1
- package/bin/cli/service/ServiceScheduleCommand.js.map +0 -1
- package/bin/cli/service/Services.d.ts +0 -14
- package/bin/cli/service/Services.d.ts.map +0 -1
- package/bin/cli/service/Services.js +0 -154
- package/bin/cli/service/Services.js.map +0 -1
- package/bin/control/instant/InstantSessionService.d.ts.map +0 -1
- package/bin/control/instant/InstantSessionService.js.map +0 -1
- package/bin/process/registry/PluginRuntime.d.ts +0 -24
- package/bin/process/registry/PluginRuntime.d.ts.map +0 -1
- package/bin/process/registry/PluginRuntime.js +0 -31
- package/bin/process/registry/PluginRuntime.js.map +0 -1
- package/src/cli/service/Services.ts +0 -189
- package/src/process/registry/PluginRuntime.ts +0 -42
|
@@ -3,35 +3,117 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export type ModelManagerRootAction =
|
|
6
|
+
/**
|
|
7
|
+
* 进入 provider 管理列表。
|
|
8
|
+
*/
|
|
6
9
|
| "providers"
|
|
10
|
+
/**
|
|
11
|
+
* 进入 model 管理列表。
|
|
12
|
+
*/
|
|
7
13
|
| "models"
|
|
14
|
+
/**
|
|
15
|
+
* 跳转到创建流程。
|
|
16
|
+
*/
|
|
8
17
|
| "create"
|
|
18
|
+
/**
|
|
19
|
+
* 退出 manager。
|
|
20
|
+
*/
|
|
9
21
|
| "exit";
|
|
10
22
|
|
|
11
23
|
export type ModelManagerProviderAction =
|
|
24
|
+
/**
|
|
25
|
+
* 查看 provider 详情。
|
|
26
|
+
*/
|
|
12
27
|
| "details"
|
|
28
|
+
/**
|
|
29
|
+
* 编辑 provider 配置。
|
|
30
|
+
*/
|
|
31
|
+
| "edit"
|
|
32
|
+
/**
|
|
33
|
+
* 测试 provider 并导入发现到的模型。
|
|
34
|
+
*/
|
|
13
35
|
| "discover"
|
|
36
|
+
/**
|
|
37
|
+
* 删除 provider。
|
|
38
|
+
*/
|
|
39
|
+
| "remove"
|
|
40
|
+
/**
|
|
41
|
+
* 返回上一层。
|
|
42
|
+
*/
|
|
14
43
|
| "back";
|
|
15
44
|
|
|
16
45
|
export type ModelManagerModelAction =
|
|
46
|
+
/**
|
|
47
|
+
* 查看 model 详情。
|
|
48
|
+
*/
|
|
17
49
|
| "details"
|
|
50
|
+
/**
|
|
51
|
+
* 编辑 model 配置。
|
|
52
|
+
*/
|
|
53
|
+
| "edit"
|
|
54
|
+
/**
|
|
55
|
+
* 切换暂停状态。
|
|
56
|
+
*/
|
|
18
57
|
| "togglePause"
|
|
58
|
+
/**
|
|
59
|
+
* 测试 model 可调用性。
|
|
60
|
+
*/
|
|
19
61
|
| "test"
|
|
62
|
+
/**
|
|
63
|
+
* 绑定到项目。
|
|
64
|
+
*/
|
|
20
65
|
| "use"
|
|
66
|
+
/**
|
|
67
|
+
* 删除 model。
|
|
68
|
+
*/
|
|
69
|
+
| "remove"
|
|
70
|
+
/**
|
|
71
|
+
* 返回上一层。
|
|
72
|
+
*/
|
|
21
73
|
| "back";
|
|
22
74
|
|
|
23
75
|
export interface ModelManagerProviderSummary {
|
|
76
|
+
/**
|
|
77
|
+
* provider 在全局模型池中的唯一 ID。
|
|
78
|
+
*/
|
|
24
79
|
id: string;
|
|
80
|
+
/**
|
|
81
|
+
* provider 类型,例如 `openai`、`anthropic`。
|
|
82
|
+
*/
|
|
25
83
|
type: string;
|
|
84
|
+
/**
|
|
85
|
+
* provider 自定义 base URL;为空表示使用 SDK 默认地址。
|
|
86
|
+
*/
|
|
26
87
|
baseUrl?: string;
|
|
88
|
+
/**
|
|
89
|
+
* 当前引用该 provider 的模型数量。
|
|
90
|
+
*/
|
|
27
91
|
modelCount: number;
|
|
28
92
|
}
|
|
29
93
|
|
|
30
94
|
export interface ModelManagerModelSummary {
|
|
95
|
+
/**
|
|
96
|
+
* model 在全局模型池中的唯一 ID。
|
|
97
|
+
*/
|
|
31
98
|
id: string;
|
|
99
|
+
/**
|
|
100
|
+
* 当前 model 绑定的 provider ID。
|
|
101
|
+
*/
|
|
32
102
|
providerId: string;
|
|
103
|
+
/**
|
|
104
|
+
* 上游真实模型名。
|
|
105
|
+
*/
|
|
33
106
|
name: string;
|
|
107
|
+
/**
|
|
108
|
+
* 当前 model 是否已暂停。
|
|
109
|
+
*/
|
|
34
110
|
isPaused: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* 可选的 temperature 覆写;为空表示使用上游默认值。
|
|
113
|
+
*/
|
|
35
114
|
temperature?: number;
|
|
115
|
+
/**
|
|
116
|
+
* 可选的 maxTokens 覆写;为空表示使用上游默认值。
|
|
117
|
+
*/
|
|
36
118
|
maxTokens?: number;
|
|
37
119
|
}
|
|
@@ -181,7 +181,7 @@ export async function discoverProviderModels(params: {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
export { resolveProjectRoot } from "../
|
|
184
|
+
export { resolveProjectRoot } from "../shared/PluginTargetSupport.js";
|
|
185
185
|
|
|
186
186
|
/**
|
|
187
187
|
* 设置项目 `downcity.json.execution.modelId`。
|
package/src/cli/shared/Chat.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 这里先注册裸 `city chat` 的交互式入口。
|
|
6
|
-
* - 具体
|
|
6
|
+
* - 具体 plugin runtime actions/lifecycle 命令仍由 plugin runtime 注册器补充到同一个命令组。
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Command } from "commander";
|
|
@@ -16,7 +16,7 @@ import { runInteractiveChatManager } from "./ChatManager.js";
|
|
|
16
16
|
export function registerChatCommand(program: Command): void {
|
|
17
17
|
const chat = program
|
|
18
18
|
.command("chat")
|
|
19
|
-
.description("管理 chat
|
|
19
|
+
.description("管理 chat plugin(无参数时启动交互式管理器)")
|
|
20
20
|
.helpOption("--help", "display help for command")
|
|
21
21
|
.action(async () => {
|
|
22
22
|
if (process.stdin.isTTY === true && process.stdout.isTTY === true) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `city chat` 交互式管理器。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* - 裸 `city chat` 进入 chat
|
|
5
|
+
* - 裸 `city chat` 进入 chat plugin 管理,而不是只输出静态 help。
|
|
6
6
|
* - chat channel account 属于 city 级配置,在这里通过“配置 channel”管理。
|
|
7
7
|
* - agent 只绑定 channel account,不在 agent 流程中维护密钥。
|
|
8
8
|
*/
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
import prompts from "prompts";
|
|
11
11
|
import type { PromptObject } from "prompts";
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
ChatChannelAccountManager,
|
|
14
14
|
type ChatChannelAccountListItem,
|
|
15
15
|
} from "@downcity/agent";
|
|
16
16
|
import { emitCliBlock, emitCliList } from "./CliReporter.js";
|
|
17
|
-
import {
|
|
17
|
+
import { runManagedPluginControlCommand } from "./ManagedPluginRemote.js";
|
|
18
18
|
import type { StoredChannelAccountChannel } from "@downcity/agent";
|
|
19
19
|
import type {
|
|
20
20
|
ChatChannelAccountAction,
|
|
@@ -25,8 +25,8 @@ import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.
|
|
|
25
25
|
|
|
26
26
|
const CHAT_CHANNELS: StoredChannelAccountChannel[] = ["telegram", "feishu", "qq"];
|
|
27
27
|
|
|
28
|
-
function
|
|
29
|
-
return new
|
|
28
|
+
function createChannelAccountManager(): ChatChannelAccountManager {
|
|
29
|
+
return new ChatChannelAccountManager(createAgentPlatformRuntime());
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function isInteractiveTerminal(): boolean {
|
|
@@ -49,31 +49,31 @@ function formatCredentialSummary(account: ChatChannelAccountListItem): string {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async function promptRootAction(): Promise<ChatManagerRootAction | null> {
|
|
52
|
-
const
|
|
53
|
-
const accounts = await
|
|
52
|
+
const manager = createChannelAccountManager();
|
|
53
|
+
const accounts = await manager.list();
|
|
54
54
|
const response = (await prompts({
|
|
55
55
|
type: "select",
|
|
56
56
|
name: "action",
|
|
57
|
-
message: "管理 chat
|
|
57
|
+
message: "管理 chat plugin",
|
|
58
58
|
choices: [
|
|
59
59
|
{
|
|
60
60
|
title: "查看状态",
|
|
61
|
-
description: "查看当前项目 chat
|
|
61
|
+
description: "查看当前项目 chat plugin 运行状态",
|
|
62
62
|
value: "status",
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
title: "启动",
|
|
66
|
-
description: "启动当前项目 chat
|
|
66
|
+
description: "启动当前项目 chat plugin",
|
|
67
67
|
value: "start",
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
title: "停止",
|
|
71
|
-
description: "停止当前项目 chat
|
|
71
|
+
description: "停止当前项目 chat plugin",
|
|
72
72
|
value: "stop",
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
title: "重启",
|
|
76
|
-
description: "重启当前项目 chat
|
|
76
|
+
description: "重启当前项目 chat plugin",
|
|
77
77
|
value: "restart",
|
|
78
78
|
},
|
|
79
79
|
{
|
|
@@ -94,8 +94,8 @@ async function promptRootAction(): Promise<ChatManagerRootAction | null> {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
async function promptChannelAccountAction(): Promise<ChatChannelAccountAction | null> {
|
|
97
|
-
const
|
|
98
|
-
const accounts = await
|
|
97
|
+
const manager = createChannelAccountManager();
|
|
98
|
+
const accounts = await manager.list();
|
|
99
99
|
const response = (await prompts({
|
|
100
100
|
type: "select",
|
|
101
101
|
name: "action",
|
|
@@ -128,7 +128,7 @@ async function promptChannelAccountAction(): Promise<ChatChannelAccountAction |
|
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
title: "返回",
|
|
131
|
-
description: "回到 chat
|
|
131
|
+
description: "回到 chat plugin 菜单",
|
|
132
132
|
value: "back",
|
|
133
133
|
},
|
|
134
134
|
],
|
|
@@ -139,8 +139,8 @@ async function promptChannelAccountAction(): Promise<ChatChannelAccountAction |
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
async function emitChannelAccountList(): Promise<void> {
|
|
142
|
-
const
|
|
143
|
-
const { items } = await
|
|
142
|
+
const manager = createChannelAccountManager();
|
|
143
|
+
const { items } = await manager.list();
|
|
144
144
|
if (items.length === 0) {
|
|
145
145
|
emitCliBlock({
|
|
146
146
|
tone: "info",
|
|
@@ -182,8 +182,8 @@ async function chooseChannel(): Promise<StoredChannelAccountChannel | null> {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
async function chooseAccount(): Promise<ChatChannelAccountListItem | null> {
|
|
185
|
-
const
|
|
186
|
-
const { items } = await
|
|
185
|
+
const manager = createChannelAccountManager();
|
|
186
|
+
const { items } = await manager.list();
|
|
187
187
|
if (items.length === 0) {
|
|
188
188
|
emitCliBlock({
|
|
189
189
|
tone: "info",
|
|
@@ -296,8 +296,8 @@ async function addChannelAccount(): Promise<void> {
|
|
|
296
296
|
initial: true,
|
|
297
297
|
})) as { probe?: boolean };
|
|
298
298
|
|
|
299
|
-
const
|
|
300
|
-
const result = await
|
|
299
|
+
const manager = createChannelAccountManager();
|
|
300
|
+
const result = await manager.create({
|
|
301
301
|
channel,
|
|
302
302
|
name,
|
|
303
303
|
botToken: input.botToken,
|
|
@@ -324,8 +324,8 @@ async function editChannelAccount(): Promise<void> {
|
|
|
324
324
|
channel: account.channel,
|
|
325
325
|
current: account,
|
|
326
326
|
});
|
|
327
|
-
const
|
|
328
|
-
await
|
|
327
|
+
const manager = createChannelAccountManager();
|
|
328
|
+
await manager.upsert({
|
|
329
329
|
id: account.id,
|
|
330
330
|
channel: account.channel,
|
|
331
331
|
name: String(input.name || account.name).trim(),
|
|
@@ -356,8 +356,8 @@ async function removeChannelAccount(): Promise<void> {
|
|
|
356
356
|
|
|
357
357
|
if (response.remove !== true) return;
|
|
358
358
|
|
|
359
|
-
const
|
|
360
|
-
|
|
359
|
+
const manager = createChannelAccountManager();
|
|
360
|
+
await manager.remove(account.id);
|
|
361
361
|
emitCliBlock({
|
|
362
362
|
tone: "success",
|
|
363
363
|
title: "Channel account removed",
|
|
@@ -403,8 +403,8 @@ async function runChannelAccountManager(): Promise<void> {
|
|
|
403
403
|
async function runChatLifecycleAction(
|
|
404
404
|
action: "start" | "stop" | "restart" | "status",
|
|
405
405
|
): Promise<void> {
|
|
406
|
-
await
|
|
407
|
-
|
|
406
|
+
await runManagedPluginControlCommand({
|
|
407
|
+
pluginName: "chat",
|
|
408
408
|
action,
|
|
409
409
|
options: {
|
|
410
410
|
path: ".",
|
package/src/cli/shared/Config.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { getDowncityJsonPath } from "@/config/Paths.js";
|
|
|
14
14
|
import { printResult } from "@/utils/cli/CliOutput.js";
|
|
15
15
|
import { aliasCommand } from "./Alias.js";
|
|
16
16
|
import { parseBoolean } from "./IndexSupport.js";
|
|
17
|
-
import { resolveProjectRoot } from "
|
|
17
|
+
import { resolveProjectRoot } from "./PluginTargetSupport.js";
|
|
18
18
|
import type { DowncityConfig } from "@downcity/agent";
|
|
19
19
|
|
|
20
20
|
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 受 agent 托管的 plugin action CLI 注册器。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
6
|
-
* - 仅处理 CLI 参数映射与远程调用,不承载
|
|
7
|
-
* -
|
|
5
|
+
* - 负责把需要运行中 agent 承载的 plugin actions 挂到 commander(`city <plugin> <action>`)。
|
|
6
|
+
* - 仅处理 CLI 参数映射与远程调用,不承载 plugin 状态机逻辑。
|
|
7
|
+
* - 命令注册表与调度时间解析统一复用 agent 包实现,避免 city 维护第二套事实源。
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import type { Command } from "commander";
|
|
12
12
|
import {
|
|
13
13
|
callAgentTransport,
|
|
14
|
-
|
|
14
|
+
listManagedPlugins,
|
|
15
15
|
parseScheduledRunAtMsOrThrow,
|
|
16
16
|
} from "@downcity/agent";
|
|
17
|
-
import type {
|
|
17
|
+
import type { BasePlugin, PluginAction } from "@downcity/agent";
|
|
18
18
|
import type { JsonObject, JsonValue } from "@downcity/agent";
|
|
19
|
-
import type {
|
|
20
|
-
import type {
|
|
21
|
-
import type {
|
|
19
|
+
import type { PluginCommandScheduleInput } from "@downcity/agent";
|
|
20
|
+
import type { PluginCommandResponse } from "@downcity/agent";
|
|
21
|
+
import type { PluginCliBaseOptions } from "@downcity/agent";
|
|
22
22
|
import { printResult } from "@/utils/cli/CliOutput.js";
|
|
23
|
-
import { parseBoolean, parsePort } from "
|
|
24
|
-
import {
|
|
23
|
+
import { parseBoolean, parsePort } from "./IndexSupport.js";
|
|
24
|
+
import { runManagedPluginControlCommand } from "./ManagedPluginRemote.js";
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const CHAT_PLUGIN_HELP_TEXT = [
|
|
27
27
|
"",
|
|
28
28
|
"Chat quick guide:",
|
|
29
29
|
" 直接输出 assistant 文本会发送到当前 chat channel。",
|
|
@@ -40,7 +40,7 @@ const CHAT_SERVICE_HELP_TEXT = [
|
|
|
40
40
|
|
|
41
41
|
const CHAT_HELP_HOOK_ATTACHED = Symbol("chat-help-hook-attached");
|
|
42
42
|
|
|
43
|
-
type
|
|
43
|
+
type PluginCliBridgeOptions = {
|
|
44
44
|
path?: string;
|
|
45
45
|
host?: string;
|
|
46
46
|
port?: number;
|
|
@@ -85,7 +85,7 @@ function toJsonValue(input: unknown): JsonValue | undefined {
|
|
|
85
85
|
return undefined;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
function
|
|
88
|
+
function toPluginActionCommandOpts(
|
|
89
89
|
options: Record<string, unknown>,
|
|
90
90
|
): Record<string, JsonValue> {
|
|
91
91
|
const reservedKeys = new Set(["path", "host", "port", "token", "json", "delay", "time"]);
|
|
@@ -99,9 +99,9 @@ function toServiceActionCommandOpts(
|
|
|
99
99
|
return normalized;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
function
|
|
102
|
+
function toPluginCliBridgeOptions(
|
|
103
103
|
options: Record<string, unknown>,
|
|
104
|
-
):
|
|
104
|
+
): PluginCliBridgeOptions {
|
|
105
105
|
return {
|
|
106
106
|
path: typeof options.path === "string" ? options.path : ".",
|
|
107
107
|
host: typeof options.host === "string" ? options.host : undefined,
|
|
@@ -111,7 +111,7 @@ function toServiceCliBridgeOptions(
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function
|
|
114
|
+
function flattenPluginActionCommandArgs(values: unknown[]): string[] {
|
|
115
115
|
const out: string[] = [];
|
|
116
116
|
const pushValue = (value: unknown): void => {
|
|
117
117
|
if (value === undefined || value === null) return;
|
|
@@ -160,7 +160,7 @@ function hasLongOption(command: Command, longFlag: string): boolean {
|
|
|
160
160
|
*/
|
|
161
161
|
function extractCommandScheduleInput(
|
|
162
162
|
options: Record<string, unknown>,
|
|
163
|
-
):
|
|
163
|
+
): PluginCommandScheduleInput | undefined {
|
|
164
164
|
const runAtMs = parseScheduledRunAtMsOrThrow({
|
|
165
165
|
delay: options.delay as string | number | undefined,
|
|
166
166
|
time: options.time as string | number | undefined,
|
|
@@ -169,38 +169,38 @@ function extractCommandScheduleInput(
|
|
|
169
169
|
return { runAtMs };
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
function
|
|
172
|
+
function registerPluginActionCommand(params: {
|
|
173
173
|
program: Command;
|
|
174
|
-
|
|
174
|
+
plugin: BasePlugin;
|
|
175
175
|
actionName: string;
|
|
176
|
-
action:
|
|
176
|
+
action: PluginAction<JsonValue, JsonValue>;
|
|
177
177
|
}): void {
|
|
178
178
|
const commandSpec = params.action.command;
|
|
179
179
|
if (!commandSpec) return;
|
|
180
180
|
|
|
181
|
-
const
|
|
182
|
-
params.program.commands.find((item) => item.name() === params.
|
|
181
|
+
const pluginCommand =
|
|
182
|
+
params.program.commands.find((item) => item.name() === params.plugin.name) ||
|
|
183
183
|
params.program
|
|
184
|
-
.command(params.
|
|
185
|
-
.description(`${params.
|
|
184
|
+
.command(params.plugin.name)
|
|
185
|
+
.description(`${params.plugin.name} plugin actions`)
|
|
186
186
|
.helpOption("--help", "display help for command");
|
|
187
187
|
|
|
188
188
|
if (
|
|
189
|
-
params.
|
|
190
|
-
!(
|
|
189
|
+
params.plugin.name === "chat" &&
|
|
190
|
+
!(pluginCommand as Command & { [CHAT_HELP_HOOK_ATTACHED]?: boolean })[
|
|
191
191
|
CHAT_HELP_HOOK_ATTACHED
|
|
192
192
|
]
|
|
193
193
|
) {
|
|
194
|
-
const chatCommand =
|
|
194
|
+
const chatCommand = pluginCommand as Command & {
|
|
195
195
|
[CHAT_HELP_HOOK_ATTACHED]?: boolean;
|
|
196
196
|
};
|
|
197
197
|
chatCommand.on("--help", () => {
|
|
198
|
-
console.log(
|
|
198
|
+
console.log(CHAT_PLUGIN_HELP_TEXT);
|
|
199
199
|
});
|
|
200
200
|
chatCommand[CHAT_HELP_HOOK_ATTACHED] = true;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
const actionCommand =
|
|
203
|
+
const actionCommand = pluginCommand
|
|
204
204
|
.command(params.actionName)
|
|
205
205
|
.description(commandSpec.description)
|
|
206
206
|
.helpOption("--help", "display help for command")
|
|
@@ -212,12 +212,12 @@ function registerServiceActionCommand(params: {
|
|
|
212
212
|
|
|
213
213
|
commandSpec.configure?.(actionCommand);
|
|
214
214
|
if (!hasLongOption(actionCommand, "--delay")) {
|
|
215
|
-
actionCommand.option("--delay <ms>", "延迟执行毫秒数(所有
|
|
215
|
+
actionCommand.option("--delay <ms>", "延迟执行毫秒数(所有 plugin action 通用)");
|
|
216
216
|
}
|
|
217
217
|
if (!hasLongOption(actionCommand, "--time")) {
|
|
218
218
|
actionCommand.option(
|
|
219
219
|
"--time <time>",
|
|
220
|
-
"定时执行时间(Unix 时间戳秒/毫秒或 ISO 时间,所有
|
|
220
|
+
"定时执行时间(Unix 时间戳秒/毫秒或 ISO 时间,所有 plugin action 通用)",
|
|
221
221
|
);
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -225,7 +225,7 @@ function registerServiceActionCommand(params: {
|
|
|
225
225
|
const last = rawArgs.at(-1);
|
|
226
226
|
const commandLike = isCommanderCommandLike(last) ? last : null;
|
|
227
227
|
const positionalArgs = commandLike
|
|
228
|
-
?
|
|
228
|
+
? flattenPluginActionCommandArgs(
|
|
229
229
|
Array.isArray(commandLike.processedArgs)
|
|
230
230
|
? (commandLike.processedArgs as unknown[])
|
|
231
231
|
: [],
|
|
@@ -235,7 +235,7 @@ function registerServiceActionCommand(params: {
|
|
|
235
235
|
const fallbackPositional = isPlainOptionsObject(fallbackLast)
|
|
236
236
|
? rawArgs.slice(0, -1)
|
|
237
237
|
: rawArgs;
|
|
238
|
-
return
|
|
238
|
+
return flattenPluginActionCommandArgs(fallbackPositional);
|
|
239
239
|
})();
|
|
240
240
|
const allOptions = commandLike
|
|
241
241
|
? ((commandLike.opts() as Record<string, unknown>) || {})
|
|
@@ -243,16 +243,16 @@ function registerServiceActionCommand(params: {
|
|
|
243
243
|
const fallbackLast = rawArgs.at(-1);
|
|
244
244
|
return isPlainOptionsObject(fallbackLast) ? fallbackLast : {};
|
|
245
245
|
})();
|
|
246
|
-
const actionOptions =
|
|
247
|
-
const bridgeOptions =
|
|
248
|
-
let schedule:
|
|
246
|
+
const actionOptions = toPluginActionCommandOpts(allOptions);
|
|
247
|
+
const bridgeOptions = toPluginCliBridgeOptions(allOptions);
|
|
248
|
+
let schedule: PluginCommandScheduleInput | undefined;
|
|
249
249
|
try {
|
|
250
250
|
schedule = extractCommandScheduleInput(allOptions);
|
|
251
251
|
} catch (error) {
|
|
252
252
|
printResult({
|
|
253
253
|
asJson: bridgeOptions.json,
|
|
254
254
|
success: false,
|
|
255
|
-
title: `${params.
|
|
255
|
+
title: `${params.plugin.name}.${params.actionName} failed`,
|
|
256
256
|
payload: {
|
|
257
257
|
error: `Failed to parse schedule input: ${String(error)}`,
|
|
258
258
|
},
|
|
@@ -270,7 +270,7 @@ function registerServiceActionCommand(params: {
|
|
|
270
270
|
printResult({
|
|
271
271
|
asJson: bridgeOptions.json,
|
|
272
272
|
success: false,
|
|
273
|
-
title: `${params.
|
|
273
|
+
title: `${params.plugin.name}.${params.actionName} failed`,
|
|
274
274
|
payload: {
|
|
275
275
|
error: `Failed to parse command input: ${String(error)}`,
|
|
276
276
|
},
|
|
@@ -278,15 +278,15 @@ function registerServiceActionCommand(params: {
|
|
|
278
278
|
return;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
const remote = await callAgentTransport<
|
|
281
|
+
const remote = await callAgentTransport<PluginCommandResponse>({
|
|
282
282
|
projectRoot: resolveProjectRoot(bridgeOptions.path),
|
|
283
|
-
path: "/api/
|
|
283
|
+
path: "/api/plugins/command",
|
|
284
284
|
method: "POST",
|
|
285
285
|
host: bridgeOptions.host,
|
|
286
286
|
port: bridgeOptions.port,
|
|
287
287
|
authToken: bridgeOptions.token,
|
|
288
288
|
body: {
|
|
289
|
-
|
|
289
|
+
pluginName: params.plugin.name,
|
|
290
290
|
command: params.actionName,
|
|
291
291
|
payload,
|
|
292
292
|
...(schedule ? { schedule } : {}),
|
|
@@ -299,8 +299,8 @@ function registerServiceActionCommand(params: {
|
|
|
299
299
|
asJson: bridgeOptions.json,
|
|
300
300
|
success: Boolean(data.success),
|
|
301
301
|
title: data.success
|
|
302
|
-
? `${params.
|
|
303
|
-
: `${params.
|
|
302
|
+
? `${params.plugin.name}.${params.actionName} ok`
|
|
303
|
+
: `${params.plugin.name}.${params.actionName} failed`,
|
|
304
304
|
payload: {
|
|
305
305
|
...(data.data !== undefined ? { data: data.data } : {}),
|
|
306
306
|
...(data.message ? { message: data.message } : {}),
|
|
@@ -313,7 +313,7 @@ function registerServiceActionCommand(params: {
|
|
|
313
313
|
printResult({
|
|
314
314
|
asJson: bridgeOptions.json,
|
|
315
315
|
success: false,
|
|
316
|
-
title: `${params.
|
|
316
|
+
title: `${params.plugin.name}.${params.actionName} failed`,
|
|
317
317
|
payload: {
|
|
318
318
|
error: remote.error || "Unknown error",
|
|
319
319
|
},
|
|
@@ -321,11 +321,11 @@ function registerServiceActionCommand(params: {
|
|
|
321
321
|
});
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
function
|
|
324
|
+
function hasPluginSubcommand(command: Command, name: string): boolean {
|
|
325
325
|
return command.commands.some((item) => item.name() === name);
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
function
|
|
328
|
+
function attachPluginLifecycleOptions(command: Command): Command {
|
|
329
329
|
return command
|
|
330
330
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
331
331
|
.option("--host <host>", "Server host(覆盖自动解析)")
|
|
@@ -334,57 +334,57 @@ function attachServiceLifecycleOptions(command: Command): Command {
|
|
|
334
334
|
.option("--json [enabled]", "以 JSON 输出", parseBoolean, true);
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
function
|
|
337
|
+
function registerPluginLifecycleCommands(params: {
|
|
338
338
|
program: Command;
|
|
339
|
-
|
|
339
|
+
plugin: BasePlugin;
|
|
340
340
|
}): void {
|
|
341
|
-
if (!params.
|
|
341
|
+
if (!params.plugin.lifecycle?.start && !params.plugin.lifecycle?.stop) {
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
const
|
|
346
|
-
params.program.commands.find((item) => item.name() === params.
|
|
345
|
+
const pluginCommand =
|
|
346
|
+
params.program.commands.find((item) => item.name() === params.plugin.name) ||
|
|
347
347
|
params.program
|
|
348
|
-
.command(params.
|
|
349
|
-
.description(`${params.
|
|
348
|
+
.command(params.plugin.name)
|
|
349
|
+
.description(`${params.plugin.name} plugin actions`)
|
|
350
350
|
.helpOption("--help", "display help for command");
|
|
351
351
|
|
|
352
352
|
const lifecycleCommands = [
|
|
353
353
|
{
|
|
354
354
|
name: "start",
|
|
355
|
-
description: `启动 ${params.
|
|
355
|
+
description: `启动 ${params.plugin.name} plugin`,
|
|
356
356
|
action: "start" as const,
|
|
357
357
|
},
|
|
358
358
|
{
|
|
359
359
|
name: "stop",
|
|
360
|
-
description: `停止 ${params.
|
|
360
|
+
description: `停止 ${params.plugin.name} plugin`,
|
|
361
361
|
action: "stop" as const,
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
name: "restart",
|
|
365
|
-
description: `重启 ${params.
|
|
365
|
+
description: `重启 ${params.plugin.name} plugin`,
|
|
366
366
|
action: "restart" as const,
|
|
367
367
|
},
|
|
368
368
|
{
|
|
369
369
|
name: "status",
|
|
370
|
-
description: `查看 ${params.
|
|
370
|
+
description: `查看 ${params.plugin.name} plugin 运行状态`,
|
|
371
371
|
action: "status" as const,
|
|
372
372
|
},
|
|
373
373
|
];
|
|
374
374
|
|
|
375
375
|
for (const item of lifecycleCommands) {
|
|
376
|
-
if (
|
|
376
|
+
if (hasPluginSubcommand(pluginCommand, item.name)) {
|
|
377
377
|
continue;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
|
|
381
|
-
|
|
380
|
+
attachPluginLifecycleOptions(
|
|
381
|
+
pluginCommand
|
|
382
382
|
.command(item.name)
|
|
383
383
|
.description(item.description)
|
|
384
384
|
.helpOption("--help", "display help for command"),
|
|
385
|
-
).action(async (options:
|
|
386
|
-
await
|
|
387
|
-
|
|
385
|
+
).action(async (options: PluginCliBaseOptions) => {
|
|
386
|
+
await runManagedPluginControlCommand({
|
|
387
|
+
pluginName: params.plugin.name,
|
|
388
388
|
action: item.action,
|
|
389
389
|
options,
|
|
390
390
|
});
|
|
@@ -393,24 +393,24 @@ function registerServiceLifecycleCommands(params: {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
/**
|
|
396
|
-
*
|
|
396
|
+
* 注册所有受 agent 托管的 plugin actions CLI 命令。
|
|
397
397
|
*/
|
|
398
|
-
export function
|
|
399
|
-
const
|
|
400
|
-
for (const
|
|
401
|
-
for (const [actionName, action] of Object.entries(
|
|
402
|
-
|
|
398
|
+
export function registerManagedPluginCommandsForCli(program: Command): void {
|
|
399
|
+
const plugins = listManagedPlugins();
|
|
400
|
+
for (const plugin of plugins) {
|
|
401
|
+
for (const [actionName, action] of Object.entries(plugin.actions)) {
|
|
402
|
+
registerPluginActionCommand({
|
|
403
403
|
program,
|
|
404
|
-
|
|
404
|
+
plugin,
|
|
405
405
|
actionName,
|
|
406
|
-
action,
|
|
406
|
+
action: action as PluginAction<JsonValue, JsonValue>,
|
|
407
407
|
});
|
|
408
408
|
}
|
|
409
409
|
}
|
|
410
|
-
for (const
|
|
411
|
-
|
|
410
|
+
for (const plugin of plugins) {
|
|
411
|
+
registerPluginLifecycleCommands({
|
|
412
412
|
program,
|
|
413
|
-
|
|
413
|
+
plugin,
|
|
414
414
|
});
|
|
415
415
|
}
|
|
416
416
|
}
|