dsh-loop-engine-allinone 0.0.0-stage → 0.4.0

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.
Files changed (143) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/CONTRIBUTING.md +78 -0
  3. package/LICENSE +23 -0
  4. package/NOTICE +45 -0
  5. package/README.md +221 -2
  6. package/README.zh.md +89 -0
  7. package/SECURITY.md +39 -0
  8. package/cordis.patch.yml +3 -0
  9. package/lib/client.js +2166 -0
  10. package/lib/index.js +11621 -0
  11. package/lib/invariant.js +453 -0
  12. package/lib/types/agent-preset-ids.d.ts +276 -0
  13. package/lib/types/client/LoopEngineBadge.d.ts +71 -0
  14. package/lib/types/client/LoopEngineComposerSelect.d.ts +126 -0
  15. package/lib/types/client/LoopEngineSection.d.ts +35 -0
  16. package/lib/types/client/engine-marks.d.ts +87 -0
  17. package/lib/types/client/index.d.ts +39 -0
  18. package/lib/types/client/locales.d.ts +182 -0
  19. package/lib/types/client/reload.d.ts +135 -0
  20. package/lib/types/client/session-engine.d.ts +508 -0
  21. package/lib/types/client/store.d.ts +103 -0
  22. package/lib/types/client/turn-status.d.ts +234 -0
  23. package/lib/types/client/use-session-engine.d.ts +74 -0
  24. package/lib/types/commands.d.ts +77 -0
  25. package/lib/types/compat.d.ts +25 -0
  26. package/lib/types/driver-acp/agent.d.ts +289 -0
  27. package/lib/types/driver-acp/approval.d.ts +27 -0
  28. package/lib/types/driver-acp/capabilities.d.ts +200 -0
  29. package/lib/types/driver-acp/client.d.ts +297 -0
  30. package/lib/types/driver-acp/executable.d.ts +53 -0
  31. package/lib/types/driver-acp/mapping.d.ts +76 -0
  32. package/lib/types/driver-acp/profile.d.ts +126 -0
  33. package/lib/types/driver-acp/runtime.d.ts +45 -0
  34. package/lib/types/driver-acp/subprocess.d.ts +19 -0
  35. package/lib/types/driver-acp/terminal.d.ts +98 -0
  36. package/lib/types/driver-acp/transport.d.ts +43 -0
  37. package/lib/types/driver-acp/types.d.ts +152 -0
  38. package/lib/types/driver-cli/capability.d.ts +42 -0
  39. package/lib/types/driver-cli/cli-agent.d.ts +258 -0
  40. package/lib/types/driver-cli/cli-loop.d.ts +46 -0
  41. package/lib/types/driver-cli/flatten.d.ts +35 -0
  42. package/lib/types/driver-cli/frames.d.ts +128 -0
  43. package/lib/types/driver-cli/ndjson.d.ts +106 -0
  44. package/lib/types/driver-cli/session-sink.d.ts +333 -0
  45. package/lib/types/driver-cli/stream-json.d.ts +61 -0
  46. package/lib/types/driver-cli/text.d.ts +66 -0
  47. package/lib/types/driver-cli/transport.d.ts +84 -0
  48. package/lib/types/driver-core/agents-md-skill-provider.d.ts +72 -0
  49. package/lib/types/driver-core/assistant-stream.d.ts +68 -0
  50. package/lib/types/driver-core/context-files.d.ts +62 -0
  51. package/lib/types/driver-core/host-servers.d.ts +119 -0
  52. package/lib/types/driver-core/hosted-engine-runtime.d.ts +190 -0
  53. package/lib/types/driver-core/hosted-tool-vocabulary.d.ts +78 -0
  54. package/lib/types/driver-core/idle-child.d.ts +57 -0
  55. package/lib/types/driver-core/image-access.d.ts +25 -0
  56. package/lib/types/driver-core/inbox.d.ts +104 -0
  57. package/lib/types/driver-core/model-handover.d.ts +134 -0
  58. package/lib/types/driver-core/ownership.d.ts +41 -0
  59. package/lib/types/driver-core/permission-knobs.d.ts +26 -0
  60. package/lib/types/driver-core/prompt.d.ts +64 -0
  61. package/lib/types/driver-core/session-lifetime.d.ts +62 -0
  62. package/lib/types/driver-core/session-model.d.ts +128 -0
  63. package/lib/types/driver-core/skill-inject.d.ts +59 -0
  64. package/lib/types/driver-core/step-close.d.ts +49 -0
  65. package/lib/types/driver-core/step-images.d.ts +62 -0
  66. package/lib/types/driver-core/step-tools.d.ts +43 -0
  67. package/lib/types/driver-core/system-head.d.ts +43 -0
  68. package/lib/types/engine-agy/agent.d.ts +67 -0
  69. package/lib/types/engine-agy/frames.d.ts +90 -0
  70. package/lib/types/engine-agy/loop.d.ts +64 -0
  71. package/lib/types/engine-agy/process.d.ts +173 -0
  72. package/lib/types/engine-claude/agent.d.ts +186 -0
  73. package/lib/types/engine-claude/loop.d.ts +73 -0
  74. package/lib/types/engine-claude/mapping.d.ts +108 -0
  75. package/lib/types/engine-claude/permission.d.ts +41 -0
  76. package/lib/types/engine-claude/process.d.ts +59 -0
  77. package/lib/types/engine-claude/sdk.d.ts +67 -0
  78. package/lib/types/engine-claude/types.d.ts +28 -0
  79. package/lib/types/engine-codex/agent.d.ts +216 -0
  80. package/lib/types/engine-codex/appserver/client.d.ts +80 -0
  81. package/lib/types/engine-codex/appserver/mapping.d.ts +67 -0
  82. package/lib/types/engine-codex/appserver/thread.d.ts +66 -0
  83. package/lib/types/engine-codex/appserver/types.d.ts +225 -0
  84. package/lib/types/engine-codex/loop.d.ts +75 -0
  85. package/lib/types/engine-codex/model-handover.d.ts +56 -0
  86. package/lib/types/engine-codex/permission.d.ts +126 -0
  87. package/lib/types/engine-codex/skills.d.ts +28 -0
  88. package/lib/types/engine-codex/types.d.ts +36 -0
  89. package/lib/types/engine-drivers.d.ts +132 -0
  90. package/lib/types/engine-grok/agent.d.ts +24 -0
  91. package/lib/types/engine-grok/loop.d.ts +61 -0
  92. package/lib/types/engine-grok/process.d.ts +46 -0
  93. package/lib/types/engine-grok/profile.d.ts +82 -0
  94. package/lib/types/engine-hermes/agent.d.ts +47 -0
  95. package/lib/types/engine-hermes/loop.d.ts +56 -0
  96. package/lib/types/engine-hermes/process.d.ts +92 -0
  97. package/lib/types/engine-kimi/acp/client.d.ts +123 -0
  98. package/lib/types/engine-kimi/acp/mapping.d.ts +73 -0
  99. package/lib/types/engine-kimi/acp/types.d.ts +143 -0
  100. package/lib/types/engine-kimi/agent.d.ts +24 -0
  101. package/lib/types/engine-kimi/commands.d.ts +44 -0
  102. package/lib/types/engine-kimi/loop.d.ts +62 -0
  103. package/lib/types/engine-kimi/model-handover.d.ts +32 -0
  104. package/lib/types/engine-kimi/permission.d.ts +28 -0
  105. package/lib/types/engine-kimi/process.d.ts +47 -0
  106. package/lib/types/engine-kimi/profile.d.ts +19 -0
  107. package/lib/types/engine-kimi/skills.d.ts +52 -0
  108. package/lib/types/engine-kimi/types.d.ts +25 -0
  109. package/lib/types/engine-minimaxcode/agent.d.ts +24 -0
  110. package/lib/types/engine-minimaxcode/loop.d.ts +83 -0
  111. package/lib/types/engine-minimaxcode/process.d.ts +53 -0
  112. package/lib/types/engine-minimaxcode/profile.d.ts +72 -0
  113. package/lib/types/engine-of-session.d.ts +97 -0
  114. package/lib/types/engine-pi/agent.d.ts +230 -0
  115. package/lib/types/engine-pi/loop.d.ts +72 -0
  116. package/lib/types/engine-pi/model-handover.d.ts +84 -0
  117. package/lib/types/engine-pi/permission.d.ts +47 -0
  118. package/lib/types/engine-pi/rpc/client.d.ts +107 -0
  119. package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
  120. package/lib/types/engine-pi/rpc/types.d.ts +249 -0
  121. package/lib/types/engine-pi/skills.d.ts +47 -0
  122. package/lib/types/engine-pi/types.d.ts +36 -0
  123. package/lib/types/engine-qoderclicn/agent.d.ts +59 -0
  124. package/lib/types/engine-qoderclicn/loop.d.ts +51 -0
  125. package/lib/types/engine-qoderclicn/process.d.ts +113 -0
  126. package/lib/types/engine-registry.d.ts +584 -0
  127. package/lib/types/engine-remote.d.ts +192 -0
  128. package/lib/types/engine-surface.d.ts +36 -0
  129. package/lib/types/engine-zcode/agent.d.ts +50 -0
  130. package/lib/types/engine-zcode/loop.d.ts +47 -0
  131. package/lib/types/engine-zcode/process.d.ts +111 -0
  132. package/lib/types/index.d.ts +205 -0
  133. package/lib/types/invariant.d.ts +26 -0
  134. package/lib/types/model-selection-reset.d.ts +271 -0
  135. package/lib/types/namespace.d.ts +25 -0
  136. package/lib/types/patch-manager.d.ts +104 -0
  137. package/lib/types/preset.d.ts +254 -0
  138. package/lib/types/provider-route.d.ts +245 -0
  139. package/lib/types/router-loop.d.ts +458 -0
  140. package/lib/types/session-engine-store.d.ts +138 -0
  141. package/lib/types/settings.d.ts +60 -0
  142. package/lib/types/skills.d.ts +85 -0
  143. package/package.json +150 -4
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The plain-text protocol skeleton.
3
+ *
4
+ * The simplest family, and a real one rather than a fallback: an engine invoked
5
+ * as `engine -p "prompt"` prints its finished answer on stdout and exits. There
6
+ * are no frames, no tool events and no usage — just text.
7
+ *
8
+ * Two consequences the driver has to state rather than hide:
9
+ *
10
+ * - **No streaming.** The answer exists only once the child is done (or once
11
+ * stdout stops growing), so `capabilities.streaming` is `false` for such an
12
+ * engine and the settings page/UI must not promise token-by-token output.
13
+ * - **No tool events.** A text engine may run tools internally, but it reports
14
+ * none of them, so nothing lands in the tool rows. That is a faithful
15
+ * transcript, not a gap: the plugin reports what the engine said.
16
+ *
17
+ * Exit status is part of the answer. A non-zero exit with empty stdout is a
18
+ * failed run with the child's own stderr as the message; a non-zero exit WITH
19
+ * output is still reported as a failure, because an engine that dies mid-answer
20
+ * has not answered.
21
+ *
22
+ * @module dsh-loop-engine-allinone/driver-cli/text
23
+ */
24
+ import type { CliTransport } from './transport.ts';
25
+ /** What one text run produced. */
26
+ export interface TextRunResult {
27
+ /** The child's stdout, verbatim. */
28
+ readonly stdout: string;
29
+ /** The child's stderr, truncated to the last {@link STDERR_LIMIT} characters. */
30
+ readonly stderr: string;
31
+ /** Exit code, or null when the child died from a signal. */
32
+ readonly exitCode: number | null;
33
+ }
34
+ /** What one text run needs. */
35
+ export interface TextRunSpec {
36
+ /** The spawned child. */
37
+ readonly transport: CliTransport;
38
+ /**
39
+ * A payload to write to the child's stdin, when the prompt travels that way.
40
+ * Closing stdin is what lets an engine that reads to EOF start working.
41
+ */
42
+ readonly stdin?: string;
43
+ }
44
+ /**
45
+ * Run one plain-text query to completion.
46
+ * @param spec - the run's transport and optional stdin payload.
47
+ * @returns the child's output and exit facts.
48
+ */
49
+ export declare function runText(spec: TextRunSpec): Promise<TextRunResult>;
50
+ /**
51
+ * Turn a finished text run into the answer, or the reason there is none.
52
+ *
53
+ * Kept separate from {@link runText} so the decision is testable without
54
+ * spawning anything: it is where the "did the engine actually answer?"
55
+ * judgement lives.
56
+ * @param result - the finished run.
57
+ * @returns the answer text, or the failure message to report.
58
+ */
59
+ export declare function textRunOutcome(result: TextRunResult): {
60
+ readonly kind: 'answered';
61
+ readonly text: string;
62
+ } | {
63
+ readonly kind: 'failed';
64
+ readonly message: string;
65
+ };
66
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The subprocess transport every CLI driver spawns through.
3
+ *
4
+ * One thin layer over the harness's subprocess seam, for two reasons. First, the
5
+ * seam is where the sandbox lives: a spawned CLI is under the deployment's
6
+ * privilege policy, which is the only boundary available for an engine that has
7
+ * no permission system of its own. Second, every driver needs the same four
8
+ * things from a child — write its stdin, read its stdout as lines, know when it
9
+ * exited, and kill it — and doing that four times is how the drivers drift.
10
+ *
11
+ * The transport deliberately knows nothing about any protocol. It hands back
12
+ * streams; deciding what a line MEANS is the adapter's job
13
+ * (`./ndjson.ts`, `./text.ts`).
14
+ *
15
+ * @module dsh-loop-engine-allinone/driver-cli/transport
16
+ */
17
+ import type { Readable, Writable } from 'node:stream';
18
+ import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess';
19
+ /** What one driver asks the transport to spawn. */
20
+ export interface CliSpawnRequest {
21
+ /** Executable and arguments; `argv[0]` is the program. */
22
+ readonly argv: readonly string[];
23
+ /** Working directory for the child. */
24
+ readonly cwd: string;
25
+ /** Explicit environment entries layered over the scrubbed parent environment. */
26
+ readonly env: Record<string, string>;
27
+ /** Cancellation: the seam escalates process-tree termination when it fires. */
28
+ readonly signal?: AbortSignal;
29
+ }
30
+ /**
31
+ * A spawned CLI child, as a protocol adapter needs it.
32
+ *
33
+ * `stdin` may be absent when the prompt travels in argv instead (`agy --print=…`,
34
+ * `hermes -z …`, `qoderclicn -p …`): an engine that takes its prompt as an
35
+ * argument has no use for a stdin pipe, and asking for one would leave a pipe
36
+ * the child waits on.
37
+ */
38
+ export interface CliTransport {
39
+ /** The child's stdin, or undefined when the spawn did not request a pipe. */
40
+ readonly stdin: Writable | undefined;
41
+ /** The child's stdout, or undefined when the spawn did not request a pipe. */
42
+ readonly stdout: Readable | undefined;
43
+ /** The child's stderr, or undefined when the spawn did not request a pipe. */
44
+ readonly stderr: Readable | undefined;
45
+ /** Resolves when the child closes. */
46
+ readonly done: Promise<unknown>;
47
+ /** Request process-tree termination. */
48
+ terminate(): void;
49
+ }
50
+ /** Spawns one CLI child over the given request (a driver's spawn capability). */
51
+ export type CliSpawnCapability = (request: CliSpawnRequest) => CliTransport;
52
+ /**
53
+ * Build a {@link CliSpawnRequest} from a subprocess spawn spec.
54
+ *
55
+ * The two shapes are structurally the same; this exists so a driver can state
56
+ * its request in its own vocabulary and the projection lives in one place.
57
+ * @param request - the driver's spawn request.
58
+ * @param graceMs - grace period for the provider's termination procedure.
59
+ * @param pipeStdin - whether the child reads its prompt from stdin.
60
+ * @returns the seam's spawn spec.
61
+ */
62
+ export declare function cliSubprocessSpec(request: CliSpawnRequest, graceMs: number, pipeStdin: boolean): SubprocessSpawnSpec;
63
+ /**
64
+ * Project a subprocess handle onto the transport.
65
+ *
66
+ * A missing stream after a successful spawn is a wiring hole rather than a
67
+ * runtime condition — the spec above always asks for the pipes it needs — so it
68
+ * throws rather than degrading to an empty stream that would look like a silent
69
+ * engine.
70
+ * @param handle - the spawned handle.
71
+ * @param engine - the engine name, for the diagnostic.
72
+ * @returns the transport.
73
+ */
74
+ export declare function transportOf(handle: SubprocessHandle, engine: string): CliTransport;
75
+ /**
76
+ * Wrap a spawn capability so a driver never has to remember the grace period or
77
+ * the stdin decision at each call site.
78
+ * @param spawn - the raw seam projection.
79
+ * @param graceMs - grace period for termination.
80
+ * @param pipeStdin - whether this engine reads its prompt from stdin.
81
+ * @returns a capability taking the driver's own request shape.
82
+ */
83
+ export declare function cliSpawner(spawn: (spec: SubprocessSpawnSpec) => SubprocessHandle, graceMs: number, pipeStdin: boolean): CliSpawnCapability;
84
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Data-driven skill provider for the hosted engines whose discovery surface is
3
+ * "per-directory instruction files plus a skills catalog".
4
+ *
5
+ * Codex, Pi, and Kimi Code each expose the same two things through the dsh
6
+ * skill-injection seam: an `agents-md` candidate merging the per-directory
7
+ * instruction files found between the session cwd and the git root, and one
8
+ * candidate per `SKILL.md` catalog entry. Only the *locations*, *names*, and
9
+ * *precedence ranks* differ — never the algorithm — so those are the entire
10
+ * configuration surface here, and each engine module supplies one
11
+ * {@link AgentsMdProviderSpec} and a thin subclass.
12
+ *
13
+ * `.agents/skills` roots are deliberately absent from every engine's spec:
14
+ * dsh's own `skill-filesystem` provider already serves them through the same
15
+ * registry in the web profile.
16
+ *
17
+ * @module dsh-loop-engine-allinone/driver-core/agents-md-skill-provider
18
+ */
19
+ import { type ContextFilePolicy } from './context-files.ts';
20
+ import type { SkillCandidate, SkillDefinition, SkillLookupOptions, SkillProvider, SkillProviderControl } from '../skills.ts';
21
+ /** A skills catalog: a per-ancestor project directory plus one user-level directory. */
22
+ export interface SkillCatalogSpec {
23
+ /** Directory path, relative to each ancestor of the session cwd. */
24
+ readonly project: readonly string[];
25
+ /** Rank of project catalog entries — project instructions beat project skills. */
26
+ readonly projectRank: number;
27
+ /** Directory name under the user install root. */
28
+ readonly userDir: string;
29
+ /** Rank of user catalog entries — project files win duplicate names. */
30
+ readonly userRank: number;
31
+ }
32
+ /** Everything that varies between the codex, pi, and kimi discovery surfaces. */
33
+ export interface AgentsMdProviderSpec {
34
+ /** Provider identity registered against the host skills service. */
35
+ readonly name: string;
36
+ /** Description of the merged `agents-md` candidate. */
37
+ readonly agentsMdDescription: string;
38
+ /** Per-directory instruction files this engine reads, and its override. */
39
+ readonly contextPolicy: ContextFilePolicy;
40
+ /** The engine's user-level install root. */
41
+ readonly userDir: () => string;
42
+ /** Rank of the project `agents-md` candidate. */
43
+ readonly projectRank: number;
44
+ /** User-level instruction file inside {@link userDir}, when the engine reads one. */
45
+ readonly userContext?: {
46
+ readonly file: string;
47
+ readonly rank: number;
48
+ };
49
+ /** Skill catalogs, when the engine has any. */
50
+ readonly skills?: SkillCatalogSpec;
51
+ }
52
+ /**
53
+ * Skill provider that discovers an engine's per-directory instruction files and
54
+ * `SKILL.md` catalogs from the locations its spec names.
55
+ */
56
+ export declare class AgentsMdSkillProvider implements SkillProvider {
57
+ private readonly spec;
58
+ private readonly control;
59
+ readonly name: string;
60
+ constructor(spec: AgentsMdProviderSpec, control: SkillProviderControl);
61
+ list(options: SkillLookupOptions): Promise<readonly SkillCandidate[]>;
62
+ get(candidate: SkillCandidate, _options: SkillLookupOptions): Promise<SkillDefinition | undefined>;
63
+ /** One merged `agents-md` candidate for a ranked file set. */
64
+ private agentsCandidate;
65
+ /** Collect every skill in one skills directory, both nesting layouts. */
66
+ private collectSkillsDir;
67
+ /** One parsed skill as a ranked candidate. */
68
+ private skillCandidate;
69
+ /** Parse one SKILL.md file, or `undefined` when it is unreadable or invalid. */
70
+ private tryParse;
71
+ }
72
+ //# sourceMappingURL=agents-md-skill-provider.d.ts.map
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Live assistant-stream framing for the hosted engines.
3
+ *
4
+ * Harness 0.1.5 made the model stream the durable record of an assistant
5
+ * attempt: `assistant/message` embeds its exact timed stream and may no longer
6
+ * cite `sourceEventSeqs`, and the transient per-chunk log events the plugin
7
+ * used to append (`assistant/chunk`) no longer exist. Live partials now travel
8
+ * through the process-local `agent/assistant-stream` notification instead, and
9
+ * the compact records are handed to the durable message.
10
+ *
11
+ * This is the driver-side equivalent of the loop's `AssistantStreamAttempt`,
12
+ * minus the block assembly: a hosted engine keeps assembling its own
13
+ * authoritative transcript from its own protocol, and this class only frames
14
+ * the attempt and compacts its stream for replay fidelity.
15
+ *
16
+ * @module dsh-loop-engine-allinone/driver-core/assistant-stream
17
+ */
18
+ import type { AssistantStreamFrame } from '@deepseek-ai/dsh-agent';
19
+ import { LlmAttemptId, type AssistantStreamRecord, type StreamChunk } from '@deepseek-ai/dsh-llm';
20
+ import type { SessionId, SessionSeq } from '@deepseek-ai/dsh-session';
21
+ /**
22
+ * One model attempt on a hosted engine: ordered live frames plus the compact
23
+ * stream the durable `assistant/message` carries.
24
+ */
25
+ export declare class DriverAssistantStream {
26
+ private readonly turn;
27
+ private readonly step;
28
+ private readonly emit;
29
+ private accumulator;
30
+ private index;
31
+ private revision;
32
+ private terminal;
33
+ /** Attempt identity unique within this agent lifecycle. */
34
+ readonly attemptId: LlmAttemptId;
35
+ /**
36
+ * @param sessionId - identity embedded only in the agent-lifecycle-local attempt id.
37
+ * @param attempt - agent-local attempt counter.
38
+ * @param turn - durable turn owning the request.
39
+ * @param step - durable step owning the request.
40
+ * @param emit - agent-scoped notification publisher.
41
+ */
42
+ constructor(sessionId: SessionId, attempt: number, turn: number, step: number, emit: (frame: AssistantStreamFrame) => void);
43
+ /** Whether this attempt has already published its terminal frame. */
44
+ get ended(): boolean;
45
+ /** Publish the opening marker before the first delivered chunk. */
46
+ start(): void;
47
+ /** Snapshot one chunk once, then feed durable compaction and live publication. */
48
+ push(chunk: StreamChunk): void;
49
+ /** Exact compact stream for the durable assistant message. */
50
+ get stream(): AssistantStreamRecord[];
51
+ /**
52
+ * Close the current record run and return it, leaving later chunks in a
53
+ * fresh run. An engine whose protocol reports content segments (rather than
54
+ * one stream per message) cuts at each segment boundary, so every durable
55
+ * message embeds exactly the chunks its own content produced even though the
56
+ * live frames keep flowing through one attempt.
57
+ * @returns the compact records accumulated since the previous cut.
58
+ */
59
+ takeStream(): AssistantStreamRecord[];
60
+ /**
61
+ * Publish terminal settlement after the matching durable event commits.
62
+ * @param append - synchronous durable append returning its committed seq.
63
+ */
64
+ settle(append: () => SessionSeq): void;
65
+ /** Publish abandonment when no durable settlement can be committed. */
66
+ abandon(): void;
67
+ }
68
+ //# sourceMappingURL=assistant-stream.d.ts.map
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Context-file collection and body loading shared by the hosted engine
3
+ * drivers.
4
+ *
5
+ * Codex and Pi read per-directory instruction files (`AGENTS.md`; pi also
6
+ * accepts `CLAUDE.md` and prefers `AGENTS.override.md` inside any directory
7
+ * that has one) while walking from the session cwd up to the git root. The
8
+ * skill providers surface each collected set as one merged skill candidate so
9
+ * the dsh skill-injection seam (`/name` gestures) can carry it into the
10
+ * prompt; the body-loading helpers below feed both providers' list/get paths.
11
+ *
12
+ * @module dsh-loop-engine-allinone/driver-core/context-files
13
+ */
14
+ /** Per-directory context-file resolution policy for one engine. */
15
+ export interface ContextFilePolicy {
16
+ /** Per-directory override file that replaces the primary files when present. */
17
+ readonly override?: string;
18
+ /** Per-directory primary files, tried in order until one exists. */
19
+ readonly primary: readonly string[];
20
+ }
21
+ /**
22
+ * The directory chain from `cwd` up to the git root, nearest first. Without a
23
+ * repository the chain is just the resolved `cwd` itself, matching
24
+ * {@link findProjectRoot}'s fallback so the walk stays bounded.
25
+ * @param cwd - the session working directory.
26
+ * @returns the chain of directories to inspect.
27
+ */
28
+ export declare function projectAncestors(cwd: string): Promise<string[]>;
29
+ /**
30
+ * Collect every directory's context file per the policy, from the session cwd
31
+ * up to the git root.
32
+ * @param cwd - the session working directory.
33
+ * @param policy - per-directory resolution policy.
34
+ * @returns existing context files, nearest directory first.
35
+ */
36
+ export declare function collectProjectContextFiles(cwd: string, policy: ContextFilePolicy): Promise<string[]>;
37
+ /**
38
+ * Read one file, or `undefined` when it is unreadable.
39
+ * @param path - the file to read.
40
+ * @returns the file body, or `undefined` on any failure.
41
+ */
42
+ export declare function readOptionalFile(path: string): Promise<string | undefined>;
43
+ /**
44
+ * Whether any of the given sources carries non-whitespace content.
45
+ * @param paths - candidate file paths.
46
+ * @returns whether at least one readable source is non-empty.
47
+ */
48
+ export declare function anySourceNonEmpty(paths: readonly string[]): Promise<boolean>;
49
+ /**
50
+ * Whether one file exists and carries non-whitespace content.
51
+ * @param path - the file to inspect.
52
+ * @returns whether the file is readable and non-empty.
53
+ */
54
+ export declare function fileNonEmpty(path: string): Promise<boolean>;
55
+ /**
56
+ * Concatenate every non-empty readable source body in order, or `undefined`
57
+ * when none are readable.
58
+ * @param paths - candidate file paths, nearest directory first.
59
+ * @returns the joined bodies, or `undefined` when nothing could be read.
60
+ */
61
+ export declare function readSources(paths: readonly string[]): Promise<string | undefined>;
62
+ //# sourceMappingURL=context-files.d.ts.map
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Minimal structural shapes of the optional host registries the plugin
3
+ * extends.
4
+ *
5
+ * Declared locally rather than imported from their packages: the plugin
6
+ * depends on the SERVICE CONTRACTS it consumes only where the harness exposes
7
+ * one (`dsh-agent`, `dsh-session`, …), and the command/skill registries are
8
+ * read through `ctx.get` and may legitimately be absent in a minimal profile.
9
+ * Keeping the shapes here means one definition shared by every consumer and no
10
+ * peer dependency that a headless composition does not need.
11
+ *
12
+ * @module dsh-loop-engine-allinone/driver-core/host-servers
13
+ */
14
+ import type { CommandDefinition } from '../commands.ts';
15
+ import type { SkillProvider, SkillProviderControl } from '../skills.ts';
16
+ import type { SettingsNamespace, SettingsPathOp } from '@deepseek-ai/dsh-settings';
17
+ import type { Session } from '@deepseek-ai/dsh-session';
18
+ import type { HostedEngineRouteAdapter } from '../provider-route.ts';
19
+ /** The host command registry (`ctx.commands`), as this plugin uses it. */
20
+ export interface CommandsService {
21
+ /** Register one definition in the calling context's scope layer. */
22
+ register(def: CommandDefinition): () => void;
23
+ }
24
+ /** The host skill registry (`ctx.skills`), as this plugin uses it. */
25
+ export interface SkillsService {
26
+ /** Register a provider in the calling context's scope layer. */
27
+ registerProvider(create: (control: SkillProviderControl) => SkillProvider): () => void;
28
+ }
29
+ /** The host preset roster (`ctx.agentPresets`), as this plugin uses it. */
30
+ export interface AgentPresetsService {
31
+ /** The effective default preset id. */
32
+ readonly defaultId: string;
33
+ /**
34
+ * The presets this roster serves, when it can enumerate them. Authoring a
35
+ * preset can report success while the roster still serves nothing (each
36
+ * generation reads presets out of a different carrier), so a caller that is
37
+ * about to NAME one of them asks the roster itself rather than the disk.
38
+ */
39
+ list?(): Promise<readonly {
40
+ readonly id: string;
41
+ }[]>;
42
+ /** 0.1.5 line: read one preset's composition text directly. */
43
+ read?(id: string): Promise<string>;
44
+ /** 0.1.7 line: read one preset's document; its `content` is the composition text. */
45
+ readDocument?(id: string): Promise<{
46
+ readonly content: string;
47
+ }>;
48
+ }
49
+ /** The host settings service's mutation seam, as this plugin uses it. */
50
+ export interface SettingsMutator {
51
+ /** Apply ops to one namespace. */
52
+ mutate(ns: SettingsNamespace, ops: readonly SettingsPathOp[]): Promise<void>;
53
+ /** Registered namespaces, when the provider can enumerate them. */
54
+ describe?(): SettingsDescriptorLike[];
55
+ }
56
+ /**
57
+ * One registered settings namespace, as the host describes it
58
+ * (`@deepseek-ai/dsh-settings` `SettingsDescriptor`). Only the two fields this
59
+ * plugin reads are declared.
60
+ */
61
+ export interface SettingsDescriptorLike {
62
+ /** Namespace name. */
63
+ readonly ns: string;
64
+ /**
65
+ * The composition's own value for this namespace, before the user layer. It is
66
+ * what a saved user-layer value overrode, which is why `model-selection-reset.ts`
67
+ * reads it: the deployment's own configured default model is a real model it
68
+ * can name when the saved default does not.
69
+ */
70
+ readonly base?: unknown;
71
+ }
72
+ /** The host llm registry (`ctx.llm`), as this plugin uses it. */
73
+ export interface LlmRegistry {
74
+ /** Register a placeholder adapter for one or more provider labels. */
75
+ registerAdapter(providers: string[], adapter: HostedEngineRouteAdapter): () => void;
76
+ }
77
+ /** The host session-projection registry (`ctx.sessionProjections`), as this plugin uses it. */
78
+ export interface SessionProjectionsService {
79
+ /** Folded projection state of one session, or undefined when it never advanced. */
80
+ stateOf(session: Session, key: 'turnBoundary'): TurnBoundaryFacts | undefined;
81
+ /** The same fold for the durable model selection (`model-selection-reset.ts`). */
82
+ stateOf(session: Session, key: 'modelSelection'): ModelSelectionFacts | undefined;
83
+ }
84
+ /**
85
+ * One complete model selection as the host's `model/selection` event and its
86
+ * projection carry it (`packages/api/session-controller/src/types.ts`,
87
+ * `ModelSelection`).
88
+ */
89
+ export interface SessionModelSelection {
90
+ /** Registered provider route. */
91
+ readonly provider: string;
92
+ /** Provider-owned model id. */
93
+ readonly model: string;
94
+ /** Adapter-owned reasoning effort, or provider/default behavior when absent. */
95
+ readonly reasoningEffort?: string;
96
+ }
97
+ /**
98
+ * The slice of the host's `modelSelection` projection state this plugin reads.
99
+ * `lastUsed` is deliberately not declared: it is that fold's view of the newest
100
+ * `request/header`, which the plugin reads from the session itself
101
+ * (`Session.requestHeader()`) with the same result.
102
+ */
103
+ export interface ModelSelectionFacts {
104
+ /** Later selection not yet consumed by a matching recorded request, or null. */
105
+ readonly pending: SessionModelSelection | null;
106
+ }
107
+ /**
108
+ * The turn-boundary facts this plugin reads. Mirrors `TurnBoundaryProjection`
109
+ * in `@deepseek-ai/dsh-agent` without depending on that module's projection
110
+ * registry augmentation, which a non-plugin consumer has no other reason to
111
+ * pull into its program.
112
+ */
113
+ export interface TurnBoundaryFacts {
114
+ /** Seq of the open turn's `turn/start`, or null between turns. */
115
+ readonly openTurnStartSeq: number | null;
116
+ /** Turn number of the latest `turn/start`; 0 before the first turn. */
117
+ readonly lastTurn: number;
118
+ }
119
+ //# sourceMappingURL=host-servers.d.ts.map
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Shared AgentFactory transaction machinery for the hosted loop engines.
3
+ *
4
+ * Every hosted engine (Claude Code, Codex, Pi, Kimi Code, Antigravity, ZCode, Qoder CN, Hermes, Grok Build, MiniMax Code) implements the harness's
5
+ * AgentFactory contract the same way: prepare a driver, scope, and one memoized
6
+ * reverse teardown for a session; run the caller's setup under a fused abort
7
+ * signal; publish through both registries and announce; and on resume, own a
8
+ * session's write handle across the cold read, crash repair, and
9
+ * re-publication. None of that touches an engine protocol — the whole
10
+ * engine-specific surface is one call, {@link HostedEngineRuntime.buildAgent}.
11
+ *
12
+ * One move has no counterpart in the harness's own factory contract and is what
13
+ * makes an in-place engine swap possible: a LIVE session changes drivers without
14
+ * being released. {@link HostedAgentHandle.retire} stops the outgoing machine
15
+ * while leaving the session entered, and {@link HostedEngineRuntime.swap} builds
16
+ * the incoming engine's machine onto that same Session. The session's store
17
+ * entry and write handle travel across the handover in a
18
+ * {@link SessionLifetime} — the one object that owns them.
19
+ *
20
+ * This body mirrors the default in-process `agent-loop` factory. It is a plain
21
+ * class, not a Cordis plugin: the process-wide AgentFactory slot is owned by
22
+ * the router (`router-loop.ts`, which subclasses the harness `AgentLoop`), and
23
+ * every hosted engine is one runtime instance the router delegates to. That is
24
+ * what lets several engines serve different sessions concurrently — the
25
+ * harness admits exactly one factory, so the factory itself must dispatch.
26
+ *
27
+ * Subclasses supply:
28
+ * - the effect label prefix (`<label>.transactions()`,
29
+ * `<label>.lifecycle(id)`, `<label>.resume-load(id)`) — the lifecycle label
30
+ * is asserted by tests, so it must stay `<label>.lifecycle(...)`;
31
+ * - their own configuration resolution;
32
+ * - {@link HostedEngineRuntime.buildAgent}.
33
+ *
34
+ * @module dsh-loop-engine-allinone/driver-core/hosted-engine-runtime
35
+ */
36
+ import type { Context } from '@deepseek-ai/cordis';
37
+ import type { Agent, AgentFactory, AgentHandle, AgentOptions, AgentSetup, CreateAgentOptions, ResumeAgentOptions } from '@deepseek-ai/dsh-agent';
38
+ import { SessionId } from '@deepseek-ai/dsh-session';
39
+ import type { Session } from '@deepseek-ai/dsh-session';
40
+ import type { Scope } from '@deepseek-ai/dsh-scope';
41
+ import { SessionLifetime } from './session-lifetime.ts';
42
+ /**
43
+ * What the transaction machinery needs of a driver beyond the harness `Agent`
44
+ * contract: a teardown entry point that also unwinds the driver's own scope.
45
+ * The concrete engines declare these; the base only spells them out so the
46
+ * shared body can call them generically.
47
+ */
48
+ export interface HostedAgent extends Agent {
49
+ /** Stop the machine with the given cause, without waiting for it to settle. */
50
+ cancel(cause: Parameters<Agent['cancel']>[0]): void;
51
+ /** Resolves when the machine has no work in flight. */
52
+ whenIdle(): Promise<void>;
53
+ /** The driver's own resource scope, unwound after the machine settles. */
54
+ readonly scope: Scope;
55
+ }
56
+ /**
57
+ * The plugin's own handle for one published hosted agent: the harness contract
58
+ * plus the two facts an in-place engine swap needs.
59
+ *
60
+ * A swap is two moves by two different runtimes: the outgoing engine retires its
61
+ * machine and hands the session over, and the incoming engine builds onto that
62
+ * session. The router is the only caller and it tracks the handle already, so
63
+ * the harness's own `AgentHandle` — which carries neither fact — is widened
64
+ * here rather than reaching back into a transaction that has ended.
65
+ */
66
+ export interface HostedAgentHandle extends AgentHandle {
67
+ /** The live session's lifetime resources, owned by this agent until it is disposed. */
68
+ readonly lifetime: SessionLifetime;
69
+ /**
70
+ * Retire this machine for good while LEAVING the session alive: stop it,
71
+ * unwind its scope, and leave the agent registry — the session's entry and
72
+ * write handle pass to {@link SessionLifetime}'s next owner instead of being
73
+ * released here. Only valid while this agent still owns the session: the
74
+ * router calls it for the session's live, idle agent only.
75
+ */
76
+ retire(): Promise<void>;
77
+ }
78
+ /** Options for {@link HostedEngineRuntime.swap}. */
79
+ export interface SwapAgentOptions {
80
+ /** The live session's lifetime resources, handed over by the outgoing engine. */
81
+ readonly lifetime: SessionLifetime;
82
+ /** Loop options for the successor; the router replays the outgoing agent's own. */
83
+ readonly agentOptions?: AgentOptions | undefined;
84
+ /** The composition callback the session was built with, replayed onto the successor. */
85
+ readonly setup?: AgentSetup | undefined;
86
+ /** The outgoing agent's runtime owner, for a child session's inherited ownership. */
87
+ readonly parentAgent?: Agent | undefined;
88
+ }
89
+ /**
90
+ * Concrete creation/resume machinery for one hosted engine.
91
+ *
92
+ * Creation and resume follow the registry factory contract and the shared
93
+ * publication transaction: prepare, run setup, then publish through both
94
+ * registries and await the serial `agent/created` announcement. {@link swap}
95
+ * follows the same transaction onto a session another agent entered, which is
96
+ * the only difference between taking a session over and owning it from birth.
97
+ */
98
+ export declare abstract class HostedEngineRuntime<TConfig, TAgent extends HostedAgent> implements AgentFactory {
99
+ /** Validated configuration owned by this engine instance. */
100
+ readonly config: TConfig;
101
+ /** Effect-label prefix; also identifies the engine in diagnostics. */
102
+ readonly label: string;
103
+ /** Plain holder prevents Cordis from re-tracing the factory's dependency context through a caller shadow. */
104
+ protected readonly runtime: {
105
+ ctx: Context;
106
+ };
107
+ private readonly ownership;
108
+ /**
109
+ * @param ctx - the owning context; its fiber's unload tears every live agent down.
110
+ * @param label - effect-label prefix, e.g. `agentLoopKimi`.
111
+ * @param config - already-resolved engine configuration.
112
+ */
113
+ constructor(ctx: Context, label: string, config: TConfig);
114
+ /**
115
+ * Construct this engine's driver for one prepared session. Called once per
116
+ * create, resume, or swap, after the session exists and before setup runs; the
117
+ * hook is the engine's entire protocol surface.
118
+ */
119
+ protected abstract buildAgent(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session): TAgent;
120
+ /**
121
+ * Construct the driver, scope, and one memoized reverse teardown for a new
122
+ * agent. The teardown is registered with the factory and the owner fiber
123
+ * BEFORE publication, so a mid-setup unload rolls everything back; `signal`
124
+ * fuses caller cancellation with lifecycle teardown for setup awaits.
125
+ *
126
+ * `lifetime` carries the session's store entry and write handle rather than
127
+ * this body owning them: a fresh transaction binds them when it publishes,
128
+ * while a swap publishes a session whose entry another machine already bound
129
+ * and whose write handle another machine already opened.
130
+ */
131
+ private prepare;
132
+ /** Prepare one Agent around an acquired Session, run setup, and publish it. */
133
+ private setupAndPublish;
134
+ /**
135
+ * Create an agent and session under one caller-supplied identity, owned by
136
+ * the accessing fiber. When a persistence backend is mounted, the session's
137
+ * durable identity is stored before publication.
138
+ * @param ownerCtx - caller context that structurally owns the lifecycle.
139
+ * @param options - identities, optional live parent, session seed/metadata, loop options, setup, and cancellation.
140
+ * @returns the published handle.
141
+ */
142
+ createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<HostedAgentHandle>;
143
+ /**
144
+ * Take a fresh session's write ownership when persistence is mounted.
145
+ * Nothing is appended here: the constructor seed (which never re-emits
146
+ * through `session/event`) is stored by {@link appendUnstoredSuffix} at the
147
+ * publication commit point, so a failed or cancelled setup closes an
148
+ * unmaterialized handle and leaves no stored residue — the same id can be
149
+ * created again.
150
+ * @param session - the unpublished session to store.
151
+ * @param signal - optional cancellation forwarded to the backend create.
152
+ * @returns the owned handle and stored cursor, or `undefined` without a backend.
153
+ */
154
+ private createStoredSession;
155
+ /**
156
+ * Durably store the session events appended since the last stored cursor.
157
+ * Pre-publication appends (constructor seed markers, setup-window events)
158
+ * never re-emit through `session/event`, so publication must flush them
159
+ * through the handle before live events start routing into it.
160
+ * @param stored - the session's owned handle and stored cursor, if any.
161
+ * @param session - the unpublished session whose suffix is stored.
162
+ */
163
+ private appendUnstoredSuffix;
164
+ /**
165
+ * Resume an owned agent from the configured persistence service.
166
+ * @param ownerCtx - caller context that owns load, setup, and the live lifecycle.
167
+ * @param options - persisted identity, optional live parent, loop options, setup, and cancellation.
168
+ * @returns the published handle.
169
+ */
170
+ resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<HostedAgentHandle>;
171
+ /**
172
+ * Build this engine's agent onto a LIVE session another engine's agent left,
173
+ * taking the session's lifetime over.
174
+ *
175
+ * The counterpart of {@link HostedAgentHandle.retire}: together they are an
176
+ * in-place engine swap, and the harness's own factory contract has neither.
177
+ * Nothing is read from persistence and nothing is created in the store — the
178
+ * successor drives the Session object that is already live and already
179
+ * entered, so a browser half attached to that session sees no lifecycle edge
180
+ * at all. The lifetime carries the still-open write handle, so the session
181
+ * keeps being stored through the same channel it was already using.
182
+ * @param ownerCtx - caller context that structurally owns the lifecycle.
183
+ * @param options - the live session's lifetime, loop options, setup, and parent.
184
+ * @returns the published handle, which owns the session from here on.
185
+ */
186
+ swap(ownerCtx: Context, options: SwapAgentOptions): Promise<HostedAgentHandle>;
187
+ /** Resume through an explicit persistence service. */
188
+ private resumeWith;
189
+ }
190
+ //# sourceMappingURL=hosted-engine-runtime.d.ts.map