@di-code/coding-agent 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/dist/cli.d.ts +26 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +117 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/models-loader.d.ts +4 -0
- package/dist/config/models-loader.d.ts.map +1 -0
- package/dist/config/models-loader.js +134 -0
- package/dist/config/models-loader.js.map +1 -0
- package/dist/config/models-types.d.ts +23 -0
- package/dist/config/models-types.d.ts.map +1 -0
- package/dist/config/models-types.js +2 -0
- package/dist/config/models-types.js.map +1 -0
- package/dist/config/settings-loader.d.ts +3 -0
- package/dist/config/settings-loader.d.ts.map +1 -0
- package/dist/config/settings-loader.js +130 -0
- package/dist/config/settings-loader.js.map +1 -0
- package/dist/config/settings-types.d.ts +21 -0
- package/dist/config/settings-types.d.ts.map +1 -0
- package/dist/config/settings-types.js +2 -0
- package/dist/config/settings-types.js.map +1 -0
- package/dist/core/context-builder.d.ts +8 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +46 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/model-catalog-store.d.ts +8 -0
- package/dist/core/model-catalog-store.d.ts.map +1 -0
- package/dist/core/model-catalog-store.js +68 -0
- package/dist/core/model-catalog-store.js.map +1 -0
- package/dist/core/model-composer.d.ts +4 -0
- package/dist/core/model-composer.d.ts.map +1 -0
- package/dist/core/model-composer.js +37 -0
- package/dist/core/model-composer.js.map +1 -0
- package/dist/core/session/session-manager.d.ts +44 -0
- package/dist/core/session/session-manager.d.ts.map +1 -0
- package/dist/core/session/session-manager.js +138 -0
- package/dist/core/session/session-manager.js.map +1 -0
- package/dist/core/session/session-storage.d.ts +11 -0
- package/dist/core/session/session-storage.d.ts.map +1 -0
- package/dist/core/session/session-storage.js +382 -0
- package/dist/core/session/session-storage.js.map +1 -0
- package/dist/core/session/types.d.ts +65 -0
- package/dist/core/session/types.d.ts.map +1 -0
- package/dist/core/session/types.js +28 -0
- package/dist/core/session/types.js.map +1 -0
- package/dist/core/session.d.ts +80 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +262 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/tools/bash.d.ts +39 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +208 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/edit.d.ts +18 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +107 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +2 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +24 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/path-boundary.d.ts +3 -0
- package/dist/core/tools/path-boundary.d.ts.map +1 -0
- package/dist/core/tools/path-boundary.js +62 -0
- package/dist/core/tools/path-boundary.js.map +1 -0
- package/dist/core/tools/read.d.ts +17 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +132 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/write.d.ts +17 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +45 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/entry.d.ts +3 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +27 -0
- package/dist/entry.js.map +1 -0
- package/dist/extensions/index.d.ts +5 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +3 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/runtime.d.ts +46 -0
- package/dist/extensions/runtime.d.ts.map +1 -0
- package/dist/extensions/runtime.js +179 -0
- package/dist/extensions/runtime.js.map +1 -0
- package/dist/extensions/trust.d.ts +8 -0
- package/dist/extensions/trust.d.ts.map +1 -0
- package/dist/extensions/trust.js +59 -0
- package/dist/extensions/trust.js.map +1 -0
- package/dist/extensions/types.d.ts +46 -0
- package/dist/extensions/types.d.ts.map +1 -0
- package/dist/extensions/types.js +2 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +19 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +198 -0
- package/dist/main.js.map +1 -0
- package/dist/modes/interactive-components.d.ts +41 -0
- package/dist/modes/interactive-components.d.ts.map +1 -0
- package/dist/modes/interactive-components.js +195 -0
- package/dist/modes/interactive-components.js.map +1 -0
- package/dist/modes/interactive-layout.d.ts +20 -0
- package/dist/modes/interactive-layout.d.ts.map +1 -0
- package/dist/modes/interactive-layout.js +34 -0
- package/dist/modes/interactive-layout.js.map +1 -0
- package/dist/modes/interactive-state.d.ts +61 -0
- package/dist/modes/interactive-state.d.ts.map +1 -0
- package/dist/modes/interactive-state.js +201 -0
- package/dist/modes/interactive-state.js.map +1 -0
- package/dist/modes/interactive.d.ts +61 -0
- package/dist/modes/interactive.d.ts.map +1 -0
- package/dist/modes/interactive.js +436 -0
- package/dist/modes/interactive.js.map +1 -0
- package/dist/modes/json.d.ts +14 -0
- package/dist/modes/json.d.ts.map +1 -0
- package/dist/modes/json.js +26 -0
- package/dist/modes/json.js.map +1 -0
- package/dist/modes/print.d.ts +10 -0
- package/dist/modes/print.d.ts.map +1 -0
- package/dist/modes/print.js +28 -0
- package/dist/modes/print.js.map +1 -0
- package/dist/provider-onboarding.d.ts +13 -0
- package/dist/provider-onboarding.d.ts.map +1 -0
- package/dist/provider-onboarding.js +162 -0
- package/dist/provider-onboarding.js.map +1 -0
- package/dist/rpc/client.d.ts +38 -0
- package/dist/rpc/client.d.ts.map +1 -0
- package/dist/rpc/client.js +153 -0
- package/dist/rpc/client.js.map +1 -0
- package/dist/rpc/index.d.ts +5 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +5 -0
- package/dist/rpc/index.js.map +1 -0
- package/dist/rpc/jsonl.d.ts +17 -0
- package/dist/rpc/jsonl.d.ts.map +1 -0
- package/dist/rpc/jsonl.js +52 -0
- package/dist/rpc/jsonl.js.map +1 -0
- package/dist/rpc/protocol.d.ts +80 -0
- package/dist/rpc/protocol.d.ts.map +1 -0
- package/dist/rpc/protocol.js +231 -0
- package/dist/rpc/protocol.js.map +1 -0
- package/dist/rpc/server.d.ts +41 -0
- package/dist/rpc/server.d.ts.map +1 -0
- package/dist/rpc/server.js +186 -0
- package/dist/rpc/server.js.map +1 -0
- package/dist/rpc-entry.d.ts +3 -0
- package/dist/rpc-entry.d.ts.map +1 -0
- package/dist/rpc-entry.js +28 -0
- package/dist/rpc-entry.js.map +1 -0
- package/dist/startup.d.ts +24 -0
- package/dist/startup.d.ts.map +1 -0
- package/dist/startup.js +227 -0
- package/dist/startup.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
export const RPC_PROTOCOL_VERSION = 1;
|
|
2
|
+
export const RPC_MAX_ID_LENGTH = 128;
|
|
3
|
+
export const RPC_MAX_PROMPT_LENGTH = 1_000_000;
|
|
4
|
+
const RPC_ERROR_CODES = new Set([
|
|
5
|
+
"PARSE_ERROR",
|
|
6
|
+
"INVALID_REQUEST",
|
|
7
|
+
"UNSUPPORTED_VERSION",
|
|
8
|
+
"METHOD_NOT_FOUND",
|
|
9
|
+
"INVALID_PARAMS",
|
|
10
|
+
"BUSY",
|
|
11
|
+
"NOT_FOUND",
|
|
12
|
+
"CANCELLED",
|
|
13
|
+
"INTERNAL_ERROR",
|
|
14
|
+
"PROCESS_EXIT",
|
|
15
|
+
]);
|
|
16
|
+
const RPC_EVENT_TYPES = new Set([
|
|
17
|
+
"agent_start",
|
|
18
|
+
"turn_start",
|
|
19
|
+
"message_start",
|
|
20
|
+
"message_update",
|
|
21
|
+
"message_end",
|
|
22
|
+
"turn_end",
|
|
23
|
+
"tool_execution_start",
|
|
24
|
+
"tool_execution_end",
|
|
25
|
+
"agent_end",
|
|
26
|
+
"compaction_start",
|
|
27
|
+
"compaction_end",
|
|
28
|
+
"usage_update",
|
|
29
|
+
]);
|
|
30
|
+
const ASSISTANT_STOP_REASONS = new Set(["stop", "length", "tool_use", "error", "aborted"]);
|
|
31
|
+
export class RpcProtocolError extends Error {
|
|
32
|
+
code;
|
|
33
|
+
requestId;
|
|
34
|
+
constructor(code, message, requestId) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = "RpcProtocolError";
|
|
37
|
+
this.code = code;
|
|
38
|
+
this.requestId = requestId;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function objectRecord(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
43
|
+
? value
|
|
44
|
+
: undefined;
|
|
45
|
+
}
|
|
46
|
+
function requiredId(value, field, requestId) {
|
|
47
|
+
if (typeof value !== "string" || value.length === 0 || value.length > RPC_MAX_ID_LENGTH) {
|
|
48
|
+
throw new RpcProtocolError("INVALID_REQUEST", `${field} must be a non-empty string of at most ${RPC_MAX_ID_LENGTH} characters.`, requestId);
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
function parseJsonObject(line) {
|
|
53
|
+
let value;
|
|
54
|
+
try {
|
|
55
|
+
value = JSON.parse(line);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw new RpcProtocolError("PARSE_ERROR", "RPC input must be valid JSON.");
|
|
59
|
+
}
|
|
60
|
+
const record = objectRecord(value);
|
|
61
|
+
if (!record)
|
|
62
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC input must be a JSON object.");
|
|
63
|
+
return record;
|
|
64
|
+
}
|
|
65
|
+
function assertVersion(record, requestId) {
|
|
66
|
+
if (record.version !== RPC_PROTOCOL_VERSION) {
|
|
67
|
+
throw new RpcProtocolError("UNSUPPORTED_VERSION", `Unsupported RPC protocol version; expected ${RPC_PROTOCOL_VERSION}.`, requestId);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function parseRpcRequest(line) {
|
|
71
|
+
const record = parseJsonObject(line);
|
|
72
|
+
const candidateId = typeof record.id === "string" ? record.id : undefined;
|
|
73
|
+
assertVersion(record, candidateId);
|
|
74
|
+
if (record.kind !== "request") {
|
|
75
|
+
throw new RpcProtocolError("INVALID_REQUEST", 'RPC request kind must be "request".', candidateId);
|
|
76
|
+
}
|
|
77
|
+
const id = requiredId(record.id, "id", candidateId);
|
|
78
|
+
const params = objectRecord(record.params);
|
|
79
|
+
if (!params)
|
|
80
|
+
throw new RpcProtocolError("INVALID_PARAMS", "RPC params must be an object.", id);
|
|
81
|
+
switch (record.method) {
|
|
82
|
+
case "prompt": {
|
|
83
|
+
const message = params.message;
|
|
84
|
+
if (typeof message !== "string" || message.trim().length === 0 || message.length > RPC_MAX_PROMPT_LENGTH) {
|
|
85
|
+
throw new RpcProtocolError("INVALID_PARAMS", `prompt.message must be non-empty and at most ${RPC_MAX_PROMPT_LENGTH} characters.`, id);
|
|
86
|
+
}
|
|
87
|
+
return { version: RPC_PROTOCOL_VERSION, kind: "request", id, method: "prompt", params: { message } };
|
|
88
|
+
}
|
|
89
|
+
case "cancel":
|
|
90
|
+
return {
|
|
91
|
+
version: RPC_PROTOCOL_VERSION,
|
|
92
|
+
kind: "request",
|
|
93
|
+
id,
|
|
94
|
+
method: "cancel",
|
|
95
|
+
params: { requestId: requiredId(params.requestId, "cancel.requestId", id) },
|
|
96
|
+
};
|
|
97
|
+
case "get_state":
|
|
98
|
+
return { version: RPC_PROTOCOL_VERSION, kind: "request", id, method: "get_state", params: {} };
|
|
99
|
+
default:
|
|
100
|
+
throw new RpcProtocolError("METHOD_NOT_FOUND", "Unknown RPC method.", id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function parseRpcServerMessage(line) {
|
|
104
|
+
const record = parseJsonObject(line);
|
|
105
|
+
assertVersion(record);
|
|
106
|
+
if (record.kind === "event") {
|
|
107
|
+
requiredId(record.requestId, "requestId");
|
|
108
|
+
const event = objectRecord(record.event);
|
|
109
|
+
if (!event || typeof event.type !== "string" || !RPC_EVENT_TYPES.has(event.type)) {
|
|
110
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC event must contain a typed event object.");
|
|
111
|
+
}
|
|
112
|
+
return record;
|
|
113
|
+
}
|
|
114
|
+
if (record.kind !== "response") {
|
|
115
|
+
throw new RpcProtocolError("INVALID_REQUEST", 'RPC server message kind must be "response" or "event".');
|
|
116
|
+
}
|
|
117
|
+
if (record.ok === false) {
|
|
118
|
+
const error = objectRecord(record.error);
|
|
119
|
+
if (!error ||
|
|
120
|
+
typeof error.code !== "string" ||
|
|
121
|
+
!RPC_ERROR_CODES.has(error.code) ||
|
|
122
|
+
typeof error.message !== "string") {
|
|
123
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC error response has an invalid error object.");
|
|
124
|
+
}
|
|
125
|
+
if (record.id !== undefined)
|
|
126
|
+
requiredId(record.id, "id");
|
|
127
|
+
return record;
|
|
128
|
+
}
|
|
129
|
+
if (record.ok !== true)
|
|
130
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC response ok must be a boolean.");
|
|
131
|
+
requiredId(record.id, "id");
|
|
132
|
+
const result = objectRecord(record.result);
|
|
133
|
+
if (!result) {
|
|
134
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC success response must contain a result object.");
|
|
135
|
+
}
|
|
136
|
+
assertSuccessResult(result);
|
|
137
|
+
return record;
|
|
138
|
+
}
|
|
139
|
+
function assertSuccessResult(result) {
|
|
140
|
+
switch (result.method) {
|
|
141
|
+
case "prompt": {
|
|
142
|
+
const message = objectRecord(result.message);
|
|
143
|
+
if (!message ||
|
|
144
|
+
message.role !== "assistant" ||
|
|
145
|
+
!Array.isArray(message.content) ||
|
|
146
|
+
!message.content.every(isAssistantContent) ||
|
|
147
|
+
typeof message.provider !== "string" ||
|
|
148
|
+
typeof message.model !== "string" ||
|
|
149
|
+
!finiteNumber(message.timestamp) ||
|
|
150
|
+
typeof message.stopReason !== "string" ||
|
|
151
|
+
!ASSISTANT_STOP_REASONS.has(message.stopReason) ||
|
|
152
|
+
!isUsage(message.usage) ||
|
|
153
|
+
(message.stopReason === "error" || message.stopReason === "aborted"
|
|
154
|
+
? typeof message.errorMessage !== "string"
|
|
155
|
+
: message.errorMessage !== undefined)) {
|
|
156
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC prompt response has an invalid message.");
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
case "cancel":
|
|
161
|
+
if (typeof result.cancelled !== "boolean") {
|
|
162
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC cancel response has an invalid result.");
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
case "get_state": {
|
|
166
|
+
const state = objectRecord(result.state);
|
|
167
|
+
if (!state ||
|
|
168
|
+
typeof state.sessionId !== "string" ||
|
|
169
|
+
state.sessionId.length === 0 ||
|
|
170
|
+
typeof state.modelId !== "string" ||
|
|
171
|
+
state.modelId.length === 0 ||
|
|
172
|
+
typeof state.isStreaming !== "boolean" ||
|
|
173
|
+
!Number.isInteger(state.messageCount) ||
|
|
174
|
+
state.messageCount < 0) {
|
|
175
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC get_state response has an invalid state.");
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
default:
|
|
180
|
+
throw new RpcProtocolError("INVALID_REQUEST", "RPC success response has an unknown method.");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function finiteNumber(value) {
|
|
184
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
185
|
+
}
|
|
186
|
+
function nonNegativeNumber(value) {
|
|
187
|
+
return finiteNumber(value) && value >= 0;
|
|
188
|
+
}
|
|
189
|
+
function isAssistantContent(value) {
|
|
190
|
+
const content = objectRecord(value);
|
|
191
|
+
if (!content)
|
|
192
|
+
return false;
|
|
193
|
+
switch (content.type) {
|
|
194
|
+
case "text":
|
|
195
|
+
return typeof content.text === "string";
|
|
196
|
+
case "thinking":
|
|
197
|
+
return typeof content.thinking === "string";
|
|
198
|
+
case "tool_call":
|
|
199
|
+
return (typeof content.id === "string" &&
|
|
200
|
+
typeof content.name === "string" &&
|
|
201
|
+
objectRecord(content.arguments) !== undefined);
|
|
202
|
+
default:
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function isUsage(value) {
|
|
207
|
+
const usage = objectRecord(value);
|
|
208
|
+
const cost = objectRecord(usage?.cost);
|
|
209
|
+
return Boolean(usage &&
|
|
210
|
+
cost &&
|
|
211
|
+
nonNegativeNumber(usage.input) &&
|
|
212
|
+
nonNegativeNumber(usage.output) &&
|
|
213
|
+
nonNegativeNumber(usage.cacheRead) &&
|
|
214
|
+
nonNegativeNumber(usage.cacheWrite) &&
|
|
215
|
+
nonNegativeNumber(usage.totalTokens) &&
|
|
216
|
+
nonNegativeNumber(cost.input) &&
|
|
217
|
+
nonNegativeNumber(cost.output) &&
|
|
218
|
+
nonNegativeNumber(cost.cacheRead) &&
|
|
219
|
+
nonNegativeNumber(cost.cacheWrite) &&
|
|
220
|
+
nonNegativeNumber(cost.total));
|
|
221
|
+
}
|
|
222
|
+
export function rpcErrorResponse(error) {
|
|
223
|
+
return {
|
|
224
|
+
version: RPC_PROTOCOL_VERSION,
|
|
225
|
+
kind: "response",
|
|
226
|
+
...(error.requestId === undefined ? {} : { id: error.requestId }),
|
|
227
|
+
ok: false,
|
|
228
|
+
error: { code: error.code, message: error.message },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/rpc/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@di-code/ai\";\nimport type { AgentSessionEvent } from \"../core/session.ts\";\n\nexport const RPC_PROTOCOL_VERSION = 1 as const;\nexport const RPC_MAX_ID_LENGTH = 128;\nexport const RPC_MAX_PROMPT_LENGTH = 1_000_000;\n\nexport type RpcMethod = \"prompt\" | \"cancel\" | \"get_state\";\n\nexport type RpcRequest =\n\t| {\n\t\t\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\t\t\treadonly kind: \"request\";\n\t\t\treadonly id: string;\n\t\t\treadonly method: \"prompt\";\n\t\t\treadonly params: { readonly message: string };\n\t }\n\t| {\n\t\t\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\t\t\treadonly kind: \"request\";\n\t\t\treadonly id: string;\n\t\t\treadonly method: \"cancel\";\n\t\t\treadonly params: { readonly requestId: string };\n\t }\n\t| {\n\t\t\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\t\t\treadonly kind: \"request\";\n\t\t\treadonly id: string;\n\t\t\treadonly method: \"get_state\";\n\t\t\treadonly params: Record<string, never>;\n\t };\n\nexport interface RpcSessionState {\n\treadonly sessionId: string;\n\treadonly modelId: string;\n\treadonly isStreaming: boolean;\n\treadonly messageCount: number;\n}\n\nexport type RpcSuccessResult =\n\t| { readonly method: \"prompt\"; readonly message: AssistantMessage }\n\t| { readonly method: \"cancel\"; readonly cancelled: boolean }\n\t| { readonly method: \"get_state\"; readonly state: RpcSessionState };\n\nexport type RpcErrorCode =\n\t| \"PARSE_ERROR\"\n\t| \"INVALID_REQUEST\"\n\t| \"UNSUPPORTED_VERSION\"\n\t| \"METHOD_NOT_FOUND\"\n\t| \"INVALID_PARAMS\"\n\t| \"BUSY\"\n\t| \"NOT_FOUND\"\n\t| \"CANCELLED\"\n\t| \"INTERNAL_ERROR\"\n\t| \"PROCESS_EXIT\";\n\nconst RPC_ERROR_CODES: ReadonlySet<RpcErrorCode> = new Set([\n\t\"PARSE_ERROR\",\n\t\"INVALID_REQUEST\",\n\t\"UNSUPPORTED_VERSION\",\n\t\"METHOD_NOT_FOUND\",\n\t\"INVALID_PARAMS\",\n\t\"BUSY\",\n\t\"NOT_FOUND\",\n\t\"CANCELLED\",\n\t\"INTERNAL_ERROR\",\n\t\"PROCESS_EXIT\",\n]);\n\nconst RPC_EVENT_TYPES: ReadonlySet<AgentSessionEvent[\"type\"]> = new Set([\n\t\"agent_start\",\n\t\"turn_start\",\n\t\"message_start\",\n\t\"message_update\",\n\t\"message_end\",\n\t\"turn_end\",\n\t\"tool_execution_start\",\n\t\"tool_execution_end\",\n\t\"agent_end\",\n\t\"compaction_start\",\n\t\"compaction_end\",\n\t\"usage_update\",\n]);\n\nconst ASSISTANT_STOP_REASONS = new Set([\"stop\", \"length\", \"tool_use\", \"error\", \"aborted\"]);\n\nexport interface RpcSuccessResponse {\n\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\treadonly kind: \"response\";\n\treadonly id: string;\n\treadonly ok: true;\n\treadonly result: RpcSuccessResult;\n}\n\nexport interface RpcErrorResponse {\n\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\treadonly kind: \"response\";\n\treadonly id?: string;\n\treadonly ok: false;\n\treadonly error: { readonly code: RpcErrorCode; readonly message: string };\n}\n\nexport interface RpcEventRecord {\n\treadonly version: typeof RPC_PROTOCOL_VERSION;\n\treadonly kind: \"event\";\n\treadonly requestId: string;\n\treadonly event: AgentSessionEvent;\n}\n\nexport type RpcResponse = RpcSuccessResponse | RpcErrorResponse;\nexport type RpcServerMessage = RpcResponse | RpcEventRecord;\n\nexport class RpcProtocolError extends Error {\n\treadonly code: RpcErrorCode;\n\treadonly requestId?: string;\n\n\tconstructor(code: RpcErrorCode, message: string, requestId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RpcProtocolError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\nfunction objectRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction requiredId(value: unknown, field: string, requestId?: string): string {\n\tif (typeof value !== \"string\" || value.length === 0 || value.length > RPC_MAX_ID_LENGTH) {\n\t\tthrow new RpcProtocolError(\n\t\t\t\"INVALID_REQUEST\",\n\t\t\t`${field} must be a non-empty string of at most ${RPC_MAX_ID_LENGTH} characters.`,\n\t\t\trequestId,\n\t\t);\n\t}\n\treturn value;\n}\n\nfunction parseJsonObject(line: string): Record<string, unknown> {\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(line);\n\t} catch {\n\t\tthrow new RpcProtocolError(\"PARSE_ERROR\", \"RPC input must be valid JSON.\");\n\t}\n\tconst record = objectRecord(value);\n\tif (!record) throw new RpcProtocolError(\"INVALID_REQUEST\", \"RPC input must be a JSON object.\");\n\treturn record;\n}\n\nfunction assertVersion(record: Record<string, unknown>, requestId?: string): void {\n\tif (record.version !== RPC_PROTOCOL_VERSION) {\n\t\tthrow new RpcProtocolError(\n\t\t\t\"UNSUPPORTED_VERSION\",\n\t\t\t`Unsupported RPC protocol version; expected ${RPC_PROTOCOL_VERSION}.`,\n\t\t\trequestId,\n\t\t);\n\t}\n}\n\nexport function parseRpcRequest(line: string): RpcRequest {\n\tconst record = parseJsonObject(line);\n\tconst candidateId = typeof record.id === \"string\" ? record.id : undefined;\n\tassertVersion(record, candidateId);\n\tif (record.kind !== \"request\") {\n\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", 'RPC request kind must be \"request\".', candidateId);\n\t}\n\tconst id = requiredId(record.id, \"id\", candidateId);\n\tconst params = objectRecord(record.params);\n\tif (!params) throw new RpcProtocolError(\"INVALID_PARAMS\", \"RPC params must be an object.\", id);\n\n\tswitch (record.method) {\n\t\tcase \"prompt\": {\n\t\t\tconst message = params.message;\n\t\t\tif (typeof message !== \"string\" || message.trim().length === 0 || message.length > RPC_MAX_PROMPT_LENGTH) {\n\t\t\t\tthrow new RpcProtocolError(\n\t\t\t\t\t\"INVALID_PARAMS\",\n\t\t\t\t\t`prompt.message must be non-empty and at most ${RPC_MAX_PROMPT_LENGTH} characters.`,\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { version: RPC_PROTOCOL_VERSION, kind: \"request\", id, method: \"prompt\", params: { message } };\n\t\t}\n\t\tcase \"cancel\":\n\t\t\treturn {\n\t\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\t\tkind: \"request\",\n\t\t\t\tid,\n\t\t\t\tmethod: \"cancel\",\n\t\t\t\tparams: { requestId: requiredId(params.requestId, \"cancel.requestId\", id) },\n\t\t\t};\n\t\tcase \"get_state\":\n\t\t\treturn { version: RPC_PROTOCOL_VERSION, kind: \"request\", id, method: \"get_state\", params: {} };\n\t\tdefault:\n\t\t\tthrow new RpcProtocolError(\"METHOD_NOT_FOUND\", \"Unknown RPC method.\", id);\n\t}\n}\n\nexport function parseRpcServerMessage(line: string): RpcServerMessage {\n\tconst record = parseJsonObject(line);\n\tassertVersion(record);\n\tif (record.kind === \"event\") {\n\t\trequiredId(record.requestId, \"requestId\");\n\t\tconst event = objectRecord(record.event);\n\t\tif (!event || typeof event.type !== \"string\" || !RPC_EVENT_TYPES.has(event.type as AgentSessionEvent[\"type\"])) {\n\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC event must contain a typed event object.\");\n\t\t}\n\t\treturn record as unknown as RpcEventRecord;\n\t}\n\tif (record.kind !== \"response\") {\n\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", 'RPC server message kind must be \"response\" or \"event\".');\n\t}\n\tif (record.ok === false) {\n\t\tconst error = objectRecord(record.error);\n\t\tif (\n\t\t\t!error ||\n\t\t\ttypeof error.code !== \"string\" ||\n\t\t\t!RPC_ERROR_CODES.has(error.code as RpcErrorCode) ||\n\t\t\ttypeof error.message !== \"string\"\n\t\t) {\n\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC error response has an invalid error object.\");\n\t\t}\n\t\tif (record.id !== undefined) requiredId(record.id, \"id\");\n\t\treturn record as unknown as RpcErrorResponse;\n\t}\n\tif (record.ok !== true) throw new RpcProtocolError(\"INVALID_REQUEST\", \"RPC response ok must be a boolean.\");\n\trequiredId(record.id, \"id\");\n\tconst result = objectRecord(record.result);\n\tif (!result) {\n\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC success response must contain a result object.\");\n\t}\n\tassertSuccessResult(result);\n\treturn record as unknown as RpcSuccessResponse;\n}\n\nfunction assertSuccessResult(result: Record<string, unknown>): void {\n\tswitch (result.method) {\n\t\tcase \"prompt\": {\n\t\t\tconst message = objectRecord(result.message);\n\t\t\tif (\n\t\t\t\t!message ||\n\t\t\t\tmessage.role !== \"assistant\" ||\n\t\t\t\t!Array.isArray(message.content) ||\n\t\t\t\t!message.content.every(isAssistantContent) ||\n\t\t\t\ttypeof message.provider !== \"string\" ||\n\t\t\t\ttypeof message.model !== \"string\" ||\n\t\t\t\t!finiteNumber(message.timestamp) ||\n\t\t\t\ttypeof message.stopReason !== \"string\" ||\n\t\t\t\t!ASSISTANT_STOP_REASONS.has(message.stopReason) ||\n\t\t\t\t!isUsage(message.usage) ||\n\t\t\t\t(message.stopReason === \"error\" || message.stopReason === \"aborted\"\n\t\t\t\t\t? typeof message.errorMessage !== \"string\"\n\t\t\t\t\t: message.errorMessage !== undefined)\n\t\t\t) {\n\t\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC prompt response has an invalid message.\");\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tcase \"cancel\":\n\t\t\tif (typeof result.cancelled !== \"boolean\") {\n\t\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC cancel response has an invalid result.\");\n\t\t\t}\n\t\t\treturn;\n\t\tcase \"get_state\": {\n\t\t\tconst state = objectRecord(result.state);\n\t\t\tif (\n\t\t\t\t!state ||\n\t\t\t\ttypeof state.sessionId !== \"string\" ||\n\t\t\t\tstate.sessionId.length === 0 ||\n\t\t\t\ttypeof state.modelId !== \"string\" ||\n\t\t\t\tstate.modelId.length === 0 ||\n\t\t\t\ttypeof state.isStreaming !== \"boolean\" ||\n\t\t\t\t!Number.isInteger(state.messageCount) ||\n\t\t\t\t(state.messageCount as number) < 0\n\t\t\t) {\n\t\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC get_state response has an invalid state.\");\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault:\n\t\t\tthrow new RpcProtocolError(\"INVALID_REQUEST\", \"RPC success response has an unknown method.\");\n\t}\n}\n\nfunction finiteNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction nonNegativeNumber(value: unknown): value is number {\n\treturn finiteNumber(value) && value >= 0;\n}\n\nfunction isAssistantContent(value: unknown): boolean {\n\tconst content = objectRecord(value);\n\tif (!content) return false;\n\tswitch (content.type) {\n\t\tcase \"text\":\n\t\t\treturn typeof content.text === \"string\";\n\t\tcase \"thinking\":\n\t\t\treturn typeof content.thinking === \"string\";\n\t\tcase \"tool_call\":\n\t\t\treturn (\n\t\t\t\ttypeof content.id === \"string\" &&\n\t\t\t\ttypeof content.name === \"string\" &&\n\t\t\t\tobjectRecord(content.arguments) !== undefined\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction isUsage(value: unknown): boolean {\n\tconst usage = objectRecord(value);\n\tconst cost = objectRecord(usage?.cost);\n\treturn Boolean(\n\t\tusage &&\n\t\t\tcost &&\n\t\t\tnonNegativeNumber(usage.input) &&\n\t\t\tnonNegativeNumber(usage.output) &&\n\t\t\tnonNegativeNumber(usage.cacheRead) &&\n\t\t\tnonNegativeNumber(usage.cacheWrite) &&\n\t\t\tnonNegativeNumber(usage.totalTokens) &&\n\t\t\tnonNegativeNumber(cost.input) &&\n\t\t\tnonNegativeNumber(cost.output) &&\n\t\t\tnonNegativeNumber(cost.cacheRead) &&\n\t\t\tnonNegativeNumber(cost.cacheWrite) &&\n\t\t\tnonNegativeNumber(cost.total),\n\t);\n}\n\nexport function rpcErrorResponse(error: RpcProtocolError): RpcErrorResponse {\n\treturn {\n\t\tversion: RPC_PROTOCOL_VERSION,\n\t\tkind: \"response\",\n\t\t...(error.requestId === undefined ? {} : { id: error.requestId }),\n\t\tok: false,\n\t\terror: { code: error.code, message: error.message },\n\t};\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
import type { AssistantMessage, Message } from "@di-code/ai";
|
|
3
|
+
import type { AgentSessionListener } from "../core/session.ts";
|
|
4
|
+
export interface RpcSession {
|
|
5
|
+
readonly sessionId: string;
|
|
6
|
+
readonly modelId: string;
|
|
7
|
+
readonly isStreaming: boolean;
|
|
8
|
+
readonly transcript: readonly Message[];
|
|
9
|
+
prompt(text: string, signal?: AbortSignal): Promise<AssistantMessage>;
|
|
10
|
+
subscribeSession(listener: AgentSessionListener): () => void;
|
|
11
|
+
}
|
|
12
|
+
export interface RpcServerOptions {
|
|
13
|
+
readonly session: RpcSession;
|
|
14
|
+
readonly input: Readable;
|
|
15
|
+
readonly output: Writable;
|
|
16
|
+
readonly onError?: (error: Error) => void;
|
|
17
|
+
readonly maxLineBytes?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class RpcServer {
|
|
20
|
+
private readonly session;
|
|
21
|
+
private readonly input;
|
|
22
|
+
private readonly output;
|
|
23
|
+
private readonly onError;
|
|
24
|
+
private readonly decoder;
|
|
25
|
+
private readonly inFlightIds;
|
|
26
|
+
private activePrompt?;
|
|
27
|
+
private unsubscribeSession?;
|
|
28
|
+
private started;
|
|
29
|
+
constructor(options: RpcServerOptions);
|
|
30
|
+
start(): void;
|
|
31
|
+
stop(): void;
|
|
32
|
+
private readonly handleData;
|
|
33
|
+
private readonly handleEnd;
|
|
34
|
+
private readonly handleInputError;
|
|
35
|
+
private acceptLine;
|
|
36
|
+
private handleRequest;
|
|
37
|
+
private handlePrompt;
|
|
38
|
+
private writeError;
|
|
39
|
+
private write;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/rpc/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAY/D,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtE,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAWD,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,kBAAkB,CAAC,CAAa;IACxC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,gBAAgB;IAUrC,KAAK,IAAI,IAAI;IAkBb,IAAI,IAAI,IAAI;IAWZ,OAAO,CAAC,QAAQ,CAAC,UAAU,CASzB;IAEF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAOxB;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG/B;IAEF,OAAO,CAAC,UAAU;YAuBJ,aAAa;YAqCb,YAAY;IA8B1B,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,KAAK;CAQb"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { JsonlLineDecoder, serializeJsonLine } from "./jsonl.js";
|
|
2
|
+
import { parseRpcRequest, RPC_PROTOCOL_VERSION, RpcProtocolError, rpcErrorResponse, } from "./protocol.js";
|
|
3
|
+
function errorFrom(cause) {
|
|
4
|
+
return cause instanceof Error ? cause : new Error(String(cause));
|
|
5
|
+
}
|
|
6
|
+
export class RpcServer {
|
|
7
|
+
session;
|
|
8
|
+
input;
|
|
9
|
+
output;
|
|
10
|
+
onError;
|
|
11
|
+
decoder;
|
|
12
|
+
inFlightIds = new Set();
|
|
13
|
+
activePrompt;
|
|
14
|
+
unsubscribeSession;
|
|
15
|
+
started = false;
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.session = options.session;
|
|
18
|
+
this.input = options.input;
|
|
19
|
+
this.output = options.output;
|
|
20
|
+
this.onError = options.onError ?? (() => undefined);
|
|
21
|
+
this.decoder = new JsonlLineDecoder((line) => this.acceptLine(line), {
|
|
22
|
+
maxLineBytes: options.maxLineBytes,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
start() {
|
|
26
|
+
if (this.started)
|
|
27
|
+
throw new Error("RPC server is already started.");
|
|
28
|
+
this.started = true;
|
|
29
|
+
this.unsubscribeSession = this.session.subscribeSession(async (event) => {
|
|
30
|
+
const active = this.activePrompt;
|
|
31
|
+
if (!active)
|
|
32
|
+
return;
|
|
33
|
+
await this.write({
|
|
34
|
+
version: RPC_PROTOCOL_VERSION,
|
|
35
|
+
kind: "event",
|
|
36
|
+
requestId: active.requestId,
|
|
37
|
+
event,
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
this.input.on("data", this.handleData);
|
|
41
|
+
this.input.once("end", this.handleEnd);
|
|
42
|
+
this.input.once("error", this.handleInputError);
|
|
43
|
+
}
|
|
44
|
+
stop() {
|
|
45
|
+
if (!this.started)
|
|
46
|
+
return;
|
|
47
|
+
this.started = false;
|
|
48
|
+
this.input.off("data", this.handleData);
|
|
49
|
+
this.input.off("end", this.handleEnd);
|
|
50
|
+
this.input.off("error", this.handleInputError);
|
|
51
|
+
this.unsubscribeSession?.();
|
|
52
|
+
this.unsubscribeSession = undefined;
|
|
53
|
+
this.activePrompt?.controller.abort();
|
|
54
|
+
}
|
|
55
|
+
handleData = (chunk) => {
|
|
56
|
+
try {
|
|
57
|
+
this.decoder.push(chunk);
|
|
58
|
+
}
|
|
59
|
+
catch (cause) {
|
|
60
|
+
const error = errorFrom(cause);
|
|
61
|
+
this.onError(error);
|
|
62
|
+
void this.writeError(undefined, "INVALID_REQUEST", error.message);
|
|
63
|
+
this.stop();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
handleEnd = () => {
|
|
67
|
+
try {
|
|
68
|
+
this.decoder.end();
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
this.onError(errorFrom(cause));
|
|
72
|
+
}
|
|
73
|
+
this.stop();
|
|
74
|
+
};
|
|
75
|
+
handleInputError = (cause) => {
|
|
76
|
+
this.onError(cause);
|
|
77
|
+
this.stop();
|
|
78
|
+
};
|
|
79
|
+
acceptLine(line) {
|
|
80
|
+
let request;
|
|
81
|
+
try {
|
|
82
|
+
request = parseRpcRequest(line);
|
|
83
|
+
}
|
|
84
|
+
catch (cause) {
|
|
85
|
+
const protocolError = cause instanceof RpcProtocolError
|
|
86
|
+
? cause
|
|
87
|
+
: new RpcProtocolError("INVALID_REQUEST", "RPC request validation failed.");
|
|
88
|
+
void this.write(rpcErrorResponse(protocolError)).catch(this.onError);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (this.inFlightIds.has(request.id)) {
|
|
92
|
+
void this.writeError(request.id, "INVALID_REQUEST", "RPC request id is already in flight.");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.inFlightIds.add(request.id);
|
|
96
|
+
void this.handleRequest(request)
|
|
97
|
+
.catch((cause) => this.onError(errorFrom(cause)))
|
|
98
|
+
.finally(() => this.inFlightIds.delete(request.id));
|
|
99
|
+
}
|
|
100
|
+
async handleRequest(request) {
|
|
101
|
+
switch (request.method) {
|
|
102
|
+
case "get_state":
|
|
103
|
+
await this.write({
|
|
104
|
+
version: RPC_PROTOCOL_VERSION,
|
|
105
|
+
kind: "response",
|
|
106
|
+
id: request.id,
|
|
107
|
+
ok: true,
|
|
108
|
+
result: {
|
|
109
|
+
method: "get_state",
|
|
110
|
+
state: {
|
|
111
|
+
sessionId: this.session.sessionId,
|
|
112
|
+
modelId: this.session.modelId,
|
|
113
|
+
isStreaming: this.session.isStreaming,
|
|
114
|
+
messageCount: this.session.transcript.length,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
case "cancel": {
|
|
120
|
+
const active = this.activePrompt;
|
|
121
|
+
const cancelled = active?.requestId === request.params.requestId;
|
|
122
|
+
if (cancelled)
|
|
123
|
+
active.controller.abort();
|
|
124
|
+
await this.write({
|
|
125
|
+
version: RPC_PROTOCOL_VERSION,
|
|
126
|
+
kind: "response",
|
|
127
|
+
id: request.id,
|
|
128
|
+
ok: true,
|
|
129
|
+
result: { method: "cancel", cancelled },
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
case "prompt":
|
|
134
|
+
await this.handlePrompt(request);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async handlePrompt(request) {
|
|
138
|
+
if (this.activePrompt || this.session.isStreaming) {
|
|
139
|
+
await this.writeError(request.id, "BUSY", "The RPC session is already processing a prompt.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const active = { requestId: request.id, controller: new AbortController() };
|
|
143
|
+
this.activePrompt = active;
|
|
144
|
+
try {
|
|
145
|
+
const message = await this.session.prompt(request.params.message, active.controller.signal);
|
|
146
|
+
await this.write({
|
|
147
|
+
version: RPC_PROTOCOL_VERSION,
|
|
148
|
+
kind: "response",
|
|
149
|
+
id: request.id,
|
|
150
|
+
ok: true,
|
|
151
|
+
result: { method: "prompt", message },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (cause) {
|
|
155
|
+
const error = errorFrom(cause);
|
|
156
|
+
const aborted = active.controller.signal.aborted || error.name === "AbortError";
|
|
157
|
+
await this.writeError(request.id, aborted ? "CANCELLED" : "INTERNAL_ERROR", aborted ? "The RPC prompt was cancelled." : "The RPC prompt failed.");
|
|
158
|
+
if (!aborted)
|
|
159
|
+
this.onError(error);
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
if (this.activePrompt === active)
|
|
163
|
+
this.activePrompt = undefined;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
writeError(id, code, message) {
|
|
167
|
+
return this.write({
|
|
168
|
+
version: RPC_PROTOCOL_VERSION,
|
|
169
|
+
kind: "response",
|
|
170
|
+
...(id === undefined ? {} : { id }),
|
|
171
|
+
ok: false,
|
|
172
|
+
error: { code, message },
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
write(message) {
|
|
176
|
+
return new Promise((resolve, reject) => {
|
|
177
|
+
this.output.write(serializeJsonLine(message), (error) => {
|
|
178
|
+
if (error)
|
|
179
|
+
reject(error);
|
|
180
|
+
else
|
|
181
|
+
resolve();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/rpc/server.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Readable, Writable } from \"node:stream\";\nimport type { AssistantMessage, Message } from \"@di-code/ai\";\nimport type { AgentSessionListener } from \"../core/session.ts\";\nimport { JsonlLineDecoder, serializeJsonLine } from \"./jsonl.ts\";\nimport {\n\tparseRpcRequest,\n\tRPC_PROTOCOL_VERSION,\n\ttype RpcErrorCode,\n\tRpcProtocolError,\n\ttype RpcRequest,\n\ttype RpcServerMessage,\n\trpcErrorResponse,\n} from \"./protocol.ts\";\n\nexport interface RpcSession {\n\treadonly sessionId: string;\n\treadonly modelId: string;\n\treadonly isStreaming: boolean;\n\treadonly transcript: readonly Message[];\n\tprompt(text: string, signal?: AbortSignal): Promise<AssistantMessage>;\n\tsubscribeSession(listener: AgentSessionListener): () => void;\n}\n\nexport interface RpcServerOptions {\n\treadonly session: RpcSession;\n\treadonly input: Readable;\n\treadonly output: Writable;\n\treadonly onError?: (error: Error) => void;\n\treadonly maxLineBytes?: number;\n}\n\ninterface ActivePrompt {\n\treadonly requestId: string;\n\treadonly controller: AbortController;\n}\n\nfunction errorFrom(cause: unknown): Error {\n\treturn cause instanceof Error ? cause : new Error(String(cause));\n}\n\nexport class RpcServer {\n\tprivate readonly session: RpcSession;\n\tprivate readonly input: Readable;\n\tprivate readonly output: Writable;\n\tprivate readonly onError: (error: Error) => void;\n\tprivate readonly decoder: JsonlLineDecoder;\n\tprivate readonly inFlightIds = new Set<string>();\n\tprivate activePrompt?: ActivePrompt;\n\tprivate unsubscribeSession?: () => void;\n\tprivate started = false;\n\n\tconstructor(options: RpcServerOptions) {\n\t\tthis.session = options.session;\n\t\tthis.input = options.input;\n\t\tthis.output = options.output;\n\t\tthis.onError = options.onError ?? (() => undefined);\n\t\tthis.decoder = new JsonlLineDecoder((line) => this.acceptLine(line), {\n\t\t\tmaxLineBytes: options.maxLineBytes,\n\t\t});\n\t}\n\n\tstart(): void {\n\t\tif (this.started) throw new Error(\"RPC server is already started.\");\n\t\tthis.started = true;\n\t\tthis.unsubscribeSession = this.session.subscribeSession(async (event) => {\n\t\t\tconst active = this.activePrompt;\n\t\t\tif (!active) return;\n\t\t\tawait this.write({\n\t\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\t\tkind: \"event\",\n\t\t\t\trequestId: active.requestId,\n\t\t\t\tevent,\n\t\t\t});\n\t\t});\n\t\tthis.input.on(\"data\", this.handleData);\n\t\tthis.input.once(\"end\", this.handleEnd);\n\t\tthis.input.once(\"error\", this.handleInputError);\n\t}\n\n\tstop(): void {\n\t\tif (!this.started) return;\n\t\tthis.started = false;\n\t\tthis.input.off(\"data\", this.handleData);\n\t\tthis.input.off(\"end\", this.handleEnd);\n\t\tthis.input.off(\"error\", this.handleInputError);\n\t\tthis.unsubscribeSession?.();\n\t\tthis.unsubscribeSession = undefined;\n\t\tthis.activePrompt?.controller.abort();\n\t}\n\n\tprivate readonly handleData = (chunk: string | Buffer): void => {\n\t\ttry {\n\t\t\tthis.decoder.push(chunk);\n\t\t} catch (cause) {\n\t\t\tconst error = errorFrom(cause);\n\t\t\tthis.onError(error);\n\t\t\tvoid this.writeError(undefined, \"INVALID_REQUEST\", error.message);\n\t\t\tthis.stop();\n\t\t}\n\t};\n\n\tprivate readonly handleEnd = (): void => {\n\t\ttry {\n\t\t\tthis.decoder.end();\n\t\t} catch (cause) {\n\t\t\tthis.onError(errorFrom(cause));\n\t\t}\n\t\tthis.stop();\n\t};\n\n\tprivate readonly handleInputError = (cause: Error): void => {\n\t\tthis.onError(cause);\n\t\tthis.stop();\n\t};\n\n\tprivate acceptLine(line: string): void {\n\t\tlet request: RpcRequest;\n\t\ttry {\n\t\t\trequest = parseRpcRequest(line);\n\t\t} catch (cause) {\n\t\t\tconst protocolError =\n\t\t\t\tcause instanceof RpcProtocolError\n\t\t\t\t\t? cause\n\t\t\t\t\t: new RpcProtocolError(\"INVALID_REQUEST\", \"RPC request validation failed.\");\n\t\t\tvoid this.write(rpcErrorResponse(protocolError)).catch(this.onError);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.inFlightIds.has(request.id)) {\n\t\t\tvoid this.writeError(request.id, \"INVALID_REQUEST\", \"RPC request id is already in flight.\");\n\t\t\treturn;\n\t\t}\n\t\tthis.inFlightIds.add(request.id);\n\t\tvoid this.handleRequest(request)\n\t\t\t.catch((cause) => this.onError(errorFrom(cause)))\n\t\t\t.finally(() => this.inFlightIds.delete(request.id));\n\t}\n\n\tprivate async handleRequest(request: RpcRequest): Promise<void> {\n\t\tswitch (request.method) {\n\t\t\tcase \"get_state\":\n\t\t\t\tawait this.write({\n\t\t\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\t\t\tkind: \"response\",\n\t\t\t\t\tid: request.id,\n\t\t\t\t\tok: true,\n\t\t\t\t\tresult: {\n\t\t\t\t\t\tmethod: \"get_state\",\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\tsessionId: this.session.sessionId,\n\t\t\t\t\t\t\tmodelId: this.session.modelId,\n\t\t\t\t\t\t\tisStreaming: this.session.isStreaming,\n\t\t\t\t\t\t\tmessageCount: this.session.transcript.length,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\tcase \"cancel\": {\n\t\t\t\tconst active = this.activePrompt;\n\t\t\t\tconst cancelled = active?.requestId === request.params.requestId;\n\t\t\t\tif (cancelled) active.controller.abort();\n\t\t\t\tawait this.write({\n\t\t\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\t\t\tkind: \"response\",\n\t\t\t\t\tid: request.id,\n\t\t\t\t\tok: true,\n\t\t\t\t\tresult: { method: \"cancel\", cancelled },\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"prompt\":\n\t\t\t\tawait this.handlePrompt(request);\n\t\t}\n\t}\n\n\tprivate async handlePrompt(request: Extract<RpcRequest, { method: \"prompt\" }>): Promise<void> {\n\t\tif (this.activePrompt || this.session.isStreaming) {\n\t\t\tawait this.writeError(request.id, \"BUSY\", \"The RPC session is already processing a prompt.\");\n\t\t\treturn;\n\t\t}\n\t\tconst active: ActivePrompt = { requestId: request.id, controller: new AbortController() };\n\t\tthis.activePrompt = active;\n\t\ttry {\n\t\t\tconst message = await this.session.prompt(request.params.message, active.controller.signal);\n\t\t\tawait this.write({\n\t\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\t\tkind: \"response\",\n\t\t\t\tid: request.id,\n\t\t\t\tok: true,\n\t\t\t\tresult: { method: \"prompt\", message },\n\t\t\t});\n\t\t} catch (cause) {\n\t\t\tconst error = errorFrom(cause);\n\t\t\tconst aborted = active.controller.signal.aborted || error.name === \"AbortError\";\n\t\t\tawait this.writeError(\n\t\t\t\trequest.id,\n\t\t\t\taborted ? \"CANCELLED\" : \"INTERNAL_ERROR\",\n\t\t\t\taborted ? \"The RPC prompt was cancelled.\" : \"The RPC prompt failed.\",\n\t\t\t);\n\t\t\tif (!aborted) this.onError(error);\n\t\t} finally {\n\t\t\tif (this.activePrompt === active) this.activePrompt = undefined;\n\t\t}\n\t}\n\n\tprivate writeError(id: string | undefined, code: RpcErrorCode, message: string): Promise<void> {\n\t\treturn this.write({\n\t\t\tversion: RPC_PROTOCOL_VERSION,\n\t\t\tkind: \"response\",\n\t\t\t...(id === undefined ? {} : { id }),\n\t\t\tok: false,\n\t\t\terror: { code, message },\n\t\t});\n\t}\n\n\tprivate write(message: RpcServerMessage): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.output.write(serializeJsonLine(message), (error) => {\n\t\t\t\tif (error) reject(error);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\t}\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-entry.d.ts","sourceRoot":"","sources":["../src/rpc-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { AgentSession } from "./core/session.js";
|
|
4
|
+
import { RpcServer } from "./rpc/server.js";
|
|
5
|
+
import { loadStartupConfiguration, resolveStartupRuntime } from "./startup.js";
|
|
6
|
+
try {
|
|
7
|
+
const allowedRoot = resolve(process.cwd());
|
|
8
|
+
const configuration = await loadStartupConfiguration(allowedRoot);
|
|
9
|
+
const runtime = resolveStartupRuntime(configuration.environment, configuration.providers);
|
|
10
|
+
const session = new AgentSession({
|
|
11
|
+
allowedRoot,
|
|
12
|
+
provider: runtime.provider,
|
|
13
|
+
model: runtime.model,
|
|
14
|
+
});
|
|
15
|
+
const server = new RpcServer({
|
|
16
|
+
session,
|
|
17
|
+
input: process.stdin,
|
|
18
|
+
output: process.stdout,
|
|
19
|
+
onError: (error) => process.stderr.write(`${error.message}\n`),
|
|
20
|
+
});
|
|
21
|
+
server.start();
|
|
22
|
+
}
|
|
23
|
+
catch (cause) {
|
|
24
|
+
const message = cause instanceof Error ? cause.message : "Unknown RPC startup error";
|
|
25
|
+
process.stderr.write(`${message}\n`);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=rpc-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-entry.js","sourceRoot":"","sources":["../src/rpc-entry.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE/E,IAAI,CAAC;IACJ,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,MAAM,wBAAwB,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,qBAAqB,CAAC,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC1F,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAChC,WAAW;QACX,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;KACpB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC5B,OAAO;QACP,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC;KAC9D,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;IACrF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACtB,CAAC","sourcesContent":["#!/usr/bin/env node\n\nimport { resolve } from \"node:path\";\nimport { AgentSession } from \"./core/session.ts\";\nimport { RpcServer } from \"./rpc/server.ts\";\nimport { loadStartupConfiguration, resolveStartupRuntime } from \"./startup.ts\";\n\ntry {\n\tconst allowedRoot = resolve(process.cwd());\n\tconst configuration = await loadStartupConfiguration(allowedRoot);\n\tconst runtime = resolveStartupRuntime(configuration.environment, configuration.providers);\n\tconst session = new AgentSession({\n\t\tallowedRoot,\n\t\tprovider: runtime.provider,\n\t\tmodel: runtime.model,\n\t});\n\tconst server = new RpcServer({\n\t\tsession,\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tonError: (error) => process.stderr.write(`${error.message}\\n`),\n\t});\n\tserver.start();\n} catch (cause) {\n\tconst message = cause instanceof Error ? cause.message : \"Unknown RPC startup error\";\n\tprocess.stderr.write(`${message}\\n`);\n\tprocess.exitCode = 1;\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Model, type Provider } from "@di-code/ai";
|
|
2
|
+
export interface StartupRuntime {
|
|
3
|
+
readonly provider: Provider;
|
|
4
|
+
readonly model: Model;
|
|
5
|
+
}
|
|
6
|
+
export interface StartupProviderConfiguration {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly name?: string;
|
|
9
|
+
readonly api?: string;
|
|
10
|
+
readonly apiKey?: string;
|
|
11
|
+
readonly baseUrl?: string;
|
|
12
|
+
readonly models?: readonly Model[];
|
|
13
|
+
}
|
|
14
|
+
export interface StartupConfiguration {
|
|
15
|
+
readonly environment: Environment;
|
|
16
|
+
readonly providers: readonly StartupProviderConfiguration[];
|
|
17
|
+
}
|
|
18
|
+
type Environment = Readonly<Record<string, string | undefined>>;
|
|
19
|
+
export declare function resolveStartupArgs(args: readonly string[]): readonly string[];
|
|
20
|
+
export declare function resolveStartupRuntime(env: Environment, providers: readonly StartupProviderConfiguration[]): StartupRuntime;
|
|
21
|
+
export declare function loadStartupConfiguration(cwd: string, environment?: Environment): Promise<StartupConfiguration>;
|
|
22
|
+
export declare function loadStartupEnvironment(cwd: string, environment?: Environment): Promise<Environment>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=startup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup.d.ts","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAEA,OAAO,EAKN,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,4BAA4B,EAAE,CAAC;CAC5D;AAQD,KAAK,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAehE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAE7E;AA0LD,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,SAAS,4BAA4B,EAAE,GAChD,cAAc,CAgBhB;AAED,wBAAsB,wBAAwB,CAC7C,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,WAAyB,GACpC,OAAO,CAAC,oBAAoB,CAAC,CAuB/B;AAED,wBAAsB,sBAAsB,CAC3C,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,WAAyB,GACpC,OAAO,CAAC,WAAW,CAAC,CAEtB"}
|