@jterrazz/test 6.1.0 → 6.3.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/README.md +9 -9
- package/dist/index.cjs +66 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.js +66 -14
- package/dist/index.js.map +1 -1
- package/dist/intercept.cjs +240 -0
- package/dist/intercept.cjs.map +1 -0
- package/dist/intercept.d.cts +89 -0
- package/dist/intercept.d.ts +89 -0
- package/dist/intercept.js +237 -0
- package/dist/intercept.js.map +1 -0
- package/dist/server.cjs +79 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.js +79 -0
- package/dist/server.js.map +1 -0
- package/dist/sqlite.adapter.cjs +22 -3
- package/dist/sqlite.adapter.cjs.map +1 -1
- package/dist/sqlite.adapter.js +22 -3
- package/dist/sqlite.adapter.js.map +1 -1
- package/dist/types.d.cts +35 -0
- package/dist/types.d.ts +35 -0
- package/package.json +6 -1
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/intercept/anthropic.ts
|
|
3
|
+
const ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
4
|
+
function matchesFilter$1(body, filter) {
|
|
5
|
+
if (filter.model) {
|
|
6
|
+
const model = body?.model;
|
|
7
|
+
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
8
|
+
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
9
|
+
}
|
|
10
|
+
if (filter.system) {
|
|
11
|
+
const system = typeof body?.system === "string" ? body.system : "";
|
|
12
|
+
if (typeof filter.system === "string" && !system.includes(filter.system)) return false;
|
|
13
|
+
if (filter.system instanceof RegExp && !filter.system.test(system)) return false;
|
|
14
|
+
}
|
|
15
|
+
if (filter.user) {
|
|
16
|
+
const userMsg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
17
|
+
const text = typeof userMsg === "string" ? userMsg : JSON.stringify(userMsg);
|
|
18
|
+
if (typeof filter.user === "string" && !text.includes(filter.user)) return false;
|
|
19
|
+
if (filter.user instanceof RegExp && !filter.user.test(text)) return false;
|
|
20
|
+
}
|
|
21
|
+
if (filter.tools) {
|
|
22
|
+
const requestTools = body?.tools?.map((t) => t.name).filter(Boolean) ?? [];
|
|
23
|
+
if (!filter.tools.every((t) => requestTools.includes(t))) return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Anthropic API intercept helpers.
|
|
29
|
+
*/
|
|
30
|
+
const anthropic = {
|
|
31
|
+
messages(filter) {
|
|
32
|
+
return {
|
|
33
|
+
method: "POST",
|
|
34
|
+
url: ANTHROPIC_MESSAGES_URL,
|
|
35
|
+
match: filter ? (body) => matchesFilter$1(body, filter) : void 0
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
response(data) {
|
|
39
|
+
return {
|
|
40
|
+
status: 200,
|
|
41
|
+
body: {
|
|
42
|
+
id: "msg-test",
|
|
43
|
+
type: "message",
|
|
44
|
+
role: "assistant",
|
|
45
|
+
content: [{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: typeof data === "string" ? data : JSON.stringify(data)
|
|
48
|
+
}],
|
|
49
|
+
model: "claude-sonnet-4-20250514",
|
|
50
|
+
stop_reason: "end_turn",
|
|
51
|
+
usage: {
|
|
52
|
+
input_tokens: 10,
|
|
53
|
+
output_tokens: 10
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
error(status, message) {
|
|
59
|
+
return {
|
|
60
|
+
status,
|
|
61
|
+
body: {
|
|
62
|
+
type: "error",
|
|
63
|
+
error: {
|
|
64
|
+
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
65
|
+
message: message ?? `Anthropic error (${status})`
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
timeout() {
|
|
71
|
+
return {
|
|
72
|
+
status: 200,
|
|
73
|
+
body: {},
|
|
74
|
+
delay: 3e4
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/intercept/http.ts
|
|
80
|
+
/**
|
|
81
|
+
* Generic HTTP intercept helpers for any URL.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* .intercept(http.get('https://api.example.com/data'), { body: [...] })
|
|
85
|
+
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
86
|
+
*/
|
|
87
|
+
const http = {
|
|
88
|
+
get(url) {
|
|
89
|
+
return {
|
|
90
|
+
method: "GET",
|
|
91
|
+
url
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
post(url) {
|
|
95
|
+
return {
|
|
96
|
+
method: "POST",
|
|
97
|
+
url
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
put(url) {
|
|
101
|
+
return {
|
|
102
|
+
method: "PUT",
|
|
103
|
+
url
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
delete(url) {
|
|
107
|
+
return {
|
|
108
|
+
method: "DELETE",
|
|
109
|
+
url
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
any(url) {
|
|
113
|
+
return {
|
|
114
|
+
method: "*",
|
|
115
|
+
url
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
json(data, status = 200) {
|
|
119
|
+
return {
|
|
120
|
+
status,
|
|
121
|
+
body: data
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
error(status, message) {
|
|
125
|
+
return {
|
|
126
|
+
status,
|
|
127
|
+
body: { error: message ?? `HTTP ${status}` }
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/intercept/openai.ts
|
|
133
|
+
const OPENAI_CHAT_URL = "https://api.openai.com/v1/chat/completions";
|
|
134
|
+
function matchesFilter(body, filter) {
|
|
135
|
+
if (filter.model) {
|
|
136
|
+
const model = body?.model;
|
|
137
|
+
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
138
|
+
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
139
|
+
}
|
|
140
|
+
if (filter.system) {
|
|
141
|
+
const systemMsg = body?.messages?.find((m) => m.role === "system")?.content ?? "";
|
|
142
|
+
if (typeof filter.system === "string" && !systemMsg.includes(filter.system)) return false;
|
|
143
|
+
if (filter.system instanceof RegExp && !filter.system.test(systemMsg)) return false;
|
|
144
|
+
}
|
|
145
|
+
if (filter.user) {
|
|
146
|
+
const userMsg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
147
|
+
if (typeof filter.user === "string" && !userMsg.includes(filter.user)) return false;
|
|
148
|
+
if (filter.user instanceof RegExp && !filter.user.test(userMsg)) return false;
|
|
149
|
+
}
|
|
150
|
+
if (filter.tools) {
|
|
151
|
+
const requestTools = body?.tools?.map((t) => t.function?.name).filter(Boolean) ?? [];
|
|
152
|
+
if (!filter.tools.every((t) => requestTools.includes(t))) return false;
|
|
153
|
+
}
|
|
154
|
+
if (filter.temperature !== void 0 && body?.temperature !== filter.temperature) return false;
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* OpenAI API intercept helpers.
|
|
159
|
+
*/
|
|
160
|
+
const openai = {
|
|
161
|
+
chat(filter) {
|
|
162
|
+
return {
|
|
163
|
+
method: "POST",
|
|
164
|
+
url: OPENAI_CHAT_URL,
|
|
165
|
+
match: filter ? (body) => matchesFilter(body, filter) : void 0
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
response(data) {
|
|
169
|
+
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
170
|
+
return {
|
|
171
|
+
status: 200,
|
|
172
|
+
body: {
|
|
173
|
+
id: "chatcmpl-test",
|
|
174
|
+
object: "chat.completion",
|
|
175
|
+
created: Math.floor(Date.now() / 1e3),
|
|
176
|
+
model: "gpt-4o-test",
|
|
177
|
+
choices: [{
|
|
178
|
+
index: 0,
|
|
179
|
+
message: {
|
|
180
|
+
role: "assistant",
|
|
181
|
+
content
|
|
182
|
+
},
|
|
183
|
+
finish_reason: "stop"
|
|
184
|
+
}],
|
|
185
|
+
usage: {
|
|
186
|
+
prompt_tokens: 10,
|
|
187
|
+
completion_tokens: 10,
|
|
188
|
+
total_tokens: 20
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
error(status, message) {
|
|
194
|
+
return {
|
|
195
|
+
status,
|
|
196
|
+
body: { error: {
|
|
197
|
+
message: message ?? `OpenAI error (${status})`,
|
|
198
|
+
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
199
|
+
code: status === 429 ? "rate_limit_exceeded" : null
|
|
200
|
+
} }
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
malformed(content) {
|
|
204
|
+
return {
|
|
205
|
+
status: 200,
|
|
206
|
+
body: {
|
|
207
|
+
id: "chatcmpl-test",
|
|
208
|
+
object: "chat.completion",
|
|
209
|
+
created: Math.floor(Date.now() / 1e3),
|
|
210
|
+
model: "gpt-4o-test",
|
|
211
|
+
choices: [{
|
|
212
|
+
index: 0,
|
|
213
|
+
message: {
|
|
214
|
+
role: "assistant",
|
|
215
|
+
content
|
|
216
|
+
},
|
|
217
|
+
finish_reason: "stop"
|
|
218
|
+
}],
|
|
219
|
+
usage: {
|
|
220
|
+
prompt_tokens: 10,
|
|
221
|
+
completion_tokens: 10,
|
|
222
|
+
total_tokens: 20
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
timeout() {
|
|
228
|
+
return {
|
|
229
|
+
status: 200,
|
|
230
|
+
body: {},
|
|
231
|
+
delay: 3e4
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
//#endregion
|
|
236
|
+
exports.anthropic = anthropic;
|
|
237
|
+
exports.http = http;
|
|
238
|
+
exports.openai = openai;
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=intercept.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intercept.cjs","names":["matchesFilter"],"sources":["../src/intercept/anthropic.ts","../src/intercept/http.ts","../src/intercept/openai.ts"],"sourcesContent":["import type { InterceptResponse, InterceptTrigger } from './types.js';\n\nconst ANTHROPIC_MESSAGES_URL = 'https://api.anthropic.com/v1/messages';\n\nexport interface AnthropicMessagesFilter {\n /** Match by model name. */\n model?: RegExp | string;\n /** Match by system message content. */\n system?: RegExp | string;\n /** Match by user message content. */\n user?: RegExp | string;\n /** Match by tool names. */\n tools?: string[];\n}\n\nfunction matchesFilter(body: any, filter: AnthropicMessagesFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n\n if (filter.system) {\n const system = typeof body?.system === 'string' ? body.system : '';\n if (typeof filter.system === 'string' && !system.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(system)) {\n return false;\n }\n }\n\n if (filter.user) {\n const userMsg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n const text = typeof userMsg === 'string' ? userMsg : JSON.stringify(userMsg);\n if (typeof filter.user === 'string' && !text.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(text)) {\n return false;\n }\n }\n\n if (filter.tools) {\n const requestTools = body?.tools?.map((t: any) => t.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => requestTools.includes(t))) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Anthropic API intercept helpers.\n */\nexport const anthropic = {\n /**\n * Trigger: match Anthropic messages API requests.\n */\n messages(filter?: AnthropicMessagesFilter): InterceptTrigger {\n return {\n method: 'POST',\n url: ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n };\n },\n\n /** Response: wrap data in Anthropic messages format. */\n response(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'msg-test',\n type: 'message',\n role: 'assistant',\n content: [{ type: 'text', text: content }],\n model: 'claude-sonnet-4-20250514',\n stop_reason: 'end_turn',\n usage: { input_tokens: 10, output_tokens: 10 },\n },\n };\n },\n\n /** Response: return an Anthropic error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n type: 'error',\n error: {\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n message: message ?? `Anthropic error (${status})`,\n },\n },\n };\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n};\n","import type { InterceptResponse, InterceptTrigger } from './types.js';\n\n/**\n * Generic HTTP intercept helpers for any URL.\n *\n * @example\n * .intercept(http.get('https://api.example.com/data'), { body: [...] })\n * .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })\n */\nexport const http = {\n /** Trigger: match GET requests to a URL pattern. */\n get(url: RegExp | string): InterceptTrigger {\n return { method: 'GET', url };\n },\n\n /** Trigger: match POST requests to a URL pattern. */\n post(url: RegExp | string): InterceptTrigger {\n return { method: 'POST', url };\n },\n\n /** Trigger: match PUT requests to a URL pattern. */\n put(url: RegExp | string): InterceptTrigger {\n return { method: 'PUT', url };\n },\n\n /** Trigger: match DELETE requests to a URL pattern. */\n delete(url: RegExp | string): InterceptTrigger {\n return { method: 'DELETE', url };\n },\n\n /** Trigger: match any method to a URL pattern. */\n any(url: RegExp | string): InterceptTrigger {\n return { method: '*', url };\n },\n\n /** Response: simple JSON success. */\n json(data: unknown, status = 200): InterceptResponse {\n return { status, body: data };\n },\n\n /** Response: error with message. */\n error(status: number, message?: string): InterceptResponse {\n return { status, body: { error: message ?? `HTTP ${status}` } };\n },\n};\n","import type { InterceptResponse, InterceptTrigger } from './types.js';\n\nconst OPENAI_CHAT_URL = 'https://api.openai.com/v1/chat/completions';\n\nexport interface OpenAIChatFilter {\n /** Match by model name (exact string or regex). */\n model?: RegExp | string;\n /** Match by system message content (regex or substring). */\n system?: RegExp | string;\n /** Match by user message content (regex or substring). */\n user?: RegExp | string;\n /** Match by tool/function names present in the request. */\n tools?: string[];\n /** Match by temperature value. */\n temperature?: number;\n}\n\nfunction matchesFilter(body: any, filter: OpenAIChatFilter): boolean {\n if (filter.model) {\n const model = body?.model;\n if (typeof filter.model === 'string' && model !== filter.model) {\n return false;\n }\n if (filter.model instanceof RegExp && !filter.model.test(model ?? '')) {\n return false;\n }\n }\n\n if (filter.system) {\n const systemMsg = body?.messages?.find((m: any) => m.role === 'system')?.content ?? '';\n if (typeof filter.system === 'string' && !systemMsg.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(systemMsg)) {\n return false;\n }\n }\n\n if (filter.user) {\n const userMsg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n if (typeof filter.user === 'string' && !userMsg.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(userMsg)) {\n return false;\n }\n }\n\n if (filter.tools) {\n const requestTools = body?.tools?.map((t: any) => t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => requestTools.includes(t))) {\n return false;\n }\n }\n\n if (filter.temperature !== undefined && body?.temperature !== filter.temperature) {\n return false;\n }\n\n return true;\n}\n\n/**\n * OpenAI API intercept helpers.\n */\nexport const openai = {\n /**\n * Trigger: match OpenAI chat completion requests.\n *\n * @param filter - Optional filters to narrow which requests match.\n *\n * @example\n * openai.chat() // any chat call\n * openai.chat({ model: 'gpt-4o' }) // specific model\n * openai.chat({ system: /classify/ }) // system prompt contains \"classify\"\n * openai.chat({ tools: ['extract_facts'] }) // function calling\n */\n chat(filter?: OpenAIChatFilter): InterceptTrigger {\n return {\n method: 'POST',\n url: OPENAI_CHAT_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n };\n },\n\n /**\n * Response: wrap data in OpenAI chat completion format.\n *\n * @param data - The content to return (will be JSON.stringified if not a string).\n *\n * @example\n * openai.response({ categories: ['TECH'] })\n */\n response(data: unknown): InterceptResponse {\n const content = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'chatcmpl-test',\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n choices: [\n {\n index: 0,\n message: { role: 'assistant', content },\n finish_reason: 'stop',\n },\n ],\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n },\n };\n },\n\n /** Response: return an OpenAI error. */\n error(status: number, message?: string): InterceptResponse {\n return {\n status,\n body: {\n error: {\n message: message ?? `OpenAI error (${status})`,\n type: status === 429 ? 'rate_limit_error' : 'api_error',\n code: status === 429 ? 'rate_limit_exceeded' : null,\n },\n },\n };\n },\n\n /** Response: return malformed (non-JSON) content. */\n malformed(content: string): InterceptResponse {\n return {\n status: 200,\n body: {\n id: 'chatcmpl-test',\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n choices: [\n {\n index: 0,\n message: { role: 'assistant', content },\n finish_reason: 'stop',\n },\n ],\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n },\n };\n },\n\n /** Response: simulate a timeout (30s delay). */\n timeout(): InterceptResponse {\n return {\n status: 200,\n body: {},\n delay: 30_000,\n };\n },\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { n as InterceptResponse, r as InterceptTrigger, t as InterceptEntry } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/intercept/anthropic.d.ts
|
|
4
|
+
interface AnthropicMessagesFilter {
|
|
5
|
+
/** Match by model name. */
|
|
6
|
+
model?: RegExp | string;
|
|
7
|
+
/** Match by system message content. */
|
|
8
|
+
system?: RegExp | string;
|
|
9
|
+
/** Match by user message content. */
|
|
10
|
+
user?: RegExp | string;
|
|
11
|
+
/** Match by tool names. */
|
|
12
|
+
tools?: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Anthropic API intercept helpers.
|
|
16
|
+
*/
|
|
17
|
+
declare const anthropic: {
|
|
18
|
+
/**
|
|
19
|
+
* Trigger: match Anthropic messages API requests.
|
|
20
|
+
*/
|
|
21
|
+
messages(filter?: AnthropicMessagesFilter): InterceptTrigger; /** Response: wrap data in Anthropic messages format. */
|
|
22
|
+
response(data: unknown): InterceptResponse; /** Response: return an Anthropic error. */
|
|
23
|
+
error(status: number, message?: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
24
|
+
timeout(): InterceptResponse;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/intercept/http.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Generic HTTP intercept helpers for any URL.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* .intercept(http.get('https://api.example.com/data'), { body: [...] })
|
|
33
|
+
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
34
|
+
*/
|
|
35
|
+
declare const http: {
|
|
36
|
+
/** Trigger: match GET requests to a URL pattern. */get(url: RegExp | string): InterceptTrigger; /** Trigger: match POST requests to a URL pattern. */
|
|
37
|
+
post(url: RegExp | string): InterceptTrigger; /** Trigger: match PUT requests to a URL pattern. */
|
|
38
|
+
put(url: RegExp | string): InterceptTrigger; /** Trigger: match DELETE requests to a URL pattern. */
|
|
39
|
+
delete(url: RegExp | string): InterceptTrigger; /** Trigger: match any method to a URL pattern. */
|
|
40
|
+
any(url: RegExp | string): InterceptTrigger; /** Response: simple JSON success. */
|
|
41
|
+
json(data: unknown, status?: number): InterceptResponse; /** Response: error with message. */
|
|
42
|
+
error(status: number, message?: string): InterceptResponse;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/intercept/openai.d.ts
|
|
46
|
+
interface OpenAIChatFilter {
|
|
47
|
+
/** Match by model name (exact string or regex). */
|
|
48
|
+
model?: RegExp | string;
|
|
49
|
+
/** Match by system message content (regex or substring). */
|
|
50
|
+
system?: RegExp | string;
|
|
51
|
+
/** Match by user message content (regex or substring). */
|
|
52
|
+
user?: RegExp | string;
|
|
53
|
+
/** Match by tool/function names present in the request. */
|
|
54
|
+
tools?: string[];
|
|
55
|
+
/** Match by temperature value. */
|
|
56
|
+
temperature?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* OpenAI API intercept helpers.
|
|
60
|
+
*/
|
|
61
|
+
declare const openai: {
|
|
62
|
+
/**
|
|
63
|
+
* Trigger: match OpenAI chat completion requests.
|
|
64
|
+
*
|
|
65
|
+
* @param filter - Optional filters to narrow which requests match.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* openai.chat() // any chat call
|
|
69
|
+
* openai.chat({ model: 'gpt-4o' }) // specific model
|
|
70
|
+
* openai.chat({ system: /classify/ }) // system prompt contains "classify"
|
|
71
|
+
* openai.chat({ tools: ['extract_facts'] }) // function calling
|
|
72
|
+
*/
|
|
73
|
+
chat(filter?: OpenAIChatFilter): InterceptTrigger;
|
|
74
|
+
/**
|
|
75
|
+
* Response: wrap data in OpenAI chat completion format.
|
|
76
|
+
*
|
|
77
|
+
* @param data - The content to return (will be JSON.stringified if not a string).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* openai.response({ categories: ['TECH'] })
|
|
81
|
+
*/
|
|
82
|
+
response(data: unknown): InterceptResponse; /** Response: return an OpenAI error. */
|
|
83
|
+
error(status: number, message?: string): InterceptResponse; /** Response: return malformed (non-JSON) content. */
|
|
84
|
+
malformed(content: string): InterceptResponse; /** Response: simulate a timeout (30s delay). */
|
|
85
|
+
timeout(): InterceptResponse;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { type InterceptEntry, type InterceptResponse, type InterceptTrigger, anthropic, http, openai };
|
|
89
|
+
//# sourceMappingURL=intercept.d.cts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { n as InterceptResponse, r as InterceptTrigger, t as InterceptEntry } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/intercept/anthropic.d.ts
|
|
4
|
+
interface AnthropicMessagesFilter {
|
|
5
|
+
/** Match by model name. */
|
|
6
|
+
model?: RegExp | string;
|
|
7
|
+
/** Match by system message content. */
|
|
8
|
+
system?: RegExp | string;
|
|
9
|
+
/** Match by user message content. */
|
|
10
|
+
user?: RegExp | string;
|
|
11
|
+
/** Match by tool names. */
|
|
12
|
+
tools?: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Anthropic API intercept helpers.
|
|
16
|
+
*/
|
|
17
|
+
declare const anthropic: {
|
|
18
|
+
/**
|
|
19
|
+
* Trigger: match Anthropic messages API requests.
|
|
20
|
+
*/
|
|
21
|
+
messages(filter?: AnthropicMessagesFilter): InterceptTrigger; /** Response: wrap data in Anthropic messages format. */
|
|
22
|
+
response(data: unknown): InterceptResponse; /** Response: return an Anthropic error. */
|
|
23
|
+
error(status: number, message?: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
24
|
+
timeout(): InterceptResponse;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/intercept/http.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Generic HTTP intercept helpers for any URL.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* .intercept(http.get('https://api.example.com/data'), { body: [...] })
|
|
33
|
+
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
34
|
+
*/
|
|
35
|
+
declare const http: {
|
|
36
|
+
/** Trigger: match GET requests to a URL pattern. */get(url: RegExp | string): InterceptTrigger; /** Trigger: match POST requests to a URL pattern. */
|
|
37
|
+
post(url: RegExp | string): InterceptTrigger; /** Trigger: match PUT requests to a URL pattern. */
|
|
38
|
+
put(url: RegExp | string): InterceptTrigger; /** Trigger: match DELETE requests to a URL pattern. */
|
|
39
|
+
delete(url: RegExp | string): InterceptTrigger; /** Trigger: match any method to a URL pattern. */
|
|
40
|
+
any(url: RegExp | string): InterceptTrigger; /** Response: simple JSON success. */
|
|
41
|
+
json(data: unknown, status?: number): InterceptResponse; /** Response: error with message. */
|
|
42
|
+
error(status: number, message?: string): InterceptResponse;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/intercept/openai.d.ts
|
|
46
|
+
interface OpenAIChatFilter {
|
|
47
|
+
/** Match by model name (exact string or regex). */
|
|
48
|
+
model?: RegExp | string;
|
|
49
|
+
/** Match by system message content (regex or substring). */
|
|
50
|
+
system?: RegExp | string;
|
|
51
|
+
/** Match by user message content (regex or substring). */
|
|
52
|
+
user?: RegExp | string;
|
|
53
|
+
/** Match by tool/function names present in the request. */
|
|
54
|
+
tools?: string[];
|
|
55
|
+
/** Match by temperature value. */
|
|
56
|
+
temperature?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* OpenAI API intercept helpers.
|
|
60
|
+
*/
|
|
61
|
+
declare const openai: {
|
|
62
|
+
/**
|
|
63
|
+
* Trigger: match OpenAI chat completion requests.
|
|
64
|
+
*
|
|
65
|
+
* @param filter - Optional filters to narrow which requests match.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* openai.chat() // any chat call
|
|
69
|
+
* openai.chat({ model: 'gpt-4o' }) // specific model
|
|
70
|
+
* openai.chat({ system: /classify/ }) // system prompt contains "classify"
|
|
71
|
+
* openai.chat({ tools: ['extract_facts'] }) // function calling
|
|
72
|
+
*/
|
|
73
|
+
chat(filter?: OpenAIChatFilter): InterceptTrigger;
|
|
74
|
+
/**
|
|
75
|
+
* Response: wrap data in OpenAI chat completion format.
|
|
76
|
+
*
|
|
77
|
+
* @param data - The content to return (will be JSON.stringified if not a string).
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* openai.response({ categories: ['TECH'] })
|
|
81
|
+
*/
|
|
82
|
+
response(data: unknown): InterceptResponse; /** Response: return an OpenAI error. */
|
|
83
|
+
error(status: number, message?: string): InterceptResponse; /** Response: return malformed (non-JSON) content. */
|
|
84
|
+
malformed(content: string): InterceptResponse; /** Response: simulate a timeout (30s delay). */
|
|
85
|
+
timeout(): InterceptResponse;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { type InterceptEntry, type InterceptResponse, type InterceptTrigger, anthropic, http, openai };
|
|
89
|
+
//# sourceMappingURL=intercept.d.ts.map
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
//#region src/intercept/anthropic.ts
|
|
2
|
+
const ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
3
|
+
function matchesFilter$1(body, filter) {
|
|
4
|
+
if (filter.model) {
|
|
5
|
+
const model = body?.model;
|
|
6
|
+
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
7
|
+
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
8
|
+
}
|
|
9
|
+
if (filter.system) {
|
|
10
|
+
const system = typeof body?.system === "string" ? body.system : "";
|
|
11
|
+
if (typeof filter.system === "string" && !system.includes(filter.system)) return false;
|
|
12
|
+
if (filter.system instanceof RegExp && !filter.system.test(system)) return false;
|
|
13
|
+
}
|
|
14
|
+
if (filter.user) {
|
|
15
|
+
const userMsg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
16
|
+
const text = typeof userMsg === "string" ? userMsg : JSON.stringify(userMsg);
|
|
17
|
+
if (typeof filter.user === "string" && !text.includes(filter.user)) return false;
|
|
18
|
+
if (filter.user instanceof RegExp && !filter.user.test(text)) return false;
|
|
19
|
+
}
|
|
20
|
+
if (filter.tools) {
|
|
21
|
+
const requestTools = body?.tools?.map((t) => t.name).filter(Boolean) ?? [];
|
|
22
|
+
if (!filter.tools.every((t) => requestTools.includes(t))) return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Anthropic API intercept helpers.
|
|
28
|
+
*/
|
|
29
|
+
const anthropic = {
|
|
30
|
+
messages(filter) {
|
|
31
|
+
return {
|
|
32
|
+
method: "POST",
|
|
33
|
+
url: ANTHROPIC_MESSAGES_URL,
|
|
34
|
+
match: filter ? (body) => matchesFilter$1(body, filter) : void 0
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
response(data) {
|
|
38
|
+
return {
|
|
39
|
+
status: 200,
|
|
40
|
+
body: {
|
|
41
|
+
id: "msg-test",
|
|
42
|
+
type: "message",
|
|
43
|
+
role: "assistant",
|
|
44
|
+
content: [{
|
|
45
|
+
type: "text",
|
|
46
|
+
text: typeof data === "string" ? data : JSON.stringify(data)
|
|
47
|
+
}],
|
|
48
|
+
model: "claude-sonnet-4-20250514",
|
|
49
|
+
stop_reason: "end_turn",
|
|
50
|
+
usage: {
|
|
51
|
+
input_tokens: 10,
|
|
52
|
+
output_tokens: 10
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
error(status, message) {
|
|
58
|
+
return {
|
|
59
|
+
status,
|
|
60
|
+
body: {
|
|
61
|
+
type: "error",
|
|
62
|
+
error: {
|
|
63
|
+
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
64
|
+
message: message ?? `Anthropic error (${status})`
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
timeout() {
|
|
70
|
+
return {
|
|
71
|
+
status: 200,
|
|
72
|
+
body: {},
|
|
73
|
+
delay: 3e4
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/intercept/http.ts
|
|
79
|
+
/**
|
|
80
|
+
* Generic HTTP intercept helpers for any URL.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* .intercept(http.get('https://api.example.com/data'), { body: [...] })
|
|
84
|
+
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
85
|
+
*/
|
|
86
|
+
const http = {
|
|
87
|
+
get(url) {
|
|
88
|
+
return {
|
|
89
|
+
method: "GET",
|
|
90
|
+
url
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
post(url) {
|
|
94
|
+
return {
|
|
95
|
+
method: "POST",
|
|
96
|
+
url
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
put(url) {
|
|
100
|
+
return {
|
|
101
|
+
method: "PUT",
|
|
102
|
+
url
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
delete(url) {
|
|
106
|
+
return {
|
|
107
|
+
method: "DELETE",
|
|
108
|
+
url
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
any(url) {
|
|
112
|
+
return {
|
|
113
|
+
method: "*",
|
|
114
|
+
url
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
json(data, status = 200) {
|
|
118
|
+
return {
|
|
119
|
+
status,
|
|
120
|
+
body: data
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
error(status, message) {
|
|
124
|
+
return {
|
|
125
|
+
status,
|
|
126
|
+
body: { error: message ?? `HTTP ${status}` }
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/intercept/openai.ts
|
|
132
|
+
const OPENAI_CHAT_URL = "https://api.openai.com/v1/chat/completions";
|
|
133
|
+
function matchesFilter(body, filter) {
|
|
134
|
+
if (filter.model) {
|
|
135
|
+
const model = body?.model;
|
|
136
|
+
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
137
|
+
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
138
|
+
}
|
|
139
|
+
if (filter.system) {
|
|
140
|
+
const systemMsg = body?.messages?.find((m) => m.role === "system")?.content ?? "";
|
|
141
|
+
if (typeof filter.system === "string" && !systemMsg.includes(filter.system)) return false;
|
|
142
|
+
if (filter.system instanceof RegExp && !filter.system.test(systemMsg)) return false;
|
|
143
|
+
}
|
|
144
|
+
if (filter.user) {
|
|
145
|
+
const userMsg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
146
|
+
if (typeof filter.user === "string" && !userMsg.includes(filter.user)) return false;
|
|
147
|
+
if (filter.user instanceof RegExp && !filter.user.test(userMsg)) return false;
|
|
148
|
+
}
|
|
149
|
+
if (filter.tools) {
|
|
150
|
+
const requestTools = body?.tools?.map((t) => t.function?.name).filter(Boolean) ?? [];
|
|
151
|
+
if (!filter.tools.every((t) => requestTools.includes(t))) return false;
|
|
152
|
+
}
|
|
153
|
+
if (filter.temperature !== void 0 && body?.temperature !== filter.temperature) return false;
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* OpenAI API intercept helpers.
|
|
158
|
+
*/
|
|
159
|
+
const openai = {
|
|
160
|
+
chat(filter) {
|
|
161
|
+
return {
|
|
162
|
+
method: "POST",
|
|
163
|
+
url: OPENAI_CHAT_URL,
|
|
164
|
+
match: filter ? (body) => matchesFilter(body, filter) : void 0
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
response(data) {
|
|
168
|
+
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
169
|
+
return {
|
|
170
|
+
status: 200,
|
|
171
|
+
body: {
|
|
172
|
+
id: "chatcmpl-test",
|
|
173
|
+
object: "chat.completion",
|
|
174
|
+
created: Math.floor(Date.now() / 1e3),
|
|
175
|
+
model: "gpt-4o-test",
|
|
176
|
+
choices: [{
|
|
177
|
+
index: 0,
|
|
178
|
+
message: {
|
|
179
|
+
role: "assistant",
|
|
180
|
+
content
|
|
181
|
+
},
|
|
182
|
+
finish_reason: "stop"
|
|
183
|
+
}],
|
|
184
|
+
usage: {
|
|
185
|
+
prompt_tokens: 10,
|
|
186
|
+
completion_tokens: 10,
|
|
187
|
+
total_tokens: 20
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
error(status, message) {
|
|
193
|
+
return {
|
|
194
|
+
status,
|
|
195
|
+
body: { error: {
|
|
196
|
+
message: message ?? `OpenAI error (${status})`,
|
|
197
|
+
type: status === 429 ? "rate_limit_error" : "api_error",
|
|
198
|
+
code: status === 429 ? "rate_limit_exceeded" : null
|
|
199
|
+
} }
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
malformed(content) {
|
|
203
|
+
return {
|
|
204
|
+
status: 200,
|
|
205
|
+
body: {
|
|
206
|
+
id: "chatcmpl-test",
|
|
207
|
+
object: "chat.completion",
|
|
208
|
+
created: Math.floor(Date.now() / 1e3),
|
|
209
|
+
model: "gpt-4o-test",
|
|
210
|
+
choices: [{
|
|
211
|
+
index: 0,
|
|
212
|
+
message: {
|
|
213
|
+
role: "assistant",
|
|
214
|
+
content
|
|
215
|
+
},
|
|
216
|
+
finish_reason: "stop"
|
|
217
|
+
}],
|
|
218
|
+
usage: {
|
|
219
|
+
prompt_tokens: 10,
|
|
220
|
+
completion_tokens: 10,
|
|
221
|
+
total_tokens: 20
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
timeout() {
|
|
227
|
+
return {
|
|
228
|
+
status: 200,
|
|
229
|
+
body: {},
|
|
230
|
+
delay: 3e4
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
//#endregion
|
|
235
|
+
export { anthropic, http, openai };
|
|
236
|
+
|
|
237
|
+
//# sourceMappingURL=intercept.js.map
|