@@ -2,6 +2,23 @@ import Foundation
22
33let defaultCompanionEndpoint = " ws://127.0.0.1:45554/companion/pet "
44let companionProtocolVersion = 1
5+ let petCompanionCapabilities = [
6+ " bubble " ,
7+ " movement " ,
8+ " tap-open-chat " ,
9+ " drag-reposition " ,
10+ " reactive-animations " ,
11+ " perch-memory " ,
12+ " dock-presets " ,
13+ " ambient-dialogue " ,
14+ " character-themes " ,
15+ " provider-overview " ,
16+ " provider-sync-request " ,
17+ " open-provider-settings " ,
18+ " multi-tap-actions " ,
19+ " live2d-renderer " ,
20+ " live2d-expressions "
21+ ]
522
623enum PetState : String , CaseIterable , Codable {
724 case hidden
@@ -17,13 +34,19 @@ enum CompanionCommandType: String {
1734 case stateChanged = " pet.state_changed "
1835 case showBubble = " pet.show_bubble "
1936 case openChatAnchor = " pet.open_chat_anchor "
37+ case providerOverview = " pet.provider_overview "
38+ case live2dAction = " pet.live2d_action "
2039}
2140
2241enum CompanionEventType : String {
2342 case ready = " pet.ready "
2443 case clicked = " pet.clicked "
2544 case openChat = " pet.open_chat "
2645 case dismissed = " pet.dismissed "
46+ case requestProviderOverviewSync = " pet.request_provider_overview_sync "
47+ case openProviderSettings = " pet.open_provider_settings "
48+ case requestPetCheer = " pet.request_pet_cheer "
49+ case requestPetNextStep = " pet.request_pet_next_step "
2750}
2851
2952enum IncomingCommand {
@@ -32,6 +55,8 @@ enum IncomingCommand {
3255 case stateChanged( PetState )
3356 case showBubble( text: String , autoHideMs: Int ? )
3457 case openChatAnchor
58+ case providerOverview( CompanionProviderOverviewPayload )
59+ case live2dAction( CompanionLive2DActionPayload )
3560}
3661
3762enum PetIPCConnectionStatus {
@@ -130,6 +155,84 @@ struct BubblePayload: Decodable {
130155 }
131156}
132157
158+ struct CompanionProviderSummary : Decodable {
159+ let providerType : String
160+ let displayName : String
161+ let totalCount : Int
162+ let healthyCount : Int
163+ let available : Bool
164+ let needsAttention : Bool
165+
166+ enum CodingKeys : String , CodingKey {
167+ case providerType = " provider_type "
168+ case displayName = " display_name "
169+ case totalCount = " total_count "
170+ case healthyCount = " healthy_count "
171+ case available
172+ case needsAttention = " needs_attention "
173+ }
174+ }
175+
176+ struct CompanionProviderOverviewPayload : Decodable {
177+ let providers : [ CompanionProviderSummary ]
178+ let totalProviderCount : Int
179+ let availableProviderCount : Int
180+ let needsAttentionProviderCount : Int
181+
182+ enum CodingKeys : String , CodingKey {
183+ case providers
184+ case totalProviderCount = " total_provider_count "
185+ case availableProviderCount = " available_provider_count "
186+ case needsAttentionProviderCount = " needs_attention_provider_count "
187+ }
188+ }
189+
190+ enum CompanionLive2DExpressionValue : Decodable , Hashable {
191+ case index( Int )
192+ case tag( String )
193+
194+ init ( from decoder: Decoder ) throws {
195+ let container = try decoder. singleValueContainer ( )
196+ if let intValue = try ? container. decode ( Int . self) {
197+ self = . index( intValue)
198+ return
199+ }
200+ if let stringValue = try ? container. decode ( String . self) {
201+ self = . tag( stringValue)
202+ return
203+ }
204+ throw DecodingError . typeMismatch (
205+ CompanionLive2DExpressionValue . self,
206+ DecodingError . Context (
207+ codingPath: decoder. codingPath,
208+ debugDescription: " Unsupported Live2D expression value "
209+ )
210+ )
211+ }
212+ }
213+
214+ struct CompanionLive2DActionPayload : Decodable {
215+ let expressions : [ CompanionLive2DExpressionValue ]
216+ let emotionTags : [ String ]
217+ let motionGroup : String ?
218+ let motionIndex : Int ?
219+
220+ enum CodingKeys : String , CodingKey {
221+ case expressions
222+ case emotionTags = " emotion_tags "
223+ case motionGroup = " motion_group "
224+ case motionIndex = " motion_index "
225+ }
226+
227+ init ( from decoder: Decoder ) throws {
228+ let container = try decoder. container ( keyedBy: CodingKeys . self)
229+ expressions = try container. decodeIfPresent ( [ CompanionLive2DExpressionValue ] . self, forKey: . expressions) ?? [ ]
230+ emotionTags = try container. decodeIfPresent ( [ String ] . self, forKey: . emotionTags) ?? [ ]
231+ motionGroup = try container. decodeIfPresent ( String . self, forKey: . motionGroup)
232+ motionIndex = try container. decodeIfPresent ( Int . self, forKey: . motionIndex)
233+ }
234+ }
235+
133236struct InboundEnvelope {
134237 let protocolVersion : Int
135238 let event : String
0 commit comments