feat(core): add stream object api (#12841)

Close [AI-193](https://linear.app/affine-design/issue/AI-193)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for streaming structured AI chat responses as objects,
enabling richer and more interactive chat experiences.
- Chat messages now include a new field displaying structured stream
objects, such as reasoning steps, text deltas, tool calls, and tool
results.
- GraphQL APIs and queries updated to expose these structured streaming
objects in chat histories.
  - Introduced a new streaming chat endpoint for object-based responses.

- **Bug Fixes**
- Improved error handling for streaming responses to ensure more robust
and informative error reporting.

- **Refactor**
- Centralized and streamlined session preparation and streaming logic
for AI chat providers.
  - Unified streaming setup across multiple AI model providers.

- **Tests**
- Extended test coverage for streaming object responses to ensure
reliability and correctness.

- **Documentation**
- Updated type definitions and schemas to reflect new streaming object
capabilities in both backend and frontend code.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
This commit is contained in:
Wu Yue
2025-06-19 09:13:18 +08:00
committed by GitHub
parent ce951ec316
commit 6169cdab3a
24 changed files with 722 additions and 149 deletions
@@ -14,6 +14,14 @@ query getCopilotHistories(
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
@@ -617,6 +617,14 @@ export const getCopilotHistoriesQuery = {
id
role
content
streamObjects {
type
textDelta
toolCallId
toolName
args
result
}
attachments
createdAt
}
+20
View File
@@ -137,6 +137,7 @@ export interface ChatMessage {
id: Maybe<Scalars['ID']['output']>;
params: Maybe<Scalars['JSON']['output']>;
role: Scalars['String']['output'];
streamObjects: Maybe<Array<StreamObject>>;
}
export enum ContextCategories {
@@ -2195,6 +2196,16 @@ export interface SpaceShouldHaveOnlyOneOwnerDataType {
spaceId: Scalars['String']['output'];
}
export interface StreamObject {
__typename?: 'StreamObject';
args: Maybe<Scalars['JSON']['output']>;
result: Maybe<Scalars['JSON']['output']>;
textDelta: Maybe<Scalars['String']['output']>;
toolCallId: Maybe<Scalars['String']['output']>;
toolName: Maybe<Scalars['String']['output']>;
type: Scalars['String']['output'];
}
export interface SubscriptionAlreadyExistsDataType {
__typename?: 'SubscriptionAlreadyExistsDataType';
plan: Scalars['String']['output'];
@@ -3374,6 +3385,15 @@ export type GetCopilotHistoriesQuery = {
content: string;
attachments: Array<string> | null;
createdAt: string;
streamObjects: Array<{
__typename?: 'StreamObject';
type: string;
textDelta: string | null;
toolCallId: string | null;
toolName: string | null;
args: Record<string, string> | null;
result: Record<string, string> | null;
}> | null;
}>;
}>;
};