Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd3cd006

Browse files
committed
Pre-release 0.36.123
1 parent2e8e989 commitd3cd006

File tree

34 files changed

+1036
-285
lines changed

34 files changed

+1036
-285
lines changed

‎Core/Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ let package = Package(
180180
.product(name:"ConversationServiceProvider",package:"Tool"),
181181
.product(name:"GitHubCopilotService",package:"Tool"),
182182
.product(name:"Workspace",package:"Tool"),
183-
.product(name:"Terminal",package:"Tool")
183+
.product(name:"Terminal",package:"Tool"),
184+
.product(name:"SystemUtils",package:"Tool")
184185
]),
185186
.testTarget(
186187
name:"ChatServiceTests",

‎Core/Sources/ChatService/ChatService.swift

Lines changed: 122 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Logger
1414
import Workspace
1515
import XcodeInspector
1616
import OrderedCollections
17+
import SystemUtils
1718

1819
publicprotocolChatServiceType{
1920
varmemory:ContextAwareAutoManagedChatMemory{getset}
@@ -330,22 +331,42 @@ public final class ChatService: ChatServiceType, ObservableObject {
330331
letworkDoneToken=UUID().uuidString
331332
activeRequestId= workDoneToken
332333

333-
letchatMessage=ChatMessage(
334+
varchatMessage=ChatMessage(
334335
id: id,
335336
chatTabID:self.chatTabInfo.id,
336337
role:.user,
337338
content: content,
338339
references: references.toConversationReferences()
339340
)
340341

342+
letcurrentEditorSkill= skillSet.first(where:{ $0.id==CurrentEditorSkill.ID})as?CurrentEditorSkill
343+
letcurrentFileReadability= currentEditorSkill==nil
344+
?nil
345+
:FileUtils.checkFileReadability(at: currentEditorSkill!.currentFilePath)
346+
varerrorMessage:ChatMessage?
347+
348+
varcurrentTurnId:String?= turnId
341349
// If turnId is provided, it is used to update the existing message, no need to append the user message
342350
if turnId==nil{
351+
iflet currentFileReadability, !currentFileReadability.isReadable{
352+
// For associating error message with user message
353+
currentTurnId=UUID().uuidString
354+
chatMessage.clsTurnID= currentTurnId
355+
errorMessage=buildErrorMessage(
356+
turnId: currentTurnId!,
357+
errorMessages:[
358+
currentFileReadability.errorMessage(
359+
using:CurrentEditorSkill.readabilityErrorMessageProvider
360+
)
361+
].compactMap{ $0}.filter{ !$0.isEmpty}
362+
)
363+
}
343364
await memory.appendMessage(chatMessage)
344365
}
345366

346367
// reset file edits
347368
self.resetFileEdits()
348-
369+
349370
// persist
350371
saveChatMessageToStorage(chatMessage)
351372

@@ -370,32 +391,68 @@ public final class ChatService: ChatServiceType, ObservableObject {
370391
return
371392
}
372393

373-
letskillCapabilities:[String]=[CurrentEditorSkill.ID,ProblemsInActiveDocumentSkill.ID]
394+
iflet errorMessage{
395+
Task{await memory.appendMessage(errorMessage)}
396+
}
397+
398+
varactiveDoc:Doc?
399+
varvalidSkillSet:[ConversationSkill]= skillSet
400+
iflet currentEditorSkill, currentFileReadability?.isReadable==true{
401+
activeDoc=Doc(uri: currentEditorSkill.currentFile.url.absoluteString)
402+
}else{
403+
validSkillSet.removeAll(where:{ $0.id==CurrentEditorSkill.ID || $0.id==ProblemsInActiveDocumentSkill.ID})
404+
}
405+
406+
letrequest=createConversationRequest(
407+
workDoneToken: workDoneToken,
408+
content: content,
409+
activeDoc: activeDoc,
410+
references: references,
411+
model: model,
412+
agentMode: agentMode,
413+
userLanguage: userLanguage,
414+
turnId: currentTurnId,
415+
skillSet: validSkillSet
416+
)
417+
418+
self.lastUserRequest= request
419+
self.skillSet= validSkillSet
420+
tryawaitsend(request)
421+
}
422+
423+
privatefunc createConversationRequest(
424+
workDoneToken:String,
425+
content:String,
426+
activeDoc:Doc?,
427+
references:[FileReference],
428+
model:String?=nil,
429+
agentMode:Bool=false,
430+
userLanguage:String?=nil,
431+
turnId:String?=nil,
432+
skillSet:[ConversationSkill]
433+
)->ConversationRequest{
434+
letskillCapabilities:[String]=[CurrentEditorSkill.ID,ProblemsInActiveDocumentSkill.ID]
374435
letsupportedSkills:[String]= skillSet.map{ $0.id}
375436
letignoredSkills:[String]= skillCapabilities.filter{
376437
!supportedSkills.contains($0)
377438
}
378-
letcurrentEditorSkill= skillSet.first{ $0.id==CurrentEditorSkill.ID}
379-
letactiveDoc:Doc?=(currentEditorSkillas?CurrentEditorSkill).map{Doc(uri: $0.currentFile.url.absoluteString)}
380439

381440
/// replace the `@workspace` to `@project`
382441
letnewContent=replaceFirstWord(in: content, from:"@workspace", to:"@project")
383442

384-
letrequest=ConversationRequest(workDoneToken: workDoneToken,
385-
content: newContent,
386-
workspaceFolder:"",
387-
activeDoc: activeDoc,
388-
skills: skillCapabilities,
389-
ignoredSkills: ignoredSkills,
390-
references: references,
391-
model: model,
392-
agentMode: agentMode,
393-
userLanguage: userLanguage,
394-
turnId: turnId
443+
returnConversationRequest(
444+
workDoneToken: workDoneToken,
445+
content: newContent,
446+
workspaceFolder:"",
447+
activeDoc: activeDoc,
448+
skills: skillCapabilities,
449+
ignoredSkills: ignoredSkills,
450+
references: references,
451+
model: model,
452+
agentMode: agentMode,
453+
userLanguage: userLanguage,
454+
turnId: turnId
395455
)
396-
self.lastUserRequest= request
397-
self.skillSet= skillSet
398-
tryawaitsend(request)
399456
}
400457

401458
publicfunc sendAndWait(_ id:String, content:String)asyncthrows->String{
@@ -444,20 +501,16 @@ public final class ChatService: ChatServiceType, ObservableObject {
444501
{
445502
// TODO: clean up contents for resend message
446503
activeRequestId=nil
447-
do{
448-
tryawaitsend(
449-
id,
450-
content: lastUserRequest.content,
451-
skillSet: skillSet,
452-
references: lastUserRequest.references??[],
453-
model: model!=nil? model: lastUserRequest.model,
454-
agentMode: lastUserRequest.agentMode,
455-
userLanguage: lastUserRequest.userLanguage,
456-
turnId: id
457-
)
458-
}catch{
459-
print("Failed to resend message")
460-
}
504+
tryawaitsend(
505+
id,
506+
content: lastUserRequest.content,
507+
skillSet: skillSet,
508+
references: lastUserRequest.references??[],
509+
model: model!=nil? model: lastUserRequest.model,
510+
agentMode: lastUserRequest.agentMode,
511+
userLanguage: lastUserRequest.userLanguage,
512+
turnId: id
513+
)
461514
}
462515
}
463516

@@ -569,6 +622,19 @@ public final class ChatService: ChatServiceType, ObservableObject {
569622

570623
Task{
571624
ifvar lastUserMessage=await memory.history.last(where:{ $0.role==.user}){
625+
626+
// Case: New conversation where error message was generated before CLS request
627+
// Using clsTurnId to associate this error message with the corresponding user message
628+
// When merging error messages with bot responses from CLS, these properties need to be updated
629+
await memory.mutateHistory{ historyin
630+
iflet existingBotIndex= history.lastIndex(where:{
631+
$0.role==.assistant && $0.clsTurnID== lastUserMessage.clsTurnID
632+
}){
633+
history[existingBotIndex].id= turnId
634+
history[existingBotIndex].clsTurnID= turnId
635+
}
636+
}
637+
572638
lastUserMessage.clsTurnID= progress.turnId
573639
saveChatMessageToStorage(lastUserMessage)
574640
}
@@ -653,14 +719,9 @@ public final class ChatService: ChatServiceType, ObservableObject {
653719
Task{
654720
awaitStatus.shared
655721
.updateCLSStatus(.warning, busy:false, message:CLSError.message)
656-
leterrorMessage=ChatMessage(
657-
id: progress.turnId,
658-
chatTabID:self.chatTabInfo.id,
659-
clsTurnID: progress.turnId,
660-
role:.assistant,
661-
content:"",
662-
panelMessages:[.init(type:.error, title:String(CLSError.code??0), message:CLSError.message, location:.Panel)]
663-
)
722+
leterrorMessage=buildErrorMessage(
723+
turnId: progress.turnId,
724+
panelMessages:[.init(type:.error, title:String(CLSError.code??0), message:CLSError.message, location:.Panel)])
664725
// will persist in resetongoingRequest()
665726
await memory.appendMessage(errorMessage)
666727

@@ -683,27 +744,17 @@ public final class ChatService: ChatServiceType, ObservableObject {
683744
}
684745
}elseifCLSError.code==400 &&CLSError.message.contains("model is not supported"){
685746
Task{
686-
leterrorMessage=ChatMessage(
687-
id: progress.turnId,
688-
chatTabID:self.chatTabInfo.id,
689-
role:.assistant,
690-
content:"",
691-
errorMessage:"Oops, the model is not supported. Please enable it first in [GitHub Copilot settings](https://github.com/settings/copilot)."
747+
leterrorMessage=buildErrorMessage(
748+
turnId: progress.turnId,
749+
errorMessages:["Oops, the model is not supported. Please enable it first in [GitHub Copilot settings](https://github.com/settings/copilot)."]
692750
)
693751
await memory.appendMessage(errorMessage)
694752
resetOngoingRequest()
695753
return
696754
}
697755
}else{
698756
Task{
699-
leterrorMessage=ChatMessage(
700-
id: progress.turnId,
701-
chatTabID:self.chatTabInfo.id,
702-
clsTurnID: progress.turnId,
703-
role:.assistant,
704-
content:"",
705-
errorMessage:CLSError.message
706-
)
757+
leterrorMessage=buildErrorMessage(turnId: progress.turnId, errorMessages:[CLSError.message])
707758
// will persist in resetOngoingRequest()
708759
await memory.appendMessage(errorMessage)
709760
resetOngoingRequest()
@@ -728,6 +779,22 @@ public final class ChatService: ChatServiceType, ObservableObject {
728779
}
729780
}
730781

782+
privatefunc buildErrorMessage(
783+
turnId:String,
784+
errorMessages:[String]=[],
785+
panelMessages:[CopilotShowMessageParams]=[]
786+
)->ChatMessage{
787+
return.init(
788+
id: turnId,
789+
chatTabID: chatTabInfo.id,
790+
clsTurnID: turnId,
791+
role:.assistant,
792+
content:"",
793+
errorMessages: errorMessages,
794+
panelMessages: panelMessages
795+
)
796+
}
797+
731798
privatefunc resetOngoingRequest(){
732799
activeRequestId=nil
733800
isReceivingMessage=false

‎Core/Sources/ChatService/Skills/CurrentEditorSkill.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import ConversationServiceProvider
22
import Foundation
33
import GitHubCopilotService
44
import JSONRPC
5+
import SystemUtils
56

67
publicclassCurrentEditorSkill:ConversationSkill{
78
publicstaticletID="current-editor"
89
publicletcurrentFile:FileReference
910
publicvarid:String{
1011
returnCurrentEditorSkill.ID
1112
}
13+
publicvarcurrentFilePath:String{ currentFile.url.path}
1214

1315
publicinit(
1416
currentFile:FileReference
@@ -20,6 +22,17 @@ public class CurrentEditorSkill: ConversationSkill {
2022
return params.skillId==self.id
2123
}
2224

25+
publicstaticletreadabilityErrorMessageProvider:FileUtils.ReadabilityErrorMessageProvider={ statusin
26+
switch status{
27+
case.readable:
28+
returnnil
29+
case.notFound:
30+
return"Copilot can’t find the current file, so it's not included."
31+
case.permissionDenied:
32+
return"Copilot can't access the current file. Enable\"Files & Folders\" access in [System Settings](x-apple.systempreferences:com.apple.preference.security?Privacy_FilesAndFolders)."
33+
}
34+
}
35+
2336
publicfunc resolveSkill(request:ConversationContextRequest, completion:JSONRPCResponseHandler){
2437
leturi:String?=self.currentFile.url.absoluteString
2538
completion(

‎Core/Sources/ConversationTab/Chat.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public struct DisplayedChatMessage: Equatable {
2424
publicvarreferences:[ConversationReference]=[]
2525
publicvarfollowUp:ConversationFollowUp?=nil
2626
publicvarsuggestedTitle:String?=nil
27-
publicvarerrorMessage:String?=nil
27+
publicvarerrorMessages:[String]=[]
2828
publicvarsteps:[ConversationProgressStep]=[]
2929
publicvareditAgentRounds:[AgentRound]=[]
3030
publicvarpanelMessages:[CopilotShowMessageParams]=[]
@@ -36,7 +36,7 @@ public struct DisplayedChatMessage: Equatable {
3636
references:[ConversationReference]=[],
3737
followUp:ConversationFollowUp?=nil,
3838
suggestedTitle:String?=nil,
39-
errorMessage:String?=nil,
39+
errorMessages:[String]=[],
4040
steps:[ConversationProgressStep]=[],
4141
editAgentRounds:[AgentRound]=[],
4242
panelMessages:[CopilotShowMessageParams]=[]
@@ -47,7 +47,7 @@ public struct DisplayedChatMessage: Equatable {
4747
self.references= references
4848
self.followUp= followUp
4949
self.suggestedTitle= suggestedTitle
50-
self.errorMessage=errorMessage
50+
self.errorMessages=errorMessages
5151
self.steps= steps
5252
self.editAgentRounds= editAgentRounds
5353
self.panelMessages= panelMessages
@@ -371,7 +371,7 @@ struct Chat {
371371
},
372372
followUp: message.followUp,
373373
suggestedTitle: message.suggestedTitle,
374-
errorMessage: message.errorMessage,
374+
errorMessages: message.errorMessages,
375375
steps: message.steps,
376376
editAgentRounds: message.editAgentRounds,
377377
panelMessages: message.panelMessages

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp