@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.
- package/README.md +5 -4
- package/bin/agent/Agent.d.ts.map +1 -1
- package/bin/agent/Agent.js.map +1 -1
- package/bin/config/AgentInitializer.d.ts +1 -1
- package/bin/config/AgentInitializer.js +1 -1
- package/bin/config/DowncitySchema.js +1 -1
- package/bin/config/DowncitySchema.js.map +1 -1
- package/bin/config/ExecutionBinding.d.ts +1 -1
- package/bin/config/ExecutionBinding.js +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.d.ts.map +1 -1
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js +0 -4
- package/bin/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.js.map +1 -1
- package/bin/executor/composer/system/default/InitPrompts.d.ts +1 -1
- package/bin/executor/composer/system/default/InitPrompts.js +1 -1
- package/bin/executor/composer/system/default/SystemDomain.js +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.js +1 -1
- package/bin/executor/composer/system/default/assets/task.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/task.prompt.js +1 -1
- package/bin/executor/messages/ChatMessageMarkupTypes.d.ts +1 -1
- package/bin/executor/messages/ChatMessageMarkupTypes.js +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts +1 -2
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.d.ts.map +1 -1
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js +17 -56
- package/bin/executor/store/history/jsonl/JsonlSessionHistoryStore.js.map +1 -1
- package/bin/executor/tools/shell/ShellToolBridge.js +1 -1
- package/bin/executor/tools/shell/ShellToolBridge.js.map +1 -1
- package/bin/executor/tools/shell/ShellToolDefinition.d.ts +2 -2
- package/bin/executor/tools/shell/ShellToolFormatting.d.ts +1 -1
- package/bin/executor/tools/shell/ShellToolFormatting.js +7 -7
- package/bin/executor/tools/shell/ShellToolFormatting.js.map +1 -1
- package/bin/executor/tools/shell/ShellToolSchemas.d.ts +7 -75
- package/bin/executor/tools/shell/ShellToolSchemas.d.ts.map +1 -1
- package/bin/executor/types/SessionHistoryMeta.d.ts +5 -24
- package/bin/executor/types/SessionHistoryMeta.d.ts.map +1 -1
- package/bin/executor/types/SessionHistoryMeta.js +1 -1
- package/bin/index.d.ts +3 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +1 -0
- package/bin/index.js.map +1 -1
- package/bin/model/CityModelAdapter.d.ts +23 -0
- package/bin/model/CityModelAdapter.d.ts.map +1 -0
- package/bin/model/CityModelAdapter.js +454 -0
- package/bin/model/CityModelAdapter.js.map +1 -0
- package/bin/runtime/host/daemon/Paths.d.ts +1 -1
- package/bin/runtime/host/daemon/Paths.js +1 -1
- package/bin/runtime/host/daemon/ProjectSetup.js +2 -2
- package/bin/session/Session.d.ts +1 -0
- package/bin/session/Session.d.ts.map +1 -1
- package/bin/session/Session.js +32 -6
- package/bin/session/Session.js.map +1 -1
- package/bin/session/SessionTitle.d.ts +49 -0
- package/bin/session/SessionTitle.d.ts.map +1 -0
- package/bin/session/SessionTitle.js +130 -0
- package/bin/session/SessionTitle.js.map +1 -0
- package/bin/session/browse/Browse.d.ts +2 -1
- package/bin/session/browse/Browse.d.ts.map +1 -1
- package/bin/session/browse/Browse.js +18 -15
- package/bin/session/browse/Browse.js.map +1 -1
- package/bin/session/index.d.ts +2 -1
- package/bin/session/index.d.ts.map +1 -1
- package/bin/session/index.js +2 -1
- package/bin/session/index.js.map +1 -1
- package/bin/session/storage/Metadata.d.ts +4 -0
- package/bin/session/storage/Metadata.d.ts.map +1 -1
- package/bin/session/storage/Metadata.js +12 -25
- package/bin/session/storage/Metadata.js.map +1 -1
- package/bin/session/storage/Persistence.d.ts.map +1 -1
- package/bin/session/storage/Persistence.js +1 -4
- package/bin/session/storage/Persistence.js.map +1 -1
- package/bin/types/agent/AgentTypes.d.ts +9 -5
- package/bin/types/agent/AgentTypes.d.ts.map +1 -1
- package/bin/types/config/AgentProject.d.ts +1 -1
- package/bin/types/config/DowncityConfig.d.ts +3 -3
- package/bin/types/config/ExecutionBinding.d.ts +4 -4
- package/bin/types/config/ExecutionBinding.js +1 -1
- package/bin/types/runtime/auth/AuthPermission.js +2 -2
- package/bin/types/runtime/auth/AuthPermission.js.map +1 -1
- package/bin/types/runtime/host/Store.d.ts +3 -177
- package/bin/types/runtime/host/Store.d.ts.map +1 -1
- package/bin/types/runtime/host/Store.js +7 -0
- package/bin/types/runtime/host/Store.js.map +1 -1
- package/bin/types/runtime/http/InlineInstant.d.ts +1 -1
- package/bin/types/runtime/platform/Platform.d.ts +1 -1
- package/package.json +19 -18
- package/scripts/city-model-tool-loop.test.mjs +181 -0
- package/src/agent/Agent.ts +3 -2
- package/src/config/AgentInitializer.ts +1 -1
- package/src/config/DowncitySchema.ts +1 -1
- package/src/config/ExecutionBinding.ts +1 -1
- package/src/executor/composer/compaction/jsonl/JsonlSessionCompactionExecutor.ts +0 -4
- package/src/executor/composer/system/default/InitPrompts.ts +1 -1
- package/src/executor/composer/system/default/SystemDomain.ts +1 -1
- package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -1
- package/src/executor/composer/system/default/assets/plugin.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/plugin.prompt.ts.txt +18 -18
- package/src/executor/composer/system/default/assets/task.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/task.prompt.ts.txt +1 -1
- package/src/executor/messages/ChatMessageMarkupTypes.ts +1 -1
- package/src/executor/store/history/jsonl/JsonlSessionHistoryStore.ts +17 -57
- package/src/executor/tools/shell/ShellToolBridge.ts +1 -1
- package/src/executor/tools/shell/ShellToolFormatting.ts +7 -7
- package/src/executor/types/SessionHistoryMeta.ts +5 -25
- package/src/index.ts +5 -5
- package/src/model/CityModelAdapter.ts +553 -0
- package/src/runtime/host/daemon/Paths.ts +1 -1
- package/src/runtime/host/daemon/ProjectSetup.ts +2 -2
- package/src/session/Session.ts +40 -6
- package/src/session/SessionTitle.ts +192 -0
- package/src/session/browse/Browse.ts +22 -13
- package/src/session/index.ts +5 -0
- package/src/session/storage/Metadata.ts +14 -29
- package/src/session/storage/Persistence.ts +1 -4
- package/src/types/agent/AgentTypes.ts +10 -5
- package/src/types/config/AgentProject.ts +1 -1
- package/src/types/config/DowncityConfig.ts +3 -3
- package/src/types/config/ExecutionBinding.ts +4 -4
- package/src/types/runtime/auth/AuthPermission.ts +2 -2
- package/src/types/runtime/host/Store.ts +3 -182
- package/src/types/runtime/http/InlineInstant.ts +1 -1
- package/src/types/runtime/platform/Platform.ts +1 -1
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/agent/Agent.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import fs from "fs-extra";
|
|
15
15
|
import { nanoid } from "nanoid";
|
|
16
|
-
import type {
|
|
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?:
|
|
128
|
+
private readonly defaultModel?: AgentModel;
|
|
128
129
|
private readonly pluginInstances: Map<string, BasePlugin>;
|
|
129
130
|
private readonly sessionCollection: AgentSessionCollection;
|
|
130
131
|
|
|
@@ -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
|
|
|
@@ -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 `
|
|
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- `
|
|
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
|
-
- `
|
|
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 状态管理(统一使用 `
|
|
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 状态管理(统一使用 `
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
- `
|
|
10
|
-
- `
|
|
11
|
-
- `
|
|
12
|
-
- `
|
|
13
|
-
- `
|
|
14
|
-
- `
|
|
15
|
-
- `
|
|
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
|
-
- `
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
-
- `
|
|
24
|
-
- `
|
|
25
|
-
- `
|
|
26
|
-
- `
|
|
27
|
-
- `
|
|
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- 除非任务正文明确要求,否则不要调用 `
|
|
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;
|
|
@@ -194,29 +194,9 @@ export class JsonlSessionHistoryStore implements SessionHistoryStore {
|
|
|
194
194
|
await fs.ensureFile(this.getMessagesFilePath());
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
private
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
239
|
-
|
|
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
|
-
|
|
252
|
-
|
|
221
|
+
updatedAt: typeof raw.updatedAt === "number" ? raw.updatedAt : 0,
|
|
222
|
+
...(this.normalizeText(raw.title)
|
|
223
|
+
? { title: this.normalizeText(raw.title) }
|
|
253
224
|
: {}),
|
|
254
|
-
...(this.
|
|
255
|
-
? {
|
|
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
|
-
|
|
282
|
-
|
|
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.
|
|
298
|
-
? {
|
|
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|
|
|
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
|
-
* 对 `
|
|
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 (!/\
|
|
45
|
+
if (!/\bbay\s+chat\s+send\b/.test(source)) return null;
|
|
46
46
|
if (!/[\r\n]/.test(source)) return null;
|
|
47
|
-
if (/\
|
|
47
|
+
if (/\bbay\s+chat\s+send\b[\s\S]*\s--stdin(?:\s|$)/.test(source)) {
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
|
-
if (/\
|
|
50
|
+
if (/\bbay\s+chat\s+send\b[\s\S]*\s--text(?:\s|$)/.test(source)) {
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
|
-
if (/\
|
|
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 `
|
|
58
|
-
"If your message is multi-line, use `
|
|
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
|
-
* - 用于保存
|
|
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
|
-
/**
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
|
|
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 协议类型
|