@copilotkit/aimock 1.7.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/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/plugin.json +12 -0
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/a2a-handler.cjs +203 -0
- package/dist/a2a-handler.cjs.map +1 -0
- package/dist/a2a-handler.js +199 -0
- package/dist/a2a-handler.js.map +1 -0
- package/dist/a2a-mock.cjs +292 -0
- package/dist/a2a-mock.cjs.map +1 -0
- package/dist/a2a-mock.d.cts +41 -0
- package/dist/a2a-mock.d.cts.map +1 -0
- package/dist/a2a-mock.d.ts +41 -0
- package/dist/a2a-mock.d.ts.map +1 -0
- package/dist/a2a-mock.js +290 -0
- package/dist/a2a-mock.js.map +1 -0
- package/dist/a2a-stub.cjs +4 -0
- package/dist/a2a-stub.d.cts +3 -0
- package/dist/a2a-stub.d.ts +3 -0
- package/dist/a2a-stub.js +3 -0
- package/dist/a2a-types.d.cts +68 -0
- package/dist/a2a-types.d.cts.map +1 -0
- package/dist/a2a-types.d.ts +68 -0
- package/dist/a2a-types.d.ts.map +1 -0
- package/dist/aimock-cli.cjs +112 -0
- package/dist/aimock-cli.cjs.map +1 -0
- package/dist/aimock-cli.d.cts +19 -0
- package/dist/aimock-cli.d.cts.map +1 -0
- package/dist/aimock-cli.d.ts +19 -0
- package/dist/aimock-cli.d.ts.map +1 -0
- package/dist/aimock-cli.js +110 -0
- package/dist/aimock-cli.js.map +1 -0
- package/dist/aws-event-stream.cjs +117 -0
- package/dist/aws-event-stream.cjs.map +1 -0
- package/dist/aws-event-stream.d.cts +38 -0
- package/dist/aws-event-stream.d.cts.map +1 -0
- package/dist/aws-event-stream.d.ts +38 -0
- package/dist/aws-event-stream.d.ts.map +1 -0
- package/dist/aws-event-stream.js +114 -0
- package/dist/aws-event-stream.js.map +1 -0
- package/dist/bedrock-converse.cjs +445 -0
- package/dist/bedrock-converse.cjs.map +1 -0
- package/dist/bedrock-converse.d.cts +50 -0
- package/dist/bedrock-converse.d.cts.map +1 -0
- package/dist/bedrock-converse.d.ts +50 -0
- package/dist/bedrock-converse.d.ts.map +1 -0
- package/dist/bedrock-converse.js +443 -0
- package/dist/bedrock-converse.js.map +1 -0
- package/dist/bedrock.cjs +557 -0
- package/dist/bedrock.cjs.map +1 -0
- package/dist/bedrock.d.cts +41 -0
- package/dist/bedrock.d.cts.map +1 -0
- package/dist/bedrock.d.ts +41 -0
- package/dist/bedrock.d.ts.map +1 -0
- package/dist/bedrock.js +553 -0
- package/dist/bedrock.js.map +1 -0
- package/dist/chaos.cjs +114 -0
- package/dist/chaos.cjs.map +1 -0
- package/dist/chaos.d.cts +27 -0
- package/dist/chaos.d.cts.map +1 -0
- package/dist/chaos.d.ts +27 -0
- package/dist/chaos.d.ts.map +1 -0
- package/dist/chaos.js +113 -0
- package/dist/chaos.js.map +1 -0
- package/dist/cli.cjs +268 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +268 -0
- package/dist/cli.js.map +1 -0
- package/dist/cohere.cjs +434 -0
- package/dist/cohere.cjs.map +1 -0
- package/dist/cohere.d.cts +34 -0
- package/dist/cohere.d.cts.map +1 -0
- package/dist/cohere.d.ts +34 -0
- package/dist/cohere.d.ts.map +1 -0
- package/dist/cohere.js +433 -0
- package/dist/cohere.js.map +1 -0
- package/dist/config-loader.cjs +111 -0
- package/dist/config-loader.cjs.map +1 -0
- package/dist/config-loader.d.cts +100 -0
- package/dist/config-loader.d.cts.map +1 -0
- package/dist/config-loader.d.ts +100 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +107 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/embeddings.cjs +150 -0
- package/dist/embeddings.cjs.map +1 -0
- package/dist/embeddings.d.cts +12 -0
- package/dist/embeddings.d.cts.map +1 -0
- package/dist/embeddings.d.ts +12 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +150 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/fixture-loader.cjs +269 -0
- package/dist/fixture-loader.cjs.map +1 -0
- package/dist/fixture-loader.d.cts +17 -0
- package/dist/fixture-loader.d.cts.map +1 -0
- package/dist/fixture-loader.d.ts +17 -0
- package/dist/fixture-loader.d.ts.map +1 -0
- package/dist/fixture-loader.js +265 -0
- package/dist/fixture-loader.js.map +1 -0
- package/dist/gemini.cjs +403 -0
- package/dist/gemini.cjs.map +1 -0
- package/dist/gemini.d.cts +10 -0
- package/dist/gemini.d.cts.map +1 -0
- package/dist/gemini.d.ts +10 -0
- package/dist/gemini.d.ts.map +1 -0
- package/dist/gemini.js +403 -0
- package/dist/gemini.js.map +1 -0
- package/dist/helpers.cjs +276 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +39 -0
- package/dist/helpers.d.cts.map +1 -0
- package/dist/helpers.d.ts +39 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +259 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +113 -0
- package/dist/index.d.cts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +39 -0
- package/dist/interruption.cjs +40 -0
- package/dist/interruption.cjs.map +1 -0
- package/dist/interruption.d.cts +15 -0
- package/dist/interruption.d.cts.map +1 -0
- package/dist/interruption.d.ts +15 -0
- package/dist/interruption.d.ts.map +1 -0
- package/dist/interruption.js +39 -0
- package/dist/interruption.js.map +1 -0
- package/dist/journal.cjs +65 -0
- package/dist/journal.cjs.map +1 -0
- package/dist/journal.d.cts +23 -0
- package/dist/journal.d.cts.map +1 -0
- package/dist/journal.d.ts +23 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +65 -0
- package/dist/journal.js.map +1 -0
- package/dist/jsonrpc.cjs +91 -0
- package/dist/jsonrpc.cjs.map +1 -0
- package/dist/jsonrpc.d.cts +24 -0
- package/dist/jsonrpc.d.cts.map +1 -0
- package/dist/jsonrpc.d.ts +24 -0
- package/dist/jsonrpc.d.ts.map +1 -0
- package/dist/jsonrpc.js +90 -0
- package/dist/jsonrpc.js.map +1 -0
- package/dist/llmock.cjs +223 -0
- package/dist/llmock.cjs.map +1 -0
- package/dist/llmock.d.cts +70 -0
- package/dist/llmock.d.cts.map +1 -0
- package/dist/llmock.d.ts +70 -0
- package/dist/llmock.d.ts.map +1 -0
- package/dist/llmock.js +223 -0
- package/dist/llmock.js.map +1 -0
- package/dist/logger.cjs +29 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +14 -0
- package/dist/logger.d.cts.map +1 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +28 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp-handler.cjs +189 -0
- package/dist/mcp-handler.cjs.map +1 -0
- package/dist/mcp-handler.js +188 -0
- package/dist/mcp-handler.js.map +1 -0
- package/dist/mcp-mock.cjs +169 -0
- package/dist/mcp-mock.cjs.map +1 -0
- package/dist/mcp-mock.d.cts +40 -0
- package/dist/mcp-mock.d.cts.map +1 -0
- package/dist/mcp-mock.d.ts +40 -0
- package/dist/mcp-mock.d.ts.map +1 -0
- package/dist/mcp-mock.js +167 -0
- package/dist/mcp-mock.js.map +1 -0
- package/dist/mcp-stub.cjs +4 -0
- package/dist/mcp-stub.d.cts +3 -0
- package/dist/mcp-stub.d.ts +3 -0
- package/dist/mcp-stub.js +3 -0
- package/dist/mcp-types.d.cts +65 -0
- package/dist/mcp-types.d.cts.map +1 -0
- package/dist/mcp-types.d.ts +65 -0
- package/dist/mcp-types.d.ts.map +1 -0
- package/dist/messages.cjs +489 -0
- package/dist/messages.cjs.map +1 -0
- package/dist/messages.d.cts +10 -0
- package/dist/messages.d.cts.map +1 -0
- package/dist/messages.d.ts +10 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +489 -0
- package/dist/messages.js.map +1 -0
- package/dist/metrics.cjs +160 -0
- package/dist/metrics.cjs.map +1 -0
- package/dist/metrics.d.cts +24 -0
- package/dist/metrics.d.cts.map +1 -0
- package/dist/metrics.d.ts +24 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +158 -0
- package/dist/metrics.js.map +1 -0
- package/dist/moderation.cjs +91 -0
- package/dist/moderation.cjs.map +1 -0
- package/dist/moderation.d.cts +23 -0
- package/dist/moderation.d.cts.map +1 -0
- package/dist/moderation.d.ts +23 -0
- package/dist/moderation.d.ts.map +1 -0
- package/dist/moderation.js +91 -0
- package/dist/moderation.js.map +1 -0
- package/dist/ndjson-writer.cjs +31 -0
- package/dist/ndjson-writer.cjs.map +1 -0
- package/dist/ndjson-writer.d.cts +17 -0
- package/dist/ndjson-writer.d.cts.map +1 -0
- package/dist/ndjson-writer.d.ts +17 -0
- package/dist/ndjson-writer.d.ts.map +1 -0
- package/dist/ndjson-writer.js +31 -0
- package/dist/ndjson-writer.js.map +1 -0
- package/dist/ollama.cjs +519 -0
- package/dist/ollama.cjs.map +1 -0
- package/dist/ollama.d.cts +34 -0
- package/dist/ollama.d.cts.map +1 -0
- package/dist/ollama.d.ts +34 -0
- package/dist/ollama.d.ts.map +1 -0
- package/dist/ollama.js +517 -0
- package/dist/ollama.js.map +1 -0
- package/dist/recorder.cjs +311 -0
- package/dist/recorder.cjs.map +1 -0
- package/dist/recorder.d.cts +23 -0
- package/dist/recorder.d.cts.map +1 -0
- package/dist/recorder.d.ts +23 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +305 -0
- package/dist/recorder.js.map +1 -0
- package/dist/rerank.cjs +71 -0
- package/dist/rerank.cjs.map +1 -0
- package/dist/rerank.d.cts +22 -0
- package/dist/rerank.d.cts.map +1 -0
- package/dist/rerank.d.ts +22 -0
- package/dist/rerank.d.ts.map +1 -0
- package/dist/rerank.js +71 -0
- package/dist/rerank.js.map +1 -0
- package/dist/responses.cjs +637 -0
- package/dist/responses.cjs.map +1 -0
- package/dist/responses.d.cts +16 -0
- package/dist/responses.d.cts.map +1 -0
- package/dist/responses.d.ts +16 -0
- package/dist/responses.d.ts.map +1 -0
- package/dist/responses.js +634 -0
- package/dist/responses.js.map +1 -0
- package/dist/router.cjs +68 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.cts +16 -0
- package/dist/router.d.cts.map +1 -0
- package/dist/router.d.ts +16 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +65 -0
- package/dist/router.js.map +1 -0
- package/dist/search.cjs +59 -0
- package/dist/search.cjs.map +1 -0
- package/dist/search.d.cts +23 -0
- package/dist/search.d.cts.map +1 -0
- package/dist/search.d.ts +23 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +59 -0
- package/dist/search.js.map +1 -0
- package/dist/server.cjs +935 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +28 -0
- package/dist/server.d.cts.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +933 -0
- package/dist/server.js.map +1 -0
- package/dist/sse-writer.cjs +59 -0
- package/dist/sse-writer.cjs.map +1 -0
- package/dist/sse-writer.d.cts +19 -0
- package/dist/sse-writer.d.cts.map +1 -0
- package/dist/sse-writer.d.ts +19 -0
- package/dist/sse-writer.d.ts.map +1 -0
- package/dist/sse-writer.js +55 -0
- package/dist/sse-writer.js.map +1 -0
- package/dist/stream-collapse.cjs +496 -0
- package/dist/stream-collapse.cjs.map +1 -0
- package/dist/stream-collapse.d.cts +70 -0
- package/dist/stream-collapse.d.cts.map +1 -0
- package/dist/stream-collapse.d.ts +70 -0
- package/dist/stream-collapse.d.ts.map +1 -0
- package/dist/stream-collapse.js +489 -0
- package/dist/stream-collapse.js.map +1 -0
- package/dist/suite.cjs +46 -0
- package/dist/suite.cjs.map +1 -0
- package/dist/suite.d.cts +31 -0
- package/dist/suite.d.cts.map +1 -0
- package/dist/suite.d.ts +31 -0
- package/dist/suite.d.ts.map +1 -0
- package/dist/suite.js +46 -0
- package/dist/suite.js.map +1 -0
- package/dist/types.d.cts +243 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/url.cjs +21 -0
- package/dist/url.cjs.map +1 -0
- package/dist/url.d.cts +16 -0
- package/dist/url.d.cts.map +1 -0
- package/dist/url.d.ts +16 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +20 -0
- package/dist/url.js.map +1 -0
- package/dist/vector-handler.cjs +239 -0
- package/dist/vector-handler.cjs.map +1 -0
- package/dist/vector-handler.js +238 -0
- package/dist/vector-handler.js.map +1 -0
- package/dist/vector-mock.cjs +229 -0
- package/dist/vector-mock.cjs.map +1 -0
- package/dist/vector-mock.d.cts +39 -0
- package/dist/vector-mock.d.cts.map +1 -0
- package/dist/vector-mock.d.ts +39 -0
- package/dist/vector-mock.d.ts.map +1 -0
- package/dist/vector-mock.js +227 -0
- package/dist/vector-mock.js.map +1 -0
- package/dist/vector-stub.cjs +4 -0
- package/dist/vector-stub.d.cts +3 -0
- package/dist/vector-stub.d.ts +3 -0
- package/dist/vector-stub.js +3 -0
- package/dist/vector-types.d.cts +32 -0
- package/dist/vector-types.d.cts.map +1 -0
- package/dist/vector-types.d.ts +32 -0
- package/dist/vector-types.d.ts.map +1 -0
- package/dist/watcher.cjs +59 -0
- package/dist/watcher.cjs.map +1 -0
- package/dist/watcher.js +58 -0
- package/dist/watcher.js.map +1 -0
- package/dist/ws-framing.cjs +187 -0
- package/dist/ws-framing.cjs.map +1 -0
- package/dist/ws-framing.d.cts +26 -0
- package/dist/ws-framing.d.cts.map +1 -0
- package/dist/ws-framing.d.ts +26 -0
- package/dist/ws-framing.d.ts.map +1 -0
- package/dist/ws-framing.js +184 -0
- package/dist/ws-framing.js.map +1 -0
- package/dist/ws-gemini-live.cjs +364 -0
- package/dist/ws-gemini-live.cjs.map +1 -0
- package/dist/ws-gemini-live.d.cts +18 -0
- package/dist/ws-gemini-live.d.cts.map +1 -0
- package/dist/ws-gemini-live.d.ts +18 -0
- package/dist/ws-gemini-live.d.ts.map +1 -0
- package/dist/ws-gemini-live.js +364 -0
- package/dist/ws-gemini-live.js.map +1 -0
- package/dist/ws-realtime.cjs +435 -0
- package/dist/ws-realtime.cjs.map +1 -0
- package/dist/ws-realtime.d.cts +17 -0
- package/dist/ws-realtime.d.cts.map +1 -0
- package/dist/ws-realtime.d.ts +17 -0
- package/dist/ws-realtime.d.ts.map +1 -0
- package/dist/ws-realtime.js +435 -0
- package/dist/ws-realtime.js.map +1 -0
- package/dist/ws-responses.cjs +164 -0
- package/dist/ws-responses.cjs.map +1 -0
- package/dist/ws-responses.d.cts +18 -0
- package/dist/ws-responses.d.cts.map +1 -0
- package/dist/ws-responses.d.ts +18 -0
- package/dist/ws-responses.d.ts.map +1 -0
- package/dist/ws-responses.js +164 -0
- package/dist/ws-responses.js.map +1 -0
- package/fixtures/example-greeting.json +12 -0
- package/fixtures/example-multi-turn.json +14 -0
- package/fixtures/example-tool-call.json +15 -0
- package/package.json +118 -0
- package/skills/write-fixtures/SKILL.md +625 -0
package/dist/jsonrpc.cjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/jsonrpc.ts
|
|
3
|
+
function errorResponse(code, message, id = null) {
|
|
4
|
+
return {
|
|
5
|
+
jsonrpc: "2.0",
|
|
6
|
+
id,
|
|
7
|
+
error: {
|
|
8
|
+
code,
|
|
9
|
+
message
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function isObject(val) {
|
|
14
|
+
return typeof val === "object" && val !== null && !Array.isArray(val);
|
|
15
|
+
}
|
|
16
|
+
async function processOne(entry, methods, onNotification, req) {
|
|
17
|
+
if (!isObject(entry)) return errorResponse(-32600, "Invalid request");
|
|
18
|
+
const { jsonrpc, method, params, id } = entry;
|
|
19
|
+
if (jsonrpc !== "2.0" || typeof method !== "string") return errorResponse(-32600, "Invalid request", typeof id === "string" || typeof id === "number" ? id : null);
|
|
20
|
+
if (!("id" in entry) || id === void 0) {
|
|
21
|
+
if (onNotification) onNotification(method, params);
|
|
22
|
+
const handler = methods[method];
|
|
23
|
+
if (handler) try {
|
|
24
|
+
await handler(params, null, req);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
console.warn("Notification handler error:", err);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const reqId = typeof id === "string" || typeof id === "number" ? id : null;
|
|
31
|
+
const handler = methods[method];
|
|
32
|
+
if (!handler) return errorResponse(-32601, "Method not found", reqId);
|
|
33
|
+
try {
|
|
34
|
+
const result = await handler(params, reqId, req);
|
|
35
|
+
if (result) return result;
|
|
36
|
+
return {
|
|
37
|
+
jsonrpc: "2.0",
|
|
38
|
+
id: reqId,
|
|
39
|
+
result: null
|
|
40
|
+
};
|
|
41
|
+
} catch (err) {
|
|
42
|
+
return errorResponse(-32603, `Internal error: ${err instanceof Error ? err.message : String(err)}`, reqId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function createJsonRpcDispatcher(options) {
|
|
46
|
+
const { methods, onNotification } = options;
|
|
47
|
+
return async (req, res, body) => {
|
|
48
|
+
let parsed;
|
|
49
|
+
try {
|
|
50
|
+
parsed = JSON.parse(body);
|
|
51
|
+
} catch {
|
|
52
|
+
const resp = errorResponse(-32700, "Parse error");
|
|
53
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
54
|
+
res.end(JSON.stringify(resp));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(parsed) && parsed.length === 0) {
|
|
58
|
+
const resp = errorResponse(-32600, "Invalid request");
|
|
59
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
60
|
+
res.end(JSON.stringify(resp));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (Array.isArray(parsed)) {
|
|
64
|
+
const responses = [];
|
|
65
|
+
for (const entry of parsed) {
|
|
66
|
+
const result = await processOne(entry, methods, onNotification, req);
|
|
67
|
+
if (result !== null) responses.push(result);
|
|
68
|
+
}
|
|
69
|
+
if (responses.length === 0) {
|
|
70
|
+
res.writeHead(202);
|
|
71
|
+
res.end("");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
75
|
+
res.end(JSON.stringify(responses));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const result = await processOne(parsed, methods, onNotification, req);
|
|
79
|
+
if (result === null) {
|
|
80
|
+
res.writeHead(202);
|
|
81
|
+
res.end("");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
85
|
+
res.end(JSON.stringify(result));
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
exports.createJsonRpcDispatcher = createJsonRpcDispatcher;
|
|
91
|
+
//# sourceMappingURL=jsonrpc.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.cjs","names":[],"sources":["../src/jsonrpc.ts"],"sourcesContent":["import type * as http from \"node:http\";\n\nexport type JsonRpcResponse = {\n jsonrpc: \"2.0\";\n id: string | number | null;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n};\n\nexport type MethodHandler = (\n params: unknown,\n id: string | number,\n req: http.IncomingMessage,\n) => Promise<JsonRpcResponse | null>;\n\nexport interface JsonRpcDispatcherOptions {\n methods: Record<string, MethodHandler>;\n onNotification?: (method: string, params: unknown) => void;\n}\n\nfunction errorResponse(\n code: number,\n message: string,\n id: string | number | null = null,\n): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, error: { code, message } };\n}\n\nfunction isObject(val: unknown): val is Record<string, unknown> {\n return typeof val === \"object\" && val !== null && !Array.isArray(val);\n}\n\nasync function processOne(\n entry: unknown,\n methods: Record<string, MethodHandler>,\n onNotification: ((method: string, params: unknown) => void) | undefined,\n req: http.IncomingMessage,\n): Promise<JsonRpcResponse | null> {\n if (!isObject(entry)) {\n return errorResponse(-32600, \"Invalid request\");\n }\n\n const { jsonrpc, method, params, id } = entry;\n\n if (jsonrpc !== \"2.0\" || typeof method !== \"string\") {\n const reqId = typeof id === \"string\" || typeof id === \"number\" ? id : null;\n return errorResponse(-32600, \"Invalid request\", reqId);\n }\n\n // Notification: id is absent/undefined\n const isNotification = !(\"id\" in entry) || id === undefined;\n\n if (isNotification) {\n if (onNotification) {\n onNotification(method, params);\n }\n // Invoke the method handler for side effects (e.g., MCP notifications/initialized),\n // but discard the result — notifications MUST NOT produce responses per JSON-RPC 2.0.\n const handler = methods[method];\n if (handler) {\n try {\n await handler(params, null as unknown as string | number, req);\n } catch (err: unknown) {\n console.warn(\"Notification handler error:\", err);\n }\n }\n return null;\n }\n\n const reqId = typeof id === \"string\" || typeof id === \"number\" ? id : null;\n\n const handler = methods[method];\n if (!handler) {\n return errorResponse(-32601, \"Method not found\", reqId);\n }\n\n try {\n const result = await handler(params, reqId as string | number, req);\n if (result) return result;\n return { jsonrpc: \"2.0\", id: reqId, result: null };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return errorResponse(-32603, `Internal error: ${msg}`, reqId);\n }\n}\n\nexport function createJsonRpcDispatcher(\n options: JsonRpcDispatcherOptions,\n): (req: http.IncomingMessage, res: http.ServerResponse, body: string) => Promise<void> {\n const { methods, onNotification } = options;\n\n return async (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n ): Promise<void> => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n const resp = errorResponse(-32700, \"Parse error\");\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(resp));\n return;\n }\n\n // Empty batch\n if (Array.isArray(parsed) && parsed.length === 0) {\n const resp = errorResponse(-32600, \"Invalid request\");\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(resp));\n return;\n }\n\n // Batch mode\n if (Array.isArray(parsed)) {\n const responses: JsonRpcResponse[] = [];\n for (const entry of parsed) {\n const result = await processOne(entry, methods, onNotification, req);\n if (result !== null) {\n responses.push(result);\n }\n }\n if (responses.length === 0) {\n res.writeHead(202);\n res.end(\"\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(responses));\n return;\n }\n\n // Single request\n const result = await processOne(parsed, methods, onNotification, req);\n if (result === null) {\n res.writeHead(202);\n res.end(\"\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(result));\n };\n}\n"],"mappings":";;AAoBA,SAAS,cACP,MACA,SACA,KAA6B,MACZ;AACjB,QAAO;EAAE,SAAS;EAAO;EAAI,OAAO;GAAE;GAAM;GAAS;EAAE;;AAGzD,SAAS,SAAS,KAA8C;AAC9D,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI;;AAGvE,eAAe,WACb,OACA,SACA,gBACA,KACiC;AACjC,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO,cAAc,QAAQ,kBAAkB;CAGjD,MAAM,EAAE,SAAS,QAAQ,QAAQ,OAAO;AAExC,KAAI,YAAY,SAAS,OAAO,WAAW,SAEzC,QAAO,cAAc,QAAQ,mBADf,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK,KAChB;AAMxD,KAFuB,EAAE,QAAQ,UAAU,OAAO,QAE9B;AAClB,MAAI,eACF,gBAAe,QAAQ,OAAO;EAIhC,MAAM,UAAU,QAAQ;AACxB,MAAI,QACF,KAAI;AACF,SAAM,QAAQ,QAAQ,MAAoC,IAAI;WACvD,KAAc;AACrB,WAAQ,KAAK,+BAA+B,IAAI;;AAGpD,SAAO;;CAGT,MAAM,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK;CAEtE,MAAM,UAAU,QAAQ;AACxB,KAAI,CAAC,QACH,QAAO,cAAc,QAAQ,oBAAoB,MAAM;AAGzD,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,QAAQ,OAA0B,IAAI;AACnE,MAAI,OAAQ,QAAO;AACnB,SAAO;GAAE,SAAS;GAAO,IAAI;GAAO,QAAQ;GAAM;UAC3C,KAAc;AAErB,SAAO,cAAc,QAAQ,mBADjB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,IACL,MAAM;;;AAIjE,SAAgB,wBACd,SACsF;CACtF,MAAM,EAAE,SAAS,mBAAmB;AAEpC,QAAO,OACL,KACA,KACA,SACkB;EAClB,IAAI;AACJ,MAAI;AACF,YAAS,KAAK,MAAM,KAAK;UACnB;GACN,MAAM,OAAO,cAAc,QAAQ,cAAc;AACjD,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,KAAK,CAAC;AAC7B;;AAIF,MAAI,MAAM,QAAQ,OAAO,IAAI,OAAO,WAAW,GAAG;GAChD,MAAM,OAAO,cAAc,QAAQ,kBAAkB;AACrD,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,KAAK,CAAC;AAC7B;;AAIF,MAAI,MAAM,QAAQ,OAAO,EAAE;GACzB,MAAM,YAA+B,EAAE;AACvC,QAAK,MAAM,SAAS,QAAQ;IAC1B,MAAM,SAAS,MAAM,WAAW,OAAO,SAAS,gBAAgB,IAAI;AACpE,QAAI,WAAW,KACb,WAAU,KAAK,OAAO;;AAG1B,OAAI,UAAU,WAAW,GAAG;AAC1B,QAAI,UAAU,IAAI;AAClB,QAAI,IAAI,GAAG;AACX;;AAEF,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,UAAU,CAAC;AAClC;;EAIF,MAAM,SAAS,MAAM,WAAW,QAAQ,SAAS,gBAAgB,IAAI;AACrE,MAAI,WAAW,MAAM;AACnB,OAAI,UAAU,IAAI;AAClB,OAAI,IAAI,GAAG;AACX;;AAEF,MAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,MAAI,IAAI,KAAK,UAAU,OAAO,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as http from "node:http";
|
|
2
|
+
|
|
3
|
+
//#region src/jsonrpc.d.ts
|
|
4
|
+
type JsonRpcResponse = {
|
|
5
|
+
jsonrpc: "2.0";
|
|
6
|
+
id: string | number | null;
|
|
7
|
+
result?: unknown;
|
|
8
|
+
error?: {
|
|
9
|
+
code: number;
|
|
10
|
+
message: string;
|
|
11
|
+
data?: unknown;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
type MethodHandler = (params: unknown, id: string | number, req: http.IncomingMessage) => Promise<JsonRpcResponse | null>;
|
|
15
|
+
interface JsonRpcDispatcherOptions {
|
|
16
|
+
methods: Record<string, MethodHandler>;
|
|
17
|
+
onNotification?: (method: string, params: unknown) => void;
|
|
18
|
+
}
|
|
19
|
+
declare function createJsonRpcDispatcher(options: JsonRpcDispatcherOptions): (req: http.IncomingMessage, res: http.ServerResponse, body: string) => Promise<void>;
|
|
20
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher };
|
|
24
|
+
//# sourceMappingURL=jsonrpc.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.d.cts","names":[],"sources":["../src/jsonrpc.ts"],"sourcesContent":[],"mappings":";;;KAEY,eAAA;;EAAA,EAAA,EAAA,MAAA,GAAA,MAAe,GAAA,IAAA;EAOf,MAAA,CAAA,EAAA,OAAa;EAAA,KAAA,CAAA,EAAA;IAGlB,IAAK,EAAA,MAAA;IACC,OAAA,EAAA,MAAA;IAAR,IAAA,CAAA,EAAA,OAAA;EAAO,CAAA;AAEZ,CAAA;AAAyC,KAN7B,aAAA,GAM6B,CAAA,MAAA,EAAA,OAAA,EAAA,EAAA,EAAA,MAAA,GAAA,MAAA,EAAA,GAAA,EAHlC,IAAA,CAAK,eAG6B,EAAA,GAFpC,OAEoC,CAF5B,eAE4B,GAAA,IAAA,CAAA;AACf,UADT,wBAAA,CACS;SAAf,EAAA,MAAA,CAAA,MAAA,EAAe,aAAf,CAAA;EAAM,cAAA,CAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA,EAAA,GAAA,IAAA;AAsEjB;AAAuC,iBAAvB,uBAAA,CAAuB,OAAA,EAC5B,wBAD4B,CAAA,EAAA,CAAA,GAAA,EAE9B,IAAA,CAAK,eAFyB,EAAA,GAAA,EAEH,IAAA,CAAK,cAFF,EAAA,IAAA,EAAA,MAAA,EAAA,GAEmC,OAFnC,CAAA,IAAA,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as http from "node:http";
|
|
2
|
+
|
|
3
|
+
//#region src/jsonrpc.d.ts
|
|
4
|
+
type JsonRpcResponse = {
|
|
5
|
+
jsonrpc: "2.0";
|
|
6
|
+
id: string | number | null;
|
|
7
|
+
result?: unknown;
|
|
8
|
+
error?: {
|
|
9
|
+
code: number;
|
|
10
|
+
message: string;
|
|
11
|
+
data?: unknown;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
type MethodHandler = (params: unknown, id: string | number, req: http.IncomingMessage) => Promise<JsonRpcResponse | null>;
|
|
15
|
+
interface JsonRpcDispatcherOptions {
|
|
16
|
+
methods: Record<string, MethodHandler>;
|
|
17
|
+
onNotification?: (method: string, params: unknown) => void;
|
|
18
|
+
}
|
|
19
|
+
declare function createJsonRpcDispatcher(options: JsonRpcDispatcherOptions): (req: http.IncomingMessage, res: http.ServerResponse, body: string) => Promise<void>;
|
|
20
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher };
|
|
24
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.d.ts","names":[],"sources":["../src/jsonrpc.ts"],"sourcesContent":[],"mappings":";;;KAEY,eAAA;;EAAA,EAAA,EAAA,MAAA,GAAA,MAAe,GAAA,IAAA;EAOf,MAAA,CAAA,EAAA,OAAa;EAAA,KAAA,CAAA,EAAA;IAGlB,IAAK,EAAA,MAAA;IACC,OAAA,EAAA,MAAA;IAAR,IAAA,CAAA,EAAA,OAAA;EAAO,CAAA;AAEZ,CAAA;AAAyC,KAN7B,aAAA,GAM6B,CAAA,MAAA,EAAA,OAAA,EAAA,EAAA,EAAA,MAAA,GAAA,MAAA,EAAA,GAAA,EAHlC,IAAA,CAAK,eAG6B,EAAA,GAFpC,OAEoC,CAF5B,eAE4B,GAAA,IAAA,CAAA;AACf,UADT,wBAAA,CACS;SAAf,EAAA,MAAA,CAAA,MAAA,EAAe,aAAf,CAAA;EAAM,cAAA,CAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA,EAAA,GAAA,IAAA;AAsEjB;AAAuC,iBAAvB,uBAAA,CAAuB,OAAA,EAC5B,wBAD4B,CAAA,EAAA,CAAA,GAAA,EAE9B,IAAA,CAAK,eAFyB,EAAA,GAAA,EAEH,IAAA,CAAK,cAFF,EAAA,IAAA,EAAA,MAAA,EAAA,GAEmC,OAFnC,CAAA,IAAA,CAAA"}
|
package/dist/jsonrpc.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//#region src/jsonrpc.ts
|
|
2
|
+
function errorResponse(code, message, id = null) {
|
|
3
|
+
return {
|
|
4
|
+
jsonrpc: "2.0",
|
|
5
|
+
id,
|
|
6
|
+
error: {
|
|
7
|
+
code,
|
|
8
|
+
message
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function isObject(val) {
|
|
13
|
+
return typeof val === "object" && val !== null && !Array.isArray(val);
|
|
14
|
+
}
|
|
15
|
+
async function processOne(entry, methods, onNotification, req) {
|
|
16
|
+
if (!isObject(entry)) return errorResponse(-32600, "Invalid request");
|
|
17
|
+
const { jsonrpc, method, params, id } = entry;
|
|
18
|
+
if (jsonrpc !== "2.0" || typeof method !== "string") return errorResponse(-32600, "Invalid request", typeof id === "string" || typeof id === "number" ? id : null);
|
|
19
|
+
if (!("id" in entry) || id === void 0) {
|
|
20
|
+
if (onNotification) onNotification(method, params);
|
|
21
|
+
const handler = methods[method];
|
|
22
|
+
if (handler) try {
|
|
23
|
+
await handler(params, null, req);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.warn("Notification handler error:", err);
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const reqId = typeof id === "string" || typeof id === "number" ? id : null;
|
|
30
|
+
const handler = methods[method];
|
|
31
|
+
if (!handler) return errorResponse(-32601, "Method not found", reqId);
|
|
32
|
+
try {
|
|
33
|
+
const result = await handler(params, reqId, req);
|
|
34
|
+
if (result) return result;
|
|
35
|
+
return {
|
|
36
|
+
jsonrpc: "2.0",
|
|
37
|
+
id: reqId,
|
|
38
|
+
result: null
|
|
39
|
+
};
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return errorResponse(-32603, `Internal error: ${err instanceof Error ? err.message : String(err)}`, reqId);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function createJsonRpcDispatcher(options) {
|
|
45
|
+
const { methods, onNotification } = options;
|
|
46
|
+
return async (req, res, body) => {
|
|
47
|
+
let parsed;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(body);
|
|
50
|
+
} catch {
|
|
51
|
+
const resp = errorResponse(-32700, "Parse error");
|
|
52
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
53
|
+
res.end(JSON.stringify(resp));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(parsed) && parsed.length === 0) {
|
|
57
|
+
const resp = errorResponse(-32600, "Invalid request");
|
|
58
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
59
|
+
res.end(JSON.stringify(resp));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(parsed)) {
|
|
63
|
+
const responses = [];
|
|
64
|
+
for (const entry of parsed) {
|
|
65
|
+
const result = await processOne(entry, methods, onNotification, req);
|
|
66
|
+
if (result !== null) responses.push(result);
|
|
67
|
+
}
|
|
68
|
+
if (responses.length === 0) {
|
|
69
|
+
res.writeHead(202);
|
|
70
|
+
res.end("");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
74
|
+
res.end(JSON.stringify(responses));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const result = await processOne(parsed, methods, onNotification, req);
|
|
78
|
+
if (result === null) {
|
|
79
|
+
res.writeHead(202);
|
|
80
|
+
res.end("");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
84
|
+
res.end(JSON.stringify(result));
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { createJsonRpcDispatcher };
|
|
90
|
+
//# sourceMappingURL=jsonrpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","names":[],"sources":["../src/jsonrpc.ts"],"sourcesContent":["import type * as http from \"node:http\";\n\nexport type JsonRpcResponse = {\n jsonrpc: \"2.0\";\n id: string | number | null;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n};\n\nexport type MethodHandler = (\n params: unknown,\n id: string | number,\n req: http.IncomingMessage,\n) => Promise<JsonRpcResponse | null>;\n\nexport interface JsonRpcDispatcherOptions {\n methods: Record<string, MethodHandler>;\n onNotification?: (method: string, params: unknown) => void;\n}\n\nfunction errorResponse(\n code: number,\n message: string,\n id: string | number | null = null,\n): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, error: { code, message } };\n}\n\nfunction isObject(val: unknown): val is Record<string, unknown> {\n return typeof val === \"object\" && val !== null && !Array.isArray(val);\n}\n\nasync function processOne(\n entry: unknown,\n methods: Record<string, MethodHandler>,\n onNotification: ((method: string, params: unknown) => void) | undefined,\n req: http.IncomingMessage,\n): Promise<JsonRpcResponse | null> {\n if (!isObject(entry)) {\n return errorResponse(-32600, \"Invalid request\");\n }\n\n const { jsonrpc, method, params, id } = entry;\n\n if (jsonrpc !== \"2.0\" || typeof method !== \"string\") {\n const reqId = typeof id === \"string\" || typeof id === \"number\" ? id : null;\n return errorResponse(-32600, \"Invalid request\", reqId);\n }\n\n // Notification: id is absent/undefined\n const isNotification = !(\"id\" in entry) || id === undefined;\n\n if (isNotification) {\n if (onNotification) {\n onNotification(method, params);\n }\n // Invoke the method handler for side effects (e.g., MCP notifications/initialized),\n // but discard the result — notifications MUST NOT produce responses per JSON-RPC 2.0.\n const handler = methods[method];\n if (handler) {\n try {\n await handler(params, null as unknown as string | number, req);\n } catch (err: unknown) {\n console.warn(\"Notification handler error:\", err);\n }\n }\n return null;\n }\n\n const reqId = typeof id === \"string\" || typeof id === \"number\" ? id : null;\n\n const handler = methods[method];\n if (!handler) {\n return errorResponse(-32601, \"Method not found\", reqId);\n }\n\n try {\n const result = await handler(params, reqId as string | number, req);\n if (result) return result;\n return { jsonrpc: \"2.0\", id: reqId, result: null };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return errorResponse(-32603, `Internal error: ${msg}`, reqId);\n }\n}\n\nexport function createJsonRpcDispatcher(\n options: JsonRpcDispatcherOptions,\n): (req: http.IncomingMessage, res: http.ServerResponse, body: string) => Promise<void> {\n const { methods, onNotification } = options;\n\n return async (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n ): Promise<void> => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n const resp = errorResponse(-32700, \"Parse error\");\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(resp));\n return;\n }\n\n // Empty batch\n if (Array.isArray(parsed) && parsed.length === 0) {\n const resp = errorResponse(-32600, \"Invalid request\");\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(resp));\n return;\n }\n\n // Batch mode\n if (Array.isArray(parsed)) {\n const responses: JsonRpcResponse[] = [];\n for (const entry of parsed) {\n const result = await processOne(entry, methods, onNotification, req);\n if (result !== null) {\n responses.push(result);\n }\n }\n if (responses.length === 0) {\n res.writeHead(202);\n res.end(\"\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(responses));\n return;\n }\n\n // Single request\n const result = await processOne(parsed, methods, onNotification, req);\n if (result === null) {\n res.writeHead(202);\n res.end(\"\");\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(result));\n };\n}\n"],"mappings":";AAoBA,SAAS,cACP,MACA,SACA,KAA6B,MACZ;AACjB,QAAO;EAAE,SAAS;EAAO;EAAI,OAAO;GAAE;GAAM;GAAS;EAAE;;AAGzD,SAAS,SAAS,KAA8C;AAC9D,QAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI;;AAGvE,eAAe,WACb,OACA,SACA,gBACA,KACiC;AACjC,KAAI,CAAC,SAAS,MAAM,CAClB,QAAO,cAAc,QAAQ,kBAAkB;CAGjD,MAAM,EAAE,SAAS,QAAQ,QAAQ,OAAO;AAExC,KAAI,YAAY,SAAS,OAAO,WAAW,SAEzC,QAAO,cAAc,QAAQ,mBADf,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK,KAChB;AAMxD,KAFuB,EAAE,QAAQ,UAAU,OAAO,QAE9B;AAClB,MAAI,eACF,gBAAe,QAAQ,OAAO;EAIhC,MAAM,UAAU,QAAQ;AACxB,MAAI,QACF,KAAI;AACF,SAAM,QAAQ,QAAQ,MAAoC,IAAI;WACvD,KAAc;AACrB,WAAQ,KAAK,+BAA+B,IAAI;;AAGpD,SAAO;;CAGT,MAAM,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK;CAEtE,MAAM,UAAU,QAAQ;AACxB,KAAI,CAAC,QACH,QAAO,cAAc,QAAQ,oBAAoB,MAAM;AAGzD,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,QAAQ,OAA0B,IAAI;AACnE,MAAI,OAAQ,QAAO;AACnB,SAAO;GAAE,SAAS;GAAO,IAAI;GAAO,QAAQ;GAAM;UAC3C,KAAc;AAErB,SAAO,cAAc,QAAQ,mBADjB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,IACL,MAAM;;;AAIjE,SAAgB,wBACd,SACsF;CACtF,MAAM,EAAE,SAAS,mBAAmB;AAEpC,QAAO,OACL,KACA,KACA,SACkB;EAClB,IAAI;AACJ,MAAI;AACF,YAAS,KAAK,MAAM,KAAK;UACnB;GACN,MAAM,OAAO,cAAc,QAAQ,cAAc;AACjD,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,KAAK,CAAC;AAC7B;;AAIF,MAAI,MAAM,QAAQ,OAAO,IAAI,OAAO,WAAW,GAAG;GAChD,MAAM,OAAO,cAAc,QAAQ,kBAAkB;AACrD,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,KAAK,CAAC;AAC7B;;AAIF,MAAI,MAAM,QAAQ,OAAO,EAAE;GACzB,MAAM,YAA+B,EAAE;AACvC,QAAK,MAAM,SAAS,QAAQ;IAC1B,MAAM,SAAS,MAAM,WAAW,OAAO,SAAS,gBAAgB,IAAI;AACpE,QAAI,WAAW,KACb,WAAU,KAAK,OAAO;;AAG1B,OAAI,UAAU,WAAW,GAAG;AAC1B,QAAI,UAAU,IAAI;AAClB,QAAI,IAAI,GAAG;AACX;;AAEF,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,UAAU,CAAC;AAClC;;EAIF,MAAM,SAAS,MAAM,WAAW,QAAQ,SAAS,gBAAgB,IAAI;AACrE,MAAI,WAAW,MAAM;AACnB,OAAI,UAAU,IAAI;AAClB,OAAI,IAAI,GAAG;AACX;;AAEF,MAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,MAAI,IAAI,KAAK,UAAU,OAAO,CAAC"}
|
package/dist/llmock.cjs
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
const require_fixture_loader = require('./fixture-loader.cjs');
|
|
2
|
+
const require_server = require('./server.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/llmock.ts
|
|
5
|
+
var LLMock = class LLMock {
|
|
6
|
+
fixtures = [];
|
|
7
|
+
searchFixtures = [];
|
|
8
|
+
rerankFixtures = [];
|
|
9
|
+
moderationFixtures = [];
|
|
10
|
+
mounts = [];
|
|
11
|
+
serverInstance = null;
|
|
12
|
+
options;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options ?? {};
|
|
15
|
+
}
|
|
16
|
+
addFixture(fixture) {
|
|
17
|
+
this.fixtures.push(fixture);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
addFixtures(fixtures) {
|
|
21
|
+
this.fixtures.push(...fixtures);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
prependFixture(fixture) {
|
|
25
|
+
this.fixtures.unshift(fixture);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
getFixtures() {
|
|
29
|
+
return this.fixtures;
|
|
30
|
+
}
|
|
31
|
+
loadFixtureFile(filePath) {
|
|
32
|
+
this.fixtures.push(...require_fixture_loader.loadFixtureFile(filePath));
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
loadFixtureDir(dirPath) {
|
|
36
|
+
this.fixtures.push(...require_fixture_loader.loadFixturesFromDir(dirPath));
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Add fixtures from a JSON string or pre-parsed array of fixture entries.
|
|
41
|
+
* Validates all fixtures and throws if any have severity "error".
|
|
42
|
+
*/
|
|
43
|
+
addFixturesFromJSON(input) {
|
|
44
|
+
const converted = (typeof input === "string" ? JSON.parse(input) : input).map(require_fixture_loader.entryToFixture);
|
|
45
|
+
const errors = require_fixture_loader.validateFixtures(converted).filter((i) => i.severity === "error");
|
|
46
|
+
if (errors.length > 0) throw new Error(`Fixture validation failed: ${JSON.stringify(errors)}`);
|
|
47
|
+
this.fixtures.push(...converted);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
clearFixtures() {
|
|
51
|
+
this.fixtures.length = 0;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
on(match, response, opts) {
|
|
55
|
+
return this.addFixture({
|
|
56
|
+
match,
|
|
57
|
+
response,
|
|
58
|
+
...opts
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
onMessage(pattern, response, opts) {
|
|
62
|
+
return this.on({ userMessage: pattern }, response, opts);
|
|
63
|
+
}
|
|
64
|
+
onEmbedding(pattern, response, opts) {
|
|
65
|
+
return this.on({ inputText: pattern }, response, opts);
|
|
66
|
+
}
|
|
67
|
+
onJsonOutput(pattern, jsonContent, opts) {
|
|
68
|
+
const content = typeof jsonContent === "string" ? jsonContent : JSON.stringify(jsonContent);
|
|
69
|
+
return this.on({
|
|
70
|
+
userMessage: pattern,
|
|
71
|
+
responseFormat: "json_object"
|
|
72
|
+
}, { content }, opts);
|
|
73
|
+
}
|
|
74
|
+
onToolCall(name, response, opts) {
|
|
75
|
+
return this.on({ toolName: name }, response, opts);
|
|
76
|
+
}
|
|
77
|
+
onToolResult(id, response, opts) {
|
|
78
|
+
return this.on({ toolCallId: id }, response, opts);
|
|
79
|
+
}
|
|
80
|
+
onSearch(pattern, results) {
|
|
81
|
+
this.searchFixtures.push({
|
|
82
|
+
match: pattern,
|
|
83
|
+
results
|
|
84
|
+
});
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
onRerank(pattern, results) {
|
|
88
|
+
this.rerankFixtures.push({
|
|
89
|
+
match: pattern,
|
|
90
|
+
results
|
|
91
|
+
});
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
onModerate(pattern, result) {
|
|
95
|
+
this.moderationFixtures.push({
|
|
96
|
+
match: pattern,
|
|
97
|
+
result
|
|
98
|
+
});
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Queue a one-shot error that will be returned for the next matching
|
|
103
|
+
* request, then automatically removed. Implemented as an internal fixture
|
|
104
|
+
* with a `predicate` that always matches (so it fires first) and spliced
|
|
105
|
+
* at the front of the fixture list.
|
|
106
|
+
*/
|
|
107
|
+
nextRequestError(status, errorBody) {
|
|
108
|
+
const fixture = {
|
|
109
|
+
match: { predicate: () => true },
|
|
110
|
+
response: {
|
|
111
|
+
error: {
|
|
112
|
+
message: errorBody?.message ?? "Injected error",
|
|
113
|
+
type: errorBody?.type ?? "server_error",
|
|
114
|
+
code: errorBody?.code
|
|
115
|
+
},
|
|
116
|
+
status
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
this.fixtures.unshift(fixture);
|
|
120
|
+
const original = fixture.match.predicate;
|
|
121
|
+
fixture.match.predicate = (req) => {
|
|
122
|
+
const result = original(req);
|
|
123
|
+
if (result) queueMicrotask(() => {
|
|
124
|
+
const idx = this.fixtures.indexOf(fixture);
|
|
125
|
+
if (idx !== -1) this.fixtures.splice(idx, 1);
|
|
126
|
+
});
|
|
127
|
+
return result;
|
|
128
|
+
};
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
mount(path, handler) {
|
|
132
|
+
this.mounts.push({
|
|
133
|
+
path,
|
|
134
|
+
handler
|
|
135
|
+
});
|
|
136
|
+
if (this.serverInstance) {
|
|
137
|
+
if (handler.setJournal) handler.setJournal(this.serverInstance.journal);
|
|
138
|
+
if (handler.setBaseUrl) handler.setBaseUrl(this.serverInstance.url + path);
|
|
139
|
+
const registry = this.serverInstance.defaults.registry;
|
|
140
|
+
if (registry && handler.setRegistry) handler.setRegistry(registry);
|
|
141
|
+
}
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
getRequests() {
|
|
145
|
+
return this.journal.getAll();
|
|
146
|
+
}
|
|
147
|
+
getLastRequest() {
|
|
148
|
+
return this.journal.getLast();
|
|
149
|
+
}
|
|
150
|
+
clearRequests() {
|
|
151
|
+
this.journal.clear();
|
|
152
|
+
}
|
|
153
|
+
resetMatchCounts() {
|
|
154
|
+
if (this.serverInstance) this.serverInstance.journal.clearMatchCounts();
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
setChaos(config) {
|
|
158
|
+
this.options.chaos = config;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
clearChaos() {
|
|
162
|
+
delete this.options.chaos;
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
enableRecording(config) {
|
|
166
|
+
this.options.record = config;
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
disableRecording() {
|
|
170
|
+
delete this.options.record;
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
reset() {
|
|
174
|
+
this.clearFixtures();
|
|
175
|
+
this.searchFixtures.length = 0;
|
|
176
|
+
this.rerankFixtures.length = 0;
|
|
177
|
+
this.moderationFixtures.length = 0;
|
|
178
|
+
if (this.serverInstance) this.serverInstance.journal.clear();
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
async start() {
|
|
182
|
+
if (this.serverInstance) throw new Error("Server already started");
|
|
183
|
+
this.serverInstance = await require_server.createServer(this.fixtures, this.options, this.mounts, {
|
|
184
|
+
search: this.searchFixtures,
|
|
185
|
+
rerank: this.rerankFixtures,
|
|
186
|
+
moderation: this.moderationFixtures
|
|
187
|
+
});
|
|
188
|
+
return this.serverInstance.url;
|
|
189
|
+
}
|
|
190
|
+
async stop() {
|
|
191
|
+
if (!this.serverInstance) throw new Error("Server not started");
|
|
192
|
+
const { server } = this.serverInstance;
|
|
193
|
+
await new Promise((resolve, reject) => {
|
|
194
|
+
server.close((err) => err ? reject(err) : resolve());
|
|
195
|
+
});
|
|
196
|
+
this.serverInstance = null;
|
|
197
|
+
}
|
|
198
|
+
get journal() {
|
|
199
|
+
if (!this.serverInstance) throw new Error("Server not started");
|
|
200
|
+
return this.serverInstance.journal;
|
|
201
|
+
}
|
|
202
|
+
get url() {
|
|
203
|
+
if (!this.serverInstance) throw new Error("Server not started");
|
|
204
|
+
return this.serverInstance.url;
|
|
205
|
+
}
|
|
206
|
+
get baseUrl() {
|
|
207
|
+
return this.url;
|
|
208
|
+
}
|
|
209
|
+
get port() {
|
|
210
|
+
const parsed = new URL(this.url);
|
|
211
|
+
if (!parsed.port) throw new Error(`Server URL has no explicit port: ${this.url}`);
|
|
212
|
+
return parseInt(parsed.port, 10);
|
|
213
|
+
}
|
|
214
|
+
static async create(options) {
|
|
215
|
+
const instance = new LLMock(options);
|
|
216
|
+
await instance.start();
|
|
217
|
+
return instance;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
//#endregion
|
|
222
|
+
exports.LLMock = LLMock;
|
|
223
|
+
//# sourceMappingURL=llmock.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llmock.cjs","names":["loadFixtureFile","loadFixturesFromDir","entryToFixture","validateFixtures","createServer"],"sources":["../src/llmock.ts"],"sourcesContent":["import type {\n ChaosConfig,\n EmbeddingFixtureOpts,\n Fixture,\n FixtureFileEntry,\n FixtureMatch,\n FixtureOpts,\n FixtureResponse,\n MockServerOptions,\n Mountable,\n RecordConfig,\n} from \"./types.js\";\nimport { createServer, type ServerInstance } from \"./server.js\";\nimport {\n loadFixtureFile,\n loadFixturesFromDir,\n entryToFixture,\n validateFixtures,\n} from \"./fixture-loader.js\";\nimport { Journal } from \"./journal.js\";\nimport type { SearchFixture, SearchResult } from \"./search.js\";\nimport type { RerankFixture, RerankResult } from \"./rerank.js\";\nimport type { ModerationFixture, ModerationResult } from \"./moderation.js\";\n\nexport class LLMock {\n private fixtures: Fixture[] = [];\n private searchFixtures: SearchFixture[] = [];\n private rerankFixtures: RerankFixture[] = [];\n private moderationFixtures: ModerationFixture[] = [];\n private mounts: Array<{ path: string; handler: Mountable }> = [];\n private serverInstance: ServerInstance | null = null;\n private options: MockServerOptions;\n\n constructor(options?: MockServerOptions) {\n this.options = options ?? {};\n }\n\n // ---- Fixture management ----\n\n addFixture(fixture: Fixture): this {\n this.fixtures.push(fixture);\n return this;\n }\n\n addFixtures(fixtures: Fixture[]): this {\n this.fixtures.push(...fixtures);\n return this;\n }\n\n prependFixture(fixture: Fixture): this {\n this.fixtures.unshift(fixture);\n return this;\n }\n\n getFixtures(): readonly Fixture[] {\n return this.fixtures;\n }\n\n loadFixtureFile(filePath: string): this {\n this.fixtures.push(...loadFixtureFile(filePath));\n return this;\n }\n\n loadFixtureDir(dirPath: string): this {\n this.fixtures.push(...loadFixturesFromDir(dirPath));\n return this;\n }\n\n /**\n * Add fixtures from a JSON string or pre-parsed array of fixture entries.\n * Validates all fixtures and throws if any have severity \"error\".\n */\n addFixturesFromJSON(input: string | FixtureFileEntry[]): this {\n const entries: FixtureFileEntry[] = typeof input === \"string\" ? JSON.parse(input) : input;\n const converted = entries.map(entryToFixture);\n const issues = validateFixtures(converted);\n const errors = issues.filter((i) => i.severity === \"error\");\n if (errors.length > 0) {\n throw new Error(`Fixture validation failed: ${JSON.stringify(errors)}`);\n }\n this.fixtures.push(...converted);\n return this;\n }\n\n // Uses length = 0 to preserve array reference identity — the running\n // server reads this same array on every request.\n clearFixtures(): this {\n this.fixtures.length = 0;\n return this;\n }\n\n // ---- Convenience ----\n\n on(match: FixtureMatch, response: FixtureResponse, opts?: FixtureOpts): this {\n return this.addFixture({\n match,\n response,\n ...opts,\n });\n }\n\n onMessage(pattern: string | RegExp, response: FixtureResponse, opts?: FixtureOpts): this {\n return this.on({ userMessage: pattern }, response, opts);\n }\n\n onEmbedding(\n pattern: string | RegExp,\n response: FixtureResponse,\n opts?: EmbeddingFixtureOpts,\n ): this {\n return this.on({ inputText: pattern }, response, opts);\n }\n\n onJsonOutput(pattern: string | RegExp, jsonContent: object | string, opts?: FixtureOpts): this {\n const content = typeof jsonContent === \"string\" ? jsonContent : JSON.stringify(jsonContent);\n return this.on({ userMessage: pattern, responseFormat: \"json_object\" }, { content }, opts);\n }\n\n onToolCall(name: string, response: FixtureResponse, opts?: FixtureOpts): this {\n return this.on({ toolName: name }, response, opts);\n }\n\n onToolResult(id: string, response: FixtureResponse, opts?: FixtureOpts): this {\n return this.on({ toolCallId: id }, response, opts);\n }\n\n // ---- Service mock convenience methods ----\n\n onSearch(pattern: string | RegExp, results: SearchResult[]): this {\n this.searchFixtures.push({ match: pattern, results });\n return this;\n }\n\n onRerank(pattern: string | RegExp, results: RerankResult[]): this {\n this.rerankFixtures.push({ match: pattern, results });\n return this;\n }\n\n onModerate(pattern: string | RegExp, result: ModerationResult): this {\n this.moderationFixtures.push({ match: pattern, result });\n return this;\n }\n\n /**\n * Queue a one-shot error that will be returned for the next matching\n * request, then automatically removed. Implemented as an internal fixture\n * with a `predicate` that always matches (so it fires first) and spliced\n * at the front of the fixture list.\n */\n nextRequestError(\n status: number,\n errorBody?: { message?: string; type?: string; code?: string },\n ): this {\n const errorResponse: FixtureResponse = {\n error: {\n message: errorBody?.message ?? \"Injected error\",\n type: errorBody?.type ?? \"server_error\",\n code: errorBody?.code,\n },\n status,\n };\n const fixture: Fixture = {\n match: { predicate: () => true },\n response: errorResponse,\n };\n // Insert at front so it matches before everything else\n this.fixtures.unshift(fixture);\n // Remove after first match — the journal records it so tests can assert\n const original = fixture.match.predicate!;\n fixture.match.predicate = (req) => {\n const result = original(req);\n if (result) {\n // Defer splice so it doesn't mutate the array while matchFixture iterates it\n queueMicrotask(() => {\n const idx = this.fixtures.indexOf(fixture);\n if (idx !== -1) this.fixtures.splice(idx, 1);\n });\n }\n return result;\n };\n return this;\n }\n\n // ---- Mounts ----\n\n mount(path: string, handler: Mountable): this {\n this.mounts.push({ path, handler });\n\n // If server is already running, wire up journal, registry, and baseUrl immediately\n // so late mounts behave identically to pre-start mounts.\n if (this.serverInstance) {\n if (handler.setJournal) handler.setJournal(this.serverInstance.journal);\n if (handler.setBaseUrl) handler.setBaseUrl(this.serverInstance.url + path);\n const registry = this.serverInstance.defaults.registry;\n if (registry && handler.setRegistry) handler.setRegistry(registry);\n }\n\n return this;\n }\n\n // ---- Journal proxies ----\n\n getRequests(): import(\"./types.js\").JournalEntry[] {\n return this.journal.getAll();\n }\n\n getLastRequest(): import(\"./types.js\").JournalEntry | null {\n return this.journal.getLast();\n }\n\n clearRequests(): void {\n this.journal.clear();\n }\n\n resetMatchCounts(): this {\n if (this.serverInstance) {\n this.serverInstance.journal.clearMatchCounts();\n }\n return this;\n }\n\n // ---- Chaos ----\n\n setChaos(config: ChaosConfig): this {\n this.options.chaos = config;\n return this;\n }\n\n clearChaos(): this {\n delete this.options.chaos;\n return this;\n }\n\n // ---- Recording ----\n\n enableRecording(config: RecordConfig): this {\n this.options.record = config;\n return this;\n }\n\n disableRecording(): this {\n delete this.options.record;\n return this;\n }\n\n // ---- Reset ----\n\n reset(): this {\n this.clearFixtures();\n this.searchFixtures.length = 0;\n this.rerankFixtures.length = 0;\n this.moderationFixtures.length = 0;\n if (this.serverInstance) {\n this.serverInstance.journal.clear();\n }\n return this;\n }\n\n // ---- Server lifecycle ----\n\n async start(): Promise<string> {\n if (this.serverInstance) {\n throw new Error(\"Server already started\");\n }\n this.serverInstance = await createServer(this.fixtures, this.options, this.mounts, {\n search: this.searchFixtures,\n rerank: this.rerankFixtures,\n moderation: this.moderationFixtures,\n });\n return this.serverInstance.url;\n }\n\n async stop(): Promise<void> {\n if (!this.serverInstance) {\n throw new Error(\"Server not started\");\n }\n const { server } = this.serverInstance;\n await new Promise<void>((resolve, reject) => {\n server.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.serverInstance = null;\n }\n\n // ---- Accessors ----\n\n get journal(): Journal {\n if (!this.serverInstance) {\n throw new Error(\"Server not started\");\n }\n return this.serverInstance.journal;\n }\n\n get url(): string {\n if (!this.serverInstance) {\n throw new Error(\"Server not started\");\n }\n return this.serverInstance.url;\n }\n\n get baseUrl(): string {\n return this.url;\n }\n\n get port(): number {\n const parsed = new URL(this.url); // this.url throws if not started\n if (!parsed.port) {\n throw new Error(`Server URL has no explicit port: ${this.url}`);\n }\n return parseInt(parsed.port, 10);\n }\n\n // ---- Static factory ----\n\n static async create(options?: MockServerOptions): Promise<LLMock> {\n const instance = new LLMock(options);\n await instance.start();\n return instance;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Journal } from "./journal.cjs";
|
|
2
|
+
import { ChaosConfig, EmbeddingFixtureOpts, Fixture, FixtureFileEntry, FixtureMatch, FixtureOpts, FixtureResponse, JournalEntry, MockServerOptions, Mountable, RecordConfig } from "./types.cjs";
|
|
3
|
+
import { SearchResult } from "./search.cjs";
|
|
4
|
+
import { RerankResult } from "./rerank.cjs";
|
|
5
|
+
import { ModerationResult } from "./moderation.cjs";
|
|
6
|
+
|
|
7
|
+
//#region src/llmock.d.ts
|
|
8
|
+
declare class LLMock {
|
|
9
|
+
private fixtures;
|
|
10
|
+
private searchFixtures;
|
|
11
|
+
private rerankFixtures;
|
|
12
|
+
private moderationFixtures;
|
|
13
|
+
private mounts;
|
|
14
|
+
private serverInstance;
|
|
15
|
+
private options;
|
|
16
|
+
constructor(options?: MockServerOptions);
|
|
17
|
+
addFixture(fixture: Fixture): this;
|
|
18
|
+
addFixtures(fixtures: Fixture[]): this;
|
|
19
|
+
prependFixture(fixture: Fixture): this;
|
|
20
|
+
getFixtures(): readonly Fixture[];
|
|
21
|
+
loadFixtureFile(filePath: string): this;
|
|
22
|
+
loadFixtureDir(dirPath: string): this;
|
|
23
|
+
/**
|
|
24
|
+
* Add fixtures from a JSON string or pre-parsed array of fixture entries.
|
|
25
|
+
* Validates all fixtures and throws if any have severity "error".
|
|
26
|
+
*/
|
|
27
|
+
addFixturesFromJSON(input: string | FixtureFileEntry[]): this;
|
|
28
|
+
clearFixtures(): this;
|
|
29
|
+
on(match: FixtureMatch, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
30
|
+
onMessage(pattern: string | RegExp, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
31
|
+
onEmbedding(pattern: string | RegExp, response: FixtureResponse, opts?: EmbeddingFixtureOpts): this;
|
|
32
|
+
onJsonOutput(pattern: string | RegExp, jsonContent: object | string, opts?: FixtureOpts): this;
|
|
33
|
+
onToolCall(name: string, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
34
|
+
onToolResult(id: string, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
35
|
+
onSearch(pattern: string | RegExp, results: SearchResult[]): this;
|
|
36
|
+
onRerank(pattern: string | RegExp, results: RerankResult[]): this;
|
|
37
|
+
onModerate(pattern: string | RegExp, result: ModerationResult): this;
|
|
38
|
+
/**
|
|
39
|
+
* Queue a one-shot error that will be returned for the next matching
|
|
40
|
+
* request, then automatically removed. Implemented as an internal fixture
|
|
41
|
+
* with a `predicate` that always matches (so it fires first) and spliced
|
|
42
|
+
* at the front of the fixture list.
|
|
43
|
+
*/
|
|
44
|
+
nextRequestError(status: number, errorBody?: {
|
|
45
|
+
message?: string;
|
|
46
|
+
type?: string;
|
|
47
|
+
code?: string;
|
|
48
|
+
}): this;
|
|
49
|
+
mount(path: string, handler: Mountable): this;
|
|
50
|
+
getRequests(): JournalEntry[];
|
|
51
|
+
getLastRequest(): JournalEntry | null;
|
|
52
|
+
clearRequests(): void;
|
|
53
|
+
resetMatchCounts(): this;
|
|
54
|
+
setChaos(config: ChaosConfig): this;
|
|
55
|
+
clearChaos(): this;
|
|
56
|
+
enableRecording(config: RecordConfig): this;
|
|
57
|
+
disableRecording(): this;
|
|
58
|
+
reset(): this;
|
|
59
|
+
start(): Promise<string>;
|
|
60
|
+
stop(): Promise<void>;
|
|
61
|
+
get journal(): Journal;
|
|
62
|
+
get url(): string;
|
|
63
|
+
get baseUrl(): string;
|
|
64
|
+
get port(): number;
|
|
65
|
+
static create(options?: MockServerOptions): Promise<LLMock>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=llmock.d.ts.map
|
|
68
|
+
//#endregion
|
|
69
|
+
export { LLMock };
|
|
70
|
+
//# sourceMappingURL=llmock.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llmock.d.cts","names":[],"sources":["../src/llmock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAwBa,MAAA;;EAAA,QAAA,cAAM;EAAA,QAAA,cAAA;UASK,kBAAA;UAMF,MAAA;UAKE,cAAA;UAKE,OAAA;aAKA,CAAA,OAAA,CAAA,EArBF,iBAqBE;YAkBY,CAAA,OAAA,EAjChB,OAiCgB,CAAA,EAAA,IAAA;aAqB1B,CAAA,QAAA,EAjDY,OAiDZ,EAAA,CAAA,EAAA,IAAA;gBAAwB,CAAA,OAAA,EA5CV,OA4CU,CAAA,EAAA,IAAA;aAAwB,CAAA,CAAA,EAAA,SAvClC,OAuCkC,EAAA;iBAQ9B,CAAA,QAAA,EAAA,MAAA,CAAA,EAAA,IAAA;gBAAkB,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;;qBAYf,CAAA,KAAA,EAAA,MAAA,GAzCK,gBAyCL,EAAA,CAAA,EAAA,IAAA;eAA6C,CAAA,CAAA,EAAA,IAAA;KAKzC,KAAA,EAzBzB,YAyByB,EAAA,QAAA,EAzBD,eAyBC,EAAA,IAAA,CAAA,EAzBuB,WAyBvB,CAAA,EAAA,IAAA;WAAwB,CAAA,OAAA,EAAA,MAAA,GAjB/B,MAiB+B,EAAA,QAAA,EAjBb,eAiBa,EAAA,IAAA,CAAA,EAjBW,WAiBX,CAAA,EAAA,IAAA;aAIxB,CAAA,OAAA,EAAA,MAAA,GAhBf,MAgBe,EAAA,QAAA,EAfvB,eAeuB,EAAA,IAAA,CAAA,EAd1B,oBAc0B,CAAA,EAAA,IAAA;cAAwB,CAAA,OAAA,EAAA,MAAA,GAT5B,MAS4B,EAAA,WAAA,EAAA,MAAA,GAAA,MAAA,EAAA,IAAA,CAAA,EATiB,WASjB,CAAA,EAAA,IAAA;YAMhC,CAAA,IAAA,EAAA,MAAA,EAAA,QAAA,EAVQ,eAUR,EAAA,IAAA,CAAA,EAVgC,WAUhC,CAAA,EAAA,IAAA;cAAiB,CAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EANT,eAMS,EAAA,IAAA,CAAA,EANe,WAMf,CAAA,EAAA,IAAA;UAKjB,CAAA,OAAA,EAAA,MAAA,GALA,MAKA,EAAA,OAAA,EALiB,YAKjB,EAAA,CAAA,EAAA,IAAA;UAAiB,CAAA,OAAA,EAAA,MAAA,GAAjB,MAAiB,EAAA,OAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA;YAKf,CAAA,OAAA,EAAA,MAAA,GAAA,MAAA,EAAA,MAAA,EAAgB,gBAAhB,CAAA,EAAA,IAAA;;;;;;;kBA0Hd,CAAA,MAAA,EAAA,MAAA,EAAA,UAAA,EAAA;IAYD,OAAA,CAAA,EAAA,MAAA;IAaC,IAAA,CAAA,EAAA,MAAA;IA4Be,IAAA,CAAA,EAAA,MAAA;MAA4B,IAAA;OAAR,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAhIrB,SAgIqB,CAAA,EAAA,IAAA;EAAO,WAAA,CAAA,CAAA,EAhInB,YAAA,EAgImB;oBA/GT,YAAA;;;mBAqB/B;;0BAYO;;;WAyBT;UAYD;iBAaC;;;;0BA4Be,oBAAoB,QAAQ"}
|
package/dist/llmock.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Journal } from "./journal.js";
|
|
2
|
+
import { ChaosConfig, EmbeddingFixtureOpts, Fixture, FixtureFileEntry, FixtureMatch, FixtureOpts, FixtureResponse, JournalEntry, MockServerOptions, Mountable, RecordConfig } from "./types.js";
|
|
3
|
+
import { SearchResult } from "./search.js";
|
|
4
|
+
import { RerankResult } from "./rerank.js";
|
|
5
|
+
import { ModerationResult } from "./moderation.js";
|
|
6
|
+
|
|
7
|
+
//#region src/llmock.d.ts
|
|
8
|
+
declare class LLMock {
|
|
9
|
+
private fixtures;
|
|
10
|
+
private searchFixtures;
|
|
11
|
+
private rerankFixtures;
|
|
12
|
+
private moderationFixtures;
|
|
13
|
+
private mounts;
|
|
14
|
+
private serverInstance;
|
|
15
|
+
private options;
|
|
16
|
+
constructor(options?: MockServerOptions);
|
|
17
|
+
addFixture(fixture: Fixture): this;
|
|
18
|
+
addFixtures(fixtures: Fixture[]): this;
|
|
19
|
+
prependFixture(fixture: Fixture): this;
|
|
20
|
+
getFixtures(): readonly Fixture[];
|
|
21
|
+
loadFixtureFile(filePath: string): this;
|
|
22
|
+
loadFixtureDir(dirPath: string): this;
|
|
23
|
+
/**
|
|
24
|
+
* Add fixtures from a JSON string or pre-parsed array of fixture entries.
|
|
25
|
+
* Validates all fixtures and throws if any have severity "error".
|
|
26
|
+
*/
|
|
27
|
+
addFixturesFromJSON(input: string | FixtureFileEntry[]): this;
|
|
28
|
+
clearFixtures(): this;
|
|
29
|
+
on(match: FixtureMatch, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
30
|
+
onMessage(pattern: string | RegExp, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
31
|
+
onEmbedding(pattern: string | RegExp, response: FixtureResponse, opts?: EmbeddingFixtureOpts): this;
|
|
32
|
+
onJsonOutput(pattern: string | RegExp, jsonContent: object | string, opts?: FixtureOpts): this;
|
|
33
|
+
onToolCall(name: string, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
34
|
+
onToolResult(id: string, response: FixtureResponse, opts?: FixtureOpts): this;
|
|
35
|
+
onSearch(pattern: string | RegExp, results: SearchResult[]): this;
|
|
36
|
+
onRerank(pattern: string | RegExp, results: RerankResult[]): this;
|
|
37
|
+
onModerate(pattern: string | RegExp, result: ModerationResult): this;
|
|
38
|
+
/**
|
|
39
|
+
* Queue a one-shot error that will be returned for the next matching
|
|
40
|
+
* request, then automatically removed. Implemented as an internal fixture
|
|
41
|
+
* with a `predicate` that always matches (so it fires first) and spliced
|
|
42
|
+
* at the front of the fixture list.
|
|
43
|
+
*/
|
|
44
|
+
nextRequestError(status: number, errorBody?: {
|
|
45
|
+
message?: string;
|
|
46
|
+
type?: string;
|
|
47
|
+
code?: string;
|
|
48
|
+
}): this;
|
|
49
|
+
mount(path: string, handler: Mountable): this;
|
|
50
|
+
getRequests(): JournalEntry[];
|
|
51
|
+
getLastRequest(): JournalEntry | null;
|
|
52
|
+
clearRequests(): void;
|
|
53
|
+
resetMatchCounts(): this;
|
|
54
|
+
setChaos(config: ChaosConfig): this;
|
|
55
|
+
clearChaos(): this;
|
|
56
|
+
enableRecording(config: RecordConfig): this;
|
|
57
|
+
disableRecording(): this;
|
|
58
|
+
reset(): this;
|
|
59
|
+
start(): Promise<string>;
|
|
60
|
+
stop(): Promise<void>;
|
|
61
|
+
get journal(): Journal;
|
|
62
|
+
get url(): string;
|
|
63
|
+
get baseUrl(): string;
|
|
64
|
+
get port(): number;
|
|
65
|
+
static create(options?: MockServerOptions): Promise<LLMock>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=llmock.d.ts.map
|
|
68
|
+
//#endregion
|
|
69
|
+
export { LLMock };
|
|
70
|
+
//# sourceMappingURL=llmock.d.ts.map
|