@jterrazz/test 6.5.1 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +22 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -8
- package/dist/index.d.ts +10 -8
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/intercept.cjs +143 -129
- package/dist/intercept.cjs.map +1 -1
- package/dist/intercept.d.cts +39 -53
- package/dist/intercept.d.ts +39 -53
- package/dist/intercept.js +143 -129
- package/dist/intercept.js.map +1 -1
- package/dist/types.d.cts +8 -1
- package/dist/types.d.ts +8 -1
- package/package.json +1 -1
package/dist/intercept.d.ts
CHANGED
|
@@ -2,26 +2,29 @@ import { n as InterceptResponse, r as InterceptTrigger, t as InterceptEntry } fr
|
|
|
2
2
|
|
|
3
3
|
//#region src/builder/common/intercept/adapters/anthropic.d.ts
|
|
4
4
|
interface AnthropicMessagesFilter {
|
|
5
|
-
/** Match by model name. */
|
|
6
5
|
model?: RegExp | string;
|
|
7
|
-
/** Match by system message content. */
|
|
8
6
|
system?: RegExp | string;
|
|
9
|
-
/** Match by user message content. */
|
|
10
7
|
user?: RegExp | string;
|
|
11
|
-
/** Match by tool names. */
|
|
12
8
|
tools?: string[];
|
|
13
9
|
}
|
|
10
|
+
declare function buildReply(data: unknown): InterceptResponse;
|
|
14
11
|
/**
|
|
15
12
|
* Anthropic API intercept helpers.
|
|
16
13
|
*/
|
|
17
14
|
declare const anthropic: {
|
|
18
15
|
/**
|
|
19
16
|
* Trigger: match Anthropic messages API requests.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* anthropic.request()
|
|
20
|
+
* anthropic.request({ system: /classify/ })
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
request(filter?: AnthropicMessagesFilter): InterceptTrigger; /** Response: wrap data in Anthropic messages format. */
|
|
23
|
+
reply: typeof buildReply; /** Response: return an Anthropic error. */
|
|
23
24
|
error(status: number, message?: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
24
|
-
timeout(): InterceptResponse;
|
|
25
|
+
timeout(): InterceptResponse; /** @deprecated Use anthropic.request() instead. */
|
|
26
|
+
messages(filter?: AnthropicMessagesFilter): InterceptTrigger; /** @deprecated Use anthropic.reply() instead. */
|
|
27
|
+
response: typeof buildReply;
|
|
25
28
|
};
|
|
26
29
|
//#endregion
|
|
27
30
|
//#region src/builder/common/intercept/adapters/http.d.ts
|
|
@@ -29,14 +32,13 @@ declare const anthropic: {
|
|
|
29
32
|
* Generic HTTP intercept helpers for any URL.
|
|
30
33
|
*
|
|
31
34
|
* @example
|
|
32
|
-
* .intercept(http.get('https://api.example.com/data'),
|
|
33
|
-
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
35
|
+
* .intercept(http.get('https://api.example.com/data'), 'http/response.json')
|
|
34
36
|
*/
|
|
35
37
|
declare const http: {
|
|
36
|
-
|
|
37
|
-
post(url: RegExp | string): InterceptTrigger;
|
|
38
|
-
put(url: RegExp | string): InterceptTrigger;
|
|
39
|
-
delete(url: RegExp | string): InterceptTrigger;
|
|
38
|
+
get(url: RegExp | string): InterceptTrigger;
|
|
39
|
+
post(url: RegExp | string): InterceptTrigger;
|
|
40
|
+
put(url: RegExp | string): InterceptTrigger;
|
|
41
|
+
delete(url: RegExp | string): InterceptTrigger;
|
|
40
42
|
any(url: RegExp | string): InterceptTrigger; /** Response: simple JSON success. */
|
|
41
43
|
json(data: unknown, status?: number): InterceptResponse; /** Response: error with message. */
|
|
42
44
|
error(status: number, message?: string): InterceptResponse;
|
|
@@ -44,75 +46,59 @@ declare const http: {
|
|
|
44
46
|
//#endregion
|
|
45
47
|
//#region src/builder/common/intercept/adapters/openai.d.ts
|
|
46
48
|
interface OpenAIChatFilter {
|
|
47
|
-
/** Match by model name (exact string or regex). */
|
|
48
49
|
model?: RegExp | string;
|
|
49
|
-
/** Match by system message content (regex or substring). */
|
|
50
50
|
system?: RegExp | string;
|
|
51
|
-
/** Match by user message content (regex or substring). */
|
|
52
51
|
user?: RegExp | string;
|
|
53
|
-
/** Match by tool/function names present in the request. */
|
|
54
52
|
tools?: string[];
|
|
55
|
-
/** Match by temperature value. */
|
|
56
53
|
temperature?: number;
|
|
57
54
|
}
|
|
58
|
-
/** Responses API filter — uses `input` array instead of `messages`. */
|
|
59
55
|
interface OpenAIResponsesFilter {
|
|
60
|
-
/** Match by model name. */
|
|
61
56
|
model?: RegExp | string;
|
|
62
|
-
/** Match by system instruction content. */
|
|
63
57
|
system?: RegExp | string;
|
|
64
|
-
/** Match by user input content. */
|
|
65
58
|
user?: RegExp | string;
|
|
66
|
-
/** Match by tool names. */
|
|
67
59
|
tools?: string[];
|
|
68
60
|
}
|
|
61
|
+
declare function buildChatReply(data: unknown): InterceptResponse;
|
|
62
|
+
declare function buildResponsesReply(data: unknown): InterceptResponse;
|
|
69
63
|
/**
|
|
70
64
|
* OpenAI API intercept helpers.
|
|
71
65
|
*/
|
|
72
66
|
declare const openai: {
|
|
73
67
|
/**
|
|
74
|
-
* Trigger: match
|
|
75
|
-
*
|
|
76
|
-
* @param filter - Optional filters to narrow which requests match.
|
|
68
|
+
* Trigger: match Chat Completions API requests.
|
|
77
69
|
*
|
|
78
70
|
* @example
|
|
79
|
-
* openai.
|
|
80
|
-
* openai.
|
|
81
|
-
* openai.
|
|
82
|
-
* openai.chat({ tools: ['extract_facts'] }) // function calling
|
|
71
|
+
* openai.request() // any chat call
|
|
72
|
+
* openai.request({ model: 'gpt-4o' }) // specific model
|
|
73
|
+
* openai.request({ system: /classify/ }) // system prompt match
|
|
83
74
|
*/
|
|
84
|
-
|
|
75
|
+
request(filter?: OpenAIChatFilter): InterceptTrigger;
|
|
85
76
|
/**
|
|
86
|
-
* Trigger: match
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* @param url - Override URL for custom gateways (e.g. 'https://gateway.example.com/v1/responses').
|
|
77
|
+
* Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.
|
|
78
|
+
* When used with a JSON file, the data is automatically wrapped in the
|
|
79
|
+
* Responses API envelope.
|
|
90
80
|
*
|
|
91
|
-
* @
|
|
92
|
-
*
|
|
93
|
-
* openai.responses({ user: /Report Ingestion/ }) // match by prompt content
|
|
94
|
-
* openai.responses({ model: 'gpt-4o' }, 'https://my-gateway/v1/responses') // custom gateway
|
|
95
|
-
*/
|
|
96
|
-
responses(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger;
|
|
97
|
-
/**
|
|
98
|
-
* Response: wrap data in OpenAI Responses API format (AI SDK v5+).
|
|
81
|
+
* @param filter - Optional body filters.
|
|
82
|
+
* @param url - Custom gateway URL (default: api.openai.com).
|
|
99
83
|
*
|
|
100
84
|
* @example
|
|
101
|
-
* openai.
|
|
85
|
+
* openai.agent({ user: /Report Ingestion/ }, GATEWAY)
|
|
102
86
|
*/
|
|
103
|
-
|
|
87
|
+
agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger;
|
|
104
88
|
/**
|
|
105
|
-
* Response: wrap data in
|
|
106
|
-
*
|
|
107
|
-
* @param data - The content to return (will be JSON.stringified if not a string).
|
|
89
|
+
* Response: wrap data in Chat Completions format.
|
|
108
90
|
*
|
|
109
91
|
* @example
|
|
110
|
-
* openai.
|
|
92
|
+
* openai.reply({ categories: ['TECH'] })
|
|
111
93
|
*/
|
|
112
|
-
|
|
113
|
-
error(status: number, message?: string): InterceptResponse; /** Response: return malformed
|
|
114
|
-
malformed(content: string): InterceptResponse; /** Response: simulate a timeout
|
|
115
|
-
timeout(): InterceptResponse;
|
|
94
|
+
reply: typeof buildChatReply; /** Response: return an OpenAI error. */
|
|
95
|
+
error(status: number, message?: string): InterceptResponse; /** Response: return malformed content. */
|
|
96
|
+
malformed(content: string): InterceptResponse; /** Response: simulate a timeout. */
|
|
97
|
+
timeout(): InterceptResponse; /** @deprecated Use openai.request() instead. */
|
|
98
|
+
chat(filter?: OpenAIChatFilter): InterceptTrigger; /** @deprecated Use openai.reply() instead. */
|
|
99
|
+
response: typeof buildChatReply; /** @deprecated Use openai.agent() instead. */
|
|
100
|
+
responses(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger; /** @deprecated Use openai.reply() or .intercept(trigger, 'file.json') instead. */
|
|
101
|
+
responsesResponse: typeof buildResponsesReply;
|
|
116
102
|
};
|
|
117
103
|
//#endregion
|
|
118
104
|
export { type InterceptEntry, type InterceptResponse, type InterceptTrigger, anthropic, http, openai };
|
package/dist/intercept.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/builder/common/intercept/adapters/anthropic.ts
|
|
2
2
|
const ANTHROPIC_MESSAGES_URL = "https://api.anthropic.com/v1/messages";
|
|
3
|
-
function matchesFilter
|
|
3
|
+
function matchesFilter(body, filter) {
|
|
4
4
|
if (filter.model) {
|
|
5
5
|
const model = body?.model;
|
|
6
6
|
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
@@ -18,42 +18,45 @@ function matchesFilter$1(body, filter) {
|
|
|
18
18
|
if (filter.user instanceof RegExp && !filter.user.test(text)) return false;
|
|
19
19
|
}
|
|
20
20
|
if (filter.tools) {
|
|
21
|
-
const
|
|
22
|
-
if (!filter.tools.every((t) =>
|
|
21
|
+
const names = body?.tools?.map((t) => t.name).filter(Boolean) ?? [];
|
|
22
|
+
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
23
23
|
}
|
|
24
24
|
return true;
|
|
25
25
|
}
|
|
26
|
+
function buildReply(data) {
|
|
27
|
+
return {
|
|
28
|
+
status: 200,
|
|
29
|
+
body: {
|
|
30
|
+
id: "msg-test",
|
|
31
|
+
type: "message",
|
|
32
|
+
role: "assistant",
|
|
33
|
+
content: [{
|
|
34
|
+
type: "text",
|
|
35
|
+
text: typeof data === "string" ? data : JSON.stringify(data)
|
|
36
|
+
}],
|
|
37
|
+
model: "claude-sonnet-4-20250514",
|
|
38
|
+
stop_reason: "end_turn",
|
|
39
|
+
usage: {
|
|
40
|
+
input_tokens: 10,
|
|
41
|
+
output_tokens: 10
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
26
46
|
/**
|
|
27
47
|
* Anthropic API intercept helpers.
|
|
28
48
|
*/
|
|
29
49
|
const anthropic = {
|
|
30
|
-
|
|
50
|
+
request(filter) {
|
|
31
51
|
return {
|
|
52
|
+
adapter: "anthropic",
|
|
32
53
|
method: "POST",
|
|
33
54
|
url: ANTHROPIC_MESSAGES_URL,
|
|
34
|
-
match: filter ? (body) => matchesFilter
|
|
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
|
+
match: filter ? (body) => matchesFilter(body, filter) : void 0,
|
|
56
|
+
wrap: buildReply
|
|
55
57
|
};
|
|
56
58
|
},
|
|
59
|
+
reply: buildReply,
|
|
57
60
|
error(status, message) {
|
|
58
61
|
return {
|
|
59
62
|
status,
|
|
@@ -72,46 +75,65 @@ const anthropic = {
|
|
|
72
75
|
body: {},
|
|
73
76
|
delay: 3e4
|
|
74
77
|
};
|
|
75
|
-
}
|
|
78
|
+
},
|
|
79
|
+
messages(filter) {
|
|
80
|
+
return anthropic.request(filter);
|
|
81
|
+
},
|
|
82
|
+
response: buildReply
|
|
76
83
|
};
|
|
77
84
|
//#endregion
|
|
78
85
|
//#region src/builder/common/intercept/adapters/http.ts
|
|
86
|
+
function wrapJson(data) {
|
|
87
|
+
return {
|
|
88
|
+
status: 200,
|
|
89
|
+
body: data
|
|
90
|
+
};
|
|
91
|
+
}
|
|
79
92
|
/**
|
|
80
93
|
* Generic HTTP intercept helpers for any URL.
|
|
81
94
|
*
|
|
82
95
|
* @example
|
|
83
|
-
* .intercept(http.get('https://api.example.com/data'),
|
|
84
|
-
* .intercept(http.post('https://api.stripe.com/v1/charges'), { body: { id: 'ch_...' } })
|
|
96
|
+
* .intercept(http.get('https://api.example.com/data'), 'http/response.json')
|
|
85
97
|
*/
|
|
86
98
|
const http = {
|
|
87
99
|
get(url) {
|
|
88
100
|
return {
|
|
101
|
+
adapter: "http",
|
|
89
102
|
method: "GET",
|
|
90
|
-
url
|
|
103
|
+
url,
|
|
104
|
+
wrap: wrapJson
|
|
91
105
|
};
|
|
92
106
|
},
|
|
93
107
|
post(url) {
|
|
94
108
|
return {
|
|
109
|
+
adapter: "http",
|
|
95
110
|
method: "POST",
|
|
96
|
-
url
|
|
111
|
+
url,
|
|
112
|
+
wrap: wrapJson
|
|
97
113
|
};
|
|
98
114
|
},
|
|
99
115
|
put(url) {
|
|
100
116
|
return {
|
|
117
|
+
adapter: "http",
|
|
101
118
|
method: "PUT",
|
|
102
|
-
url
|
|
119
|
+
url,
|
|
120
|
+
wrap: wrapJson
|
|
103
121
|
};
|
|
104
122
|
},
|
|
105
123
|
delete(url) {
|
|
106
124
|
return {
|
|
125
|
+
adapter: "http",
|
|
107
126
|
method: "DELETE",
|
|
108
|
-
url
|
|
127
|
+
url,
|
|
128
|
+
wrap: wrapJson
|
|
109
129
|
};
|
|
110
130
|
},
|
|
111
131
|
any(url) {
|
|
112
132
|
return {
|
|
133
|
+
adapter: "http",
|
|
113
134
|
method: "*",
|
|
114
|
-
url
|
|
135
|
+
url,
|
|
136
|
+
wrap: wrapJson
|
|
115
137
|
};
|
|
116
138
|
},
|
|
117
139
|
json(data, status = 200) {
|
|
@@ -131,25 +153,25 @@ const http = {
|
|
|
131
153
|
//#region src/builder/common/intercept/adapters/openai.ts
|
|
132
154
|
const OPENAI_CHAT_URL = "https://api.openai.com/v1/chat/completions";
|
|
133
155
|
const OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses";
|
|
134
|
-
function
|
|
156
|
+
function matchesChatFilter(body, filter) {
|
|
135
157
|
if (filter.model) {
|
|
136
158
|
const model = body?.model;
|
|
137
159
|
if (typeof filter.model === "string" && model !== filter.model) return false;
|
|
138
160
|
if (filter.model instanceof RegExp && !filter.model.test(model ?? "")) return false;
|
|
139
161
|
}
|
|
140
162
|
if (filter.system) {
|
|
141
|
-
const
|
|
142
|
-
if (typeof filter.system === "string" && !
|
|
143
|
-
if (filter.system instanceof RegExp && !filter.system.test(
|
|
163
|
+
const msg = body?.messages?.find((m) => m.role === "system")?.content ?? "";
|
|
164
|
+
if (typeof filter.system === "string" && !msg.includes(filter.system)) return false;
|
|
165
|
+
if (filter.system instanceof RegExp && !filter.system.test(msg)) return false;
|
|
144
166
|
}
|
|
145
167
|
if (filter.user) {
|
|
146
|
-
const
|
|
147
|
-
if (typeof filter.user === "string" && !
|
|
148
|
-
if (filter.user instanceof RegExp && !filter.user.test(
|
|
168
|
+
const msg = body?.messages?.find((m) => m.role === "user")?.content ?? "";
|
|
169
|
+
if (typeof filter.user === "string" && !msg.includes(filter.user)) return false;
|
|
170
|
+
if (filter.user instanceof RegExp && !filter.user.test(msg)) return false;
|
|
149
171
|
}
|
|
150
172
|
if (filter.tools) {
|
|
151
|
-
const
|
|
152
|
-
if (!filter.tools.every((t) =>
|
|
173
|
+
const names = body?.tools?.map((t) => t.function?.name).filter(Boolean) ?? [];
|
|
174
|
+
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
153
175
|
}
|
|
154
176
|
if (filter.temperature !== void 0 && body?.temperature !== filter.temperature) return false;
|
|
155
177
|
return true;
|
|
@@ -163,91 +185,96 @@ function matchesResponsesFilter(body, filter) {
|
|
|
163
185
|
if (filter.system) {
|
|
164
186
|
const instructions = body?.instructions ?? "";
|
|
165
187
|
const systemInput = body?.input?.find?.((m) => m.role === "system")?.content ?? "";
|
|
166
|
-
const
|
|
167
|
-
if (typeof filter.system === "string" && !
|
|
168
|
-
if (filter.system instanceof RegExp && !filter.system.test(
|
|
188
|
+
const text = instructions || systemInput;
|
|
189
|
+
if (typeof filter.system === "string" && !text.includes(filter.system)) return false;
|
|
190
|
+
if (filter.system instanceof RegExp && !filter.system.test(text)) return false;
|
|
169
191
|
}
|
|
170
192
|
if (filter.user) {
|
|
171
|
-
const
|
|
172
|
-
if (typeof filter.user === "string" && !
|
|
173
|
-
if (filter.user instanceof RegExp && !filter.user.test(
|
|
193
|
+
const msgs = (body?.input ?? []).filter((m) => m.role === "user").map((m) => typeof m.content === "string" ? m.content : JSON.stringify(m.content)).join(" ");
|
|
194
|
+
if (typeof filter.user === "string" && !msgs.includes(filter.user)) return false;
|
|
195
|
+
if (filter.user instanceof RegExp && !filter.user.test(msgs)) return false;
|
|
174
196
|
}
|
|
175
197
|
if (filter.tools) {
|
|
176
|
-
const
|
|
177
|
-
if (!filter.tools.every((t) =>
|
|
198
|
+
const names = body?.tools?.map((t) => t.name ?? t.function?.name).filter(Boolean) ?? [];
|
|
199
|
+
if (!filter.tools.every((t) => names.includes(t))) return false;
|
|
178
200
|
}
|
|
179
201
|
return true;
|
|
180
202
|
}
|
|
203
|
+
function buildChatReply(data) {
|
|
204
|
+
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
205
|
+
return {
|
|
206
|
+
status: 200,
|
|
207
|
+
body: {
|
|
208
|
+
id: "chatcmpl-test",
|
|
209
|
+
object: "chat.completion",
|
|
210
|
+
created: Math.floor(Date.now() / 1e3),
|
|
211
|
+
model: "gpt-4o-test",
|
|
212
|
+
choices: [{
|
|
213
|
+
index: 0,
|
|
214
|
+
message: {
|
|
215
|
+
role: "assistant",
|
|
216
|
+
content
|
|
217
|
+
},
|
|
218
|
+
finish_reason: "stop"
|
|
219
|
+
}],
|
|
220
|
+
usage: {
|
|
221
|
+
prompt_tokens: 10,
|
|
222
|
+
completion_tokens: 10,
|
|
223
|
+
total_tokens: 20
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function buildResponsesReply(data) {
|
|
229
|
+
const text = typeof data === "string" ? data : JSON.stringify(data);
|
|
230
|
+
return {
|
|
231
|
+
status: 200,
|
|
232
|
+
body: {
|
|
233
|
+
id: "resp-test",
|
|
234
|
+
object: "response",
|
|
235
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
236
|
+
model: "gpt-4o-test",
|
|
237
|
+
output: [{
|
|
238
|
+
type: "message",
|
|
239
|
+
id: "msg-test",
|
|
240
|
+
role: "assistant",
|
|
241
|
+
content: [{
|
|
242
|
+
type: "output_text",
|
|
243
|
+
text,
|
|
244
|
+
annotations: []
|
|
245
|
+
}]
|
|
246
|
+
}],
|
|
247
|
+
usage: {
|
|
248
|
+
input_tokens: 10,
|
|
249
|
+
output_tokens: 10,
|
|
250
|
+
total_tokens: 20
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
181
255
|
/**
|
|
182
256
|
* OpenAI API intercept helpers.
|
|
183
257
|
*/
|
|
184
258
|
const openai = {
|
|
185
|
-
|
|
259
|
+
request(filter) {
|
|
186
260
|
return {
|
|
261
|
+
adapter: "openai",
|
|
187
262
|
method: "POST",
|
|
188
263
|
url: OPENAI_CHAT_URL,
|
|
189
|
-
match: filter ? (body) =>
|
|
264
|
+
match: filter ? (body) => matchesChatFilter(body, filter) : void 0,
|
|
265
|
+
wrap: buildChatReply
|
|
190
266
|
};
|
|
191
267
|
},
|
|
192
|
-
|
|
268
|
+
agent(filter, url) {
|
|
193
269
|
return {
|
|
270
|
+
adapter: "openai",
|
|
194
271
|
method: "POST",
|
|
195
272
|
url: url ?? OPENAI_RESPONSES_URL,
|
|
196
|
-
match: filter ? (body) => matchesResponsesFilter(body, filter) : void 0
|
|
197
|
-
|
|
198
|
-
},
|
|
199
|
-
responsesResponse(data) {
|
|
200
|
-
const text = typeof data === "string" ? data : JSON.stringify(data);
|
|
201
|
-
return {
|
|
202
|
-
status: 200,
|
|
203
|
-
body: {
|
|
204
|
-
id: "resp-test",
|
|
205
|
-
object: "response",
|
|
206
|
-
created_at: Math.floor(Date.now() / 1e3),
|
|
207
|
-
model: "gpt-4o-test",
|
|
208
|
-
output: [{
|
|
209
|
-
type: "message",
|
|
210
|
-
id: "msg-test",
|
|
211
|
-
role: "assistant",
|
|
212
|
-
content: [{
|
|
213
|
-
type: "output_text",
|
|
214
|
-
text,
|
|
215
|
-
annotations: []
|
|
216
|
-
}]
|
|
217
|
-
}],
|
|
218
|
-
usage: {
|
|
219
|
-
input_tokens: 10,
|
|
220
|
-
output_tokens: 10,
|
|
221
|
-
total_tokens: 20
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
},
|
|
226
|
-
response(data) {
|
|
227
|
-
const content = typeof data === "string" ? data : JSON.stringify(data);
|
|
228
|
-
return {
|
|
229
|
-
status: 200,
|
|
230
|
-
body: {
|
|
231
|
-
id: "chatcmpl-test",
|
|
232
|
-
object: "chat.completion",
|
|
233
|
-
created: Math.floor(Date.now() / 1e3),
|
|
234
|
-
model: "gpt-4o-test",
|
|
235
|
-
choices: [{
|
|
236
|
-
index: 0,
|
|
237
|
-
message: {
|
|
238
|
-
role: "assistant",
|
|
239
|
-
content
|
|
240
|
-
},
|
|
241
|
-
finish_reason: "stop"
|
|
242
|
-
}],
|
|
243
|
-
usage: {
|
|
244
|
-
prompt_tokens: 10,
|
|
245
|
-
completion_tokens: 10,
|
|
246
|
-
total_tokens: 20
|
|
247
|
-
}
|
|
248
|
-
}
|
|
273
|
+
match: filter ? (body) => matchesResponsesFilter(body, filter) : void 0,
|
|
274
|
+
wrap: buildResponsesReply
|
|
249
275
|
};
|
|
250
276
|
},
|
|
277
|
+
reply: buildChatReply,
|
|
251
278
|
error(status, message) {
|
|
252
279
|
return {
|
|
253
280
|
status,
|
|
@@ -259,28 +286,7 @@ const openai = {
|
|
|
259
286
|
};
|
|
260
287
|
},
|
|
261
288
|
malformed(content) {
|
|
262
|
-
return
|
|
263
|
-
status: 200,
|
|
264
|
-
body: {
|
|
265
|
-
id: "chatcmpl-test",
|
|
266
|
-
object: "chat.completion",
|
|
267
|
-
created: Math.floor(Date.now() / 1e3),
|
|
268
|
-
model: "gpt-4o-test",
|
|
269
|
-
choices: [{
|
|
270
|
-
index: 0,
|
|
271
|
-
message: {
|
|
272
|
-
role: "assistant",
|
|
273
|
-
content
|
|
274
|
-
},
|
|
275
|
-
finish_reason: "stop"
|
|
276
|
-
}],
|
|
277
|
-
usage: {
|
|
278
|
-
prompt_tokens: 10,
|
|
279
|
-
completion_tokens: 10,
|
|
280
|
-
total_tokens: 20
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
};
|
|
289
|
+
return buildChatReply(content);
|
|
284
290
|
},
|
|
285
291
|
timeout() {
|
|
286
292
|
return {
|
|
@@ -288,7 +294,15 @@ const openai = {
|
|
|
288
294
|
body: {},
|
|
289
295
|
delay: 3e4
|
|
290
296
|
};
|
|
291
|
-
}
|
|
297
|
+
},
|
|
298
|
+
chat(filter) {
|
|
299
|
+
return openai.request(filter);
|
|
300
|
+
},
|
|
301
|
+
response: buildChatReply,
|
|
302
|
+
responses(filter, url) {
|
|
303
|
+
return openai.agent(filter, url);
|
|
304
|
+
},
|
|
305
|
+
responsesResponse: buildResponsesReply
|
|
292
306
|
};
|
|
293
307
|
//#endregion
|
|
294
308
|
export { anthropic, http, openai };
|
package/dist/intercept.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intercept.js","names":["matchesFilter"],"sources":["../src/builder/common/intercept/adapters/anthropic.ts","../src/builder/common/intercept/adapters/http.ts","../src/builder/common/intercept/adapters/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';\nconst OPENAI_RESPONSES_URL = 'https://api.openai.com/v1/responses';\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/** Responses API filter — uses `input` array instead of `messages`. */\nexport interface OpenAIResponsesFilter {\n /** Match by model name. */\n model?: RegExp | string;\n /** Match by system instruction content. */\n system?: RegExp | string;\n /** Match by user input content. */\n user?: RegExp | string;\n /** Match by tool names. */\n tools?: string[];\n}\n\nfunction matchesResponsesFilter(body: any, filter: OpenAIResponsesFilter): 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 instructions = body?.instructions ?? '';\n const systemInput = body?.input?.find?.((m: any) => m.role === 'system')?.content ?? '';\n const systemText = instructions || systemInput;\n if (typeof filter.system === 'string' && !systemText.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(systemText)) {\n return false;\n }\n }\n\n if (filter.user) {\n const userInputs = (body?.input ?? [])\n .filter((m: any) => m.role === 'user')\n .map((m: any) =>\n typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n )\n .join(' ');\n if (typeof filter.user === 'string' && !userInputs.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(userInputs)) {\n return false;\n }\n }\n\n if (filter.tools) {\n const requestTools =\n body?.tools?.map((t: any) => t.name ?? t.function?.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 * 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 * Trigger: match OpenAI Responses API requests (AI SDK v5+).\n *\n * @param filter - Optional filters. Supports custom gateway URLs.\n * @param url - Override URL for custom gateways (e.g. 'https://gateway.example.com/v1/responses').\n *\n * @example\n * openai.responses() // default URL\n * openai.responses({ user: /Report Ingestion/ }) // match by prompt content\n * openai.responses({ model: 'gpt-4o' }, 'https://my-gateway/v1/responses') // custom gateway\n */\n responses(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger {\n return {\n method: 'POST',\n url: url ?? OPENAI_RESPONSES_URL,\n match: filter ? (body: unknown) => matchesResponsesFilter(body, filter) : undefined,\n };\n },\n\n /**\n * Response: wrap data in OpenAI Responses API format (AI SDK v5+).\n *\n * @example\n * openai.responsesResponse({ categories: ['TECH'] })\n */\n responsesResponse(data: unknown): InterceptResponse {\n const text = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'resp-test',\n object: 'response',\n created_at: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n output: [\n {\n type: 'message',\n id: 'msg-test',\n role: 'assistant',\n content: [{ type: 'output_text', text, annotations: [] }],\n },\n ],\n usage: {\n input_tokens: 10,\n output_tokens: 10,\n total_tokens: 20,\n },\n },\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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"}
|
|
1
|
+
{"version":3,"file":"intercept.js","names":[],"sources":["../src/builder/common/intercept/adapters/anthropic.ts","../src/builder/common/intercept/adapters/http.ts","../src/builder/common/intercept/adapters/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 model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\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 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 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 if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\nfunction buildReply(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/**\n * Anthropic API intercept helpers.\n */\nexport const anthropic = {\n /**\n * Trigger: match Anthropic messages API requests.\n *\n * @example\n * anthropic.request()\n * anthropic.request({ system: /classify/ })\n */\n request(filter?: AnthropicMessagesFilter): InterceptTrigger {\n return {\n adapter: 'anthropic',\n method: 'POST',\n url: ANTHROPIC_MESSAGES_URL,\n match: filter ? (body: unknown) => matchesFilter(body, filter) : undefined,\n wrap: buildReply,\n };\n },\n\n /** Response: wrap data in Anthropic messages format. */\n reply: buildReply,\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 // Legacy aliases\n /** @deprecated Use anthropic.request() instead. */\n messages(filter?: AnthropicMessagesFilter): InterceptTrigger {\n return anthropic.request(filter);\n },\n /** @deprecated Use anthropic.reply() instead. */\n response: buildReply,\n};\n","import type { InterceptResponse, InterceptTrigger } from '../types.js';\n\nfunction wrapJson(data: unknown): InterceptResponse {\n return { status: 200, body: data };\n}\n\n/**\n * Generic HTTP intercept helpers for any URL.\n *\n * @example\n * .intercept(http.get('https://api.example.com/data'), 'http/response.json')\n */\nexport const http = {\n get(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'GET', url, wrap: wrapJson };\n },\n\n post(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'POST', url, wrap: wrapJson };\n },\n\n put(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'PUT', url, wrap: wrapJson };\n },\n\n delete(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: 'DELETE', url, wrap: wrapJson };\n },\n\n any(url: RegExp | string): InterceptTrigger {\n return { adapter: 'http', method: '*', url, wrap: wrapJson };\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';\nconst OPENAI_RESPONSES_URL = 'https://api.openai.com/v1/responses';\n\n// ── Chat Completions filters ──\n\nexport interface OpenAIChatFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n temperature?: number;\n}\n\nfunction matchesChatFilter(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 if (filter.system) {\n const msg = body?.messages?.find((m: any) => m.role === 'system')?.content ?? '';\n if (typeof filter.system === 'string' && !msg.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(msg)) {\n return false;\n }\n }\n if (filter.user) {\n const msg = body?.messages?.find((m: any) => m.role === 'user')?.content ?? '';\n if (typeof filter.user === 'string' && !msg.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msg)) {\n return false;\n }\n }\n if (filter.tools) {\n const names = body?.tools?.map((t: any) => t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n if (filter.temperature !== undefined && body?.temperature !== filter.temperature) {\n return false;\n }\n return true;\n}\n\n// ── Responses API filters ──\n\nexport interface OpenAIResponsesFilter {\n model?: RegExp | string;\n system?: RegExp | string;\n user?: RegExp | string;\n tools?: string[];\n}\n\nfunction matchesResponsesFilter(body: any, filter: OpenAIResponsesFilter): 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 if (filter.system) {\n const instructions = body?.instructions ?? '';\n const systemInput = body?.input?.find?.((m: any) => m.role === 'system')?.content ?? '';\n const text = instructions || systemInput;\n if (typeof filter.system === 'string' && !text.includes(filter.system)) {\n return false;\n }\n if (filter.system instanceof RegExp && !filter.system.test(text)) {\n return false;\n }\n }\n if (filter.user) {\n const msgs = (body?.input ?? [])\n .filter((m: any) => m.role === 'user')\n .map((m: any) =>\n typeof m.content === 'string' ? m.content : JSON.stringify(m.content),\n )\n .join(' ');\n if (typeof filter.user === 'string' && !msgs.includes(filter.user)) {\n return false;\n }\n if (filter.user instanceof RegExp && !filter.user.test(msgs)) {\n return false;\n }\n }\n if (filter.tools) {\n const names =\n body?.tools?.map((t: any) => t.name ?? t.function?.name).filter(Boolean) ?? [];\n if (!filter.tools.every((t) => names.includes(t))) {\n return false;\n }\n }\n return true;\n}\n\n// ── Response builders ──\n\nfunction buildChatReply(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: [{ index: 0, message: { role: 'assistant', content }, finish_reason: 'stop' }],\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\nfunction buildResponsesReply(data: unknown): InterceptResponse {\n const text = typeof data === 'string' ? data : JSON.stringify(data);\n return {\n status: 200,\n body: {\n id: 'resp-test',\n object: 'response',\n created_at: Math.floor(Date.now() / 1000),\n model: 'gpt-4o-test',\n output: [\n {\n type: 'message',\n id: 'msg-test',\n role: 'assistant',\n content: [{ type: 'output_text', text, annotations: [] }],\n },\n ],\n usage: { input_tokens: 10, output_tokens: 10, total_tokens: 20 },\n },\n };\n}\n\n// ── Public API ──\n\n/**\n * OpenAI API intercept helpers.\n */\nexport const openai = {\n /**\n * Trigger: match Chat Completions API requests.\n *\n * @example\n * openai.request() // any chat call\n * openai.request({ model: 'gpt-4o' }) // specific model\n * openai.request({ system: /classify/ }) // system prompt match\n */\n request(filter?: OpenAIChatFilter): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: OPENAI_CHAT_URL,\n match: filter ? (body: unknown) => matchesChatFilter(body, filter) : undefined,\n wrap: buildChatReply,\n };\n },\n\n /**\n * Trigger: match Responses API requests (AI SDK v5+) with auto-wrapping.\n * When used with a JSON file, the data is automatically wrapped in the\n * Responses API envelope.\n *\n * @param filter - Optional body filters.\n * @param url - Custom gateway URL (default: api.openai.com).\n *\n * @example\n * openai.agent({ user: /Report Ingestion/ }, GATEWAY)\n */\n agent(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger {\n return {\n adapter: 'openai',\n method: 'POST',\n url: url ?? OPENAI_RESPONSES_URL,\n match: filter ? (body: unknown) => matchesResponsesFilter(body, filter) : undefined,\n wrap: buildResponsesReply,\n };\n },\n\n /**\n * Response: wrap data in Chat Completions format.\n *\n * @example\n * openai.reply({ categories: ['TECH'] })\n */\n reply: buildChatReply,\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 content. */\n malformed(content: string): InterceptResponse {\n return buildChatReply(content);\n },\n\n /** Response: simulate a timeout. */\n timeout(): InterceptResponse {\n return { status: 200, body: {}, delay: 30_000 };\n },\n\n // ── Legacy aliases ──\n\n /** @deprecated Use openai.request() instead. */\n chat(filter?: OpenAIChatFilter): InterceptTrigger {\n return openai.request(filter);\n },\n\n /** @deprecated Use openai.reply() instead. */\n response: buildChatReply,\n\n /** @deprecated Use openai.agent() instead. */\n responses(filter?: OpenAIResponsesFilter, url?: string): InterceptTrigger {\n return openai.agent(filter, url);\n },\n\n /** @deprecated Use openai.reply() or .intercept(trigger, 'file.json') instead. */\n responsesResponse: buildResponsesReply,\n};\n"],"mappings":"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"}
|
package/dist/types.d.cts
CHANGED
|
@@ -3,12 +3,19 @@
|
|
|
3
3
|
* An intercept trigger describes which HTTP request to match.
|
|
4
4
|
*/
|
|
5
5
|
interface InterceptTrigger {
|
|
6
|
+
/** Adapter name - must match the folder prefix in file-based intercepts. */
|
|
7
|
+
adapter: string;
|
|
6
8
|
/** HTTP method to match. */
|
|
7
9
|
method: string;
|
|
8
10
|
/** URL pattern to match (string for exact prefix, RegExp for pattern). */
|
|
9
11
|
url: RegExp | string;
|
|
10
|
-
/** Optional request body matcher
|
|
12
|
+
/** Optional request body matcher - the handler only fires if this returns true. */
|
|
11
13
|
match?: (body: unknown) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Transform raw JSON data into a provider-specific response envelope.
|
|
16
|
+
* Called when .intercept(trigger, 'adapter/file.json') loads a file.
|
|
17
|
+
*/
|
|
18
|
+
wrap: (data: unknown) => InterceptResponse;
|
|
12
19
|
}
|
|
13
20
|
/**
|
|
14
21
|
* An intercept response describes what to return when the trigger matches.
|