anpord 0.1.13 → 0.1.16
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/api-context.cjs +18 -0
- package/dist/api-context.d.cts +8 -0
- package/dist/api-context.d.mts +8 -0
- package/dist/api-context.mjs +17 -0
- package/dist/api-mocks-B3qngoqS.cjs +68 -0
- package/dist/api-mocks-BfKw_hXc.mjs +33 -0
- package/dist/api-mocks-Bz3G00ve.d.cts +101 -0
- package/dist/api-mocks-Bz3G00ve.d.mts +101 -0
- package/dist/api-runtime.cjs +4 -0
- package/dist/api-runtime.d.cts +13 -0
- package/dist/api-runtime.d.mts +13 -0
- package/dist/api-runtime.mjs +2 -0
- package/dist/api.cjs +5 -0
- package/dist/api.d.cts +4 -0
- package/dist/api.d.mts +4 -0
- package/dist/api.mjs +2 -0
- package/dist/bin.cjs +8 -8
- package/dist/bin.mjs +6 -6
- package/dist/cli-runtime.cjs +1 -1
- package/dist/cli-runtime.mjs +1 -1
- package/dist/{client-BgRs8JvW.d.mts → client-C8tBcLYs.d.mts} +17 -17
- package/dist/{client-BirFO3jz.d.cts → client-CMkx-LKC.d.cts} +16 -16
- package/dist/{client-C-P2I00z.cjs → client-CfYNoI3L.cjs} +4 -91
- package/dist/{client-BfdjFtlV.mjs → client-YWKJd3f-.mjs} +3 -90
- package/dist/{compiler-uwb1pkdK.cjs → compiler-4FKsNxZ-.cjs} +89 -33
- package/dist/{compiler-D96wI7UP.mjs → compiler-Dsltkkj5.mjs} +77 -21
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/define-NZvmQuIv.d.cts +34 -0
- package/dist/define-NZvmQuIv.d.mts +34 -0
- package/dist/{eval-judges-DPPUftbh.d.cts → eval-judges-JiC8cUCE.d.cts} +1 -1
- package/dist/{eval-judges-DPPUftbh.d.mts → eval-judges-JiC8cUCE.d.mts} +1 -1
- package/dist/{eval-validations-BRdoZrTQ.mjs → eval-validations-Bmagd2y7.mjs} +2 -2
- package/dist/{eval-validations-_MlnQ_uv.cjs → eval-validations-CqMUt5ra.cjs} +7 -1
- package/dist/eval.cjs +1 -1
- package/dist/eval.d.cts +42 -21
- package/dist/eval.d.mts +42 -21
- package/dist/eval.mjs +1 -1
- package/dist/{evals-B6aT3xgH.d.cts → evals-B2UuSop0.d.cts} +136 -136
- package/dist/{evals-B6aT3xgH.d.mts → evals-B2UuSop0.d.mts} +136 -136
- package/dist/{types-Codjaq-o.d.mts → evals-api-CfAA3cew.d.mts} +12 -112
- package/dist/{types-ISsteq95.d.cts → evals-api-Clbj_nEN.d.cts} +11 -111
- package/dist/{evals-Dcc_x6jW.mjs → evals-api-DDv4gXU1.mjs} +95 -4
- package/dist/{evals-DouMsrsM.cjs → evals-api-kOuyIqvB.cjs} +103 -72
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +6 -6
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +2 -2
- package/dist/mcp-runtime.cjs +1 -1
- package/dist/mcp-runtime.mjs +1 -1
- package/dist/runtime-C0_JPkef.mjs +269 -0
- package/dist/runtime-YVJP5P2r.cjs +292 -0
- package/dist/source.d.cts +1 -1
- package/dist/source.d.mts +1 -1
- package/dist/types-BHokRQpg.d.mts +112 -0
- package/dist/types-UKEi5CCa.d.cts +112 -0
- package/dist/validator-runtime.cjs +6 -1
- package/dist/validator-runtime.d.cts +1 -1
- package/dist/validator-runtime.d.mts +1 -1
- package/dist/validator-runtime.mjs +6 -1
- package/dist/validators.d.cts +1 -1
- package/dist/validators.d.mts +1 -1
- package/package.json +21 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
const require_eval_validations = require("./eval-validations-CqMUt5ra.cjs");
|
|
2
|
+
const require_api_mocks = require("./api-mocks-B3qngoqS.cjs");
|
|
3
|
+
let effect = require("effect");
|
|
4
|
+
let _effect_platform = require("@effect/platform");
|
|
5
|
+
let _effect_platform_node_NodeFileSystem = require("@effect/platform-node/NodeFileSystem");
|
|
6
|
+
let _effect_platform_node_NodeRuntime = require("@effect/platform-node/NodeRuntime");
|
|
7
|
+
let node_http = require("node:http");
|
|
8
|
+
let _effect_platform_node_NodeHttpServer = require("@effect/platform-node/NodeHttpServer");
|
|
9
|
+
//#region src/mock-api/define.ts
|
|
10
|
+
const endpoint = (definition) => definition;
|
|
11
|
+
const Name = effect.Schema.String.pipe(effect.Schema.pattern(/^[a-z][a-z0-9-]{0,63}$/));
|
|
12
|
+
const Path = effect.Schema.String.pipe(effect.Schema.pattern(/^\/(?:[A-Za-z0-9._~-]+|:[A-Za-z][A-Za-z0-9_]*)(?:\/(?:[A-Za-z0-9._~-]+|:[A-Za-z][A-Za-z0-9_]*))*\/?$|^\/$/));
|
|
13
|
+
const PARAMETER = /:[A-Za-z][A-Za-z0-9_]*/g;
|
|
14
|
+
const api = (definition) => {
|
|
15
|
+
effect.Schema.decodeUnknownSync(Name)(definition.name);
|
|
16
|
+
const routes = /* @__PURE__ */ new Set();
|
|
17
|
+
for (const route of definition.endpoints) {
|
|
18
|
+
effect.Schema.decodeUnknownSync(Path)(route.path);
|
|
19
|
+
const key = `${route.method} ${route.path.replace(PARAMETER, ":parameter")}`;
|
|
20
|
+
if (routes.has(key)) throw new Error(`Duplicate API endpoint: ${key}`);
|
|
21
|
+
routes.add(key);
|
|
22
|
+
if (Object.keys(route.responses).length === 0) throw new Error(`API endpoint needs response schemas: ${key}`);
|
|
23
|
+
for (const status of Object.keys(route.responses)) effect.Schema.decodeUnknownSync(effect.Schema.Int.pipe(effect.Schema.between(200, 599)))(Number(status));
|
|
24
|
+
}
|
|
25
|
+
return definition;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/mock-api/errors.ts
|
|
29
|
+
var ApiMockError = class extends effect.Data.TaggedError("ApiMockError") {};
|
|
30
|
+
var ApiRequestError = class extends effect.Data.TaggedError("ApiRequestError") {};
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/mock-api/capture.ts
|
|
33
|
+
const SECRET_KEYS = [
|
|
34
|
+
"authorization",
|
|
35
|
+
"proxy-authorization",
|
|
36
|
+
"cookie",
|
|
37
|
+
"set-cookie",
|
|
38
|
+
"api-key",
|
|
39
|
+
"x-api-key",
|
|
40
|
+
"token",
|
|
41
|
+
"password",
|
|
42
|
+
"secret"
|
|
43
|
+
];
|
|
44
|
+
const apiCapture = (keys = []) => {
|
|
45
|
+
const sensitive = new Set([...SECRET_KEYS, ...keys].map((key) => key.toLowerCase()));
|
|
46
|
+
const capture = require_eval_validations.validationCapture();
|
|
47
|
+
return (value) => {
|
|
48
|
+
try {
|
|
49
|
+
const text = JSON.stringify(value, (key, current) => sensitive.has(key.toLowerCase()) ? "[redacted]" : current);
|
|
50
|
+
return capture(text === void 0 ? null : JSON.parse(text));
|
|
51
|
+
} catch {
|
|
52
|
+
return require_eval_validations.unavailableValue;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/mock-api/standard-schema.ts
|
|
58
|
+
const decodeStandard = (schema, value) => effect.Effect.tryPromise({
|
|
59
|
+
try: async () => {
|
|
60
|
+
const result = await schema["~standard"].validate(value);
|
|
61
|
+
if (result.issues !== void 0) throw new Error(result.issues.map(({ message }) => message).join("; "));
|
|
62
|
+
return result.value;
|
|
63
|
+
},
|
|
64
|
+
catch: () => new ApiMockError({ message: "Value does not match the declared schema" })
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/mock-api/response.ts
|
|
68
|
+
const HeaderName = effect.Schema.String.pipe(effect.Schema.pattern(/^[!#$%&'*+.^_`|~A-Za-z0-9-]+$/), effect.Schema.filter((name) => ![
|
|
69
|
+
"content-length",
|
|
70
|
+
"transfer-encoding",
|
|
71
|
+
"content-type"
|
|
72
|
+
].includes(name.toLowerCase())));
|
|
73
|
+
const Response = effect.Schema.Struct({
|
|
74
|
+
status: effect.Schema.Int,
|
|
75
|
+
body: effect.Schema.Unknown,
|
|
76
|
+
headers: effect.Schema.optional(effect.Schema.Record({
|
|
77
|
+
key: HeaderName,
|
|
78
|
+
value: effect.Schema.String.pipe(effect.Schema.pattern(/^[\t\x20-\x7e\x80-\xff]*$/))
|
|
79
|
+
}))
|
|
80
|
+
});
|
|
81
|
+
const bodyless = (status) => [
|
|
82
|
+
204,
|
|
83
|
+
205,
|
|
84
|
+
304
|
|
85
|
+
].includes(status);
|
|
86
|
+
const endpointResponse = (route, input, log) => effect.Effect.gen(function* () {
|
|
87
|
+
const decoded = yield* decodeStandard(route.inputSchema, input).pipe(effect.Effect.mapError(() => new ApiRequestError({
|
|
88
|
+
status: 400,
|
|
89
|
+
message: "Request does not match the endpoint schema"
|
|
90
|
+
})));
|
|
91
|
+
const returned = yield* effect.Effect.tryPromise({
|
|
92
|
+
try: (signal) => Promise.resolve(route.handler(decoded, {
|
|
93
|
+
signal,
|
|
94
|
+
log
|
|
95
|
+
})),
|
|
96
|
+
catch: () => new ApiMockError({ message: "Endpoint handler threw" })
|
|
97
|
+
}).pipe(effect.Effect.timeoutFail({
|
|
98
|
+
duration: "30 seconds",
|
|
99
|
+
onTimeout: () => new ApiMockError({ message: "Endpoint handler timed out" })
|
|
100
|
+
}));
|
|
101
|
+
const response = yield* effect.Schema.decodeUnknown(Response)(returned).pipe(effect.Effect.mapError(() => new ApiMockError({ message: "Invalid endpoint response" })));
|
|
102
|
+
const schema = route.responses[response.status];
|
|
103
|
+
if (schema === void 0) return yield* new ApiMockError({ message: "Endpoint returned an undeclared status" });
|
|
104
|
+
const output = yield* decodeStandard(schema, response.body);
|
|
105
|
+
if (bodyless(response.status) && output !== null) return yield* new ApiMockError({ message: "This HTTP status cannot carry a response body" });
|
|
106
|
+
const body = yield* effect.Effect.try({
|
|
107
|
+
try: () => {
|
|
108
|
+
const text = JSON.stringify(output);
|
|
109
|
+
if (text === void 0) throw new Error("Response body is undefined");
|
|
110
|
+
return text;
|
|
111
|
+
},
|
|
112
|
+
catch: () => new ApiMockError({ message: "Response is not JSON serializable" })
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
...response,
|
|
116
|
+
body,
|
|
117
|
+
error: null
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/mock-api/handler.ts
|
|
122
|
+
const Json = effect.Schema.parseJson(effect.Schema.Unknown);
|
|
123
|
+
const JSON_CONTENT_TYPE = /^application\/(?:[a-z0-9!#$&^_.+-]+\+)?json$/i;
|
|
124
|
+
const requestHandler = (definition, route, sequence, record) => effect.Effect.gen(function* () {
|
|
125
|
+
const request = yield* _effect_platform.HttpServerRequest.HttpServerRequest;
|
|
126
|
+
const routeContext = yield* effect.Effect.serviceOption(_effect_platform.HttpRouter.RouteContext);
|
|
127
|
+
const params = effect.Option.isSome(routeContext) ? routeContext.value.params : {};
|
|
128
|
+
const index = yield* effect.Ref.getAndUpdate(sequence, (value) => value + 1);
|
|
129
|
+
const startedAt = yield* effect.Clock.currentTimeMillis;
|
|
130
|
+
const url = new URL(request.url, "http://localhost");
|
|
131
|
+
const capture = apiCapture(definition.redact);
|
|
132
|
+
const captureLog = apiCapture(definition.redact);
|
|
133
|
+
const logs = [];
|
|
134
|
+
const fields = {
|
|
135
|
+
params,
|
|
136
|
+
query: _effect_platform.HttpServerRequest.searchParamsFromURL(url),
|
|
137
|
+
headers: request.headers
|
|
138
|
+
};
|
|
139
|
+
let input = fields;
|
|
140
|
+
const save = (status, output, error) => effect.Effect.gen(function* () {
|
|
141
|
+
const finishedAt = yield* effect.Clock.currentTimeMillis;
|
|
142
|
+
yield* record({
|
|
143
|
+
api: definition.name,
|
|
144
|
+
index,
|
|
145
|
+
method: request.method,
|
|
146
|
+
path: url.pathname,
|
|
147
|
+
matched: route !== void 0,
|
|
148
|
+
startedAt,
|
|
149
|
+
durationMs: Math.max(0, Math.round(finishedAt - startedAt)),
|
|
150
|
+
input: capture(input),
|
|
151
|
+
output: capture(output),
|
|
152
|
+
status,
|
|
153
|
+
error,
|
|
154
|
+
logs
|
|
155
|
+
});
|
|
156
|
+
}).pipe(effect.Effect.uninterruptible);
|
|
157
|
+
const { status, headers, body, error } = yield* effect.Effect.gen(function* () {
|
|
158
|
+
if (route === void 0) return yield* new ApiRequestError({
|
|
159
|
+
status: 404,
|
|
160
|
+
message: "No mock endpoint matches this request"
|
|
161
|
+
});
|
|
162
|
+
const text = yield* request.text.pipe(effect.Effect.mapError(() => new ApiRequestError({
|
|
163
|
+
status: 413,
|
|
164
|
+
message: "Request body could not be read within the size limit"
|
|
165
|
+
})));
|
|
166
|
+
if (text && !JSON_CONTENT_TYPE.test(request.headers["content-type"]?.split(";")[0]?.trim() ?? "")) return yield* new ApiRequestError({
|
|
167
|
+
status: 415,
|
|
168
|
+
message: "Expected a JSON request body"
|
|
169
|
+
});
|
|
170
|
+
const body = text === "" ? null : yield* effect.Schema.decodeUnknown(Json)(text).pipe(effect.Effect.mapError(() => new ApiRequestError({
|
|
171
|
+
status: 400,
|
|
172
|
+
message: "Invalid JSON request body"
|
|
173
|
+
})));
|
|
174
|
+
input = {
|
|
175
|
+
...fields,
|
|
176
|
+
body
|
|
177
|
+
};
|
|
178
|
+
return yield* endpointResponse(route, input, (value) => {
|
|
179
|
+
if (logs.length < 64) logs.push(captureLog(value));
|
|
180
|
+
});
|
|
181
|
+
}).pipe(effect.Effect.catchTags({
|
|
182
|
+
ApiRequestError: ({ status, message }) => effect.Effect.succeed({
|
|
183
|
+
status,
|
|
184
|
+
body: JSON.stringify({ message }),
|
|
185
|
+
headers: void 0,
|
|
186
|
+
error: null
|
|
187
|
+
}),
|
|
188
|
+
ApiMockError: ({ message }) => effect.Effect.succeed({
|
|
189
|
+
status: 500,
|
|
190
|
+
body: JSON.stringify({ message }),
|
|
191
|
+
headers: void 0,
|
|
192
|
+
error: message
|
|
193
|
+
})
|
|
194
|
+
}), effect.Effect.onInterrupt(() => save(499, null, "Request cancelled").pipe(effect.Effect.orDie)));
|
|
195
|
+
const empty = request.method === "HEAD" || bodyless(status);
|
|
196
|
+
yield* save(status, {
|
|
197
|
+
status,
|
|
198
|
+
headers,
|
|
199
|
+
body: empty ? null : JSON.parse(body)
|
|
200
|
+
}, error);
|
|
201
|
+
return empty ? _effect_platform.HttpServerResponse.empty({
|
|
202
|
+
status,
|
|
203
|
+
headers
|
|
204
|
+
}) : _effect_platform.HttpServerResponse.text(body, {
|
|
205
|
+
status,
|
|
206
|
+
headers,
|
|
207
|
+
contentType: "application/json"
|
|
208
|
+
});
|
|
209
|
+
}).pipe(_effect_platform.HttpServerRequest.withMaxBodySize(effect.Option.some(1048576)), effect.Effect.withSpan("ApiMock.request"));
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/mock-api/server.ts
|
|
212
|
+
const startApi = (definition, record) => effect.Effect.gen(function* () {
|
|
213
|
+
yield* effect.Effect.try({
|
|
214
|
+
try: () => api(definition),
|
|
215
|
+
catch: () => new ApiMockError({ message: "Invalid API definition" })
|
|
216
|
+
});
|
|
217
|
+
const sequence = yield* effect.Ref.make(0);
|
|
218
|
+
let router = _effect_platform.HttpRouter.empty;
|
|
219
|
+
for (const route of definition.endpoints) router = _effect_platform.HttpRouter.route(route.method)(router, route.path, requestHandler(definition, route, sequence, record));
|
|
220
|
+
const server = yield* (0, _effect_platform_node_NodeHttpServer.make)(node_http.createServer, {
|
|
221
|
+
host: "127.0.0.1",
|
|
222
|
+
port: 0
|
|
223
|
+
}).pipe(effect.Effect.mapError(() => new ApiMockError({ message: "Could not start local API server" })));
|
|
224
|
+
yield* server.serve(router.pipe(effect.Effect.catchTag("RouteNotFound", () => requestHandler(definition, void 0, sequence, record))));
|
|
225
|
+
if (server.address._tag !== "TcpAddress") return yield* new ApiMockError({ message: "API server did not bind TCP" });
|
|
226
|
+
return {
|
|
227
|
+
name: definition.name,
|
|
228
|
+
url: `http://127.0.0.1:${server.address.port}`,
|
|
229
|
+
endpoints: definition.endpoints.map(({ method, path, description }) => ({
|
|
230
|
+
method,
|
|
231
|
+
path,
|
|
232
|
+
...description ? { description } : {}
|
|
233
|
+
}))
|
|
234
|
+
};
|
|
235
|
+
}).pipe(effect.Effect.withSpan("ApiMock.start"));
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/mock-api/runtime.ts
|
|
238
|
+
const withApi = ({ api, run }) => effect.Effect.gen(function* () {
|
|
239
|
+
const calls = yield* effect.Ref.make([]);
|
|
240
|
+
const fatal = yield* effect.Deferred.make();
|
|
241
|
+
const server = yield* startApi(api, (call) => effect.Ref.modify(calls, (values) => [values.length < 256, values.length < 256 ? [...values, call] : values]).pipe(effect.Effect.flatMap((recorded) => recorded ? effect.Effect.void : effect.Deferred.fail(fatal, new ApiMockError({ message: "API request limit exceeded" })).pipe(effect.Effect.asVoid))));
|
|
242
|
+
const result = yield* effect.Effect.tryPromise({
|
|
243
|
+
try: () => run({
|
|
244
|
+
url: server.url,
|
|
245
|
+
calls: () => effect.Effect.runPromise(effect.Ref.get(calls))
|
|
246
|
+
}),
|
|
247
|
+
catch: (cause) => cause
|
|
248
|
+
}).pipe(effect.Effect.raceFirst(effect.Deferred.await(fatal)));
|
|
249
|
+
if ((yield* effect.Ref.get(calls)).some((call) => call.error !== null)) return yield* new ApiMockError({ message: "An API endpoint failed during execution" });
|
|
250
|
+
return result;
|
|
251
|
+
}).pipe(effect.Effect.scoped, effect.Effect.withSpan("ApiMock.withApi"), effect.Effect.runPromise);
|
|
252
|
+
const runApiServers = (definitions) => effect.Effect.gen(function* () {
|
|
253
|
+
const fs = yield* _effect_platform.FileSystem.FileSystem;
|
|
254
|
+
const fatal = yield* effect.Deferred.make();
|
|
255
|
+
yield* fs.makeDirectory(".anpord/api", { recursive: true });
|
|
256
|
+
yield* fs.writeFileString(require_api_mocks.API_JOURNAL, "");
|
|
257
|
+
const lock = yield* effect.Effect.makeSemaphore(1);
|
|
258
|
+
const count = yield* effect.Ref.make(0);
|
|
259
|
+
const record = (call) => effect.Effect.gen(function* () {
|
|
260
|
+
if ((yield* effect.Ref.getAndUpdate(count, (value) => value + 1)) >= 256) return yield* new ApiMockError({ message: "API request limit exceeded" });
|
|
261
|
+
yield* fs.writeFileString(require_api_mocks.API_JOURNAL, `${JSON.stringify(call)}\n`, { flag: "a" });
|
|
262
|
+
}).pipe(effect.Effect.mapError(() => new ApiMockError({ message: "API request evidence could not be written" })), effect.Effect.tapError((cause) => effect.Deferred.fail(fatal, cause)), lock.withPermits(1));
|
|
263
|
+
const manifest = yield* effect.Effect.forEach(definitions, (definition) => startApi(definition, record));
|
|
264
|
+
yield* fs.writeFileString(require_api_mocks.API_MANIFEST, JSON.stringify(manifest));
|
|
265
|
+
yield* effect.Effect.sync(() => process.stdout.write(`${require_api_mocks.API_READY}${JSON.stringify(manifest)}\n`));
|
|
266
|
+
yield* effect.Deferred.await(fatal);
|
|
267
|
+
}).pipe(effect.Effect.scoped, effect.Effect.provide(_effect_platform_node_NodeFileSystem.layer), effect.Effect.withSpan("ApiMock.serve"), _effect_platform_node_NodeRuntime.runMain);
|
|
268
|
+
//#endregion
|
|
269
|
+
Object.defineProperty(exports, "api", {
|
|
270
|
+
enumerable: true,
|
|
271
|
+
get: function() {
|
|
272
|
+
return api;
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
Object.defineProperty(exports, "endpoint", {
|
|
276
|
+
enumerable: true,
|
|
277
|
+
get: function() {
|
|
278
|
+
return endpoint;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
Object.defineProperty(exports, "runApiServers", {
|
|
282
|
+
enumerable: true,
|
|
283
|
+
get: function() {
|
|
284
|
+
return runApiServers;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
Object.defineProperty(exports, "withApi", {
|
|
288
|
+
enumerable: true,
|
|
289
|
+
get: function() {
|
|
290
|
+
return withApi;
|
|
291
|
+
}
|
|
292
|
+
});
|
package/dist/source.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as EvalSource } from "./evals-
|
|
1
|
+
import { f as EvalSource } from "./evals-B2UuSop0.cjs";
|
|
2
2
|
//#region src/evals/source.d.ts
|
|
3
3
|
declare const repo: (spec: string) => EvalSource;
|
|
4
4
|
declare const files: (contents: Readonly<Record<string, string>>) => EvalSource;
|
package/dist/source.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as EvalSource } from "./evals-
|
|
1
|
+
import { f as EvalSource } from "./evals-B2UuSop0.mjs";
|
|
2
2
|
//#region src/evals/source.d.ts
|
|
3
3
|
declare const repo: (spec: string) => EvalSource;
|
|
4
4
|
declare const files: (contents: Readonly<Record<string, string>>) => EvalSource;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { t as PublicStartEvalRequest } from "./evals-api-CfAA3cew.mjs";
|
|
2
|
+
import { f as EvalSource, o as EvalHarness } from "./evals-B2UuSop0.mjs";
|
|
3
|
+
import { t as ApiCall } from "./api-mocks-Bz3G00ve.mjs";
|
|
4
|
+
import { t as EvalJudge } from "./eval-judges-JiC8cUCE.mjs";
|
|
5
|
+
import { t as McpCall } from "./calls-DYqBi5FA.mjs";
|
|
6
|
+
import { n as McpServerDefinition } from "./define-HK0eeSNn.mjs";
|
|
7
|
+
import { t as ApiDefinition } from "./define-NZvmQuIv.mjs";
|
|
8
|
+
import { t as CliCall } from "./calls-Drj_dZpu.mjs";
|
|
9
|
+
import { n as CliDefinition } from "./define-BEiYXrC5.mjs";
|
|
10
|
+
//#region src/evals/types.d.ts
|
|
11
|
+
type EvalTaskRequest = PublicStartEvalRequest["tasks"][number];
|
|
12
|
+
/** A profile directory beside the eval file; `dir` resolves against it. */
|
|
13
|
+
interface ProfileRef {
|
|
14
|
+
readonly dir: string;
|
|
15
|
+
readonly name: string;
|
|
16
|
+
}
|
|
17
|
+
type HarnessRef = EvalHarness | {
|
|
18
|
+
readonly base: EvalHarness;
|
|
19
|
+
readonly profile: ProfileRef;
|
|
20
|
+
};
|
|
21
|
+
interface EvalTaskDefinition {
|
|
22
|
+
readonly harness: HarnessRef;
|
|
23
|
+
readonly model: EvalTaskRequest["model"];
|
|
24
|
+
readonly sandbox?: EvalTaskRequest["sandbox"];
|
|
25
|
+
}
|
|
26
|
+
interface CommandResult {
|
|
27
|
+
readonly exitCode: number;
|
|
28
|
+
readonly stderr: string;
|
|
29
|
+
readonly stdout: string;
|
|
30
|
+
}
|
|
31
|
+
interface ExecOptions {
|
|
32
|
+
readonly cwd?: string;
|
|
33
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
34
|
+
readonly timeoutMs?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Entries are write-once, so the key must name everything the contents
|
|
37
|
+
* depend on -- a lockfile hash above all. */
|
|
38
|
+
interface CaseCache {
|
|
39
|
+
readonly key: string;
|
|
40
|
+
/** Relative to the workspace. */
|
|
41
|
+
readonly path: string;
|
|
42
|
+
}
|
|
43
|
+
interface PrepareContext {
|
|
44
|
+
readonly api: {
|
|
45
|
+
readonly url: (name: string) => Promise<string>;
|
|
46
|
+
};
|
|
47
|
+
/** True when the runner restored a cached directory, so a prepare can skip
|
|
48
|
+
* the work that produced it. */
|
|
49
|
+
readonly cached: boolean;
|
|
50
|
+
readonly exec: (file: string, args?: readonly string[], options?: ExecOptions) => Promise<CommandResult>;
|
|
51
|
+
readonly exists: (path: string) => Promise<boolean>;
|
|
52
|
+
readonly readText: (path: string) => Promise<string>;
|
|
53
|
+
readonly workspace: string;
|
|
54
|
+
}
|
|
55
|
+
type PrepareValue = Readonly<Record<string, unknown>>;
|
|
56
|
+
type Prepare = (context: PrepareContext) => Promise<PrepareValue | undefined> | PrepareValue | undefined;
|
|
57
|
+
interface ValidatorContext {
|
|
58
|
+
/** Empty when the agent said nothing. */
|
|
59
|
+
readonly answer: () => Promise<string>;
|
|
60
|
+
readonly api: {
|
|
61
|
+
readonly url: (name: string) => Promise<string>;
|
|
62
|
+
readonly calls: (name?: string) => Promise<readonly ApiCall[]>;
|
|
63
|
+
};
|
|
64
|
+
readonly cli: {
|
|
65
|
+
readonly calls: (cli?: string) => Promise<readonly CliCall[]>;
|
|
66
|
+
};
|
|
67
|
+
readonly exec: (command: string) => Promise<CommandResult>;
|
|
68
|
+
readonly exists: (path: string) => Promise<boolean>;
|
|
69
|
+
readonly mcp: {
|
|
70
|
+
readonly calls: (server?: string) => Promise<readonly McpCall[]>;
|
|
71
|
+
};
|
|
72
|
+
readonly prepared: Readonly<Record<string, unknown>>;
|
|
73
|
+
readonly readText: (path: string) => Promise<string>;
|
|
74
|
+
/** Every reply, oldest first, separated by a blank line. */
|
|
75
|
+
readonly transcript: () => Promise<string>;
|
|
76
|
+
}
|
|
77
|
+
interface ValidatorResult {
|
|
78
|
+
readonly message?: string;
|
|
79
|
+
readonly passed: boolean;
|
|
80
|
+
}
|
|
81
|
+
type Validator = (context: ValidatorContext) => boolean | ValidatorResult | Promise<boolean | ValidatorResult>;
|
|
82
|
+
type DeclaredSource = EvalSource | string;
|
|
83
|
+
interface EvalCaseBase {
|
|
84
|
+
/** Restored before the prepare runs, saved after it succeeds. */
|
|
85
|
+
readonly cache?: CaseCache;
|
|
86
|
+
readonly name: string;
|
|
87
|
+
readonly prepare?: Prepare | null;
|
|
88
|
+
readonly source?: DeclaredSource;
|
|
89
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
90
|
+
}
|
|
91
|
+
type EvalCaseDefinition = EvalCaseBase & ({
|
|
92
|
+
readonly validate: Validator | EvalJudge | readonly (Validator | EvalJudge)[];
|
|
93
|
+
readonly verify?: never;
|
|
94
|
+
} | {
|
|
95
|
+
readonly validate?: never;
|
|
96
|
+
readonly verify: string;
|
|
97
|
+
});
|
|
98
|
+
interface EvalDefinition {
|
|
99
|
+
readonly api?: readonly ApiDefinition[];
|
|
100
|
+
readonly captureSource?: boolean;
|
|
101
|
+
readonly captureValidation?: boolean;
|
|
102
|
+
readonly cases: readonly EvalCaseDefinition[];
|
|
103
|
+
readonly cli?: readonly CliDefinition[];
|
|
104
|
+
readonly mcp?: readonly McpServerDefinition[];
|
|
105
|
+
readonly name: string;
|
|
106
|
+
readonly prompt: string;
|
|
107
|
+
readonly source?: DeclaredSource;
|
|
108
|
+
readonly tasks: readonly EvalTaskDefinition[];
|
|
109
|
+
readonly trials: number;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { EvalTaskDefinition as a, Prepare as c, ProfileRef as d, Validator as f, EvalDefinition as i, PrepareContext as l, ValidatorResult as m, CommandResult as n, ExecOptions as o, ValidatorContext as p, EvalCaseDefinition as r, HarnessRef as s, CaseCache as t, PrepareValue as u };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { t as PublicStartEvalRequest } from "./evals-api-Clbj_nEN.cjs";
|
|
2
|
+
import { f as EvalSource, o as EvalHarness } from "./evals-B2UuSop0.cjs";
|
|
3
|
+
import { t as ApiCall } from "./api-mocks-Bz3G00ve.cjs";
|
|
4
|
+
import { t as EvalJudge } from "./eval-judges-JiC8cUCE.cjs";
|
|
5
|
+
import { t as McpCall } from "./calls-DYqBi5FA.cjs";
|
|
6
|
+
import { n as McpServerDefinition } from "./define-HK0eeSNn.cjs";
|
|
7
|
+
import { t as ApiDefinition } from "./define-NZvmQuIv.cjs";
|
|
8
|
+
import { t as CliCall } from "./calls-Drj_dZpu.cjs";
|
|
9
|
+
import { n as CliDefinition } from "./define-BEiYXrC5.cjs";
|
|
10
|
+
//#region src/evals/types.d.ts
|
|
11
|
+
type EvalTaskRequest = PublicStartEvalRequest["tasks"][number];
|
|
12
|
+
/** A profile directory beside the eval file; `dir` resolves against it. */
|
|
13
|
+
interface ProfileRef {
|
|
14
|
+
readonly dir: string;
|
|
15
|
+
readonly name: string;
|
|
16
|
+
}
|
|
17
|
+
type HarnessRef = EvalHarness | {
|
|
18
|
+
readonly base: EvalHarness;
|
|
19
|
+
readonly profile: ProfileRef;
|
|
20
|
+
};
|
|
21
|
+
interface EvalTaskDefinition {
|
|
22
|
+
readonly harness: HarnessRef;
|
|
23
|
+
readonly model: EvalTaskRequest["model"];
|
|
24
|
+
readonly sandbox?: EvalTaskRequest["sandbox"];
|
|
25
|
+
}
|
|
26
|
+
interface CommandResult {
|
|
27
|
+
readonly exitCode: number;
|
|
28
|
+
readonly stderr: string;
|
|
29
|
+
readonly stdout: string;
|
|
30
|
+
}
|
|
31
|
+
interface ExecOptions {
|
|
32
|
+
readonly cwd?: string;
|
|
33
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
34
|
+
readonly timeoutMs?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Entries are write-once, so the key must name everything the contents
|
|
37
|
+
* depend on -- a lockfile hash above all. */
|
|
38
|
+
interface CaseCache {
|
|
39
|
+
readonly key: string;
|
|
40
|
+
/** Relative to the workspace. */
|
|
41
|
+
readonly path: string;
|
|
42
|
+
}
|
|
43
|
+
interface PrepareContext {
|
|
44
|
+
readonly api: {
|
|
45
|
+
readonly url: (name: string) => Promise<string>;
|
|
46
|
+
};
|
|
47
|
+
/** True when the runner restored a cached directory, so a prepare can skip
|
|
48
|
+
* the work that produced it. */
|
|
49
|
+
readonly cached: boolean;
|
|
50
|
+
readonly exec: (file: string, args?: readonly string[], options?: ExecOptions) => Promise<CommandResult>;
|
|
51
|
+
readonly exists: (path: string) => Promise<boolean>;
|
|
52
|
+
readonly readText: (path: string) => Promise<string>;
|
|
53
|
+
readonly workspace: string;
|
|
54
|
+
}
|
|
55
|
+
type PrepareValue = Readonly<Record<string, unknown>>;
|
|
56
|
+
type Prepare = (context: PrepareContext) => Promise<PrepareValue | undefined> | PrepareValue | undefined;
|
|
57
|
+
interface ValidatorContext {
|
|
58
|
+
/** Empty when the agent said nothing. */
|
|
59
|
+
readonly answer: () => Promise<string>;
|
|
60
|
+
readonly api: {
|
|
61
|
+
readonly url: (name: string) => Promise<string>;
|
|
62
|
+
readonly calls: (name?: string) => Promise<readonly ApiCall[]>;
|
|
63
|
+
};
|
|
64
|
+
readonly cli: {
|
|
65
|
+
readonly calls: (cli?: string) => Promise<readonly CliCall[]>;
|
|
66
|
+
};
|
|
67
|
+
readonly exec: (command: string) => Promise<CommandResult>;
|
|
68
|
+
readonly exists: (path: string) => Promise<boolean>;
|
|
69
|
+
readonly mcp: {
|
|
70
|
+
readonly calls: (server?: string) => Promise<readonly McpCall[]>;
|
|
71
|
+
};
|
|
72
|
+
readonly prepared: Readonly<Record<string, unknown>>;
|
|
73
|
+
readonly readText: (path: string) => Promise<string>;
|
|
74
|
+
/** Every reply, oldest first, separated by a blank line. */
|
|
75
|
+
readonly transcript: () => Promise<string>;
|
|
76
|
+
}
|
|
77
|
+
interface ValidatorResult {
|
|
78
|
+
readonly message?: string;
|
|
79
|
+
readonly passed: boolean;
|
|
80
|
+
}
|
|
81
|
+
type Validator = (context: ValidatorContext) => boolean | ValidatorResult | Promise<boolean | ValidatorResult>;
|
|
82
|
+
type DeclaredSource = EvalSource | string;
|
|
83
|
+
interface EvalCaseBase {
|
|
84
|
+
/** Restored before the prepare runs, saved after it succeeds. */
|
|
85
|
+
readonly cache?: CaseCache;
|
|
86
|
+
readonly name: string;
|
|
87
|
+
readonly prepare?: Prepare | null;
|
|
88
|
+
readonly source?: DeclaredSource;
|
|
89
|
+
readonly variables?: Readonly<Record<string, string>>;
|
|
90
|
+
}
|
|
91
|
+
type EvalCaseDefinition = EvalCaseBase & ({
|
|
92
|
+
readonly validate: Validator | EvalJudge | readonly (Validator | EvalJudge)[];
|
|
93
|
+
readonly verify?: never;
|
|
94
|
+
} | {
|
|
95
|
+
readonly validate?: never;
|
|
96
|
+
readonly verify: string;
|
|
97
|
+
});
|
|
98
|
+
interface EvalDefinition {
|
|
99
|
+
readonly api?: readonly ApiDefinition[];
|
|
100
|
+
readonly captureSource?: boolean;
|
|
101
|
+
readonly captureValidation?: boolean;
|
|
102
|
+
readonly cases: readonly EvalCaseDefinition[];
|
|
103
|
+
readonly cli?: readonly CliDefinition[];
|
|
104
|
+
readonly mcp?: readonly McpServerDefinition[];
|
|
105
|
+
readonly name: string;
|
|
106
|
+
readonly prompt: string;
|
|
107
|
+
readonly source?: DeclaredSource;
|
|
108
|
+
readonly tasks: readonly EvalTaskDefinition[];
|
|
109
|
+
readonly trials: number;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { EvalTaskDefinition as a, Prepare as c, ProfileRef as d, Validator as f, EvalDefinition as i, PrepareContext as l, ValidatorResult as m, CommandResult as n, ExecOptions as o, ValidatorContext as p, EvalCaseDefinition as r, HarnessRef as s, CaseCache as t, PrepareValue as u };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_eval_validations = require("./eval-validations-
|
|
2
|
+
const require_eval_validations = require("./eval-validations-CqMUt5ra.cjs");
|
|
3
|
+
const require_api_context = require("./api-context.cjs");
|
|
3
4
|
let effect = require("effect");
|
|
4
5
|
let node_fs_promises = require("node:fs/promises");
|
|
5
6
|
let node_child_process = require("node:child_process");
|
|
@@ -117,6 +118,10 @@ const calls = async (path, schema) => {
|
|
|
117
118
|
return text.trim() === "" ? [] : text.trim().split("\n").map((line) => decode(line));
|
|
118
119
|
};
|
|
119
120
|
const context = () => ({
|
|
121
|
+
api: {
|
|
122
|
+
url: (name) => observe("api.url", [name], () => require_api_context.apiContext.url(name)),
|
|
123
|
+
calls: (name) => observe("api.calls", name === void 0 ? [] : [name], () => require_api_context.apiContext.calls(name))
|
|
124
|
+
},
|
|
120
125
|
answer: () => observe("answer", [], () => readOptional(process.env.ANPORD_ANSWER_FILE)),
|
|
121
126
|
transcript: () => observe("transcript", [], () => readOptional(process.env.ANPORD_TRANSCRIPT_FILE)),
|
|
122
127
|
prepared: effect.Schema.decodeUnknownSync(effect.Schema.parseJson(effect.Schema.Record({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as validationCapture, i as unavailableValue, n as VALIDATION_FRAME, o as validationExecution, s as validationSnapshot } from "./eval-validations-Bmagd2y7.mjs";
|
|
2
|
+
import { apiContext } from "./api-context.mjs";
|
|
2
3
|
import { Schema } from "effect";
|
|
3
4
|
import { access, readFile } from "node:fs/promises";
|
|
4
5
|
import { spawn } from "node:child_process";
|
|
@@ -116,6 +117,10 @@ const calls = async (path, schema) => {
|
|
|
116
117
|
return text.trim() === "" ? [] : text.trim().split("\n").map((line) => decode(line));
|
|
117
118
|
};
|
|
118
119
|
const context = () => ({
|
|
120
|
+
api: {
|
|
121
|
+
url: (name) => observe("api.url", [name], () => apiContext.url(name)),
|
|
122
|
+
calls: (name) => observe("api.calls", name === void 0 ? [] : [name], () => apiContext.calls(name))
|
|
123
|
+
},
|
|
119
124
|
answer: () => observe("answer", [], () => readOptional(process.env.ANPORD_ANSWER_FILE)),
|
|
120
125
|
transcript: () => observe("transcript", [], () => readOptional(process.env.ANPORD_TRANSCRIPT_FILE)),
|
|
121
126
|
prepared: Schema.decodeUnknownSync(Schema.parseJson(Schema.Record({
|
package/dist/validators.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as EvalJudgment, t as EvalJudge } from "./eval-judges-
|
|
1
|
+
import { n as EvalJudgment, t as EvalJudge } from "./eval-judges-JiC8cUCE.cjs";
|
|
2
2
|
//#region src/validators.d.ts
|
|
3
3
|
type JudgeOptions = typeof EvalJudge.Encoded extends (infer Options) ? Options extends {
|
|
4
4
|
readonly kind: "judge";
|
package/dist/validators.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as EvalJudgment, t as EvalJudge } from "./eval-judges-
|
|
1
|
+
import { n as EvalJudgment, t as EvalJudge } from "./eval-judges-JiC8cUCE.mjs";
|
|
2
2
|
//#region src/validators.d.ts
|
|
3
3
|
type JudgeOptions = typeof EvalJudge.Encoded extends (infer Options) ? Options extends {
|
|
4
4
|
readonly kind: "judge";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anpord",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "TypeScript SDK and CLI for coding agent evals and prompt management.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,6 +25,26 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"./package.json": "./package.json",
|
|
28
|
+
"./api": {
|
|
29
|
+
"import": {
|
|
30
|
+
"types": "./dist/api.d.mts",
|
|
31
|
+
"default": "./dist/api.mjs"
|
|
32
|
+
},
|
|
33
|
+
"require": {
|
|
34
|
+
"types": "./dist/api.d.cts",
|
|
35
|
+
"default": "./dist/api.cjs"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"./api/runtime": {
|
|
39
|
+
"import": {
|
|
40
|
+
"types": "./dist/api-runtime.d.mts",
|
|
41
|
+
"default": "./dist/api-runtime.mjs"
|
|
42
|
+
},
|
|
43
|
+
"require": {
|
|
44
|
+
"types": "./dist/api-runtime.d.cts",
|
|
45
|
+
"default": "./dist/api-runtime.cjs"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
28
48
|
"./validators": {
|
|
29
49
|
"import": {
|
|
30
50
|
"types": "./dist/validators.d.mts",
|