@lmctl-ai/lmctl 0.1.342 → 0.2.3
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/CHANGELOG.md +116 -0
- package/README.md +11 -51
- package/data/price-aliases.json +1 -0
- package/data/price-data.json +1 -1
- package/dist/cli/batch.d.ts +2 -0
- package/dist/cli/busy-evidence.d.ts +27 -0
- package/dist/cli/chat-cycle.d.ts +59 -0
- package/dist/cli/chat-exec.d.ts +83 -0
- package/dist/cli/chat-policy.d.ts +22 -0
- package/dist/cli/chat.d.ts +23 -0
- package/dist/cli/code-resolver.d.ts +8 -0
- package/dist/cli/common.d.ts +54 -0
- package/dist/cli/context.d.ts +12 -0
- package/dist/cli/cost.d.ts +2 -0
- package/dist/cli/export.d.ts +2 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +1062 -1400
- package/dist/cli/infra.d.ts +78 -0
- package/dist/cli/ls.d.ts +2 -0
- package/dist/cli/mailbox-cli.d.ts +6 -0
- package/dist/cli/managed.d.ts +62 -0
- package/dist/cli/mcp-install.d.ts +23 -0
- package/dist/cli/mcp.d.ts +2 -0
- package/dist/cli/paths.d.ts +50 -0
- package/dist/cli/plan-wizard.d.ts +42 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/queue-delivery.d.ts +107 -0
- package/dist/cli/ratelimit.d.ts +3 -0
- package/dist/cli/remote-fetch.d.ts +7 -0
- package/dist/cli/run-queries.d.ts +82 -0
- package/dist/cli/running.d.ts +5 -0
- package/dist/cli/schema.sql +20 -1
- package/dist/cli/script.d.ts +6 -0
- package/dist/cli/script.js +2097 -0
- package/dist/cli/self-identity.d.ts +25 -0
- package/dist/cli/session-idle.d.ts +118 -0
- package/dist/cli/status.d.ts +22 -0
- package/dist/cli/tail.d.ts +18 -0
- package/dist/cli/target-resolver.d.ts +139 -0
- package/dist/cli/team-status.d.ts +91 -0
- package/dist/cli/teamfile-compat.d.ts +71 -0
- package/dist/cli/teamfile-store.d.ts +18 -0
- package/dist/cli/teamfile-template.d.ts +40 -0
- package/dist/cli/template-env.d.ts +25 -0
- package/dist/cli/terminal-lock.d.ts +25 -0
- package/dist/cli/terminal.d.ts +23 -0
- package/dist/cli/time-filter.d.ts +10 -0
- package/dist/cli/update-notifier.d.ts +11 -0
- package/dist/cli/version-util.d.ts +2 -0
- package/dist/config/seed_templates.d.ts +1 -0
- package/dist/db/backfill-event-log.d.ts +26 -0
- package/dist/db/delegation.d.ts +37 -0
- package/dist/db/escalation_vocab.d.ts +45 -0
- package/dist/db/event-log.d.ts +40 -0
- package/dist/db/index.d.ts +1213 -0
- package/dist/db/inflight-acquire.d.ts +70 -0
- package/dist/db/invocation-event-projections.d.ts +65 -0
- package/dist/db/ledger-identity.test.d.ts +1 -0
- package/dist/db/live-event-projections.d.ts +92 -0
- package/dist/db/migrate.d.ts +51 -0
- package/dist/db/open-readonly.d.ts +2 -0
- package/dist/db/process-liveness.d.ts +37 -0
- package/dist/db/sqlite.d.ts +47 -0
- package/dist/db/sqlite.test.d.ts +1 -0
- package/dist/db/terminal-lock.d.ts +14 -0
- package/dist/db/tracked-invocation-reconcile.d.ts +52 -0
- package/dist/db/tracked-invocation.d.ts +116 -0
- package/dist/mcp/dispatch.d.ts +45 -0
- package/dist/mcp/mediation.d.ts +128 -0
- package/dist/mcp/path-warning.d.ts +7 -0
- package/dist/mcp/server.d.ts +63 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/providers/adapter.d.ts +265 -0
- package/dist/providers/adapters/agy-adapter.d.ts +17 -0
- package/dist/providers/adapters/claude-adapter.d.ts +20 -0
- package/dist/providers/adapters/codex-adapter.d.ts +22 -0
- package/dist/providers/adapters/copilot-adapter.d.ts +16 -0
- package/dist/providers/adapters/dsh-adapter.d.ts +89 -0
- package/dist/providers/adapters/gemini-adapter.d.ts +44 -0
- package/dist/providers/adapters/hermes-adapter.d.ts +71 -0
- package/dist/providers/adapters/index.d.ts +35 -0
- package/dist/providers/adapters/kimi-adapter.d.ts +16 -0
- package/dist/providers/adapters/lmplayer-adapter.d.ts +14 -0
- package/dist/providers/adapters/opencode-adapter.d.ts +11 -0
- package/dist/providers/adapters/pi-adapter.d.ts +17 -0
- package/dist/providers/adapters/print-turn.d.ts +29 -0
- package/dist/providers/adapters/qwen-adapter.d.ts +11 -0
- package/dist/providers/agy.d.ts +32 -0
- package/dist/providers/base-adapter.d.ts +107 -0
- package/dist/providers/base.d.ts +12 -0
- package/dist/providers/binary-check.d.ts +102 -0
- package/dist/providers/bundle.d.ts +118 -0
- package/dist/providers/claude-mock.d.ts +90 -0
- package/dist/providers/claude.d.ts +21 -0
- package/dist/providers/codex-config.d.ts +15 -0
- package/dist/providers/codex.d.ts +25 -0
- package/dist/providers/config/model-selection-lint.d.ts +45 -0
- package/dist/providers/config/team-config.d.ts +183 -0
- package/dist/providers/config/types.d.ts +146 -0
- package/dist/providers/config/user-config.d.ts +88 -0
- package/dist/providers/copilot.d.ts +21 -0
- package/dist/providers/debug.d.ts +128 -0
- package/dist/providers/dsh-sidecar.d.ts +65 -0
- package/dist/providers/dsh-zstd.d.ts +27 -0
- package/dist/providers/dsh.d.ts +37 -0
- package/dist/providers/frontmatter.d.ts +46 -0
- package/dist/providers/gemini-session-reader.d.ts +151 -0
- package/dist/providers/gemini.d.ts +39 -0
- package/dist/providers/hermes.d.ts +90 -0
- package/dist/providers/index.d.ts +421 -0
- package/dist/providers/kimi.d.ts +37 -0
- package/dist/providers/model-catalog.d.ts +141 -0
- package/dist/providers/one-shot-timeout.d.ts +1 -0
- package/dist/providers/opencode-config.d.ts +62 -0
- package/dist/providers/opencode.d.ts +40 -0
- package/dist/providers/parsers/acp.d.ts +47 -0
- package/dist/providers/parsers/codex-app-server.d.ts +60 -0
- package/dist/providers/parsers/stream-json.d.ts +57 -0
- package/dist/providers/passive-readers/agy.d.ts +155 -0
- package/dist/providers/passive-readers/copilot.d.ts +173 -0
- package/dist/providers/passive-readers/dsh.d.ts +34 -0
- package/dist/providers/passive-readers/kimi.d.ts +44 -0
- package/dist/providers/passive-readers/opencode.d.ts +89 -0
- package/dist/providers/passive-readers/qwen.d.ts +151 -0
- package/dist/providers/passive-readers/shared.d.ts +138 -0
- package/dist/providers/passive-session-reader.d.ts +188 -0
- package/dist/providers/path-utils.d.ts +1 -0
- package/dist/providers/pi.d.ts +32 -0
- package/dist/providers/pricing.d.ts +107 -0
- package/dist/providers/qwen.d.ts +22 -0
- package/dist/providers/ratelimit-readings.d.ts +32 -0
- package/dist/providers/registry.d.ts +31 -0
- package/dist/providers/resume.d.ts +43 -0
- package/dist/providers/seed-instruction.d.ts +3 -0
- package/dist/providers/self-session-env.d.ts +21 -0
- package/dist/providers/session-limit.d.ts +9 -0
- package/dist/providers/strip-ansi.d.ts +5 -0
- package/dist/providers/transport-errors.d.ts +94 -0
- package/dist/providers/transport-lifecycle.d.ts +63 -0
- package/dist/providers/transport-wrappers.d.ts +110 -0
- package/dist/providers/transports/acp-profiles/config-option-step.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/copilot.d.ts +12 -0
- package/dist/providers/transports/acp-profiles/gemini.d.ts +22 -0
- package/dist/providers/transports/acp-profiles/hermes.d.ts +27 -0
- package/dist/providers/transports/acp-profiles/index.d.ts +19 -0
- package/dist/providers/transports/acp-profiles/kimi.d.ts +24 -0
- package/dist/providers/transports/acp-profiles/opencode.d.ts +26 -0
- package/dist/providers/transports/acp-profiles/types.d.ts +258 -0
- package/dist/providers/transports/acp-rpc.d.ts +18 -0
- package/dist/providers/transports/acp.d.ts +215 -0
- package/dist/providers/transports/codex-app-server.d.ts +190 -0
- package/dist/providers/transports/hold-open.d.ts +120 -0
- package/dist/providers/transports/manager.d.ts +21 -0
- package/dist/providers/transports/stream-json.d.ts +162 -0
- package/dist/providers/transports/types.d.ts +56 -0
- package/dist/providers/types.d.ts +154 -0
- package/dist/providers/yolo-contract.d.ts +131 -0
- package/dist/script/adapter.d.ts +101 -0
- package/dist/script/batch-script.d.ts +7 -0
- package/dist/script/index.d.ts +3 -0
- package/dist/script/lmscript.d.ts +550 -0
- package/dist/shared/policy.d.ts +74 -0
- package/dist/shared-lib/db.d.ts +25 -0
- package/dist/shared-lib/passive-session-reader.d.ts +2 -0
- package/dist/shared-lib/provider-parse.d.ts +6 -0
- package/dist/templates/basedir.d.ts +52 -0
- package/dist/uri/lmctl_uri.d.ts +38 -0
- package/durable-memory/model_selection.md +122 -25
- package/examples/README.md +103 -0
- package/examples/anonymous-panel.lms +3 -0
- package/examples/batch-prompts.txt +9 -0
- package/examples/batchscript.lms +67 -0
- package/examples/n8n/agent-lib.lms +56 -0
- package/examples/n8n/git-lib.lms +93 -0
- package/examples/n8n/mock-support.db +0 -0
- package/examples/n8n/multi-agent-review.lms +107 -0
- package/examples/n8n/news-digest.lms +159 -0
- package/examples/n8n/rag-search.lms +163 -0
- package/examples/n8n/support-agent.lms +88 -0
- package/examples/n8n/ticket-triage.lms +156 -0
- package/package.json +13 -17
- package/dist/cli/side_effect_classifier.json +0 -19
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow-microservice mediation CORE (sub-problem 1, Phase 1).
|
|
3
|
+
*
|
|
4
|
+
* Transport-agnostic by construction: this module imports NO MCP/server
|
|
5
|
+
* code and performs NO I/O of its own — it is a pure, synchronous snapshot
|
|
6
|
+
* read over the canonical DB via the existing DAL surface (the SAME
|
|
7
|
+
* surface the apicli routes call). The later transports wrap THIS:
|
|
8
|
+
* - B (pull tools, Phase 3): an `observe` MCP tool returns observe()'s view.
|
|
9
|
+
* - A (SDK push, Phase 4): a session loop polls observe() and emits
|
|
10
|
+
* notifications/elicitation.
|
|
11
|
+
* Neither requires a core rewrite.
|
|
12
|
+
*
|
|
13
|
+
* Reuse map (design §3/§4):
|
|
14
|
+
* - `step` rows via `dal.listStepsForRun` (rows written once per
|
|
15
|
+
* state/node execution by `dal.insertStep`, src/db/index.ts) — the
|
|
16
|
+
* per-transition observable. NOT `session_event` (subordinate agent
|
|
17
|
+
* activity), NOT a parallel stream.
|
|
18
|
+
* - run lifecycle via `dal.getRun` → `run.current_state` /
|
|
19
|
+
* `run.terminal_state` / `run.paused_at` (written by
|
|
20
|
+
* `setRunCurrentState` / `setRunTerminalState` / the resume path).
|
|
21
|
+
*
|
|
22
|
+
* Deadlock class (#12/#30) stays designed-out: observe() is a stateless
|
|
23
|
+
* read that returns immediately. It performs no self-call and never
|
|
24
|
+
* blocks waiting for the run to terminate — callers poll it.
|
|
25
|
+
*/
|
|
26
|
+
import type { Dal, RunRow, StepRow } from '../db/index.js';
|
|
27
|
+
/** Minimal read surface the core needs — keeps it transport/Dal-agnostic. */
|
|
28
|
+
export interface MediationReader {
|
|
29
|
+
getRun(id: number): RunRow | null;
|
|
30
|
+
listStepsForRun(run_id: number): StepRow[];
|
|
31
|
+
/**
|
|
32
|
+
* Job→run linkage for the invoke handle. `job.run_id` is set the moment
|
|
33
|
+
* the worker creates the run — atomically inside `dal.insertRun`
|
|
34
|
+
* (src/db/index.ts `setJobRun`), and was historically reinforced by the
|
|
35
|
+
* queue worker (moved to lmbee with the daemon, 2026-09-27). Null
|
|
36
|
+
* until then. EXISTING linkage — no new table/path.
|
|
37
|
+
*/
|
|
38
|
+
getJob(id: number): {
|
|
39
|
+
run_id: number | null;
|
|
40
|
+
} | null;
|
|
41
|
+
}
|
|
42
|
+
export type RunStatus = 'not_found' | 'queued' | 'running' | 'paused' | 'terminal';
|
|
43
|
+
/** One normalized node transition (1:1 with a `step` row). */
|
|
44
|
+
export interface Transition {
|
|
45
|
+
step_id: number;
|
|
46
|
+
state_name: string;
|
|
47
|
+
outcome: string | null;
|
|
48
|
+
status_detail: string | null;
|
|
49
|
+
started_at: string;
|
|
50
|
+
ended_at: string | null;
|
|
51
|
+
}
|
|
52
|
+
export interface RunObservation {
|
|
53
|
+
/**
|
|
54
|
+
* The resolved run id, or `null` when observing by job handle and the
|
|
55
|
+
* worker has not created the run yet (transitional `status:'queued'`).
|
|
56
|
+
*/
|
|
57
|
+
run_id: number | null;
|
|
58
|
+
status: RunStatus;
|
|
59
|
+
/** run.current_state — the node the run is at / next (may be `__paused__:<state>`). */
|
|
60
|
+
current_state: string | null;
|
|
61
|
+
/** run.terminal_state — non-null once the run has ended. */
|
|
62
|
+
terminal_state: string | null;
|
|
63
|
+
/** terminal_state !== null. The terminal signal — never dropped. */
|
|
64
|
+
terminal: boolean;
|
|
65
|
+
/** paused_at set, or current_state carries the engine `__paused__:` prefix. */
|
|
66
|
+
paused: boolean;
|
|
67
|
+
/** Step rows AFTER `sinceStepId`, ascending — the per-transition delta. */
|
|
68
|
+
transitions: Transition[];
|
|
69
|
+
/** Max step id observed (full set), or null if none — the observe cursor. */
|
|
70
|
+
latest_step_id: number | null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Snapshot the canonical state of one managed-workflow run as a normalized
|
|
74
|
+
* transition view. `sinceStepId` (default 0) yields only transitions with
|
|
75
|
+
* `step_id > sinceStepId` for incremental observation; `status` and
|
|
76
|
+
* `latest_step_id` are always computed from the FULL step set so a cursored
|
|
77
|
+
* caller still gets correct queued/running/terminal classification.
|
|
78
|
+
*
|
|
79
|
+
* Pure read, returns immediately — no held self-call, never blocks to
|
|
80
|
+
* terminal (the #12/#30 deadlock class is structurally impossible here).
|
|
81
|
+
*/
|
|
82
|
+
export declare function observe(reader: MediationReader, runId: number, sinceStepId?: number): RunObservation;
|
|
83
|
+
/** Observe a managed run by run id OR by the invoke job handle. */
|
|
84
|
+
export interface RunHandle {
|
|
85
|
+
run_id?: number;
|
|
86
|
+
/** The job id returned by invoke (POST /api/jobs). Resolved via getJob. */
|
|
87
|
+
job_id?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Consumable entrypoint for the invoke→observe loop. invoke returns a JOB
|
|
91
|
+
* handle (the worker links the run LATER), so a client cannot observe by
|
|
92
|
+
* run id from invoke's response. `observeHandle` resolves job→run using
|
|
93
|
+
* the EXISTING `job.run_id` linkage (set by `insertRun`, src/db/index.ts:1240):
|
|
94
|
+
* - run_id given → observe(run) directly.
|
|
95
|
+
* - job_id, run not linked → coherent transitional snapshot
|
|
96
|
+
* (run_id:null, status:'queued') — the client
|
|
97
|
+
* keeps polling the SAME job handle, no extra
|
|
98
|
+
* tool, no blocking (deadlock-class stays out).
|
|
99
|
+
* - job_id, run linked → observe(job.run_id) — the real snapshot.
|
|
100
|
+
* Uniform RunObservation shape throughout so the client's poll loop never
|
|
101
|
+
* special-cases the job→run gap.
|
|
102
|
+
*/
|
|
103
|
+
export declare function observeHandle(reader: MediationReader, h: RunHandle, sinceStepId?: number): RunObservation;
|
|
104
|
+
export interface TransitInput {
|
|
105
|
+
/** The operator's answer text (route's `input`). */
|
|
106
|
+
input: string;
|
|
107
|
+
/** End the interactive session (route's `done`); default false. */
|
|
108
|
+
done?: boolean;
|
|
109
|
+
/** Target by run (active interactive_waiting_operator escalation for it)… */
|
|
110
|
+
run_id?: number;
|
|
111
|
+
/** …or by explicit attention id (takes precedence when both given). */
|
|
112
|
+
attention_id?: number;
|
|
113
|
+
}
|
|
114
|
+
export interface TransitResult {
|
|
115
|
+
ok: boolean;
|
|
116
|
+
/** Discovery/resume failure reason (mirrors the route's reason codes). */
|
|
117
|
+
reason?: 'no_active_escalation' | 'wrong_kind' | 'no_step' | 'already_acked' | 'not_found' | 'not_waiting_operator' | 'run_not_found';
|
|
118
|
+
/** Offending attention kind when reason === 'wrong_kind' (parity with app.ts:710). */
|
|
119
|
+
kind?: string;
|
|
120
|
+
attention_id?: number;
|
|
121
|
+
step_id?: number;
|
|
122
|
+
/** interactive_session.status after the existing resume (waiting_agent|done). */
|
|
123
|
+
session_status?: string;
|
|
124
|
+
acknowledged: boolean;
|
|
125
|
+
/** Fresh snapshot — proves the run transitioned off paused (resume cleared __paused__:). */
|
|
126
|
+
observation?: RunObservation;
|
|
127
|
+
}
|
|
128
|
+
export declare function transit(dal: Dal, t: TransitInput): TransitResult;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface McpExecutableWarningOptions {
|
|
2
|
+
env?: NodeJS.ProcessEnv;
|
|
3
|
+
warn?: (message: string) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare function executableOnPath(command: string, env?: NodeJS.ProcessEnv): boolean;
|
|
6
|
+
export declare function formatMissingMcpExecutableWarning(command: string, toolName: string): string;
|
|
7
|
+
export declare function warnIfMcpExecutableMissing(command: string, toolName: string, options?: McpExecutableWarningOptions): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type DispatchDeps } from './dispatch.js';
|
|
2
|
+
export interface JsonRpcRequest {
|
|
3
|
+
jsonrpc: '2.0';
|
|
4
|
+
id?: number | string | null;
|
|
5
|
+
method: string;
|
|
6
|
+
params?: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface JsonRpcSuccess {
|
|
9
|
+
jsonrpc: '2.0';
|
|
10
|
+
id: number | string | null;
|
|
11
|
+
result: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface JsonRpcError {
|
|
14
|
+
jsonrpc: '2.0';
|
|
15
|
+
id: number | string | null;
|
|
16
|
+
error: {
|
|
17
|
+
code: number;
|
|
18
|
+
message: string;
|
|
19
|
+
data?: unknown;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type JsonRpcResponse = JsonRpcSuccess | JsonRpcError;
|
|
23
|
+
export interface ServerIo {
|
|
24
|
+
/** Sink for outbound JSON-RPC frames (typically `process.stdout`). */
|
|
25
|
+
write(chunk: string): unknown;
|
|
26
|
+
/** Optional sink for human-readable stderr diagnostics. */
|
|
27
|
+
log?: (chunk: string) => void;
|
|
28
|
+
}
|
|
29
|
+
export interface ServerDeps {
|
|
30
|
+
io: ServerIo;
|
|
31
|
+
dispatch: DispatchDeps;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Handle a single inbound message. Public for testability — the
|
|
35
|
+
* `runServer` event loop just plumbs stdin/stdout into this.
|
|
36
|
+
*
|
|
37
|
+
* Returns:
|
|
38
|
+
* - `{kind:'response', message: ...}` for request→response handling
|
|
39
|
+
* - `{kind:'notification'}` when the inbound was a notification (id missing)
|
|
40
|
+
* - `{kind:'exit'}` when the inbound was an `exit` notification — the
|
|
41
|
+
* caller stops the loop. We pull this signal out as its own variant
|
|
42
|
+
* rather than e.g. throwing because the spec calls for a clean exit
|
|
43
|
+
* code (0 if `shutdown` was seen, 1 otherwise) and the cleanest way
|
|
44
|
+
* to encode that is bubbling the intent up.
|
|
45
|
+
*/
|
|
46
|
+
export type HandleOutcome = {
|
|
47
|
+
kind: 'response';
|
|
48
|
+
message: JsonRpcResponse;
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'notification';
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'exit';
|
|
53
|
+
};
|
|
54
|
+
export declare function handleMessage(raw: JsonRpcRequest, deps: ServerDeps): Promise<HandleOutcome>;
|
|
55
|
+
/**
|
|
56
|
+
* Run the stdio event loop until EOF or `exit`. Accepts a readable
|
|
57
|
+
* stream (default `process.stdin`) so tests can plug in a `PassThrough`.
|
|
58
|
+
*
|
|
59
|
+
* Returns the integer exit code:
|
|
60
|
+
* - 0 if `shutdown` was observed before exit (graceful)
|
|
61
|
+
* - 1 if exit / EOF arrived without `shutdown` (per LSP-derived MCP convention)
|
|
62
|
+
*/
|
|
63
|
+
export declare function runServer(deps: ServerDeps, stdin: NodeJS.ReadableStream): Promise<number>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool catalog for AI-managed .lmctl teams.
|
|
3
|
+
*
|
|
4
|
+
* The managed workflow product is intentionally CLI-first for now; its
|
|
5
|
+
* API is not exposed through MCP until that surface is explicitly designed.
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolDef {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: 'object';
|
|
12
|
+
properties: Record<string, {
|
|
13
|
+
type: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
items?: unknown;
|
|
16
|
+
}>;
|
|
17
|
+
required?: readonly string[];
|
|
18
|
+
additionalProperties?: boolean;
|
|
19
|
+
};
|
|
20
|
+
local: true;
|
|
21
|
+
}
|
|
22
|
+
export declare const TOOLS: readonly ToolDef[];
|
|
23
|
+
/** Total tool count for tests + tools/list assertions. */
|
|
24
|
+
export declare const TOOL_COUNT: number;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Adapter — unified interface for all provider-specific behavior.
|
|
3
|
+
*
|
|
4
|
+
* Consolidates discovery, session lifecycle, agent turns, and injection
|
|
5
|
+
* capabilities into one contract per provider. Replaces the scattered
|
|
6
|
+
* provider switches across session-seed, user-config, transport manager,
|
|
7
|
+
* and tail-cmd.
|
|
8
|
+
*/
|
|
9
|
+
import type { ProviderName, SessionSummary, SessionDetail, WatchPathInfo } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Normalized progress event from a provider turn. Each transport wrapper is
|
|
12
|
+
* responsible for translating its native event stream into this shape so that
|
|
13
|
+
* downstream consumers (idle-timer, stderr printer, future heartbeat) only
|
|
14
|
+
* need to know one format.
|
|
15
|
+
*/
|
|
16
|
+
export interface ProgressEvent {
|
|
17
|
+
/**
|
|
18
|
+
* Coarse classification of what the provider is doing.
|
|
19
|
+
*
|
|
20
|
+
* `api_retry` is special — it indicates the provider's HTTP transport
|
|
21
|
+
* is retrying upstream, which is the **absence** of progress, not the
|
|
22
|
+
* presence. The idle timer in withTimeouts must NOT reset on these
|
|
23
|
+
* events (task 63 finding 1). The heartbeat does observe them so the
|
|
24
|
+
* user can see the retry cadence in the running… tail.
|
|
25
|
+
*/
|
|
26
|
+
kind: "tool_use" | "tool_result" | "thinking" | "text" | "system" | "api_retry" | "other";
|
|
27
|
+
/** Tool name when kind === "tool_use" / "tool_result" (e.g., "Bash"). */
|
|
28
|
+
tool?: string;
|
|
29
|
+
/** Short human-readable summary (e.g., "cargo build", "exit 0"). */
|
|
30
|
+
summary?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Correlation id linking a tool_use to its matching tool_result. Set
|
|
33
|
+
* by classifiers when the underlying provider exposes a stable id
|
|
34
|
+
* (`tool_use_id` for claude, `item.id` for codex). Used by the
|
|
35
|
+
* progress printer to compute per-tool elapsed time on tool_result.
|
|
36
|
+
*/
|
|
37
|
+
id?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Wall-clock duration in ms, when the provider supplies it directly
|
|
40
|
+
* (codex sets this from `item.durationMs` on commandExecution
|
|
41
|
+
* completion). Optional. The printer prefers this over its own
|
|
42
|
+
* Map-based correlation when both are available.
|
|
43
|
+
*/
|
|
44
|
+
elapsedMs?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Normalized tool_result status: "ok" | "error" | "exit ${number}".
|
|
47
|
+
* Set by classifiers on tool_result events so the printer doesn't
|
|
48
|
+
* have to parse summary strings to decide success vs failure.
|
|
49
|
+
*/
|
|
50
|
+
status?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The original block / message dict from the provider's wire event,
|
|
53
|
+
* attached lossless for downstream consumers that want richer
|
|
54
|
+
* structure than the flat kind/tool/summary fields capture (e.g.
|
|
55
|
+
* `ThinkingBlock.signature`, `ServerToolUseBlock`,
|
|
56
|
+
* `RateLimitEvent`). Populated today by the claude stream-json
|
|
57
|
+
* classifier (per-block for content blocks, top-level message dict
|
|
58
|
+
* for `result`/`system`); codex/ACP classifiers do not populate it.
|
|
59
|
+
* Optional and advisory — classifiers MAY omit when the source is
|
|
60
|
+
* trivial (heartbeats, bare text deltas, synthesized api_retry).
|
|
61
|
+
*/
|
|
62
|
+
raw?: Record<string, unknown>;
|
|
63
|
+
}
|
|
64
|
+
export interface TurnOptions {
|
|
65
|
+
sessionId: string;
|
|
66
|
+
cwd: string;
|
|
67
|
+
env?: NodeJS.ProcessEnv;
|
|
68
|
+
profile?: string;
|
|
69
|
+
requireResume?: boolean;
|
|
70
|
+
onDelta?: (text: string) => void;
|
|
71
|
+
/** Called for every classified progress event from the provider. */
|
|
72
|
+
onProgress?: (event: ProgressEvent) => void;
|
|
73
|
+
signal?: AbortSignal;
|
|
74
|
+
/** Idle timeout in milliseconds. Default: 8 hours. 0 = no timeout.
|
|
75
|
+
* When the timer fires, the turn resolves with status: "stalled"
|
|
76
|
+
* instead of killing the child process. */
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
/** Called when the idle timer fires (before resolving as stalled).
|
|
79
|
+
* Use for logging/debug output. */
|
|
80
|
+
onIdleWarning?: (elapsedMs: number) => void;
|
|
81
|
+
/** User config overrides — adapter checks this before using defaults. */
|
|
82
|
+
userConfig?: import("./config/types.js").UserConfig;
|
|
83
|
+
/**
|
|
84
|
+
* Override the spawned provider binary path. Used for troubleshooting
|
|
85
|
+
* with custom builds (e.g. `~/research/studyclaude/cli-dev` for a
|
|
86
|
+
* Claude Code dev build). When set, the transport spawns this exact
|
|
87
|
+
* path instead of looking up `claude` / `codex` / etc. on PATH.
|
|
88
|
+
* (Task 63 fix 3.)
|
|
89
|
+
*/
|
|
90
|
+
progPath?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Provider-specific model name (e.g. "claude-sonnet-4-6"). The
|
|
93
|
+
* transport maps this through each provider's supported surface:
|
|
94
|
+
* claude/gemini/qwen use `--model`, codex uses app-server
|
|
95
|
+
* `-c model="..."` plus RPC `model` overrides, opencode uses ACP
|
|
96
|
+
* `session/set_config_option`, and unsupported providers ignore
|
|
97
|
+
* with provider-specific diagnostics.
|
|
98
|
+
*/
|
|
99
|
+
model?: string;
|
|
100
|
+
/** Provider-specific effort / variant override. Honored by OpenCode ACP; Kimi has no genuine per-turn effort override (see model-selection-lint.ts) so lint warns and ignores it there. */
|
|
101
|
+
effort?: string;
|
|
102
|
+
/**
|
|
103
|
+
* The teamfile alias of the member being spawned. Kept for diagnostics
|
|
104
|
+
* and old codex callers that only identify the literal "Lead" alias.
|
|
105
|
+
*/
|
|
106
|
+
alias?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Role-based Lead signal from teamfile resolution. Use this instead of
|
|
109
|
+
* alias text when Lead-only provider wiring is required; teams may name
|
|
110
|
+
* their leader something other than "Lead".
|
|
111
|
+
*/
|
|
112
|
+
isLead?: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Permission mode for the turn — `"yolo"` (default) or `"plan"`.
|
|
115
|
+
*
|
|
116
|
+
* - `"yolo"`: append the provider's permission-bypass flag (the
|
|
117
|
+
* historical hardcoded behavior — `--dangerously-skip-permissions`
|
|
118
|
+
* for claude, `--approval-mode yolo` for qwen, `-y` for gemini,
|
|
119
|
+
* `--yolo` for copilot; codex JSON-RPC sandbox is
|
|
120
|
+
* `danger-full-access`).
|
|
121
|
+
* - `"plan"`: substitute the provider's plan-mode flag instead
|
|
122
|
+
* (`--permission-mode plan` for claude, `--approval-mode plan`
|
|
123
|
+
* for qwen/gemini; codex JSON-RPC sandbox is `read-only`).
|
|
124
|
+
*
|
|
125
|
+
* Default is `"yolo"` so calls that omit the field preserve the
|
|
126
|
+
* pre-existing argv/protocol shape exactly. See
|
|
127
|
+
* `src/providers/yolo-contract.ts` for the per-provider table.
|
|
128
|
+
*
|
|
129
|
+
* Caveat (gemini): plan mode filters `write_file` by workspace path
|
|
130
|
+
* only; an agent can still escape via `run_shell_command`. A tighter
|
|
131
|
+
* sandbox for plan mode is a follow-up.
|
|
132
|
+
*/
|
|
133
|
+
permissionMode?: import("./yolo-contract.js").PermissionMode;
|
|
134
|
+
/**
|
|
135
|
+
* Defer the end-of-turn shutdown while the session being run still has
|
|
136
|
+
* outstanding dispatched work (live `agent_inflight` rows it is the
|
|
137
|
+
* SENDER of). Honored by the stream-json transport (claude/qwen), whose
|
|
138
|
+
* first-result stdin close is what orphans a session's
|
|
139
|
+
* `run_in_background` dispatches when the host process exits
|
|
140
|
+
* (BUG-chat-client-death-interrupts-receiver-live-session). Other
|
|
141
|
+
* transports currently ignore it: codex/ACP hold persistent server
|
|
142
|
+
* processes with different end-of-turn semantics and have not exhibited
|
|
143
|
+
* this failure mode.
|
|
144
|
+
*/
|
|
145
|
+
holdOpen?: import("./transports/hold-open.js").HoldOpenOptions;
|
|
146
|
+
/**
|
|
147
|
+
* Caller-held bundle session (batch bundle mode): when set, the
|
|
148
|
+
* transport sends this turn through the ALREADY-OPEN provider process
|
|
149
|
+
* instead of spawning a new one. Per-turn spawn options (model, env,
|
|
150
|
+
* holdOpen, requireResume) were fixed at open and are ignored here;
|
|
151
|
+
* the per-turn `expectedSession` check upstream still verifies the
|
|
152
|
+
* returned sessionId. See src/providers/bundle.ts for the contract.
|
|
153
|
+
*/
|
|
154
|
+
bundleSession?: import("./bundle.js").BundleSession;
|
|
155
|
+
}
|
|
156
|
+
export interface TurnResult {
|
|
157
|
+
text: string;
|
|
158
|
+
sessionId: string;
|
|
159
|
+
durationMs: number;
|
|
160
|
+
stopReason?: string;
|
|
161
|
+
numTurns?: number;
|
|
162
|
+
/** "ok" (default/omitted) = normal completion.
|
|
163
|
+
* "stalled" = idle timeout fired — provider went silent for the
|
|
164
|
+
* configured duration. The child process is still alive. The text
|
|
165
|
+
* field contains whatever was produced before the stall. */
|
|
166
|
+
status?: "ok" | "stalled";
|
|
167
|
+
/** When status === "stalled": how long the provider was idle (ms). */
|
|
168
|
+
stalledAfterMs?: number;
|
|
169
|
+
/** Human-readable strings when this turn's provider silently dropped a
|
|
170
|
+
* declared model=/effort= (task #232). Omitted when nothing was dropped.
|
|
171
|
+
* Same convention as `SeedResult.warnings`. */
|
|
172
|
+
warnings?: string[];
|
|
173
|
+
}
|
|
174
|
+
export interface SeedResult {
|
|
175
|
+
success: boolean;
|
|
176
|
+
error?: string;
|
|
177
|
+
/** Non-fatal provider diagnostics that callers should surface to the operator. */
|
|
178
|
+
warnings?: string[];
|
|
179
|
+
/** Native session id when the provider reports it directly during seed. */
|
|
180
|
+
sessionId?: string;
|
|
181
|
+
}
|
|
182
|
+
export interface SeedOptions {
|
|
183
|
+
/** Provider-specific model name requested for the initial seed turn. */
|
|
184
|
+
model?: string;
|
|
185
|
+
/** Provider-specific effort / variant requested for the initial seed turn. */
|
|
186
|
+
effort?: string;
|
|
187
|
+
/** Optional provider seed prompt; defaults to the standard lmctl seed ACK prompt. */
|
|
188
|
+
prompt?: string;
|
|
189
|
+
}
|
|
190
|
+
export interface ForkResult {
|
|
191
|
+
success: boolean;
|
|
192
|
+
error?: string;
|
|
193
|
+
/** Native session ID of the forked session. */
|
|
194
|
+
sessionId?: string;
|
|
195
|
+
/** File path of the forked session (if applicable). */
|
|
196
|
+
filePath?: string;
|
|
197
|
+
}
|
|
198
|
+
export interface ProviderCapabilities {
|
|
199
|
+
canCreate: boolean;
|
|
200
|
+
canResumeInteractive: boolean;
|
|
201
|
+
canFork: boolean;
|
|
202
|
+
/** "automatic" = lmctl can fork end-to-end; "manual" = print instructions */
|
|
203
|
+
forkSupport: "automatic" | "manual";
|
|
204
|
+
canStructuredTurn: boolean;
|
|
205
|
+
canStreamDeltas: boolean;
|
|
206
|
+
canCancel: boolean;
|
|
207
|
+
}
|
|
208
|
+
export interface InjectionInfo {
|
|
209
|
+
/** How leader behavior can be shaped through public provider mechanisms. */
|
|
210
|
+
leaderMode: "none" | "prompt-append" | "skill-file" | "custom-tool";
|
|
211
|
+
/** Human-readable hint shown when creating a managed team with this leader. */
|
|
212
|
+
leaderSetupHint?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Per-provider instructions for the user to MANUALLY create a
|
|
216
|
+
* session when `lmctl seed` auto-seed fails.
|
|
217
|
+
*
|
|
218
|
+
* Lmctl can't anticipate every cause of seed failure (workspace
|
|
219
|
+
* trust, expired auth, sandbox restriction, version drift in flag
|
|
220
|
+
* names) but the recovery is always the same shape: launch the
|
|
221
|
+
* provider interactively, send lmctl's explicit seed instruction
|
|
222
|
+
* to commit a waiting session file, then update the teamfile with
|
|
223
|
+
* the new sessionid.
|
|
224
|
+
*
|
|
225
|
+
* Adapters override the default to inject provider-specific flags
|
|
226
|
+
* (e.g. gemini's `--skip-trust` for the workspace-trust gate).
|
|
227
|
+
*/
|
|
228
|
+
export interface ManualSeedHint {
|
|
229
|
+
/** Native command the user runs interactively to create a session.
|
|
230
|
+
* Includes the `cd <sessiondir> && <binary> [flags]` shape. */
|
|
231
|
+
launchCommand: string;
|
|
232
|
+
/** One-line note on what to do INSIDE the launched session. */
|
|
233
|
+
postLaunchNote: string;
|
|
234
|
+
/** Filter to pass to `lmctl ls` for finding the freshly-created
|
|
235
|
+
* session id. */
|
|
236
|
+
lsCommand: string;
|
|
237
|
+
}
|
|
238
|
+
export interface ProviderAdapter {
|
|
239
|
+
readonly name: ProviderName;
|
|
240
|
+
readonly capabilities: ProviderCapabilities;
|
|
241
|
+
readonly injection: InjectionInfo;
|
|
242
|
+
discover(): Promise<SessionSummary[]>;
|
|
243
|
+
load(sessionId: string): Promise<SessionDetail | null>;
|
|
244
|
+
resolvePath(sessionId: string): Promise<string | null>;
|
|
245
|
+
delete(sessionId: string): Promise<boolean>;
|
|
246
|
+
getWatchPaths?(): WatchPathInfo[];
|
|
247
|
+
seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
|
|
248
|
+
resumeCommand(sessionId: string, profile?: string): string;
|
|
249
|
+
startCommand(profile?: string): string;
|
|
250
|
+
/** Instructions for the user to manually seed this provider's
|
|
251
|
+
* session in `sessiondir` when auto-seed fails. */
|
|
252
|
+
manualSeedHint(sessiondir: string): ManualSeedHint;
|
|
253
|
+
forkHint?(sessionId: string): string;
|
|
254
|
+
fork?(sessionId: string, tag: string): Promise<ForkResult>;
|
|
255
|
+
sendTurn(prompt: string, opts: TurnOptions): Promise<TurnResult>;
|
|
256
|
+
/**
|
|
257
|
+
* Open ONE provider process serving many turns (batch bundle
|
|
258
|
+
* mode). Present only on bundle-capable adapters — Landing C1
|
|
259
|
+
* implements the ACP providers (gemini/copilot/opencode/kimi/hermes);
|
|
260
|
+
* stream-json/codex/dsh follow. The lifecycle contract (per-turn
|
|
261
|
+
* boundary, cancellation, hold-open, unexpected exit, idempotent
|
|
262
|
+
* bounded close, session identity) is in `src/providers/bundle.ts`.
|
|
263
|
+
*/
|
|
264
|
+
openSession?(opts: import("./bundle.js").BundleSessionOpenOptions): Promise<import("./bundle.js").BundleSession>;
|
|
265
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseProviderAdapter } from "../base-adapter.js";
|
|
2
|
+
import type { SeedOptions } from "../adapter.js";
|
|
3
|
+
export declare function createAgyAdapter(opts?: {
|
|
4
|
+
agyDir?: string;
|
|
5
|
+
}): AgyAdapter;
|
|
6
|
+
declare class AgyAdapter extends BaseProviderAdapter {
|
|
7
|
+
constructor(opts?: {
|
|
8
|
+
agyDir?: string;
|
|
9
|
+
});
|
|
10
|
+
protected seedArgsFor(opts?: SeedOptions): string[];
|
|
11
|
+
manualSeedHint(sessiondir: string): {
|
|
12
|
+
launchCommand: string;
|
|
13
|
+
postLaunchNote: string;
|
|
14
|
+
lsCommand: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseProviderAdapter } from "../base-adapter.js";
|
|
2
|
+
import type { SeedOptions } from "../adapter.js";
|
|
3
|
+
import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
|
|
4
|
+
export declare function createClaudeAdapter(opts?: {
|
|
5
|
+
claudeDir?: string;
|
|
6
|
+
}): ClaudeAdapter;
|
|
7
|
+
declare class ClaudeAdapter extends BaseProviderAdapter {
|
|
8
|
+
private readonly claudeDir;
|
|
9
|
+
constructor(opts?: {
|
|
10
|
+
claudeDir?: string;
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Bundle support (batch redesign item 2): one stream-json process, many
|
|
14
|
+
* turns. The identity check's session-file root follows this adapter's
|
|
15
|
+
* provider home (custom claudeDir ⇒ custom projects dir).
|
|
16
|
+
*/
|
|
17
|
+
openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
|
|
18
|
+
protected seedArgsFor(opts?: SeedOptions): string[];
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseProviderAdapter } from "../base-adapter.js";
|
|
2
|
+
import type { SeedOptions, TurnOptions } from "../adapter.js";
|
|
3
|
+
import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
|
|
4
|
+
export declare function createCodexAdapter(opts?: {
|
|
5
|
+
codexDir?: string;
|
|
6
|
+
codeDir?: string;
|
|
7
|
+
}): CodexAdapter;
|
|
8
|
+
declare class CodexAdapter extends BaseProviderAdapter {
|
|
9
|
+
constructor(opts?: {
|
|
10
|
+
codexDir?: string;
|
|
11
|
+
codeDir?: string;
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Bundle support (batch redesign item 2): one app-server process, many
|
|
15
|
+
* `turn/start`s on the strictly-resumed thread. The bare-member default
|
|
16
|
+
* model applies at open (same rule as turnOptsFor for one-shot turns).
|
|
17
|
+
*/
|
|
18
|
+
openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
|
|
19
|
+
protected seedArgsFor(opts?: SeedOptions): string[];
|
|
20
|
+
protected turnOptsFor(opts: TurnOptions): TurnOptions;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseProviderAdapter } from "../base-adapter.js";
|
|
2
|
+
import type { SeedOptions, SeedResult } from "../adapter.js";
|
|
3
|
+
import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
|
|
4
|
+
export declare function createCopilotAdapter(opts?: {
|
|
5
|
+
copilotDir?: string;
|
|
6
|
+
}): CopilotAdapter;
|
|
7
|
+
declare class CopilotAdapter extends BaseProviderAdapter {
|
|
8
|
+
private readonly copilotDir?;
|
|
9
|
+
constructor(opts?: {
|
|
10
|
+
copilotDir?: string;
|
|
11
|
+
});
|
|
12
|
+
/** Bundle support (batch redesign item 2): one ACP process, many turns. */
|
|
13
|
+
openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
|
|
14
|
+
seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh (DeepSeek Harness) provider adapter.
|
|
3
|
+
*
|
|
4
|
+
* dsh's headless profile is one-shot-only (no session resume — proven
|
|
5
|
+
* three independent ways in `backlog/DESIGN-add-dsh-provider.md`). The
|
|
6
|
+
* only real continuity path is the `web` profile's internal HTTP RPC
|
|
7
|
+
* surface: `session.create` with a caller-supplied id, then repeated
|
|
8
|
+
* `session.prompt` calls against that same id, genuinely carry context
|
|
9
|
+
* forward (proven end-to-end). This adapter drives that RPC surface
|
|
10
|
+
* through a managed sidecar (`dsh-sidecar.ts`) rather than spawning a new
|
|
11
|
+
* `dsh` process per turn the way argv-templated providers (agy, claude,
|
|
12
|
+
* codex, qwen) do — there is no equivalent one-shot-with-resume-flag
|
|
13
|
+
* shape for dsh to model those on.
|
|
14
|
+
*/
|
|
15
|
+
import { BaseProviderAdapter } from "../base-adapter.js";
|
|
16
|
+
import type { SeedOptions, SeedResult } from "../adapter.js";
|
|
17
|
+
import type { BundleSession, BundleSessionOpenOptions } from "../bundle.js";
|
|
18
|
+
export declare function createDshAdapter(opts?: {
|
|
19
|
+
dshHome?: string;
|
|
20
|
+
}): DshAdapter;
|
|
21
|
+
interface DshRecord {
|
|
22
|
+
type?: string;
|
|
23
|
+
seq?: number;
|
|
24
|
+
time?: number;
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
declare class DshAdapter extends BaseProviderAdapter {
|
|
28
|
+
private readonly dshProvider;
|
|
29
|
+
constructor(opts?: {
|
|
30
|
+
dshHome?: string;
|
|
31
|
+
});
|
|
32
|
+
manualSeedHint(sessiondir: string): {
|
|
33
|
+
launchCommand: string;
|
|
34
|
+
postLaunchNote: string;
|
|
35
|
+
lsCommand: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Overridden entirely rather than relying on BaseProviderAdapter's
|
|
39
|
+
* default (spawn `binary` with `seedArgs` as a one-shot process) — dsh
|
|
40
|
+
* has no such mode with continuity. Generates the session id lmctl will
|
|
41
|
+
* use for every future turn, creates it via RPC, and sends the seed
|
|
42
|
+
* prompt through the exact same path a real turn uses.
|
|
43
|
+
*/
|
|
44
|
+
seed(cwd: string, opts?: SeedOptions): Promise<SeedResult>;
|
|
45
|
+
private dshPromptTurn;
|
|
46
|
+
/**
|
|
47
|
+
* Bundle support (batch redesign item 2): hold the shared sidecar across
|
|
48
|
+
* turns — the per-turn `shutdownDshSidecar` in dshPromptTurn is deferred
|
|
49
|
+
* to close(). Turn completion stays the seq-scoped transcript poll
|
|
50
|
+
* (promptAndWait), which is per-turn safe by construction: each turn
|
|
51
|
+
* waits for a turn/end NEWER than the seq captured before its prompt.
|
|
52
|
+
*
|
|
53
|
+
* Cancellation is TERMINAL for dsh bundles (the adapter advertises
|
|
54
|
+
* canCancel: false — the RPC surface has no cancel verb): aborting a
|
|
55
|
+
* turn rejects it, shuts the sidecar down, and closes the bundle.
|
|
56
|
+
*/
|
|
57
|
+
openSession(opts: BundleSessionOpenOptions): Promise<BundleSession>;
|
|
58
|
+
/** Send `prompt`, poll the session file until a NEW turn/end record
|
|
59
|
+
* appears (by seq, so an earlier turn's completion can't be mistaken
|
|
60
|
+
* for this one's), and return the newest assistant/message text. */
|
|
61
|
+
private promptAndWait;
|
|
62
|
+
}
|
|
63
|
+
interface TurnEndReason {
|
|
64
|
+
kind?: string;
|
|
65
|
+
error?: {
|
|
66
|
+
message?: string;
|
|
67
|
+
code?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* dsh's own `turn/end` record carries a real, actionable error (e.g.
|
|
72
|
+
* `{code:"MISSING_CREDENTIAL", message:"...store DEEPSEEK_API_KEY..."}`)
|
|
73
|
+
* on a failed turn -- surface it instead of the bare reason kind, which
|
|
74
|
+
* gave no hint the actual cause was a missing DEEPSEEK_API_KEY (real
|
|
75
|
+
* incident: math.lmctl spent 4 seed attempts chasing a model-name red
|
|
76
|
+
* herring before finding the real cause by reading raw session bytes).
|
|
77
|
+
*/
|
|
78
|
+
declare function turnEndErrorMessage(reason: TurnEndReason | undefined): string;
|
|
79
|
+
declare function maxTurnEndSeq(filePath: string): Promise<number>;
|
|
80
|
+
declare function readRecordsSafe(filePath: string): Promise<DshRecord[]>;
|
|
81
|
+
declare function assistantText(record: DshRecord): string;
|
|
82
|
+
/** Test seam for the pure record helpers (F1/F4 regression tests). */
|
|
83
|
+
export declare const _internals: {
|
|
84
|
+
assistantText: typeof assistantText;
|
|
85
|
+
readRecordsSafe: typeof readRecordsSafe;
|
|
86
|
+
maxTurnEndSeq: typeof maxTurnEndSeq;
|
|
87
|
+
turnEndErrorMessage: typeof turnEndErrorMessage;
|
|
88
|
+
};
|
|
89
|
+
export {};
|