Repository navigation
Conversation
5 tasks done
whes1015
force-pushed
the
feat/ai-chat
branch
from
October 22, 2026 00:48
901fb2b to
02e5fb2
Compare
Member
Author
|
Force-push:rebase 到目前的 main( 修正: 另外兩個 commit 內容沒變。push 前 |
Platform: all New(zh-Hant): 首頁右上角新增 AI 助理:用你自己的 AI 服務問地震、天氣、颱風等,AI 會先查 DPIP 的即時資料再回答;金鑰只存在這支手機,對話不會儲存 New(en-US): a new AI assistant, opened from the top right of Home, answers questions about earthquakes, weather and typhoons with your own AI service, looking up DPIP's live data first; your key stays on this phone and conversations are not saved
whes1015
force-pushed
the
feat/ai-chat
branch
from
October 22, 2026 21:21
02e5fb2 to
fc0e362
Compare
Member
Author
|
Force-push:AI 不再佔導覽列的第六格。Material 3 建議導覽列放 3 到 5 個 destination,6 個在小螢幕和部分語系上標籤會擠。
push 前 |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
這個 PR 做了什麼
在首頁右上角(地區列的右端)新增「AI 助理」入口,點開是蓋在 shell 上的全螢幕頁面;導覽列維持 5 格。使用者填入自己的 AI 服務(OpenAI 相容格式)的網址、金鑰和模型後,就能問地震、天氣、颱風、海嘯和災害通知。AI 會先透過 DPIP 的 MCP 伺服器(
/mcp)查即時資料,再用使用者的語言回答。第一次進入會先顯示說明頁,寫清楚資料會送到哪裡、哪些會留在手機上。說明頁也提供 MCP 伺服器網址,讓使用者接到自己的工具(Claude、ChatGPT 等)。
這個 PR 沒有 public AI:ExpTech 自己提供的 AI、限流與排隊,以及「不要濫用、歡迎贊助」的說明,之後另外處理。
改動內容
正式程式碼
3523a20a把 secret 存在平台的金鑰庫(core/platform/secret_store.dart)SecretStorePlugin.swift):Keychain generic password,kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,所以備份還原到別支手機時不會帶走。SecretStoreChannel.kt):AES-GCM 金鑰在 Android Keystore 內產生、不會離開 Keystore,只把密文寫到noBackupFilesDir。寫入先寫暫存檔再 rename;無法解密的檔案(例如移除螢幕鎖後 Keystore 金鑰失效)會刪掉,當成沒存過。SecretKeyenum 當 key,和SettingKey同樣的理由:不能用任意字串存取。SettingsStore:dpip.db在 application-support,iOS 會把它放進備份,這樣說明頁「金鑰不離開手機」就不成立。024baf92AI 助理(lib/features/ai_chat/)data/openai_chat_model.dart):OpenAI 相容的/chat/completions,stream: true。index)、reasoning_content、開頭的<think>…</think>(自架模型常見)、不串流的 JSON 回應、200 串流裡夾帶的錯誤(OpenRouter)。["null","integer"]改成integer,拿掉additionalProperties。DPIP 的 schema 用了這兩種寫法,Gemini 的相容端點會因此拒絕整個請求。data/dpip_mcp_tool_host.dart):initialize→tools/list(每個 session 列一次)→tools/call,回應 SSE 或 JSON 都能解析。ApiClient的coreApi,和其他 DPIP 請求一樣區域綁定、可以切換區域。instructions(單位、震度刻度、代碼格式)會放進系統提示。domain/chat_agent.dart):domain/system_prompt.dart):AppTime.utc8),模型才知道「今天」「一小時前」是什麼時候。https://,localhost例外。core/network/api_client.dart新增streamAbsolute:絕對網址、串流回應、回傳所有狀態碼。AI 服務的兩個呼叫都走它:串流回應不進 ETag 快取,而這些回應取決於使用者的金鑰(getAbsolute的 GET 會被快取)。SettingKeys.aiBaseUrl、aiModel、aiIntroSeen;金鑰不是 setting。shared/widgets/region_bar.dart新增可選的trailing:一個圖示按鈕放在地區列右端,跟著地區列一起淡出、滑走,用和地區 badge 相同的天空配色;有trailing時兩側留相同的 inset,選取中的地區仍在螢幕正中間。事件頁不傳,所以不變。context.pushNamed(AppRoutes.ai);首頁不 import AI 這個 feature。AppRoutes.ai和aiSettings都是蓋在 shell 上的頁面,不是 branch,導覽列 5 格、既有分頁的索引都沒變。離開再回來,對話還在(存在AiChatController,不在頁面裡)。fc0e3623文件:api.md補上/mcp和使用者 AI 服務的兩個呼叫;ARCHITECTURE.md § Persistence說明 secret 為什麼是 SQLite 以外的唯一例外。測試
<think>、非串流回應、200 裡的錯誤、取消時中止請求。trailing在右端、按得到、跟著地區列消失;選取中的 badge 仍置中(只留右側 inset 時這個測試會失敗)。AppRoutes.ai。路由:shell 只有 5 個 branch,AI 是 shell 外的頁面。ApiClient(earthquake_api_test.dart、replay_session_test.dart)補上streamAbsolute。SecretStorePluginTests5 個,包含「Keychain 項目是ThisDeviceOnly」。沒做的與已知限制
http://(例如另一台電腦上的 Ollama)不能用,Android 的 network security config 只允許 localhost 走明文。相關 issue
沒有對應的 issue。
怎麼驗
tool/check.sh全部通過,Dart 測試 3,703 個全過(pre-push hook 也跑過一次)。DpipMcpToolHost(臨時測試,沒有 commit):instructions有 1,016 字元。township_lookup、earthquake_reports都查得到資料。validating /properties/limit: … want "integer",模型可以讀到並重試。/mcp在core-tnn1和core-tyo1都有回應。tool/dev/test_ios.sh用CODE_SIGNING_ALLOWED=NO)沒有 keychain entitlement,會拿到errSecMissingEntitlement(-34018),所以這種情況下會跳過。另外用 ad-hoc 簽章(tool/dev/test_ios.sh CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY=-)跑過,5 個全部通過。檢查清單
tool/check/commits.sh origin/main..HEAD通過(3 個 commit)tool/commit.sh --push)AppLocalizations,12 個語系都有翻譯AppSpacing/AppRadius;深色模式與大字級還沒在實機上看過