@downcity/plugins 1.0.34 → 1.0.38

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 (77) hide show
  1. package/bin/auth/Plugin.js +2 -2
  2. package/bin/auth/Plugin.js.map +1 -1
  3. package/bin/chat/Action.js +4 -4
  4. package/bin/chat/Action.js.map +1 -1
  5. package/bin/chat/accounts/ChannelAccountManager.d.ts +3 -3
  6. package/bin/chat/accounts/ChannelAccountManager.js +6 -6
  7. package/bin/chat/accounts/ChannelAccountManager.js.map +1 -1
  8. package/bin/chat/accounts/Crypto.d.ts +1 -1
  9. package/bin/chat/accounts/Crypto.js +1 -1
  10. package/bin/chat/accounts/Store.d.ts +8 -8
  11. package/bin/chat/accounts/Store.js +13 -13
  12. package/bin/chat/accounts/Store.js.map +1 -1
  13. package/bin/chat/channels/feishu/Configuration.d.ts +1 -1
  14. package/bin/chat/channels/feishu/Configuration.js +5 -5
  15. package/bin/chat/channels/feishu/Configuration.js.map +1 -1
  16. package/bin/chat/channels/qq/Configuration.d.ts +1 -1
  17. package/bin/chat/channels/qq/Configuration.js +5 -5
  18. package/bin/chat/channels/qq/Configuration.js.map +1 -1
  19. package/bin/chat/channels/telegram/BotInfo.d.ts +1 -1
  20. package/bin/chat/channels/telegram/BotInfo.js +1 -1
  21. package/bin/chat/channels/telegram/Configuration.d.ts +1 -1
  22. package/bin/chat/channels/telegram/Configuration.js +5 -5
  23. package/bin/chat/channels/telegram/Configuration.js.map +1 -1
  24. package/bin/chat/runtime/ChatChannelCore.d.ts +1 -1
  25. package/bin/chat/runtime/ChatChannelCore.js +1 -1
  26. package/bin/chat/runtime/ChatChannelLifecycle.js +1 -1
  27. package/bin/chat/runtime/ChatChannelLifecycle.js.map +1 -1
  28. package/bin/chat/runtime/ChatPluginSystem.d.ts +2 -2
  29. package/bin/chat/runtime/ChatPluginSystem.js +1 -1
  30. package/bin/chat/runtime/ChatPromptAssets.d.ts +1 -1
  31. package/bin/chat/runtime/ChatPromptAssets.js +1 -1
  32. package/bin/chat/runtime/ChatQueueWorker.d.ts.map +1 -1
  33. package/bin/chat/runtime/ChatQueueWorker.js +12 -33
  34. package/bin/chat/runtime/ChatQueueWorker.js.map +1 -1
  35. package/bin/chat/runtime/ChatSession.d.ts.map +1 -1
  36. package/bin/chat/runtime/ChatSession.js +11 -2
  37. package/bin/chat/runtime/ChatSession.js.map +1 -1
  38. package/bin/chat/runtime/SystemPrompt.js +2 -2
  39. package/bin/chat/runtime/SystemPrompt.js.map +1 -1
  40. package/bin/chat/types/BotInfo.d.ts +2 -2
  41. package/bin/chat/types/BotInfo.js +1 -1
  42. package/bin/chat/types/ChannelAccount.d.ts +12 -12
  43. package/bin/chat/types/ChannelAccount.js +2 -2
  44. package/bin/chat/types/ChannelConfiguration.d.ts +2 -2
  45. package/bin/chat/types/FeishuPost.d.ts +1 -1
  46. package/bin/chat/types/FeishuPost.js +1 -1
  47. package/bin/shell/runtime/ShellRuntimeEnvironment.js +4 -4
  48. package/bin/shell/runtime/ShellRuntimeEnvironment.js.map +1 -1
  49. package/bin/skill/runtime/SystemProvider.js +3 -3
  50. package/bin/skill/runtime/SystemProvider.js.map +1 -1
  51. package/bin/task/runtime/TaskRunnerRound.d.ts.map +1 -1
  52. package/bin/task/runtime/TaskRunnerRound.js +13 -2
  53. package/bin/task/runtime/TaskRunnerRound.js.map +1 -1
  54. package/package.json +2 -2
  55. package/src/auth/Plugin.ts +2 -2
  56. package/src/chat/Action.ts +4 -4
  57. package/src/chat/accounts/ChannelAccountManager.ts +6 -6
  58. package/src/chat/accounts/Crypto.ts +1 -1
  59. package/src/chat/accounts/Store.ts +13 -13
  60. package/src/chat/channels/feishu/Configuration.ts +5 -5
  61. package/src/chat/channels/qq/Configuration.ts +5 -5
  62. package/src/chat/channels/telegram/BotInfo.ts +1 -1
  63. package/src/chat/channels/telegram/Configuration.ts +5 -5
  64. package/src/chat/runtime/ChatChannelCore.ts +1 -1
  65. package/src/chat/runtime/ChatChannelLifecycle.ts +1 -1
  66. package/src/chat/runtime/ChatPluginSystem.ts +2 -2
  67. package/src/chat/runtime/ChatPromptAssets.ts +1 -1
  68. package/src/chat/runtime/ChatQueueWorker.ts +12 -39
  69. package/src/chat/runtime/ChatSession.ts +12 -2
  70. package/src/chat/runtime/SystemPrompt.ts +2 -2
  71. package/src/chat/types/BotInfo.ts +2 -2
  72. package/src/chat/types/ChannelAccount.ts +12 -12
  73. package/src/chat/types/ChannelConfiguration.ts +2 -3
  74. package/src/chat/types/FeishuPost.ts +1 -1
  75. package/src/shell/runtime/ShellRuntimeEnvironment.ts +4 -4
  76. package/src/skill/runtime/SystemProvider.ts +3 -3
  77. package/src/task/runtime/TaskRunnerRound.ts +15 -2
@@ -76,9 +76,9 @@ function toSnapshotData(snapshot: ChatAuthorizationSnapshot): JsonValue {
76
76
  function createChatAuthorizationPluginDefinition(): Plugin {
77
77
  return {
78
78
  name: CHAT_AUTHORIZATION_PLUGIN_NAME,
79
- title: "Chat Authorization",
79
+ title: "Chat Access",
80
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.",
81
+ "Controls who can talk to the agent through chat platforms, records observed users and chats, and resolves each user's effective role for downstream service decisions.",
82
82
  availability() {
83
83
  return {
84
84
  enabled: true,
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
10
- import { getSessionRunScope } from "@downcity/agent/internal/executor/SessionRunScope.js";
10
+ import { getSessionRunContext } from "@downcity/agent/internal/executor/SessionRunScope.js";
11
11
  import {
12
12
  sendActionByChatKey,
13
13
  sendTextByChatKey,
@@ -59,13 +59,13 @@ export function resolveChatSessionSnapshot(input?: {
59
59
  chatKey?: string;
60
60
  context?: AgentContext;
61
61
  }): ChatSessionSnapshot {
62
- const requestCtx = getSessionRunScope();
62
+ const run_context = getSessionRunContext();
63
63
 
64
64
  const explicitSessionId = String(input?.sessionId || "").trim();
65
65
  const explicitChatKey = String(input?.chatKey || "").trim();
66
66
  const requestSessionId =
67
- typeof requestCtx?.sessionId === "string" && requestCtx.sessionId.trim()
68
- ? requestCtx.sessionId.trim()
67
+ typeof run_context?.sessionId === "string" && run_context.sessionId.trim()
68
+ ? run_context.sessionId.trim()
69
69
  : undefined;
70
70
  const envSessionId = readEnvString("DC_SESSION_ID");
71
71
  const envChatKey = readEnvString("DC_CTX_CHAT_KEY");
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Chat channel account 管理器。
2
+ * Chat account 管理器。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 统一封装 agent 运行时下 chat channel account 的 CRUD 与探测。
5
+ * - 统一封装 agent 运行时下 chat account 的 CRUD 与探测。
6
6
  * - 账号凭据只在写入路径接收明文;列表与读取路径返回脱敏结果。
7
7
  * - city / vibecape 等上层产品都应直接复用这个实现,而不是各自维护副本。
8
8
  */
@@ -80,7 +80,7 @@ export class ChatChannelAccountManager {
80
80
  constructor() {}
81
81
 
82
82
  /**
83
- * 生成唯一 channel account id。
83
+ * 生成唯一 chat account id。
84
84
  *
85
85
  * 关键点(中文)
86
86
  * - 账号 id 统一由系统生成,避免用户手填导致冲突或命名不一致。
@@ -222,9 +222,9 @@ export class ChatChannelAccountManager {
222
222
  */
223
223
  async upsert(input: ChatChannelAccountUpsertInput): Promise<{ id: string }> {
224
224
  const id = String(input.id || "").trim();
225
- if (!id) throw new Error("channel account id cannot be empty");
225
+ if (!id) throw new Error("chat account id cannot be empty");
226
226
  const name = String(input.name || "").trim();
227
- if (!name) throw new Error("channel account name cannot be empty");
227
+ if (!name) throw new Error("chat account name cannot be empty");
228
228
 
229
229
  const channel = normalizeChannelAccountChannel(input.channel);
230
230
 
@@ -285,7 +285,7 @@ export class ChatChannelAccountManager {
285
285
  */
286
286
  async remove(idInput: string): Promise<void> {
287
287
  const id = String(idInput || "").trim();
288
- if (!id) throw new Error("channel account id cannot be empty");
288
+ if (!id) throw new Error("chat account id cannot be empty");
289
289
  await removeStoredChannelAccount(id);
290
290
  }
291
291
  }
@@ -2,7 +2,7 @@
2
2
  * Channel account 默认存储加密工具。
3
3
  *
4
4
  * 职责说明(中文)
5
- * - 负责默认 channel account 存储中的敏感字段加解密。
5
+ * - 负责默认 chat account 存储中的敏感字段加解密。
6
6
  * - 默认复用平台级 `model-db.key`,保证和现有 `~/.downcity/downcity.db` 数据兼容。
7
7
  *
8
8
  * 边界说明(中文)
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Channel account 默认存储实现。
2
+ * Chat account 默认存储实现。
3
3
  *
4
4
  * 职责说明(中文)
5
- * - 提供 `chat` plugin 默认使用的全局 channel account 读写能力。
5
+ * - 提供 `chat` plugin 默认使用的全局 chat account 读写能力。
6
6
  * - 默认直接操作 `~/.downcity/downcity.db` 里的 `channel_accounts` 表。
7
7
  * - 对 `city` 而言,这里也是统一的默认账号池实现来源。
8
8
  *
9
9
  * 边界说明(中文)
10
- * - 这里只负责 channel account 这一个表,不扩展成通用平台数据库门面。
10
+ * - 这里只负责 chat account 这一个表,不扩展成通用平台数据库门面。
11
11
  * - 模型池、env、其他平台级配置仍由各自模块独立管理。
12
12
  */
13
13
 
@@ -40,7 +40,7 @@ function optionalTrimmedText(value: string | undefined): string | undefined {
40
40
  }
41
41
 
42
42
  /**
43
- * 规范化 channel 类型。
43
+ * 规范化 chat platform 类型。
44
44
  */
45
45
  export function normalizeChannelAccountChannel(
46
46
  input: string,
@@ -49,7 +49,7 @@ export function normalizeChannelAccountChannel(
49
49
  if (channel === "telegram" || channel === "feishu" || channel === "qq") {
50
50
  return channel;
51
51
  }
52
- throw new Error(`Unsupported channel account type: ${input}`);
52
+ throw new Error(`Unsupported chat account platform: ${input}`);
53
53
  }
54
54
 
55
55
  function ensureChannelAccountSchema(database: Database.Database): void {
@@ -138,7 +138,7 @@ function buildChannelAccountFromRow(
138
138
  }
139
139
 
140
140
  /**
141
- * 同步列出全部 channel account。
141
+ * 同步列出全部 chat account。
142
142
  */
143
143
  export function listStoredChannelAccountsSync(
144
144
  channelInput?: string,
@@ -178,12 +178,12 @@ export function listStoredChannelAccountsSync(
178
178
  }
179
179
 
180
180
  /**
181
- * 同步按 ID 读取单个 channel account。
181
+ * 同步按 ID 读取单个 chat account。
182
182
  */
183
183
  export function getStoredChannelAccountSync(
184
184
  accountIdInput: string,
185
185
  ): StoredChannelAccount | null {
186
- const accountId = normalizeNonEmptyText(accountIdInput, "channel account id");
186
+ const accountId = normalizeNonEmptyText(accountIdInput, "chat account id");
187
187
  return withChannelAccountDb((database) => {
188
188
  const row = database.prepare(
189
189
  `
@@ -201,7 +201,7 @@ export function getStoredChannelAccountSync(
201
201
  }
202
202
 
203
203
  /**
204
- * 新增或更新 channel account。
204
+ * 新增或更新 chat account。
205
205
  *
206
206
  * 关键点(中文)
207
207
  * - 这里保留和现有平台库一致的落盘结构,避免默认实现切换后出现数据断层。
@@ -210,9 +210,9 @@ export function getStoredChannelAccountSync(
210
210
  export async function upsertStoredChannelAccount(
211
211
  input: UpsertChannelAccountInput,
212
212
  ): Promise<void> {
213
- const id = normalizeNonEmptyText(input.id, "channel account id");
213
+ const id = normalizeNonEmptyText(input.id, "chat account id");
214
214
  const channel = normalizeChannelAccountChannel(input.channel);
215
- const name = normalizeNonEmptyText(input.name, "channel account name");
215
+ const name = normalizeNonEmptyText(input.name, "chat account name");
216
216
  const existing = getStoredChannelAccountSync(id);
217
217
  const createdAt = existing?.createdAt || nowIso();
218
218
  const updatedAt = nowIso();
@@ -275,12 +275,12 @@ export async function upsertStoredChannelAccount(
275
275
  }
276
276
 
277
277
  /**
278
- * 删除单个 channel account。
278
+ * 删除单个 chat account。
279
279
  */
280
280
  export async function removeStoredChannelAccount(
281
281
  accountIdInput: string,
282
282
  ): Promise<void> {
283
- const accountId = normalizeNonEmptyText(accountIdInput, "channel account id");
283
+ const accountId = normalizeNonEmptyText(accountIdInput, "chat account id");
284
284
  withChannelAccountDb((database) => {
285
285
  database.prepare("DELETE FROM channel_accounts WHERE id = ?;").run(accountId);
286
286
  });
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - ship 层只保留绑定字段。
6
- * - appId/appSecret/domain 由 channel account 维护。
6
+ * - appId/appSecret/domain 由 chat account 维护。
7
7
  */
8
8
 
9
9
  import { ChatChannelConfiguration } from "@/chat/channels/Configuration.js";
@@ -18,9 +18,9 @@ export class FeishuChannelConfiguration extends ChatChannelConfiguration {
18
18
  describe(): ChatChannelConfigurationDescriptor {
19
19
  return {
20
20
  channel: this.channel,
21
- title: "Feishu Channel Configuration",
21
+ title: "Feishu Chat Platform Configuration",
22
22
  description:
23
- "Bind a Feishu/Lark channel account and control runtime enable/disable state.",
23
+ "Bind a Feishu/Lark chat account and control runtime enable/disable state.",
24
24
  version: "1.0.0",
25
25
  capabilities: {
26
26
  canToggleEnabled: true,
@@ -45,9 +45,9 @@ export class FeishuChannelConfiguration extends ChatChannelConfiguration {
45
45
  },
46
46
  {
47
47
  key: "channelAccountId",
48
- label: "Channel Account ID",
48
+ label: "Chat Account ID",
49
49
  description:
50
- "Bind channel to a channel account row in ~/.downcity/downcity.db channel_accounts.",
50
+ "Bind this chat platform to a chat account row in ~/.downcity/downcity.db channel_accounts.",
51
51
  type: "string",
52
52
  source: "ship_json",
53
53
  required: false,
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - ship 层只保留 `enabled` 与 `channelAccountId`。
6
- * - QQ 专属参数(sandbox 等)在 channel account 中维护。
6
+ * - QQ 专属参数(sandbox 等)在 chat account 中维护。
7
7
  */
8
8
 
9
9
  import { ChatChannelConfiguration } from "@/chat/channels/Configuration.js";
@@ -18,9 +18,9 @@ export class QqChannelConfiguration extends ChatChannelConfiguration {
18
18
  describe(): ChatChannelConfigurationDescriptor {
19
19
  return {
20
20
  channel: this.channel,
21
- title: "QQ Channel Configuration",
21
+ title: "QQ Chat Platform Configuration",
22
22
  description:
23
- "Bind a QQ channel account and control runtime enable/disable state.",
23
+ "Bind a QQ chat account and control runtime enable/disable state.",
24
24
  version: "1.0.0",
25
25
  capabilities: {
26
26
  canToggleEnabled: true,
@@ -44,9 +44,9 @@ export class QqChannelConfiguration extends ChatChannelConfiguration {
44
44
  },
45
45
  {
46
46
  key: "channelAccountId",
47
- label: "Channel Account ID",
47
+ label: "Chat Account ID",
48
48
  description:
49
- "Bind channel to a channel account row in ~/.downcity/downcity.db channel_accounts.",
49
+ "Bind this chat platform to a chat account row in ~/.downcity/downcity.db channel_accounts.",
50
50
  type: "string",
51
51
  source: "ship_json",
52
52
  required: false,
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 基于 `getMe` 接口验证 token 有效性。
6
- * - 返回统一结构,供 channel account 创建流程复用。
6
+ * - 返回统一结构,供 chat account 创建流程复用。
7
7
  */
8
8
 
9
9
  import type {
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - ship 层只绑定 `enabled` 与 `channelAccountId`。
6
- * - 真实密钥由 channel account 统一托管。
6
+ * - 真实密钥由 chat account 统一托管。
7
7
  */
8
8
 
9
9
  import { ChatChannelConfiguration } from "@/chat/channels/Configuration.js";
@@ -18,9 +18,9 @@ export class TelegramChannelConfiguration extends ChatChannelConfiguration {
18
18
  describe(): ChatChannelConfigurationDescriptor {
19
19
  return {
20
20
  channel: this.channel,
21
- title: "Telegram Channel Configuration",
21
+ title: "Telegram Chat Platform Configuration",
22
22
  description:
23
- "Bind a Telegram channel account and control runtime enable/disable state.",
23
+ "Bind a Telegram chat account and control runtime enable/disable state.",
24
24
  version: "1.0.0",
25
25
  capabilities: {
26
26
  canToggleEnabled: true,
@@ -45,9 +45,9 @@ export class TelegramChannelConfiguration extends ChatChannelConfiguration {
45
45
  },
46
46
  {
47
47
  key: "channelAccountId",
48
- label: "Channel Account ID",
48
+ label: "Chat Account ID",
49
49
  description:
50
- "Bind channel to a channel account row in ~/.downcity/downcity.db channel_accounts.",
50
+ "Bind this chat platform to a chat account row in ~/.downcity/downcity.db channel_accounts.",
51
51
  type: "string",
52
52
  source: "ship_json",
53
53
  required: false,
@@ -4,7 +4,7 @@
4
4
  * 关键点(中文)
5
5
  * - 这里只放最基础的渠道状态/名称/account 解析能力。
6
6
  * - 生命周期、配置写入、action 执行分别放到更细的模块中。
7
- * - 目标是让 chat channel 子模块共享同一套最小公共基元。
7
+ * - 目标是让 chat platform 子模块共享同一套最小公共基元。
8
8
  */
9
9
 
10
10
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
@@ -69,7 +69,7 @@ async function startQQChannel(
69
69
  context: AgentContext,
70
70
  ): Promise<void> {
71
71
  if (!isChatChannelEnabled(context, "qq")) return;
72
- context.logger.info("QQ channel enabled");
72
+ context.logger.info("QQ chat platform enabled");
73
73
  const account = resolveChannelAccount(context, "qq");
74
74
  const appId = String(account?.appId || "").trim();
75
75
  const appSecret = String(account?.appSecret || "").trim();
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - chat plugin prompt 与 channel prompt 都属于静态资产。
6
- * - 当前请求只注入当前 channel 的 prompt,避免平台规则串味。
6
+ * - 当前请求只注入当前 chat platform 的 prompt,避免平台规则串味。
7
7
  * - 该模块只负责 prompt 解析与拼装,不承担运行态控制职责。
8
8
  */
9
9
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
@@ -38,7 +38,7 @@ function resolveCurrentChatPromptChannel(
38
38
  *
39
39
  * 关键点(中文)
40
40
  * - 仅注入当前 context 对应的 channel prompt,避免把其他平台规则混入本轮会话。
41
- * - 若当前 context 不是 chat channel(如 consoleui)或尚无路由元信息,则不注入 channel prompt。
41
+ * - 若当前 context 不是 chat platform(如 Console UI)或尚无路由元信息,则不注入 platform prompt。
42
42
  */
43
43
  export async function buildCurrentChannelPrompts(
44
44
  context: AgentContext,
@@ -22,7 +22,7 @@ export const CHAT_PLUGIN_PROMPT = chatPluginPromptText.trim();
22
22
  export const FEISHU_CHAT_CHANNEL_PROMPT = feishuChatPromptText.trim();
23
23
 
24
24
  /**
25
- * QQ channel prompt。
25
+ * QQ chat platform prompt。
26
26
  */
27
27
  export const QQ_CHAT_CHANNEL_PROMPT = qqChatPromptText.trim();
28
28
 
@@ -44,7 +44,6 @@ type TurnObservation = {
44
44
  turnId: string;
45
45
  sessionId: string;
46
46
  messageId?: string;
47
- assistantStepDispatched: boolean;
48
47
  typing: { stop: () => void };
49
48
  };
50
49
 
@@ -342,13 +341,18 @@ export class ChatQueueWorker {
342
341
  if (event.visibility === "internal") return;
343
342
  const stepText = String(event.text || "").trim();
344
343
  if (!stepText) return;
345
- const dispatched = await this.dispatchAssistantStepMessage({
346
- sessionId: observation.sessionId,
347
- text: stepText,
348
- messageId: observation.messageId,
349
- });
350
- if (dispatched) {
351
- observation.assistantStepDispatched = true;
344
+
345
+ try {
346
+ await this.dispatchAssistantStepMessage({
347
+ sessionId: observation.sessionId,
348
+ text: stepText,
349
+ messageId: observation.messageId,
350
+ });
351
+ } catch (error) {
352
+ this.logger.warn("ChatQueueWorker assistant step dispatch failed", {
353
+ sessionId: observation.sessionId,
354
+ error: String(error),
355
+ });
352
356
  }
353
357
  }
354
358
 
@@ -369,7 +373,6 @@ export class ChatQueueWorker {
369
373
  turnId: turn.id,
370
374
  sessionId: item.sessionId,
371
375
  messageId: item.messageId,
372
- assistantStepDispatched: false,
373
376
  typing: this.startTypingHeartbeat(item),
374
377
  };
375
378
  params.lane.turnObservers.set(turn.id, observation);
@@ -437,36 +440,6 @@ export class ChatQueueWorker {
437
440
  });
438
441
  return;
439
442
  }
440
-
441
- if (observation.assistantStepDispatched) {
442
- return;
443
- }
444
-
445
- const finalAssistantText =
446
- pickLastSuccessfulChatSendText(result.assistantMessage) || result.text;
447
- if (!finalAssistantText) {
448
- return;
449
- }
450
-
451
- const dispatchedDirectly = await dispatchAssistantTextDirect({
452
- logger: this.logger,
453
- context: this.context,
454
- sessionId: observation.sessionId,
455
- assistantText: finalAssistantText,
456
- phase: "final",
457
- });
458
- if (dispatchedDirectly) {
459
- return;
460
- }
461
-
462
- await dispatchTextToChannel({
463
- logger: this.logger,
464
- context: this.context,
465
- sessionId: observation.sessionId,
466
- text: finalAssistantText,
467
- messageId: observation.messageId,
468
- phase: "final",
469
- });
470
443
  }
471
444
 
472
445
  /**
@@ -17,6 +17,7 @@ import type { ChatSessionContextComposer } from "@/chat/runtime/ChatSessionConte
17
17
  import type { Logger } from "@downcity/agent/internal/utils/logger/Logger.js";
18
18
  import type { SessionAssistantStepCallback } from "@downcity/agent/internal/executor/types/SessionRun.js";
19
19
  import type { SessionRunResult } from "@downcity/agent/internal/executor/types/SessionRun.js";
20
+ import type { SessionRunContext } from "@downcity/agent/internal/types/executor/SessionRunContext.js";
20
21
  import type { ChatSessionTurnState } from "@/chat/runtime/ChatSessionTypes.js";
21
22
 
22
23
  type ChatSessionOptions = {
@@ -144,10 +145,19 @@ export class ChatSession extends Executor {
144
145
  : {}),
145
146
  };
146
147
  try {
148
+ const run_context: SessionRunContext = {
149
+ sessionId: this.sessionId,
150
+ ...(typeof params.onStepCallback === "function"
151
+ ? { onStepCallback: params.onStepCallback }
152
+ : {}),
153
+ onAssistantStepCallback: this.forwardAssistantStep,
154
+ injectedUserMessages: [],
155
+ deferredPersistedUserMessages: [],
156
+ pendingAssistantFileParts: [],
157
+ };
147
158
  return await super.run({
148
159
  query: params.query,
149
- onStepCallback: params.onStepCallback,
150
- onAssistantStepCallback: this.forwardAssistantStep,
160
+ runContext: run_context,
151
161
  });
152
162
  } finally {
153
163
  this.activeTurnState = null;
@@ -7,7 +7,7 @@
7
7
  * - 统一从 request context + ChatMetaStore 读取当前 chat 元信息。
8
8
  */
9
9
 
10
- import { getSessionRunScope } from "@downcity/agent/internal/executor/SessionRunScope.js";
10
+ import { getSessionRunContext } from "@downcity/agent/internal/executor/SessionRunScope.js";
11
11
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
12
12
  import type { ChatEnvironmentPromptInput } from "@/chat/types/ChatPromptContext.js";
13
13
  import { readChatMetaBySessionId } from "@/chat/runtime/ChatMetaStore.js";
@@ -26,7 +26,7 @@ function normalizePromptValue(value: unknown, fallback: string): string {
26
26
  export async function resolveCurrentChatEnvironmentPromptInput(
27
27
  context: AgentContext,
28
28
  ): Promise<ChatEnvironmentPromptInput | null> {
29
- const sessionId = String(getSessionRunScope()?.sessionId || "").trim();
29
+ const sessionId = String(getSessionRunContext()?.sessionId || "").trim();
30
30
  if (!sessionId) return null;
31
31
 
32
32
  const meta = await readChatMetaBySessionId({
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 将“凭据 -> bot 基础信息”的探测输入输出结构标准化。
6
- * - Console、Channel Account 存储、后续自动化流程都复用该结构。
6
+ * - Console、Chat Account 存储、后续自动化流程都复用该结构。
7
7
  */
8
8
 
9
9
  import type { ChatChannelName } from "@/chat/types/ChannelStatus.js";
@@ -77,7 +77,7 @@ export interface ChatBotInfoResult {
77
77
  */
78
78
  botUserId?: string;
79
79
  /**
80
- * 建议用于生成 channel account id 的稳定种子。
80
+ * 建议用于生成 chat account id 的稳定种子。
81
81
  */
82
82
  idSeed?: string;
83
83
  /**
@@ -1,24 +1,24 @@
1
1
  /**
2
- * Chat channel account 管理类型。
2
+ * Chat account 管理类型。
3
3
  *
4
4
  * 关键点(中文)
5
- * - 这些类型描述 agent 运行时内部的 chat channel account 管理输入输出。
5
+ * - 这些类型描述 agent 运行时内部的 chat account 管理输入输出。
6
6
  * - 凭据明文只允许出现在写入输入中,读取结果必须是脱敏后的安全视图。
7
7
  */
8
8
 
9
9
  import type { StoredChannelAccountChannel } from "@downcity/agent/internal/types/platform/Store.js";
10
10
 
11
11
  /**
12
- * 支持的 chat channel account 类型。
12
+ * 支持的 chat account 平台类型。
13
13
  */
14
14
  export type ChatChannelAccountChannel = StoredChannelAccountChannel;
15
15
 
16
16
  /**
17
- * Channel account 探测结果。
17
+ * Chat account 探测结果。
18
18
  */
19
19
  export interface ChatChannelAccountProbeResult {
20
20
  /**
21
- * 账号所属 chat channel
21
+ * 账号所属 chat platform
22
22
  */
23
23
  channel: ChatChannelAccountChannel;
24
24
  /**
@@ -52,7 +52,7 @@ export interface ChatChannelAccountProbeResult {
52
52
  }
53
53
 
54
54
  /**
55
- * Channel account 列表中的安全视图。
55
+ * Chat account 列表中的安全视图。
56
56
  */
57
57
  export interface ChatChannelAccountListItem {
58
58
  /**
@@ -60,7 +60,7 @@ export interface ChatChannelAccountListItem {
60
60
  */
61
61
  id: string;
62
62
  /**
63
- * 账号所属 chat channel
63
+ * 账号所属 chat platform
64
64
  */
65
65
  channel: ChatChannelAccountChannel;
66
66
  /**
@@ -122,7 +122,7 @@ export interface ChatChannelAccountListItem {
122
122
  }
123
123
 
124
124
  /**
125
- * Channel account 列表结果。
125
+ * Chat account 列表结果。
126
126
  */
127
127
  export interface ChatChannelAccountListResult {
128
128
  /**
@@ -132,7 +132,7 @@ export interface ChatChannelAccountListResult {
132
132
  }
133
133
 
134
134
  /**
135
- * Channel account 写入输入。
135
+ * Chat account 写入输入。
136
136
  */
137
137
  export interface ChatChannelAccountUpsertInput {
138
138
  /**
@@ -140,7 +140,7 @@ export interface ChatChannelAccountUpsertInput {
140
140
  */
141
141
  id: string;
142
142
  /**
143
- * 账号所属 chat channel
143
+ * 账号所属 chat platform
144
144
  */
145
145
  channel: string;
146
146
  /**
@@ -194,11 +194,11 @@ export interface ChatChannelAccountUpsertInput {
194
194
  }
195
195
 
196
196
  /**
197
- * Channel account 凭据创建输入。
197
+ * Chat account 凭据创建输入。
198
198
  */
199
199
  export interface ChatChannelAccountCreateInput {
200
200
  /**
201
- * 账号所属 chat channel
201
+ * 账号所属 chat platform
202
202
  */
203
203
  channel: string;
204
204
  /**
@@ -70,7 +70,7 @@ export interface ChatChannelConfigurationField {
70
70
  */
71
71
  type: ChatChannelConfigurationFieldType;
72
72
  /**
73
- * 字段值来源(downcity.json / channel account / env fallback)。
73
+ * 字段值来源(downcity.json / chat account / env fallback)。
74
74
  */
75
75
  source: ChatChannelConfigurationFieldSource;
76
76
  /**
@@ -132,7 +132,7 @@ export interface ChatChannelConfigurationDescriptor {
132
132
  */
133
133
  canToggleEnabled: boolean;
134
134
  /**
135
- * 是否支持 channel account 绑定。
135
+ * 是否支持 chat account 绑定。
136
136
  */
137
137
  canBindChannelAccount: boolean;
138
138
  /**
@@ -158,4 +158,3 @@ export interface ChatChannelConfigurationDescriptor {
158
158
  envFallback: ChatChannelConfigurationField[];
159
159
  };
160
160
  }
161
-
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 统一描述飞书 `msg_type=post` 的核心结构,供入站解析与出站构建复用。
6
- * - 这里只保留当前 chat channel 真正会消费的字段,避免把平台超大 schema 整体引入运行时。
6
+ * - 这里只保留当前 chat platform 真正会消费的字段,避免把平台超大 schema 整体引入运行时。
7
7
  */
8
8
 
9
9
  /**
@@ -8,7 +8,7 @@
8
8
 
9
9
  import path from "node:path";
10
10
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
11
- import { getSessionRunScope } from "@downcity/agent/internal/executor/SessionRunScope.js";
11
+ import { getSessionRunContext } from "@downcity/agent/internal/executor/SessionRunScope.js";
12
12
 
13
13
  function stripShellSecretEnv(env: NodeJS.ProcessEnv): void {
14
14
  delete env.DC_AUTH_TOKEN;
@@ -31,8 +31,8 @@ export function buildShellEnv(context: AgentContext): NodeJS.ProcessEnv {
31
31
  env[normalizedKey] = normalizedValue;
32
32
  }
33
33
 
34
- const request = getSessionRunScope();
35
- const sessionId = String(request?.sessionId || "").trim();
34
+ const run_context = getSessionRunContext();
35
+ const sessionId = String(run_context?.sessionId || "").trim();
36
36
  const agentPath = String(context.rootPath || "").trim();
37
37
  const configuredAgentId = String(context.config?.id || "").trim();
38
38
  const agentId = configuredAgentId || (agentPath ? path.basename(agentPath) : "");
@@ -66,6 +66,6 @@ export function resolveShellCwd(context: AgentContext, cwd?: string): string {
66
66
  export function resolveOwnerContextId(explicit?: string): string | undefined {
67
67
  const fromInput = String(explicit || "").trim();
68
68
  if (fromInput) return fromInput;
69
- const fromRequest = String(getSessionRunScope()?.sessionId || "").trim();
69
+ const fromRequest = String(getSessionRunContext()?.sessionId || "").trim();
70
70
  return fromRequest || undefined;
71
71
  }
@@ -7,7 +7,7 @@
7
7
  * - `lookup` 行为为无状态:由 action 读取 SKILL.md 后通过协议注入 user message
8
8
  */
9
9
 
10
- import { getSessionRunScope } from "@downcity/agent/internal/executor/SessionRunScope.js";
10
+ import { getSessionRunContext } from "@downcity/agent/internal/executor/SessionRunScope.js";
11
11
  import type { DowncityConfig } from "@downcity/agent/internal/types/config/DowncityConfig.js";
12
12
  import { discoverClaudeSkillsSync } from "./Discovery.js";
13
13
  import { renderClaudeSkillsPromptSection } from "./Prompt.js";
@@ -19,8 +19,8 @@ type SkillSystemRuntime = {
19
19
  };
20
20
 
21
21
  function getCurrentSessionId(): string {
22
- const request = getSessionRunScope();
23
- return String(request?.sessionId || "").trim();
22
+ const run_context = getSessionRunContext();
23
+ return String(run_context?.sessionId || "").trim();
24
24
  }
25
25
 
26
26
  /**