Commit Graph
71 Commits
Author SHA1 Message Date
yiqi-017 bb4b2ca974 feat(desktop): refresh compiled React Desktop 2.0 distribution
Rebuild the compiled renderer from abraxas914/GenericAgent source
commit 9fe5d69b85cfad8778ace84b6f69bc75f9e0d392, refreshing:

- New-chat default model tag: the selected-model badge in Settings
  and the composer now read '新会话默认' / 'New chat default'.
- Model selectors display the configured profile name (备注名) so the
  same model served by different providers is distinguishable.
- desktop_bridge: syncing mixin llm_nos references when a profile is
  renamed, preventing orphan references in the mixin config.
- Release publisher sets GH_REPO so 'gh release create' resolves the
  target repository without checking out source, satisfying the
  publisher security contract while fixing the prerelease step.

Provenance and verifier updated to the new source commit and the
LF-normalized content manifest (98 generated assets).
2026-08-25 18:00:43 +08:00
yiqi-017 9e56a95ac8 desktop: add workspace copy and switch action
Add a user-triggered desktop action to copy the current GA workspace to a chosen location and verify the bridge actually switches there before reporting success.
2026-08-03 20:31:16 +08:00
yiqi-017 8ea039724f feat(desktop): thin-shell over external core via GA_ROOT (方案三)
Run the bundle's own bridge + frontend but drive an external GenericAgent
核 injected via GA_ROOT, instead of swapping to the external bridge or
copying files into 本体. New UI + external核/data, no mutation, logs
naturally unified with the核's other frontends.

- desktop_bridge.py: find_default_ga_root() honors --ga-root / GA_ROOT
  (validated), else derives as before; conductor now spawned from the
  BUNDLE (APP_DIR/conductor.py) with GA_ROOT in env; scheduler stays核-side
- conductor.py: ROOT prefers GA_ROOT env, else own-path derivation
- lib.rs: override no longer changes project_dir (always bundle bridge);
  sanitize_bundle_env injects GA_ROOT; takeover compares effective ga_root;
  set_ga_source drops file-copy sync and instead runs a contract probe
  before committing; removed copy_dir_all/sync_desktop_files
- ga_contract_probe.py (new): subprocess, introspect-only (no GenericAgent
  instantiation) symbol/signature check of the核's bridge/conductor/
  cost_tracker contract; doubles as a dependency check
- GA桌面壳-参考方案.md: plan + feasibility review + probe checklist
2026-07-10 09:53:21 +08:00
yiqi-017 17b87f1c6a Merge origin/main into main 2026-07-09 22:49:05 +08:00
yiqi-017 377e437d85 Merge branch 'yiqi_source_sync' into main
On connect-to-source, push the shell's own (new) desktop files into the
本体 (backing up its originals) before restarting the bridge, so it
serves the new frontend + bridge while keeping the 本体 agent/data.
2026-07-09 22:45:43 +08:00
yiqi-017 da5fbef965 feat(desktop): sync shell desktop files into 本体 on connect
When connecting to a separate GA source (design A), the bridge and the
served frontend come from that 本体 — so an older 本体 showed an old
desktop UI. set_ga_source now pushes this shell's own (new) desktop
files into the 本体 before restarting the bridge, so it serves the new
UI + bridge while keeping the 本体 agent/data.

- copy_dir_all + sync_desktop_files: back up 本体 originals into
  temp/desktop_sync_backup_<ts>/, then copy the shell version over
- synced set: frontends/desktop/static/, desktop_bridge.py,
  plan_state.py, cost_tracker.py (NOT src-tauri / build artifacts)
- skipped when the source is the shell's own code location (dev tree)
2026-07-08 00:55:09 +08:00
yiqi-017 a5c184c232 Merge branch 'yiqi_sessions_perf' into main
Fix desktop session-store scaling: store each session as its own
temp/desktop_sessions/<id>.json instead of one monolithic
desktop_sessions.json rewritten on every message. Write cost is now
O(one session) regardless of session count. Auto-migrates the legacy
file on first load; import reads both formats.
2026-07-06 14:35:26 +08:00
yiqi-017 bdd5309607 perf(desktop): store sessions one file each, not one monolithic JSON
Every message called _persist(), which rewrote the ENTIRE
desktop_sessions.json (all sessions, full messages + llm_history) under
the lock. Write cost was O(all sessions), so performance degraded badly
as sessions piled up.

Now each session is its own temp/desktop_sessions/<id>.json:
- _persist_session(s): atomic per-session write, O(one session)
- _delete_session_file(sid): remove on delete
- add_message / create / plan-bind / set_model / patch now write only
  the touched session; write cost no longer scales with session count
- _load_sessions reads the dir; one-time migration from the legacy
  monolithic file, which is then renamed to .json.migrated
- import_sessions reads both source formats (per-file dir + legacy),
  persists only newly added sessions
2026-07-06 14:05:31 +08:00
yiqi-017 157f4fec77 Merge branch 'yiqi_install' into main
Add "connect to a separate GenericAgent source" (thin-shell / design A):
a Settings option that points the packaged desktop app at a standalone
本体 checkout, so its bridge, agent code, memory and sessions all come
from that source. Invalid/missing override safely falls back to the
bundled runtime.
2026-07-06 02:54:17 +08:00
yiqi-017 300fe4ae34 feat(desktop): connect to a separate GA source (thin-shell / design A)
Adds a "GA source directory" setting so the packaged desktop app can run
against a standalone GenericAgent checkout instead of its own bundled
runtime/app — memory, sessions, model_responses and the agent code all
come from that 本体, live-shared with other frontends.

- lib.rs: ga_source_override settings key honored in get_or_discover_config
  BEFORE the bundle default; validated (agentmain.py + desktop_bridge.py),
  invalid/missing override falls back to the bundle (本体-moved safety net)
- set_ga_source / clear_ga_source / get_ga_source commands: write setting,
  stop current bridge, respawn from resolved config, reload webview
- startup uses the override-aware config for takeover + spawn
- ACL grants for the three new commands
- Settings > Features UI: pick source dir, show current, clear; zh/en i18n
2026-07-06 02:20:48 +08:00
yiqi-017 44f3706ddc Merge branch 'yiqi_memory' into main
Add import-memory feature to the desktop app: import memory/,
model_responses/ and desktop_sessions.json from an existing GenericAgent
install so past memory and sessions carry over to the standalone desktop.
2026-07-06 01:36:15 +08:00
yiqi-017 4798e72f3f fix(desktop): render sidebar after importing sessions
loadSessions() only refreshes the data model; the sidebar DOM is drawn by
renderSessionList(). Imported sessions therefore only appeared after the
next render (e.g. sending a message). Call renderSessionList() right after.
2026-07-06 01:13:29 +08:00
yiqi-017 aff6560440 feat(desktop): merge desktop_sessions.json on memory import
Import now also merges the source's temp/desktop_sessions.json into the
current session list (dedup by id), updating both memory and the on-disk
file so past desktop chats reappear in the sidebar immediately.

- manager.import_sessions(): id-dedup merge, in-memory + persist
- import handler returns sessionsAdded/sessionsSkipped
- frontend shows session count in toast and reloads the sidebar
2026-07-06 00:48:15 +08:00
yiqi-017 ec44d69bfe feat(desktop): clarify import-memory targets the GA root dir
- button label now says "select GenericAgent root"
- pick_directory accepts a title; native dialog shows the hint
- browser-fallback prompt clarifies root dir vs memory folder
2026-07-05 23:46:19 +08:00
yiqi-017 4cda8cadb7 fix(desktop): allow pick_directory command in ACL
The import-memory button failed with "Command pick_directory not allowed
by ACL" because Tauri v2 requires custom commands to be granted in the
capability. Add allow-pick-directory permission and grant it.
2026-07-05 22:55:10 +08:00
yiqi-017 74275f8980 feat(desktop): add import-memory feature in settings
Lets users import memory/ and temp/model_responses/ from an existing
GenericAgent install into the desktop app's ga_root, so past sessions
and memory are not lost when running the standalone desktop bundle.

- bridge: POST /memory/import copies memory (backup-then-overwrite) and
  model_responses (fill-missing), returns counts + backup dir
- tauri: pick_directory command (rfd native folder picker)
- frontend: "Import memory" button in Settings > Features + zh/en i18n
2026-07-05 22:28:17 +08:00
yiqi-017 5e7e5f608e refactor(desktop): model switching only via /session/{sid}/model
Remove the implicit model-write that rode along with each prompt. The
frontend no longer sends llmNo on session/prompt, and the bridge no longer
reads/forwards it there — sending a message now uses only the session's
bound sess.llm_no (falling back to the global default). Model switching
goes through the single POST /session/{sid}/model entry point.

selectModel now rolls back the chip + shows a toast when the switch request
fails, so the frontend display never diverges from the backend.
2026-06-24 18:29:13 +08:00
yiqi-017 e0117c40de feat(desktop): per-session model binding with backend as source of truth
Session.llm_no is now the authoritative per-session model selection
(persisted to desktop_sessions.json). Frontend state.llmNo becomes a
display cache; switching a session re-displays its bound model, and the
chip follows the backend's live model for native models too (not just
mixin failover).

- bridge: Session.llm_no field + persistence; submit_prompt/run_agent_turn
  read sess.llm_no with global ui.llmNo as fallback; make_agent/restore
  seed from it; new POST /session/{sid}/model; _live_model reports llmNo
- app.js: applyLiveModel supports native; setActiveSession re-displays
  bound model; selectModel posts to session route + updates global default;
  remove ga_llm_no localStorage
- conductor unchanged: keeps reading global default ui.llmNo
2026-06-24 16:44:58 +08:00
yiqi-017 9103f8e8c8 style(desktop): drop the accent left bar on selected model dropdown item
Selected item in the model dropdown now uses only a tinted background + bold
(both light and dark); the inset left bar is removed per design preference.
2026-06-22 15:37:25 +08:00
yiqi-017 f0f2b50763 style(desktop): send button colors + clearer selected model in dropdown
- Send button: light mode now black (was green), dark mode bright blue
  (#2559d8 / hover #3a6ef0).
- Model dropdown selected item is now obvious: light mode gets an accent
  left bar + tinted bg + bold; dark mode gets a tinted bg + soft-white left
  bar + bold.
2026-06-22 15:24:14 +08:00
yiqi-017 cf17adab24 feat(desktop): maximize main window + uninstall clears WebView2 data
- Main window now opens maximized (maximized: true); 1280x800 stays as the
  restore size. Previously it always opened windowed.
- Uninstaller now also removes %LOCALAPPDATA%\com.genericagent.app (WebView2
  EBWebView cache + localStorage), which lives outside the bundle. Only the
  Tauri desktop shell uses it, so removal is safe.
2026-06-22 00:50:42 +08:00
yiqi-017 24c6a64d0e Revert no-cache middleware for bridge static assets
Back out the no_cache_middleware added in f3a85d1. Fresh installs have no
cache so it is not needed for first run; cache during testing is cleared
manually. The uninstaller arg-bug fix from the same commit is kept.
2026-06-22 00:38:08 +08:00
yiqi-017 cd9f029edc fix(desktop): uninstaller arg bug + no-cache for bridge static assets
Bug 1 (uninstall.bat could not delete the folder): %~dp0 ends with a
backslash, so -BundleDir "%~dp0" passed "...\dir\" — the trailing \" escaped
the closing quote and PowerShell received a path with a literal quote
("Illegal characters in path"). Resolve-Path failed, the deleter ran rd on a
garbage path, and nothing was removed. Strip the trailing backslash in the
.bat before passing, and defensively trim stray quotes/separators in the ps1.

Bug 2 root cause (shortcut prompt / UI showed stale code after updates):
the bridge served app.js via aiohttp's static handler with only
ETag/Last-Modified and no Cache-Control, so WebView2 heuristically cached it
and kept serving an old app.js after rebuilds. Add a no_cache_middleware
that sets Cache-Control: no-cache, no-store, must-revalidate on GET/HEAD.
2026-06-22 00:31:11 +08:00
yiqi-017 eab0b4a02b chore(desktop): remove temp diagnostic banner from shortcut prompt
Bug 2 root cause was WebView2 serving a stale cached app.js (no
Cache-Control header on the bridge static response). With a fresh
extract / cleared cache the first-run prompt works. Revert the diagnostic
instrumentation back to the clean maybeAskDesktopShortcut.
2026-06-22 00:08:26 +08:00
yiqi-017 0191b28609 chore(desktop): TEMP diagnostic banner for first-run shortcut prompt
Not a fix — instruments maybeAskDesktopShortcut with an on-page banner
reporting __TAURI__ availability, shortcut_should_ask result, and whether
window.confirm fires/returns, so we can locate why the first-run prompt
never shows. To be reverted once the cause is confirmed.
2026-06-21 23:41:33 +08:00
yiqi-017 4e1fa78ecf fix(desktop): first-run shortcut prompt + uninstaller folder deletion
Bug 1 (shortcut prompt only showed on the second launch): a native rfd
dialog spawned from the Rust startup thread has no parent window and got
buried behind the main window on first launch. Move the prompt to the web
UI: add shortcut_should_ask / shortcut_decide commands; the frontend asks
once via window.confirm after load (always on top). The startup thread now
only self-heals the shortcut path when already enabled.

Bug 2 (uninstall.bat could not delete the folder): kill ANY process whose
exe lives inside the bundle (not just GenericAgent/python by name), and run
the folder delete from a detached temp .bat that retries the recursive
remove ~20x to cover the window where uninstall.bat releases its handle.
2026-06-21 23:18:29 +08:00
yiqi-017 15c59dd1e7 feat(desktop): add portable uninstaller for Windows
Ship uninstall.bat (top-level, double-click entry) + uninstall_windows.ps1
(worker under runtime/) in the Windows portable bundle. The uninstaller:
- gracefully stops the bridge, then force-kills bundle-owned processes on
  ports 14168/8900 (filtered by exe path so other bundles are untouched)
- removes the desktop shortcut only when it targets this bundle
- removes ~/.ga_desktop_settings.json
- schedules deletion of the bundle folder after exit (detached cmd)

Wire both scripts into the release-package workflow.
2026-06-21 22:48:26 +08:00
yiqi-017 ccd912da08 feat(desktop): auto-create desktop shortcut on first run (Windows)
Windows portable bundle now offers to create a desktop shortcut on first
launch via a native yes/no dialog, remembers the choice in
~/.ga_desktop_settings.json (desktop_shortcut), and self-heals the .lnk
target to current_exe() on every enabled launch so a relocated bundle
keeps working.

Also add read_settings/merge_settings and route the three existing
settings writers through merge, so sibling keys (like desktop_shortcut)
are no longer clobbered by the python_path/project_dir rewrite.
2026-06-21 21:48:24 +08:00
yiqi-017 5af3d4497e ci(macos): bundle bilingual install guides (zh + en) with xattr workaround 2026-06-19 02:32:52 +08:00
yiqi-017 87bc3bd14a feat(conductor): follow desktop-selected model live + build on test_yiqi
Conductor and its subagents always used the first model (llm_no=0)
because GenericAgent() defaults to index 0 and conductor never switched.
Read ui.llmNo from ~/.ga_desktop_settings.json and apply it before each
conductor task (live follow) and on every subagent spawn, so the
conductor uses whatever model the user picked in the desktop UI.

Also enable the three desktop package workflows on the test_yiqi branch
and add frontends/conductor.py to their path filters so conductor
changes trigger a build.
2026-06-19 00:26:11 +08:00
yiqi-017 1dc186805f style(desktop): remove pricing disclaimer from token page 2026-06-18 22:43:07 +08:00
yiqi-017 40cbe4441e style(desktop): tidy conductor token tab — auto table layout + 1em icon
The conductor token tab only has two summary rows but reused the chat
tab's fixed-layout 6-column table, so the first column ate all the
slack and looked sparse. Add a tok-table--conductor class that switches
just that tab to auto layout with evenly distributed columns. Also size
the conductor row icon to 1em so it matches the text instead of blowing
up to the SVG viewBox size. Chat tab layout is unchanged.
2026-06-18 22:00:16 +08:00
yiqi-017 a72b7a5b14 fix(desktop): don't trust stale settings from inside macOS .app bundle
On macOS, App Translocation runs a quarantined .app from a random
read-only copy, so bundle_root() can't see our own runtime/ and
get_or_discover_config() would fall back to ~/.ga_desktop_settings.json
— silently pointing the bridge at a previously installed checkout. Add
running_inside_app_bundle() and skip stale settings when running from a
packaged .app, falling through to .app-relative auto-discovery instead.
2026-06-18 19:57:41 +08:00
yiqi-017 0c4b602b1b ci(macos): fix 'app is damaged' — preserve signature, add unquarantine launcher
cp -R broke the symlinks and ad-hoc code signature inside GenericAgent.app,
which makes Apple Silicon report the bundle as damaged. Copy with ditto and
re-apply an ad-hoc signature so it verifies. Also ship a 'Start
GenericAgent.command' that runs xattr -cr to clear the download quarantine
flag before launching, so users avoid the damaged/Gatekeeper prompt without
touching a terminal. README and SHA256SUMS updated accordingly.
2026-06-18 19:02:57 +08:00
yiqi-017 143a0ac3ea ci(macos): authenticate python-build-standalone API call to avoid 403 rate limit
The assemble step queried api.github.com/releases/latest anonymously,
which is capped at 60 requests/hour/IP on shared runners and failed with
HTTP 403 rate limit exceeded. Pass GITHUB_TOKEN via GH_TOKEN env and add
an Authorization header so the call uses the 1000/hour authenticated limit.
2026-06-18 18:53:16 +08:00
yiqi-017 69ba144c90 ci(macos): drop npm cache and use npm install to match win/linux
The mac workflow enabled cache: npm with cache-dependency-path pointing
at package-lock.json, but that file is gitignored and never committed, so
setup-node failed with 'unable to cache dependencies' and npm ci would
also fail without a lockfile. Align with the win/linux workflows which use
plain npm install and no cache.
2026-06-18 18:48:23 +08:00
yiqi-017andGenericAgent 64634a582d fix(desktop): onBridgeReady 无条件刷新状态条
有活跃会话时 refreshStatusLabel 未被调用,
导致状态条卡在「连接中」直到 hydrate 完成。

Co-authored-by: GenericAgent <292701730+GenericAgent@users.noreply.github.com>
2026-06-11 16:59:01 +08:00
yiqi-017andGenericAgent 22cc940795 fix(desktop): 切换会话后恢复「已运行 Xs」elapsed badge
切换到已hydrate的会话时,setActiveSession的else分支
漏调restoreElapsedBadges,导致DOM重建后badge丢失。

Co-authored-by: GenericAgent <292701730+GenericAgent@users.noreply.github.com>
2026-06-11 16:06:30 +08:00
yiqi-017 5ec31c3c89 fix: 修复两个侧边栏拖动延迟(拖拽时禁用transition) 2026-06-11 15:15:23 +08:00
yiqi-017 e256e9b982 feat: turn_segs 结构化渲染,支持按轮独立渲染与模型切换 2026-06-08 18:42:38 +08:00
yiqi-017 554586fa82 fix: 持久化 llm_history 修复重启后模型幻觉工具调用 2026-06-06 16:09:22 +08:00
yiqi-017 7173a05b06 [FIX]:估算价格改成缓存率 2026-06-06 12:00:41 +08:00
yiqi-017 8e37028370 [update]:修改文件上传大小至500MB 2026-06-05 18:30:29 +08:00
yiqi-017 c8e19dd13b fix(desktop): 打字机步长自适应 + 修复 details 自冻结循环
- renderDraft 步长按上次渲染耗时自适应:轻文档小步封顶 160 字/帧
  平滑打字,大块到达时数十帧内追平而非一帧瞬跳一大坨;重文档加大
  步长用更少次昂贵渲染排空积压,避免单帧卡死数百 ms。
- rewriteDraftBubble 程序化恢复 details open 态会异步触发 toggle,
  置 _suppressToggleFreeze 标记让 guard 忽略,setTimeout(0) 在已排队
  的 toggle 任务后清除,消除自冻结循环。
- bump app.js?v=102→103 刷新缓存。
2026-06-05 00:02:50 +08:00
yiqi-017 21231c653b feat(desktop): add collapsible daily cost trend chart to token stats
Pure SVG line chart showing daily spending (¥) over time. Respects
date filter, fills zero-cost gaps, uses local timezone for grouping.
Hidden on Conductor tab.
2026-06-02 04:23:00 +08:00
yiqi-017 243645e5e6 i18n(desktop): localize conductor token stats and pricing disclaimer 2026-06-02 03:58:13 +08:00
yiqi-017 0c45c86a42 feat(desktop): token stats tab bar separating chat and conductor
- Two tabs: 聊天 (chat sessions) and Conductor (cumulative/current)
- Conductor tab hides date filter and stat-row summary
- Remove green background and expand triangle from conductor rows
- Bump app.js and styles.css cache versions
2026-06-01 19:31:41 +08:00
yiqi-017 d66f84e0d3 style(desktop): use conductor SVG icon in token stats rows 2026-05-30 22:13:41 +08:00
yiqi-017 febd3d86fc fix(desktop): conductor token accumulation loop on refresh
Always overwrite last snapshot with current values (even zero) so
restart detection only triggers once instead of every refresh.
2026-05-30 00:06:54 +08:00
yiqi-017 7223a0d2ec fix(desktop): update model pricing + add pricing disclaimer
- o4-mini: .10/.40 -> /usr/bin/bash.55/.20 (price drop)
- deepseek-v4-pro: /usr/bin/bash.55/.19 -> /usr/bin/bash.435//usr/bin/bash.87 (permanent 75% cut)
- Add claude-opus-4-8 at /5
- Add disclaimer: pricing may vary by API provider
2026-05-29 23:46:58 +08:00
yiqi-017 90960679b9 feat(desktop): persist conductor token stats via bridge file storage
Two rows: cumulative total (survives conductor restart) and current
session. Restart detection via value comparison; data stored alongside
bridge token history in desktop_token_history.json.
2026-05-29 23:40:34 +08:00
yiqi-017 b53f107e6e fix(desktop): skip token delta recording while session is busy
Prevents token records from splitting into two entries when polling
occurs mid-generation. The full delta is captured on the next poll
after the session becomes idle.
2026-05-29 23:09:47 +08:00
yiqi-017 90a37236aa feat(desktop): conductor token stats summary row in token page
- conductor.py: install cost_tracker + expose /token-stats endpoint (5 lines)
- app.js: fetch conductor token totals and display as a single summary row at top of token table (not expandable, with tooltip noting it's excluded from cumulative totals)
- styles.css: conductor row styling
2026-05-29 23:03:53 +08:00
yiqi-017 db7dd70ab3 fix(desktop): token stats title fallback when sess.title is empty
两个修复:

1. tokRenderTable 里 title 显示修复 — 新的 session naming 把 sess.title 默认设为空字符串,导致 token 统计 fallback 到原始 session ID(sess-xxx)。改为用 displayTitle(sess) 实时推导标题,和侧边栏一致。
2. tokPollBridge 里写入 history 时的 title 修复 — 同样的问题,写入时 sess?.title || sid 对空标题 fallback 到 ID。改为 sess ? displayTitle(sess) : sid。
2026-05-29 18:36:08 +08:00
yiqi-017 6fcdc7f2af [feat]:增加rename会话的功能 2026-05-27 21:36:07 +08:00
yiqi-017 4d31e1cd46 Merge branch 'feat/conductor' into main 2026-05-27 18:21:19 +08:00
yiqi-017 24ea45f028 [feat]:增加删除subagent的功能,增加跨域请求,增加subagent卡片点击展开的功能,并且把原本的collab.js全部放进去app.js里面 2026-05-27 18:19:38 +08:00
yiqi-017 51b2949424 @
feat(desktop): mark deleted sessions in token stats page

Show a "此会话已删除 / Session deleted" tag next to session titles
in the token usage table when the session no longer exists.
@
2026-05-24 22:47:08 +08:00
yiqi-017 913ec672a5 @
feat(desktop): persist token usage history to local file instead of localStorage

Token stats (history + snapshot) now stored in temp/desktop_token_history.json
via GET/POST /token-history endpoints, ensuring cross-browser consistency.
@
2026-05-24 15:38:59 +08:00
yiqi-017 a045524f84 feat(desktop):
>>   move session persistence from localStorage to backend API
>>
>>   Sessions are now loaded from GET /sessions and metadata updates (pin,
>>   title) go through PATCH /session/{sid}, eliminating cross-browser
>>   isolation issues between Chrome and Safari.
2026-05-24 15:12:38 +08:00
yiqi-017 46fc1faaa7 feat(desktop): session persistence + token stats fixes + model pricing tooltip
- Sessions persist across refresh (localStorage metadata + bridge disk storage)
- Bridge restores LLM context on restart via /session/{sid}/restore endpoint
- Sort sessions: pinned first, then by most recent activity
- Fix token stats: remove double .json() parse, handle negative deltas after restart
- Add model pricing tooltip on hover in token statistics page
- localStorage only stores session metadata (not messages) to prevent quota overflow
- Remove duplicate tokPollBridge() call in pollSession
2026-05-21 15:05:37 +08:00
yiqi-017 c2a7707d1d feat: token stats page with per-prompt tracking, time filter & cost estimation
- Add /token-stats bridge endpoint exposing cost_tracker data + model name
- Frontend localStorage persistence for per-prompt token records (WS-triggered)
- Time range filter (datetime-local), pagination, expandable session details
- Model-based cost estimation (Claude/GPT/DeepSeek price table with cache rates)
- All UI text via i18n, all colors via CSS variables
2026-05-20 18:38:57 +08:00
yiqi-017 94b83d4226 Revert "feat: token stats with persistent history, time filter, pagination & model-based cost"
This reverts commit 011824860d.
2026-05-20 15:40:42 +08:00
yiqi-017 5180eca7d6 feat: token stats with persistent history, time filter, pagination & model-based cost
- Persist per-prompt token usage to ~/.GenericAgent/token_history.json
- Add GET /token-stats API endpoint with since/until filtering
- Token page: real data, expandable per-prompt details with model & cost
- Model price table for accurate cost estimation (GPT/Claude/DeepSeek/etc)
- Time range filter (datetime-local) with reset button
- Pagination (15 sessions per page)
- Stat cards (total/today/cost) follow time filter, today always absolute
- Migrate Rust settings path to ~/.GenericAgent/ga_desktop_settings.json
- Fix cost_tracker Python 3.9 compat (from __future__ import annotations)
2026-05-20 15:14:50 +08:00
yiqi-017 3ae3b065d4 feat: session search, collapsible & resizable right panel
- Wire up search input to filter sessions by title/message content
- Add toggle button to collapse/expand the session panel
- Add drag handle for resizing panel width (160–400px)
2026-05-20 03:08:42 +08:00
yiqi-017 7fc64bb341 fix: use incremental streaming in ACP bridge to prevent text overlap
Switch to inc_out=True mode so queue items are incremental deltas
instead of cumulative text. The old cumulative approach broke when
agentmain's post-processing (</summary>\n\n insertion) shifted offsets,
causing the bridge's delta calculation to produce overlapping or
truncated content.

Now "next" items are forwarded directly, and "done" is only used as
content when no streaming occurred (error fallback).
2026-05-06 03:54:09 +08:00
yiqi-017 424324a429 docs: add codeg integration section to README 2026-05-05 15:34:57 +08:00
yiqi-017 7e357dcc64 refactor: move acp bridge to frontends/ 2026-05-05 14:28:13 +08:00
yiqi-017 88f0e69231 fix: mark ACP stdout fd as non-inheritable to prevent child process pollution
- os.set_inheritable(_stdout_fd, False) on both Windows and Unix
- Unix path now uses os.dup() + os.fdopen() consistent with Windows
- Prevents subprocess.Popen children from inheriting the ACP JSON-RPC
  file descriptor, which could corrupt the protocol stream
2026-05-02 17:46:13 +08:00
yiqi-017 6770a02d59 feat: enable verbose output in ACP bridge 2026-04-29 21:13:11 +08:00
yiqi-017 21d2a4ca20 feat: add ACP bridge for codeg integration
Stdio-based JSON-RPC bridge implementing the Agent Client Protocol,
allowing codeg to connect to GenericAgent as a live ACP agent.

Handles Windows binary stdout/stdin, redirects stray prints to stderr,
and converts GenericAgent's cumulative text queue to ACP delta streaming.
2026-04-29 15:46:47 +08:00