-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
feat(core): add stream object api #12841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: canary
Are you sure you want to change the base?
Conversation
## Walkthrough
This change introduces support for streaming structured objects ("stream objects") in the backend AI chat system. It adds a new database column, updates the Prisma schema, extends provider interfaces and implementations, introduces new GraphQL types and fields, and adds comprehensive test coverage for the new streaming object functionality.
## Changes
| File(s) / Group | Change Summary |
|--------------------------------------------------------------------------------------------------|---------------|
| migrations/20250617004240_ai_stream_objects_message/migration.sql, schema.prisma | Add `streamObjects` JSON column to `ai_sessions_messages` table and Prisma model. |
| .../src/plugins/copilot/providers/types.ts, .../type.ts | Define `StreamObjectSchema` and `StreamObject` type; extend message schemas to support `streamObjects`. |
| .../src/plugins/copilot/providers/provider.ts | Add abstract `streamObject` method to provider interface. |
| .../src/plugins/copilot/providers/utils.ts | Add `parseUnknownError` and `StreamObjectParser` for error handling and parsing stream objects. |
| .../src/plugins/copilot/providers/anthropic/anthropic.ts, .../gemini/gemini.ts, .../openai.ts | Implement `streamObject` method and shared streaming logic in providers. |
| .../src/plugins/copilot/providers/anthropic/official.ts, .../anthropic/vertex.ts, .../gemini/generative.ts, .../gemini/vertex.ts, .../openai.ts, .../mocks/copilot.mock.ts | Update model capabilities to include `ModelOutputType.Object`. |
| .../src/plugins/copilot/controller.ts | Refactor session preparation logic; add new SSE endpoint for streaming objects. |
| .../src/plugins/copilot/session.ts | Persist and retrieve `streamObjects` in chat session messages. |
| .../src/plugins/copilot/resolver.ts, .../src/schema.gql, .../graphql/src/schema.ts | Add `StreamObject` GraphQL type and integrate with `ChatMessage`. |
| .../graphql/src/graphql/copilot-history-list.gql, .../graphql/src/graphql/index.ts | Extend queries to retrieve `streamObjects` in histories. |
| .../src/__tests__/copilot-provider.spec.ts, .../copilot.e2e.ts, .../mocks/copilot.mock.ts, .../utils/copilot.ts | Add/extend tests for streaming object functionality. |
| .../frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts | Add frontend schema and type for `StreamObject` and extend chat message schema. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant Client
participant Controller
participant Provider
participant SessionService
participant Database
Client->>Controller: Request /stream-object (SSE)
Controller->>SessionService: Prepare session, get provider/model
Controller->>Provider: streamObject(model, messages, options)
loop Stream chunks
Provider-->>Controller: StreamObject
Controller-->>Client: StreamObject (SSE)
Controller->>SessionService: Save StreamObjects and content
SessionService->>Database: Store message with streamObjects
end Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Suggested reviewers
Poem
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## canary #12841 +/- ##
==========================================
+ Coverage 55.93% 56.01% +0.07%
==========================================
Files 2658 2658
Lines 125982 126408 +426
Branches 20031 20065 +34
==========================================
+ Hits 70474 70804 +330
- Misses 53172 53254 +82
- Partials 2336 2350 +14
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (13)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql (1)
1-2
: Validate JSON vs JSONB usage for performance
Consider usingJSONB
instead ofJSON
for thestreamObjects
column to gain indexing and performance benefits in Postgres, and think about whether a default empty array (DEFAULT '[]'
) orNOT NULL
constraint is desirable.packages/backend/server/src/__tests__/utils/copilot.ts (1)
585-592
: Align return type with other chat helpers
The newchatWithStreamObject
helper mirrorschatWithTextStream
; consider adding a return type annotation (: Promise<string>
) for consistency and clarity.packages/backend/server/src/schema.gql (1)
1632-1639
: Add basic description blocks to the newly introducedStreamObject
typeSDL generated docs are empty; a short description clarifies its intent for GraphQL-first consumers and tooling such as GraphiQL.
packages/backend/server/src/__tests__/copilot.e2e.ts (1)
516-536
: Tests pass but duplicate generator logic – consider a small helper
Array.from('generate text to object stream').map(...)
is now repeated in three places for the different stream tests (text, text-stream, object-stream). A tiny helper such asbuildTextDeltaStream(content: string)
would remove duplication and make intent clearer.-const objects = Array.from('generate text to object stream').map(data => - JSON.stringify({ type: 'text-delta', textDelta: data }) -); +const objects = buildTextDeltaStream('generate text to object stream');Nice-to-have only – feel free to skip if you think the duplication is acceptable.
packages/backend/server/src/plugins/copilot/session.ts (1)
283-289
: Duplicate property spread may silently mask bugs
...m
already containsstreamObjects
/attachments
/params
. Re-adding them on the next lines is redundant and makes the effective precedence non-obvious.- data: state.messages.map(m => ({ - ...m, - streamObjects: m.streamObjects || undefined, - attachments: m.attachments || undefined, - params: omit(m.params, ['docs']) || undefined, - sessionId, - })), + data: state.messages.map(m => ({ + ...omit(m, ['params']), // avoid double assignment + streamObjects: m.streamObjects || undefined, + attachments: m.attachments || undefined, + params: omit(m.params, ['docs']) || undefined, + sessionId, + })),Removing the first spread or the explicit overrides would be cleaner.
packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (1)
3-25
: Schema duplication – export or share from a common package
StreamObjectSchema
is now defined here and inbackend/providers/types.ts
. Divergence between the two copies is a maintainability risk.Suggestion: move the schema to
packages/common/graphql
(or similar) and import it in both places, or at least export the constant so consumers can reference a single source.No immediate functional bug – purely a maintainability note.
packages/backend/server/src/plugins/copilot/resolver.ts (1)
204-206
: Type import is unused at runtime – safe, but ESLint may complain
StreamObject
is referenced only as a TS type. If your linter flags unused values, addimport type { … }
or// eslint-disable-next-line @typescript-eslint/consistent-type-imports
to avoid false positives.packages/backend/server/src/plugins/copilot/providers/types.ts (2)
145-150
: Makecontent
truly optional whenstreamObjects
are present
content
is required even for pure streaming-object messages. Call-sites will have to pass an empty string, which is easy to forget and clutters data. Making it optional simplifies usage and enforces exactly one source of truth per message.- content: z.string(), + content: z.string().optional(),NB: If you still need at least one of
content
orstreamObjects
, wrap the whole schema in arefine
for mutual exclusivity.
157-157
: Duplicate type alias – consider a single, central export
StreamObject
now exists both here and inpackages/frontend/core/.../type.ts
. Divergence risks creep in quickly. Re-export the type from one place (e.g.@affine/copilot-types
) and import it everywhere else.packages/backend/server/src/__tests__/mocks/copilot.mock.ts (2)
20-114
: Model capability list is highly repetitive – extract a helperThe same capability object (
input: [Text, Image] / output: [Text, Object]
) is duplicated many times, which is error-prone when the enum evolves. A tiny factory or shared constant keeps things DRY:const textObjectCap = { input: [ModelInputType.Text, ModelInputType.Image], output: [ModelOutputType.Text, ModelOutputType.Object], }; this.models = [ { id: 'test', capabilities: [{ ...textObjectCap, input: [ModelInputType.Text], defaultForOutputType: true }] }, { id: 'gpt-4o', capabilities: [textObjectCap] }, … ];Not critical for a mock, but tidier and easier to maintain.
208-226
:streamObject
yields one character per delta – adequate for tests but maybe misleadingThe generator currently does:
for (const data of result /* plain string */) { yield { type: 'text-delta', textDelta: data }; }So
"foo"
streams three separate deltas"f","o","o"
. Real providers usually chunk by token or sentence, not single UTF-16 code unit. If the tests rely on more realistic behaviour, consider:- for (const data of result) { - yield { type: 'text-delta', textDelta: data } as const; + for (const token of result.split(' ')) { // or your tokeniser + yield { type: 'text-delta', textDelta: token }; }This keeps the mock closer to production behaviour without extra complexity.
packages/common/graphql/src/schema.ts (1)
132-141
:streamObjects
should probably be non-nullable and default to an empty listIn practice a consumer usually has to branch on three cases (
null | [] | [...data]
).
If the resolver always returns an array (possibly empty) and you define the field asstreamObjects: [StreamObject!]!
, the caller’s logic and generated types are simpler, and it avoids the common “cannot read property ‘length’ of null” foot-gun.If there is a hard reason to expose
null
, please document the difference between “missing” and “present but empty”.packages/backend/server/src/__tests__/copilot-provider.spec.ts (1)
188-201
: Consider logging validation errors for easier debugging.The validation logic is correct, but consider logging the error before returning false to help with debugging test failures.
const checkStreamObjects = (result: string) => { try { const streamObjects = JSON.parse(result); if (!Array.isArray(streamObjects)) { return false; } for (const streamObject of streamObjects) { StreamObjectSchema.parse(streamObject); } return true; - } catch { + } catch (error) { + console.error('Stream object validation failed:', error); return false; } };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(4 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(3 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
packages/backend/server/src/__tests__/utils/copilot.ts (1)
packages/backend/server/src/__tests__/e2e/test.ts (1)
app
(8-8)
packages/backend/server/src/plugins/copilot/providers/provider.ts (3)
packages/backend/server/src/plugins/copilot/providers/types.ts (4)
ModelConditions
(233-236)PromptMessage
(155-155)CopilotChatOptions
(176-176)StreamObject
(157-157)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (1)
StreamObject
(27-27)packages/common/graphql/src/schema.ts (1)
StreamObject
(2199-2207)
packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (2)
packages/backend/server/src/plugins/copilot/providers/types.ts (2)
StreamObjectSchema
(121-143)StreamObject
(157-157)packages/common/graphql/src/schema.ts (1)
StreamObject
(2199-2207)
packages/backend/server/src/plugins/copilot/providers/types.ts (2)
packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (1)
StreamObject
(27-27)packages/common/graphql/src/schema.ts (1)
StreamObject
(2199-2207)
packages/backend/server/src/__tests__/copilot-provider.spec.ts (4)
packages/backend/server/src/__tests__/mocks/copilot.mock.ts (1)
streamObject
(208-226)packages/backend/server/src/plugins/copilot/providers/openai.ts (1)
streamObject
(370-401)packages/backend/server/src/plugins/copilot/providers/types.ts (2)
StreamObjectSchema
(121-143)StreamObject
(157-157)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (1)
StreamObject
(27-27)
packages/backend/server/src/__tests__/copilot.e2e.ts (2)
packages/backend/server/src/__tests__/utils/copilot.ts (4)
createCopilotSession
(20-36)createCopilotMessage
(490-542)chatWithStreamObject
(585-591)textToEventStream
(628-638)packages/backend/server/src/__tests__/e2e/test.ts (1)
app
(8-8)
⏰ Context from checks skipped due to timeout of 90000ms (51)
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: test-build-mobile-app / build-ios-web
- GitHub Check: E2E BlockSuite Cross Browser Test (2, webkit)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, firefox)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E Test (5)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, chromium)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, webkit)
- GitHub Check: Build @affine/electron renderer
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, chromium)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, firefox)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: Build Server native
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: Build AFFiNE native (aarch64-pc-windows-msvc)
- GitHub Check: y-octo binding test on x86_64-apple-darwin
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: Build AFFiNE native (x86_64-pc-windows-msvc)
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: Build AFFiNE native (x86_64-apple-darwin)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: Run native tests
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: loom thread test
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Build AFFiNE native (aarch64-apple-darwin)
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: Typecheck
- GitHub Check: Lint
🔇 Additional comments (31)
packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts (2)
26-30
: Approve adding Object output capability
IncludingModelOutputType.Object
in the first model’s outputs aligns this provider with others and enables structured object streaming.
44-48
: Approve adding Object output capability
The same update for the "Gemini 2.5 Pro" model is correct—ModelOutputType.Object
support is now in place.packages/backend/server/schema.prisma (1)
416-423
: Prisma schema updated to store stream objects
The optionalstreamObjects
JSON field onAiSessionMessage
is correctly added betweencontent
andattachments
. Ensure client code generation is rerun.packages/common/graphql/src/graphql/copilot-history-list.gql (1)
17-24
: Expose newstreamObjects
field in query
The GraphQL query now retrieves all relevant properties ofstreamObjects
. Confirm that the server schema and client typings include this new field.packages/common/graphql/src/graphql/index.ts (1)
620-627
: Consider factoringstreamObjects
selection into a fragment
streamObjects
is now projected inline in every history query. Since it is a stable, reusable field set, extracting it into a small fragment (e.g.StreamObjectFields
) would keep the generated file shorter and make future field-level changes less error-prone.- streamObjects { - type - textDelta - toolCallId - toolName - args - result - } + ...StreamObjectFields ... +fragment StreamObjectFields on StreamObject { + type + textDelta + toolCallId + toolName + args + result +}[ suggest_optional_refactor ]
packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts (1)
21-22
: Verify a default “object” model is really selectedOnly the last capability marks
defaultForOutputType: true
.
If callers requestoutputType = ModelOutputType.Object
without an explicitmodelId
, every other model will be skipped even when it supports object output, and Sonnet-v2 is always chosen.
Please confirm this is intentional; otherwise mark one capability per model, or move the flag to the capability that is actually intended to be the fallback.[ request_verification ]
Also applies to: 30-31, 39-40, 48-50
packages/backend/server/src/schema.gql (1)
93-100
:content
should be nullable now that messages may contain onlystreamObjects
With object streaming a message can legitimately have no text.
Keepingcontent: String!
forces producers to emit an empty string, breaking semantic validation elsewhere (e.g.min(1)
checks inPromptMessageSchema
). Recommend relaxing the field:- content: String! + content: StringThis change ripples to generated typings and the Zod schema, but avoids inconsistent data and simplifies validation.
[ raise_critical_issue ]
packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts (1)
23-24
: Same default-model caveat as Vertex providerSee the comment on
AnthropicVertexProvider
: onlyclaude-3-5-sonnet-20241022
is markeddefaultForOutputType
. A generic “object” request will bypass Opus/Sonnet-4 even if they are superior. Double-check this selection logic.[ request_verification ]
Also applies to: 32-33, 41-42, 50-52
packages/backend/server/src/plugins/copilot/providers/provider.ts (1)
36-37
: Abstract method name bikeshedding – plural vs. singularThe new API is
streamObject
but returns anAsyncIterable<StreamObject>
(plural). To stay parallel withstreamText
, considerstreamObjects
to avoid confusion.Not blocking, but aligning the naming now is cheaper than later API churn.
[ suggest_nitpick ]
Also applies to: 229-234
packages/backend/server/src/__tests__/copilot.e2e.ts (1)
42-44
: Import looks good – no action required
Nothing to flag regarding the addedchatWithStreamObject
import.packages/backend/server/src/plugins/copilot/session.ts (1)
512-520
: Good –streamObjects
now fetched for history queries
IncludingstreamObjects
in themessages.select
list is essential for the new UI. Nice catch.packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts (1)
28-33
: Capability update is correct
AddingModelOutputType.Object
aligns Gemini models with the new streaming-object feature. No further changes required here.Also applies to: 47-52, 65-69
packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts (1)
34-35
: Minor type mismatch with backend attachment union (outside this PR)
Frontend still restrictsattachments
tostring[]
, whereas backend allows mixed string / { attachment, mimeType }. Not introduced by this PR, but worth aligning in the future to avoid runtime casting.packages/backend/server/src/plugins/copilot/resolver.ts (1)
171-190
: GraphQL type aligns with backend object – good
StreamObjectType
mirrors the discriminated-union contract; nullable fields are correctly marked.packages/backend/server/src/plugins/copilot/providers/types.ts (1)
214-220
: Confirm semantic split betweenObject
andStructured
output types
ModelOutputType
already containsStructured
; introducingObject
may confuse downstream filtering logic unless the semantics are crystal-clear. Please verify:
- Providers return distinct payloads for the two.
- Capability resolution and default selection handle them correctly.
If they are synonyms, prefer a single enum member to avoid branching.
packages/common/graphql/src/schema.ts (1)
3388-3396
: Large nested selection may bloat theGetCopilotHistories
payloadThe query now pulls
streamObjects
(including JSON-typedargs
/result
) for every message in every session.
For long histories this can explode response size and cause noticeable latency.Consider adding a parameter to make
streamObjects
opt-in (e.g.includeStreamObjects
boolean inQueryChatHistoriesInput
) or slicing the message set.Please benchmark the worst-case payload size with realistic sessions and check whether the current CDN / client cache limits are hit.
packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts (3)
159-159
: Good refactoring to reduce code duplication.The extraction of common streaming logic into the
getFullStream
helper method improves maintainability.
175-206
: Well-implemented streaming object method.The
streamObject
method correctly implements structured object streaming with proper error handling, metrics tracking, and cancellation support. The implementation is consistent with the existingstreamText
pattern.
208-227
: Clean extraction of common streaming logic.The
getFullStream
method effectively consolidates the streaming setup, properly handling system prompts, messages, and provider-specific options.packages/backend/server/src/__tests__/copilot-provider.spec.ts (2)
407-420
: Good test coverage for streaming objects.The test case properly validates the new streaming object functionality.
714-734
: Correct implementation of object streaming test runner.The test runner properly collects stream objects and converts them to JSON for verification.
packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts (1)
117-169
: Consistent implementation across providers.The Anthropic provider correctly implements the same streaming object pattern as other providers, with proper handling of Anthropic-specific options like tools and multi-step support.
packages/backend/server/src/plugins/copilot/providers/utils.ts (3)
390-404
: Robust error parsing utility.The
parseUnknownError
function properly handles various error types and ensures consistent Error instances are thrown.
465-466
: Good use of centralized error handling.Using
parseUnknownError
improves robustness compared to directly accessingchunk.error.message
.
510-528
: Clean implementation of StreamObjectParser.The parser correctly handles the supported chunk types and maintains consistent error handling.
packages/backend/server/src/plugins/copilot/controller.ts (2)
193-229
: Excellent refactoring to centralize session preparation.The
prepareChatSession
method effectively reduces code duplication. Note that it currently hardcodesModelOutputType.Text
when choosing the provider, which is appropriate for the current usage but may need adjustment if used for other output types in the future.
346-440
: Well-implemented streaming object endpoint.The
chatStreamObject
endpoint correctly:
- Merges consecutive chunks of the same type to reduce redundancy
- Extracts content only from text-delta chunks
- Persists both content and structured stream objects to the session
- Maintains consistency with other streaming endpoints for error handling and metrics
packages/backend/server/src/plugins/copilot/providers/openai.ts (4)
75-76
: LGTM! Consistent model capability updates.The addition of
ModelOutputType.Object
to model capabilities is consistently applied across all relevant OpenAI models. The newer models (gpt-4.1 series) appropriately include both Object and Structured output types.Also applies to: 85-85, 94-94, 104-104, 113-117, 127-131, 140-144, 153-157, 166-166, 175-175, 184-184
338-338
: Good refactoring to reduce code duplication.Extracting the stream setup logic to
getFullStream
improves maintainability and ensures consistency betweenstreamText
andstreamObject
methods.
370-401
: Well-structured implementation of streamObject method.The new method follows the established patterns in the codebase:
- Proper parameter validation and model selection
- Consistent error handling and metrics tracking
- Correct handling of abort signals
- Clean separation of concerns with
StreamObjectParser
443-466
: Clean extraction of stream setup logic.The
getFullStream
method successfully consolidates the common streaming setup code, making it reusable betweenstreamText
andstreamObject
while maintaining all the necessary configuration options.
92571c7
to
640bfa3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/backend/server/src/plugins/copilot/controller.ts (1)
426-439
: Metric name inconsistency – object stream errors counted as text streamThe outer
catch
block incrementschat_stream_errors
instead ofchat_object_stream_errors
, skewing dashboards and alerts.- metrics.ai.counter('chat_stream_errors').add(1, info); + metrics.ai.counter('chat_object_stream_errors').add(1, info);packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts (1)
150-169
:getFullStream
duplicated across providers – consider elevating to base classAlmost identical helper logic (
chatToGPTMessage
+streamText({...}).fullStream
) now exists in Anthropic, OpenAI, Gemini, etc. Extracting it intoCopilotProvider
(or a small mix-in) would:• eliminate copy-paste bugs,
• keep all provider-agnostic options (tools, maxSteps, continueSteps) in one place,
• make future tweaks (e.g. retry, logging) one-shot.No functional blocker, but worthwhile to improve maintainability.
packages/backend/server/src/plugins/copilot/providers/openai.ts (1)
443-466
: SamegetFullStream
boilerplate here – centralise or shareSee similar comment in Anthropic provider: this block is nearly identical (aside from provider-specific option mapping). A shared utility would avoid drift between providers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(4 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(3 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (21)
- packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
- packages/common/graphql/src/graphql/index.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
- packages/backend/server/schema.prisma
- packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
- packages/backend/server/src/tests/utils/copilot.ts
- packages/backend/server/src/plugins/copilot/session.ts
- packages/common/graphql/src/graphql/copilot-history-list.gql
- packages/backend/server/src/plugins/copilot/providers/provider.ts
- packages/backend/server/src/plugins/copilot/resolver.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
- packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
- packages/backend/server/src/schema.gql
- packages/backend/server/src/plugins/copilot/providers/types.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
- packages/backend/server/src/tests/mocks/copilot.mock.ts
- packages/backend/server/src/tests/copilot.e2e.ts
- packages/backend/server/src/plugins/copilot/providers/utils.ts
- packages/backend/server/src/tests/copilot-provider.spec.ts
- packages/common/graphql/src/schema.ts
⏰ Context from checks skipped due to timeout of 90000ms (57)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (3)
- GitHub Check: Native Unit Test
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: test-build-mobile-app / build-ios-web
- GitHub Check: E2E Test (8)
- GitHub Check: fuzzing
- GitHub Check: y-octo binding test on aarch64-unknown-linux-gnu
- GitHub Check: y-octo binding test on aarch64-apple-darwin
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Cross Browser Test (1, webkit)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E Test (5)
- GitHub Check: y-octo binding test on x86_64-apple-darwin
- GitHub Check: E2E Test (1)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, firefox)
- GitHub Check: Run native tests
- GitHub Check: E2E BlockSuite Cross Browser Test (1, chromium)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, webkit)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, chromium)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, firefox)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: Build @affine/electron renderer
- GitHub Check: Build AFFiNE native (x86_64-pc-windows-msvc)
- GitHub Check: loom thread test
- GitHub Check: Build AFFiNE native (aarch64-pc-windows-msvc)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Build Server native
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: Lint
- GitHub Check: Typecheck
🔇 Additional comments (1)
packages/backend/server/src/plugins/copilot/providers/openai.ts (1)
370-401
: Guard againstundefined
yields fromStreamObjectParser
parser.parse(chunk)
may returnundefined
for non-boundary chunks, but the current loop already filters withif (result)
. Good.
However, whenchunk.type === 'finish'
,StreamObjectParser
can emit any remaining buffered object(s). Ensure the parser implementation returns all pending objects; otherwise the terminal piece may be lost.
If the parser returns an array on finish, adapt the yield logic accordingly.Just flagging for verification – no change required if the utility already handles this.
37f9b85
to
3e1de13
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (3)
packages/backend/server/src/plugins/copilot/controller.ts (2)
399-411
: Collecting the whole stream into memory may hurt large responses
shared$.pipe(toArray(), …)
buffers everyStreamObject
chunk before persisting the message.
For lengthy object streams this can explode memory and delay DB writes.Consider incremental persistence instead:
-shared$.pipe( - toArray(), - concatMap(values => { - … - }) +shared$.pipe( + bufferTime(500), // or bufferCount(N) + filter(buf => buf.length), + mergeMap(buf => { + const parser = new StreamObjectParser(); + const objects = parser.mergeTextDelta(buf); + … + })This keeps memory bounded and makes partial results visible sooner.
255-257
: Minor duplication – query is parsed three times
ChatQuerySchema.parse(query)
is invoked inprepareChatSession
, then again in each endpoint to extractreasoning
,webSearch
, etc.
Returning these flags fromprepareChatSession
would avoid redundant schema validation.Also applies to: 308-310, 381-383
packages/backend/server/src/plugins/copilot/providers/utils.ts (1)
390-404
: DeclareparseUnknownError
asnever
The helper always throws, so its signature should reflect that.
This lets TypeScript flag unreachable code and prevents “falls through but returns void” confusion.-export function parseUnknownError(error: unknown) { +export function parseUnknownError(error: unknown): never { … }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(5 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(4 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
- packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
- packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
- packages/backend/server/src/tests/copilot.e2e.ts
- packages/backend/server/schema.prisma
- packages/backend/server/src/tests/utils/copilot.ts
- packages/common/graphql/src/graphql/copilot-history-list.gql
- packages/common/graphql/src/graphql/index.ts
- packages/backend/server/src/plugins/copilot/session.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
- packages/backend/server/src/plugins/copilot/providers/provider.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
- packages/backend/server/src/tests/mocks/copilot.mock.ts
- packages/backend/server/src/schema.gql
- packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
- packages/backend/server/src/plugins/copilot/providers/types.ts
- packages/backend/server/src/plugins/copilot/resolver.ts
- packages/backend/server/src/tests/copilot-provider.spec.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
- packages/backend/server/src/plugins/copilot/providers/openai.ts
- packages/common/graphql/src/schema.ts
⏰ Context from checks skipped due to timeout of 90000ms (703)
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Lint
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: test-build-mobile-app / android
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: test-build-mobile-app / android
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: test-build-mobile-app / android
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: test-build-mobile-app / android
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: test-build-mobile-app / android
- GitHub Check: Cloud E2E Test 4/6
- GitHub Check: Frontend Copilot E2E Test (6, 8)
- GitHub Check: Cloud E2E Test 3/6
- GitHub Check: Cloud E2E Test 6/6
- GitHub Check: Cloud E2E Test 1/6
- GitHub Check: Cloud Desktop E2E Test
- GitHub Check: Cloud E2E Test 5/6
- GitHub Check: Server Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (8, 8)
- GitHub Check: Cloud E2E Test 2/6
- GitHub Check: Check Git Status
- GitHub Check: Frontend Copilot E2E Test (7, 8)
- GitHub Check: Frontend Copilot E2E Test (2, 8)
- GitHub Check: Server E2E Test
- GitHub Check: Frontend Copilot E2E Test (5, 8)
- GitHub Check: Frontend Copilot E2E Test (3, 8)
- GitHub Check: Frontend Copilot E2E Test (1, 8)
- GitHub Check: Server Test (6, 8)
- GitHub Check: Frontend Copilot E2E Test (4, 8)
- GitHub Check: Server Test (5, 8)
- GitHub Check: Server Test with Elasticsearch
- GitHub Check: Server Test (7, 8)
- GitHub Check: Server Test (4, 8)
- GitHub Check: Server Test (0, 8)
- GitHub Check: Server Copilot Api Test
- GitHub Check: Server Test (1, 8)
- GitHub Check: Server Test (2, 8)
- GitHub Check: Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop bundle check (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true)
- GitHub Check: Desktop bundle check (macos-latest, macos, arm64, aarch64-apple-darwin, true)
- GitHub Check: Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true)
- GitHub Check: Unit Test (4)
- GitHub Check: Unit Test (5)
- GitHub Check: Unit Test (2)
- GitHub Check: Unit Test (1)
- GitHub Check: Unit Test (3)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (5)
- GitHub Check: Typecheck
- GitHub Check: fuzzing
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
🔇 Additional comments (1)
packages/backend/server/src/plugins/copilot/controller.ts (1)
193-230
: 👍 Well-factoredprepareChatSession
helperPulling the common boilerplate (provider selection, message stashing, param merging) into a single method noticeably cuts duplication and makes the three endpoints easier to reason about.
3e1de13
to
28bfa95
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/backend/server/src/plugins/copilot/controller.ts (4)
193-230
: Consider returning the parsed query to avoid triple-parsing
prepareChatSession
is a valuable extraction, but every call-site still has to callChatQuerySchema.parse
again forreasoning
,webSearch
, andmessageId
.
Returning the parse result (or at least those three fields) from this helper would:
- remove duplicate parsing logic in
chat
,chatStream
, andchatStreamObject
;- avoid the extra Zod validation cost on every request;
- keep the controller code a bit tidier.
- private async prepareChatSession( + private async prepareChatSession( … - ) { - let { messageId, retry, modelId, params } = ChatQuerySchema.parse(query); + ): Promise<{ + provider: CopilotProvider; + model: string; + session: ChatSession; + finalMessage: ChatMessage[]; + parsed: ReturnType<typeof ChatQuerySchema.parse>; // <─ new + }> { + const parsed = ChatQuerySchema.parse(query); + let { messageId, retry, modelId, params } = parsed; … - return { - provider, - model, - session, - finalMessage, - }; + return { provider, model, session, finalMessage, parsed }; }Call-sites can then use
parsed.reasoning
etc. without a second Zod round-trip.
Not critical, but worth the small refactor.
243-256
: Duplicate parsing immediately after helper callRight after invoking
prepareChatSession
, the code re-parsesquery
to extractreasoning
/webSearch
. If the previous comment is applied this block can simply use the already-returned data and drop the redundantChatQuerySchema.parse
.
295-308
: Same duplicate parsing pattern here
chatStream
repeats the same extra parse; onceprepareChatSession
exposes the parsed result this duplication disappears.
399-414
: Possible memory bloat when buffering the full object stream
shared$.pipe(toArray())
buffers every streamed object chunk until the stream completes before persisting the message. For very long object streams this can grow unbounded and delay persistence until the end.A lighter approach:
- accumulate
StreamObject
s in a local array and persist every N chunks or on a throttle window; or- use
reduce
to build the merged objects incrementally without keeping all raw chunks.Not a blocker (the text endpoint already behaves similarly), but worth revisiting if large object streams are expected.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(5 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(4 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (23)
- packages/backend/server/schema.prisma
- packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
- packages/common/graphql/src/graphql/copilot-history-list.gql
- packages/backend/server/src/tests/utils/copilot.ts
- packages/backend/server/src/plugins/copilot/session.ts
- packages/common/graphql/src/graphql/index.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
- packages/backend/server/src/schema.gql
- packages/backend/server/src/plugins/copilot/providers/provider.ts
- packages/backend/server/src/plugins/copilot/resolver.ts
- packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
- packages/backend/server/src/tests/copilot.e2e.ts
- packages/backend/server/src/plugins/copilot/providers/types.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
- packages/backend/server/src/tests/mocks/copilot.mock.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
- packages/backend/server/src/tests/copilot-provider.spec.ts
- packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
- packages/backend/server/src/plugins/copilot/providers/openai.ts
- packages/backend/server/src/plugins/copilot/providers/utils.ts
- packages/common/graphql/src/schema.ts
🧰 Additional context used
🪛 ESLint
packages/backend/server/src/plugins/copilot/controller.ts
[error] 382-382: Finnish notation should not be used here.
(rxjs/finnish)
[error] 392-392: Finnish notation should not be used here.
(rxjs/finnish)
⏰ Context from checks skipped due to timeout of 90000ms (54)
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: test-build-mobile-app / build-ios-web
- GitHub Check: loom thread test
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: y-octo binding test on x86_64-apple-darwin
- GitHub Check: y-octo binding test on aarch64-unknown-linux-gnu
- GitHub Check: E2E Test (6)
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: y-octo binding test on x86_64-unknown-linux-gnu
- GitHub Check: Run native tests
- GitHub Check: fuzzing
- GitHub Check: y-octo binding test on aarch64-apple-darwin
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, chromium)
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (5)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, firefox)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, webkit)
- GitHub Check: Build AFFiNE native (x86_64-unknown-linux-gnu)
- GitHub Check: Build AFFiNE native (x86_64-apple-darwin)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, chromium)
- GitHub Check: Build AFFiNE native (aarch64-pc-windows-msvc)
- GitHub Check: Build AFFiNE native (x86_64-pc-windows-msvc)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, firefox)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, webkit)
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Build @affine/electron renderer
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: Lint
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Build Server native
- GitHub Check: Typecheck
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Analyze (javascript, affine)
🔇 Additional comments (1)
packages/backend/server/src/plugins/copilot/controller.ts (1)
384-390
: Workspace context now forwarded – good catchThe provider options for
streamObject
now includeworkspace: session.config.workspaceId
, fixing the tenant-scoping issue flagged in the previous review.
28bfa95
to
1bc9e60
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/backend/server/src/plugins/copilot/providers/utils.ts (2)
465-466
: Unreachablebreak
after a guaranteed throw
parseUnknownError
never returns, so thebreak
can’t execute.- parseUnknownError(chunk.error); - break; + parseUnknownError(chunk.error);
520-522
: Same unreachable path inStreamObjectParser.parse
- parseUnknownError(chunk.error); - return null; + parseUnknownError(chunk.error);
🧹 Nitpick comments (2)
packages/backend/server/src/plugins/copilot/controller.ts (1)
381-390
: Nit: avoid double-parsing the query
ChatQuerySchema.parse(query)
is executed once inprepareChatSession
(line 199) and then repeated here just to pluckreasoning
/webSearch
. Consider returning those flags fromprepareChatSession
(or caching the parsed result) to avoid the redundant validation pass.packages/backend/server/src/plugins/copilot/providers/utils.ts (1)
510-527
: Add explicit return type toStreamObjectParser.parse
Declaring the intent helps TypeScript catch future regressions.
-public parse(chunk: TextStreamPart<CustomAITools>) { +public parse(chunk: TextStreamPart<CustomAITools>): StreamObject | null {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(5 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(4 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (21)
- packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
- packages/backend/server/schema.prisma
- packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
- packages/backend/server/src/tests/utils/copilot.ts
- packages/backend/server/src/plugins/copilot/session.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
- packages/common/graphql/src/graphql/copilot-history-list.gql
- packages/backend/server/src/plugins/copilot/providers/provider.ts
- packages/common/graphql/src/graphql/index.ts
- packages/backend/server/src/tests/copilot.e2e.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
- packages/backend/server/src/schema.gql
- packages/backend/server/src/tests/mocks/copilot.mock.ts
- packages/backend/server/src/plugins/copilot/resolver.ts
- packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
- packages/backend/server/src/plugins/copilot/providers/types.ts
- packages/common/graphql/src/schema.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
- packages/backend/server/src/tests/copilot-provider.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms (48)
- GitHub Check: test-build-mobile-app / build-ios-web
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: y-octo binding test on aarch64-unknown-linux-gnu
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: y-octo binding test on x86_64-apple-darwin
- GitHub Check: E2E BlockSuite Cross Browser Test (1, webkit)
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: fuzzing
- GitHub Check: E2E BlockSuite Cross Browser Test (2, firefox)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, chromium)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, firefox)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, chromium)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, webkit)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E Test (9)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E Test (5)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E Test (10)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: Build Server native
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: Build @affine/electron renderer
- GitHub Check: Typecheck
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Build AFFiNE native (aarch64-pc-windows-msvc)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: Build AFFiNE native (x86_64-pc-windows-msvc)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Lint
🔇 Additional comments (2)
packages/backend/server/src/plugins/copilot/controller.ts (1)
193-230
:prepareChatSession
abstraction looks solidThe new helper eliminates the duplicated boilerplate around provider selection, message rewinding and
session.finish()
. The extraoutputType
parameter also solves the previous hard-coding issue.
No further concerns here.packages/backend/server/src/plugins/copilot/providers/openai.ts (1)
370-401
:streamObject
implementation reusesgetFullStream
nicelyLogic mirrors
streamText
and keeps the parser concerns separated – looks good.
No blocking issues detected.
1bc9e60
to
ccb026b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
packages/backend/server/src/plugins/copilot/providers/openai.ts (1)
359-363
: Cancel stream infinally
to avoid leaks on happy-path completion
fullStream.cancel()
is called only whenoptions.signal.aborted
fires.
If the consumer simply stops iterating early (e.g. client disconnect), the generator exits without cancelling, leaving the upstream request alive.Add a
finally
block:- for await (const chunk of fullStream) { - … - } + try { + for await (const chunk of fullStream) { … } + } finally { + await fullStream.cancel?.(); + }Same pattern applies to
streamObject
.
🧹 Nitpick comments (1)
packages/backend/server/src/plugins/copilot/controller.ts (1)
193-230
: Consider exposingreasoning
,webSearch
, &messageId
fromprepareChatSession
to avoid repeated schema parsingEach endpoint still calls
ChatQuerySchema.parse(query)
after invokingprepareChatSession
, duplicating work already done on line 199.
Returning these fields (or the whole parsed object) fromprepareChatSession
would:
- remove three extra parses per request
- guarantee the same canonical values are used everywhere
- marginally simplify each handler’s body
Not urgent, but worth a small follow-up refactor.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
(1 hunks)packages/backend/server/schema.prisma
(1 hunks)packages/backend/server/src/__tests__/copilot-provider.spec.ts
(5 hunks)packages/backend/server/src/__tests__/copilot.e2e.ts
(2 hunks)packages/backend/server/src/__tests__/mocks/copilot.mock.ts
(9 hunks)packages/backend/server/src/__tests__/utils/copilot.ts
(1 hunks)packages/backend/server/src/plugins/copilot/controller.ts
(5 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
(4 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/openai.ts
(15 hunks)packages/backend/server/src/plugins/copilot/providers/provider.ts
(2 hunks)packages/backend/server/src/plugins/copilot/providers/types.ts
(3 hunks)packages/backend/server/src/plugins/copilot/providers/utils.ts
(4 hunks)packages/backend/server/src/plugins/copilot/resolver.ts
(3 hunks)packages/backend/server/src/plugins/copilot/session.ts
(2 hunks)packages/backend/server/src/schema.gql
(2 hunks)packages/common/graphql/src/graphql/copilot-history-list.gql
(1 hunks)packages/common/graphql/src/graphql/index.ts
(1 hunks)packages/common/graphql/src/schema.ts
(3 hunks)packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (22)
- packages/backend/server/migrations/20250617004240_ai_stream_objects_message/migration.sql
- packages/backend/server/src/plugins/copilot/providers/gemini/vertex.ts
- packages/backend/server/src/plugins/copilot/providers/provider.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/vertex.ts
- packages/backend/server/src/plugins/copilot/session.ts
- packages/common/graphql/src/graphql/copilot-history-list.gql
- packages/backend/server/schema.prisma
- packages/backend/server/src/tests/copilot.e2e.ts
- packages/backend/server/src/tests/utils/copilot.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/generative.ts
- packages/backend/server/src/schema.gql
- packages/frontend/core/src/blocksuite/ai/components/ai-chat-messages/type.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/official.ts
- packages/backend/server/src/plugins/copilot/resolver.ts
- packages/backend/server/src/tests/mocks/copilot.mock.ts
- packages/backend/server/src/plugins/copilot/providers/gemini/gemini.ts
- packages/backend/server/src/plugins/copilot/providers/types.ts
- packages/backend/server/src/plugins/copilot/providers/anthropic/anthropic.ts
- packages/common/graphql/src/graphql/index.ts
- packages/backend/server/src/tests/copilot-provider.spec.ts
- packages/backend/server/src/plugins/copilot/providers/utils.ts
- packages/common/graphql/src/schema.ts
🧰 Additional context used
🪛 ESLint
packages/backend/server/src/plugins/copilot/controller.ts
[error] 382-382: Finnish notation should not be used here.
(rxjs/finnish)
[error] 392-392: Finnish notation should not be used here.
(rxjs/finnish)
⏰ Context from checks skipped due to timeout of 90000ms (57)
- GitHub Check: test-build-mobile-app / build-android-web
- GitHub Check: test-build-mobile-app / build-ios-web
- GitHub Check: Build Server native
- GitHub Check: fuzzing
- GitHub Check: y-octo binding test on x86_64-pc-windows-msvc
- GitHub Check: y-octo binding test on aarch64-apple-darwin
- GitHub Check: y-octo binding test on aarch64-pc-windows-msvc
- GitHub Check: y-octo binding test on aarch64-unknown-linux-gnu
- GitHub Check: loom thread test
- GitHub Check: y-octo binding test on x86_64-unknown-linux-gnu
- GitHub Check: miri code check
- GitHub Check: Run native tests
- GitHub Check: Build @affine/electron renderer
- GitHub Check: E2E Test (9)
- GitHub Check: y-octo binding test on x86_64-apple-darwin
- GitHub Check: E2E Test (10)
- GitHub Check: E2E Test (6)
- GitHub Check: E2E Test (5)
- GitHub Check: E2E Test (4)
- GitHub Check: E2E Test (7)
- GitHub Check: E2E Test (3)
- GitHub Check: E2E Test (8)
- GitHub Check: E2E Test (2)
- GitHub Check: E2E BlockSuite Test (5)
- GitHub Check: E2E Test (1)
- GitHub Check: E2E BlockSuite Test (10)
- GitHub Check: E2E BlockSuite Test (8)
- GitHub Check: E2E BlockSuite Test (9)
- GitHub Check: E2E BlockSuite Test (6)
- GitHub Check: E2E BlockSuite Test (7)
- GitHub Check: E2E BlockSuite Test (2)
- GitHub Check: E2E BlockSuite Test (3)
- GitHub Check: E2E BlockSuite Test (4)
- GitHub Check: E2E BlockSuite Test (1)
- GitHub Check: Build AFFiNE native (aarch64-pc-windows-msvc)
- GitHub Check: Build AFFiNE native (x86_64-pc-windows-msvc)
- GitHub Check: Analyze (javascript, blocksuite)
- GitHub Check: E2E Mobile Test (3)
- GitHub Check: Analyze (javascript, affine)
- GitHub Check: Analyze (typescript, blocksuite)
- GitHub Check: Lint Rust
- GitHub Check: Build AFFiNE native (x86_64-unknown-linux-gnu)
- GitHub Check: Analyze (typescript, affine)
- GitHub Check: E2E Mobile Test (4)
- GitHub Check: E2E Mobile Test (1)
- GitHub Check: Build AFFiNE native (x86_64-apple-darwin)
- GitHub Check: E2E Mobile Test (2)
- GitHub Check: E2E Mobile Test (5)
- GitHub Check: Typecheck
- GitHub Check: E2E BlockSuite Cross Browser Test (1, firefox)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, firefox)
- GitHub Check: Build AFFiNE native (aarch64-apple-darwin)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, chromium)
- GitHub Check: E2E BlockSuite Cross Browser Test (2, webkit)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, webkit)
- GitHub Check: E2E BlockSuite Cross Browser Test (1, chromium)
- GitHub Check: Lint
🔇 Additional comments (2)
packages/backend/server/src/plugins/copilot/providers/openai.ts (2)
70-77
: VerifyselectModel
chooses an Object-capable model whenoutputType = Object
Models now advertise
ModelOutputType.Object
, but only one capability (gpt-4.1
lines 110-119) is flaggeddefaultForOutputType: true
.
IfselectModel
falls back to the first capability marked as default for the requested output, all object requests may be routed togpt-4.1
even when the caller asked forgpt-4o
.Please double-check the selection logic or explicitly mark the intended default for each series.
370-401
:streamObject
still relies onstreamText
API – verify chunk format
getFullStream()
delegates tostreamText()
fromai
, which streams text deltas.
If/when OpenAI ships a native object-stream API the chunk format may diverge, breakingStreamObjectParser
.Keep an eye on provider docs and gate this path behind feature detection so we don’t silently mis-parse future responses.
shared$.pipe( | ||
toArray(), | ||
concatMap(values => { | ||
const parser = new StreamObjectParser(); | ||
const streamObjects = parser.mergeTextDelta(values); | ||
const content = parser.mergeContent(streamObjects); | ||
session.push({ | ||
role: 'assistant', | ||
content, | ||
streamObjects, | ||
createdAt: new Date(), | ||
}); | ||
return from(session.save()); | ||
}), | ||
mergeMap(() => EMPTY) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
toArray()
buffers the entire object stream – may balloon memory for long chats
shared$.pipe(toArray(), …)
stores every StreamObject
chunk until the provider finishes.
Large, multi-turn streams (or hallucinating models) could easily reach MBs in RAM before the session is flushed.
A light-weight alternative:
- shared$.pipe(
- toArray(),
- concatMap(values => {
- const parser = new StreamObjectParser();
- const streamObjects = parser.mergeTextDelta(values);
- const content = parser.mergeContent(streamObjects);
- …
- }),
+ shared$.pipe(
+ bufferTime(1000), // flush every second (or N chunks)
+ filter(batch => batch.length),
+ mergeMap(batch => {
+ parser.mergeTextDelta(batch); // keep parser outside the pipeline
+ return EMPTY;
+ }),
+ finalize(async () => {
+ const streamObjects = parser.getObjects(); // expose accumulated result
+ const content = parser.mergeContent(streamObjects);
+ …
+ }),
This streams chunks through while still persisting the final merged result, keeping peak memory constant.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/backend/server/src/plugins/copilot/controller.ts around lines 399 to
414, the use of toArray() buffers the entire stream of StreamObject chunks,
which can cause high memory usage for long or large streams. To fix this,
refactor the code to process and persist chunks incrementally as they arrive
instead of collecting them all before saving. This approach will keep memory
usage constant by streaming chunks through and only merging and saving the final
result at the end.
Close AI-193
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
Documentation