修复 DirectProject 校验清单合并
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m3s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 7m25s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 7m30s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m41s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m9s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m40s
Project CI / Frontend tests (pull_request) Failing after 7m45s
Project CI / AI game creator shell web tests (pull_request) Failing after 8m31s
Project CI / Native shell tests (pull_request) Successful in 13m1s

让校验函数返回已读取的项目清单

补齐附件在 Codex 输入转换中的分支;图片 part 已退役,只保留附件 part
This commit is contained in:
2026-09-16 13:39:57 +08:00
parent 71000b6df1
commit ade1b7803e
3 changed files with 28 additions and 16 deletions
@@ -14,7 +14,7 @@ pub(crate) const MAX_DIRECT_CODEX_REFERENCES: usize = 32;
pub(crate) fn validate_direct_codex_user_item(
root: &Path,
item: &DirectCodexUserItem,
) -> Result<(), String> {
) -> Result<GameCreationAppManifest, String> {
let DirectCodexUserItem::Message(message) = item;
if !matches!(message.role, DirectCodexUserRole::User) {
return Err("DirectProject 只接受 user message item".to_string());
@@ -98,7 +98,7 @@ pub(crate) fn validate_direct_codex_user_item(
if reference_count > MAX_DIRECT_CODEX_REFERENCES {
return Err(format!("一次最多引用 {MAX_DIRECT_CODEX_REFERENCES} 个素材"));
}
Ok(())
Ok(manifest)
}
/// 整条 content 是否还有有效输入:任何一段非空白文本、或任何一个非文本 part 都算。
@@ -178,6 +178,23 @@ pub(crate) fn direct_codex_user_item_to_codex_turn_input(
"text": runtime_region_summary(reference),
}));
}
DirectCodexUserContentPart::AgcAttachmentReference(reference) => {
let mut summary = format!(
"[附件:名称={};类型={};大小={} 字节",
reference.name.trim(),
reference.media_type.trim(),
reference.size
);
if !reference.local_path.trim().is_empty() {
summary.push_str(&format!(";项目路径={}", reference.local_path.trim()));
}
summary.push_str(&format!(";状态={}", reference.status.trim()));
summary.push(']');
input.push(serde_json::json!({
"type": "text",
"text": summary,
}));
}
}
}
Ok(Value::Array(input))
@@ -192,15 +192,6 @@ class SkillMentionOption extends MenuOption {
}
}
const BUILTIN_SKILL_REFERENCES: SkillReference[] = [
'agc-browser-playtest',
'agc-client-projection',
'agc-game-production-workflow',
'agc-project-structure',
'agc-web-game-development',
'taonier-art-assets',
].map((name) => ({ type: 'skill', name }));
/**
* 编辑器节点 → canonical content part**原样透传**:段落分隔(root 子节点之间补的
* `\n`)、软换行、chip 后的分隔空格都各自成 part,不做空白过滤、不与相邻 part 合并。
@@ -265,8 +256,12 @@ function readDraftFromNodes(): ChatComposerDraft {
const projection = readDraftProjectionFromNodes();
const labels = new Map(
projection.references.map((reference) => [
reference.type === 'resource' ? reference.resourceId : reference.label,
`@${reference.label}`,
reference.type === 'resource'
? reference.resourceId
: reference.type === 'skill'
? reference.name
: reference.label,
reference.type === 'skill' ? `$${reference.name}` : `@${reference.label}`,
]),
);
const text = projection.content
@@ -277,7 +272,7 @@ function readDraftFromNodes(): ChatComposerDraft {
? (labels.get(part.resourceId) ?? `@${part.resourceId}`)
: part.type === 'agc_runtime_region_reference'
? `@${part.label}`
: `@${part.name}`,
: `$${part.name}`,
)
.join('')
.trim();
@@ -872,13 +867,13 @@ function ResourceReferenceEditor({
const currentRefKey = current.references
?.map(
(reference) =>
`${reference.type}:${reference.type === 'resource' ? reference.resourceId : reference.label}`,
`${reference.type}:${reference.type === 'resource' ? reference.resourceId : reference.type === 'skill' ? reference.name : reference.label}`,
)
.join('|');
const desiredRefKey = desiredRefs
.map(
(reference) =>
`${reference.type}:${reference.type === 'resource' ? reference.resourceId : reference.label}`,
`${reference.type}:${reference.type === 'resource' ? reference.resourceId : reference.type === 'skill' ? reference.name : reference.label}`,
)
.join('|');
if (current.text === desiredValue && currentRefKey === desiredRefKey)