Merge remote-tracking branch 'origin/master' into codex/provider-retry-policy

# Conflicts:
#	docs/architecture.i18n.yaml
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	packages/examples/acp-demo/README.md
#	packages/llm/llm-deepseek/README.md
#	packages/ui/acp/src/index.ts
#	packages/ui/acp/tests/stream-update.spec.ts
This commit is contained in:
Turtle
2026-07-25 13:38:09 +08:00
637 changed files with 13106 additions and 24144 deletions

View File

@@ -139,10 +139,9 @@ export type TurnEndReason = TurnEndReasonMap[keyof TurnEndReasonMap]
*
* Deliberately minimal: a human-readable `content` line and a three-state
* `status`. No id, priority, or `activeForm` — the list is replaced wholesale
* on every write (last-write-wins), so entries need no stable identity, and the
* status triple is exactly the ACP `PlanEntryStatus`, so a UI bridge can map a
* todo list onto an ACP `plan` 1:1 (synthesizing the priority ACP additionally
* requires).
* on every write (last-write-wins), so entries need no stable identity. The
* three statuses describe the complete portable lifecycle needed by model and
* UI consumers.
*/
export interface TodoItem {
/** What this task is — a short imperative line shown in the UI. */

View File

@@ -363,7 +363,7 @@ export function createRunCodeTool(registry: ToolRegistry, requireRuntime: () =>
exec.signal.removeEventListener('abort', onOuterAbort)
}
},
// ACP execute cards use the program as their visible title.
// The program is the call's always-visible UI label.
presentCall: args => ({
card: 'generic',
title: args.code,

View File

@@ -69,7 +69,7 @@ export { defineContentToolFixture, type ContentToolFixtureOptions } from './test
// The render-intent vocabulary a tool declares via `presentCall`/`presentResult`
// lives in its own UI-facing module; re-export it so `@deepseek-ai/dsh-tools`
// stays the single public surface for consumers (producers + the ACP bridge).
// stays the single public surface for tool producers and UI adapters.
export type {
ToolCallKind,
FileLocation,

View File

@@ -8,19 +8,17 @@
import type { ContentBlock } from '@deepseek-ai/dsh-llm'
/**
* Category of a tool call, used by a UI to pick an icon / treatment. A neutral
* vocabulary owned here (NOT an ACP type) so tools describe themselves without
* depending on any client protocol; a UI bridge maps it to its own enum. The
* member set mirrors the common ACP `ToolKind` values; `other` is the default.
* Category of a tool call, used by a UI to pick an icon or treatment. The
* provider-neutral vocabulary lets tools describe themselves without depending
* on a particular client; `other` is the default.
*/
export type ToolCallKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'
/**
* A file location a tool reads or modifies, so a capable UI can "follow along" —
* highlight or jump to the file (and line) as the tool runs. Provider-neutral;
* a UI bridge maps it to its own affordance (the ACP bridge forwards it as
* `tool_call.locations`). `path` is what the tool operated on (the model-facing
* path); `line` is an optional 1-based line to focus (e.g. a read's offset).
* highlight or jump to the file (and line) as the tool runs. `path` is what the
* tool operated on (the model-facing path); `line` is an optional 1-based line
* to focus (e.g. a read's offset).
*/
export interface FileLocation {
path: string
@@ -29,10 +27,9 @@ export interface FileLocation {
/**
* A single-file change a tool is about to make, for a UI that renders inline
* diffs (an editor's diff card). Provider-neutral; the ACP bridge forwards it as
* a `{ type: 'diff' }` tool-call content block. `oldText` is `null` for a
* new-file create (nothing to diff against); an overwrite also uses `null`,
* because a call-time presenter has no access to the file's prior content.
* diffs. `oldText` is `null` for a new-file create (nothing to diff against);
* an overwrite also uses `null`, because a call-time presenter has no access to
* the file's prior content.
*/
export interface FileDiff {
path: string

View File

@@ -696,10 +696,8 @@ describe('the run_code dispatch bridge', () => {
it('presents the program as the execute-card title', async () => {
const { ctx } = await setup({ mode: 'code' })
const tool = ctx.tools.get(RUN_CODE_NAME)!
// The program IS the title, mirroring how command tools title their cards
// with the command: an ACP client's execute-card header is the only
// always-visible slot (Zed renders no body content and no raw input for
// execute-kind cards without a real terminal).
// The program is the title, mirroring how command tools label their cards
// with the command while retaining the same value in the expanded input.
expect(tool.presentCall?.({ code: 'return 1' })).toEqual({
card: 'generic',
title: 'return 1',