合并最新master的历史表清理与聊天优化
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
同步master历史表清理、生成绑定和客户端优化,保留埋点实现。
This commit is contained in:
@@ -2641,48 +2641,6 @@ const databaseTableLabelMap: Record<string, string> = {
|
||||
profile_recharge_order: '充值订单',
|
||||
profile_feedback_submission: '反馈提交',
|
||||
profile_save_archive: '存档记录',
|
||||
story_session: '剧情会话',
|
||||
story_event: '剧情事件',
|
||||
npc_state: 'NPC 状态',
|
||||
inventory_slot: '背包槽位',
|
||||
battle_state: '战斗状态',
|
||||
treasure_record: '宝藏记录',
|
||||
quest_record: '任务记录',
|
||||
quest_log: '任务日志',
|
||||
player_progression: '玩家进度',
|
||||
chapter_progression: '章节进度',
|
||||
custom_world_profile: '自定义世界档案',
|
||||
custom_world_session: '自定义世界会话',
|
||||
custom_world_agent_session: '自定义世界 Agent 会话',
|
||||
custom_world_agent_message: '自定义世界 Agent 消息',
|
||||
custom_world_agent_operation: '自定义世界 Agent 操作',
|
||||
custom_world_draft_card: '自定义世界草稿卡片',
|
||||
custom_world_gallery_entry: '自定义世界画廊条目',
|
||||
puzzle_agent_session: '拼图 Agent 会话',
|
||||
puzzle_agent_message: '拼图 Agent 消息',
|
||||
puzzle_work_profile: '拼图作品档案',
|
||||
puzzle_event: '拼图事件',
|
||||
puzzle_runtime_run: '拼图运行记录',
|
||||
puzzle_leaderboard_entry: '拼图排行榜条目',
|
||||
match3d_agent_session: '抓大鹅 Agent 会话',
|
||||
match3d_agent_message: '抓大鹅 Agent 消息',
|
||||
match3d_work_profile: '抓大鹅作品档案',
|
||||
match3d_runtime_run: '抓大鹅运行记录',
|
||||
square_hole_agent_session: '方洞挑战 Agent 会话',
|
||||
square_hole_agent_message: '方洞挑战 Agent 消息',
|
||||
square_hole_work_profile: '方洞挑战作品档案',
|
||||
square_hole_runtime_run: '方洞挑战运行记录',
|
||||
visual_novel_agent_session: '视觉小说 Agent 会话',
|
||||
visual_novel_agent_message: '视觉小说 Agent 消息',
|
||||
visual_novel_work_profile: '视觉小说作品档案',
|
||||
visual_novel_runtime_run: '视觉小说运行记录',
|
||||
visual_novel_runtime_history_entry: '视觉小说历史条目',
|
||||
visual_novel_runtime_event: '视觉小说运行事件',
|
||||
big_fish_creation_session: '大鱼吃小鱼创建会话',
|
||||
big_fish_agent_message: '大鱼吃小鱼 Agent 消息',
|
||||
big_fish_asset_slot: '大鱼吃小鱼资产槽位',
|
||||
big_fish_event: '大鱼吃小鱼事件',
|
||||
big_fish_runtime_run: '大鱼吃小鱼运行记录',
|
||||
asset_object: '资产对象',
|
||||
asset_entity_binding: '资产实体绑定',
|
||||
asset_event: '资产事件',
|
||||
@@ -2724,48 +2682,6 @@ const databaseTableDescriptionMap: Record<string, string> = {
|
||||
profile_recharge_order: '充值订单表',
|
||||
profile_feedback_submission: '反馈提交记录表',
|
||||
profile_save_archive: '用户存档记录表',
|
||||
story_session: '剧情会话表',
|
||||
story_event: '剧情事件表',
|
||||
npc_state: 'NPC 状态表',
|
||||
inventory_slot: '背包槽位表',
|
||||
battle_state: '战斗状态表',
|
||||
treasure_record: '宝藏记录表',
|
||||
quest_record: '任务记录表',
|
||||
quest_log: '任务日志表',
|
||||
player_progression: '玩家进度表',
|
||||
chapter_progression: '章节进度表',
|
||||
custom_world_profile: '自定义世界档案表',
|
||||
custom_world_session: '自定义世界会话表',
|
||||
custom_world_agent_session: '自定义世界 Agent 会话表',
|
||||
custom_world_agent_message: '自定义世界 Agent 消息表',
|
||||
custom_world_agent_operation: '自定义世界 Agent 操作表',
|
||||
custom_world_draft_card: '自定义世界草稿卡片表',
|
||||
custom_world_gallery_entry: '自定义世界画廊条目表',
|
||||
puzzle_agent_session: '拼图 Agent 会话表',
|
||||
puzzle_agent_message: '拼图 Agent 消息表',
|
||||
puzzle_work_profile: '拼图作品档案表',
|
||||
puzzle_event: '拼图事件表',
|
||||
puzzle_runtime_run: '拼图运行记录表',
|
||||
puzzle_leaderboard_entry: '拼图排行榜条目表',
|
||||
match3d_agent_session: '抓大鹅 Agent 会话表',
|
||||
match3d_agent_message: '抓大鹅 Agent 消息表',
|
||||
match3d_work_profile: '抓大鹅作品档案表',
|
||||
match3d_runtime_run: '抓大鹅运行记录表',
|
||||
square_hole_agent_session: '方洞挑战 Agent 会话表',
|
||||
square_hole_agent_message: '方洞挑战 Agent 消息表',
|
||||
square_hole_work_profile: '方洞挑战作品档案表',
|
||||
square_hole_runtime_run: '方洞挑战运行记录表',
|
||||
visual_novel_agent_session: '视觉小说 Agent 会话表',
|
||||
visual_novel_agent_message: '视觉小说 Agent 消息表',
|
||||
visual_novel_work_profile: '视觉小说作品档案表',
|
||||
visual_novel_runtime_run: '视觉小说运行记录表',
|
||||
visual_novel_runtime_history_entry: '视觉小说历史条目表',
|
||||
visual_novel_runtime_event: '视觉小说运行事件表',
|
||||
big_fish_creation_session: '大鱼吃小鱼创建会话表',
|
||||
big_fish_agent_message: '大鱼吃小鱼 Agent 消息表',
|
||||
big_fish_asset_slot: '大鱼吃小鱼资产槽位表',
|
||||
big_fish_event: '大鱼吃小鱼事件表',
|
||||
big_fish_runtime_run: '大鱼吃小鱼运行记录表',
|
||||
asset_object: '资产对象表',
|
||||
asset_entity_binding: '资产实体绑定表',
|
||||
asset_event: '资产事件表',
|
||||
|
||||
@@ -203,12 +203,51 @@ pub(in crate::agent) fn game_creator_codex_cli_version_at(
|
||||
Ok(version.to_string())
|
||||
}
|
||||
|
||||
/// 开发态允许从宿主 PATH 里找到 Codex,但宿主必须持有可锚定的绝对文件:
|
||||
/// 裸命令名按 PATH 解析成真实路径,否则 `bind_codex_executor` 的 canonicalize 会按 CWD 解析并失败。
|
||||
/// 发行构建不走这段,候选顺序、校验与返回值都与原先一致(打包环境用内置侧车/npm 绝对路径)。
|
||||
#[cfg(debug_assertions)]
|
||||
fn anchor_codex_cli_executable_candidate(
|
||||
candidate: &Path,
|
||||
path: Option<&std::ffi::OsStr>,
|
||||
) -> Option<PathBuf> {
|
||||
let is_bare_command_name = candidate
|
||||
.parent()
|
||||
.is_some_and(|parent| parent.as_os_str().is_empty());
|
||||
if !is_bare_command_name {
|
||||
return candidate.is_file().then(|| candidate.to_path_buf());
|
||||
}
|
||||
let name = candidate.as_os_str();
|
||||
for directory in path.into_iter().flat_map(std::env::split_paths) {
|
||||
if directory.as_os_str().is_empty() {
|
||||
continue;
|
||||
}
|
||||
let target = directory.join(name);
|
||||
if target.is_file() {
|
||||
// 第一个实际命中的项就是 OS 会执行的项;锚定失败时不再从 PATH 里换另一个。
|
||||
return target.canonicalize().ok();
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn game_creator_codex_cli_executable_path() -> Result<PathBuf, String> {
|
||||
let mut last_error = None;
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
let bundled =
|
||||
game_creator_bundled_codex_cli_path(game_creator_bundled_resource_dir().as_deref());
|
||||
for candidate in game_creator_codex_cli_executable_candidates() {
|
||||
#[cfg(debug_assertions)]
|
||||
let candidate = match anchor_codex_cli_executable_candidate(
|
||||
&candidate,
|
||||
std::env::var_os("PATH").as_deref(),
|
||||
) {
|
||||
Some(candidate) => candidate,
|
||||
None => {
|
||||
last_error = Some("候选执行器不是可锚定的文件".to_string());
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let identity = candidate.to_string_lossy().to_ascii_lowercase();
|
||||
if !seen.insert(identity) {
|
||||
continue;
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Component,
|
||||
createContext,
|
||||
isValidElement,
|
||||
memo,
|
||||
useContext,
|
||||
} from 'react';
|
||||
import ReactMarkdown, { type Components } from 'react-markdown';
|
||||
@@ -302,7 +303,15 @@ const streamingMarkdownComponents: Components = {
|
||||
p: StreamingMarkdownParagraph,
|
||||
};
|
||||
|
||||
export function ChatMarkdownMessage({
|
||||
/**
|
||||
* 解析器的输入只有 `text` / `role` / `streaming` / `preserveBlankLines` 这几个标量,所以
|
||||
* 内容没变的旧消息在父级重渲染时可以直接跳过:Markdown 解析与语法高亮是这个组件里最贵的
|
||||
* 两件事(`react-markdown` 每次渲染都会重建 `unified()` 处理器并重跑全部插件),而旧消息
|
||||
* 的文本永远不会再改。
|
||||
*/
|
||||
export const ChatMarkdownMessage = memo(ChatMarkdownMessageImpl);
|
||||
|
||||
function ChatMarkdownMessageImpl({
|
||||
text,
|
||||
role,
|
||||
streaming = false,
|
||||
@@ -317,8 +326,13 @@ export function ChatMarkdownMessage({
|
||||
<ReactMarkdown
|
||||
skipHtml
|
||||
remarkPlugins={[remarkGfm]}
|
||||
// 流式中不高亮:高亮要跑一遍完整 AST + highlight.js,而流式增量会让同一段代码
|
||||
// 每来一个 chunk 就重新高亮一次(文本还在长,结果立刻作废)。文本定稿时
|
||||
// `streaming` 变回 false,这一笔高亮自然补上。
|
||||
rehypePlugins={
|
||||
text.length <= MAX_HIGHLIGHT_CHARACTERS ? [rehypeHighlight] : []
|
||||
streaming || text.length > MAX_HIGHLIGHT_CHARACTERS
|
||||
? []
|
||||
: [rehypeHighlight]
|
||||
}
|
||||
components={
|
||||
streaming ? streamingMarkdownComponents : markdownComponents
|
||||
|
||||
+10
-3
@@ -1,5 +1,5 @@
|
||||
import { ChevronDown, Lightbulb } from 'lucide-react';
|
||||
import { useState } from 'react';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
|
||||
import { AgentMessageContent } from '../../../../../../../../packages/shared/src/components/AgentMessageContent';
|
||||
import { AgentProcessSummary } from '../../../../../../../../packages/shared/src/components/AgentProcessSummary';
|
||||
@@ -12,7 +12,9 @@ import { agentProcessPreview } from '../../../../../features/project-workspace/a
|
||||
* 折叠态是单行纯文本预览(Markdown 只取可见文字,符号不进预览);展开态复用助手正文的
|
||||
* 安全 Markdown 链路。这里只有表现与展开态,思考内容本身由两条产品路径各自的事实源提供。
|
||||
*/
|
||||
export function AgentReasoning({
|
||||
export const AgentReasoning = memo(AgentReasoningImpl);
|
||||
|
||||
function AgentReasoningImpl({
|
||||
text,
|
||||
label = '思考过程',
|
||||
testId,
|
||||
@@ -22,7 +24,12 @@ export function AgentReasoning({
|
||||
testId?: string;
|
||||
}) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const preview = agentProcessPreview(text);
|
||||
/*
|
||||
折叠态那一行预览是**完整 Markdown AST 解析**(`remark-parse` + `unified`),和展开态
|
||||
`react-markdown` 那次解析是两笔开销;上面那层 `memo` 让内容没变的思考块整个跳过,
|
||||
这里的 `useMemo` 再兜一层,避免同一文本在真正重渲染时被重算。
|
||||
*/
|
||||
const preview = useMemo(() => agentProcessPreview(text), [text]);
|
||||
return (
|
||||
<AgentMessageContent
|
||||
as="details"
|
||||
|
||||
Reference in New Issue
Block a user