解析:薄客戶端+服務端協(xié)議單一事實源)
jcode iOS應用純Swift架構(gòu)解析薄客戶端服務端協(xié)議單一事實源【免費下載鏈接】jcodeThe most RAM efficient harness項目地址: https://gitcode.com/GitHub_Trending/jcod/jcodejcode 是目前內(nèi)存占用最極致的 AI 編程代理the most RAM efficient harness它運行在你自己的機器上驅(qū)動 LLM、工具、Git 與文件操作。而 ios/ 目錄下的 iOS 應用則是這套系統(tǒng)的遙控器一部純 Swift 編寫的薄客戶端掃碼配對后就能遠程查看對話、發(fā)送消息、中途打斷。本文將帶你解析這套架構(gòu)的三個核心決策——為什么放棄 Rust 共享核心、薄客戶端如何分層、以及服務端協(xié)議如何成為單一事實源。一個產(chǎn)品決策為什么是純 Swift 而不是共享 Rust 核心早期原型曾嘗試 Rust-mobile-core 方向但 v2 重建時徹底放棄寫進了架構(gòu)決策文檔The app is a thin client over an existing, server-owned protocol.理由很直接值得共享的行為協(xié)議、狀態(tài)機、工具執(zhí)行已經(jīng)全部在服務端了。如果再把 Rust 核心編進手機等于把服務端協(xié)議第三次重復還要搭 FFI 橋接、自定義渲染器和一套仿真器——成本遠大于收益。于是職責被清晰地切開了Swift 擁有客戶端SwiftUI 做界面Swift 6 并發(fā)actor、Observable管狀態(tài)?服務端協(xié)議是唯一真相Swift 側(cè)的編解碼器用真實線上抓取的 JSON 夾具做測試協(xié)議漂移會直接讓測試失敗可測試性靠分層而非設備視圖層以下全部能在 macOS 上swift test跑完不需要真機iOS 應用本身從不直接和 LLM 提供商通信——所有重活LLM 調(diào)用、工具、Git、文件、MCP都留在服務端。手機只負責渲染對話和驅(qū)動會話。上方是 iOS 應用遠程驅(qū)動的 jcode 服務端 Agent 界面三層架構(gòu)JCodeKit 內(nèi)核 JCodeMobile 外殼 測試層整個工程是一個 SPM 包Package.swift在 ios/ 下分成三部分1?? JCodeKit —— 無平臺的客戶端內(nèi)核位于 Sources/JCodeKit/禁止 import UIKit/SwiftUI必須在 macOS 上能編譯這樣才能被無頭測試文件職責Gateway.swift網(wǎng)關端點/health、/pair、/ws三個地址Pairing.swift配對碼 → 長效 token 的交換Wire.swift請求/事件編解碼器WebSocket 上的 NDJSONTransport.swiftWebSocket 抽象協(xié)議 URLSession 實現(xiàn)Connection.swiftactor連接、鑒權(quán)、指數(shù)退避重連SessionReducer.swift純函數(shù)狀態(tài)機事件 → 對話/應用狀態(tài)CredentialStore.swiftKeychain 憑證存儲其中SessionReducer是最關鍵的設計它是一個純函數(shù)(State, ServerEvent) - State所有流式輸出、工具調(diào)用生命周期、會話切換的邊界情況都在這里單元測試取代了舊版 Rust 仿真器的角色。2?? JCodeMobile —— SwiftUI 應用外殼位于 Sources/JCodeMobile/包含配對掃碼QRScannerView.swift、聊天、工具調(diào)用卡片ToolCallCard.swift、會話列表等視圖。規(guī)則很嚴格視圖里不允許有任何協(xié)議或狀態(tài)遷移邏輯AppModel.swift 只負責轉(zhuǎn)發(fā)用戶動作、把SessionReducer的輸出發(fā)布給視圖。3?? 測試與構(gòu)建Tests/JCodeKitTests/在 macOS 上跑swift test——編解碼器夾具、Reducer 流式場景、配對客戶端、連接 actor 全部無設備可測project.ymlXcodeGen 規(guī)范CI 用xcodebuild保持 UI 可編譯配對與連接從掃二維碼到 WebSocketiOS 應用背后是運行在自有機器上的 jcode 服務端承載全部 Agent 能力配對流程設計得既簡單又安全在服務器側(cè)執(zhí)行jcode pair生成 6 位配對碼5 分鐘有效和二維碼內(nèi)容為jcode://pair?hostHportPcodeC手機掃二維碼或手輸 host/port/碼Pairing.swift 向POST /pair提交{code, device_id, device_name}服務端返回長效 token服務端只存哈??蛻舳税阉B同服務器信息一起存入KeychainCredentialStore.swift模擬器無 Keychain 權(quán)限時自動降級到文件ws://host:7643/ws升級成 WebSocket攜帶Authorization: Bearer token連接由 Connection.swift 中的 actor 托管細節(jié)值得新手學習指數(shù)退避重連基礎延遲翻倍遞增、封頂 30 秒若服務端主動宣告 reload則跳過退避快速重連401 即終止token 被吊銷時用同一 token 重試永遠不會成功直接提示重新配對而不是無限退避請求 ID 自增分配響應按 ID 對應協(xié)議單一事實源Swift 代碼與 Rust 服務端如何不漂移這是整篇文章的題眼。服務端的協(xié)議定義在 Rust 側(cè)crates/jcode-protocol/src/wire.rsiOS 的 Wire.swift 在注釋中直接聲明Wire format mirrorscrates/jcode-protocol/src/wire.rs#[serde(tag type)], snake_case tags也就是說Rust 服務端是唯一事實源Swift 只是它的鏡像。iOS 只建模了手機用到的請求子集message、cancel、soft_interrupt、get_history、resume_session、set_model等 13 種服務端會忽略不認識的字段。前向兼容有三道保險全部體現(xiàn)在 Wire.swift 里未知事件歸.unknown新版服務端發(fā)出的新事件舊版 App 直接忽略而不是崩潰寬容的 JSON 訪問器JSONObject缺字段給默認值app must never crash on a server that is newer or older than itself夾具測試WireTests.swift 用真實服務端抓取的 JSON 做往返測試任何漂移都會讓swift test失敗寫在最后jcode 的 iOS 應用給給終端工具做移動端提供了一個教科書式的答案別在客戶端重復造協(xié)議——服務端協(xié)議即契約客戶端只做鏡像?分層換可測試性——內(nèi)核不碰 UIKitswift test在 macOS 上覆蓋全部行為邏輯憑證進 Keychain、token 服務端只存哈希——配對碼 5 分鐘過期長效 token 可吊銷如果你想動手閱讀源碼建議從 docs/IOS_APP.md 的架構(gòu)說明開始再到 Wire.swift 和 Connection.swift 看協(xié)議與連接的實際實現(xiàn)。薄客戶端不薄——薄的是代碼厚的是把邊界切得足夠干凈。【免費下載鏈接】jcodeThe most RAM efficient harness項目地址: https://gitcode.com/GitHub_Trending/jcod/jcode創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考