要求AI 处理器
道具
| Prop | 类型 |
|---|---|
| 用户故事 | IUserStory | null |
| 用户故事 | React.Dispatch<React.SetStateAction<IUserStory | null>> |
| 爱因斯坦语 | TAIReasoning[] |
| 设置 | React.Dispatch<React.SetStateAction<TAIReasoning[]>> |
| 引用 | UserStoryCitations[] |
| 设置 | React.Dispatch<React.SetStateAction<UserStoryCitations[]>> |
| 儿童 | ReactNode |
数据结构
用户故事
export interface IUserStory {
artifactId: string;
title: string;
value: string;
sub_features?: IUserStory[];
storyNumber?: string;
description?: string;
section?: "intro" | "subfeature";
blockNumber?: string;
citation?: UserStoryCitations;
aiReasoning?: TAIReasoning[];
isEnd?: boolean;
}
针锋相对
export type TAIReasoning = {
id: string;
reason: string;
gap: string;
relevance_score: number;
reasonSource?: string;
gapSource?: string;
isOpen?: boolean;
relevance_score_diff?: number;
explanation?: string;
};
用户故事
export type UserStoryCitations = {
image_citations?: ImageCitation[];
appmod_citations?: TextCitation[];
audio_citations?: AudioCitation[];
file_citations?: FileCitation[];
file_image_data?: ImageCitationsForFile | null;
rca_citations?: RcaCitation[];
web_citations?: WebCitation[];
code_generated?: GeneratedCodeCitation[];
};
图像选择文件
interface ImageCitationsForFile {
[key: string]: FileImageData;
}
文件图像数据
interface FileImageData {
filename: string;
signed_url: string;
gs_url: string;
}
使用量
创建状态
const [userStory, setUserStory] = useState<IUserStory | null>(null);
const [aiReasoning, setAiReasoning] = useState<TAIReasoning[]>([]);
const [citations, setCitations] = useState<UserStoryCitations[]>([]);
环绕组件
<RequirementAIWrapper
userStory={userStory}
setUserStory={setUserStory}
aiReasoning={aiReasoning}
setAiReasoning={setAiReasoning}
citations={citations}
setCitations={setCitations}
>
{children}
</RequirementAIWrapper>
上下文值
包装提供了以下上下文值:
{
(userStory,
setUserStory,
aiReasoning,
setAiReasoning,
citations,
setCitations);
}
使用量
import { useStreamContentHandler } from "@e-llm-studio/requirement-ai";
function StreamingComponent() {
const { processStreamContent } = useStreamContentHandler({
setUserStory,
setAiReasoning,
setUserStoryCitations,
onStreamingCompleted,
isGraphQLCallInProgress,
knowledgeBase,
projectAnalyserSummary,
dataSourceFiles,
aiReasoning,
setRedisValue,
fetchCitationByBlock,
});
const handleStream = (blockList) => {
processStreamContent(blockList, metadata, "story-artifact-id");
};
return <div>Streaming...</div>;
}
虎克 API
使用Stream ContentHandler(道具)
回返
{
processStreamContent: (
blockList: BlockStreamItem[],
customMetadata: any,
storyArtifactID: string
) => void
}
道具
用户故事
反应状态设置器用于存储生成的用户故事.
React.Dispatch<React.SetStateAction<IUserStory[]>>;
设置
国家设置器用来存储提取的AI推理.
React.Dispatch<React.SetStateAction<TAIReasoning[]>>;
用户的故事
用于存储从块生成的引用的状态设置器 .
React.Dispatch<React.SetStateAction<UserStoryCitations>>;
已安装完成
召回一次执行 所有引用生成任务已完成。 。 。 .
(gap_items_prompt?: string, risk_items_prompt?: string) => Promise<void>;
是 GraphQLCall 在进步中
显示 GraphQL 调用是否正在运行的布尔旗 .
这使得完成回调不能过早地发射.
boolean;
知识库
与当前流相关的知识基础元数据.
any;
分析器概要
处理过程中使用的项目分析摘要.
any;
数据源文件
关于上传数据源文件的信息.
{
document: string[];
image: string[];
meetingRecording: string[];
}
爱因斯坦语
现有AI推理状态.
TAIReasoning[]
设置重置值
负责在 Redis 存储流状态的函数 .
<T>({ key, value }: SetRedisParams<T>) => Promise<any>;
实施实例:
async function setRedisValue({ key, value }) {
await redis.set(key, JSON.stringify(value));
}
获取 CitationByBlock
Async 函数负责生成给定块的引用 .
(block: BlockStreamItem, metadata: any, ai_reasonings: TAIReasoning[]) =>
Promise<IGetCitationsByBlock>;
类型
块结构项目
代表一个串行的AI块.
type BlockStreamItem = {
title: string;
section: "intro" | "subfeature";
description?: string;
blockNumber: string;
value: string;
storyNumber: string;
};
流动
AI Stream
↓
Block List
↓
processStreamContent
↓
Reasoning Extraction
↓
User Story Generation
↓
Citation Generation
↓
Redis Persistence
↓
Streaming Completed Callback
内部保障
钩子包括几种优化流出性能的机制:
| 机制 | 目的 |
|---|---|
| 更新 CitationCallKeys 参考文献 | 防止重复引用请求 |
| 引用Generation 完成键 | 音轨已完成引用任务 |
| 上次处理的 BlockListHash 参考文献 | 避免后处理相同的区块清单 |
| 最后一个Redisvalue 注释 | 防止冗余 Redis 写入 |
最佳做法
- 保证
fetchCitationByBlock是无能的. - 避免频繁打来
processStreamContent没有批量. - 总是使用 JSON 序列化 Redis 值 .
用户史克林组件
用于显示和编辑用户故事并带有AI推理引用的可调和的UI组件系统. 它必须包裹在内 RequirementAIWrapper 进入共享状态.
快速演示
import React, { useState } from "react";
import RequirementAIWrapper from "@e-llm-studio/requirement-ai";
import UserStoryScreen from "@e-llm-studio/requirement-ai";
import UserStoryWithCitations from "@e-llm-studio/requirement-ai";
import RichTextEditor from "@e-llm-studio/requirement-ai";
import AtomicButton from "@e-llm-studio/requirement-ai";
function MyStoryApp() {
const [userStory, setUserStory] = useState<IUserStory[]>([
{
artifactId: "story-1",
title: "User Login",
value: "As a user, I want to login to the system",
},
]);
const [aiReasoning, setAiReasoning] = useState<TAIReasoning[]>([]);
const [citations, setCitations] = useState<UserStoryCitations[]>([]);
return (
<RequirementAIWrapper
userStory={userStory}
setUserStory={setUserStory}
aiReasoning={aiReasoning}
setAiReasoning={setAiReasoning}
citations={citations}
setCitations={setCitations}
apiCachingConfig={{
queryClient: null, // replace with original tanstack-query client
useGetSignedUrlQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
useGetSignedUrlMutation: (gsUtilPath: string) => null, // replace with original hook
useExtractAudioPeaksMutation: () => null, // replace with original hook
useExtractAudioPeaksQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
useGetVideoSignedUrlMutation: (gsUtilPath: string) => null, // replace with original hook
useGetVideoSignedUrlQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
}}
>
<UserStoryScreen scenario="ready" isCitationLoadingNotStarted={true}>
<UserStoryScreen.Content AtomicButton={AtomicButton}>
<UserStoryScreen.Body>
<UserStoryScreen.Story Component={UserStoryWithCitations} />
<UserStoryScreen.Editor Component={RichTextEditor} />
<UserStoryScreen.SubFeatures />
</UserStoryScreen.Body>
<UserStoryScreen.ScrollButton />
</UserStoryScreen.Content>
</UserStoryScreen>
</RequirementAIWrapper>
);
}
核心子组成部分
| 构成部分 | 目的 |
|---|---|
UserStoryScreen.Sidebar | 故事选择的导航侧边栏 |
UserStoryScreen.SidebarToggle | 折叠/扩展侧边栏按钮 |
UserStoryScreen.Content | 主要内容有标题和控件 |
UserStoryScreen.Body | 故事/编辑容器(相互排除) |
UserStoryScreen.Story | 以引用( 读取模式) 显示选中的故事 |
UserStoryScreen.Editor | 编辑故事的丰富文本编辑器( 编辑模式) |
UserStoryScreen.SubFeatures | 嵌入子地块的受体 |
UserStoryScreen.ScrollButton | 向下滚动的浮动按钮 |
根道具
interface UserStoryScreenProps {
scenario: "streaming" | "ready"; // "streaming" for real-time, "ready" for static
isCitationLoadingNotStarted: boolean; // Flag for citation loading state
children: React.ReactNode; // Sub-components
classNames?: UserStoryScreenClassNames; // Optional custom CSS classes
}
关键特性
- 自动国家管理: 所有组件从
RequirementAIWrapper上下文 - 相互排斥: 故事和编辑器视图自动为专属
- 流程支持: 有骨架加载器的实时更新
- 引用整合: AI 故事中强调的推理和引用
- 标记下方支持: 故事支持自定义标记下标记格式
用法说明
- 总是用
RequirementAIWrapper- 为所有子组成部分提供上下文 - 使用
Body包装 - 确保适当的故事/编辑相互排斥 - 通过自定义组件 - 故事和编辑器期望将反应组件作为道具
- 正确设定情景 - 实时数据的"流",静态内容的"已就绪"
用户Story核准Screen组件
用于审查和批准AI生成的用户故事的专用审批工作流程组件. 它必须包裹在内 RequirementAIWrapper 进入共享状态.
概览
用户StoryApprovalScreen提供了一个结构化的界面,用于:
- 逐块审查生成的用户故事
- 编辑单个内容部分
- 逐步核准内容
- 管理具有删除能力的子特征
- 带有“ 全部验证” 功能的批量审批
快速演示
import React, { useState } from "react";
import RequirementAIWrapper from "@e-llm-studio/requirement-ai";
import UserStoryApprovalScreen from "@e-llm-studio/requirement-ai";
import UserStoryWithCitations from "@e-llm-studio/requirement-ai";
import RichTextEditor from "@e-llm-studio/requirement-ai";
import AtomicButton from "@e-llm-studio/requirement-ai";
function MyApprovalFlow() {
const [userStory, setUserStory] = useState<IUserStory[]>([]);
const [aiReasoning, setAiReasoning] = useState<TAIReasoning[]>([]);
const [citations, setCitations] = useState<UserStoryCitations[]>([]);
return (
<RequirementAIWrapper
userStory={userStory}
setUserStory={setUserStory}
aiReasoning={aiReasoning}
setAiReasoning={setAiReasoning}
citations={citations}
setCitations={setCitations}
apiCachingConfig={{
queryClient: null, // replace with original tanstack-query client
useGetSignedUrlQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
useGetSignedUrlMutation: (gsUtilPath: string) => null, // replace with original hook
useExtractAudioPeaksMutation: () => null, // replace with original hook
useExtractAudioPeaksQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
useGetVideoSignedUrlMutation: (gsUtilPath: string) => null, // replace with original hook
useGetVideoSignedUrlQuery: (gsUtilPath: string, cacheKey: string[]) => null, // replace with original hook
}}
>
<UserStoryApprovalScreen
artifactTitleIds={["STORY-001"]}
config={{
showApproveAllButton: true,
allowEditing: true,
allowDeletion: true,
containerHeight: "calc(100vh - 100px)",
}}
callbacks={{
onShowNotification: (type, title, message) => {
console.log(`[${type}] ${title}: ${message}`);
},
onInitialize: () => {
console.log("Approval screen initialized");
},
onSaveState: async (stories) => {
await saveToRedis(stories);
},
onAllApproved: async (stories) => {
await submitApprovedStories(stories);
},
}}
>
<UserStoryApprovalScreen.Content ButtonComponent={AtomicButton}>
<UserStoryApprovalScreen.Body
EditorComponent={RichTextEditor}
ViewerComponent={UserStoryWithCitations}
/>
</UserStoryApprovalScreen.Content>
</UserStoryApprovalScreen>
</RequirementAIWrapper>
);
}
构成部分结构
| 构成部分 | 目的 |
|---|---|
UserStoryApprovalScreen (旋转) | 经批准的国家管理集装箱 |
UserStoryApprovalScreen.Content | 标题、元数据以及“ 证明全部” 按钮的标题 |
UserStoryApprovalScreen.Body | 有编辑/批准/删除动作的渲染内容段 |
根组件道具
interface UserStoryApprovalScreenProps {
artifactTitleIds: string[]; // Display IDs for each story
config?: UserStoryApprovalScreenConfig; // Feature toggles
callbacks?: UserStoryApprovalScreenCallbacks; // Platform-specific handlers
labels?: Partial<UserStoryApprovalScreenLabels>; // Custom text labels
isDisabled?: boolean; // Disable all interactions
children: React.ReactNode; // Sub-components
classNames?: UserStoryApprovalScreenClassNames; // Custom CSS classes
}
配置选项
interface UserStoryApprovalScreenConfig {
showApproveAllButton?: boolean; // Show/hide "Approve All" button (default: true)
allowEditing?: boolean; // Enable editing segments (default: true)
allowDeletion?: boolean; // Enable deleting sub-features (default: true)
showSidebar?: boolean; // Show sidebar for multi-story navigation (default: false)
containerHeight?: string; // CSS height value (default: "calc(100vh - 100px)")
useFullWidth?: boolean; // Use 100% width without margins (default: false)
}
回调处理器
interface UserStoryApprovalScreenCallbacks {
/** Show toast/notification - required for user feedback */
onShowNotification?: (
type: "success" | "error" | "warn" | "info",
title: string,
message: string,
duration?: number,
) => void;
/** Initialize platform (e.g., adjust chat width in web app) */
onInitialize?: () => void;
/** Persist approval state to Redis/storage */
onSaveState?: (stories: IUserStoryForApproval[]) => Promise<void>;
/** Triggered when all stories are approved */
onAllApproved?: (stories: IUserStoryForApproval[]) => Promise<void>;
/** Custom scroll behavior for focusing segments */
onScrollToElement?: (element: HTMLElement) => void;
}
访问上下文
使用 useRequirementAI() 用户StoryScreen组件中的钩子 :
import { useRequirementAI } from "@e-llm-studio/requirement-ai";
function MyCustomComponent() {
const { userStory, setUserStory, aiReasoning } = useRequirementAI();
return <div>{userStory?.[0]?.title}</div>;
}
Diff 编辑工具 — 用法指南
1. 联合国. handleDiffEditApplied
应用AI diff对用户故事,推理,聊天历史的响应.
handleDiffEditApplied(
aiResponseString,
selectedUserStoryType,
username,
setUserStory,
setAiReasoning,
setAiReasoningDiffView,
setChatHistory,
setUserStoryDiffView
);
使用时 :
- 你收到AI diff编辑的答复
- 您想要更新用户界面的新故事、 推理和聊天
2. 联合国. handleDiscardAll
拒绝所有 diff 更改并恢复原始状态.
handleDiscardAll(
userStory,
setUserStory,
setAiReasoning,
setUserStoryDiffView
);
使用时 :
- 用户点击 “丢弃所有更改”
- 您想要恢复到原始内容
3个. handleAcceptAllChanges
接受所有 diff 更改并更新用户故事 .
handleAcceptAllChanges(
userStory,
setUserStory,
setIsAutoSaveEnabled
);
许可证
这个图书馆根据麻省理工学院的许可证发行. 详见LICENSE文件.
许可证信息也可在下列表格中查阅: citation/package.json 在“许可证”栏下的文件.