重构/抽取带引用功能的输入框 #464

Merged
k88936 merged 13 commits from refactor/extract-dep-from-ref-inputer into master 2026-09-22 19:05:31 +08:00
2 changed files with 13 additions and 2 deletions
Showing only changes of commit aa973ea34d - Show all commits
@@ -21,6 +21,7 @@ import {
ResourceReferencePicker,
type ResourceReferencePickerHandle,
} from '../../../../../features/project-workspace/ResourceReferencePicker';
import { assetsSignature } from '../../../../../features/project-workspace/resourceReferences';
import type { DirectCodexTurnAttachment } from '../../conversation/directCodexTurnAttachments';
import type { DirectCodexUserContentPart } from '../../generated/DirectCodexUserContentPart';
import type { QueuedChatTurn } from './chatComposerQueue';
@@ -107,6 +108,7 @@ export function DirectProjectComposer({
(Rust `direct_codex_user_item_to_codex_turn_input`),所以只有这里注入 Skill provider。
*/
const skillProvider = useSkillReferenceProvider();
const assetsContentSignature = assetsSignature(assets);
const referenceProviders = useMemo(
() => [
createResourceReferenceProvider({ assets }),
@@ -114,7 +116,11 @@ export function DirectProjectComposer({
attachmentReferenceProvider,
runtimeRegionReferenceProvider,
],
[assets, skillProvider],
// `assets` 由 manifest 订阅每次渲染重新 `.filter()` 派生,依赖它等于从不命中缓存:
// provider 身份一变,输入区就重新注册 Lexical 更新监听(流式回复时每帧都换)。
// 按内容签名取依赖才真的能跳过重建。
// eslint-disable-next-line react-hooks/exhaustive-deps
[assetsContentSignature, skillProvider],
);
const openPicker = useCallback(() => {
onReferencePickerOpen?.();
@@ -23,6 +23,7 @@ import {
ResourceReferenceInput,
type ResourceReferenceInputHandle,
} from '../../../features/project-workspace/ResourceReferenceInput';
import { assetsSignature } from '../../../features/project-workspace/resourceReferences';
import { AgentReasoning } from '../chat/components/AgentReasoning/AgentReasoning';
import { ComposerReasoningEffortSelect } from '../chat/components/DirectProjectComposer/ComposerControls';
import { formatClockTime } from '../chat/components/ToolCallGroup/toolCallGroupPresentation';
@@ -135,13 +136,17 @@ export function PlanningChatView({
`$` Skill 候选只有 DirectProject 回合那条路径会把 `agc_skill_reference` 解析成真 Skill,
这里注入 Skill provider 只会得到一个退化成本文的误导入口,所以不注入。
*/
const chatProjectAssetsSignature = assetsSignature(chatProjectAssets);
const referenceProviders = useMemo(
() => [
createResourceReferenceProvider({ assets: chatProjectAssets }),
attachmentReferenceProvider,
runtimeRegionReferenceProvider,
],
[chatProjectAssets],
// `chatProjectAssets` 由工作台壳每次渲染重新 `.filter()` 派生,依赖它等于从不命中缓存:
// provider 身份一变,输入区就重新注册 Lexical 更新监听。按内容签名取依赖才真的能跳过重建。
// eslint-disable-next-line react-hooks/exhaustive-deps
[chatProjectAssetsSignature],
);
let submitLabel = '发送';
if (needsUserInput) {