@downcity/agent 1.1.51 → 1.1.63

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 (126) hide show
  1. package/README.md +5 -4
  2. package/bin/agent/Agent.d.ts.map +1 -1
  3. package/bin/agent/Agent.js.map +1 -1
  4. package/bin/config/AgentInitializer.d.ts +1 -1
  5. package/bin/config/AgentInitializer.js +1 -1
  6. package/bin/config/DowncitySchema.js +1 -1
  7. package/bin/config/DowncitySchema.js.map +1 -1
  8. package/bin/config/ExecutionBinding.d.ts +1 -1
  9. package/bin/config/ExecutionBinding.js +1 -1
  10. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
  11. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +0 -4
  12. package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
  13. package/bin/executor/composer/system/default/InitPrompts.d.ts +1 -1
  14. package/bin/executor/composer/system/default/InitPrompts.js +1 -1
  15. package/bin/executor/composer/system/default/SystemDomain.js +1 -1
  16. package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
  17. package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
  18. package/bin/executor/composer/system/default/assets/plugin.prompt.d.ts +1 -1
  19. package/bin/executor/composer/system/default/assets/plugin.prompt.js +1 -1
  20. package/bin/executor/composer/system/default/assets/task.prompt.d.ts +1 -1
  21. package/bin/executor/composer/system/default/assets/task.prompt.js +1 -1
  22. package/bin/executor/messages/ChatMessageMarkupTypes.d.ts +1 -1
  23. package/bin/executor/messages/ChatMessageMarkupTypes.js +1 -1
  24. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +1 -2
  25. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
  26. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +17 -56
  27. package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
  28. package/bin/executor/tools/shell/ShellToolBridge.js +1 -1
  29. package/bin/executor/tools/shell/ShellToolBridge.js.map +1 -1
  30. package/bin/executor/tools/shell/ShellToolDefinition.d.ts +2 -2
  31. package/bin/executor/tools/shell/ShellToolFormatting.d.ts +1 -1
  32. package/bin/executor/tools/shell/ShellToolFormatting.js +7 -7
  33. package/bin/executor/tools/shell/ShellToolFormatting.js.map +1 -1
  34. package/bin/executor/tools/shell/ShellToolSchemas.d.ts +7 -75
  35. package/bin/executor/tools/shell/ShellToolSchemas.d.ts.map +1 -1
  36. package/bin/executor/types/SessionHistoryMeta.d.ts +5 -24
  37. package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
  38. package/bin/executor/types/SessionHistoryMeta.js +1 -1
  39. package/bin/index.d.ts +3 -2
  40. package/bin/index.d.ts.map +1 -1
  41. package/bin/index.js +1 -0
  42. package/bin/index.js.map +1 -1
  43. package/bin/model/CityModelAdapter.d.ts +23 -0
  44. package/bin/model/CityModelAdapter.d.ts.map +1 -0
  45. package/bin/model/CityModelAdapter.js +454 -0
  46. package/bin/model/CityModelAdapter.js.map +1 -0
  47. package/bin/runtime/host/daemon/Paths.d.ts +1 -1
  48. package/bin/runtime/host/daemon/Paths.js +1 -1
  49. package/bin/runtime/host/daemon/ProjectSetup.js +2 -2
  50. package/bin/session/Session.d.ts +1 -0
  51. package/bin/session/Session.d.ts.map +1 -1
  52. package/bin/session/Session.js +32 -6
  53. package/bin/session/Session.js.map +1 -1
  54. package/bin/session/SessionTitle.d.ts +49 -0
  55. package/bin/session/SessionTitle.d.ts.map +1 -0
  56. package/bin/session/SessionTitle.js +130 -0
  57. package/bin/session/SessionTitle.js.map +1 -0
  58. package/bin/session/browse/Browse.d.ts +2 -1
  59. package/bin/session/browse/Browse.d.ts.map +1 -1
  60. package/bin/session/browse/Browse.js +18 -15
  61. package/bin/session/browse/Browse.js.map +1 -1
  62. package/bin/session/index.d.ts +2 -1
  63. package/bin/session/index.d.ts.map +1 -1
  64. package/bin/session/index.js +2 -1
  65. package/bin/session/index.js.map +1 -1
  66. package/bin/session/storage/Metadata.d.ts +4 -0
  67. package/bin/session/storage/Metadata.d.ts.map +1 -1
  68. package/bin/session/storage/Metadata.js +12 -25
  69. package/bin/session/storage/Metadata.js.map +1 -1
  70. package/bin/session/storage/Persistence.d.ts.map +1 -1
  71. package/bin/session/storage/Persistence.js +1 -4
  72. package/bin/session/storage/Persistence.js.map +1 -1
  73. package/bin/types/agent/AgentTypes.d.ts +9 -5
  74. package/bin/types/agent/AgentTypes.d.ts.map +1 -1
  75. package/bin/types/config/AgentProject.d.ts +1 -1
  76. package/bin/types/config/DowncityConfig.d.ts +3 -3
  77. package/bin/types/config/ExecutionBinding.d.ts +4 -4
  78. package/bin/types/config/ExecutionBinding.js +1 -1
  79. package/bin/types/runtime/auth/AuthPermission.js +2 -2
  80. package/bin/types/runtime/auth/AuthPermission.js.map +1 -1
  81. package/bin/types/runtime/host/Store.d.ts +3 -177
  82. package/bin/types/runtime/host/Store.d.ts.map +1 -1
  83. package/bin/types/runtime/host/Store.js +7 -0
  84. package/bin/types/runtime/host/Store.js.map +1 -1
  85. package/bin/types/runtime/http/InlineInstant.d.ts +1 -1
  86. package/bin/types/runtime/platform/Platform.d.ts +1 -1
  87. package/package.json +19 -18
  88. package/scripts/city-model-tool-loop.test.mjs +181 -0
  89. package/src/agent/Agent.ts +3 -2
  90. package/src/config/AgentInitializer.ts +1 -1
  91. package/src/config/DowncitySchema.ts +1 -1
  92. package/src/config/ExecutionBinding.ts +1 -1
  93. package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +0 -4
  94. package/src/executor/composer/system/default/InitPrompts.ts +1 -1
  95. package/src/executor/composer/system/default/SystemDomain.ts +1 -1
  96. package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
  97. package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -1
  98. package/src/executor/composer/system/default/assets/plugin.prompt.ts +1 -1
  99. package/src/executor/composer/system/default/assets/plugin.prompt.ts.txt +18 -18
  100. package/src/executor/composer/system/default/assets/task.prompt.ts +1 -1
  101. package/src/executor/composer/system/default/assets/task.prompt.ts.txt +1 -1
  102. package/src/executor/messages/ChatMessageMarkupTypes.ts +1 -1
  103. package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +17 -57
  104. package/src/executor/tools/shell/ShellToolBridge.ts +1 -1
  105. package/src/executor/tools/shell/ShellToolFormatting.ts +7 -7
  106. package/src/executor/types/SessionHistoryMeta.ts +5 -25
  107. package/src/index.ts +5 -5
  108. package/src/model/CityModelAdapter.ts +553 -0
  109. package/src/runtime/host/daemon/Paths.ts +1 -1
  110. package/src/runtime/host/daemon/ProjectSetup.ts +2 -2
  111. package/src/session/Session.ts +40 -6
  112. package/src/session/SessionTitle.ts +192 -0
  113. package/src/session/browse/Browse.ts +22 -13
  114. package/src/session/index.ts +5 -0
  115. package/src/session/storage/Metadata.ts +14 -29
  116. package/src/session/storage/Persistence.ts +1 -4
  117. package/src/types/agent/AgentTypes.ts +10 -5
  118. package/src/types/config/AgentProject.ts +1 -1
  119. package/src/types/config/DowncityConfig.ts +3 -3
  120. package/src/types/config/ExecutionBinding.ts +4 -4
  121. package/src/types/runtime/auth/AuthPermission.ts +2 -2
  122. package/src/types/runtime/host/Store.ts +3 -182
  123. package/src/types/runtime/http/InlineInstant.ts +1 -1
  124. package/src/types/runtime/platform/Platform.ts +1 -1
  125. package/tsconfig.json +1 -0
  126. package/tsconfig.tsbuildinfo +1 -1
@@ -13,7 +13,7 @@
13
13
 
14
14
  import fs from "fs-extra";
15
15
  import { nanoid } from "nanoid";
16
- import type { LanguageModel, Tool } from "ai";
16
+ import type { Tool } from "ai";
17
17
  import type { BasePlugin } from "@/plugin/core/BasePlugin.js";
18
18
  import type {
19
19
  AgentContext,
@@ -41,6 +41,7 @@ import type {
41
41
  AgentSessionSummaryPage,
42
42
  AgentSessionSystemBlock,
43
43
  } from "@/types/agent/AgentTypes.js";
44
+ import type { AgentModel } from "@/model/CityModelAdapter.js";
44
45
  import { Logger } from "@/utils/logger/Logger.js";
45
46
  import { Session } from "@/session/Session.js";
46
47
  import { DEFAULT_SHIP_PROMPTS } from "@executor/composer/system/default/SystemDomain.js";
@@ -124,7 +125,7 @@ export class Agent {
124
125
  private readonly pluginRegistry: PluginRegistry;
125
126
  private readonly config: DowncityConfig;
126
127
  private readonly env: Record<string, string>;
127
- private readonly defaultModel?: LanguageModel;
128
+ private readonly defaultModel?: AgentModel;
128
129
  private readonly pluginInstances: Map<string, BasePlugin>;
129
130
  private readonly sessionCollection: AgentSessionCollection;
130
131
 
@@ -2,7 +2,7 @@
2
2
  * Agent 项目初始化模块。
3
3
  *
4
4
  * 职责说明(中文)
5
- * - CLI `city agent create` 与 Console 共用同一套初始化逻辑,避免模板与目录结构分叉。
5
+ * - CLI `town agent create` 与 Console 共用同一套初始化逻辑,避免模板与目录结构分叉。
6
6
  * - 负责创建项目骨架、静态 prompt、默认 `downcity.json`、基础目录与 schema 文件。
7
7
  * - 负责把用户在创建阶段提供的最小执行配置与渠道配置写入项目。
8
8
  *
@@ -51,7 +51,7 @@ export const DOWNCITY_JSON_SCHEMA: JsonObject = {
51
51
  modelId: {
52
52
  type: "string",
53
53
  description:
54
- "API 执行模式下绑定的平台全局模型 ID。",
54
+ "API 执行模式下绑定的 City AIService 模型 ID。",
55
55
  },
56
56
  },
57
57
  required: ["type", "modelId"],
@@ -7,7 +7,7 @@
7
7
  * - 让初始化、配置装配、运行时启动都复用同一套执行目标解释规则。
8
8
  *
9
9
  * 边界说明(中文)
10
- * - 这里只解析配置结构,不负责验证模型是否真实存在于平台模型池中。
10
+ * - 这里只解析配置结构,不负责验证模型是否真实存在于 City AIService 中。
11
11
  * - 当前只接受 agent 包已经落地支持的执行绑定格式。
12
12
  */
13
13
 
@@ -191,10 +191,6 @@ export async function compactSessionMessagesIfNeeded(
191
191
  await deps.writeMetaUnsafe({
192
192
  ...prevMeta,
193
193
  updatedAt: Date.now(),
194
- lastArchiveId: params.archiveOnCompact ? archiveId : undefined,
195
- keepLastMessages: Math.max(1, currentKept.length),
196
- maxInputTokensApprox: params.maxInputTokensApprox,
197
- compactRatio,
198
194
  });
199
195
  });
200
196
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * InitPrompts:`city agent create` 默认 prompt 资产加载器。
2
+ * InitPrompts:`town agent create` 默认 prompt 资产加载器。
3
3
  *
4
4
  * 职责说明(中文)
5
5
  * - 统一管理 create 生成的 `PROFILE.md` / `SOUL.md` 默认内容。
@@ -74,7 +74,7 @@ export function buildContextSystemPrompt(input: {
74
74
  const outputRules = [
75
75
  "Task-run output rules:",
76
76
  "- This is a task execution context, not an interactive chat turn.",
77
- "- Do NOT send external channel messages via `city chat send` unless explicitly required by the task itself.",
77
+ "- Do NOT send external channel messages via `town chat send` unless explicitly required by the task itself.",
78
78
  "- Reply with result-oriented content; do NOT paste raw tool outputs or JSON logs.",
79
79
  "- Keep output compact and avoid unnecessary conversational fillers.",
80
80
  ].join("\n");
@@ -4,6 +4,6 @@
4
4
  */
5
5
 
6
6
  // Source: src/executor/composer/system/default/assets/core.prompt.ts.txt
7
- const TEXT_MODULE_CONTENT = "你拥有且仅拥有当前项目 {{project_path}} 的使用权和修改权。当前年份是 {{current_year}} 年。\n1. `.downcity/` 是 Downcity 的运行时数据目录(通常不需要你手动读取/修改;系统会自动写入与注入)。结构与逻辑如下:\n - `.downcity/agents/<agentId>/sessions/` 是会话消息。\n - `.downcity/memory/` 是中长期记忆。\n - `.downcity/profile/Primary.md`、`.downcity/profile/other.md`:全局 profile 记忆;存在时会自动作为 system prompt 注入。\n - `.downcity/public/`:对外静态资源目录,通过 `GET /downcity/public/<path>` 访问;用于给外部访问的路径。不要存放敏感信息,运行中的 agent server 会把 `.downcity/public/` 暴露为 HTTP 静态资源:`GET /downcity/public/<path>`,你可以把该 URL 发给用户用于下载/查看生成的文件(注意不要暴露敏感信息)。\n - `.downcity/logs/<YYYY-MM-DD>.jsonl`:运行日志(JSONL);用于排查问题,避免把原始日志整段贴给用户。\n - `.downcity/.cache/`:幂等/去重缓存(ingress/egress);不要手动改。\n - `.downcity/.debug/`:调试产物(daemon pid/log/meta、适配器事件抓取等);仅在排查问题时查看。\n - `.downcity/data/`:小型持久化数据(预留)。\n - `.downcity/task/`:Task 目录。\n2. PROFILE.md + SOUL.md + downcity.json 是你的一些配置文件,你不需要读取。\n\n# 最重要\n【关于命令执行工具】(重要)\n- 短命令、一次性命令优先使用 `shell_exec`。\n- 长任务、需要中途查状态、需要 stdin 交互时,使用 `shell_start` / `shell_status` / `shell_read` / `shell_write` / `shell_wait` / `shell_close`。\n- 先用 `shell_start` 启动命令并拿到 `shell_id`。\n- `shell_id` 是 shell 会话标识;它不是 chat `session_id`。\n- 长任务期间,优先使用 `shell_status` 查询进度,或使用 `shell_wait` 等待状态变化;不要自己写高频空轮询循环。\n- 只有在确实需要原始增量输出时,才使用 `shell_read` 按 `from_cursor` 继续读取。\n- 需要向进程 stdin 输入内容时,使用 `shell_write`。\n- 命令会话完成后若不再需要,使用 `shell_close` 主动释放资源。\n- 不要把原始超长 shell 输出直接转发给用户,应先总结。\n\n# 默认决策与澄清\n- 默认先执行,再沟通:对低风险、可回滚、用户意图已经足够明显的请求,优先基于当前日期、时区、聊天上下文与常见默认值直接执行,不要在事件标题、默认平台、显然的时间表达上反复追问。\n- 只有当“缺失信息会实质改变结果”时才追问;例如:会影响日期/对象/金额/账户/发送目标,或会触发不可逆、高风险、涉隐私操作。\n- 处理时间表达时,优先使用当前环境提供的 `current_date`、`current_time` 与 `timezone`;如果入站 `<info>` 明确提供了 `user_timezone`,则优先按 `user_timezone` 解析,否则按 runtime clock 的 `timezone` 解析。像“今天/明天/下午两点/提前两小时”这类表达,应先解析为绝对时间,再执行,并在回复里明确写出绝对日期时间。\n- 当任务依赖外部权限、系统能力或第三方连接(如日历、提醒事项、聊天渠道、系统授权)时,先探测可用性,再决定是否承诺“我来创建/发送/写入”。\n- 如果探测结果显示被系统权限、宿主环境或连接状态阻塞,要直接说明真实阻塞点和下一步,而不是先给出“可以,我来做”的承诺后再多轮追问。\n- 若已经有足够信息可以一次完成多个低风险默认动作,应直接完成,并在结果里简短说明采用了哪些默认假设。\n\n# 很重要\n\n安全与边界\n- 不要执行破坏性命令(如 `rm -rf`、`git reset --hard`)除非用户明确要求。\n- 遇到 API Key、Token、Secret、环境变量、bot 凭据等密钥管理问题时,优先指导用户使用 Console(如 `Global / Env`、`Global / Channel Accounts`)维护,不要要求用户把密钥明文直接发送到当前聊天里。\n- `city keys` 只能列出已配置的 key 名与描述,不会返回密钥值。不要让用户把密钥“发给你自己”或继续尝试通过 `city keys` 获取明文。\n";
7
+ const TEXT_MODULE_CONTENT = "你拥有且仅拥有当前项目 {{project_path}} 的使用权和修改权。当前年份是 {{current_year}} 年。\n1. `.downcity/` 是 Downcity 的运行时数据目录(通常不需要你手动读取/修改;系统会自动写入与注入)。结构与逻辑如下:\n - `.downcity/agents/<agentId>/sessions/` 是会话消息。\n - `.downcity/memory/` 是中长期记忆。\n - `.downcity/profile/Primary.md`、`.downcity/profile/other.md`:全局 profile 记忆;存在时会自动作为 system prompt 注入。\n - `.downcity/public/`:对外静态资源目录,通过 `GET /downcity/public/<path>` 访问;用于给外部访问的路径。不要存放敏感信息,运行中的 agent server 会把 `.downcity/public/` 暴露为 HTTP 静态资源:`GET /downcity/public/<path>`,你可以把该 URL 发给用户用于下载/查看生成的文件(注意不要暴露敏感信息)。\n - `.downcity/logs/<YYYY-MM-DD>.jsonl`:运行日志(JSONL);用于排查问题,避免把原始日志整段贴给用户。\n - `.downcity/.cache/`:幂等/去重缓存(ingress/egress);不要手动改。\n - `.downcity/.debug/`:调试产物(daemon pid/log/meta、适配器事件抓取等);仅在排查问题时查看。\n - `.downcity/data/`:小型持久化数据(预留)。\n - `.downcity/task/`:Task 目录。\n2. PROFILE.md + SOUL.md + downcity.json 是你的一些配置文件,你不需要读取。\n\n# 最重要\n【关于命令执行工具】(重要)\n- 短命令、一次性命令优先使用 `shell_exec`。\n- 长任务、需要中途查状态、需要 stdin 交互时,使用 `shell_start` / `shell_status` / `shell_read` / `shell_write` / `shell_wait` / `shell_close`。\n- 先用 `shell_start` 启动命令并拿到 `shell_id`。\n- `shell_id` 是 shell 会话标识;它不是 chat `session_id`。\n- 长任务期间,优先使用 `shell_status` 查询进度,或使用 `shell_wait` 等待状态变化;不要自己写高频空轮询循环。\n- 只有在确实需要原始增量输出时,才使用 `shell_read` 按 `from_cursor` 继续读取。\n- 需要向进程 stdin 输入内容时,使用 `shell_write`。\n- 命令会话完成后若不再需要,使用 `shell_close` 主动释放资源。\n- 不要把原始超长 shell 输出直接转发给用户,应先总结。\n\n# 默认决策与澄清\n- 默认先执行,再沟通:对低风险、可回滚、用户意图已经足够明显的请求,优先基于当前日期、时区、聊天上下文与常见默认值直接执行,不要在事件标题、默认平台、显然的时间表达上反复追问。\n- 只有当“缺失信息会实质改变结果”时才追问;例如:会影响日期/对象/金额/账户/发送目标,或会触发不可逆、高风险、涉隐私操作。\n- 处理时间表达时,优先使用当前环境提供的 `current_date`、`current_time` 与 `timezone`;如果入站 `<info>` 明确提供了 `user_timezone`,则优先按 `user_timezone` 解析,否则按 runtime clock 的 `timezone` 解析。像“今天/明天/下午两点/提前两小时”这类表达,应先解析为绝对时间,再执行,并在回复里明确写出绝对日期时间。\n- 当任务依赖外部权限、系统能力或第三方连接(如日历、提醒事项、聊天渠道、系统授权)时,先探测可用性,再决定是否承诺“我来创建/发送/写入”。\n- 如果探测结果显示被系统权限、宿主环境或连接状态阻塞,要直接说明真实阻塞点和下一步,而不是先给出“可以,我来做”的承诺后再多轮追问。\n- 若已经有足够信息可以一次完成多个低风险默认动作,应直接完成,并在结果里简短说明采用了哪些默认假设。\n\n# 很重要\n\n安全与边界\n- 不要执行破坏性命令(如 `rm -rf`、`git reset --hard`)除非用户明确要求。\n- 遇到 API Key、Token、Secret、环境变量、bot 凭据等密钥管理问题时,优先指导用户使用 Console(如 `Global / Env`、`Global / Channel Accounts`)维护,不要要求用户把密钥明文直接发送到当前聊天里。\n- `town keys` 只能列出已配置的 key 名与描述,不会返回密钥值。不要让用户把密钥“发给你自己”或继续尝试通过 `town keys` 获取明文。\n";
8
8
 
9
9
  export default TEXT_MODULE_CONTENT;
@@ -36,4 +36,4 @@
36
36
  安全与边界
37
37
  - 不要执行破坏性命令(如 `rm -rf`、`git reset --hard`)除非用户明确要求。
38
38
  - 遇到 API Key、Token、Secret、环境变量、bot 凭据等密钥管理问题时,优先指导用户使用 Console(如 `Global / Env`、`Global / Channel Accounts`)维护,不要要求用户把密钥明文直接发送到当前聊天里。
39
- - `city keys` 只能列出已配置的 key 名与描述,不会返回密钥值。不要让用户把密钥“发给你自己”或继续尝试通过 `city keys` 获取明文。
39
+ - `town keys` 只能列出已配置的 key 名与描述,不会返回密钥值。不要让用户把密钥“发给你自己”或继续尝试通过 `town keys` 获取明文。
@@ -4,6 +4,6 @@
4
4
  */
5
5
 
6
6
  // Source: src/executor/composer/system/default/assets/plugin.prompt.ts.txt
7
- const TEXT_MODULE_CONTENT = "# Plugin State\n\n你正在一个基于 plugin 的执行环境中工作。\n\n## 可用命令总览\n- plugin 状态管理(统一使用 `city plugin`):\n - `city plugin list`\n - `city plugin status <pluginName>`\n - `city plugin start <pluginName>`\n - `city plugin stop <pluginName>`\n - `city plugin restart <pluginName>`\n - `city plugin command <pluginName> <command> [--payload '<json>']`\n - `city plugin schedule list`\n - `city plugin schedule info <jobId>`\n - `city plugin schedule cancel <jobId>`\n- ActionSchedule 管理命令用于查看/取消延迟执行的 plugin action,不是独立 plugin。\n- 当前内建托管 plugin:`shell` / `chat` / `task` / `memory` / `contact`。\n- 当前内建本地 plugin:`auth` / `skill` / `asr` / `tts`。\n- 模块级 action 命令:\n - `city shell <action> ...`\n - `city chat <action> ...`\n - `city task <action> ...`\n - `city memory <action> ...`\n - `city plugin action <plugin> <action> ...`\n - `city skill <action> ...`\n - `city asr <action> ...`\n - `city tts <action> ...`\n\n具体 plugin 的执行参考对应文档。\n";
7
+ const TEXT_MODULE_CONTENT = "# Plugin State\n\n你正在一个基于 plugin 的执行环境中工作。\n\n## 可用命令总览\n- plugin 状态管理(统一使用 `town plugin`):\n - `town plugin list`\n - `town plugin status <pluginName>`\n - `town plugin start <pluginName>`\n - `town plugin stop <pluginName>`\n - `town plugin restart <pluginName>`\n - `town plugin command <pluginName> <command> [--payload '<json>']`\n - `town plugin schedule list`\n - `town plugin schedule info <jobId>`\n - `town plugin schedule cancel <jobId>`\n- ActionSchedule 管理命令用于查看/取消延迟执行的 plugin action,不是独立 plugin。\n- 当前内建托管 plugin:`shell` / `chat` / `task` / `memory` / `contact`。\n- 当前内建本地 plugin:`auth` / `skill` / `asr` / `tts`。\n- 模块级 action 命令:\n - `town shell <action> ...`\n - `town chat <action> ...`\n - `town task <action> ...`\n - `town memory <action> ...`\n - `town plugin action <plugin> <action> ...`\n - `town skill <action> ...`\n - `town asr <action> ...`\n - `town tts <action> ...`\n\n具体 plugin 的执行参考对应文档。\n";
8
8
 
9
9
  export default TEXT_MODULE_CONTENT;
@@ -3,27 +3,27 @@
3
3
  你正在一个基于 plugin 的执行环境中工作。
4
4
 
5
5
  ## 可用命令总览
6
- - plugin 状态管理(统一使用 `city plugin`):
7
- - `city plugin list`
8
- - `city plugin status <pluginName>`
9
- - `city plugin start <pluginName>`
10
- - `city plugin stop <pluginName>`
11
- - `city plugin restart <pluginName>`
12
- - `city plugin command <pluginName> <command> [--payload '<json>']`
13
- - `city plugin schedule list`
14
- - `city plugin schedule info <jobId>`
15
- - `city plugin schedule cancel <jobId>`
6
+ - plugin 状态管理(统一使用 `town plugin`):
7
+ - `town plugin list`
8
+ - `town plugin status <pluginName>`
9
+ - `town plugin start <pluginName>`
10
+ - `town plugin stop <pluginName>`
11
+ - `town plugin restart <pluginName>`
12
+ - `town plugin command <pluginName> <command> [--payload '<json>']`
13
+ - `town plugin schedule list`
14
+ - `town plugin schedule info <jobId>`
15
+ - `town plugin schedule cancel <jobId>`
16
16
  - ActionSchedule 管理命令用于查看/取消延迟执行的 plugin action,不是独立 plugin。
17
17
  - 当前内建托管 plugin:`shell` / `chat` / `task` / `memory` / `contact`。
18
18
  - 当前内建本地 plugin:`auth` / `skill` / `asr` / `tts`。
19
19
  - 模块级 action 命令:
20
- - `city shell <action> ...`
21
- - `city chat <action> ...`
22
- - `city task <action> ...`
23
- - `city memory <action> ...`
24
- - `city plugin action <plugin> <action> ...`
25
- - `city skill <action> ...`
26
- - `city asr <action> ...`
27
- - `city tts <action> ...`
20
+ - `town shell <action> ...`
21
+ - `town chat <action> ...`
22
+ - `town task <action> ...`
23
+ - `town memory <action> ...`
24
+ - `town plugin action <plugin> <action> ...`
25
+ - `town skill <action> ...`
26
+ - `town asr <action> ...`
27
+ - `town tts <action> ...`
28
28
 
29
29
  具体 plugin 的执行参考对应文档。
@@ -4,6 +4,6 @@
4
4
  */
5
5
 
6
6
  // Source: src/executor/composer/system/default/assets/task.prompt.ts.txt
7
- const TEXT_MODULE_CONTENT = "你正在执行 Task 系统内部任务(非聊天会话)。\n\n运行约束(关键):\n- 当前上下文用于任务执行与审计,不是用户聊天回合。\n- 除非任务正文明确要求,否则不要调用 `city chat send` 或任何外部渠道发送动作。\n- 不要把自己当作“即时对话客服”;优先完成任务目标并输出可审计结果。\n- 允许在执行过程中产生必要的中间说明,但你**最后一条 assistant 返回**会被系统直接当作 `output.md` 与最终发送内容。\n\n输出原则:\n- 你的最后一条 assistant 返回必须是“任务交付物本身”。\n- 最后一条 assistant 返回不要包含过程汇报、状态说明、任务管理说明或发送说明。\n- 优先返回可复用、结构化、简洁的结果内容。\n- 不要回显冗长原始日志;必要时给摘要与关键结论。\n- 如任务输入要求固定格式(例如 JSON),严格遵守该格式。\n- 如果任务要求“发送到当前会话”或“发送给用户”,默认理解为:系统会把你的最后一条 assistant 返回直接回发;因此你应该直接输出那段要发给用户的正文。\n- 除非任务正文明确要求输出执行摘要,否则最后一条 assistant 返回不要输出“任务已完成”“已发送”“我先查看一下”“我来为你处理”等元话术。\n\n最后一条 assistant 返回禁止的常见内容:\n- “我来为你……”\n- “首先让我……”\n- “我看到已经有一个同名任务……”\n- “任务已发送 / 已完成 / 已更新……”\n- “任务状态总结……”\n- 任何围绕 task 管理流程的说明性文字\n\n结束前自检:\n- 在结束前检查:你准备发出的最后一条 assistant 返回,是否就是最终交付物本身。\n- 如果最后一条 assistant 返回主要是在描述执行过程、任务状态或发送情况,而不是最终交付内容本身,说明输出方向错误,必须重写。\n- 如果删掉“我来”“首先”“已发送”“任务状态”这类句子后几乎没有剩余内容,说明这不是合格的 task 输出。\n\n上下文原则:\n- 该任务上下文是独立执行上下文,不继承聊天对话目标。\n- 如与系统其他提示冲突,以“任务执行上下文规则”为准。\n";
7
+ const TEXT_MODULE_CONTENT = "你正在执行 Task 系统内部任务(非聊天会话)。\n\n运行约束(关键):\n- 当前上下文用于任务执行与审计,不是用户聊天回合。\n- 除非任务正文明确要求,否则不要调用 `town chat send` 或任何外部渠道发送动作。\n- 不要把自己当作“即时对话客服”;优先完成任务目标并输出可审计结果。\n- 允许在执行过程中产生必要的中间说明,但你**最后一条 assistant 返回**会被系统直接当作 `output.md` 与最终发送内容。\n\n输出原则:\n- 你的最后一条 assistant 返回必须是“任务交付物本身”。\n- 最后一条 assistant 返回不要包含过程汇报、状态说明、任务管理说明或发送说明。\n- 优先返回可复用、结构化、简洁的结果内容。\n- 不要回显冗长原始日志;必要时给摘要与关键结论。\n- 如任务输入要求固定格式(例如 JSON),严格遵守该格式。\n- 如果任务要求“发送到当前会话”或“发送给用户”,默认理解为:系统会把你的最后一条 assistant 返回直接回发;因此你应该直接输出那段要发给用户的正文。\n- 除非任务正文明确要求输出执行摘要,否则最后一条 assistant 返回不要输出“任务已完成”“已发送”“我先查看一下”“我来为你处理”等元话术。\n\n最后一条 assistant 返回禁止的常见内容:\n- “我来为你……”\n- “首先让我……”\n- “我看到已经有一个同名任务……”\n- “任务已发送 / 已完成 / 已更新……”\n- “任务状态总结……”\n- 任何围绕 task 管理流程的说明性文字\n\n结束前自检:\n- 在结束前检查:你准备发出的最后一条 assistant 返回,是否就是最终交付物本身。\n- 如果最后一条 assistant 返回主要是在描述执行过程、任务状态或发送情况,而不是最终交付内容本身,说明输出方向错误,必须重写。\n- 如果删掉“我来”“首先”“已发送”“任务状态”这类句子后几乎没有剩余内容,说明这不是合格的 task 输出。\n\n上下文原则:\n- 该任务上下文是独立执行上下文,不继承聊天对话目标。\n- 如与系统其他提示冲突,以“任务执行上下文规则”为准。\n";
8
8
 
9
9
  export default TEXT_MODULE_CONTENT;
@@ -2,7 +2,7 @@
2
2
 
3
3
  运行约束(关键):
4
4
  - 当前上下文用于任务执行与审计,不是用户聊天回合。
5
- - 除非任务正文明确要求,否则不要调用 `city chat send` 或任何外部渠道发送动作。
5
+ - 除非任务正文明确要求,否则不要调用 `town chat send` 或任何外部渠道发送动作。
6
6
  - 不要把自己当作“即时对话客服”;优先完成任务目标并输出可审计结果。
7
7
  - 允许在执行过程中产生必要的中间说明,但你**最后一条 assistant 返回**会被系统直接当作 `output.md` 与最终发送内容。
8
8
 
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 统一描述 chat plugin runtime 中可见的消息协议:frontmatter metadata + `<file>` 标签。
6
- * - direct 模式、`city chat send`、入站附件注入、渠道出站解析都应复用本类型。
6
+ * - direct 模式、`town chat send`、入站附件注入、渠道出站解析都应复用本类型。
7
7
  */
8
8
 
9
9
  /**
@@ -194,29 +194,9 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
194
194
  await fs.ensureFile(this.getMessagesFilePath());
195
195
  }
196
196
 
197
- private normalizePinnedSkillIds(input: string[] | undefined): string[] {
198
- if (!Array.isArray(input)) return [];
199
- const out: string[] = [];
200
- for (const raw of input) {
201
- const id = typeof raw === "string" ? raw.trim() : "";
202
- if (!id) continue;
203
- out.push(id);
204
- }
205
- return Array.from(new Set(out)).slice(0, 2000);
206
- }
207
-
208
- private normalizeSdkConfig(
209
- input: SessionHistoryMetaV1["sdkConfig"],
210
- ): SessionHistoryMetaV1["sdkConfig"] {
211
- if (!input || typeof input !== "object" || Array.isArray(input)) {
212
- return undefined;
213
- }
214
- const modelLabel =
215
- typeof input.modelLabel === "string" ? input.modelLabel.trim() : "";
216
- if (!modelLabel) return undefined;
217
- return {
218
- modelLabel,
219
- };
197
+ private normalizeText(input: unknown): string | undefined {
198
+ const value = typeof input === "string" ? input.trim() : "";
199
+ return value || undefined;
220
200
  }
221
201
 
222
202
  private async readMetaUnsafe(): Promise<SessionHistoryMetaV1> {
@@ -235,24 +215,15 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
235
215
  ...(typeof raw.createdAt === "number" && Number.isFinite(raw.createdAt)
236
216
  ? { createdAt: raw.createdAt }
237
217
  : {}),
238
- updatedAt: typeof raw.updatedAt === "number" ? raw.updatedAt : 0,
239
- pinnedSkillIds: this.normalizePinnedSkillIds(raw.pinnedSkillIds),
240
- ...(typeof raw.lastArchiveId === "string" && raw.lastArchiveId.trim()
241
- ? { lastArchiveId: raw.lastArchiveId.trim() }
242
- : {}),
243
- ...(typeof raw.keepLastMessages === "number" &&
244
- Number.isFinite(raw.keepLastMessages)
245
- ? { keepLastMessages: raw.keepLastMessages }
246
- : {}),
247
- ...(typeof raw.maxInputTokensApprox === "number" &&
248
- Number.isFinite(raw.maxInputTokensApprox)
249
- ? { maxInputTokensApprox: raw.maxInputTokensApprox }
218
+ ...(this.normalizeText(raw.timezone)
219
+ ? { timezone: this.normalizeText(raw.timezone) }
250
220
  : {}),
251
- ...(typeof raw.compactRatio === "number" && Number.isFinite(raw.compactRatio)
252
- ? { compactRatio: raw.compactRatio }
221
+ updatedAt: typeof raw.updatedAt === "number" ? raw.updatedAt : 0,
222
+ ...(this.normalizeText(raw.title)
223
+ ? { title: this.normalizeText(raw.title) }
253
224
  : {}),
254
- ...(this.normalizeSdkConfig(raw.sdkConfig)
255
- ? { sdkConfig: this.normalizeSdkConfig(raw.sdkConfig) }
225
+ ...(this.normalizeText(raw.modelLabel)
226
+ ? { modelLabel: this.normalizeText(raw.modelLabel) }
256
227
  : {}),
257
228
  };
258
229
  } catch {
@@ -261,7 +232,6 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
261
232
  sessionId: this.sessionId,
262
233
  createdAt: Date.now(),
263
234
  updatedAt: 0,
264
- pinnedSkillIds: [],
265
235
  };
266
236
  }
267
237
  }
@@ -276,26 +246,16 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
276
246
  ...(typeof next.createdAt === "number" && Number.isFinite(next.createdAt)
277
247
  ? { createdAt: next.createdAt }
278
248
  : {}),
249
+ ...(this.normalizeText(next.timezone)
250
+ ? { timezone: this.normalizeText(next.timezone) }
251
+ : {}),
279
252
  updatedAt:
280
253
  typeof next.updatedAt === "number" ? next.updatedAt : Date.now(),
281
- pinnedSkillIds: this.normalizePinnedSkillIds(next.pinnedSkillIds),
282
- ...(typeof next.lastArchiveId === "string" && next.lastArchiveId.trim()
283
- ? { lastArchiveId: next.lastArchiveId.trim() }
284
- : {}),
285
- ...(typeof next.keepLastMessages === "number" &&
286
- Number.isFinite(next.keepLastMessages)
287
- ? { keepLastMessages: next.keepLastMessages }
288
- : {}),
289
- ...(typeof next.maxInputTokensApprox === "number" &&
290
- Number.isFinite(next.maxInputTokensApprox)
291
- ? { maxInputTokensApprox: next.maxInputTokensApprox }
292
- : {}),
293
- ...(typeof next.compactRatio === "number" &&
294
- Number.isFinite(next.compactRatio)
295
- ? { compactRatio: next.compactRatio }
254
+ ...(this.normalizeText(next.title)
255
+ ? { title: this.normalizeText(next.title) }
296
256
  : {}),
297
- ...(this.normalizeSdkConfig(next.sdkConfig)
298
- ? { sdkConfig: this.normalizeSdkConfig(next.sdkConfig) }
257
+ ...(this.normalizeText(next.modelLabel)
258
+ ? { modelLabel: this.normalizeText(next.modelLabel) }
299
259
  : {}),
300
260
  };
301
261
  await fs.writeJson(this.getMetaFilePath(), normalized, { spaces: 2 });
@@ -75,7 +75,7 @@ function tryParseJsonObject(raw: string): JsonObject | null {
75
75
  function shouldEnableCommandBridge(command: string): boolean {
76
76
  const raw = String(command || "").trim();
77
77
  if (!raw) return false;
78
- return /(?:^|\s)(?:city|downcity)(?:\s|$)/i.test(raw);
78
+ return /(?:^|\s)(?:city|town)(?:\s|$)/i.test(raw);
79
79
  }
80
80
 
81
81
  async function injectUserTextMessage(params: {
@@ -33,7 +33,7 @@ function applyEnvMap(
33
33
  }
34
34
 
35
35
  /**
36
- * 对 `city chat send` 命令做前置安全校验。
36
+ * 对 `town chat send` 命令做前置安全校验。
37
37
  *
38
38
  * 关键点(中文)
39
39
  * - 历史上模型会把长文本直接拼进多行 shell 命令,导致后续行被 zsh 当作独立命令解析。
@@ -42,20 +42,20 @@ function applyEnvMap(
42
42
  */
43
43
  export function validateChatSendCommand(cmd: string): string | null {
44
44
  const source = String(cmd ?? "");
45
- if (!/\b(?:city|downcity)\s+chat\s+send\b/.test(source)) return null;
45
+ if (!/\bbay\s+chat\s+send\b/.test(source)) return null;
46
46
  if (!/[\r\n]/.test(source)) return null;
47
- if (/\b(?:city|downcity)\s+chat\s+send\b[\s\S]*\s--stdin(?:\s|$)/.test(source)) {
47
+ if (/\bbay\s+chat\s+send\b[\s\S]*\s--stdin(?:\s|$)/.test(source)) {
48
48
  return null;
49
49
  }
50
- if (/\b(?:city|downcity)\s+chat\s+send\b[\s\S]*\s--text(?:\s|$)/.test(source)) {
50
+ if (/\bbay\s+chat\s+send\b[\s\S]*\s--text(?:\s|$)/.test(source)) {
51
51
  return null;
52
52
  }
53
- if (/\b(?:city|downcity)\s+chat\s+send\b[\s\S]*\s--text-file(?:\s|$)/.test(source)) {
53
+ if (/\bbay\s+chat\s+send\b[\s\S]*\s--text-file(?:\s|$)/.test(source)) {
54
54
  return null;
55
55
  }
56
56
  return [
57
- "Unsafe `city chat send` command: real newlines are not allowed.",
58
- "If your message is multi-line, use `city chat send --stdin` (with heredoc/pipe), `--text-file`, or explicit `--text`.",
57
+ "Unsafe `town chat send` command: real newlines are not allowed.",
58
+ "If your message is multi-line, use `town chat send --stdin` (with heredoc/pipe), `--text-file`, or explicit `--text`.",
59
59
  ].join(" ");
60
60
  }
61
61
 
@@ -3,21 +3,9 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 存储位置:`.downcity/agents/<encodedAgentId>/sessions/<encodedSessionId>/messages/meta.json`
6
- * - 用于保存 compact 元数据与固定注入的 skills 信息
6
+ * - 用于保存 session 列表、详情和索引所需的轻量元信息
7
7
  */
8
8
 
9
- /**
10
- * SDK Session 配置摘要。
11
- *
12
- * 关键点(中文)
13
- * - 这里只存可稳定序列化、仅用于回显/索引的轻量配置摘要。
14
- * - 例如本地注入的 `LanguageModel` 实例本身不可序列化,因此仅记录其可读标签。
15
- */
16
- export type SessionHistorySdkConfigV1 = {
17
- /** 当前 session 绑定模型的可读标签。 */
18
- modelLabel?: string;
19
- };
20
-
21
9
  export type SessionHistoryMetaV1 = {
22
10
  /** schema 版本。 */
23
11
  v: 1;
@@ -31,16 +19,8 @@ export type SessionHistoryMetaV1 = {
31
19
  timezone?: string;
32
20
  /** 最近一次更新元信息的时间戳(ms)。 */
33
21
  updatedAt: number;
34
- /** 固定注入到 Session 上下文的 skill id 列表。 */
35
- pinnedSkillIds: string[];
36
- /** 最近一次归档生成的 archive id。 */
37
- lastArchiveId?: string;
38
- /** 最近一次 compact 生效的保留消息数。 */
39
- keepLastMessages?: number;
40
- /** 最近一次 compact 生效的输入 token 近似上限。 */
41
- maxInputTokensApprox?: number;
42
- /** 最近一次 compact 生效的前段压缩比例。 */
43
- compactRatio?: number;
44
- /** SDK 侧的轻量配置摘要。 */
45
- sdkConfig?: SessionHistorySdkConfigV1;
22
+ /** 当前 session 持久化标题。 */
23
+ title?: string;
24
+ /** 当前 session 绑定模型的可读标签。 */
25
+ modelLabel?: string;
46
26
  };
package/src/index.ts CHANGED
@@ -10,8 +10,13 @@
10
10
  // Agent 入口
11
11
  export { Agent } from "./agent/Agent.js";
12
12
  export { RemoteAgent } from "./agent/RemoteAgent.js";
13
+ export {
14
+ inferAgentModelLabel,
15
+ normalizeAgentModel,
16
+ } from "./model/CityModelAdapter.js";
13
17
  export type {
14
18
  AgentSessionCollection,
19
+ AgentModel,
15
20
  AgentSessionActor,
16
21
  AgentSession,
17
22
  AgentCreateSessionInput,
@@ -281,14 +286,9 @@ export type {
281
286
  StoredChannelAccountChannel,
282
287
  StoredEnvEntry,
283
288
  StoredGlobalEnvEntry,
284
- StoredModel,
285
- StoredModelProvider,
286
- StoredProviderMeta,
287
289
  UpsertChannelAccountInput,
288
290
  UpsertEnvEntryInput,
289
291
  UpsertGlobalEnvEntryInput,
290
- UpsertModelInput,
291
- UpsertModelProviderInput,
292
292
  } from "./types/runtime/host/Store.js";
293
293
 
294
294
  // HTTP auth 协议类型