feat(assistant): include attachment source paths in gateway prompts
This commit is contained in:
parent
a1d905f272
commit
4b62300e40
@ -577,6 +577,7 @@ extension AppControllerDesktopThreadActions on AppController {
|
||||
sha256: key,
|
||||
type: attachment.type.trim(),
|
||||
uploadedAtMs: uploadedAtMs,
|
||||
sourcePath: attachment.sourcePath.trim(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -998,8 +999,10 @@ extension AppControllerDesktopThreadActions on AppController {
|
||||
if (visibleTaskInputAttachments.isNotEmpty) {
|
||||
buffer.writeln('- taskInputAttachments:');
|
||||
for (final attachment in visibleTaskInputAttachments) {
|
||||
final sourcePath = attachment.sourcePath.trim();
|
||||
final pathSuffix = sourcePath.isEmpty ? '' : ', path: $sourcePath';
|
||||
buffer.writeln(
|
||||
' - ${attachment.name.trim()} (${attachment.mimeType.trim()}, sha256: ${attachment.key})',
|
||||
' - ${attachment.name.trim()} (${attachment.mimeType.trim()}, sha256: ${attachment.key}$pathSuffix)',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,7 @@ buildAssistantAttachmentPayloadsInternal(
|
||||
fileName: attachment.name,
|
||||
content: base64Encode(bytes),
|
||||
sha256: crypto.sha256.convert(bytes).toString(),
|
||||
sourcePath: attachment.path,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ class GoTaskServiceRequest {
|
||||
(item) => <String, dynamic>{
|
||||
'name': item.fileName,
|
||||
'description': item.mimeType,
|
||||
'path': '',
|
||||
'path': item.sourcePath.trim(),
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -314,6 +314,8 @@ class GoTaskServiceRequest {
|
||||
'sizeBytes': goTaskServiceBase64Size(item.content),
|
||||
if (goTaskServiceAttachmentSha256(item).isNotEmpty)
|
||||
'sha256': goTaskServiceAttachmentSha256(item),
|
||||
if (item.sourcePath.trim().isNotEmpty)
|
||||
'sourcePath': item.sourcePath.trim(),
|
||||
},
|
||||
)
|
||||
.toList(growable: false),
|
||||
|
||||
@ -17,6 +17,7 @@ class GatewayChatAttachmentPayload {
|
||||
required this.fileName,
|
||||
required this.content,
|
||||
this.sha256 = '',
|
||||
this.sourcePath = '',
|
||||
});
|
||||
|
||||
final String type;
|
||||
@ -24,6 +25,7 @@ class GatewayChatAttachmentPayload {
|
||||
final String fileName;
|
||||
final String content;
|
||||
final String sha256;
|
||||
final String sourcePath;
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
@ -32,6 +34,7 @@ class GatewayChatAttachmentPayload {
|
||||
'fileName': fileName,
|
||||
'content': content,
|
||||
if (sha256.trim().isNotEmpty) 'sha256': sha256.trim(),
|
||||
if (sourcePath.trim().isNotEmpty) 'sourcePath': sourcePath.trim(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -360,6 +363,7 @@ class LocalDeviceIdentity {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CollaborationAttachment {
|
||||
const CollaborationAttachment({
|
||||
required this.name,
|
||||
|
||||
@ -855,6 +855,7 @@ class TaskInputAttachmentRecord {
|
||||
required this.sha256,
|
||||
required this.type,
|
||||
required this.uploadedAtMs,
|
||||
this.sourcePath = '',
|
||||
});
|
||||
|
||||
final String name;
|
||||
@ -862,6 +863,7 @@ class TaskInputAttachmentRecord {
|
||||
final String sha256;
|
||||
final String type;
|
||||
final double uploadedAtMs;
|
||||
final String sourcePath;
|
||||
|
||||
String get key => sha256.trim().toLowerCase();
|
||||
|
||||
@ -872,6 +874,7 @@ class TaskInputAttachmentRecord {
|
||||
'sha256': key,
|
||||
'type': type.trim(),
|
||||
'uploadedAtMs': uploadedAtMs,
|
||||
if (sourcePath.trim().isNotEmpty) 'sourcePath': sourcePath.trim(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -889,6 +892,7 @@ class TaskInputAttachmentRecord {
|
||||
sha256: json['sha256']?.toString().trim().toLowerCase() ?? '',
|
||||
type: json['type']?.toString().trim() ?? '',
|
||||
uploadedAtMs: uploadedAtMs(json['uploadedAtMs']),
|
||||
sourcePath: json['sourcePath']?.toString().trim() ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ void main() {
|
||||
expect(payloads.single.fileName, 'note.txt');
|
||||
expect(payloads.single.mimeType, 'text/plain');
|
||||
expect(payloads.single.type, 'file');
|
||||
expect(payloads.single.sourcePath, file.path);
|
||||
expect(
|
||||
base64Decode(payloads.single.content),
|
||||
utf8.encode('hello attachment'),
|
||||
|
||||
@ -1591,6 +1591,7 @@ void main() {
|
||||
mimeType: 'text/plain',
|
||||
fileName: 'note.txt',
|
||||
content: base64Encode(utf8.encode('note body')),
|
||||
sourcePath: '/Users/shenlan/Desktop/note.txt',
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -1615,7 +1616,11 @@ void main() {
|
||||
final attachments = params['attachments'] as List<dynamic>;
|
||||
final attachment = attachments.single as Map<String, dynamic>;
|
||||
expect(attachment['name'], 'note.txt');
|
||||
expect(attachment['path'], isEmpty);
|
||||
expect(attachment['path'], '/Users/shenlan/Desktop/note.txt');
|
||||
expect(
|
||||
inlineAttachment['sourcePath'],
|
||||
'/Users/shenlan/Desktop/note.txt',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@ -1636,6 +1641,7 @@ void main() {
|
||||
mimeType: 'image/png',
|
||||
fileName: 'diagram.png',
|
||||
content: base64Encode(utf8.encode('image bytes')),
|
||||
sourcePath: '/Users/shenlan/Pictures/diagram.png',
|
||||
);
|
||||
|
||||
await controller.sendChatMessage(
|
||||
@ -1662,11 +1668,19 @@ void main() {
|
||||
fakeGoTaskService.requests.last.prompt,
|
||||
contains('diagram.png (image/png, sha256:'),
|
||||
);
|
||||
expect(
|
||||
fakeGoTaskService.requests.last.prompt,
|
||||
contains('path: /Users/shenlan/Pictures/diagram.png'),
|
||||
);
|
||||
final thread = controller.requireTaskThreadForSessionInternal(
|
||||
fakeGoTaskService.requests.last.sessionId,
|
||||
);
|
||||
expect(thread.taskInputAttachments, hasLength(1));
|
||||
expect(thread.taskInputAttachments.single.name, 'diagram.png');
|
||||
expect(
|
||||
thread.taskInputAttachments.single.sourcePath,
|
||||
'/Users/shenlan/Pictures/diagram.png',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user