@dudousxd/nestjs-agent-opencode 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +145 -2
- package/dist/durable/index.cjs +3138 -0
- package/dist/durable/index.cjs.map +1 -0
- package/dist/durable/index.d.cts +75 -0
- package/dist/durable/index.d.ts +75 -0
- package/dist/durable/index.js +3109 -0
- package/dist/durable/index.js.map +1 -0
- package/dist/engine-C_WSZ0cZ.d.cts +846 -0
- package/dist/engine-C_WSZ0cZ.d.ts +846 -0
- package/dist/index.cjs +2938 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +124 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.js +2889 -0
- package/dist/index.js.map +1 -0
- package/package.json +93 -3
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { d as OpenCodeClient, e as OpenCodeEvent, f as OpenCodeForm, g as OpenCodeFormValue, h as OpenCodeFormField, i as OpenCodeMcpEndpoint, O as OpenCodeTurns, a as OpenCodeEngineSettings } from './engine-C_WSZ0cZ.cjs';
|
|
2
|
+
export { I as InMemoryOpenCodeSessionStore, M as Milestone, j as OpenCodeAmendment, k as OpenCodeCallContext, c as OpenCodeEngineOptions, b as OpenCodeHost, l as OpenCodeKeyValue, m as OpenCodeModelRef, n as OpenCodePermissionRequest, o as OpenCodePermissionRule, p as OpenCodeReplyMismatchError, q as OpenCodeRunResult, r as OpenCodeServer, s as OpenCodeSessionCreate, t as OpenCodeSessionRef, u as OpenCodeSessionStore, v as OpenCodeToolCall, w as OpenCodeToolRefusedError, x as OpenCodeToolsClaims, y as OpenCodeToolsOptions, z as OpenCodeToolsTokens, A as OpenCodeTurn, B as OpenCodeTurnContext, P as PendingAsk, S as SessionHandle, T as TurnOutcome, C as keyValueOpenCodeSessionStore, D as openCode, E as openCodeControllers, F as openCodeProviders } from './engine-C_WSZ0cZ.cjs';
|
|
3
|
+
import { ElicitationRequest, ElicitationQuestion, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply } from '@dudousxd/nestjs-agent-core';
|
|
4
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
5
|
+
import '@dudousxd/nestjs-agent';
|
|
6
|
+
import '@nestjs/common';
|
|
7
|
+
import '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
|
|
9
|
+
type Listener = (event: OpenCodeEvent) => void;
|
|
10
|
+
/** The session an event belongs to. Form events carry it inside the form. */
|
|
11
|
+
declare function sessionOf(event: OpenCodeEvent): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* One event subscription per OpenCode server, fanned out to the turns listening on its sessions. A
|
|
14
|
+
* server's stream closes when its last listener leaves; a stream that drops reconnects with backoff.
|
|
15
|
+
*
|
|
16
|
+
* `subscribe()` only describes the request: the client connects when the stream is first iterated,
|
|
17
|
+
* and the server registers the subscriber some time after that. A stream is therefore open when its
|
|
18
|
+
* first event arrives, not when it was asked for — events a prompt causes before then would be lost
|
|
19
|
+
* (the catch-up recovers permissions and forms, not text, tools or the end of the execution).
|
|
20
|
+
*/
|
|
21
|
+
declare class OpenCodeEventHub {
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private readonly streams;
|
|
25
|
+
constructor(options?: {
|
|
26
|
+
connectTimeoutMs?: number;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Listen to one session's events on a server. Resolves once the server's stream is open (its first
|
|
30
|
+
* event arrived), or after the connect timeout — the turn's safety nets cover a stream that is
|
|
31
|
+
* slow to open.
|
|
32
|
+
*/
|
|
33
|
+
listen(serverKey: string, client: OpenCodeClient, sessionId: string, listener: Listener): Promise<() => void>;
|
|
34
|
+
close(): void;
|
|
35
|
+
/**
|
|
36
|
+
* The server's stream, opened on `client`. A different client for a known key (the host
|
|
37
|
+
* replaced the connection, e.g. a new sandbox under the same key) moves every listener to a stream
|
|
38
|
+
* on the new one: the old connection may be dead, and its sessions would never hear back.
|
|
39
|
+
*/
|
|
40
|
+
private streamFor;
|
|
41
|
+
private pump;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** An OpenCode form field as a stream-protocol question (`docs/stream-protocol.md`, *Asking the user*). */
|
|
45
|
+
declare function toQuestion(field: OpenCodeFormField): ElicitationQuestion;
|
|
46
|
+
/** The elicitation an OpenCode form streams as, under `id` (the tool-call id it is answered through). */
|
|
47
|
+
declare function toElicitation(id: string, form: OpenCodeForm): ElicitationRequest;
|
|
48
|
+
declare class FormAnswerError extends Error {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The protocol's answers (question id → canonical strings) as OpenCode's form reply: numbers as
|
|
52
|
+
* numbers, booleans as booleans, multiple choice as a list. Questions left out take their defaults;
|
|
53
|
+
* a value a question can't take throws {@link FormAnswerError}.
|
|
54
|
+
*/
|
|
55
|
+
declare function toFormAnswer(form: OpenCodeForm, answers?: Record<string, string[]>): Record<string, OpenCodeFormValue>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `POST <agent path>/opencode/mcp` — the endpoint the engine registers in every OpenCode session
|
|
59
|
+
* (`mcp.add`) when `tools` is set. It authenticates its callers itself (the bearer token the engine
|
|
60
|
+
* minted for the session), so the module's `guards` are not applied to it. Stateless: no
|
|
61
|
+
* server-sent stream to resume, no session to close.
|
|
62
|
+
*/
|
|
63
|
+
declare class OpenCodeMcpController {
|
|
64
|
+
private readonly endpoint;
|
|
65
|
+
constructor(endpoint: OpenCodeMcpEndpoint);
|
|
66
|
+
post(req: IncomingMessage, res: ServerResponse, body: unknown): Promise<void>;
|
|
67
|
+
get(res: ServerResponse): void;
|
|
68
|
+
delete(res: ServerResponse): void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Runs OpenCode turns in this process: `begin → prompt → [observe → wait for a person → reply]* →
|
|
73
|
+
* settle`, with the waits on people held in memory. Like `InlineAgentRunner`, a run parked on a
|
|
74
|
+
* person lives in this process, so deploy it single-replica — or use `openCodeDurable()`
|
|
75
|
+
* (`@dudousxd/nestjs-agent-opencode/durable`), which checkpoints every step and waits on a durable
|
|
76
|
+
* signal.
|
|
77
|
+
*/
|
|
78
|
+
declare class OpenCodeAgentRunner implements AgentRunner {
|
|
79
|
+
private readonly turns;
|
|
80
|
+
private readonly settings;
|
|
81
|
+
private readonly live;
|
|
82
|
+
private readonly cancelled;
|
|
83
|
+
private readonly pending;
|
|
84
|
+
constructor(turns: OpenCodeTurns, settings: OpenCodeEngineSettings);
|
|
85
|
+
runIdFor(input: AgentRunInput): string;
|
|
86
|
+
isRunActive(runId: string): Promise<boolean>;
|
|
87
|
+
start(input: AgentRunInput, options?: AgentRunStartOptions): Promise<{
|
|
88
|
+
runId: string;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* Deliver a person's reply. Answers addressed at an approval are refused
|
|
92
|
+
* ({@link OpenCodeReplyMismatchError}, a 409) and the approval keeps waiting: they say nothing
|
|
93
|
+
* about whether the action should run.
|
|
94
|
+
*/
|
|
95
|
+
signal(runId: string, toolCallId: string, reply: HumanReply): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Stop the run: what it waits on a person for is dropped, and OpenCode is interrupted — it answers
|
|
98
|
+
* `session.execution.interrupted`, which settles the run as cancelled.
|
|
99
|
+
*/
|
|
100
|
+
cancel(runId: string): Promise<void>;
|
|
101
|
+
private readonly inputs;
|
|
102
|
+
private run;
|
|
103
|
+
/** Wait for a person's answer; a lapsed approval answers itself as expired. */
|
|
104
|
+
private park;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** The host's {@link import('./host.js').OpenCodeHost}. */
|
|
108
|
+
declare const OPENCODE_HOST: unique symbol;
|
|
109
|
+
/** Where each thread's session is kept ({@link import('./host.js').OpenCodeSessionStore}). */
|
|
110
|
+
declare const OPENCODE_SESSIONS: unique symbol;
|
|
111
|
+
/** The engine's {@link import('./turns.js').OpenCodeEngineSettings}. */
|
|
112
|
+
declare const OPENCODE_OPTIONS: unique symbol;
|
|
113
|
+
/**
|
|
114
|
+
* The engine's turn steps ({@link import('./turns.js').OpenCodeTurns}): `callContext` for the MCP
|
|
115
|
+
* surface, `pushToSession`, `liveRuns`. Inject this token, not the class — the class a host imports
|
|
116
|
+
* from the main bundle is not the one `openCodeDurable()` (`/durable`) registers.
|
|
117
|
+
*/
|
|
118
|
+
declare const OPENCODE_TURNS: unique symbol;
|
|
119
|
+
/** The engine's tools endpoint ({@link import('./mcp.js').OpenCodeMcpEndpoint}), when `tools` is set. */
|
|
120
|
+
declare const OPENCODE_MCP_ENDPOINT: unique symbol;
|
|
121
|
+
/** Mints and checks the tools endpoint's bearer tokens ({@link import('./mcp.js').OpenCodeToolsTokens}). */
|
|
122
|
+
declare const OPENCODE_TOOLS_TOKENS: unique symbol;
|
|
123
|
+
|
|
124
|
+
export { FormAnswerError, OPENCODE_HOST, OPENCODE_MCP_ENDPOINT, OPENCODE_OPTIONS, OPENCODE_SESSIONS, OPENCODE_TOOLS_TOKENS, OPENCODE_TURNS, OpenCodeAgentRunner, OpenCodeClient, OpenCodeEngineSettings, OpenCodeEvent, OpenCodeEventHub, OpenCodeForm, OpenCodeFormField, OpenCodeFormValue, OpenCodeMcpController, OpenCodeMcpEndpoint, OpenCodeTurns, sessionOf, toElicitation, toFormAnswer, toQuestion };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { d as OpenCodeClient, e as OpenCodeEvent, f as OpenCodeForm, g as OpenCodeFormValue, h as OpenCodeFormField, i as OpenCodeMcpEndpoint, O as OpenCodeTurns, a as OpenCodeEngineSettings } from './engine-C_WSZ0cZ.js';
|
|
2
|
+
export { I as InMemoryOpenCodeSessionStore, M as Milestone, j as OpenCodeAmendment, k as OpenCodeCallContext, c as OpenCodeEngineOptions, b as OpenCodeHost, l as OpenCodeKeyValue, m as OpenCodeModelRef, n as OpenCodePermissionRequest, o as OpenCodePermissionRule, p as OpenCodeReplyMismatchError, q as OpenCodeRunResult, r as OpenCodeServer, s as OpenCodeSessionCreate, t as OpenCodeSessionRef, u as OpenCodeSessionStore, v as OpenCodeToolCall, w as OpenCodeToolRefusedError, x as OpenCodeToolsClaims, y as OpenCodeToolsOptions, z as OpenCodeToolsTokens, A as OpenCodeTurn, B as OpenCodeTurnContext, P as PendingAsk, S as SessionHandle, T as TurnOutcome, C as keyValueOpenCodeSessionStore, D as openCode, E as openCodeControllers, F as openCodeProviders } from './engine-C_WSZ0cZ.js';
|
|
3
|
+
import { ElicitationRequest, ElicitationQuestion, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply } from '@dudousxd/nestjs-agent-core';
|
|
4
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
5
|
+
import '@dudousxd/nestjs-agent';
|
|
6
|
+
import '@nestjs/common';
|
|
7
|
+
import '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
|
|
9
|
+
type Listener = (event: OpenCodeEvent) => void;
|
|
10
|
+
/** The session an event belongs to. Form events carry it inside the form. */
|
|
11
|
+
declare function sessionOf(event: OpenCodeEvent): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* One event subscription per OpenCode server, fanned out to the turns listening on its sessions. A
|
|
14
|
+
* server's stream closes when its last listener leaves; a stream that drops reconnects with backoff.
|
|
15
|
+
*
|
|
16
|
+
* `subscribe()` only describes the request: the client connects when the stream is first iterated,
|
|
17
|
+
* and the server registers the subscriber some time after that. A stream is therefore open when its
|
|
18
|
+
* first event arrives, not when it was asked for — events a prompt causes before then would be lost
|
|
19
|
+
* (the catch-up recovers permissions and forms, not text, tools or the end of the execution).
|
|
20
|
+
*/
|
|
21
|
+
declare class OpenCodeEventHub {
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private readonly streams;
|
|
25
|
+
constructor(options?: {
|
|
26
|
+
connectTimeoutMs?: number;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Listen to one session's events on a server. Resolves once the server's stream is open (its first
|
|
30
|
+
* event arrived), or after the connect timeout — the turn's safety nets cover a stream that is
|
|
31
|
+
* slow to open.
|
|
32
|
+
*/
|
|
33
|
+
listen(serverKey: string, client: OpenCodeClient, sessionId: string, listener: Listener): Promise<() => void>;
|
|
34
|
+
close(): void;
|
|
35
|
+
/**
|
|
36
|
+
* The server's stream, opened on `client`. A different client for a known key (the host
|
|
37
|
+
* replaced the connection, e.g. a new sandbox under the same key) moves every listener to a stream
|
|
38
|
+
* on the new one: the old connection may be dead, and its sessions would never hear back.
|
|
39
|
+
*/
|
|
40
|
+
private streamFor;
|
|
41
|
+
private pump;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** An OpenCode form field as a stream-protocol question (`docs/stream-protocol.md`, *Asking the user*). */
|
|
45
|
+
declare function toQuestion(field: OpenCodeFormField): ElicitationQuestion;
|
|
46
|
+
/** The elicitation an OpenCode form streams as, under `id` (the tool-call id it is answered through). */
|
|
47
|
+
declare function toElicitation(id: string, form: OpenCodeForm): ElicitationRequest;
|
|
48
|
+
declare class FormAnswerError extends Error {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The protocol's answers (question id → canonical strings) as OpenCode's form reply: numbers as
|
|
52
|
+
* numbers, booleans as booleans, multiple choice as a list. Questions left out take their defaults;
|
|
53
|
+
* a value a question can't take throws {@link FormAnswerError}.
|
|
54
|
+
*/
|
|
55
|
+
declare function toFormAnswer(form: OpenCodeForm, answers?: Record<string, string[]>): Record<string, OpenCodeFormValue>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `POST <agent path>/opencode/mcp` — the endpoint the engine registers in every OpenCode session
|
|
59
|
+
* (`mcp.add`) when `tools` is set. It authenticates its callers itself (the bearer token the engine
|
|
60
|
+
* minted for the session), so the module's `guards` are not applied to it. Stateless: no
|
|
61
|
+
* server-sent stream to resume, no session to close.
|
|
62
|
+
*/
|
|
63
|
+
declare class OpenCodeMcpController {
|
|
64
|
+
private readonly endpoint;
|
|
65
|
+
constructor(endpoint: OpenCodeMcpEndpoint);
|
|
66
|
+
post(req: IncomingMessage, res: ServerResponse, body: unknown): Promise<void>;
|
|
67
|
+
get(res: ServerResponse): void;
|
|
68
|
+
delete(res: ServerResponse): void;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Runs OpenCode turns in this process: `begin → prompt → [observe → wait for a person → reply]* →
|
|
73
|
+
* settle`, with the waits on people held in memory. Like `InlineAgentRunner`, a run parked on a
|
|
74
|
+
* person lives in this process, so deploy it single-replica — or use `openCodeDurable()`
|
|
75
|
+
* (`@dudousxd/nestjs-agent-opencode/durable`), which checkpoints every step and waits on a durable
|
|
76
|
+
* signal.
|
|
77
|
+
*/
|
|
78
|
+
declare class OpenCodeAgentRunner implements AgentRunner {
|
|
79
|
+
private readonly turns;
|
|
80
|
+
private readonly settings;
|
|
81
|
+
private readonly live;
|
|
82
|
+
private readonly cancelled;
|
|
83
|
+
private readonly pending;
|
|
84
|
+
constructor(turns: OpenCodeTurns, settings: OpenCodeEngineSettings);
|
|
85
|
+
runIdFor(input: AgentRunInput): string;
|
|
86
|
+
isRunActive(runId: string): Promise<boolean>;
|
|
87
|
+
start(input: AgentRunInput, options?: AgentRunStartOptions): Promise<{
|
|
88
|
+
runId: string;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* Deliver a person's reply. Answers addressed at an approval are refused
|
|
92
|
+
* ({@link OpenCodeReplyMismatchError}, a 409) and the approval keeps waiting: they say nothing
|
|
93
|
+
* about whether the action should run.
|
|
94
|
+
*/
|
|
95
|
+
signal(runId: string, toolCallId: string, reply: HumanReply): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Stop the run: what it waits on a person for is dropped, and OpenCode is interrupted — it answers
|
|
98
|
+
* `session.execution.interrupted`, which settles the run as cancelled.
|
|
99
|
+
*/
|
|
100
|
+
cancel(runId: string): Promise<void>;
|
|
101
|
+
private readonly inputs;
|
|
102
|
+
private run;
|
|
103
|
+
/** Wait for a person's answer; a lapsed approval answers itself as expired. */
|
|
104
|
+
private park;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** The host's {@link import('./host.js').OpenCodeHost}. */
|
|
108
|
+
declare const OPENCODE_HOST: unique symbol;
|
|
109
|
+
/** Where each thread's session is kept ({@link import('./host.js').OpenCodeSessionStore}). */
|
|
110
|
+
declare const OPENCODE_SESSIONS: unique symbol;
|
|
111
|
+
/** The engine's {@link import('./turns.js').OpenCodeEngineSettings}. */
|
|
112
|
+
declare const OPENCODE_OPTIONS: unique symbol;
|
|
113
|
+
/**
|
|
114
|
+
* The engine's turn steps ({@link import('./turns.js').OpenCodeTurns}): `callContext` for the MCP
|
|
115
|
+
* surface, `pushToSession`, `liveRuns`. Inject this token, not the class — the class a host imports
|
|
116
|
+
* from the main bundle is not the one `openCodeDurable()` (`/durable`) registers.
|
|
117
|
+
*/
|
|
118
|
+
declare const OPENCODE_TURNS: unique symbol;
|
|
119
|
+
/** The engine's tools endpoint ({@link import('./mcp.js').OpenCodeMcpEndpoint}), when `tools` is set. */
|
|
120
|
+
declare const OPENCODE_MCP_ENDPOINT: unique symbol;
|
|
121
|
+
/** Mints and checks the tools endpoint's bearer tokens ({@link import('./mcp.js').OpenCodeToolsTokens}). */
|
|
122
|
+
declare const OPENCODE_TOOLS_TOKENS: unique symbol;
|
|
123
|
+
|
|
124
|
+
export { FormAnswerError, OPENCODE_HOST, OPENCODE_MCP_ENDPOINT, OPENCODE_OPTIONS, OPENCODE_SESSIONS, OPENCODE_TOOLS_TOKENS, OPENCODE_TURNS, OpenCodeAgentRunner, OpenCodeClient, OpenCodeEngineSettings, OpenCodeEvent, OpenCodeEventHub, OpenCodeForm, OpenCodeFormField, OpenCodeFormValue, OpenCodeMcpController, OpenCodeMcpEndpoint, OpenCodeTurns, sessionOf, toElicitation, toFormAnswer, toQuestion };
|