diff --git a/docs/config-catalog.i18n.yaml b/docs/config-catalog.i18n.yaml index 331fd66a3f..a06cbd8903 100644 --- a/docs/config-catalog.i18n.yaml +++ b/docs/config-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/config-catalog.md -config-catalog.md: aaadee78a5de4a42fc28566215b9fff70a5caca4 -config-catalog.zh.md: 393857b50cb7e750eb90fc6e3a605559a5ce2cad +config-catalog.md: 74834994902bd5fe1e75653ab5645aef5bf587be +config-catalog.zh.md: 77c83f46128a54b1a8f917e82ce3c6750060fcec diff --git a/docs/config-catalog.md b/docs/config-catalog.md index aaadee78a5..7483499490 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -155,7 +155,7 @@ export interface PresetRoot { export type PresetTrust = 'system' | 'user' ``` -Source: [`packages/preset/agent-presets/src/preset.ts:52`](../packages/preset/agent-presets/src/preset.ts) +Source: [`packages/preset/agent-presets/src/preset.ts:54`](../packages/preset/agent-presets/src/preset.ts) diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index 393857b50c..77c83f4612 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -157,7 +157,7 @@ export interface PresetRoot { export type PresetTrust = 'system' | 'user' ``` -来源:[`packages/preset/agent-presets/src/preset.ts:52`](../packages/preset/agent-presets/src/preset.ts) +来源:[`packages/preset/agent-presets/src/preset.ts:54`](../packages/preset/agent-presets/src/preset.ts) diff --git a/docs/event-producer-consumer.i18n.yaml b/docs/event-producer-consumer.i18n.yaml index d217fb3d03..0f42ef8ea1 100644 --- a/docs/event-producer-consumer.i18n.yaml +++ b/docs/event-producer-consumer.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/event-producer-consumer.md -event-producer-consumer.md: 6353c42953fcdd460749bd19197b3bab0b936b66 -event-producer-consumer.zh.md: 9879e6a3141ed078976beede6f1192867ee3d26b +event-producer-consumer.md: ff4a530f6071824da89c88a30a9744695f4d4eef +event-producer-consumer.zh.md: 074597f038b215731e8c005afcd2fed1bc8c4bd4 diff --git a/docs/event-producer-consumer.md b/docs/event-producer-consumer.md index 6353c42953..ff4a530f60 100644 --- a/docs/event-producer-consumer.md +++ b/docs/event-producer-consumer.md @@ -8,7 +8,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac | Event | Mode | Declared in | Dispatchers | Listeners | | --- | --- | --- | --- | --- | | `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:183`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | -| `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:23`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | +| `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:92`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | | `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:166`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:175`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:297`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`session-telemetry`](../packages/session/session-telemetry) | diff --git a/docs/event-producer-consumer.zh.md b/docs/event-producer-consumer.zh.md index 9879e6a314..074597f038 100644 --- a/docs/event-producer-consumer.zh.md +++ b/docs/event-producer-consumer.zh.md @@ -10,7 +10,7 @@ | 事件 | 模式 | 声明位置 | 派发方 | 监听方 | | --- | --- | --- | --- | --- | | `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:183`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - | -| `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:23`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | +| `agent-preset/selected` | `emit` | [`packages/preset/agent-presets/src/types.ts:92`](../packages/preset/agent-presets/src/types.ts) | [`agent-presets`](../packages/preset/agent-presets) (`emit`) | `remotes` | | `agent/created` | `emit` | [`packages/core/agent/src/runtime-types.ts:166`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-presets`](../packages/preset/agent-presets), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`schedule`](../packages/schedule/schedule), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:175`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) | | `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:297`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`session-telemetry`](../packages/session/session-telemetry) | diff --git a/docs/module-graph.i18n.yaml b/docs/module-graph.i18n.yaml index ae3d6422d8..e561402860 100644 --- a/docs/module-graph.i18n.yaml +++ b/docs/module-graph.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/module-graph.md -module-graph.md: e044939e4b48dee60faa03ff955c713e88ddaefa -module-graph.zh.md: d707bd63394b94f511ca40484e23e9e629521515 +module-graph.md: f2c8a499fc54ac90bd9b9a8a7f155ee56ad94dc7 +module-graph.zh.md: ff0d0c72020ed8cd23d6701aaac6e0125174e501 diff --git a/docs/module-graph.md b/docs/module-graph.md index e044939e4b..f2c8a499fc 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -896,6 +896,7 @@ flowchart TD pkg_agent_presets --> pkg_settings pkg_agent_presets --> pkg_system_prompt pkg_agent_presets --> pkg_tools + pkg_agent_presets --> pkg_typert_protocol pkg_schedule --> pkg_agent pkg_schedule --> pkg_brand pkg_schedule --> pkg_invariants @@ -1822,7 +1823,7 @@ flowchart TD | [`tool-jobs`](../packages/jobs/tool-jobs) | `jobs` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | | [`tool-lsp`](../packages/lsp/tool-lsp) | `lsp` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) | | [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`attachment`](../packages/attachment/attachment), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) | -| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | +| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol) | | [`schedule`](../packages/schedule/schedule) | `schedule` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`tools`](../packages/core/tools) | | [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy) | `session` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`tools`](../packages/core/tools) | | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | `session` | [`anonymous-user-id`](../packages/identity/anonymous-user-id), [`command-feedback`](../packages/feedback/command-feedback), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-telemetry`](../packages/session/session-telemetry) | diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index d707bd6339..ff0d0c7202 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -898,6 +898,7 @@ flowchart TD pkg_agent_presets --> pkg_settings pkg_agent_presets --> pkg_system_prompt pkg_agent_presets --> pkg_tools + pkg_agent_presets --> pkg_typert_protocol pkg_schedule --> pkg_agent pkg_schedule --> pkg_brand pkg_schedule --> pkg_invariants @@ -1824,7 +1825,7 @@ flowchart TD | [`tool-jobs`](../packages/jobs/tool-jobs) | `jobs` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | | [`tool-lsp`](../packages/lsp/tool-lsp) | `lsp` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`lsp`](../packages/lsp/lsp), [`system-prompt`](../packages/core/system-prompt), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) | | [`mcp-client`](../packages/mcp/mcp-client) | `mcp` | [`attachment`](../packages/attachment/attachment), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`subprocess`](../packages/subprocess/subprocess), [`timeout`](../packages/util/timeout), [`tools`](../packages/core/tools) | -| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) | +| [`agent-presets`](../packages/preset/agent-presets) | `preset` | [`agent`](../packages/core/agent), [`atomic-write`](../packages/util/atomic-write), [`home-paths`](../packages/util/home-paths), [`invariants`](../packages/runtime-diagnostics/invariants), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`settings`](../packages/settings/settings), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol) | | [`schedule`](../packages/schedule/schedule) | `schedule` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`tools`](../packages/core/tools) | | [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy) | `session` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`tools`](../packages/core/tools) | | [`session-telemetry-otel`](../packages/session/session-telemetry-otel) | `session` | [`anonymous-user-id`](../packages/identity/anonymous-user-id), [`command-feedback`](../packages/feedback/command-feedback), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-telemetry`](../packages/session/session-telemetry) | diff --git a/docs/subsystems/core.i18n.yaml b/docs/subsystems/core.i18n.yaml index 1b16dff02b..f5d61a2ed8 100644 --- a/docs/subsystems/core.i18n.yaml +++ b/docs/subsystems/core.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/subsystems/core.md -core.md: 15135ad1dcacd762fbf31668c13ea0760cd9bc95 -core.zh.md: 7e0270a49f11ef01e6ffb2ca8e1af5831a738198 +core.md: 6490712bc3c90686ba2cbd787a9f21f59b9f9f3d +core.zh.md: 79a2b5d1e9090fe56ea3807d4cf42d0f87c6a48b diff --git a/docs/subsystems/core.md b/docs/subsystems/core.md index 15135ad1dc..6490712bc3 100644 --- a/docs/subsystems/core.md +++ b/docs/subsystems/core.md @@ -400,6 +400,16 @@ Discovery is unmemoized: `list()` and `resolve()` re-read the roots on every cal */ async list(): Promise +/** + * The roster off the Host: {@link list} projected to path-free rows, with + * the default marked and this deployment's authoring capability beside it. + * + * Whether a client can open a preset's directory is the Host's own opener + * capability, not a roster property — a caller needing both joins them. + * @returns the rows and the authoring capability. + */ +@Remote('list') async remoteExportList(): Promise + /** * Resolve one preset by id. * @@ -474,6 +484,15 @@ composedPreset(agentCtx: Context): string | undefined */ async read(id: string): Promise +/** + * One preset's composition text with the roster row it belongs to. + * @param agentPreset - the preset id. + * @returns the composition beside its trust and published metadata. + * @throws {TypertRemoteFailure} `bad-request` for an empty id, or + * `agent-preset-not-found` when no configured root supplies it. + */ +@Remote('read') async readDocument(agentPreset: string): Promise + /** * Create a locally authored preset by copying an existing one whole. * @@ -491,13 +510,34 @@ async read(id: string): Promise */ async copy(from: string, id: string, name?: string): Promise +/** + * Copy one preset through the Remote API. + * @param from - the source preset id. + * @param id - the new preset id. + * @param name - the copy's optional display name. + * @returns once the copy is stored. + * @throws {TypertRemoteFailure} with the corresponding stable preset code + * and details when the copy is refused. + */ +@Remote('copy') async remoteExportCopy(from: string, id: string, name?: string): Promise + /** * Delete a locally authored preset. + * * @param id - the preset id. * @throws when the preset is unknown or ships with the deployment. */ async remove(id: string): Promise +/** + * Delete one preset through the Remote API. + * @param id - the preset id. + * @returns once the preset is deleted. + * @throws {TypertRemoteFailure} with the corresponding stable preset code + * and details when deletion is refused. + */ +@Remote('deletePreset') async remoteExportDelete(id: string): Promise + /** * One agent's instance of a service its preset mounted. * @@ -540,6 +580,16 @@ serviceFor(agent: { ctx: Context }, name: K): */ async recompose(agentCtx: Context, id: string): Promise +/** + * Compose a blank session's agent from a different preset and record it. + * @param agent - the session's live agent, resolved from the wire identity. + * @param agentPreset - the preset to compose the agent from instead. + * @returns the preset id that was recorded. + * @throws {TypertRemoteFailure} with `bad-request`, `agent-preset-locked`, + * `agent-preset-not-found`, or `agent-preset-invalid` when refused. + */ +@Remote('select') async select(agent: Agent, agentPreset: string): Promise + /** * The standing scope key of one preset, for a host reader with no agent. * diff --git a/docs/subsystems/core.zh.md b/docs/subsystems/core.zh.md index 7e0270a49f..79a2b5d1e9 100644 --- a/docs/subsystems/core.zh.md +++ b/docs/subsystems/core.zh.md @@ -410,6 +410,16 @@ Discovery is unmemoized: `list()` and `resolve()` re-read the roots on every cal */ async list(): Promise +/** + * The roster off the Host: {@link list} projected to path-free rows, with + * the default marked and this deployment's authoring capability beside it. + * + * Whether a client can open a preset's directory is the Host's own opener + * capability, not a roster property — a caller needing both joins them. + * @returns the rows and the authoring capability. + */ +@Remote('list') async remoteExportList(): Promise + /** * Resolve one preset by id. * @@ -484,6 +494,15 @@ composedPreset(agentCtx: Context): string | undefined */ async read(id: string): Promise +/** + * One preset's composition text with the roster row it belongs to. + * @param agentPreset - the preset id. + * @returns the composition beside its trust and published metadata. + * @throws {TypertRemoteFailure} `bad-request` for an empty id, or + * `agent-preset-not-found` when no configured root supplies it. + */ +@Remote('read') async readDocument(agentPreset: string): Promise + /** * Create a locally authored preset by copying an existing one whole. * @@ -501,13 +520,34 @@ async read(id: string): Promise */ async copy(from: string, id: string, name?: string): Promise +/** + * Copy one preset through the Remote API. + * @param from - the source preset id. + * @param id - the new preset id. + * @param name - the copy's optional display name. + * @returns once the copy is stored. + * @throws {TypertRemoteFailure} with the corresponding stable preset code + * and details when the copy is refused. + */ +@Remote('copy') async remoteExportCopy(from: string, id: string, name?: string): Promise + /** * Delete a locally authored preset. + * * @param id - the preset id. * @throws when the preset is unknown or ships with the deployment. */ async remove(id: string): Promise +/** + * Delete one preset through the Remote API. + * @param id - the preset id. + * @returns once the preset is deleted. + * @throws {TypertRemoteFailure} with the corresponding stable preset code + * and details when deletion is refused. + */ +@Remote('deletePreset') async remoteExportDelete(id: string): Promise + /** * One agent's instance of a service its preset mounted. * @@ -550,6 +590,16 @@ serviceFor(agent: { ctx: Context }, name: K): */ async recompose(agentCtx: Context, id: string): Promise +/** + * Compose a blank session's agent from a different preset and record it. + * @param agent - the session's live agent, resolved from the wire identity. + * @param agentPreset - the preset to compose the agent from instead. + * @returns the preset id that was recorded. + * @throws {TypertRemoteFailure} with `bad-request`, `agent-preset-locked`, + * `agent-preset-not-found`, or `agent-preset-invalid` when refused. + */ +@Remote('select') async select(agent: Agent, agentPreset: string): Promise + /** * The standing scope key of one preset, for a host reader with no agent. * diff --git a/packages/extensions/tool-cordis/src/api-catalog.ts b/packages/extensions/tool-cordis/src/api-catalog.ts index 3256371016..c18983dfbf 100644 --- a/packages/extensions/tool-cordis/src/api-catalog.ts +++ b/packages/extensions/tool-cordis/src/api-catalog.ts @@ -141,6 +141,12 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ parameters: [], returns: 'the presets, first-root-wins per id.', }, + { + signature: '@Remote(\'list\') async remoteExportList(): Promise', + description: 'The roster off the Host: list projected to path-free rows, with the default marked and this deployment\'s authoring capability beside it.\n\nWhether a client can open a preset\'s directory is the Host\'s own opener capability, not a roster property — a caller needing both joins them.', + parameters: [], + returns: 'the rows and the authoring capability.', + }, { signature: 'async resolve(id?: string): Promise', description: 'Resolve one preset by id.\n\nA broken preset resolves — deleting one, reading one, and reporting one all need the row — and the mounting paths refuse it AFTER resolution through resolveMountable.', @@ -175,18 +181,39 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ returns: 'the composition exactly as stored.', throws: ['when no configured root supplies that id.'], }, + { + signature: '@Remote(\'read\') async readDocument(agentPreset: string): Promise', + description: 'One preset\'s composition text with the roster row it belongs to.', + parameters: [{ name: 'agentPreset', description: 'the preset id.' }], + returns: 'the composition beside its trust and published metadata.', + throws: ['{TypertRemoteFailure} `bad-request` for an empty id, or `agent-preset-not-found` when no configured root supplies it.'], + }, { signature: 'async copy(from: string, id: string, name?: string): Promise', description: 'Create a locally authored preset by copying an existing one whole.\n\nCopy is the only authoring write. Composition text never crosses this seam: the source is named by id and its directory is copied as it stands, so the copy is exactly as loadable as its source and authoring grants no capability the roster did not already carry. The copy is NOT mounted to validate — a source that mounts today yields a copy that mounts today.', parameters: [{ name: 'from', description: 'the preset the copy starts from; shipped presets are the primary source, so any trust is accepted.' }, { name: 'id', description: 'the new preset\'s id, which becomes its directory name.' }, { name: 'name', description: 'display name for the copy; absent falls back to the id.' }], throws: ['when the source is unknown, the id is unusable or already taken, or the deployment configures no writable root.'], }, + { + signature: '@Remote(\'copy\') async remoteExportCopy(from: string, id: string, name?: string): Promise', + description: 'Copy one preset through the Remote API.', + parameters: [{ name: 'from', description: 'the source preset id.' }, { name: 'id', description: 'the new preset id.' }, { name: 'name', description: 'the copy\'s optional display name.' }], + returns: 'once the copy is stored.', + throws: ['{TypertRemoteFailure} with the corresponding stable preset code and details when the copy is refused.'], + }, { signature: 'async remove(id: string): Promise', description: 'Delete a locally authored preset.', parameters: [{ name: 'id', description: 'the preset id.' }], throws: ['when the preset is unknown or ships with the deployment.'], }, + { + signature: '@Remote(\'deletePreset\') async remoteExportDelete(id: string): Promise', + description: 'Delete one preset through the Remote API.', + parameters: [{ name: 'id', description: 'the preset id.' }], + returns: 'once the preset is deleted.', + throws: ['{TypertRemoteFailure} with the corresponding stable preset code and details when deletion is refused.'], + }, { signature: 'serviceFor(agent: { ctx: Context }, name: K): Context[K] | undefined', description: 'One agent\'s instance of a service its preset mounted.\n\nA preset publishes services behind `isolate` realms, which are invisible outside the group that declares them — including to the host. This is how a caller holding the agent reads one anyway: a request that is ABOUT a session but arrives from outside it, which is every browser RPC.\n\nRead addressing only. A host row that `inject`s a service cannot use this, because injection resolves before any session exists and has no agent to key by; such a service belongs on the host plane instead.', @@ -200,6 +227,13 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [ returns: 'the preset now installed.', throws: ['when the preset is unknown or its composition is unusable.'], }, + { + signature: '@Remote(\'select\') async select(agent: Agent, agentPreset: string): Promise', + description: 'Compose a blank session\'s agent from a different preset and record it.', + parameters: [{ name: 'agent', description: 'the session\'s live agent, resolved from the wire identity.' }, { name: 'agentPreset', description: 'the preset to compose the agent from instead.' }], + returns: 'the preset id that was recorded.', + throws: ['{TypertRemoteFailure} with `bad-request`, `agent-preset-locked`, `agent-preset-not-found`, or `agent-preset-invalid` when refused.'], + }, { signature: 'async standingKeyFor(id?: string): Promise', description: 'The standing scope key of one preset, for a host reader with no agent.\n\nA cold transcript read resolves tool presenters against the composition the session recorded, and the standing mount makes that possible without resuming anything: ensuring the mount composes plugins but starts no agent, no session, and no turn.', @@ -3197,6 +3231,18 @@ export const TYPE_API: readonly TypeApiEntry[] = [ name: 'AgentPreset', declaration: 'export interface AgentPreset {\n readonly id: string;\n readonly trust: PresetTrust;\n readonly path: string;\n readonly name?: string;\n readonly description?: string;\n readonly order?: number;\n readonly broken?: string;\n}', }, + { + name: 'AgentPresetDocument', + declaration: 'export interface AgentPresetDocument {\n readonly agentPreset: string;\n readonly trust: PresetTrust;\n readonly content: string;\n readonly name?: string;\n readonly description?: string;\n}', + }, + { + name: 'AgentPresetRoster', + declaration: 'export interface AgentPresetRoster {\n readonly presets: readonly AgentPresetRow[];\n readonly authorable: boolean;\n}', + }, + { + name: 'AgentPresetRow', + declaration: 'export interface AgentPresetRow {\n readonly id: string;\n readonly trust: PresetTrust;\n readonly isDefault: boolean;\n readonly name?: string;\n readonly description?: string;\n readonly broken?: string;\n}', + }, { name: 'AgentSetup', declaration: 'export type AgentSetup = (agentCtx: Context) => AgentSetupCommit | Promise | void;', diff --git a/packages/preset/agent-presets/README.i18n.yaml b/packages/preset/agent-presets/README.i18n.yaml index 6d552c4e43..0fb8f1ea65 100644 --- a/packages/preset/agent-presets/README.i18n.yaml +++ b/packages/preset/agent-presets/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/preset/agent-presets/README.md -README.md: 9dff11bd44a92013852021db5de6b23dfd7e634c -README.zh.md: c63c72b7a1066948eeabb385685306535a03e84d +README.md: e2e002da72069a0ad0edd5cc8e2692784dcbd8bd +README.zh.md: 4f0e11413edaa8f461681d2e1a1e5b23b2421b49 diff --git a/packages/preset/agent-presets/README.md b/packages/preset/agent-presets/README.md index 9dff11bd44..e2e002da72 100644 --- a/packages/preset/agent-presets/README.md +++ b/packages/preset/agent-presets/README.md @@ -110,7 +110,7 @@ This section explains the design behind the roster and the standing mount; obser | [`src/authoring.ts`](src/authoring.ts) | Copy/delete/read of locally authored presets, permission tightening | | [`src/metadata.ts`](src/metadata.ts) | `preset.yml` display metadata | | [`src/session.ts`](src/session.ts) | `agent-preset/selected` event and the `agentPreset` Session projection | -| [`src/types.ts`](src/types.ts) | Client-safe cordis event declaration | +| [`src/types.ts`](src/types.ts) | Client-safe wire payloads and cordis event declaration | | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: post-mount service-leak recheck, unjoined-agent failure | ### The standing mount diff --git a/packages/preset/agent-presets/README.zh.md b/packages/preset/agent-presets/README.zh.md index c63c72b7a1..4f0e11413e 100644 --- a/packages/preset/agent-presets/README.zh.md +++ b/packages/preset/agent-presets/README.zh.md @@ -110,7 +110,7 @@ agent-presets: | [`src/authoring.ts`](src/authoring.ts) | 本地创作 preset 的复制/删除/读取、权限收紧 | | [`src/metadata.ts`](src/metadata.ts) | `preset.yml` 展示元数据 | | [`src/session.ts`](src/session.ts) | `agent-preset/selected` 事件与 `agentPreset` Session 投影 | -| [`src/types.ts`](src/types.ts) | client-safe 的 cordis 事件声明 | +| [`src/types.ts`](src/types.ts) | client-safe 的线上载荷与 cordis 事件声明 | | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件:挂载后的服务泄漏复查、未加入 agent 的失败 | ### 常驻挂载 diff --git a/scripts/gen-cordis-catalog.ts b/scripts/gen-cordis-catalog.ts index 40bda124f7..fc040769e1 100644 --- a/scripts/gen-cordis-catalog.ts +++ b/scripts/gen-cordis-catalog.ts @@ -629,6 +629,8 @@ export const TYPE_LINK_EXEMPTIONS: Readonly> = { InsertTextRequest: 'event-local request contract is owned by packages/client/ui-input-trigger/src/types.ts', AgentHandle: 'agent ownership handle is owned by packages/core/agent/README.md', AgentPreset: 'discovered preset record is owned by packages/preset/agent-presets/README.md', + AgentPresetRoster: 'path-free preset roster is owned by packages/preset/agent-presets/README.md', + AgentPresetDocument: 'preset composition view is owned by packages/preset/agent-presets/README.md', PresetMetadata: 'preset display text is owned by packages/preset/agent-presets/README.md', BashEnvContributor: 'service-local extension type is owned by packages/shell/tool-bash/src/index.ts', BashEnvVariableInfo: 'service-local metadata type is owned by packages/shell/tool-bash/src/index.ts',