Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

106 lines
3.7 KiB
TypeScript

import { useEffect, useMemo, useRef, useState } from "react";
import { useRichTextMentionService } from "@tutti-os/ui-rich-text/editor";
import type { RichTextTriggerProvider } from "@tutti-os/ui-rich-text/types";
import type { AgentContextMentionProvider } from "../agentContextMentionProvider";
import {
AgentMentionSearchController,
type AgentMentionSearchState
} from "../AgentMentionSearchController";
import { DEFAULT_AGENT_MENTION_FILTER } from "../agentMentionSearchHelpers";
import type { AgentComposerReferenceProvenanceFilters } from "./AgentComposer.types";
const EMPTY_AGENT_CONTEXT_MENTION_PROVIDERS: readonly AgentContextMentionProvider[] =
[];
const EMPTY_HIDDEN_FILTER_IDS: readonly string[] = [];
export function useAgentMentionSearchController(
referenceProvenanceFilters: AgentComposerReferenceProvenanceFilters | null,
hiddenFilterIds: readonly string[] = EMPTY_HIDDEN_FILTER_IDS
): {
mentionControllerRef: React.RefObject<AgentMentionSearchController | null>;
mentionSearchState: AgentMentionSearchState;
} {
const mentionService = useRichTextMentionService();
const contextMentionProviders = useMemo(
() =>
mentionService?.listProviders().filter(isAgentContextMentionProvider) ??
EMPTY_AGENT_CONTEXT_MENTION_PROVIDERS,
[mentionService]
);
const [mentionSearchState, setMentionSearchState] =
useState<AgentMentionSearchState>(INITIAL_AGENT_MENTION_SEARCH_STATE);
const mentionControllerRef = useRef<AgentMentionSearchController | null>(
null
);
const sessionProvenanceFilter =
referenceProvenanceFilters?.byFilter.session.snapshot.value ?? null;
const fileProvenanceFilter =
referenceProvenanceFilters?.byFilter.file.snapshot.value ?? null;
const issueProvenanceFilter =
referenceProvenanceFilters?.byFilter.issue.snapshot.value ?? null;
const agentProvenanceFilter =
referenceProvenanceFilters?.byFilter.agent.snapshot.value ?? null;
const appProvenanceFilter =
referenceProvenanceFilters?.byFilter.app.snapshot.value ?? null;
const provenanceCatalog =
referenceProvenanceFilters?.byFilter.session.snapshot.catalog ?? null;
useEffect(() => {
const controller = new AgentMentionSearchController({
contextMentionProviders,
hiddenFilterIds
});
controller.setProvenanceCatalog(provenanceCatalog);
controller.setProvenanceFilters({
session: sessionProvenanceFilter,
file: fileProvenanceFilter,
issue: issueProvenanceFilter,
agent: agentProvenanceFilter,
app: appProvenanceFilter
});
mentionControllerRef.current = controller;
const unsubscribe = controller.subscribe(setMentionSearchState);
return () => {
unsubscribe();
controller.dispose();
mentionControllerRef.current = null;
};
}, [contextMentionProviders, hiddenFilterIds]);
useEffect(() => {
mentionControllerRef.current?.setProvenanceCatalog(provenanceCatalog);
mentionControllerRef.current?.setProvenanceFilters({
session: sessionProvenanceFilter,
file: fileProvenanceFilter,
issue: issueProvenanceFilter,
agent: agentProvenanceFilter,
app: appProvenanceFilter
});
}, [
provenanceCatalog,
sessionProvenanceFilter,
fileProvenanceFilter,
issueProvenanceFilter,
agentProvenanceFilter,
appProvenanceFilter
]);
return { mentionControllerRef, mentionSearchState };
}
function isAgentContextMentionProvider(
provider: RichTextTriggerProvider
): provider is AgentContextMentionProvider {
return provider.trigger === "@";
}
const INITIAL_AGENT_MENTION_SEARCH_STATE: AgentMentionSearchState = {
status: "idle",
query: "",
mode: "browse",
filter: DEFAULT_AGENT_MENTION_FILTER,
categories: [],
groups: [],
error: null
};