Commit graph

986 commits

Author SHA1 Message Date
_Kerman
ec133ce2a4 fix: align plugin session start injection 2026-07-07 14:43:04 +08:00
_Kerman
d25cb76138 fix: align v2 external hook behavior 2026-07-07 14:36:02 +08:00
_Kerman
b2fe7a7c7c Merge branch 'kimi-code-v2' of https://github.com/MoonshotAI/kimi-code into kimi-code-v2 2026-07-07 14:17:43 +08:00
_Kerman
b6c9413baa refactor(agent-core-v2): rename tool dedupe domain 2026-07-07 14:16:59 +08:00
7Sageer
ebe16e39ff fix(server-v2): treat already-authenticated OAuth start as success
When the Kimi OAuth toolkit short-circuits via its `ensureFresh` fast path (the cached refresh token is still usable), `toolkit.login` resolves without firing `onDeviceCode`. The v2 `OAuthService.startLogin` previously rejected in this case, so `POST /api/v1/oauth/login` returned a 500 that the web client swallowed and mislabeled as "current daemon does not support login". CLI-authenticated users could not (re)enter the v2 daemon through the web UI.

Treat that path as already authenticated: provision the managed provider (idempotent), refresh OAuth provider models so `defaultModel` is seeded (`/auth` then reports ready, matching v1 parity), and return a new `status: 'authenticated'` `OAuthFlowStart` variant so the web LoginDialog can skip the device-code UI entirely instead of falling into its catch-all "unsupported daemon" state.

The protocol `OAuthFlowStart` schema is now a discriminated union on `status`; kimi-web's wire / composable / LoginDialog types are updated to handle the new `authenticated` branch.

Tests: updated the v2 OAuthService test that previously asserted the buggy rejection to instead assert the fast path returns authenticated and provisions the provider.
2026-07-07 14:16:48 +08:00
_Kerman
898fa70901 chore: simplify toolDedupe interface 2026-07-07 14:00:28 +08:00
_Kerman
c51d8df461 Merge branch 'kimi-code-v2' of https://github.com/MoonshotAI/kimi-code into kimi-code-v2 2026-07-07 13:59:20 +08:00
_Kerman
42dd3ef566 refactor: allow full agent event types 2026-07-07 13:55:38 +08:00
7Sageer
453580264f fix(agent-core-v2): align full compaction handoff with v1 2026-07-07 13:39:59 +08:00
7Sageer
339022b375 feat(agent-core-v2): add workspace add-dir command 2026-07-07 13:37:09 +08:00
haozhe.yang
b37345e5d5 refactor(agent-core-v2): remove domain barrels via debarrel tool
- add scripts/debarrel.mjs (ts-morph) to rewrite #/<dir> imports to
  precise leaf specifiers and regenerate src/index.ts
- rewrite src and test consumers across the package to import from leaf
  files instead of domain barrels
- delete src/app/event/index.ts barrel and load its leaves from the
  package entry
- extract applyPromptMetadataUpdate so /api/v1 prompt submission derives
  the easy session title, matching /api/v2
- rename the v2 prefix to beta in the CLI prefix tests
2026-07-07 13:33:18 +08:00
haozhe.yang
41ed52cd62 feat(v2): mirror v1 prompt metadata and sync protocol parity
- derive session title and lastPrompt from the first prompt before the turn launches, then broadcast session.meta.updated on IEventService so the web title updates live
- generalize the prompt metadata update to cover prompt() and activateSkill(), not just plugin commands
- add turn.started origin and new prompt/session/fs error codes to the protocol schema
- rename the background.task_id_empty error code to task.task_id_empty
2026-07-07 11:20:11 +08:00
haozhe.yang
40cbc1a7f4 refactor(agent-core-v2): replace blob selector with ModelDef.blobs codec
- introduce ModelBlobCodec ({ dehydrate, rehydrate }) declared on ModelDef.blobs; the model owns record/state traversal, WireService owns storage I/O
- remove WireBlobSelector / WireBlobTarget and the contextBlobSelector seed; declare blob handling inline on ContextModel.blobs
- rename IAgentBlobService.rehydrateParts -> loadParts and PartsRehydrator -> PartsTransformer (same shape for both directions)
- WireService.appendToWireLog routes dehydrate through the per-record model codec instead of a construction-time selector
2026-07-07 11:20:11 +08:00
haozhe.yang
b0fafa5f5c Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	apps/kimi-web/src/api/daemon/agentEventProjector.ts
2026-07-06 23:47:51 +08:00
Kai
25a655cf88
feat(agent-core): enable Preserved Thinking by default on the Anthropic provider (#1432)
* feat(agent-core): enable Preserved Thinking by default on the Anthropic provider

Default thinking.keep to "all" for the Anthropic provider (Claude and Kimi in Anthropic-compatible mode) while Thinking is on, via a context_management clear_thinking_20251015 edit, mirroring the Kimi default. Reuses [thinking] keep and KIMI_MODEL_THINKING_KEEP (env > config > default "all"); off-values disable it.

* feat(kosong): route Anthropic Preserved Thinking through the beta Messages API

Force the beta endpoint (client.beta.messages.create) when thinking.keep is enabled, since clear_thinking_20251015 is only honored there. Also prepend clear_thinking to any existing context-management edits (for example clear_tool_uses) instead of replacing them, keeping it first as Anthropic requires when combining edits.

* docs: clarify Anthropic beta endpoint and compaction keep behavior

Note in code comments and bilingual docs that enabling Anthropic Preserved Thinking routes requests to the beta Messages API (client.beta.messages.create), with keep=off as the escape hatch back to the standard endpoint. Correct the resolveThinkingKeep comment to reflect that compaction shares ConfigState.provider and intentionally carries the same keep.

* test(kosong): cover Anthropic beta endpoint (streaming and forced betaApi)

Add a streaming beta-endpoint capture and a test that withThinkingKeep forces the beta endpoint even when constructed with betaApi: false, pinning down the documented behavior.
2026-07-06 23:45:17 +08:00
github-actions[bot]
379bc57ef0
ci: release packages (#1378)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-06 23:18:32 +08:00
qer
c4c2fef162
chore(skills): merge similar changelog entries and credit external contributors (#1442) 2026-07-06 23:18:09 +08:00
haozhe.yang
fbb4a3a0c6 refactor(agent-core-v2): drop empty args from AgentBlobServiceImpl registration
AgentBlobServiceImpl no longer takes constructor arguments, so remove the
now-unnecessary [{}] from its SyncDescriptor registrations in the agent
lifecycle service and the blob tests.
2026-07-06 23:01:10 +08:00
haozhe.yang
959717e922 feat(v2): add kimi v2 prefix and fold v1 loop events on replay
- handle `kimi v2 <subcommand>` in main.ts, gated on KIMI_CODE_EXPERIMENTAL_FLAG via shared isKimiV2Enabled
- route `kimi server run` to server-v2 through the same switch; drop server-v2 standalone main.ts/dev script
- fold v1 context.append_loop_event records into messages at replay and snapshot so v1 sessions restore on agent-core-v2
- report backend: 'v2' in meta; serve session status via SessionLegacyService.status
- drop unused service options (blob/fullCompaction/goal/permissionGate); permissionGate reads agentId from scope context
2026-07-06 22:57:49 +08:00
qer
903e8ed93a
fix(web): clarify archive session confirmation copy (#1428)
* fix(web): clarify archive session confirmation copy

* fix(web): drop delete mention from archive confirmation copy

* feat(web): add archived-sessions restore entry to mobile settings

Mobile used a separate settings bottom-sheet with no archived-sessions
restore surface, so the archive confirmation pointing users to Settings
to restore was untrue on mobile. Add an Archived sessions sub-view to
the mobile settings sheet with search, sort and restore, mirroring the
desktop Settings tab.

* fix(web): refresh mobile archived list and use Input primitive

Refresh the archived-sessions list each time the mobile sub-view opens so
sessions archived from the mobile switcher show up without remounting the
sheet, and replace the hand-rolled search input plus inline svg with the
shared Input primitive.

* fix(web): use Button primitive for mobile archived restore

Render the mobile Archived sessions restore action with the shared Button
primitive instead of a hand-rolled button and scoped CSS, matching the
desktop archived list and the app's design-system rule.
2026-07-06 22:48:01 +08:00
liruifengv
2374bc41c3
feat(kimi-web): render cron fire notices in the web chat (#1426)
* feat(kimi-web): render cron fire notices as in-transcript cards

Show scheduled-reminder fires as distinct notice cards in the web chat,
both live and after a reload, instead of hiding them. Each card carries
a humanized schedule, a dimmed job id, and a collapsible prompt body.

* fix(kimi-web): isolate cron notice prompt id and route prefixed events

- Give synthesized cron messages a fresh promptId so a fire mid-turn
  cannot be reconciled into the optimistic user echo and hide it.
- Add cron.fired to KNOWN_AGENT_CORE_TYPES so event.-prefixed frames
  reach the projector and render live too.

* fix(kimi-web): truncate long one-line cron prompts when collapsed

Slice the first line to the collapse limit with an ellipsis when a
single-line prompt exceeds it, so the collapsed state actually truncates
and the expand toggle is not a no-op for common one-line reminders.

* fix(kimi-web): keep cron notices from reconciling into optimistic user echoes

Skip optimistic-echo reconciliation for user messages whose origin is
cron_job or cron_missed: their prompt text can coincide with a still-
optimistic user message, and the loose content match would otherwise
replace the user's turn with the cron notice instead of appending.

* fix(kimi-web): keep in-turn cron injections from breaking tool results

A cron injection steered into an active turn lands inside that turn's
message sequence, between a tool use and its result. Treating it as a
hard user-turn boundary flushed the pending assistant group, so the next
tool result had no group to fold into and the tool rendered without
output. Embed such in-turn cron notices as a block inside the assistant
group instead, and only render a cron at a turn boundary as its own turn.

* fix(kimi-web): only embed cron notices while a tool is in flight

Embedding whenever a group was pending was too broad: on REST snapshots
without prompt ids the whole transcript shares one group, so an idle cron
fire merged into the previous assistant answer and its own reply kept
going in that group. Embed only while the group has a running tool (a
cron sandwiched between a tool use and its result); flush to its own
turn otherwise.

* fix(kimi-web): omit synthetic prompt id on cron notices

The synthesized cron message carried a cron_pr_ promptId that the web
client caches into promptIdBySession for Stop/abort. Because it is not a
real daemon prompt id, it clobbered the active promptId, so Stop first
aborted a nonexistent prompt and only recovered via the error fallback.
Omit the promptId; the reducer already skips optimistic-echo
reconciliation for cron-origin messages, so it is not needed for de-dup.
2026-07-06 22:25:19 +08:00
7Sageer
ad9997fd91 fix(agent-core-v2): seed wire metadata via lifecycle 2026-07-06 22:19:09 +08:00
liruifengv
ac5b5e4cbf
fix(kimi-web): keep tool components from jumping on expand or collapse (#1433)
* fix(kimi-web): keep tool components from jumping on expand or collapse

Also show the scroll-to-bottom button whenever scrolled up, and render a
fallback icon for tools without a dedicated glyph.

* fix(kimi-web): preserve bottom follow during content-only resizes

Late-loading media can grow after scrollKey has run; keep chasing the
bottom on content growth, and only suppress follow during the pinned
expand/collapse window.
2026-07-06 22:19:02 +08:00
qer
d86fa38e11
fix(kimi-web): disable text hyphenation and code ligatures (#1438)
Set hyphens: none (with the -webkit- prefix) on body so chat and markdown text never gain a hyphen glyph at a line break; components still control where lines wrap via word-break/overflow-wrap.

Disable the ligatures that coding fonts enable by default (liga/calt/ss01) on native code elements so code renders literally, e.g. != stays as two characters.
2026-07-06 22:12:43 +08:00
qer
0824e7b668
chore: ignore and remove throwaway scratch files (#1439)
Agent working notes (HANDOVER/handoff) and one-off UI prototype HTML files were committed by mistake. Remove the already-tracked ones, add .gitignore patterns for these classes of files and a .tmp/ scratch dir, and document the rule plus a pre-commit self-check in AGENTS.md so future mistakes are caught mechanically.

No publishable package is affected, so this PR needs no changeset.
2026-07-06 22:12:14 +08:00
qer
c5e3e80041
feat(web): render AgentSwarm as an inline tool card (#1425)
* feat(web): render AgentSwarm as an inline tool card

Replace the bottom SwarmCard footer and the messagesToTurns live-skip
with one dedicated inline tool card for AgentSwarm. The card shows a
phase overview plus a per-subagent accordion: live progress while it
runs, parsed aggregated result once it completes (and after a refresh
that has already dropped the live tasks).

Refresh and resync keep member identity metadata (swarmIndex,
parentToolCallId, subagentType, runInBackground) stable across skeleton
task replacement in the reducer, and the .content-wrap flex layout is
hardened against the overflow compression that previously displaced the
footer.

* fix(web): handle swarm review feedback

- SwarmTool: when AgentSwarm fails before producing a structured
  agent_swarm_result (e.g. argument validation), render the raw tool
  output instead of the "waiting for subagents" placeholder so the
  failure cause is visible.
- resolveSwarmMembers: source live members from the AppTask store keyed
  by parentToolCallId rather than buildSwarmGroups, which filters out
  single-member groups. A resume-only AgentSwarm now streams its live
  progress before the final result arrives. The badge counter still
  relies on buildSwarmGroups's filter.

* fix(web): carry streamed subagent text into swarm rows

Swarm subagents that stream normal assistant output accumulate it on
AppTask.text (text-kind taskProgress), not outputLines. The new live
member map was dropping `text`, so a still-composing subagent rendered
an empty / stale row until the structured result arrived.

- Add `text` to SwarmMember and thread it through buildSwarmGroups and
  swarmMembersByToolCall.
- SwarmTool: prefer member.text for both the row activity preview and
  the expanded body; fall back to outputLines / summary.
- Tests cover text propagation through both helpers.

* fix(web): merge swarm result rows and fall back to raw output

Address the two latest swarm review comments:

- Rows: when a parsed agent_swarm_result coexists with live AppTasks
  (which the detail panel also depends on), the inline card previously
  only rendered the live members. Interrupted swarms can carry
  state="not_started" / outcome="aborted" result entries for items that
  never spawned a task; those rows were dropped until a refresh cleared
  the live tasks. Extract the row model into buildSwarmCardRows and
  merge result-only aborted/not-started rows with the live member rows.
- Fallback: when the tool is no longer running but produced no
  structured result (argument validation, parser miss, or legacy
  legacy transcript), render the raw tool output instead of
  "Waiting for subagents…" so the final text / failure cause is
  visible to the user.

* fix(web): parse swarm result subagent bodies defensively

Producer writes subagent body unescaped, so a subagent that analyzes or
emits an AgentSwarm snippet can include a literal "</subagent>" inside
its body. The non-greedy regex treated that as the row close and truncated
the body in the result-only path (post-refresh where the AppTask store is
gone).

Rewrite the parser to scan opening tags, then resolve each row's body as
everything up to the last "</subagent>" before the next row's opening tag
(or document end), preserving embedded close-tag strings. Add tests for a
literal "</subagent>" within a single body and across sibling rows.

* fix(web): only count top-level subagent result tags

A subagent body that contains a literal `<subagent ...>` tag — for
example emitting an AgentSwarm/XML snippet — was being pre-collected as
another result row, splitting the real body and producing duplicate /
bogus subagents after refresh where the AppTask store is gone.

Rewrite parseSubagents with a depth-tracking tokenizer: scan every
`<subagent ...>` / `</subagent>` token in order, push a real row frame
only at the outermost level, and treat openings / closings while nested
inside another body as body text. Drop the now-inaccurate "literal
</subagent> without matching open" regression tests; replace with tests
that verify a balanced nested snippet stays inside the parent body and
does not register as a separate row.
2026-07-06 22:05:05 +08:00
qer
a5fbcb75b4
fix(kimi-web): keep composer toolbar usable on narrow windows (#1436)
The desktop composer toolbar renders every control on one row and relies on
overflow:hidden to fit, so between the mobile breakpoint and a wide window it
clipped its own content. Shed secondary ink below 980px (the context readout
moves into the ring tooltip, the model name truncates earlier, permission is
capped) and keep the context ring visible on phones too, instead of sending it
to the settings sheet.
2026-07-06 21:54:38 +08:00
7Sageer
10922fc70f
feat(telemetry): add system metrics collection (#1435)
* feat(telemetry): add system metrics collection

Add periodic CPU and memory telemetry sampling with warmup capture, lifecycle cleanup, and tests.

* fix(telemetry): attach prompt session to system metrics
2026-07-06 21:54:12 +08:00
haozhe.yang
590eca5ccd feat(server-v2): wire server-v2 into CLI and close v1 parity gaps
- cli: opt into server-v2 via KIMI_CODE_EXPERIMENTAL_FLAG, lazy-loaded behind a RoutedServer adapter so the v1 module graph stays untouched by default
- build: add hashImportsPlugin (rolldown/tsdown) to resolve #/ subpath imports of inlined agent-core-v2 when bundling server-v2
- server-v2: add --dangerous-bypass-auth flag disabling bearer auth on every route, surfaced on /meta via dangerous_bypass_auth
- server-v2: serve bundled web UI at GET / + SPA fallback when webAssetsDir is set (auth-exempt, mirroring v1)
- server-v2: snapshot auto reader reads state.json + wire.jsonl from disk with a hard timeout; legacy keeps the live assembly as escape hatch
- server-v2: POST /sessions/{id}/profile now updates title, metadata, and agent_config and broadcasts session.meta.updated on title change
- server-v2: session list/children project live ISessionActivity status and filter by status; add archived_only query and workspace_id validation
- server-v2: close cwd gap G3 — persist cwd on session metadata and surface it on the index so unregistered workspaces keep their cwd
- server-v2: GET /warnings surfaces agents-md-oversized; add GET /workspaces/{id}/skills session-less scan
- server-v2: broadcaster reads the cold watermark from the disk journal and broadcasts title updates to every connection
- agent-core-v2: fix plan-file path resolution in AgentPlanService
- server: rename IFileService to IFileStore
2026-07-06 21:53:33 +08:00
7Sageer
1854e6df29 feat: add v2 session export 2026-07-06 21:40:12 +08:00
qer
578f7d334c
fix(web): reconcile session from snapshot on reopen (#1409)
* fix(web): reconcile session from snapshot on reopen

* fix(web): discard stale snapshot when a newer prompt races reopen

* fix(web): harden reopen snapshot against first-open and optimistic-send races

* fix(web): keep evicted reopens subscribed when a snapshot races

* fix(web): let resync snapshots bypass the reopen staleness guard

* fix(web): force-apply the snapshot after an undo

* fix(web): gate session reopen on durable seq instead of updatedAt

* refactor(web): always rebuild reopened sessions from a snapshot

* fix(web): sharpen reopen snapshot discard and skip rebuilds mid-stream

* refactor(web): unconditionally apply session snapshots, drop the staleness guard

* fix(web): preserve loaded older messages when reopen snapshots apply
2026-07-06 21:30:25 +08:00
qer
4aacddc432
fix(kimi-web): clarify desktop notification title and icon (#1434) 2026-07-06 21:18:45 +08:00
7Sageer
dd9077595d
chore(agent-core): classify turn_interrupted telemetry cause (#1431)
Add an `interrupt_reason` field to the `turn_interrupted` telemetry event so the data can tell a deliberate user cancel (`user_cancelled`) apart from a programmatic abort (`aborted`), max-steps exhaustion (`max_steps`), an error (`error`), or a hook-filtered turn (`filtered`).

The user-cancel signal comes from the existing UserCancellationError carried as the abort signal's reason, reused here without changing any loop control or external protocol semantics.
2026-07-06 20:52:40 +08:00
7Sageer
cd5dfa91c1 fix(agent-core-v2): keep bang-shell stdout empty on silent success
When a `!cmd` shell command exits 0 with no stdout/stderr, the v2
AgentRPCService.runShellCommand fell through to a success branch that
filled stdout with the bash tool's "Command executed successfully."
signal, so the TUI rendered that text instead of "(no output)".

Drop that fill-in so the success signal stays only in result.output —
matching v1 ToolManager.runShellCommand, which uses it solely as a stderr
fallback on non-zero exit. formatBashOutputForDisplay then reaches its
"(no output)" branch for silent successful commands, restoring the
tui-bang-shell e2e expectation.
2026-07-06 20:38:20 +08:00
7Sageer
669bb8e04d fix: align v2 model thinking and mcp startup 2026-07-06 20:34:10 +08:00
7Sageer
d9d4a413f7 Merge branch 'kimi-code-v2' of https://github.com/MoonshotAI/kimi-code into kimi-code-v2 2026-07-06 20:32:36 +08:00
haozhe.yang
a32aa95c6f Merge remote-tracking branch 'origin/main' into HEAD 2026-07-06 20:22:27 +08:00
7Sageer
e181cb5f44 Merge branch 'kimi-code-v2' of https://github.com/MoonshotAI/kimi-code into kimi-code-v2 2026-07-06 20:22:11 +08:00
haozhe.yang
2ec070b1b2 refactor(agent-core-v2): scope wire records per agent as wire.jsonl
- replace the shared 'wire' append-log keyed by a hashed homedir with a
  per-agent wire.jsonl beneath each agent's homedir
- add WIRE_RECORD_FILENAME and wireRecordScope(homedir, homeDir); drop
  wireRecordPersistKey
- update session fork and agent wire wiring to the new scope/filename
- add one-off resume round-trip and debug tests over real wire logs, plus
  a cross-scope ILogService resolution test
2026-07-06 20:21:12 +08:00
haozhe.yang
dd3c7222a7 refactor(agent-core-v2): route context writes through 1.4 ops and declared tool delivery
- contextMemory: emit 1.4 ops (append_message/clear/apply_compaction/undo) on the live write path; demote context.splice to legacy (replay + rare single-deletes); drop context.append_loop_event; share computeUndoCut between reducer and service; extend contextBlobSelector to append_message records
- prompt: consume tool result `delivery` via onDidExecuteTool and perform the steer at L4, stripping the side channel before it reaches the loop; delegate undo/clear/append to context service
- skill tool: stop reaching into IAgentPromptService; declare a `delivery: steer` on the result for the agent layer to consume
- tests: update stubs/snapshots, add delivery threading coverage, drop obsolete v1.4->v1.5 migration test, clarify several test titles
- also includes a saved session transcript at repo root
2026-07-06 20:20:11 +08:00
haozhe.yang
f851cc4776 refactor(agent-core-v2): migrate service hooks to IEventBus events
- replace OrderedHookSlot-based hooks (turn onLaunched/onEnded, context onSpliced, permission approval request/resolve, task onDidNotify, fullCompaction onDidCompact, toolRegistry register/unregister) with IEventBus domain events
- add contextMemory named primitives (append/clear/undo/applyCompaction) on wire-protocol 1.4 ops, retaining splice for replay and rare single-deletes
- update externalHooks, goal, swarm, compaction, context-injector, micro-compaction, and task-notification to subscribe to the new events
- drop removed hook slots from the turn and task test stubs
2026-07-06 20:18:53 +08:00
Haozhe
6c0ce09414
feat(server): support restoring and listing archived sessions (#1073)
* feat(server): support restoring and listing archived sessions

- add a `:restore` session action that clears the archived flag in state.json and returns the restored session
- add an `archived_only` list query param, mutually exclusive with `include_archive`, that post-filters to archived sessions
- keep the implementation in the server layer as a temporary measure until agent-core exposes restore natively

* fix(server): paginate archived-only sessions before response

* feat(web): add archived sessions page in Settings

Browse, search, filter by workspace, sort, and restore archived sessions
from a new Archived tab in Settings, backed by the server archived_only
list and :restore action.

* fix(web): keep archived Load more visible when a page filters to empty

When a search or workspace filter empties the loaded archived page, the
Load more button was hidden inside the non-empty branch, so users could
not fetch older pages to find a match. Move the button out so it stays
available whenever more archived pages exist.

* fix(server): preserve after_id bound while draining archived pages

Draining an archived_only request that starts from after_id would switch
to before_id and cross the pivot, reintroducing the pivot and older
sessions. Take a single filtered page for after_id instead of draining
past the lower bound.

* fix(server): drain archived_only within the after_id bound

An archived_only request starting from after_id now keeps paging toward
older sessions until it reaches the pivot, instead of treating the first
page as exhaustive. The loop stops as soon as it encounters the pivot
session itself, so it never reintroduces the pivot or anything older.

* feat(web): drain all archived pages for global search and sort

When the user searches, sorts, or changes the workspace filter in the
Archived settings page, fetch every remaining archived page first so the
client-side filter and sort run over the full set rather than only the
pages loaded so far.

* refactor(web): load all archived sessions upfront instead of paginating

Fetch every archived session once when the Archived settings tab opens and
drop frontend pagination entirely. Search, sort and workspace filter now run
over the full set, removing the empty-page and cursor bookkeeping that
previously caused bugs.

---------

Co-authored-by: qer <wbxl2000@outlook.com>
2026-07-06 20:09:45 +08:00
7Sageer
935f5c5f5d fix: align v2 oauth web search cleanup 2026-07-06 19:53:58 +08:00
7Sageer
f54ebe0499 fix: resolve v2 model capabilities and headers 2026-07-06 18:49:26 +08:00
liruifengv
fa6d198b01
fix(kimi-web): fix input caret and todo strikethrough (#1423)
* fix(kimi-web): keep composer caret visible when input is empty

The composer textarea coloured its empty state with `--faint`, and with no caret-color set the caret inherited that faint colour and nearly vanished until the first character was typed. Pin the caret to --color-text so it stays readable regardless of the placeholder state.

* fix(kimi-web): use currentColor for done todo strikethrough

TodoCard pinned the done-state strikethrough to --color-line-strong, which is lighter than the faint text in light theme and darker in dark theme, so the line looked washed-out and broken against the text. Drop the override so the line inherits the text colour, matching TasksPane and the design-system examples.

* fix(kimi-web): do not reserve width for hidden workspace row actions

The workspace header's more/add buttons were hidden with opacity: 0, which kept them in the flex layout and permanently reserved ~60px on the right, so the workspace name (flex:1) truncated long before the row was full. Hide them with display: none and restore display: inline-flex on hover/focus/open, so the name fills the row and only truncates once the buttons actually appear.

The same actions remain reachable via the right-click menu and the section kebab, so removing them from the tab order when hidden is acceptable.

* fix(kimi-web): keep workspace header row height stable on hover

Lock .gh-top to the sm IconButton height (26px) so revealing the hover actions no longer grows the row and nudges the path line and the groups below it. Follow-up to the display: none change: that freed the horizontal space but let the row height collapse when the buttons were hidden.

* chore: add changeset for kimi-web UI fixes

* fix(kimi-web): restore keyboard access to workspace actions

Revert the display: none change (and the min-height that accompanied it) for the workspace row's hover actions, going back to opacity-hidden buttons.

The display: none approach removed the buttons from the tab order, and the 'create in workspace' add button has no keyboard-accessible alternative in the right-click or section menus, so keyboard users lost that action. Restoring opacity keeps the buttons focusable again, at the cost of the workspace name truncating a little earlier to reserve their space.

Addresses the P2 review on PR #1423.
2026-07-06 18:34:06 +08:00
haozhe.yang
98fdb3fc06 docs(write-tests): require behavior/condition/outcome in it() names
- test names must encode behavior, condition, and expected outcome
- use spaces instead of Java-style underscores in it() strings
- add good/bad naming examples
2026-07-06 18:30:32 +08:00
haozhe.yang
34c7d3d1d4 refactor(agent-core-v2): retire wire signal channel in favor of IEventBus
- delete wire/signal.ts and drop signal() from IWireService, WireService, and the WireEmission union (now record-only)
- remove SignalMap augmentations and wire.signal() calls across loop, mcp, goal, plan, task, skill, usage, swarm, fullCompaction and other domains
- re-scope IEventBus to per-agent (Agent scope) and keep IEventService as the global channel, re-exported as GlobalEvent
- route Op-derived facts through IEventBus via op toEvent; keep onEmission for the live append-log record stream
- update server-v2 ws transport (eventMap, sessionEventBroadcaster) and affected tests
2026-07-06 18:30:32 +08:00
haozhe.yang
d2b5e173cf feat(agent-core-v2): add minidb read model for session index
- implement IQueryStore over minidb (lazy open, openOrRebuild, App scope)
- FileSessionIndex serves list/get/countActive from the read model behind the
  persistence_minidb_readmodel flag, backfilling on cold miss to drop the
  per-session state.json re-read (N+1)
- SessionMetadata mirrors updates into the read model for single-process
  freshness; create/fork backfill on first read
- allow sessionIndex>flag in the domain-layer exceptions
- add unit tests plus shared flag/persistence stubs
2026-07-06 18:30:32 +08:00
haozhe.yang
6d1cb3ab23 feat(agent-core-v2): add IEventBus and Op.toEvent alongside wire.signal
Phase 1-2 of the wire/event decoupling plan.

Phase 1 (infra, pure addition): introduce IEventBus (src/app/event/eventBus.ts + eventBusService.ts, App-scope, full + per-type emitters) and an optional Op.toEvent(payload, state) that WireService publishes to IEventBus after apply+persist on dispatch (replay stays silent). Add eventBus.test.ts and store-event.test.ts.

Phase 2 (per-service, dual-channel): every domain now derives/publishes its events to IEventBus - Op-companioned signals via *Ops.toEvent (skill/task/turn/swarm/plan/usage/contextSize/fullCompaction), transient and live-snapshot events via eventBus.publish (turn/goal/loop/toolExecutor/mcp/rpc/externalHooks/profile/session). Each domain adds a DomainEventMap augmentation while keeping its SignalMap.

wire.signal/onEmission are intentionally KEPT in this phase: PLAN.md runs onEmission and EventBus in parallel through Phase 1-2, and server-v2's WS event map forwards only signal emissions (ignoring records), so the consumer cutover and the signal/onEmission deletion are deferred to Phase 3. wire.signal count is unchanged (49); eventBus.publish (34) and toEvent (12) are additive.

Two deviations from the appendix for parity: compaction.cancelled and compaction.completed are manual eventBus.publish (resume must stay quiet, and the complete Op payload strips summary), not toEvent.
2026-07-06 18:30:32 +08:00
haozhe.yang
0ec26c5378 test(agent-core-v2): fix tests after wire/op state engine migration
- migrate imports of removed modules (eventSink, chatProvider, modelRuntime, execContext, completion-budget)
- register IAgentWireService and seed ILogOptions/IAgentBlobService/IHostEnvironment in the test harness
- rewrite toolDedup tests against the hook-driven model; migrate modelRuntime tests to IModelResolver
- drop stale wire-record time assertions; remove dead chatProviderFactory test and modelRuntime stubs
- fix v1.4 to v1.5 migration dropping string-typed turnId (restore Number coercion)
2026-07-06 18:30:32 +08:00