@downcity/city 1.1.29 → 1.1.39
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.js +10 -5
- 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/AgentManager.js +3 -3
- package/bin/cli/agent/AgentManager.js.map +1 -1
- package/bin/cli/agent/Init.d.ts.map +1 -1
- package/bin/cli/agent/Init.js +14 -14
- 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 +12 -19
- 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/ControlPlaneProcess.d.ts.map +1 -1
- package/bin/cli/control-plane/ControlPlaneProcess.js +2 -3
- package/bin/cli/control-plane/ControlPlaneProcess.js.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 +1 -1
- package/bin/cli/shared/ChatAuth.d.ts.map +1 -1
- package/bin/cli/shared/ChatAuth.js +5 -7
- package/bin/cli/shared/ChatAuth.js.map +1 -1
- package/bin/cli/shared/ChatManager.d.ts +1 -1
- package/bin/cli/shared/ChatManager.d.ts.map +1 -1
- package/bin/cli/shared/ChatManager.js +20 -21
- 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 +15 -0
- package/bin/cli/shared/ManagedPluginActionCommands.d.ts.map +1 -0
- package/bin/cli/shared/{PluginRuntimeActionCommands.js → ManagedPluginActionCommands.js} +13 -12
- package/bin/cli/shared/ManagedPluginActionCommands.js.map +1 -0
- package/bin/cli/shared/{PluginRuntimeRemote.d.ts → ManagedPluginRemote.d.ts} +6 -6
- package/bin/cli/shared/{PluginRuntimeRemote.d.ts.map → ManagedPluginRemote.d.ts.map} +1 -1
- package/bin/cli/shared/{PluginRuntimeRemote.js → ManagedPluginRemote.js} +14 -14
- package/bin/cli/shared/ManagedPluginRemote.js.map +1 -0
- package/bin/cli/shared/PluginScheduleCommand.d.ts +3 -2
- package/bin/cli/shared/PluginScheduleCommand.d.ts.map +1 -1
- package/bin/cli/shared/PluginScheduleCommand.js +12 -11
- package/bin/cli/shared/PluginScheduleCommand.js.map +1 -1
- package/bin/cli/shared/{PluginRuntimeSupport.d.ts → PluginTargetSupport.d.ts} +7 -7
- package/bin/cli/shared/PluginTargetSupport.d.ts.map +1 -0
- package/bin/cli/shared/{PluginRuntimeSupport.js → PluginTargetSupport.js} +7 -8
- package/bin/cli/shared/{PluginRuntimeSupport.js.map → PluginTargetSupport.js.map} +1 -1
- package/bin/cli/shared/Plugins.d.ts.map +1 -1
- package/bin/cli/shared/Plugins.js +30 -21
- package/bin/cli/shared/Plugins.js.map +1 -1
- package/bin/cli/shared/PortHints.js +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 +2 -2
- package/bin/config/Paths.js +2 -2
- package/bin/control/AgentStatusApiRoutes.js +2 -2
- package/bin/control/AgentStatusApiRoutes.js.map +1 -1
- package/bin/control/ChannelAccountApiRoutes.d.ts.map +1 -1
- package/bin/control/ChannelAccountApiRoutes.js +6 -7
- package/bin/control/ChannelAccountApiRoutes.js.map +1 -1
- package/bin/control/ControlGateway.d.ts.map +1 -1
- package/bin/control/ControlGateway.js +3 -2
- package/bin/control/ControlGateway.js.map +1 -1
- package/bin/control/PluginApiRoutes.d.ts.map +1 -1
- package/bin/control/PluginApiRoutes.js +38 -30
- package/bin/control/PluginApiRoutes.js.map +1 -1
- package/bin/control/gateway/AgentActions.d.ts.map +1 -1
- package/bin/control/gateway/AgentActions.js +16 -11
- package/bin/control/gateway/AgentActions.js.map +1 -1
- package/bin/control/gateway/AgentCatalog.js +1 -1
- 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 +4 -4
- package/bin/http/auth/RoutePolicy.js.map +1 -1
- package/bin/model/runtime/CreateRuntimeModel.d.ts +2 -10
- package/bin/model/runtime/CreateRuntimeModel.d.ts.map +1 -1
- package/bin/model/runtime/CreateRuntimeModel.js +1 -16
- package/bin/model/runtime/CreateRuntimeModel.js.map +1 -1
- package/bin/model/runtime/ExecutionModelBinding.d.ts +46 -0
- package/bin/model/runtime/ExecutionModelBinding.d.ts.map +1 -0
- package/bin/model/runtime/ExecutionModelBinding.js +96 -0
- package/bin/model/runtime/ExecutionModelBinding.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 -9
- package/bin/process/registry/AgentHostRuntime.d.ts.map +1 -1
- package/bin/process/registry/AgentHostRuntime.js +2 -156
- package/bin/process/registry/AgentHostRuntime.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/Index.ts +13 -5
- package/src/cli/agent/AgentChat.ts +1 -1
- package/src/cli/agent/AgentManager.ts +3 -3
- package/src/cli/agent/Init.ts +15 -14
- package/src/cli/agent/Restart.ts +1 -1
- package/src/cli/agent/Run.ts +12 -18
- package/src/cli/agent/Start.ts +1 -1
- package/src/cli/control-plane/ControlPlaneProcess.ts +2 -3
- package/src/cli/model/ModelSupport.ts +1 -1
- package/src/cli/shared/Chat.ts +1 -1
- package/src/cli/shared/ChatAuth.ts +10 -11
- package/src/cli/shared/ChatManager.ts +21 -22
- package/src/cli/shared/Config.ts +1 -1
- package/src/cli/shared/{PluginRuntimeActionCommands.ts → ManagedPluginActionCommands.ts} +18 -15
- package/src/cli/shared/{PluginRuntimeRemote.ts → ManagedPluginRemote.ts} +15 -15
- package/src/cli/shared/PluginScheduleCommand.ts +12 -11
- package/src/cli/shared/{PluginRuntimeSupport.ts → PluginTargetSupport.ts} +8 -9
- package/src/cli/shared/Plugins.ts +38 -28
- package/src/cli/shared/PortHints.ts +1 -1
- package/src/config/DowncitySchema.ts +2 -8
- package/src/config/Paths.ts +2 -2
- package/src/control/AgentStatusApiRoutes.ts +5 -5
- package/src/control/ChannelAccountApiRoutes.ts +6 -7
- package/src/control/ControlGateway.ts +3 -2
- package/src/control/PluginApiRoutes.ts +42 -32
- package/src/control/gateway/AgentActions.ts +16 -11
- package/src/control/gateway/AgentCatalog.ts +1 -1
- package/src/control/instant/InstantApiRoutes.ts +8 -8
- package/src/control/instant/{InstantSessionService.ts → InstantSessionRunner.ts} +7 -7
- package/src/http/auth/RoutePolicy.ts +4 -4
- package/src/model/runtime/CreateRuntimeModel.ts +1 -26
- package/src/model/runtime/ExecutionModelBinding.ts +120 -0
- package/src/process/daemon/Api.ts +2 -2
- package/src/process/registry/AgentHostRuntime.ts +2 -164
- package/tsconfig.json +2 -1
- package/bin/cli/shared/PluginRuntimeActionCommands.d.ts +0 -14
- package/bin/cli/shared/PluginRuntimeActionCommands.d.ts.map +0 -1
- package/bin/cli/shared/PluginRuntimeActionCommands.js.map +0 -1
- package/bin/cli/shared/PluginRuntimeRemote.js.map +0 -1
- package/bin/cli/shared/PluginRuntimeSupport.d.ts.map +0 -1
- package/bin/control/instant/InstantSessionService.d.ts.map +0 -1
- package/bin/control/instant/InstantSessionService.js.map +0 -1
- package/bin/platform/chatAuthorization/Store.d.ts +0 -31
- package/bin/platform/chatAuthorization/Store.d.ts.map +0 -1
- package/bin/platform/chatAuthorization/Store.js +0 -145
- package/bin/platform/chatAuthorization/Store.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/platform/chatAuthorization/Store.ts +0 -181
- package/src/process/registry/PluginRuntime.ts +0 -42
|
@@ -13,30 +13,31 @@ import type { Command } from "commander";
|
|
|
13
13
|
import prompts from "prompts";
|
|
14
14
|
import {
|
|
15
15
|
buildStaticPluginAvailability,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
findPluginByName,
|
|
17
|
+
listPluginViews,
|
|
18
|
+
listPluginsWithLifecycle,
|
|
19
|
+
listPluginsWithoutLifecycle,
|
|
20
20
|
runLocalPluginAction,
|
|
21
21
|
} from "@downcity/agent";
|
|
22
|
+
import { createBuiltinPlugins } from "@downcity/plugins";
|
|
22
23
|
import { printResult } from "@/utils/cli/CliOutput.js";
|
|
23
24
|
import type { JsonValue } from "@downcity/agent";
|
|
24
25
|
import { getDowncityJsonPath } from "@/config/Paths.js";
|
|
25
26
|
import type { PluginCliBaseOptions } from "@downcity/agent";
|
|
26
27
|
import { emitCliBlock } from "./CliReporter.js";
|
|
27
28
|
import { parseBoolean, parsePort } from "./IndexSupport.js";
|
|
28
|
-
import { resolveProjectRoot } from "./
|
|
29
|
+
import { resolveProjectRoot } from "./PluginTargetSupport.js";
|
|
29
30
|
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
} from "./
|
|
31
|
+
runManagedPluginCommandBridge,
|
|
32
|
+
runManagedPluginControlCommand,
|
|
33
|
+
} from "./ManagedPluginRemote.js";
|
|
33
34
|
import { registerPluginScheduleCommands } from "./PluginScheduleCommand.js";
|
|
34
35
|
import { setCityPluginEnabled } from "@/platform/PluginLifecycle.js";
|
|
35
36
|
|
|
36
37
|
type StaticCatalogEntry = {
|
|
37
38
|
name: string;
|
|
38
39
|
title: string;
|
|
39
|
-
kind: "
|
|
40
|
+
kind: "managed" | "local";
|
|
40
41
|
enabled: boolean;
|
|
41
42
|
available: boolean;
|
|
42
43
|
actionCount: number;
|
|
@@ -45,6 +46,10 @@ type StaticCatalogEntry = {
|
|
|
45
46
|
note?: string;
|
|
46
47
|
};
|
|
47
48
|
|
|
49
|
+
function createPluginCatalog() {
|
|
50
|
+
return createBuiltinPlugins();
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
async function resolvePluginProjectRoot(options: PluginCliBaseOptions): Promise<{
|
|
49
54
|
projectRoot?: string;
|
|
50
55
|
error?: string;
|
|
@@ -79,6 +84,7 @@ function buildSafeStaticPluginAvailability(pluginName: string): {
|
|
|
79
84
|
} {
|
|
80
85
|
try {
|
|
81
86
|
const availability = buildStaticPluginAvailability({
|
|
87
|
+
plugins: createPluginCatalog(),
|
|
82
88
|
pluginName,
|
|
83
89
|
});
|
|
84
90
|
const normalizedReasons = availability.reasons.map((reason) => {
|
|
@@ -122,7 +128,7 @@ function truncateCell(input: string, width: number): string {
|
|
|
122
128
|
function renderPluginCatalogTable(rows: Array<{
|
|
123
129
|
name: string;
|
|
124
130
|
title: string;
|
|
125
|
-
kind: "
|
|
131
|
+
kind: "managed" | "local";
|
|
126
132
|
enabled: boolean;
|
|
127
133
|
available: boolean;
|
|
128
134
|
actionCount: number;
|
|
@@ -166,24 +172,27 @@ function renderPluginCatalogTable(rows: Array<{
|
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
function listStaticCatalogEntries(): StaticCatalogEntry[] {
|
|
169
|
-
const
|
|
175
|
+
const plugins = createPluginCatalog();
|
|
176
|
+
const managedEntries = listPluginsWithLifecycle(plugins).map((plugin) => ({
|
|
170
177
|
name: plugin.name,
|
|
171
|
-
title:
|
|
172
|
-
kind: "
|
|
178
|
+
title: String(plugin.title || plugin.name || "").trim() || plugin.name,
|
|
179
|
+
kind: "managed" as const,
|
|
173
180
|
enabled: true,
|
|
174
181
|
available: true,
|
|
175
182
|
actionCount: Object.keys(plugin.actions || {}).length,
|
|
176
183
|
actions: Object.keys(plugin.actions || {}).sort((left, right) => left.localeCompare(right)),
|
|
177
184
|
hasSystem: typeof plugin.system === "function",
|
|
178
|
-
note: "
|
|
185
|
+
note: "Managed plugin. Use `city plugin start/stop/restart/status` with an agent target for live state.",
|
|
179
186
|
}));
|
|
180
187
|
|
|
181
|
-
const
|
|
188
|
+
const localPlugins = listPluginsWithoutLifecycle(plugins);
|
|
189
|
+
const localEntries = listPluginViews(localPlugins)
|
|
190
|
+
.map((plugin) => {
|
|
182
191
|
const availability = buildSafeStaticPluginAvailability(plugin.name);
|
|
183
192
|
return {
|
|
184
193
|
name: plugin.name,
|
|
185
194
|
title: plugin.title,
|
|
186
|
-
kind: "
|
|
195
|
+
kind: "local" as const,
|
|
187
196
|
enabled: availability.enabled,
|
|
188
197
|
available: availability.available,
|
|
189
198
|
actionCount: plugin.actions.length,
|
|
@@ -193,7 +202,7 @@ function listStaticCatalogEntries(): StaticCatalogEntry[] {
|
|
|
193
202
|
};
|
|
194
203
|
});
|
|
195
204
|
|
|
196
|
-
const merged = [...
|
|
205
|
+
const merged = [...managedEntries, ...localEntries];
|
|
197
206
|
const unique = new Map<string, StaticCatalogEntry>();
|
|
198
207
|
for (const entry of merged) {
|
|
199
208
|
if (!unique.has(entry.name)) {
|
|
@@ -416,7 +425,7 @@ async function runPluginLifecycleCommand(params: {
|
|
|
416
425
|
enabled: boolean;
|
|
417
426
|
asJson?: boolean;
|
|
418
427
|
}): Promise<void> {
|
|
419
|
-
const plugin =
|
|
428
|
+
const plugin = findPluginByName(createPluginCatalog(), params.pluginName);
|
|
420
429
|
if (!plugin) {
|
|
421
430
|
printResult({
|
|
422
431
|
asJson: params.asJson === true,
|
|
@@ -552,6 +561,7 @@ async function runPluginActionCommand(params: {
|
|
|
552
561
|
|
|
553
562
|
const payload = parseCommandPayload(params.payload);
|
|
554
563
|
const local = await runLocalPluginAction({
|
|
564
|
+
plugins: createPluginCatalog(),
|
|
555
565
|
projectRoot: resolved.projectRoot,
|
|
556
566
|
pluginName: params.pluginName,
|
|
557
567
|
actionName: params.actionName,
|
|
@@ -609,7 +619,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
609
619
|
|
|
610
620
|
plugin
|
|
611
621
|
.command("status <pluginName>")
|
|
612
|
-
.description("按 agent
|
|
622
|
+
.description("按 agent 目标查看托管 plugin 运行状态")
|
|
613
623
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
614
624
|
.option("--agent <name>", "agent 名称(从 managed agent registry 解析)")
|
|
615
625
|
.option("--host <host>", "Server host(覆盖自动解析)")
|
|
@@ -617,7 +627,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
617
627
|
.option("--token <token>", "覆盖 Bearer Token(仅远程 HTTP 调用需要;默认本地走 IPC)")
|
|
618
628
|
.option("--json [enabled]", "以 JSON 输出", parseBoolean, true)
|
|
619
629
|
.action(async (pluginName: string, opts: PluginCliBaseOptions) => {
|
|
620
|
-
await
|
|
630
|
+
await runManagedPluginControlCommand({
|
|
621
631
|
pluginName,
|
|
622
632
|
action: "status",
|
|
623
633
|
options: opts,
|
|
@@ -626,7 +636,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
626
636
|
|
|
627
637
|
plugin
|
|
628
638
|
.command("start <pluginName>")
|
|
629
|
-
.description("按 agent
|
|
639
|
+
.description("按 agent 目标启动托管 plugin")
|
|
630
640
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
631
641
|
.option("--agent <name>", "agent 名称(从 managed agent registry 解析)")
|
|
632
642
|
.option("--host <host>", "Server host(覆盖自动解析)")
|
|
@@ -634,7 +644,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
634
644
|
.option("--token <token>", "覆盖 Bearer Token(仅远程 HTTP 调用需要;默认本地走 IPC)")
|
|
635
645
|
.option("--json [enabled]", "以 JSON 输出", parseBoolean, true)
|
|
636
646
|
.action(async (pluginName: string, opts: PluginCliBaseOptions) => {
|
|
637
|
-
await
|
|
647
|
+
await runManagedPluginControlCommand({
|
|
638
648
|
pluginName,
|
|
639
649
|
action: "start",
|
|
640
650
|
options: opts,
|
|
@@ -643,7 +653,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
643
653
|
|
|
644
654
|
plugin
|
|
645
655
|
.command("stop <pluginName>")
|
|
646
|
-
.description("按 agent
|
|
656
|
+
.description("按 agent 目标停止托管 plugin")
|
|
647
657
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
648
658
|
.option("--agent <name>", "agent 名称(从 managed agent registry 解析)")
|
|
649
659
|
.option("--host <host>", "Server host(覆盖自动解析)")
|
|
@@ -651,7 +661,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
651
661
|
.option("--token <token>", "覆盖 Bearer Token(仅远程 HTTP 调用需要;默认本地走 IPC)")
|
|
652
662
|
.option("--json [enabled]", "以 JSON 输出", parseBoolean, true)
|
|
653
663
|
.action(async (pluginName: string, opts: PluginCliBaseOptions) => {
|
|
654
|
-
await
|
|
664
|
+
await runManagedPluginControlCommand({
|
|
655
665
|
pluginName,
|
|
656
666
|
action: "stop",
|
|
657
667
|
options: opts,
|
|
@@ -660,7 +670,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
660
670
|
|
|
661
671
|
plugin
|
|
662
672
|
.command("restart <pluginName>")
|
|
663
|
-
.description("按 agent
|
|
673
|
+
.description("按 agent 目标重启托管 plugin")
|
|
664
674
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
665
675
|
.option("--agent <name>", "agent 名称(从 managed agent registry 解析)")
|
|
666
676
|
.option("--host <host>", "Server host(覆盖自动解析)")
|
|
@@ -668,7 +678,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
668
678
|
.option("--token <token>", "覆盖 Bearer Token(仅远程 HTTP 调用需要;默认本地走 IPC)")
|
|
669
679
|
.option("--json [enabled]", "以 JSON 输出", parseBoolean, true)
|
|
670
680
|
.action(async (pluginName: string, opts: PluginCliBaseOptions) => {
|
|
671
|
-
await
|
|
681
|
+
await runManagedPluginControlCommand({
|
|
672
682
|
pluginName,
|
|
673
683
|
action: "restart",
|
|
674
684
|
options: opts,
|
|
@@ -677,7 +687,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
677
687
|
|
|
678
688
|
plugin
|
|
679
689
|
.command("command <pluginName> <command>")
|
|
680
|
-
.description("按 agent
|
|
690
|
+
.description("按 agent 目标转发托管 plugin command")
|
|
681
691
|
.option("--payload <json>", "可选 payload(JSON 字符串或普通字符串)")
|
|
682
692
|
.option("--path <path>", "项目根目录(默认当前目录)", ".")
|
|
683
693
|
.option("--agent <name>", "agent 名称(从 managed agent registry 解析)")
|
|
@@ -690,7 +700,7 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
690
700
|
command: string,
|
|
691
701
|
opts: PluginCliBaseOptions & { payload?: string },
|
|
692
702
|
) => {
|
|
693
|
-
await
|
|
703
|
+
await runManagedPluginCommandBridge({
|
|
694
704
|
pluginName,
|
|
695
705
|
command,
|
|
696
706
|
payloadRaw: opts.payload,
|
|
@@ -23,7 +23,7 @@ export function buildRuntimePortFacts(): Array<{
|
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
label: "Usage",
|
|
26
|
-
value: "Runtime API / plugin endpoints (health, runtime
|
|
26
|
+
value: "Runtime API / plugin endpoints (health, plugin runtime, task, extension plugin)",
|
|
27
27
|
},
|
|
28
28
|
];
|
|
29
29
|
}
|
|
@@ -120,11 +120,11 @@ export const DOWNCITY_JSON_SCHEMA: JsonObject = {
|
|
|
120
120
|
},
|
|
121
121
|
},
|
|
122
122
|
},
|
|
123
|
-
|
|
123
|
+
plugins: {
|
|
124
124
|
type: "object",
|
|
125
125
|
additionalProperties: true,
|
|
126
126
|
properties: {
|
|
127
|
-
|
|
127
|
+
skill: {
|
|
128
128
|
type: "object",
|
|
129
129
|
additionalProperties: true,
|
|
130
130
|
properties: {
|
|
@@ -187,12 +187,6 @@ export const DOWNCITY_JSON_SCHEMA: JsonObject = {
|
|
|
187
187
|
},
|
|
188
188
|
},
|
|
189
189
|
},
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
plugins: {
|
|
193
|
-
type: "object",
|
|
194
|
-
additionalProperties: true,
|
|
195
|
-
properties: {
|
|
196
190
|
asr: {
|
|
197
191
|
type: "object",
|
|
198
192
|
additionalProperties: true,
|
package/src/config/Paths.ts
CHANGED
|
@@ -111,7 +111,7 @@ export function getDowncityMemoryDailyPath(cwd: string, date: string): string {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
114
|
+
* Plugin Schedule JSONL 路径。
|
|
115
115
|
*
|
|
116
116
|
* 关键点(中文)
|
|
117
117
|
* - 调度任务属于项目 runtime 本地状态,因此放在项目 `.downcity/` 下。
|
|
@@ -226,7 +226,7 @@ export function getDowncityDebugDirPath(cwd: string): string {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
/**
|
|
229
|
-
* Chat 元信息目录(由
|
|
229
|
+
* Chat 元信息目录(由 chat plugin runtime 维护)。
|
|
230
230
|
*
|
|
231
231
|
* 关键点(中文)
|
|
232
232
|
* - 该目录存放 `sessionId -> chat` 的最近映射快照
|
|
@@ -19,7 +19,7 @@ type AgentStatusPayload = {
|
|
|
19
19
|
reason?: string;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
type
|
|
22
|
+
type PluginStateListResponse = {
|
|
23
23
|
success?: boolean;
|
|
24
24
|
plugins?: Array<{
|
|
25
25
|
name?: unknown;
|
|
@@ -94,10 +94,10 @@ async function probeSelectedAgentStatus(
|
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
let pluginsPayload:
|
|
97
|
+
let pluginsPayload: PluginStateListResponse;
|
|
98
98
|
try {
|
|
99
|
-
pluginsPayload = await fetchStatusJson<
|
|
100
|
-
new URL("/api/plugins/
|
|
99
|
+
pluginsPayload = await fetchStatusJson<PluginStateListResponse>(
|
|
100
|
+
new URL("/api/plugins/list", baseUrl).toString(),
|
|
101
101
|
);
|
|
102
102
|
} catch (error) {
|
|
103
103
|
return {
|
|
@@ -152,7 +152,7 @@ async function probeSelectedAgentStatus(
|
|
|
152
152
|
|
|
153
153
|
try {
|
|
154
154
|
await fetchStatusJson<ChatStatusResponse>(
|
|
155
|
-
new URL("/api/plugins/
|
|
155
|
+
new URL("/api/plugins/command", baseUrl).toString(),
|
|
156
156
|
{
|
|
157
157
|
method: "POST",
|
|
158
158
|
headers: {
|
|
@@ -7,19 +7,18 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Hono } from "hono";
|
|
10
|
-
import {
|
|
11
|
-
import { createAgentPlatformRuntime } from "@/process/registry/AgentHostRuntime.js";
|
|
10
|
+
import { ChatChannelAccountManager } from "@downcity/plugins";
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* 注册 Channel Account API 路由。
|
|
15
14
|
*/
|
|
16
15
|
export function registerPlatformChannelAccountRoutes(params: { app: Hono }): void {
|
|
17
16
|
const app = params.app;
|
|
18
|
-
const
|
|
17
|
+
const manager = new ChatChannelAccountManager();
|
|
19
18
|
|
|
20
19
|
app.get("/api/ui/channel-accounts", async (c) => {
|
|
21
20
|
try {
|
|
22
|
-
const payload = await
|
|
21
|
+
const payload = await manager.list();
|
|
23
22
|
return c.json({
|
|
24
23
|
success: true,
|
|
25
24
|
...payload,
|
|
@@ -47,7 +46,7 @@ export function registerPlatformChannelAccountRoutes(params: { app: Hono }): voi
|
|
|
47
46
|
clearAppId?: boolean;
|
|
48
47
|
clearAppSecret?: boolean;
|
|
49
48
|
};
|
|
50
|
-
const payload = await
|
|
49
|
+
const payload = await manager.upsert({
|
|
51
50
|
id: String(body.id || "").trim(),
|
|
52
51
|
channel: String(body.channel || "").trim(),
|
|
53
52
|
name: String(body.name || "").trim(),
|
|
@@ -82,7 +81,7 @@ export function registerPlatformChannelAccountRoutes(params: { app: Hono }): voi
|
|
|
82
81
|
domain?: string;
|
|
83
82
|
sandbox?: boolean;
|
|
84
83
|
};
|
|
85
|
-
const payload = await
|
|
84
|
+
const payload = await manager.probe({
|
|
86
85
|
channel: String(body.channel || "").trim(),
|
|
87
86
|
botToken: body.botToken,
|
|
88
87
|
appId: body.appId,
|
|
@@ -108,7 +107,7 @@ export function registerPlatformChannelAccountRoutes(params: { app: Hono }): voi
|
|
|
108
107
|
if (!id) {
|
|
109
108
|
return c.json({ success: false, error: "Missing id" }, 400);
|
|
110
109
|
}
|
|
111
|
-
await
|
|
110
|
+
await manager.remove(id);
|
|
112
111
|
return c.json({
|
|
113
112
|
success: true,
|
|
114
113
|
id,
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
buildPlatformUpstreamUrl,
|
|
41
41
|
forwardPlatformRequest,
|
|
42
42
|
} from "@/control/gateway/Proxy.js";
|
|
43
|
+
import { listPluginAuthPolicies } from "@downcity/agent";
|
|
43
44
|
import type {
|
|
44
45
|
PlatformAgentOption,
|
|
45
46
|
PlatformAgentsResponse,
|
|
@@ -49,7 +50,7 @@ import type {
|
|
|
49
50
|
PlatformLocalModelsResponse,
|
|
50
51
|
} from "@downcity/agent";
|
|
51
52
|
import type { AgentProjectInitializationResult } from "@downcity/agent";
|
|
52
|
-
import {
|
|
53
|
+
import { createBuiltinPlugins } from "@downcity/plugins";
|
|
53
54
|
import { AuthService } from "@/http/auth/AuthService.js";
|
|
54
55
|
import { registerAuthRoutes } from "@/http/auth/AuthRoutes.js";
|
|
55
56
|
import {
|
|
@@ -120,7 +121,7 @@ export class ControlGateway {
|
|
|
120
121
|
this.authService,
|
|
121
122
|
[
|
|
122
123
|
...CONTROL_PLANE_AUTH_ROUTE_POLICIES,
|
|
123
|
-
...
|
|
124
|
+
...listPluginAuthPolicies(createBuiltinPlugins()),
|
|
124
125
|
],
|
|
125
126
|
),
|
|
126
127
|
);
|
|
@@ -9,15 +9,17 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Hono } from "hono";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
findPluginByName,
|
|
13
|
+
listPluginViews,
|
|
14
14
|
runLocalPluginAction,
|
|
15
15
|
} from "@downcity/agent";
|
|
16
|
+
import { createBuiltinPlugins } from "@downcity/plugins";
|
|
16
17
|
import type { PlatformAgentOption } from "@downcity/agent";
|
|
17
18
|
import type {
|
|
18
19
|
PluginActionResult,
|
|
19
20
|
PluginAction,
|
|
20
21
|
PluginAvailability,
|
|
22
|
+
Plugin,
|
|
21
23
|
PluginSetupDefinition,
|
|
22
24
|
PluginUsageDefinition,
|
|
23
25
|
PluginView,
|
|
@@ -75,8 +77,12 @@ function getErrorMessage(error: unknown): string {
|
|
|
75
77
|
return String(error);
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
function createPluginCatalog() {
|
|
81
|
+
return createBuiltinPlugins();
|
|
82
|
+
}
|
|
83
|
+
|
|
78
84
|
function buildPluginActionConfig(
|
|
79
|
-
plugin:
|
|
85
|
+
plugin: Plugin | null,
|
|
80
86
|
): PluginActionConfigItem[] {
|
|
81
87
|
if (!plugin) return [];
|
|
82
88
|
const actions = (plugin.actions || {}) as Record<string, PluginAction>;
|
|
@@ -94,19 +100,19 @@ function buildPluginConfigMap(): Map<string, {
|
|
|
94
100
|
setup?: PluginSetupDefinition;
|
|
95
101
|
usage?: PluginUsageDefinition;
|
|
96
102
|
}> {
|
|
103
|
+
const plugins = createPluginCatalog();
|
|
97
104
|
return new Map(
|
|
98
|
-
|
|
99
|
-
view.name
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
: {}),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
] as const),
|
|
105
|
+
listPluginViews(plugins).map((view) => {
|
|
106
|
+
const plugin = findPluginByName(plugins, view.name);
|
|
107
|
+
return [
|
|
108
|
+
view.name,
|
|
109
|
+
{
|
|
110
|
+
actions: buildPluginActionConfig(plugin),
|
|
111
|
+
...(plugin?.setup ? { setup: plugin.setup } : {}),
|
|
112
|
+
...(plugin?.usage ? { usage: plugin.usage } : {}),
|
|
113
|
+
},
|
|
114
|
+
] as const;
|
|
115
|
+
}),
|
|
110
116
|
);
|
|
111
117
|
}
|
|
112
118
|
|
|
@@ -114,16 +120,18 @@ function buildGlobalPluginConfigMap(): Map<string, {
|
|
|
114
120
|
actions: PluginActionConfigItem[];
|
|
115
121
|
setup?: PluginSetupDefinition;
|
|
116
122
|
}> {
|
|
123
|
+
const plugins = createPluginCatalog();
|
|
117
124
|
return new Map(
|
|
118
|
-
|
|
119
|
-
view.name
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
: {}),
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
listPluginViews(plugins).map((view) => {
|
|
126
|
+
const plugin = findPluginByName(plugins, view.name);
|
|
127
|
+
return [
|
|
128
|
+
view.name,
|
|
129
|
+
{
|
|
130
|
+
actions: buildPluginActionConfig(plugin),
|
|
131
|
+
...(plugin?.setup ? { setup: plugin.setup } : {}),
|
|
132
|
+
},
|
|
133
|
+
] as const;
|
|
134
|
+
}),
|
|
127
135
|
);
|
|
128
136
|
}
|
|
129
137
|
|
|
@@ -132,7 +140,7 @@ function buildGlobalPluginPayload(): PluginUiResponse {
|
|
|
132
140
|
return {
|
|
133
141
|
success: true,
|
|
134
142
|
runtimeConnected: false,
|
|
135
|
-
plugins:
|
|
143
|
+
plugins: listPluginViews(createPluginCatalog()).map((view) => ({
|
|
136
144
|
...view,
|
|
137
145
|
availability: {
|
|
138
146
|
enabled: isCityPluginEnabled(view.name),
|
|
@@ -157,7 +165,7 @@ function buildAgentPluginPayload(params?: {
|
|
|
157
165
|
success: true,
|
|
158
166
|
runtimeConnected: params?.runtimeConnected === true,
|
|
159
167
|
...(reason ? { runtimeError: reason } : {}),
|
|
160
|
-
plugins:
|
|
168
|
+
plugins: listPluginViews(createPluginCatalog()).map((view) => ({
|
|
161
169
|
...view,
|
|
162
170
|
availability: {
|
|
163
171
|
enabled: isCityPluginEnabled(view.name),
|
|
@@ -213,7 +221,7 @@ async function loadPluginViews(
|
|
|
213
221
|
baseUrl: string,
|
|
214
222
|
authHeaders?: RuntimeForwardAuthHeaders,
|
|
215
223
|
): Promise<PluginView[]> {
|
|
216
|
-
const listUrl = new URL("/api/plugins/
|
|
224
|
+
const listUrl = new URL("/api/plugins/catalog", baseUrl).toString();
|
|
217
225
|
const payload = await fetchJson<PluginListResponse>(listUrl, {
|
|
218
226
|
headers: buildRuntimeRequestHeaders({ authHeaders }),
|
|
219
227
|
});
|
|
@@ -221,7 +229,7 @@ async function loadPluginViews(
|
|
|
221
229
|
return plugins.sort((a, b) => a.name.localeCompare(b.name));
|
|
222
230
|
}
|
|
223
231
|
|
|
224
|
-
async function
|
|
232
|
+
async function loadAgentPluginAvailability(
|
|
225
233
|
baseUrl: string,
|
|
226
234
|
pluginName: string,
|
|
227
235
|
authHeaders?: RuntimeForwardAuthHeaders,
|
|
@@ -245,7 +253,7 @@ async function loadRuntimePluginAvailability(
|
|
|
245
253
|
return payload.availability;
|
|
246
254
|
}
|
|
247
255
|
|
|
248
|
-
async function
|
|
256
|
+
async function buildAgentPluginPayloadFromRuntime(
|
|
249
257
|
selectedAgent: PlatformAgentOption,
|
|
250
258
|
authHeaders?: RuntimeForwardAuthHeaders,
|
|
251
259
|
): Promise<PluginUiResponse> {
|
|
@@ -256,7 +264,7 @@ async function buildRuntimePluginPayload(
|
|
|
256
264
|
pluginViews.map(async (view) => {
|
|
257
265
|
return {
|
|
258
266
|
...view,
|
|
259
|
-
availability: await
|
|
267
|
+
availability: await loadAgentPluginAvailability(
|
|
260
268
|
baseUrl,
|
|
261
269
|
view.name,
|
|
262
270
|
authHeaders,
|
|
@@ -282,7 +290,8 @@ async function runGlobalPluginAction(input: {
|
|
|
282
290
|
}): Promise<PluginActionResult<JsonValue>> {
|
|
283
291
|
const pluginName = String(input.pluginName || "").trim();
|
|
284
292
|
const actionName = String(input.actionName || "").trim();
|
|
285
|
-
const
|
|
293
|
+
const plugins = createPluginCatalog();
|
|
294
|
+
const plugin = findPluginByName(plugins, pluginName);
|
|
286
295
|
if (!plugin) {
|
|
287
296
|
return {
|
|
288
297
|
success: false,
|
|
@@ -320,6 +329,7 @@ async function runGlobalPluginAction(input: {
|
|
|
320
329
|
}
|
|
321
330
|
|
|
322
331
|
return runLocalPluginAction({
|
|
332
|
+
plugins,
|
|
323
333
|
projectRoot,
|
|
324
334
|
pluginName: plugin.name,
|
|
325
335
|
actionName,
|
|
@@ -367,7 +377,7 @@ export function registerPlatformPluginRoutes(params: {
|
|
|
367
377
|
|
|
368
378
|
try {
|
|
369
379
|
return c.json(
|
|
370
|
-
await
|
|
380
|
+
await buildAgentPluginPayloadFromRuntime(
|
|
371
381
|
selectedAgent,
|
|
372
382
|
readRuntimeForwardAuthHeaders(c.req.raw),
|
|
373
383
|
),
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
} from "@/process/daemon/Manager.js";
|
|
19
19
|
import { buildRunArgsFromOptions } from "@/process/daemon/CliArgs.js";
|
|
20
20
|
import {
|
|
21
|
-
ensureRuntimeExecutionBindingReady,
|
|
22
21
|
initializeAgentProject,
|
|
23
22
|
isAgentProjectInitialized,
|
|
24
23
|
} from "@downcity/agent";
|
|
@@ -33,7 +32,10 @@ import type { AgentProjectInitializationResult } from "@downcity/agent";
|
|
|
33
32
|
import type {
|
|
34
33
|
ExecutionBindingConfig,
|
|
35
34
|
} from "@downcity/agent";
|
|
36
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
assertPlatformModelReady,
|
|
37
|
+
assertProjectExecutionModelReady,
|
|
38
|
+
} from "@/model/runtime/ExecutionModelBinding.js";
|
|
37
39
|
|
|
38
40
|
function resolveExecutionInput(params: {
|
|
39
41
|
modelId?: unknown;
|
|
@@ -70,16 +72,17 @@ export async function initializePlatformAgentProject(params: {
|
|
|
70
72
|
modelId?: unknown;
|
|
71
73
|
forceOverwriteShipJson?: unknown;
|
|
72
74
|
}): Promise<AgentProjectInitializationResult> {
|
|
75
|
+
const execution = resolveExecutionInput({
|
|
76
|
+
modelId: params.modelId,
|
|
77
|
+
});
|
|
78
|
+
assertPlatformModelReady(execution.modelId);
|
|
73
79
|
return initializeAgentProject(
|
|
74
80
|
{
|
|
75
81
|
projectRoot: params.projectRoot,
|
|
76
82
|
agentName: String(params.agentName || "").trim() || undefined,
|
|
77
|
-
execution
|
|
78
|
-
modelId: params.modelId,
|
|
79
|
-
}),
|
|
83
|
+
execution,
|
|
80
84
|
forceOverwriteShipJson: params.forceOverwriteShipJson === true,
|
|
81
85
|
},
|
|
82
|
-
createAgentPlatformRuntime(),
|
|
83
86
|
);
|
|
84
87
|
}
|
|
85
88
|
|
|
@@ -103,6 +106,7 @@ export async function updatePlatformAgentExecution(params: {
|
|
|
103
106
|
if (!modelId) {
|
|
104
107
|
throw new Error("modelId is required");
|
|
105
108
|
}
|
|
109
|
+
assertPlatformModelReady(modelId);
|
|
106
110
|
ship.execution = {
|
|
107
111
|
type: "api",
|
|
108
112
|
modelId,
|
|
@@ -270,16 +274,17 @@ export async function startManagedAgentByProjectRoot(params: {
|
|
|
270
274
|
`Project not ready: ${normalizedRoot}. Required files: PROFILE.md and downcity.json`,
|
|
271
275
|
);
|
|
272
276
|
}
|
|
277
|
+
const execution = resolveExecutionInput({
|
|
278
|
+
modelId: params.initialization?.modelId,
|
|
279
|
+
});
|
|
280
|
+
assertPlatformModelReady(execution.modelId);
|
|
273
281
|
await initializeAgentProject(
|
|
274
282
|
{
|
|
275
283
|
projectRoot: normalizedRoot,
|
|
276
284
|
agentName: String(params.initialization?.agentName || "").trim() || undefined,
|
|
277
|
-
execution
|
|
278
|
-
modelId: params.initialization?.modelId,
|
|
279
|
-
}),
|
|
285
|
+
execution,
|
|
280
286
|
forceOverwriteShipJson: params.initialization?.forceOverwriteShipJson === true,
|
|
281
287
|
},
|
|
282
|
-
createAgentPlatformRuntime(),
|
|
283
288
|
);
|
|
284
289
|
} else {
|
|
285
290
|
const profilePath = getProfileMdPath(normalizedRoot);
|
|
@@ -291,7 +296,7 @@ export async function startManagedAgentByProjectRoot(params: {
|
|
|
291
296
|
}
|
|
292
297
|
}
|
|
293
298
|
|
|
294
|
-
|
|
299
|
+
assertProjectExecutionModelReady(normalizedRoot);
|
|
295
300
|
const args = await buildRunArgsFromOptions(normalizedRoot, {});
|
|
296
301
|
const started = await startDaemonProcess({
|
|
297
302
|
projectRoot: normalizedRoot,
|
|
@@ -119,7 +119,7 @@ async function resolveAgentChatProfiles(params: {
|
|
|
119
119
|
statusText?: string;
|
|
120
120
|
}>> {
|
|
121
121
|
try {
|
|
122
|
-
const upstreamUrl = new URL("/api/plugins/
|
|
122
|
+
const upstreamUrl = new URL("/api/plugins/command", params.baseUrl).toString();
|
|
123
123
|
const response = await fetch(upstreamUrl, {
|
|
124
124
|
method: "POST",
|
|
125
125
|
headers: {
|