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,24 @@
1
+ /**
2
+ * Grok Build's loop Agent: the shared ACP body with the dialect in `./profile.ts`.
3
+ *
4
+ * The class is this engine's published driver shape (and the seam a
5
+ * grok-specific behaviour would land on); the dialect itself — argv, protocol
6
+ * version, model selection, session handshake — lives in `./profile.ts`, which
7
+ * imports no host service so it can be exercised by `scripts/probe/smoke-acp.ts`
8
+ * against the real CLI.
9
+ *
10
+ * @module dsh-loop-engine-allinone/engine-grok/agent
11
+ */
12
+ import type { AgentOptions } from '@deepseek-ai/dsh-agent';
13
+ import type { Session, SessionId } from '@deepseek-ai/dsh-session';
14
+ import type { Context } from '@deepseek-ai/cordis';
15
+ import type { AcpResolvedConfig } from '../driver-acp/profile.ts';
16
+ import type { AcpSpawnCapability } from '../driver-acp/transport.ts';
17
+ import { AcpEngineAgent } from '../driver-acp/agent.ts';
18
+ import { grokProfile } from './profile.ts';
19
+ export { grokProfile };
20
+ /** Grok Build's loop Agent: the shared ACP body with the profile's dialect. */
21
+ export declare class GrokAgent extends AcpEngineAgent {
22
+ constructor(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session, config: AcpResolvedConfig, spawn: AcpSpawnCapability, bin?: string);
23
+ }
24
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Grok Build loop engine module: drives every session it is handed through a
3
+ * persistent `grok agent stdio` child (Agent Client Protocol over stdio), speaking
4
+ * one stateless `session/new` + `session/prompt` per dsh step, with the durable
5
+ * session log as the sole source of model context. The router routes a session
6
+ * here on the plugin's own engine record, else its agent preset; this module is a
7
+ * library, not a Cordis plugin entry.
8
+ *
9
+ * Everything below the dialect is the shared ACP runtime
10
+ * (`driver-acp/runtime.ts`); grok contributes its argv, its protocol version (from
11
+ * the registry row) and the `authenticate`-then-`session/new` handshake its own
12
+ * ACP server requires.
13
+ *
14
+ * @module dsh-loop-engine-allinone/engine-grok
15
+ */
16
+ import type { Context } from '@deepseek-ai/cordis';
17
+ import z from '@deepseek-ai/schemastery';
18
+ import type { AgentOptions } from '@deepseek-ai/dsh-agent';
19
+ import type { Session, SessionId } from '@deepseek-ai/dsh-session';
20
+ import { AcpEngineRuntime } from '../driver-acp/runtime.ts';
21
+ import { GrokAgent } from './agent.ts';
22
+ import type { AcpResolvedConfig } from '../driver-acp/profile.ts';
23
+ /** Deployment-owned configuration for the Grok Build engine. */
24
+ export interface Config {
25
+ /** Model sent per ACP session (`session/set_config_option`) when the session selects none. */
26
+ model?: string;
27
+ /**
28
+ * Explicit environment entries passed to the child.
29
+ *
30
+ * Usually empty on purpose: Grok reads its own `~/.grok/auth.json` (or
31
+ * `XAI_API_KEY`) from the INHERITED environment, and `GROK_HOME` is how a
32
+ * deployment points it at a second profile.
33
+ */
34
+ env?: Record<string, string>;
35
+ /** The `grok` executable (or its npm shim); the vendor install location, then PATH, when not pinned. */
36
+ bin?: string;
37
+ /** Idle window in milliseconds before a session's ACP child is shut down; zero or less keeps it. */
38
+ childIdleMs?: number;
39
+ }
40
+ /** Schema of the Grok Build engine configuration. */
41
+ export declare const Config: z<Config>;
42
+ /** Resolve the driver configuration at the plugin config boundary. */
43
+ export declare function resolveConfig(config: Config): AcpResolvedConfig;
44
+ /** Host-face ctx key this engine's runtime is registered under. */
45
+ export declare const GROK_ENGINE_LABEL = "agentLoopGrok";
46
+ declare module '@deepseek-ai/cordis' {
47
+ interface Context {
48
+ agentLoopGrok: GrokLoop;
49
+ }
50
+ }
51
+ /**
52
+ * Creation/resume machinery for the Grok Build engine. The process-wide
53
+ * AgentFactory slot belongs to the router, which delegates each session to the
54
+ * engine its preset names; this class is that engine's driver, not a plugin.
55
+ */
56
+ export declare class GrokLoop extends AcpEngineRuntime<GrokAgent> {
57
+ constructor(ctx: Context, config: Config);
58
+ /** Construct the Grok ACP driver for one prepared session. */
59
+ protected buildAgent(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session): GrokAgent;
60
+ }
61
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Grok Build process projection: where the `grok` executable is, and the argv that
3
+ * starts its ACP server.
4
+ *
5
+ * Measured and documented facts this file encodes (see
6
+ * Grok's shipped user guide, and the frames `scripts/probe/acp-handshake.mjs` dumps):
7
+ *
8
+ * - the ACP server is `grok agent [options] stdio` — agent options go AFTER
9
+ * `agent` and BEFORE the mode name, so `grok agent stdio` is the bare form;
10
+ * - the released binary installs to `<GROK_HOME>/bin/grok[.exe]`
11
+ * (`x.ai/cli/install.sh`, `GROK_HOME` defaulting to `~/.grok`), while the npm
12
+ * package `@xai-official/grok` installs a `grok.cmd` shim that launches its
13
+ * own JS bootstrap;
14
+ * - the CLI has no `.exe` on PATH after an npm install, so the shim case is
15
+ * handled through the shared executable helper rather than by spawning the
16
+ * bare name.
17
+ *
18
+ * @module dsh-loop-engine-allinone/engine-grok/process
19
+ */
20
+ /** Grace in milliseconds for Grok process-tree termination. */
21
+ export declare const GROK_DISPOSE_GRACE_MS = 3000;
22
+ /** Resolve the Grok home directory from `GROK_HOME` or the current user's home. */
23
+ export declare function grokHomeDir(): string;
24
+ /**
25
+ * Resolve the `grok` executable.
26
+ *
27
+ * An explicit config path wins. Otherwise the released-binary location is probed
28
+ * first (it is a real executable and the vendor's own install target), then PATH —
29
+ * where an npm install leaves a `.cmd` shim that {@link grokAcpArgv} knows how to
30
+ * launch.
31
+ * @param configBin - an operator-pinned path (or a bare name), if any.
32
+ * @returns the executable to spawn as `argv[0]`.
33
+ */
34
+ export declare function grokBinResolver(configBin?: string): string;
35
+ /**
36
+ * Build the argv that starts `grok agent stdio` (the ACP server over stdio).
37
+ *
38
+ * `--always-approve` is deliberately NOT here: it is a per-SESSION decision, and
39
+ * the engine expresses that per session through `session/new`'s `_meta.yoloMode`
40
+ * (see `./agent.ts`), which keeps this argv stable for every session the child
41
+ * serves and leaves the approval fold in one place.
42
+ * @param bin - the Grok executable (or its npm shim).
43
+ * @returns the argv, ending in the `stdio` mode name.
44
+ */
45
+ export declare function grokAcpArgv(bin: string): string[];
46
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Grok Build's ACP dialect: the shared ACP body with grok's own handshake.
3
+ *
4
+ * Three measured facts shape this profile, all of them from real frames dumped by
5
+ * `scripts/probe/acp-handshake.mjs` against the released `grok` 1.0.59 binary:
6
+ *
7
+ * 1. `initialize` answers `protocolVersion: 1`, advertises ONE auth method
8
+ * (`id: grok.com`, name `Grok`) and reports
9
+ * `promptCapabilities.image: false` — so this engine never receives image
10
+ * blocks from the driver;
11
+ * 2. `session/new` REFUSES an unauthenticated client with
12
+ * `-32000 Authentication required / "no auth method id provided"`, which is
13
+ * ACP's own flow: the client answers `authenticate` with the advertised
14
+ * method id, then opens the session. Grok on a signed-in host is expected to
15
+ * accept `authenticate` immediately (its cached credentials live in
16
+ * `~/.grok/auth.json`); on an unsigned host that call is what starts the
17
+ * vendor's sign-in, and a failure after it is reported with the registry's
18
+ * own login hint so the user is told what to run instead of reading a raw
19
+ * JSON-RPC error;
20
+ * 3. the model is selected through `session/set_config_option` (Grok's user
21
+ * guide documents the `{ value }` wrapper). MiniMax Code rejects that wrapper
22
+ * and takes the bare value, so the driver tries the documented spelling and
23
+ * falls back to the bare one, recording which the engine accepted — the
24
+ * dialect difference is real and guessing it would break a working engine.
25
+ *
26
+ * `session/new` also carries `_meta.yoloMode` when the session's dsh approval
27
+ * knobs auto-approve, which maps the dsh policy onto Grok's own always-approve
28
+ * switch. When they do not, the driver leaves it off and answers the reverse-RPC
29
+ * `session/request_permission` itself (denying under an `ask` policy, since the
30
+ * unattended runtime has no human to ask).
31
+ *
32
+ * @module dsh-loop-engine-allinone/engine-grok/profile
33
+ */
34
+ import type { AcpClient } from '../driver-acp/client.ts';
35
+ import type { AcpEngineProfile } from '../driver-acp/profile.ts';
36
+ /** Grok's model config option id, as its user guide documents it. */
37
+ export declare const GROK_MODEL_CONFIG_ID = "model";
38
+ /** The registry's login instruction, used when the engine reports it needs auth. */
39
+ export declare function grokLoginHint(): string;
40
+ /**
41
+ * Whether an error from `session/new` is ACP's "this client is not authenticated
42
+ * yet" refusal.
43
+ *
44
+ * Matched on the message because that is what the shared client surfaces from an
45
+ * error frame (`settle()` keeps `error.message`); measured text on 1.0.59 is
46
+ * exactly `Authentication required`.
47
+ * @param error - the rejection from `session/new`.
48
+ * @returns whether the agent refused for want of authentication.
49
+ */
50
+ export declare function isAuthenticationRequired(error: unknown): boolean;
51
+ /**
52
+ * The first auth method id an `initialize` result advertises.
53
+ *
54
+ * The driver takes the FIRST method rather than choosing among several: ACP
55
+ * publishes them in the agent's own preference order, and a client that ranks them
56
+ * itself would be inventing a policy the engine already stated.
57
+ * @param initializeResult - the raw `initialize` result.
58
+ * @returns the method id, or undefined when the agent advertised none.
59
+ */
60
+ export declare function firstAuthMethodId(initializeResult: unknown): string | undefined;
61
+ /**
62
+ * Select Grok's model through `session/set_config_option`, with the BARE value.
63
+ *
64
+ * MEASURED after signing in (this supersedes the earlier guess): Grok accepts
65
+ * `value: 'grok-4.7'` and REJECTS the `{ value }` wrapper its own documentation
66
+ * shows, with `-32602 "data did not match any variant of untagged enum
67
+ * SessionConfigOptionValue"`. So there is no fallback to try: the wrapper is
68
+ * simply wrong for this engine, and both ACP engines that speak
69
+ * `set_config_option` (this one and MiniMax Code) take the bare form.
70
+ *
71
+ * A model id the engine does not know is refused with `-32602 "unknown model
72
+ * id"`, which is the honest loud failure: the registry's `models` list is a
73
+ * declaration, and a stale entry must surface at the engine rather than be
74
+ * silently replaced by its default.
75
+ * @param client - the connected ACP client.
76
+ * @param sessionId - the ACP session.
77
+ * @param model - the model id to select.
78
+ */
79
+ export declare function selectGrokModel(client: AcpClient, sessionId: string, model: string): Promise<void>;
80
+ /** Grok Build's ACP dialect, as the shared driver reads it. */
81
+ export declare function grokProfile(bin: string): AcpEngineProfile;
82
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Hermes Agent: one `hermes -z "prompt"` child per dsh step, with the durable
3
+ * session log as the sole source of model context.
4
+ *
5
+ * Hermes is the plugin's plain-text engine. It prints a finished answer and
6
+ * exits, with no frames, no tool events and no usage — so the driver's whole job
7
+ * is: serialize the transcript, spawn, read stdout to completion, and commit it
8
+ * as one assistant message through the shared sink.
9
+ *
10
+ * The consequences are declared rather than papered over
11
+ * (`EngineCapabilities`): `streaming: false` means the UI must not promise
12
+ * token-by-token output, and the absence of tool events means a tool Hermes ran
13
+ * internally appears nowhere in the transcript. That is a faithful record of
14
+ * what the engine reported.
15
+ *
16
+ * @module dsh-loop-engine-allinone/engine-hermes/agent
17
+ */
18
+ import type { AgentOptions } from '@deepseek-ai/dsh-agent';
19
+ import type { Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session';
20
+ import type { Context } from '@deepseek-ai/cordis';
21
+ import type { HostedEngineId } from '../engine-registry.ts';
22
+ import { CliHostedAgent } from '../driver-cli/cli-agent.ts';
23
+ import type { SinkPosition } from '../driver-cli/session-sink.ts';
24
+ import type { CliSpawnCapability } from '../driver-cli/transport.ts';
25
+ /** Deployment-resolved configuration for the Hermes engine. */
26
+ export interface ResolvedHermesConfig {
27
+ /** Pinned executable, when the deployment named one. */
28
+ readonly bin: string | undefined;
29
+ /** Explicit environment entries layered over the scrubbed parent environment. */
30
+ readonly env: Record<string, string>;
31
+ /** Pinned model. */
32
+ readonly model: string | undefined;
33
+ /** Pinned reasoning level. */
34
+ readonly reasoning: string | undefined;
35
+ }
36
+ /** The engine id this driver registers under. */
37
+ export declare const HERMES_ENGINE: HostedEngineId;
38
+ /** Drives one session through turn and step boundaries on Hermes Agent. */
39
+ export declare class HermesAgent extends CliHostedAgent {
40
+ private readonly config;
41
+ private readonly spawn;
42
+ constructor(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session, config: ResolvedHermesConfig, spawn: CliSpawnCapability);
43
+ protected runStep(messages: readonly UserMessage[], position: SinkPosition, signal: AbortSignal): Promise<{
44
+ kind: 'completed';
45
+ } | null>;
46
+ }
47
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Hermes Agent loop engine module: drives every session it is handed through one
3
+ * `hermes -z "prompt"` child per dsh step, with the durable session log as the
4
+ * sole source of model context. The router routes a session here on the plugin's
5
+ * own engine record, else its agent preset; this module is a library, not a
6
+ * Cordis plugin entry.
7
+ *
8
+ * Hermes has no permission-mode switch this driver maps, so the effective
9
+ * boundary is the dsh subprocess sandbox the whole child is spawned under
10
+ * (default read-only).
11
+ *
12
+ * @module dsh-loop-engine-allinone/engine-hermes
13
+ */
14
+ import type { Context } from '@deepseek-ai/cordis';
15
+ import z from '@deepseek-ai/schemastery';
16
+ import type { AgentOptions } from '@deepseek-ai/dsh-agent';
17
+ import type { Session, SessionId } from '@deepseek-ai/dsh-session';
18
+ import { CliEngineRuntime } from '../driver-cli/cli-loop.ts';
19
+ import { HermesAgent, type ResolvedHermesConfig } from './agent.ts';
20
+ /** Deployment-owned configuration for the Hermes Agent engine. */
21
+ export interface Config {
22
+ /** Model for the CLI (`-m`); Hermes' own configuration owns the model when omitted. */
23
+ model?: string;
24
+ /**
25
+ * Explicit environment entries passed to the child.
26
+ *
27
+ * Usually empty on purpose: Hermes reads its own `HERMES_HOME` and `auth.json`
28
+ * from the INHERITED environment. Setting `HERMES_HOME` here is how a
29
+ * deployment points the plugin at a second Hermes profile.
30
+ */
31
+ env?: Record<string, string>;
32
+ /** The `hermes` executable; PATH (and the CLI's own venv location) when not pinned. */
33
+ bin?: string;
34
+ /** Reasoning level (`--reasoning`). */
35
+ reasoning?: string;
36
+ }
37
+ /** Schema of the Hermes Agent engine configuration. */
38
+ export declare const Config: z<Config>;
39
+ /** Host-face ctx key this engine's runtime is registered under. */
40
+ export declare const HERMES_ENGINE_LABEL = "agentLoopHermes";
41
+ declare module '@deepseek-ai/cordis' {
42
+ interface Context {
43
+ agentLoopHermes: HermesLoop;
44
+ }
45
+ }
46
+ /**
47
+ * Creation/resume machinery for the Hermes Agent engine. The process-wide
48
+ * AgentFactory slot belongs to the router, which delegates each session to the
49
+ * engine its preset names; this class is that engine's driver, not a plugin.
50
+ */
51
+ export declare class HermesLoop extends CliEngineRuntime<ResolvedHermesConfig, HermesAgent> {
52
+ constructor(ctx: Context, config: Config);
53
+ /** Construct the Hermes driver for one prepared session. */
54
+ protected buildAgent(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session): HermesAgent;
55
+ }
56
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Hermes Agent CLI process projection.
3
+ *
4
+ * Hermes is a Python CLI whose non-interactive surface is a single flag:
5
+ * `hermes -z "prompt"` runs one prompt and prints the answer. There is no
6
+ * structured output mode to speak of — the probe recorded in
7
+ * `docs/probes/hermes.md` found plain text on stdout and nothing else — so this
8
+ * driver reads the whole of stdout as one reply (`src/driver-cli/text.ts`).
9
+ *
10
+ * ## The environment, which is the interesting part
11
+ *
12
+ * Hermes keeps ALL of its state under `HERMES_HOME` (this machine: a directory
13
+ * outside the user profile holding 147 sessions, 105 skills and `auth.json`).
14
+ * The plugin never reads, writes or forwards that path — the child inherits it
15
+ * from the ambient environment like any other variable, because the dsh
16
+ * subprocess seam's scrub only removes `DSH_*` facts and names matching
17
+ * `KEY|PASSWORD|SECRET|TOKEN`, and `HERMES_HOME` matches neither.
18
+ *
19
+ * That inheritance is a FEATURE and not an accident worth leaving untested: if
20
+ * the plugin ever blanket-replaced the child environment, every Hermes session
21
+ * would silently start against an empty `HERMES_HOME` — a fresh install with no
22
+ * login — and the failure would look like "the model is broken" rather than
23
+ * "the plugin dropped an environment variable". `tests/engine-hermes/process.spec.ts`
24
+ * pins it.
25
+ *
26
+ * @module dsh-loop-engine-allinone/engine-hermes/process
27
+ */
28
+ import type { CliSpawnRequest } from '../driver-cli/transport.ts';
29
+ /** Grace in milliseconds for Hermes process-tree termination. */
30
+ export declare const HERMES_DISPOSE_GRACE_MS = 3000;
31
+ /** The flag that runs one prompt non-interactively. */
32
+ export declare const HERMES_PROMPT_FLAG = "-z";
33
+ /** The environment variable holding Hermes' entire state directory. */
34
+ export declare const HERMES_HOME_ENV = "HERMES_HOME";
35
+ /**
36
+ * Resolve the `hermes` executable.
37
+ *
38
+ * An explicit config path wins; then the well-known venv location; then PATH.
39
+ * The venv probe exists because that is where Hermes' own installer puts the
40
+ * CLI, and a profile started from a desktop shortcut does not always see the
41
+ * PATH entry pointing at it.
42
+ * @param configBin - an operator-pinned path, if any.
43
+ * @returns the executable to spawn as `argv[0]`.
44
+ */
45
+ export declare function hermesBinResolver(configBin?: string): string;
46
+ /**
47
+ * Whether a PATH entry looks like it could hold a `hermes` executable.
48
+ *
49
+ * Exported because the diagnostic surface (the settings page's engine check)
50
+ * wants to report "found on PATH" without spawning anything.
51
+ * @param pathEnv - the PATH value to inspect.
52
+ * @returns whether any entry names an existing `hermes` file.
53
+ */
54
+ export declare function hermesOnPath(pathEnv: string | undefined): boolean;
55
+ /** Everything one step's Hermes child needs. */
56
+ export interface HermesSpawnSpec {
57
+ /** The resolved executable (`argv[0]`). */
58
+ readonly bin: string;
59
+ /** The prompt, passed as an argv argument. */
60
+ readonly prompt: string;
61
+ /** The session's working directory. */
62
+ readonly cwd: string;
63
+ /**
64
+ * Explicit environment entries layered over the scrubbed parent environment.
65
+ *
66
+ * Deliberately usually EMPTY: Hermes needs no forwarded credential, because
67
+ * it reads its own `HERMES_HOME` (inherited) and its own `auth.json`. A
68
+ * deployment may still add entries here, and one that sets `HERMES_HOME`
69
+ * explicitly overrides the inherited value — which is how a user points the
70
+ * plugin at a second Hermes profile.
71
+ */
72
+ readonly env: Record<string, string>;
73
+ /** Pinned model, when the deployment or the session named one. */
74
+ readonly model: string | undefined;
75
+ /** Pinned reasoning level, when the deployment named one. */
76
+ readonly reasoning: string | undefined;
77
+ /** Cancellation. */
78
+ readonly signal: AbortSignal;
79
+ }
80
+ /**
81
+ * Build the argv for one non-interactive Hermes step.
82
+ * @param spec - the step's spawn spec.
83
+ * @returns the argv.
84
+ */
85
+ export declare function hermesArgv(spec: HermesSpawnSpec): string[];
86
+ /**
87
+ * Project one step's spawn spec onto the transport request.
88
+ * @param spec - the step's spawn spec.
89
+ * @returns the transport's request shape.
90
+ */
91
+ export declare function hermesSpawnRequest(spec: HermesSpawnSpec): CliSpawnRequest;
92
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1,123 @@
1
+ /**
2
+ * JSON-RPC client for the `kimi acp` subprocess (Agent Client Protocol over
3
+ * stdio).
4
+ *
5
+ * The driver hands the client a process handle carrying its stdin/stdout/stderr
6
+ * (projected from the dsh subprocess seam). The client frames JSON-RPC 2.0
7
+ * records on a bare `\n` (via a byte decoder, tolerating a trailing `\r`),
8
+ * correlates request responses by `id`, dispatches every `session/update`
9
+ * notification to a buffered event stream, and answers the reverse-RPC
10
+ * `session/request_permission` requests the agent publishes. The child is
11
+ * long-lived (one per factory) and stepped over via `newSession` + `prompt`.
12
+ *
13
+ * @module dsh-loop-engine/engine-kimi/acp/client
14
+ */
15
+ import type { KimiProcess, KimiSpawnCapability, KimiSpawnSpec } from '../process.ts';
16
+ import { type AcpFrame, type AcpImageContent, type AcpPermissionOption, type AcpPermissionResponse, type AcpUpdate } from './types.ts';
17
+ /** How the client answers one `session/request_permission`. */
18
+ export type AcpPermissionHandler = (request: AcpFrame) => boolean | Promise<boolean>;
19
+ /**
20
+ * The answerable options of one `session/request_permission` frame. The wire is
21
+ * untrusted, so entries without a usable `optionId` are dropped rather than
22
+ * echoed back.
23
+ * @param frame - the reverse-RPC request frame.
24
+ * @returns the options the client may answer with.
25
+ */
26
+ export declare function permissionOptionsOf(frame: AcpFrame): readonly AcpPermissionOption[];
27
+ /**
28
+ * Encode one approval decision as the ACP `RequestPermissionResponse` the agent
29
+ * correlates against the options it advertised. The agent reads a terminal
30
+ * *option*, never a boolean: an outcome it cannot resolve (or a response that
31
+ * fails to parse at all) is reported to the model as a user rejection, so a
32
+ * decision that no single option expresses becomes `cancelled` — the honest
33
+ * "this client has no answer". Kimi re-uses this RPC for its question and
34
+ * plan-review bridges, which offer one `allow_once` option per choice; picking
35
+ * one of those would answer a question no human was asked, so any ambiguous
36
+ * set (zero or several `allow_once`/`reject_once` candidates) cancels instead.
37
+ * `allow_once` is preferred over `allow_always` because the decision is re-read
38
+ * from the session knobs on every request: letting the agent cache a session
39
+ * grant would outlive a mid-session switch back to `ask`.
40
+ * @param approved - whether the driver approves the request.
41
+ * @param options - the options the agent advertised for this request.
42
+ * @returns the result payload to send back.
43
+ */
44
+ export declare function permissionResponse(approved: boolean, options: readonly AcpPermissionOption[]): AcpPermissionResponse;
45
+ /** Callback receiving every non-response event line. */
46
+ export type AcpUpdateHandler = (update: AcpUpdate) => void;
47
+ /**
48
+ * ACP client over one `kimi acp` child. Created once per driver scope and reused
49
+ * across steps, matching the Pi RPC client's lifecycle.
50
+ */
51
+ export declare class AcpClient {
52
+ private readonly process;
53
+ private readonly pending;
54
+ private readonly updateBuffer;
55
+ private updateWake;
56
+ private updateHandler;
57
+ private permissionHandler;
58
+ private sealed;
59
+ private nextId;
60
+ private readonly decoder;
61
+ private buffer;
62
+ /** Whether this client was sealed or its process exited. */
63
+ get closed(): boolean;
64
+ /** Mount a client over an already-spawned `kimi acp` process. */
65
+ constructor(process: KimiProcess);
66
+ /**
67
+ * Create a client, spawning the `kimi acp` child through the supplied
68
+ * capability (or the default node spawn when none is given).
69
+ * @param spec - the `kimi acp` argv/cwd/env the child should run with.
70
+ * @param spawn - optional process-spawn capability (the subprocess seam).
71
+ * @returns the connected client.
72
+ */
73
+ static create(spec: KimiSpawnSpec, spawn?: KimiSpawnCapability): AcpClient;
74
+ /** Register the event dispatch handler. */
75
+ onUpdate(handler: AcpUpdateHandler): void;
76
+ /** Register the permission-approval handler (reverse-RPC answers). */
77
+ onPermission(handler: AcpPermissionHandler): void;
78
+ /** Send one request and await the correlated response. */
79
+ request(method: string, params: unknown): Promise<unknown>;
80
+ /** Send a notification (no correlated response awaited). */
81
+ notify(method: string, params: unknown): void;
82
+ /** Open the protocol handshake. */
83
+ initialize(): Promise<unknown>;
84
+ /** Start a fresh ACP session and resolve to its session id. */
85
+ newSession(cwd: string): Promise<string>;
86
+ /**
87
+ * Select the model for one ACP session. The agent answers with an error frame
88
+ * when it cannot serve the id, and {@link request} rejects on that frame — so
89
+ * an engine that refuses the model fails the step loud rather than silently
90
+ * running its own default.
91
+ * @param sessionId - the ACP session the model applies to.
92
+ * @param modelId - the model id to select.
93
+ * @returns the agent's response to `session/set_model`.
94
+ */
95
+ setModel(sessionId: string, modelId: string): Promise<unknown>;
96
+ /**
97
+ * Prompt the agent in a session and resolve when the turn completes.
98
+ * @param sessionId - the ACP session to prompt.
99
+ * @param text - the serialized transcript, or a bare slash command.
100
+ * @param images - image blocks to carry after the text block; omitted or
101
+ * empty leaves the request exactly the text-only shape.
102
+ * @returns the agent's response to `session/prompt`.
103
+ */
104
+ prompt(sessionId: string, text: string, images?: readonly AcpImageContent[]): Promise<unknown>;
105
+ /** Cancel the active turn in a session (fire-and-forget). */
106
+ cancel(sessionId: string): void;
107
+ /**
108
+ * Answer a pending `session/request_permission`.
109
+ * @param id - the reverse-RPC request id.
110
+ * @param response - the ACP outcome to answer with.
111
+ */
112
+ respondPermission(id: number, response: AcpPermissionResponse): void;
113
+ /** Consume every buffered update as an async generator. */
114
+ updates(): AsyncGenerator<AcpUpdate, void, void>;
115
+ /** Seal the client and request child termination. */
116
+ dispose(): void;
117
+ private feed;
118
+ /** Dispatch one parsed line: a response, an update notification, or a reverse-RPC request. */
119
+ private dispatch;
120
+ private settle;
121
+ private handlePermission;
122
+ }
123
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Maps `kimi acp` `session/update` events to dsh session-log projections.
3
+ *
4
+ * Kimi streams incremental assistant text (`agent_message_chunk`), incremental
5
+ * thinking (`agent_thought_chunk`), a tool-call announcement (`tool_call`) and its
6
+ * progress/result updates (`tool_call_update`). Assistant text and thinking are
7
+ * Deltas; a tool update's content is a whole Snapshot that replaces the previous
8
+ * one. A tool call's identity arrives on the announcement but its input
9
+ * (`rawInput`) does not — only a later update carries it. This module is pure: it
10
+ * classifies an update, extracts chunk deltas, and projects the tool-call
11
+ * identity/input/content/result so the agent can fold them into the durable log.
12
+ * Content blocks use the observed kimi
13
+ * `{ type: 'content', content: { type: 'text', text } }` nesting; unknown block
14
+ * types are ignored.
15
+ *
16
+ * @module dsh-loop-engine/engine-kimi/acp/mapping
17
+ */
18
+ import type { ToolResultMessage } from '@deepseek-ai/dsh-llm';
19
+ import type { AcpContentBlock, AcpToolCallExt, AcpToolCallStreamExt, AcpUpdate } from './types.ts';
20
+ /** Whether the update is an incremental assistant text chunk. */
21
+ export declare function isTextChunk(update: AcpUpdate): update is AcpUpdate & {
22
+ readonly sessionUpdate: 'agent_message_chunk';
23
+ readonly content: AcpContentBlock;
24
+ };
25
+ /** Whether the update is an incremental thinking chunk. */
26
+ export declare function isThoughtChunk(update: AcpUpdate): update is AcpUpdate & {
27
+ readonly sessionUpdate: 'agent_thought_chunk';
28
+ readonly content: AcpContentBlock;
29
+ };
30
+ /** Whether the update announces a tool call. */
31
+ export declare function isToolCall(update: AcpUpdate): update is AcpToolCallExt;
32
+ /** Whether the update streams a tool call's progress/result. */
33
+ export declare function isToolCallUpdate(update: AcpUpdate): update is AcpToolCallStreamExt;
34
+ /** The delta text of a text/thinking chunk. */
35
+ export declare function chunkDelta(update: AcpUpdate): string;
36
+ /** The raw tool-call id (+ content index) as the wire carries it. */
37
+ export declare function toolCallIdOf(update: AcpUpdate): string;
38
+ /** The tool display name (`title`). */
39
+ export declare function toolCallName(update: AcpUpdate): string;
40
+ /**
41
+ * The tool call's real input as the JSON `arguments` string the durable
42
+ * `tool/call` carries, when the frame supplies it.
43
+ *
44
+ * The `tool_call` announcement never carries `rawInput`; a later
45
+ * `tool_call_update` does (measured against kimi 0.28.x: the execution-start
46
+ * frame, `status: 'in_progress'`). A call's arguments are therefore unknowable
47
+ * at announce time, and the driver logs the call only once an update supplies
48
+ * them — or when the call settles, whichever comes first.
49
+ * @param update - one tool-call announcement or update.
50
+ * @returns the arguments string, or `undefined` when the frame omits the field.
51
+ */
52
+ export declare function toolRawInput(update: AcpToolCallExt | AcpToolCallStreamExt): string | undefined;
53
+ /** Whether a tool stream status is settled (no longer streaming). */
54
+ export declare function isToolSettledStatus(status: string): boolean;
55
+ /** Whether a tool stream status denotes a failure. */
56
+ export declare function isToolErrorStatus(status: string): boolean;
57
+ /**
58
+ * The tool call's content as ONE update carries it: the joined text of its
59
+ * observed `{ type: 'content', content: { type: 'text', text } }` blocks.
60
+ *
61
+ * Kimi re-sends the call's whole content on every `tool_call_update` rather than
62
+ * streaming deltas (measured against 0.28.1: the string grows from the tool
63
+ * input's rendering to the final output), so this is a *snapshot* — callers
64
+ * replace with it, never append. `undefined` means the update carried no
65
+ * content field at all (nothing to replace), which is distinct from a present
66
+ * but empty one.
67
+ * @param update - one tool-call announcement or update.
68
+ * @returns the content snapshot, or `undefined` when the field is absent.
69
+ */
70
+ export declare function toolContentText(update: AcpToolCallExt | AcpToolCallStreamExt): string | undefined;
71
+ /** Project a completed tool call to a durable tool/result message. */
72
+ export declare function toolResult(callId: string, text: string, isError: boolean): ToolResultMessage;
73
+ //# sourceMappingURL=mapping.d.ts.map