dsh-loop-engine 0.1.5-rc2 → 0.1.5-rc4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -177
- package/README.zh.md +48 -100
- package/lib/client.js +887 -266
- package/lib/index.js +2212 -914
- package/lib/invariant.js +43 -45
- package/lib/types/agent-preset-ids.d.ts +303 -0
- package/lib/types/client/LoopEngineBadge.d.ts +44 -17
- package/lib/types/client/LoopEngineComposerSelect.d.ts +79 -13
- package/lib/types/client/LoopEngineSection.d.ts +5 -4
- package/lib/types/client/locales.d.ts +133 -7
- package/lib/types/client/reload.d.ts +135 -0
- package/lib/types/client/session-engine.d.ts +474 -0
- package/lib/types/client/store.d.ts +1 -1
- package/lib/types/client/turn-status.d.ts +112 -10
- package/lib/types/client/use-session-engine.d.ts +66 -0
- package/lib/types/commands.d.ts +11 -3
- package/lib/types/driver-core/host-servers.d.ts +106 -0
- package/lib/types/driver-core/hosted-engine-runtime.d.ts +190 -0
- package/lib/types/driver-core/hosted-tool-vocabulary.d.ts +72 -0
- package/lib/types/driver-core/model-handover.d.ts +116 -0
- package/lib/types/driver-core/ownership.d.ts +6 -5
- package/lib/types/driver-core/prompt.d.ts +32 -0
- package/lib/types/driver-core/session-lifetime.d.ts +62 -0
- package/lib/types/driver-core/session-model.d.ts +82 -0
- package/lib/types/engine-claude/agent.d.ts +23 -3
- package/lib/types/engine-claude/loop.d.ts +16 -15
- package/lib/types/engine-codex/agent.d.ts +22 -3
- package/lib/types/engine-codex/appserver/client.d.ts +15 -2
- package/lib/types/engine-codex/loop.d.ts +13 -15
- package/lib/types/engine-codex/model-handover.d.ts +44 -0
- package/lib/types/engine-kimi/acp/client.d.ts +10 -0
- package/lib/types/engine-kimi/agent.d.ts +19 -2
- package/lib/types/engine-kimi/commands.d.ts +18 -14
- package/lib/types/engine-kimi/loop.d.ts +14 -16
- package/lib/types/engine-kimi/model-handover.d.ts +32 -0
- package/lib/types/engine-kimi/process.d.ts +2 -2
- package/lib/types/engine-kimi/types.d.ts +1 -1
- package/lib/types/engine-of-session.d.ts +97 -0
- package/lib/types/engine-pi/agent.d.ts +25 -23
- package/lib/types/engine-pi/loop.d.ts +13 -23
- package/lib/types/engine-pi/model-handover.d.ts +35 -0
- package/lib/types/engine-pi/types.d.ts +2 -2
- package/lib/types/engine-remote.d.ts +192 -0
- package/lib/types/engine-surface.d.ts +36 -0
- package/lib/types/index.d.ts +51 -50
- package/lib/types/invariant.d.ts +8 -5
- package/lib/types/model-selection-reset.d.ts +271 -0
- package/lib/types/patch-manager.d.ts +57 -39
- package/lib/types/preset.d.ts +39 -26
- package/lib/types/provider-route.d.ts +83 -36
- package/lib/types/router-loop.d.ts +406 -0
- package/lib/types/session-engine-store.d.ts +138 -0
- package/lib/types/settings.d.ts +12 -11
- package/package.json +109 -104
package/lib/types/preset.d.ts
CHANGED
|
@@ -1,48 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hosted-engine agent
|
|
3
|
-
* preset with the dsh-native command and skill rows
|
|
2
|
+
* Hosted-engine agent presets: one managed copy of the deployment's `standard`
|
|
3
|
+
* preset per hosted engine, with the dsh-native command and skill rows
|
|
4
|
+
* stripped.
|
|
4
5
|
*
|
|
5
6
|
* A hosted engine (Claude Code, Codex, Pi, Kimi) owns its session's command
|
|
6
|
-
* and skill surface: the engine's own slash commands and
|
|
7
|
-
*
|
|
8
|
-
* duplicate or mislead — dsh `/plan` is
|
|
9
|
-
* engine never assembles, dsh `/compact`
|
|
10
|
-
* child process holds, and dsh skills
|
|
11
|
-
* catalog. Those rows live inside the
|
|
12
|
-
* profile patch cannot reach, so the plugin
|
|
13
|
-
*
|
|
14
|
-
*
|
|
7
|
+
* and skill surface: the plugin bridges the engine's own slash commands and
|
|
8
|
+
* skill providers into the session (see `engine-surface.ts`), and the
|
|
9
|
+
* dsh-native equivalents would only duplicate or mislead — dsh `/plan` is
|
|
10
|
+
* advisory prompt text an external engine never assembles, dsh `/compact`
|
|
11
|
+
* cannot shrink a context the engine's child process holds, and dsh skills
|
|
12
|
+
* would sit next to the engine's own catalog. Those rows live inside the
|
|
13
|
+
* agent-preset composition, which a profile patch cannot reach, so the plugin
|
|
14
|
+
* authors a stripped preset per engine into the user preset root
|
|
15
|
+
* (`$DSH_HOME/.agent-presets/<id>`).
|
|
15
16
|
*
|
|
16
|
-
* The preset is
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* The preset id is ALSO the per-session engine selector: the harness resolves
|
|
18
|
+
* one preset per session and hands its id to the agent factory at create time
|
|
19
|
+
* (`CreateAgentOptions.meta.agentPreset`), which is the only per-session
|
|
20
|
+
* channel that reaches agent creation. One preset per engine is therefore what
|
|
21
|
+
* makes "session A on Codex, session B on Kimi, concurrently" expressible in a
|
|
22
|
+
* harness that admits exactly one AgentFactory.
|
|
23
|
+
*
|
|
24
|
+
* The presets are REGENERATED from the current `standard` composition on every
|
|
25
|
+
* boot: text on disk is never authoritative, so a harness upgrade that changes
|
|
26
|
+
* `standard` flows through. The file is plain YAML the loader already accepts —
|
|
27
|
+
* the strip is a line transform that preserves everything it does not drop byte
|
|
28
|
+
* for byte, comments included.
|
|
21
29
|
*
|
|
22
30
|
* @module dsh-loop-engine/preset
|
|
23
31
|
*/
|
|
24
|
-
|
|
25
|
-
export
|
|
32
|
+
export { HOSTED_PRESET_PREFIX, SOURCE_PRESET_ID, engineOfPreset, enginePresetId, hostedEngineOf, sessionEngineOf, } from './agent-preset-ids.ts';
|
|
33
|
+
export type { SessionEngine } from './agent-preset-ids.ts';
|
|
26
34
|
/** Harness-home-relative directory of locally authored presets (mirrors `USER_PRESET_DIR` in `dsh-agent-presets`). */
|
|
27
35
|
export declare const USER_PRESET_DIR = ".agent-presets";
|
|
28
36
|
/** The composition file that makes a directory a preset. */
|
|
29
37
|
export declare const COMPOSITION_FILE = "agent.cordis.yml";
|
|
30
38
|
/** The display-metadata file beside a preset's composition. */
|
|
31
39
|
export declare const METADATA_FILE = "preset.yml";
|
|
32
|
-
/**
|
|
33
|
-
export declare const
|
|
40
|
+
/** Every preset id this plugin owns, whether or not it is currently authored. */
|
|
41
|
+
export declare const HOSTED_PRESET_IDS: readonly string[];
|
|
34
42
|
/**
|
|
35
43
|
* Top-level rows stripped from the source preset for hosted engines:
|
|
36
44
|
* - `skill-filesystem` / `tool-skill`: the dsh skill surface — each engine
|
|
37
|
-
* registers its own skill provider
|
|
38
|
-
* - `tool-goal
|
|
39
|
-
*
|
|
45
|
+
* registers its own skill provider in the session's agent scope;
|
|
46
|
+
* - `tool-goal` / `command-goal`: dsh's goal mode. The model-facing tool only
|
|
47
|
+
* works while an in-process loop drives the session, and the human command
|
|
48
|
+
* would sit in the menu with nothing behind it — no hosted engine here
|
|
49
|
+
* implements `/goal`, so there is nothing for it to hand over to. The
|
|
50
|
+
* `command-goal` row lives HERE, in the preset layer, because that is where
|
|
51
|
+
* the human command is registered; disabling the host-plane row from the
|
|
52
|
+
* profile patch does not reach it (`standard` carries its own row);
|
|
40
53
|
* - `planning`: dsh plan mode — its only model-visible effect is a system
|
|
41
54
|
* prompt section an external engine never assembles;
|
|
42
55
|
* - `compaction`: dsh `/compact` and auto-compaction — a hosted engine owns
|
|
43
56
|
* its context and its own `/compact` (Claude, Kimi).
|
|
44
57
|
*/
|
|
45
|
-
export declare const STRIPPED_ROWS: readonly ["skill-filesystem", "tool-skill", "tool-goal", "planning", "compaction"];
|
|
58
|
+
export declare const STRIPPED_ROWS: readonly ["skill-filesystem", "tool-skill", "tool-goal", "command-goal", "planning", "compaction"];
|
|
46
59
|
/**
|
|
47
60
|
* Remove top-level entries by id from a preset composition, preserving every
|
|
48
61
|
* other byte. Each entry owns the comment/blank run directly above its opener
|
|
@@ -61,7 +74,7 @@ export interface PresetCompositionSource {
|
|
|
61
74
|
read(id: string): Promise<string>;
|
|
62
75
|
}
|
|
63
76
|
/**
|
|
64
|
-
* Regenerate
|
|
77
|
+
* Regenerate every hosted engine's preset under the dsh home's user preset root
|
|
65
78
|
* from the roster's `standard` preset. Idempotent: an up-to-date directory is
|
|
66
79
|
* untouched, so no standing mount sees a spurious file-stamp change.
|
|
67
80
|
* @param dshHome - the resolved harness home.
|
|
@@ -69,5 +82,5 @@ export interface PresetCompositionSource {
|
|
|
69
82
|
* @returns whether any file was written.
|
|
70
83
|
* @throws when the source preset cannot be read or the writes fail.
|
|
71
84
|
*/
|
|
72
|
-
export declare function
|
|
85
|
+
export declare function ensureEnginePresets(dshHome: string, source: PresetCompositionSource): Promise<boolean>;
|
|
73
86
|
//# sourceMappingURL=preset.d.ts.map
|
|
@@ -1,56 +1,103 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hosted-engine provider route
|
|
2
|
+
* Hosted-engine provider route placeholder.
|
|
3
3
|
*
|
|
4
|
-
* Every hosted engine logs its sessions' request/header with
|
|
5
|
-
* label (
|
|
4
|
+
* Every hosted engine logs its sessions' request/header with ONE shared provider
|
|
5
|
+
* label ({@link HOSTED_ROUTE_LABEL}, `external`) rather than a model endpoint the
|
|
6
6
|
* harness llm registry serves — the engine owns its model natively. The web
|
|
7
7
|
* host derives a session's model selection from that header and refuses a turn
|
|
8
8
|
* whose provider no registered adapter serves, so without a placeholder route
|
|
9
9
|
* the SECOND prompt of every hosted session fails with `model-unavailable`.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* One label for all four engines, because the browser model catalog is built
|
|
12
|
+
* per Host GENERATION and does not require (or vary by) a Session
|
|
13
|
+
* (`packages/api/session-controller/src/catalog.ts`). A per-engine label would
|
|
14
|
+
* therefore show one provider group per engine in every session's menu at once —
|
|
15
|
+
* four identical `default` entries — so they are collapsed into this one route.
|
|
16
|
+
*
|
|
17
|
+
* Serving the label is only half of it. The model menu renders the session's
|
|
18
|
+
* selection through the catalog, and a provider group that advertises no models
|
|
19
|
+
* is dropped (`packages/api/session-controller/src/catalog.ts`, non-empty
|
|
20
|
+
* groups only) — leaving the seat to show the raw `provider/model` string, i.e.
|
|
21
|
+
* a model that does not exist to any adapter. So the placeholder advertises
|
|
22
|
+
* exactly ONE entry, {@link HOSTED_DEFAULT_MODEL}:
|
|
23
|
+
* `{ provider: HOSTED_ROUTE_LABEL, id: 'default', name: 'default' }`. The id is
|
|
24
|
+
* the same string every engine logs as its model label, which is what makes the
|
|
25
|
+
* seat resolve the session's `(provider, model)` to this entry and render the
|
|
26
|
+
* engine's own word for "whatever it decides" instead of a composite string
|
|
27
|
+
* (see {@link HOSTED_DEFAULT_MODEL} for the host-side mechanism).
|
|
28
|
+
*
|
|
29
|
+
* The entry is not a model this plugin can serve: {@link HostedEngineRouteAdapter.stream}
|
|
30
|
+
* fails loud, because a real model call reaching one of these routes means a
|
|
31
|
+
* session the harness loop drives was handed an engine label — a wiring bug,
|
|
32
|
+
* not a request. Two things keep that from happening: a session switched back
|
|
33
|
+
* to `in-process` has the deployment default written into its log
|
|
34
|
+
* (`model-selection-reset.ts`), and a session BUILT on `in-process` whose
|
|
35
|
+
* selection is one of these labels has it replaced by the same authority before
|
|
36
|
+
* the host installs it (same module, `guardFor`).
|
|
13
37
|
*
|
|
14
38
|
* @module dsh-loop-engine/provider-route
|
|
15
39
|
*/
|
|
16
|
-
import type { GenerateOptions, LlmModelInfo, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
40
|
+
import type { GenerateOptions, LlmModelInfo, LlmProviderInfo, StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
17
41
|
import { LlmAdapter } from '@deepseek-ai/dsh-llm';
|
|
18
|
-
import type {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
import type { HostedEngineId } from './settings.ts';
|
|
43
|
+
/**
|
|
44
|
+
* The provider route label ONE hosted engine logs into its sessions'
|
|
45
|
+
* request/header — always {@link HOSTED_ROUTE_LABEL}.
|
|
46
|
+
*
|
|
47
|
+
* A function rather than a per-engine map because there is now ONE label: the
|
|
48
|
+
* engine an id names no longer changes the route. It is kept as a function so
|
|
49
|
+
* the "an engine logs a route" relationship still reads as such at the call
|
|
50
|
+
* sites that have an engine id in hand (`router-loop.ts` `engineRouteOptions`,
|
|
51
|
+
* `model-selection-reset.ts` `seatOf`).
|
|
52
|
+
* @param _engine - the hosted engine whose route label is asked for.
|
|
53
|
+
* @returns the single route label every hosted engine logs.
|
|
54
|
+
*/
|
|
55
|
+
export declare function hostedRouteLabelOf(_engine: HostedEngineId): string;
|
|
31
56
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
57
|
+
* Whether a provider is one of this plugin's hosted engine route labels — a
|
|
58
|
+
* label some hosted engine logs (now, or in an earlier build), which no adapter
|
|
59
|
+
* serves a real model on.
|
|
60
|
+
*
|
|
61
|
+
* The OLD four per-engine labels are members on purpose, even though only
|
|
62
|
+
* {@link HOSTED_ROUTE_LABEL} is registered. A pre-existing session's header
|
|
63
|
+
* still names one of them; treating only the current label as hosted would let
|
|
64
|
+
* such a session keep the stale selection, and the host — which finds no
|
|
65
|
+
* adapter serving `kimi` any more — would refuse its next turn
|
|
66
|
+
* (`model-unavailable`). Membership here is what lets `model-selection-reset`
|
|
67
|
+
* rewrite the seat to `external/default` (or the deployment default) first.
|
|
68
|
+
* @param provider - the provider of any selection, header, or default.
|
|
69
|
+
* @returns whether that provider is a hosted engine's route label.
|
|
70
|
+
*/
|
|
71
|
+
export declare function isHostedProviderRoute(provider: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Placeholder adapter serving the one hosted engine provider route label.
|
|
74
|
+
*
|
|
75
|
+
* It advertises the single menu entry ({@link HOSTED_DEFAULT_MODEL}) so the
|
|
76
|
+
* model seat can name the session's selection, carries the route's display name
|
|
77
|
+
* ({@link HOSTED_ROUTE_NAME}) so the catalog's provider group is labelled
|
|
78
|
+
* `external`, and {@link stream} fails loud: a call reaching it means a real model
|
|
79
|
+
* query was routed to an engine that owns its model natively — a wiring bug, not
|
|
80
|
+
* a request to serve.
|
|
38
81
|
*/
|
|
39
82
|
export declare class HostedEngineRouteAdapter extends LlmAdapter {
|
|
40
|
-
private readonly label;
|
|
41
|
-
private readonly options;
|
|
42
83
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
84
|
+
* Name the route's one entry.
|
|
85
|
+
*
|
|
86
|
+
* `id` must equal the provider the adapter was registered for (the registry
|
|
87
|
+
* rejects a mismatch — `packages/llm/llm/src/index.ts` `prepareRoutes`), so it
|
|
88
|
+
* is echoed back; `name` is the one localized string the catalog carries.
|
|
89
|
+
* @param provider - the route this adapter is registered for.
|
|
90
|
+
* @returns the route's display metadata.
|
|
45
91
|
*/
|
|
46
|
-
|
|
92
|
+
providerInfo(provider: string): LlmProviderInfo;
|
|
47
93
|
/**
|
|
48
|
-
* Advertise the
|
|
94
|
+
* Advertise the route's single entry.
|
|
49
95
|
*
|
|
50
|
-
* The
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
96
|
+
* The id is the model label the engine logs, so the picker resolves a hosted
|
|
97
|
+
* session's selection to this entry (and highlights its row) rather than
|
|
98
|
+
* falling through to the raw composite string; the name is the same word,
|
|
99
|
+
* rendered as-is.
|
|
100
|
+
* @returns the one entry this route advertises.
|
|
54
101
|
*/
|
|
55
102
|
listModels(_provider: string): Promise<readonly LlmModelInfo[]>;
|
|
56
103
|
stream(_options: GenerateOptions): AsyncIterable<StreamChunk>;
|