@downcity/plugins 1.0.30 → 1.0.34

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 (74) hide show
  1. package/bin/BuiltinPlugins.js +2 -2
  2. package/bin/BuiltinPlugins.js.map +1 -1
  3. package/bin/asr/Config.d.ts +1 -1
  4. package/bin/asr/Config.d.ts.map +1 -1
  5. package/bin/auth/Plugin.d.ts +6 -6
  6. package/bin/auth/Plugin.d.ts.map +1 -1
  7. package/bin/auth/Plugin.js +29 -20
  8. package/bin/auth/Plugin.js.map +1 -1
  9. package/bin/auth/types/AuthPlugin.d.ts +19 -19
  10. package/bin/auth/types/AuthPlugin.d.ts.map +1 -1
  11. package/bin/auth/types/AuthPlugin.js +17 -17
  12. package/bin/auth/types/AuthPlugin.js.map +1 -1
  13. package/bin/chat/ChatPlugin.d.ts +1 -1
  14. package/bin/chat/ChatPlugin.d.ts.map +1 -1
  15. package/bin/chat/accounts/Store.d.ts +1 -1
  16. package/bin/chat/accounts/Store.d.ts.map +1 -1
  17. package/bin/chat/runtime/ChatChannelConfig.d.ts +1 -1
  18. package/bin/chat/runtime/ChatChannelConfig.d.ts.map +1 -1
  19. package/bin/chat/runtime/ChatChannelCore.d.ts +1 -1
  20. package/bin/chat/runtime/ChatChannelCore.d.ts.map +1 -1
  21. package/bin/chat/runtime/ChatQueueWorker.d.ts.map +1 -1
  22. package/bin/chat/runtime/ChatQueueWorker.js +2 -3
  23. package/bin/chat/runtime/ChatQueueWorker.js.map +1 -1
  24. package/bin/chat/runtime/PluginDispatch.js.map +1 -1
  25. package/bin/chat/runtime/PluginPoints.d.ts +3 -3
  26. package/bin/chat/runtime/PluginPoints.js +3 -3
  27. package/bin/chat/types/ChannelAccount.d.ts +1 -1
  28. package/bin/chat/types/ChannelAccount.d.ts.map +1 -1
  29. package/bin/index.d.ts +3 -3
  30. package/bin/index.d.ts.map +1 -1
  31. package/bin/index.js +2 -2
  32. package/bin/index.js.map +1 -1
  33. package/bin/shell/runtime/ShellActionRuntime.js +1 -1
  34. package/bin/shell/runtime/ShellActionRuntime.js.map +1 -1
  35. package/bin/shell/runtime/ShellRuntimeEnvironment.d.ts.map +1 -1
  36. package/bin/shell/runtime/ShellRuntimeEnvironment.js +5 -2
  37. package/bin/shell/runtime/ShellRuntimeEnvironment.js.map +1 -1
  38. package/bin/task/runtime/TaskRunnerRound.d.ts.map +1 -1
  39. package/bin/task/runtime/TaskRunnerRound.js +6 -3
  40. package/bin/task/runtime/TaskRunnerRound.js.map +1 -1
  41. package/bin/voice/Config.d.ts +1 -1
  42. package/bin/voice/Config.d.ts.map +1 -1
  43. package/bin/workboard/runtime/Collector.d.ts.map +1 -1
  44. package/bin/workboard/runtime/Collector.js +3 -5
  45. package/bin/workboard/runtime/Collector.js.map +1 -1
  46. package/bin/workboard/runtime/Normalizer.d.ts +3 -3
  47. package/bin/workboard/runtime/Normalizer.d.ts.map +1 -1
  48. package/bin/workboard/runtime/Normalizer.js.map +1 -1
  49. package/bin/workboard/runtime/SessionSummary.d.ts +47 -0
  50. package/bin/workboard/runtime/SessionSummary.d.ts.map +1 -0
  51. package/bin/workboard/runtime/SessionSummary.js +51 -0
  52. package/bin/workboard/runtime/SessionSummary.js.map +1 -0
  53. package/package.json +2 -2
  54. package/src/BuiltinPlugins.ts +2 -2
  55. package/src/asr/Config.ts +1 -1
  56. package/src/auth/Plugin.ts +151 -134
  57. package/src/auth/types/AuthPlugin.ts +24 -24
  58. package/src/chat/ChatPlugin.ts +1 -1
  59. package/src/chat/accounts/ChannelAccountManager.ts +2 -2
  60. package/src/chat/accounts/Store.ts +1 -1
  61. package/src/chat/runtime/ChatChannelConfig.ts +1 -1
  62. package/src/chat/runtime/ChatChannelCore.ts +1 -1
  63. package/src/chat/runtime/ChatQueueWorker.ts +1 -5
  64. package/src/chat/runtime/PluginDispatch.ts +2 -2
  65. package/src/chat/runtime/PluginPoints.ts +3 -3
  66. package/src/chat/types/ChannelAccount.ts +1 -1
  67. package/src/index.ts +6 -6
  68. package/src/shell/runtime/ShellActionRuntime.ts +1 -1
  69. package/src/shell/runtime/ShellRuntimeEnvironment.ts +6 -2
  70. package/src/task/runtime/TaskRunnerRound.ts +7 -3
  71. package/src/voice/Config.ts +1 -1
  72. package/src/workboard/runtime/Collector.ts +3 -5
  73. package/src/workboard/runtime/Normalizer.ts +5 -5
  74. package/src/workboard/runtime/SessionSummary.ts +92 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Workboard session 摘要采集。
3
+ *
4
+ * 关键点(中文)
5
+ * - workboard 只需要模糊运行态,不复用 Town control 视图模型。
6
+ * - 这里只读取消息数量、更新时间与执行中状态,不暴露消息内容。
7
+ */
8
+ import fs from "fs-extra";
9
+ import path from "node:path";
10
+ /**
11
+ * 采集 workboard 需要的 session 摘要。
12
+ */
13
+ export async function listWorkboardSessionSummaries(params) {
14
+ const root_dir = params.context.paths.getDowncitySessionRootDirPath();
15
+ if (!(await fs.pathExists(root_dir)))
16
+ return [];
17
+ const entries = await fs.readdir(root_dir, { withFileTypes: true });
18
+ const items = [];
19
+ for (const entry of entries) {
20
+ if (!entry.isDirectory())
21
+ continue;
22
+ const session_id = decodeMaybe(entry.name);
23
+ if (!session_id)
24
+ continue;
25
+ const messages_path = path.join(params.context.paths.getDowncitySessionDirPath(session_id), "messages", "messages.jsonl");
26
+ const stat = await fs.stat(messages_path).catch(() => null);
27
+ items.push({
28
+ sessionId: session_id,
29
+ messageCount: await countJsonlLines(messages_path),
30
+ ...(stat ? { updatedAt: stat.mtimeMs } : {}),
31
+ ...(params.executingSessionIds?.has(session_id) ? { executing: true } : {}),
32
+ });
33
+ }
34
+ items.sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0));
35
+ return items.slice(0, Math.max(1, params.limit));
36
+ }
37
+ async function countJsonlLines(file_path) {
38
+ const raw = await fs.readFile(file_path, "utf-8").catch(() => "");
39
+ if (!raw)
40
+ return 0;
41
+ return raw.split("\n").filter((line) => line.trim()).length;
42
+ }
43
+ function decodeMaybe(value) {
44
+ try {
45
+ return decodeURIComponent(String(value || "")).trim();
46
+ }
47
+ catch {
48
+ return String(value || "").trim();
49
+ }
50
+ }
51
+ //# sourceMappingURL=SessionSummary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionSummary.js","sourceRoot":"","sources":["../../../src/workboard/runtime/SessionSummary.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAyB7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,MAanD;IACC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC;IACtE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,KAAK,GAA8B,EAAE,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAS;QACnC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAC7B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,UAAU,CAAC,EAC1D,UAAU,EACV,gBAAgB,CACjB,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC;YACT,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,MAAM,eAAe,CAAC,aAAa,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAAiB;IAC9C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;AAC9D,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@downcity/plugins",
3
- "version": "1.0.30",
3
+ "version": "1.0.34",
4
4
  "type": "module",
5
5
  "description": "Downcity 内建 plugin 集合包",
6
6
  "main": "./bin/index.js",
@@ -22,7 +22,7 @@
22
22
  "node-cron": "^4.2.1",
23
23
  "ws": "^8.21.0",
24
24
  "zod": "^4.4.3",
25
- "@downcity/agent": "^1.1.74"
25
+ "@downcity/agent": "^1.1.79"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/better-sqlite3": "^7.6.13",
@@ -9,7 +9,7 @@
9
9
 
10
10
  import type { AgentRuntime } from "@downcity/agent/internal/types/runtime/agent/AgentRuntime.js";
11
11
  import type { BasePlugin } from "@downcity/agent/internal/plugin/core/BasePlugin.js";
12
- import { AuthPlugin } from "@/auth/Plugin.js";
12
+ import { ChatAuthorizationPlugin } from "@/auth/Plugin.js";
13
13
  import { SkillPlugin } from "@/skill/Plugin.js";
14
14
  import { WebPlugin } from "@/web/Plugin.js";
15
15
  import { AsrPlugin } from "@/asr/Plugin.js";
@@ -32,7 +32,7 @@ export type BuiltinPluginClass<T extends BasePlugin = BasePlugin> = new (
32
32
  * 全部内建 plugin classes。
33
33
  */
34
34
  export const BUILTIN_PLUGIN_CLASSES: BuiltinPluginClass[] = [
35
- AuthPlugin,
35
+ ChatAuthorizationPlugin,
36
36
  SkillPlugin,
37
37
  WebPlugin,
38
38
  AsrPlugin,
package/src/asr/Config.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import type { VoicePluginConfig } from "@/voice/types/VoicePlugin.js";
10
- import type { AgentPluginConfigRuntime } from "@downcity/agent/internal/types/runtime/host/AgentHost.js";
10
+ import type { AgentPluginConfigRuntime } from "@downcity/agent/internal/types/agent/AgentRuntimeAssembly.js";
11
11
  import type { JsonObject, JsonValue } from "@downcity/agent/internal/types/common/Json.js";
12
12
 
13
13
  /**
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Auth Plugin
2
+ * ChatAuthorizationPlugin
3
3
  *
4
4
  * 关键点(中文)
5
- * - auth 是内建且必需的 plugin,不走可选启停语义。
5
+ * - chat-authorization 是内建且必需的 plugin,不走可选启停语义。
6
6
  * - 静态授权配置与动态观测态都收敛在项目 `.downcity/chat/authorization/`。
7
- * - auth plugin 只负责统一暴露扩展点 / action 边界,不再依赖宿主平台读写授权配置。
7
+ * - 它只负责聊天主体授权,不负责 Town HTTP Bearer token 或路由访问鉴权。
8
8
  */
9
9
 
10
10
  import type { AgentRuntime } from "@downcity/agent/internal/types/runtime/agent/AgentRuntime.js";
@@ -13,10 +13,12 @@ import type { Plugin } from "@downcity/agent/internal/plugin/types/Plugin.js";
13
13
  import type { JsonValue } from "@downcity/agent/internal/types/common/Json.js";
14
14
  import { CHAT_PLUGIN_POINTS } from "@/chat/runtime/PluginPoints.js";
15
15
  import {
16
- AUTH_ACTIONS,
17
- type AuthObservePrincipalPayload,
18
- type AuthSetUserRolePayload,
19
- type AuthWriteConfigPayload,
16
+ CHAT_AUTHORIZATION_ACTIONS,
17
+ CHAT_AUTHORIZATION_CATALOG,
18
+ CHAT_AUTHORIZATION_PLUGIN_NAME,
19
+ type ChatAuthorizationObservePrincipalPayload,
20
+ type ChatAuthorizationSetUserRolePayload,
21
+ type ChatAuthorizationWriteConfigPayload,
20
22
  type ChatAuthorizationConfig,
21
23
  type ChatAuthorizationEvaluateInput,
22
24
  type ChatAuthorizationSnapshot,
@@ -50,7 +52,7 @@ function toRecord(value: unknown): Record<string, unknown> {
50
52
  function toEvaluateInput(payload: Record<string, unknown>): ChatAuthorizationEvaluateInput {
51
53
  const channel = toChannel(payload.channel);
52
54
  if (!channel) {
53
- throw new Error("auth.authorize_incoming requires a valid channel");
55
+ throw new Error("chat-authorization.authorize_incoming requires a valid channel");
54
56
  }
55
57
  return {
56
58
  channel,
@@ -64,158 +66,173 @@ function toEvaluateInput(payload: Record<string, unknown>): ChatAuthorizationEva
64
66
 
65
67
  function toSnapshotData(snapshot: ChatAuthorizationSnapshot): JsonValue {
66
68
  return {
69
+ catalog: CHAT_AUTHORIZATION_CATALOG as unknown as JsonValue,
67
70
  config: snapshot.config as unknown as JsonValue,
68
71
  users: snapshot.users as unknown as JsonValue,
69
72
  chats: snapshot.chats as unknown as JsonValue,
70
73
  };
71
74
  }
72
75
 
73
- function createAuthPluginDefinition(): Plugin {
76
+ function createChatAuthorizationPluginDefinition(): Plugin {
74
77
  return {
75
- name: "auth",
76
- title: "User Authorization System",
77
- description:
78
- "Controls who can talk to the agent in chat channels, records observed users and chats, and resolves each user's effective role for downstream service decisions.",
79
- availability() {
80
- return {
81
- enabled: true,
82
- available: true,
83
- reasons: [],
84
- };
85
- },
86
- hooks: {
87
- guard: {
88
- [CHAT_PLUGIN_POINTS.authorizeIncoming]: [
89
- async ({ context, value }) => {
90
- const input =
91
- value && typeof value === "object" && !Array.isArray(value)
92
- ? (value as Record<string, unknown>)
93
- : {};
94
- const evaluateInput = toEvaluateInput(input);
95
- const authorizationConfig = readChatAuthorizationConfig(context);
96
- const result = evaluateIncomingChatAuthorization({
97
- config: context.config,
98
- channel: evaluateInput.channel,
99
- input: evaluateInput,
100
- authorizationConfig,
101
- });
102
- if (result.decision !== "allow") {
103
- throw new Error(result.reason || "chat authorization blocked");
104
- }
105
- },
106
- ],
107
- },
108
- effect: {
109
- [CHAT_PLUGIN_POINTS.observePrincipal]: [
110
- async ({ context, value }) => {
111
- const input = toRecord(value) as unknown as AuthObservePrincipalPayload;
112
- const channel = toChannel(input.channel);
113
- if (!channel) {
114
- throw new Error("chat.observePrincipal requires a valid channel");
115
- }
116
- await recordObservedAuthorizationPrincipal({
117
- context,
118
- channel,
119
- chatId: String(input.chatId || "").trim(),
120
- ...(typeof input.chatType === "string" ? { chatType: input.chatType.trim() } : {}),
121
- ...(typeof input.chatTitle === "string" ? { chatTitle: input.chatTitle.trim() } : {}),
122
- ...(typeof input.userId === "string" ? { userId: input.userId.trim() } : {}),
123
- ...(typeof input.username === "string" ? { username: input.username.trim() } : {}),
124
- });
125
- },
126
- ],
78
+ name: CHAT_AUTHORIZATION_PLUGIN_NAME,
79
+ title: "Chat Authorization",
80
+ description:
81
+ "Controls who can talk to the agent in chat channels, records observed users and chats, and resolves each user's effective role for downstream service decisions.",
82
+ availability() {
83
+ return {
84
+ enabled: true,
85
+ available: true,
86
+ reasons: [],
87
+ };
127
88
  },
128
- },
129
- resolves: {
130
- [CHAT_PLUGIN_POINTS.resolveUserRole]: async ({ context, value }) => {
131
- const input =
132
- value && typeof value === "object" && !Array.isArray(value)
133
- ? (value as Record<string, unknown>)
134
- : {};
135
- const channel = toChannel(input.channel);
136
- if (!channel) {
137
- throw new Error("chat.resolveUserRole requires a valid channel");
138
- }
139
- const role = resolveAuthorizedUserRole({
140
- channel,
141
- userId: String(input.userId || "").trim(),
142
- rootPath: context.rootPath,
143
- });
144
- return ((role || null) as unknown) as JsonValue;
145
- },
146
- },
147
- actions: {
148
- [AUTH_ACTIONS.snapshot]: {
149
- execute: async ({ context }) => {
150
- const snapshot = await readAuthorizationSnapshot({
151
- context,
152
- });
153
- return {
154
- success: true,
155
- data: toSnapshotData(snapshot),
156
- };
89
+ hooks: {
90
+ guard: {
91
+ [CHAT_PLUGIN_POINTS.authorizeIncoming]: [
92
+ async ({ context, value }) => {
93
+ const input =
94
+ value && typeof value === "object" && !Array.isArray(value)
95
+ ? (value as Record<string, unknown>)
96
+ : {};
97
+ const evaluateInput = toEvaluateInput(input);
98
+ const authorizationConfig = readChatAuthorizationConfig(context);
99
+ const result = evaluateIncomingChatAuthorization({
100
+ config: context.config,
101
+ channel: evaluateInput.channel,
102
+ input: evaluateInput,
103
+ authorizationConfig,
104
+ });
105
+ if (result.decision !== "allow") {
106
+ throw new Error(result.reason || "chat authorization blocked");
107
+ }
108
+ },
109
+ ],
157
110
  },
158
- },
159
- [AUTH_ACTIONS.readConfig]: {
160
- execute: async ({ context }) => {
161
- return {
162
- success: true,
163
- data: readChatAuthorizationConfig(context) as unknown as JsonValue,
164
- };
111
+ effect: {
112
+ [CHAT_PLUGIN_POINTS.observePrincipal]: [
113
+ async ({ context, value }) => {
114
+ const input = toRecord(
115
+ value,
116
+ ) as unknown as ChatAuthorizationObservePrincipalPayload;
117
+ const channel = toChannel(input.channel);
118
+ if (!channel) {
119
+ throw new Error("chat.observePrincipal requires a valid channel");
120
+ }
121
+ await recordObservedAuthorizationPrincipal({
122
+ context,
123
+ channel,
124
+ chatId: String(input.chatId || "").trim(),
125
+ ...(typeof input.chatType === "string"
126
+ ? { chatType: input.chatType.trim() }
127
+ : {}),
128
+ ...(typeof input.chatTitle === "string"
129
+ ? { chatTitle: input.chatTitle.trim() }
130
+ : {}),
131
+ ...(typeof input.userId === "string"
132
+ ? { userId: input.userId.trim() }
133
+ : {}),
134
+ ...(typeof input.username === "string"
135
+ ? { username: input.username.trim() }
136
+ : {}),
137
+ });
138
+ },
139
+ ],
165
140
  },
166
141
  },
167
- [AUTH_ACTIONS.writeConfig]: {
168
- execute: async ({ context, payload }) => {
169
- const body = toRecord(payload) as unknown as AuthWriteConfigPayload;
170
- const nextConfig =
171
- body.config && typeof body.config === "object" && !Array.isArray(body.config)
172
- ? (body.config as ChatAuthorizationConfig)
142
+ resolves: {
143
+ [CHAT_PLUGIN_POINTS.resolveUserRole]: async ({ context, value }) => {
144
+ const input =
145
+ value && typeof value === "object" && !Array.isArray(value)
146
+ ? (value as Record<string, unknown>)
173
147
  : {};
174
- await writeChatAuthorizationConfig({
175
- context,
176
- nextConfig,
148
+ const channel = toChannel(input.channel);
149
+ if (!channel) {
150
+ throw new Error("chat.resolveUserRole requires a valid channel");
151
+ }
152
+ const role = resolveAuthorizedUserRole({
153
+ channel,
154
+ userId: String(input.userId || "").trim(),
155
+ rootPath: context.rootPath,
177
156
  });
178
- return {
179
- success: true,
180
- data: readChatAuthorizationConfig(context) as unknown as JsonValue,
181
- };
157
+ return ((role || null) as unknown) as JsonValue;
182
158
  },
183
159
  },
184
- [AUTH_ACTIONS.setUserRole]: {
185
- execute: async ({ context, payload }) => {
186
- const body = toRecord(payload) as unknown as AuthSetUserRolePayload;
187
- const channel = toChannel(body.channel);
188
- if (!channel) {
160
+ actions: {
161
+ [CHAT_AUTHORIZATION_ACTIONS.snapshot]: {
162
+ execute: async ({ context }) => {
163
+ const snapshot = await readAuthorizationSnapshot({
164
+ context,
165
+ });
189
166
  return {
190
- success: false,
191
- error: "set-user-role requires a valid channel",
192
- message: "set-user-role requires a valid channel",
167
+ success: true,
168
+ data: toSnapshotData(snapshot),
193
169
  };
194
- }
195
- await setChatAuthorizationUserRole({
196
- context,
197
- channel,
198
- userId: String(body.userId || "").trim(),
199
- roleId: String(body.roleId || "").trim(),
200
- });
201
- return {
202
- success: true,
203
- data: readChatAuthorizationConfig(context) as unknown as JsonValue,
204
- };
170
+ },
171
+ },
172
+ [CHAT_AUTHORIZATION_ACTIONS.readConfig]: {
173
+ execute: async ({ context }) => {
174
+ return {
175
+ success: true,
176
+ data: readChatAuthorizationConfig(context) as unknown as JsonValue,
177
+ };
178
+ },
179
+ },
180
+ [CHAT_AUTHORIZATION_ACTIONS.writeConfig]: {
181
+ execute: async ({ context, payload }) => {
182
+ const body = toRecord(
183
+ payload,
184
+ ) as unknown as ChatAuthorizationWriteConfigPayload;
185
+ const nextConfig =
186
+ body.config && typeof body.config === "object" && !Array.isArray(body.config)
187
+ ? (body.config as ChatAuthorizationConfig)
188
+ : {};
189
+ await writeChatAuthorizationConfig({
190
+ context,
191
+ nextConfig,
192
+ });
193
+ return {
194
+ success: true,
195
+ data: readChatAuthorizationConfig(context) as unknown as JsonValue,
196
+ };
197
+ },
198
+ },
199
+ [CHAT_AUTHORIZATION_ACTIONS.setUserRole]: {
200
+ execute: async ({ context, payload }) => {
201
+ const body = toRecord(
202
+ payload,
203
+ ) as unknown as ChatAuthorizationSetUserRolePayload;
204
+ const channel = toChannel(body.channel);
205
+ if (!channel) {
206
+ return {
207
+ success: false,
208
+ error: "set-user-role requires a valid channel",
209
+ message: "set-user-role requires a valid channel",
210
+ };
211
+ }
212
+ await setChatAuthorizationUserRole({
213
+ context,
214
+ channel,
215
+ userId: String(body.userId || "").trim(),
216
+ roleId: String(body.roleId || "").trim(),
217
+ });
218
+ return {
219
+ success: true,
220
+ data: readChatAuthorizationConfig(context) as unknown as JsonValue,
221
+ };
222
+ },
205
223
  },
206
224
  },
207
- },
208
225
  };
209
226
  }
210
227
 
211
228
  /**
212
- * AuthPlugin:统一承载授权能力。
229
+ * ChatAuthorizationPlugin:统一承载聊天用户授权能力。
213
230
  */
214
- export class AuthPlugin extends BasePlugin {
215
- readonly name = "auth";
231
+ export class ChatAuthorizationPlugin extends BasePlugin {
232
+ readonly name = CHAT_AUTHORIZATION_PLUGIN_NAME;
216
233
 
217
234
  constructor(agent: AgentRuntime | null = null) {
218
235
  super(agent);
219
- Object.assign(this, createAuthPluginDefinition());
236
+ Object.assign(this, createChatAuthorizationPluginDefinition());
220
237
  }
221
238
  }
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Auth Plugin 类型与契约定义。
2
+ * ChatAuthorizationPlugin 类型与契约定义。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 统一维护 auth plugin 的领域类型、扩展点/action 名称、payload 契约。
5
+ * - 统一维护聊天授权 plugin 的领域类型、扩展点/action 名称、payload 契约。
6
6
  * - 业务层不应散落硬编码字符串,如 `chat.authorizeIncoming`、`set-user-role`。
7
7
  * - chat / console / plugin 执行链路都从这里共享同一份边界定义。
8
8
  */
@@ -11,12 +11,12 @@ import type { ChatDispatchChannel } from "@/chat/types/ChatDispatcher.js";
11
11
  import { CHAT_PLUGIN_POINTS } from "@/chat/runtime/PluginPoints.js";
12
12
 
13
13
  /**
14
- * auth plugin 稳定名称。
14
+ * 聊天授权 plugin 稳定名称。
15
15
  */
16
- export const AUTH_PLUGIN_NAME = "auth";
16
+ export const CHAT_AUTHORIZATION_PLUGIN_NAME = "chat-authorization";
17
17
 
18
18
  /**
19
- * auth 支持的渠道目录。
19
+ * 聊天授权支持的渠道目录。
20
20
  */
21
21
  export const CHAT_AUTHORIZATION_CHANNELS = ["telegram", "feishu", "qq"] as const;
22
22
 
@@ -26,18 +26,18 @@ export const CHAT_AUTHORIZATION_CHANNELS = ["telegram", "feishu", "qq"] as const
26
26
  export type ChatAuthorizationChannel = (typeof CHAT_AUTHORIZATION_CHANNELS)[number];
27
27
 
28
28
  /**
29
- * auth 扩展点名称集合。
29
+ * 聊天授权扩展点名称集合。
30
30
  */
31
- export const AUTH_PLUGIN_POINTS = {
31
+ export const CHAT_AUTHORIZATION_PLUGIN_POINTS = {
32
32
  observePrincipal: CHAT_PLUGIN_POINTS.observePrincipal,
33
33
  authorizeIncoming: CHAT_PLUGIN_POINTS.authorizeIncoming,
34
34
  resolveUserRole: CHAT_PLUGIN_POINTS.resolveUserRole,
35
35
  } as const;
36
36
 
37
37
  /**
38
- * auth action 名称集合。
38
+ * 聊天授权 action 名称集合。
39
39
  */
40
- export const AUTH_ACTIONS = {
40
+ export const CHAT_AUTHORIZATION_ACTIONS = {
41
41
  snapshot: "snapshot",
42
42
  readConfig: "read-config",
43
43
  writeConfig: "write-config",
@@ -50,8 +50,8 @@ export const AUTH_ACTIONS = {
50
50
  export const CHAT_AUTHORIZATION_PERMISSIONS = [
51
51
  "chat.dm.use",
52
52
  "chat.group.use",
53
- "auth.manage.users",
54
- "auth.manage.roles",
53
+ "chat.authorization.manage.users",
54
+ "chat.authorization.manage.roles",
55
55
  "agent.view.logs",
56
56
  "agent.manage",
57
57
  ] as const;
@@ -70,8 +70,8 @@ export const CHAT_AUTHORIZATION_PERMISSION_LABELS: Record<
70
70
  > = {
71
71
  "chat.dm.use": "DM",
72
72
  "chat.group.use": "Group",
73
- "auth.manage.users": "Users",
74
- "auth.manage.roles": "Roles",
73
+ "chat.authorization.manage.users": "Users",
74
+ "chat.authorization.manage.roles": "Roles",
75
75
  "agent.view.logs": "Logs",
76
76
  "agent.manage": "Agent",
77
77
  };
@@ -85,8 +85,8 @@ export const CHAT_AUTHORIZATION_PERMISSION_DESCRIPTIONS: Record<
85
85
  > = {
86
86
  "chat.dm.use": "允许用户在私聊场景中直接向 agent 发送请求并得到响应。",
87
87
  "chat.group.use": "允许用户在群聊或频道场景中触发 agent 执行对话与任务。",
88
- "auth.manage.users": "允许修改用户与权限组之间的绑定关系。",
89
- "auth.manage.roles": "允许编辑权限组定义,以及调整各渠道的新用户默认组。",
88
+ "chat.authorization.manage.users": "允许修改聊天用户与权限组之间的绑定关系。",
89
+ "chat.authorization.manage.roles": "允许编辑聊天权限组定义,以及调整各渠道的新用户默认组。",
90
90
  "agent.view.logs": "允许查看当前 agent 的运行日志与排障信息。",
91
91
  "agent.manage": "允许执行高权限管理动作,例如变更配置、操作服务与任务。",
92
92
  };
@@ -112,11 +112,11 @@ export interface ChatAuthorizationPermissionMeta {
112
112
  }
113
113
 
114
114
  /**
115
- * auth 目录快照。
115
+ * 聊天授权目录快照。
116
116
  */
117
117
  export interface ChatAuthorizationCatalog {
118
118
  /**
119
- * auth 支持的渠道列表。
119
+ * 聊天授权支持的渠道列表。
120
120
  */
121
121
  channels: ChatAuthorizationChannel[];
122
122
 
@@ -137,7 +137,7 @@ export interface ChatAuthorizationCatalog {
137
137
  }
138
138
 
139
139
  /**
140
- * auth 统一目录常量。
140
+ * 聊天授权统一目录常量。
141
141
  */
142
142
  export const CHAT_AUTHORIZATION_CATALOG: ChatAuthorizationCatalog = {
143
143
  channels: [...CHAT_AUTHORIZATION_CHANNELS],
@@ -207,7 +207,7 @@ export function createDefaultChatAuthorizationRoles(): Record<string, ChatAuthor
207
207
  }
208
208
 
209
209
  /**
210
- * 判断给定值是否为 auth 支持的渠道。
210
+ * 判断给定值是否为聊天授权支持的渠道。
211
211
  */
212
212
  export function isChatAuthorizationChannel(
213
213
  value: unknown,
@@ -465,7 +465,7 @@ export interface ChatAuthorizationStateFile {
465
465
  /**
466
466
  * plugin effect 输入:记录观测主体。
467
467
  */
468
- export interface AuthObservePrincipalPayload {
468
+ export interface ChatAuthorizationObservePrincipalPayload {
469
469
  /**
470
470
  * 当前渠道。
471
471
  */
@@ -495,7 +495,7 @@ export interface AuthObservePrincipalPayload {
495
495
  /**
496
496
  * plugin effect 输出:记录观测主体结果。
497
497
  */
498
- export interface AuthObservePrincipalResult {
498
+ export interface ChatAuthorizationObservePrincipalResult {
499
499
  /**
500
500
  * 是否成功落盘。
501
501
  */
@@ -505,7 +505,7 @@ export interface AuthObservePrincipalResult {
505
505
  /**
506
506
  * plugin resolve 输入:查询用户角色。
507
507
  */
508
- export interface AuthResolveUserRolePayload {
508
+ export interface ChatAuthorizationResolveUserRolePayload {
509
509
  /**
510
510
  * 当前渠道。
511
511
  */
@@ -519,7 +519,7 @@ export interface AuthResolveUserRolePayload {
519
519
  /**
520
520
  * action: 覆盖写入配置输入。
521
521
  */
522
- export interface AuthWriteConfigPayload {
522
+ export interface ChatAuthorizationWriteConfigPayload {
523
523
  /**
524
524
  * 新配置。
525
525
  */
@@ -529,7 +529,7 @@ export interface AuthWriteConfigPayload {
529
529
  /**
530
530
  * action: 设置用户角色输入。
531
531
  */
532
- export interface AuthSetUserRolePayload {
532
+ export interface ChatAuthorizationSetUserRolePayload {
533
533
  /**
534
534
  * 当前渠道。
535
535
  */
@@ -13,7 +13,7 @@ import { BasePlugin } from "@downcity/agent/internal/plugin/core/BasePlugin.js";
13
13
  import type { PluginActions } from "@downcity/agent/internal/plugin/types/Plugin.js";
14
14
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
15
15
  import type { ChatChannelState } from "@/chat/types/ChatRuntime.js";
16
- import type { StoredChannelAccount } from "@downcity/agent/internal/types/runtime/host/Store.js";
16
+ import type { StoredChannelAccount } from "@downcity/agent/internal/types/platform/Store.js";
17
17
  import type { ChatQueueWorkerConfig } from "@/chat/types/ChatQueueWorker.js";
18
18
  import type {
19
19
  ChatPluginFeishuOptions,
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import crypto from "node:crypto";
11
- import type { StoredChannelAccountChannel } from "@downcity/agent/internal/types/runtime/host/Store.js";
11
+ import type { StoredChannelAccountChannel } from "@downcity/agent/internal/types/platform/Store.js";
12
12
  import { resolveChatChannelBotInfo } from "@/chat/channels/BotInfoProvider.js";
13
13
  import {
14
14
  getStoredChannelAccountSync,
@@ -24,7 +24,7 @@ import type {
24
24
  ChatChannelAccountProbeResult,
25
25
  ChatChannelAccountUpsertInput,
26
26
  } from "@/chat/types/ChannelAccount.js";
27
- import type { StoredChannelAccount } from "@downcity/agent/internal/types/runtime/host/Store.js";
27
+ import type { StoredChannelAccount } from "@downcity/agent/internal/types/platform/Store.js";
28
28
 
29
29
  const SUPPORTED_CHANNELS: readonly StoredChannelAccountChannel[] = [
30
30
  "telegram",
@@ -20,7 +20,7 @@ import type {
20
20
  StoredChannelAccount,
21
21
  StoredChannelAccountChannel,
22
22
  UpsertChannelAccountInput,
23
- } from "@downcity/agent/internal/types/runtime/host/Store.js";
23
+ } from "@downcity/agent/internal/types/platform/Store.js";
24
24
 
25
25
  function nowIso(): string {
26
26
  return new Date().toISOString();
@@ -11,7 +11,7 @@ import fs from "node:fs/promises";
11
11
  import path from "node:path";
12
12
  import type { JsonObject, JsonValue } from "@downcity/agent/internal/types/common/Json.js";
13
13
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
14
- import type { StoredChannelAccount } from "@downcity/agent/internal/types/runtime/host/Store.js";
14
+ import type { StoredChannelAccount } from "@downcity/agent/internal/types/platform/Store.js";
15
15
  import type {
16
16
  ChatChannelName,
17
17
  ChatChannelStateSnapshot,
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
11
- import type { StoredChannelAccount } from "@downcity/agent/internal/types/runtime/host/Store.js";
11
+ import type { StoredChannelAccount } from "@downcity/agent/internal/types/platform/Store.js";
12
12
  import type { ChatChannelName } from "@/chat/types/ChannelStatus.js";
13
13
  import type { ChatChannelState } from "@/chat/types/ChatRuntime.js";
14
14
  import { getStoredChannelAccountSync } from "@/chat/accounts/Store.js";