feat: adopt new backend api for attachment (#13336)

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

## Summary by CodeRabbit

* **New Features**
* Introduced a new query for applying document updates using AI,
allowing merged markdown responses.
* Added support for an optional file upload field when creating chat
messages.

* **Improvements**
* Enhanced recent Copilot sessions query with pagination by adding an
offset parameter.
* Refined attachment handling in chat responses to better distinguish
between single and multiple file uploads, improving reliability.

* **Bug Fixes**
  * Minor update to error handling for clearer messaging.

* **Chores**
* Cleaned up and updated iOS project configuration files for improved
build consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Lakr
2025-07-28 15:23:03 +08:00
committed by GitHub
parent 30c42fc51b
commit 4586e4a18f
7 changed files with 91 additions and 25 deletions

View File

@@ -167,8 +167,12 @@ private extension ChatManager {
"files": [String](), // attachment in context, keep nil for now
"searchMode": editorData.isSearchEnabled ? "MUST" : "AUTO",
]
let attachmentFieldName = "options.blobs"
var uploadableAttachments: [GraphQLFile] = [
let hasMultipleAttachmentBlobs = [
editorData.fileAttachments.count,
editorData.documentAttachments.count,
].reduce(0, +) > 1
let attachmentFieldName = hasMultipleAttachmentBlobs ? "options.blobs" : "options.blob"
let uploadableAttachments: [GraphQLFile] = [
editorData.fileAttachments.map { file -> GraphQLFile in
.init(fieldName: attachmentFieldName, originalName: file.name, data: file.data ?? .init())
},
@@ -177,15 +181,10 @@ private extension ChatManager {
},
].flatMap(\.self)
assert(uploadableAttachments.allSatisfy { !($0.data?.isEmpty ?? true) })
// in Apollo, filed name is handled as attached object to field when there is only one attachment
// to use array on our server, we need to append a dummy attachment
// which is ignored if data is empty and name is empty
if uploadableAttachments.count == 1 {
uploadableAttachments.append(.init(fieldName: attachmentFieldName, originalName: "", data: .init()))
}
guard let input = try? CreateChatMessageInput(
attachments: [],
blobs: .some([]), // must have the placeholder
blob: hasMultipleAttachmentBlobs ? .none : "",
blobs: hasMultipleAttachmentBlobs ? .some([]) : .none,
content: .some(contextSnippet.isEmpty ? editorData.text : "\(contextSnippet)\n\(editorData.text)"),
params: .some(AffineGraphQL.JSON(_jsonValue: messageParameters)),
sessionId: sessionId

View File

@@ -62,7 +62,7 @@ public class IntelligentContext {
"Login required: \(reason)"
case let .sessionCreationFailed(reason):
"Session creation failed: \(reason)"
case let .featureClosed:
case .featureClosed:
"Intelligent feature closed"
}
}