@adversarylabs/sdk 0.1.37 → 0.1.39
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 +111 -0
- package/dist/candidate-recovery.d.ts +53 -0
- package/dist/candidate-recovery.d.ts.map +1 -0
- package/dist/candidate-recovery.js +185 -0
- package/dist/candidate-recovery.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -2
- package/dist/index.js.map +1 -1
- package/dist/model-diagnostics.d.ts +6 -0
- package/dist/model-diagnostics.d.ts.map +1 -0
- package/dist/model-diagnostics.js +78 -0
- package/dist/model-diagnostics.js.map +1 -0
- package/dist/model.d.ts +2 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +92 -26
- package/dist/model.js.map +1 -1
- package/dist/repository-diagnostics.d.ts +29 -0
- package/dist/repository-diagnostics.d.ts.map +1 -0
- package/dist/repository-diagnostics.js +73 -0
- package/dist/repository-diagnostics.js.map +1 -0
- package/dist/repository-model.d.ts +4 -0
- package/dist/repository-model.d.ts.map +1 -1
- package/dist/repository-model.js +333 -168
- package/dist/repository-model.js.map +1 -1
- package/dist/repository-path.d.ts +4 -0
- package/dist/repository-path.d.ts.map +1 -0
- package/dist/repository-path.js +16 -0
- package/dist/repository-path.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Bounded, content-free broker timing; never changes request or retry behavior. */
|
|
2
|
+
export declare function modelAttemptDiagnostics(deadlineMs: number, stage: "model_review" | "repository_planning"): {
|
|
3
|
+
startRetryDelay(attempt: number): (failureCode: string) => void;
|
|
4
|
+
start(attempt: number): (outcome: "succeeded" | "failed", actualProvider?: string, actualModel?: string, failureCode?: string) => void;
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=model-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-diagnostics.d.ts","sourceRoot":"","sources":["../src/model-diagnostics.ts"],"names":[],"mappings":"AAsBA,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,cAAc,GAAG,qBAAqB;6BAQlB,MAAM,IAGrB,aAAa,MAAM;mBAmBd,MAAM,IAajB,SAAS,WAAW,GAAG,QAAQ,EAC/B,iBAAiB,MAAM,EACvB,cAAc,MAAM,EACpB,cAAc,MAAM;EAgB3B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { writeRepositoryDiagnostic } from "./repository-diagnostics.js";
|
|
3
|
+
function identity(value) {
|
|
4
|
+
return value && /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/.test(value) ? value : "unknown";
|
|
5
|
+
}
|
|
6
|
+
const failureCodes = new Set([
|
|
7
|
+
"broker_unavailable",
|
|
8
|
+
"model_timeout",
|
|
9
|
+
"model_response_too_large",
|
|
10
|
+
"model_response_limit",
|
|
11
|
+
"invalid_broker_response",
|
|
12
|
+
"unsupported_model_protocol",
|
|
13
|
+
"invalid_model_output",
|
|
14
|
+
"invalid_model_schema",
|
|
15
|
+
"model_review_failed",
|
|
16
|
+
"bad_gateway",
|
|
17
|
+
"rate_limited",
|
|
18
|
+
"provider_unavailable",
|
|
19
|
+
]);
|
|
20
|
+
/** Bounded, content-free broker timing; never changes request or retry behavior. */
|
|
21
|
+
export function modelAttemptDiagnostics(deadlineMs, stage) {
|
|
22
|
+
const requestId = randomUUID();
|
|
23
|
+
const reviewStarted = performance.now();
|
|
24
|
+
const jobId = identity(process.env.HOSTED_REVIEW_JOB_ID);
|
|
25
|
+
const provider = identity(process.env.ADVERSARY_MODEL_PROVIDER);
|
|
26
|
+
const model = identity(process.env.ADVERSARY_MODEL);
|
|
27
|
+
return {
|
|
28
|
+
startRetryDelay(attempt) {
|
|
29
|
+
const started = performance.now();
|
|
30
|
+
const remainingDeadlineMs = Math.max(0, Math.round(deadlineMs - (started - reviewStarted)));
|
|
31
|
+
return (failureCode) => {
|
|
32
|
+
writeRepositoryDiagnostic({
|
|
33
|
+
event: "model.retry-delay",
|
|
34
|
+
requestId,
|
|
35
|
+
jobId,
|
|
36
|
+
stage: "broker_retry_delay",
|
|
37
|
+
modelStage: stage,
|
|
38
|
+
attempt,
|
|
39
|
+
deadlineMs,
|
|
40
|
+
remainingDeadlineMs,
|
|
41
|
+
elapsedMs: Math.round(performance.now() - started),
|
|
42
|
+
outcome: "failed",
|
|
43
|
+
provider,
|
|
44
|
+
model,
|
|
45
|
+
identitySource: "runner_environment",
|
|
46
|
+
failureCode: failureCodes.has(failureCode) ? failureCode : "model_review_failed",
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
start(attempt) {
|
|
51
|
+
const started = performance.now();
|
|
52
|
+
const record = {
|
|
53
|
+
event: "model.attempt",
|
|
54
|
+
requestId,
|
|
55
|
+
jobId,
|
|
56
|
+
stage,
|
|
57
|
+
attempt,
|
|
58
|
+
deadlineMs,
|
|
59
|
+
remainingDeadlineMs: Math.max(0, Math.round(deadlineMs - (started - reviewStarted))),
|
|
60
|
+
};
|
|
61
|
+
writeRepositoryDiagnostic({ ...record, outcome: "started", elapsedMs: 0, provider, model });
|
|
62
|
+
return (outcome, actualProvider, actualModel, failureCode) => {
|
|
63
|
+
writeRepositoryDiagnostic({
|
|
64
|
+
...record,
|
|
65
|
+
outcome,
|
|
66
|
+
elapsedMs: Math.round(performance.now() - started),
|
|
67
|
+
provider: actualProvider === undefined ? provider : identity(actualProvider),
|
|
68
|
+
model: actualModel === undefined ? model : identity(actualModel),
|
|
69
|
+
identitySource: actualProvider === undefined ? "runner_environment" : "broker_response",
|
|
70
|
+
...(failureCode === undefined
|
|
71
|
+
? {}
|
|
72
|
+
: { failureCode: failureCodes.has(failureCode) ? failureCode : "model_review_failed" }),
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=model-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-diagnostics.js","sourceRoot":"","sources":["../src/model-diagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { writeRepositoryDiagnostic } from \"./repository-diagnostics.js\";\n\nfunction identity(value: string | undefined): string {\n return value && /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/.test(value) ? value : \"unknown\";\n}\n\nconst failureCodes = new Set([\n \"broker_unavailable\",\n \"model_timeout\",\n \"model_response_too_large\",\n \"model_response_limit\",\n \"invalid_broker_response\",\n \"unsupported_model_protocol\",\n \"invalid_model_output\",\n \"invalid_model_schema\",\n \"model_review_failed\",\n \"bad_gateway\",\n \"rate_limited\",\n \"provider_unavailable\",\n]);\n\n/** Bounded, content-free broker timing; never changes request or retry behavior. */\nexport function modelAttemptDiagnostics(\n deadlineMs: number,\n stage: \"model_review\" | \"repository_planning\",\n) {\n const requestId = randomUUID();\n const reviewStarted = performance.now();\n const jobId = identity(process.env.HOSTED_REVIEW_JOB_ID);\n const provider = identity(process.env.ADVERSARY_MODEL_PROVIDER);\n const model = identity(process.env.ADVERSARY_MODEL);\n return {\n startRetryDelay(attempt: number) {\n const started = performance.now();\n const remainingDeadlineMs = Math.max(0, Math.round(deadlineMs - (started - reviewStarted)));\n return (failureCode: string) => {\n writeRepositoryDiagnostic({\n event: \"model.retry-delay\",\n requestId,\n jobId,\n stage: \"broker_retry_delay\",\n modelStage: stage,\n attempt,\n deadlineMs,\n remainingDeadlineMs,\n elapsedMs: Math.round(performance.now() - started),\n outcome: \"failed\",\n provider,\n model,\n identitySource: \"runner_environment\",\n failureCode: failureCodes.has(failureCode) ? failureCode : \"model_review_failed\",\n });\n };\n },\n start(attempt: number) {\n const started = performance.now();\n const record = {\n event: \"model.attempt\",\n requestId,\n jobId,\n stage,\n attempt,\n deadlineMs,\n remainingDeadlineMs: Math.max(0, Math.round(deadlineMs - (started - reviewStarted))),\n };\n writeRepositoryDiagnostic({ ...record, outcome: \"started\", elapsedMs: 0, provider, model });\n return (\n outcome: \"succeeded\" | \"failed\",\n actualProvider?: string,\n actualModel?: string,\n failureCode?: string,\n ) => {\n writeRepositoryDiagnostic({\n ...record,\n outcome,\n elapsedMs: Math.round(performance.now() - started),\n provider: actualProvider === undefined ? provider : identity(actualProvider),\n model: actualModel === undefined ? model : identity(actualModel),\n identitySource: actualProvider === undefined ? \"runner_environment\" : \"broker_response\",\n ...(failureCode === undefined\n ? {}\n : { failureCode: failureCodes.has(failureCode) ? failureCode : \"model_review_failed\" }),\n });\n };\n },\n };\n}\n"]}
|
package/dist/model.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface ModelReviewValidation<T = unknown> {
|
|
|
13
13
|
maximumAttempts?: number;
|
|
14
14
|
}
|
|
15
15
|
export interface ModelReviewRequest<T = unknown> {
|
|
16
|
+
/** Local timing classification only; never sent to the broker or model. */
|
|
17
|
+
diagnosticStage?: "model_review" | "repository_planning";
|
|
16
18
|
prompt: string;
|
|
17
19
|
input: unknown;
|
|
18
20
|
schema: Record<string, unknown>;
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAClD,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AACvE,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAwCjE,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,GAAG,OAAO;IAChD,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,wFAAwF;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,2EAA2E;IAC3E,eAAe,CAAC,EAAE,cAAc,GAAG,qBAAqB,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,UAAU,CAAC,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE;QACN,UAAU,EAAE,0BAA0B,CAAC;KACxC,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC5C,MAAM,EAAE,CAAC,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC/C,SAAS,CAAC,EAAE,wBAAwB,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,sEAAsE;AACtE,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAChD,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AA8B5E,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,SAA8D;CAIlF;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;gBAGvD,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KAC5C;CAQT;AAkBD,wBAAgB,0BAA0B,CACxC,WAAW,GAAE,gBAA8B,GAC1C,WAAW,CAOb;AAED,wBAAgB,gBAAgB,IAAI,WAAW,CAM9C;AAED,qBAAa,iBAAkB,YAAW,WAAW;;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAMd,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,wBAA6B;IA8B7E,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAuKzF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAC9B,QAAQ,GAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,iBAAiB,CAAC,CAAC,CAAsB,GACpF,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAuD/B"}
|
package/dist/model.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
2
|
+
import { Agent } from "undici";
|
|
3
|
+
import { modelAttemptDiagnostics } from "./model-diagnostics.js";
|
|
2
4
|
export const ADVERSARY_MODEL_PROTOCOL_VERSION = 1;
|
|
3
5
|
export const ADVERSARY_MODEL_ENDPOINT_ENV = "ADVERSARY_MODEL_ENDPOINT";
|
|
4
6
|
export const ADVERSARY_MODEL_TOKEN_ENV = "ADVERSARY_MODEL_TOKEN";
|
|
@@ -16,6 +18,23 @@ const MAX_BROKER_RETRY_DELAY_MS = 5_000;
|
|
|
16
18
|
const DEFAULT_VALIDATION_MAXIMUM_ATTEMPTS = 3;
|
|
17
19
|
const MAX_VALIDATION_MAXIMUM_ATTEMPTS = 5;
|
|
18
20
|
const MAX_VALIDATION_FEEDBACK_BYTES = 8 << 10;
|
|
21
|
+
// Fetch supplies its own five-minute header timeout, overriding Agent defaults.
|
|
22
|
+
// Override dispatch options for this review only; its shared AbortSignal remains
|
|
23
|
+
// the authoritative deadline across connection, headers, body, and retries.
|
|
24
|
+
class ModelBrokerDispatcher extends Agent {
|
|
25
|
+
deadlineMs;
|
|
26
|
+
constructor(deadlineMs) {
|
|
27
|
+
super({ connectTimeout: deadlineMs });
|
|
28
|
+
this.deadlineMs = deadlineMs;
|
|
29
|
+
}
|
|
30
|
+
dispatch(options, handler) {
|
|
31
|
+
return super.dispatch({
|
|
32
|
+
...options,
|
|
33
|
+
headersTimeout: this.deadlineMs,
|
|
34
|
+
bodyTimeout: this.deadlineMs,
|
|
35
|
+
}, handler);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
19
38
|
export class ModelUnavailableError extends Error {
|
|
20
39
|
constructor(message = "Model review is unavailable for this adversary execution.") {
|
|
21
40
|
super(message);
|
|
@@ -34,6 +53,15 @@ export class ModelReviewError extends Error {
|
|
|
34
53
|
this.retryable = options.retryable ?? false;
|
|
35
54
|
}
|
|
36
55
|
}
|
|
56
|
+
// The message carries the code because subprocess runners may only retain stderr.
|
|
57
|
+
// Never include an upstream error body, prompt, or validator feedback here.
|
|
58
|
+
function exhaustedModelRecovery(attempts, reason) {
|
|
59
|
+
return new ModelReviewError(`model_request_recovery_exhausted: Model request recovery exhausted after ${attempts} attempt(s) (${reason}).`, {
|
|
60
|
+
code: "model_request_recovery_exhausted",
|
|
61
|
+
retryable: false,
|
|
62
|
+
diagnostics: Object.freeze({ attempts, reason }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
37
65
|
export function createModelFromEnvironment(environment = process.env) {
|
|
38
66
|
const endpoint = environment[ADVERSARY_MODEL_ENDPOINT_ENV]?.trim();
|
|
39
67
|
const token = environment[ADVERSARY_MODEL_TOKEN_ENV]?.trim();
|
|
@@ -84,35 +112,71 @@ export class BrokerReviewModel {
|
|
|
84
112
|
throw new ModelReviewError("Repository model tools require ctx.model so the SDK can enforce the repository boundary.", { code: "invalid_model_request" });
|
|
85
113
|
}
|
|
86
114
|
const normalized = normalizeRequest(request);
|
|
115
|
+
const diagnostics = modelAttemptDiagnostics(normalized.budget.timeoutMs, request.diagnosticStage === "repository_planning" ? "repository_planning" : "model_review");
|
|
87
116
|
const controller = new AbortController();
|
|
88
117
|
const timeout = setTimeout(() => controller.abort(), normalized.budget.timeoutMs);
|
|
118
|
+
const dispatcher = new ModelBrokerDispatcher(normalized.budget.timeoutMs);
|
|
89
119
|
try {
|
|
90
120
|
for (let attempt = 1; attempt <= this.#maximumAttempts; attempt += 1) {
|
|
91
|
-
|
|
92
|
-
|
|
121
|
+
const outcome = await this.#reviewAttempt(normalized, controller.signal, dispatcher, diagnostics, attempt);
|
|
122
|
+
if (outcome.ok)
|
|
123
|
+
return outcome.result;
|
|
124
|
+
const error = outcome.error;
|
|
125
|
+
if (!(error instanceof ModelReviewError) || !error.retryable)
|
|
126
|
+
throw error;
|
|
127
|
+
if (controller.signal.aborted) {
|
|
128
|
+
throw exhaustedModelRecovery(attempt, "deadline");
|
|
93
129
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
!error.retryable ||
|
|
97
|
-
controller.signal.aborted ||
|
|
98
|
-
attempt === this.#maximumAttempts) {
|
|
99
|
-
throw error;
|
|
100
|
-
}
|
|
101
|
-
const exponential = Math.min(MAX_BROKER_RETRY_DELAY_MS, this.#initialRetryDelayMs * 2 ** (attempt - 1));
|
|
102
|
-
const jittered = Math.round(exponential * (0.75 + 0.5 * this.#random()));
|
|
103
|
-
await waitForRetry(jittered, controller.signal, normalized.budget.timeoutMs);
|
|
130
|
+
if (attempt === this.#maximumAttempts) {
|
|
131
|
+
throw exhaustedModelRecovery(attempt, "attempt_limit");
|
|
104
132
|
}
|
|
133
|
+
await this.#waitForRetry(attempt, controller.signal, normalized.budget.timeoutMs, diagnostics);
|
|
105
134
|
}
|
|
106
|
-
throw
|
|
107
|
-
code: "broker_unavailable",
|
|
108
|
-
retryable: true,
|
|
109
|
-
});
|
|
135
|
+
throw exhaustedModelRecovery(this.#maximumAttempts, "attempt_limit");
|
|
110
136
|
}
|
|
111
137
|
finally {
|
|
112
138
|
clearTimeout(timeout);
|
|
139
|
+
// Cleanup must not replace the typed request error or a successful response.
|
|
140
|
+
try {
|
|
141
|
+
await dispatcher.destroy();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// The dispatcher is no longer used after this request.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// One attempt owns its timing and error outcome; retry decisions belong to review().
|
|
149
|
+
async #reviewAttempt(normalized, signal, dispatcher, diagnostics, attempt) {
|
|
150
|
+
const finish = diagnostics.start(attempt);
|
|
151
|
+
try {
|
|
152
|
+
const result = await this.#reviewOnce(normalized, signal, dispatcher);
|
|
153
|
+
finish("succeeded", result.provider, result.model);
|
|
154
|
+
return { ok: true, result };
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
finish("failed", undefined, undefined, error instanceof ModelReviewError ? error.code : "broker_unavailable");
|
|
158
|
+
return { ok: false, error };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Keep backoff, timeout diagnostics, and error translation together.
|
|
162
|
+
async #waitForRetry(attempt, signal, timeoutMs, diagnostics) {
|
|
163
|
+
const exponential = Math.min(MAX_BROKER_RETRY_DELAY_MS, this.#initialRetryDelayMs * 2 ** (attempt - 1));
|
|
164
|
+
const jittered = Math.round(exponential * (0.75 + 0.5 * this.#random()));
|
|
165
|
+
const retryDelayFailed = diagnostics.startRetryDelay(attempt);
|
|
166
|
+
try {
|
|
167
|
+
await waitForRetry(jittered, signal, timeoutMs);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
retryDelayFailed(error instanceof ModelReviewError
|
|
171
|
+
? (error.code ?? "model_review_failed")
|
|
172
|
+
: "model_review_failed");
|
|
173
|
+
if (error instanceof ModelReviewError && error.retryable) {
|
|
174
|
+
throw exhaustedModelRecovery(attempt, "deadline");
|
|
175
|
+
}
|
|
176
|
+
throw error;
|
|
113
177
|
}
|
|
114
178
|
}
|
|
115
|
-
async #reviewOnce(normalized, signal) {
|
|
179
|
+
async #reviewOnce(normalized, signal, dispatcher) {
|
|
116
180
|
let response;
|
|
117
181
|
try {
|
|
118
182
|
response = await fetch(this.endpoint, {
|
|
@@ -131,23 +195,18 @@ export class BrokerReviewModel {
|
|
|
131
195
|
budget: normalized.budget,
|
|
132
196
|
}),
|
|
133
197
|
signal,
|
|
198
|
+
dispatcher,
|
|
134
199
|
});
|
|
135
200
|
}
|
|
136
201
|
catch (error) {
|
|
137
|
-
|
|
138
|
-
throw modelTimeoutError(normalized.budget.timeoutMs);
|
|
139
|
-
}
|
|
140
|
-
throw new ModelReviewError(`Model broker request failed: ${error instanceof Error ? error.message : String(error)}`, { code: "broker_unavailable", retryable: true });
|
|
202
|
+
throw brokerTransportError(error, signal, normalized.budget.timeoutMs);
|
|
141
203
|
}
|
|
142
204
|
let body;
|
|
143
205
|
try {
|
|
144
206
|
body = await readBoundedResponse(response);
|
|
145
207
|
}
|
|
146
208
|
catch (error) {
|
|
147
|
-
|
|
148
|
-
throw modelTimeoutError(normalized.budget.timeoutMs);
|
|
149
|
-
}
|
|
150
|
-
throw error;
|
|
209
|
+
throw brokerTransportError(error, signal, normalized.budget.timeoutMs);
|
|
151
210
|
}
|
|
152
211
|
let decoded;
|
|
153
212
|
try {
|
|
@@ -198,7 +257,7 @@ export async function reviewWithValidation(model, request, decorate = (result) =
|
|
|
198
257
|
const elapsed = Date.now() - startedAt;
|
|
199
258
|
const remainingTimeoutMs = timeoutMs - elapsed;
|
|
200
259
|
if (remainingTimeoutMs <= 0)
|
|
201
|
-
throw
|
|
260
|
+
throw exhaustedModelRecovery(attempt - 1, "deadline");
|
|
202
261
|
const result = decorate(await model.review({
|
|
203
262
|
...baseRequest,
|
|
204
263
|
prompt: feedback === undefined
|
|
@@ -333,6 +392,13 @@ function requireIntegerRange(value, name, minimum, maximum) {
|
|
|
333
392
|
});
|
|
334
393
|
}
|
|
335
394
|
}
|
|
395
|
+
function brokerTransportError(error, signal, timeoutMs) {
|
|
396
|
+
if (signal.aborted)
|
|
397
|
+
return modelTimeoutError(timeoutMs);
|
|
398
|
+
if (error instanceof ModelReviewError)
|
|
399
|
+
return error;
|
|
400
|
+
return new ModelReviewError(`Model broker request failed: ${error instanceof Error ? error.message : String(error)}`, { code: "broker_unavailable", retryable: true });
|
|
401
|
+
}
|
|
336
402
|
async function readBoundedResponse(response) {
|
|
337
403
|
const declared = response.headers.get("content-length");
|
|
338
404
|
if (declared !== null && Number(declared) > MAX_RESPONSE_BYTES) {
|
package/dist/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv2020 } from \"ajv/dist/2020.js\";\nimport type {\n ModelRepositoryCitation,\n ModelRepositoryRetrieval,\n ModelRepositoryToolOptions,\n} from \"./repository-model.js\";\n\nexport const ADVERSARY_MODEL_PROTOCOL_VERSION = 1;\nexport const ADVERSARY_MODEL_ENDPOINT_ENV = \"ADVERSARY_MODEL_ENDPOINT\";\nexport const ADVERSARY_MODEL_TOKEN_ENV = \"ADVERSARY_MODEL_TOKEN\";\n\nconst DEFAULT_MODEL_TIMEOUT_MS = 600_000;\nconst MAX_MODEL_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAXIMUM_OUTPUT_TOKENS = 8_192;\nconst MAX_MAXIMUM_OUTPUT_TOKENS = 65_536;\nconst MAX_PROMPT_BYTES = 256 << 10;\nconst MAX_INPUT_BYTES = 4 << 20;\nconst MAX_SCHEMA_BYTES = 512 << 10;\nconst MAX_RESPONSE_BYTES = 4 << 20;\nconst DEFAULT_BROKER_MAXIMUM_ATTEMPTS = 3;\nconst DEFAULT_BROKER_RETRY_DELAY_MS = 250;\nconst MAX_BROKER_RETRY_DELAY_MS = 5_000;\nconst DEFAULT_VALIDATION_MAXIMUM_ATTEMPTS = 3;\nconst MAX_VALIDATION_MAXIMUM_ATTEMPTS = 5;\nconst MAX_VALIDATION_FEEDBACK_BYTES = 8 << 10;\n\nexport interface ModelReviewBudget {\n maximumOutputTokens?: number;\n timeoutMs?: number;\n}\n\nexport interface ModelReviewValidation<T = unknown> {\n /** Validate a completed model result. Throw to retry generation with the error as feedback. */\n validate(result: ModelReviewResult<T>): void | Promise<void>;\n /** Total generation attempts, including the first. Defaults to 3 and is capped at 5. */\n maximumAttempts?: number;\n}\n\nexport interface ModelReviewRequest<T = unknown> {\n prompt: string;\n input: unknown;\n schema: Record<string, unknown>;\n budget?: ModelReviewBudget;\n validation?: ModelReviewValidation<T>;\n tools?: {\n repository: ModelRepositoryToolOptions;\n };\n}\n\nexport interface ModelReviewUsage {\n inputTokens?: number;\n outputTokens?: number;\n}\n\nexport interface ModelReviewResult<T = unknown> {\n output: T;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n citations?: readonly ModelRepositoryCitation[];\n retrieval?: ModelRepositoryRetrieval;\n}\n\nexport interface ReviewModel {\n review<T = unknown>(request: ModelReviewRequest<T>): Promise<ModelReviewResult<T>>;\n}\n\nexport interface BrokerReviewModelOptions {\n maximumAttempts?: number;\n initialRetryDelayMs?: number;\n random?: () => number;\n}\n\n/**\n * Request a short noun-phrase concern suitable after \"I would address …\".\n * Implemented by the SDK via {@link ReviewModel.review} (CLI broker pass-through).\n */\nexport interface ModelConcernRequest {\n /** Free-form title, clause, or draft concern to rewrite. */\n text: string;\n budget?: ModelReviewBudget;\n /**\n * Extra attempts when the model returns a phrase that fails noun-phrase validation.\n * Defaults to 1 retry (2 total attempts).\n */\n maxAttempts?: number;\n}\n\nexport interface ModelConcernResult {\n /** Validated noun phrase (see requireOpinionConcern). */\n concern: string;\n /** False when `text` was already a valid noun phrase (no broker call). */\n rewritten: boolean;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n}\n\n/** Rule-context model: broker review plus opinion-concern rewrite. */\nexport type ContextualReviewModel = ReviewModel & {\n concern(request: ModelConcernRequest): Promise<ModelConcernResult>;\n};\n\nexport type ModelEnvironment = Readonly<Record<string, string | undefined>>;\n\ninterface ModelBrokerRequest extends Omit<ModelReviewRequest, \"validation\" | \"tools\"> {\n protocolVersion: typeof ADVERSARY_MODEL_PROTOCOL_VERSION;\n}\n\ninterface ModelBrokerResponse {\n protocolVersion: typeof ADVERSARY_MODEL_PROTOCOL_VERSION;\n output: unknown;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n}\n\ninterface ModelBrokerErrorResponse {\n error?: {\n code?: string;\n message?: string;\n retryable?: boolean;\n };\n}\n\ntype NormalizedModelReviewRequest = Omit<ModelReviewRequest, \"budget\" | \"validation\" | \"tools\"> & {\n budget: Required<ModelReviewBudget>;\n};\n\nexport class ModelUnavailableError extends Error {\n constructor(message = \"Model review is unavailable for this adversary execution.\") {\n super(message);\n this.name = \"ModelUnavailableError\";\n }\n}\n\nexport class ModelReviewError extends Error {\n readonly code?: string;\n readonly retryable: boolean;\n readonly diagnostics?: Readonly<Record<string, unknown>>;\n\n constructor(\n message: string,\n options: {\n code?: string;\n retryable?: boolean;\n diagnostics?: Readonly<Record<string, unknown>>;\n } = {},\n ) {\n super(message);\n this.name = \"ModelReviewError\";\n this.code = options.code;\n this.diagnostics = options.diagnostics;\n this.retryable = options.retryable ?? false;\n }\n}\n\nexport function createModelFromEnvironment(\n environment: ModelEnvironment = process.env,\n): ReviewModel {\n const endpoint = environment[ADVERSARY_MODEL_ENDPOINT_ENV]?.trim();\n const token = environment[ADVERSARY_MODEL_TOKEN_ENV]?.trim();\n if (endpoint === undefined || endpoint === \"\" || token === undefined || token === \"\") {\n return unavailableModel();\n }\n return new BrokerReviewModel(endpoint, token);\n}\n\nexport function unavailableModel(): ReviewModel {\n return Object.freeze({\n async review(): Promise<never> {\n throw new ModelUnavailableError();\n },\n });\n}\n\nexport class BrokerReviewModel implements ReviewModel {\n readonly endpoint: string;\n readonly #token: string;\n readonly #maximumAttempts: number;\n readonly #initialRetryDelayMs: number;\n readonly #random: () => number;\n\n constructor(endpoint: string, token: string, options: BrokerReviewModelOptions = {}) {\n const parsed = new URL(endpoint);\n if (\n parsed.protocol !== \"http:\" ||\n (parsed.hostname !== \"127.0.0.1\" &&\n parsed.hostname !== \"::1\" &&\n parsed.hostname !== \"[::1]\" &&\n parsed.hostname !== \"localhost\")\n ) {\n throw new ModelReviewError(\n \"The model broker endpoint must use HTTP on the local loopback interface.\",\n { code: \"invalid_broker_endpoint\" },\n );\n }\n if (token.trim() === \"\") {\n throw new ModelReviewError(\"The model broker token must not be empty.\", {\n code: \"invalid_broker_token\",\n });\n }\n this.endpoint = parsed.toString();\n this.#token = token;\n const maximumAttempts = options.maximumAttempts ?? DEFAULT_BROKER_MAXIMUM_ATTEMPTS;\n const initialRetryDelayMs = options.initialRetryDelayMs ?? DEFAULT_BROKER_RETRY_DELAY_MS;\n requireIntegerRange(maximumAttempts, \"maximumAttempts\", 1, 5);\n requireIntegerRange(initialRetryDelayMs, \"initialRetryDelayMs\", 0, MAX_BROKER_RETRY_DELAY_MS);\n this.#maximumAttempts = maximumAttempts;\n this.#initialRetryDelayMs = initialRetryDelayMs;\n this.#random = options.random ?? Math.random;\n }\n\n async review<T = unknown>(request: ModelReviewRequest<T>): Promise<ModelReviewResult<T>> {\n if (request.tools?.repository !== undefined) {\n throw new ModelReviewError(\n \"Repository model tools require ctx.model so the SDK can enforce the repository boundary.\",\n { code: \"invalid_model_request\" },\n );\n }\n const normalized = normalizeRequest(request);\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), normalized.budget.timeoutMs);\n try {\n for (let attempt = 1; attempt <= this.#maximumAttempts; attempt += 1) {\n try {\n return await this.#reviewOnce<T>(normalized, controller.signal);\n } catch (error) {\n if (\n !(error instanceof ModelReviewError) ||\n !error.retryable ||\n controller.signal.aborted ||\n attempt === this.#maximumAttempts\n ) {\n throw error;\n }\n const exponential = Math.min(\n MAX_BROKER_RETRY_DELAY_MS,\n this.#initialRetryDelayMs * 2 ** (attempt - 1),\n );\n const jittered = Math.round(exponential * (0.75 + 0.5 * this.#random()));\n await waitForRetry(jittered, controller.signal, normalized.budget.timeoutMs);\n }\n }\n throw new ModelReviewError(\"Model broker retry loop exhausted unexpectedly.\", {\n code: \"broker_unavailable\",\n retryable: true,\n });\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async #reviewOnce<T>(\n normalized: NormalizedModelReviewRequest,\n signal: AbortSignal,\n ): Promise<ModelReviewResult<T>> {\n let response: Response;\n try {\n response = await fetch(this.endpoint, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n authorization: `Bearer ${this.#token}`,\n \"content-type\": \"application/json\",\n \"x-adversary-model-protocol\": String(ADVERSARY_MODEL_PROTOCOL_VERSION),\n },\n body: JSON.stringify({\n protocolVersion: ADVERSARY_MODEL_PROTOCOL_VERSION,\n prompt: normalized.prompt,\n input: normalized.input,\n schema: normalized.schema,\n budget: normalized.budget,\n } satisfies ModelBrokerRequest),\n signal,\n });\n } catch (error) {\n if (signal.aborted) {\n throw modelTimeoutError(normalized.budget.timeoutMs);\n }\n throw new ModelReviewError(\n `Model broker request failed: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"broker_unavailable\", retryable: true },\n );\n }\n\n let body: string;\n try {\n body = await readBoundedResponse(response);\n } catch (error) {\n if (signal.aborted) {\n throw modelTimeoutError(normalized.budget.timeoutMs);\n }\n throw error;\n }\n let decoded: unknown;\n try {\n decoded = JSON.parse(body);\n } catch {\n throw new ModelReviewError(\"Model broker returned malformed JSON.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (!response.ok) {\n const failure = decoded as ModelBrokerErrorResponse;\n throw new ModelReviewError(\n failure.error?.message ?? `Model broker returned HTTP ${response.status}.`,\n {\n code: failure.error?.code ?? \"model_review_failed\",\n retryable: failure.error?.retryable ?? response.status >= 500,\n },\n );\n }\n\n const envelope = requireBrokerResponse(decoded);\n validateModelOutput(normalized.schema, envelope.output);\n return {\n output: envelope.output as T,\n provider: envelope.provider,\n model: envelope.model,\n ...(envelope.usage === undefined ? {} : { usage: envelope.usage }),\n };\n }\n}\n\n/**\n * Run adversary-owned semantic validation with SDK-owned bounded regeneration.\n *\n * Each retry receives the validator failure as trusted SDK feedback while retaining the\n * original input. The original timeout is shared by all validation attempts, and usage is\n * aggregated across them. Repository callers may decorate the raw result with citations before\n * validation without repeating repository retrieval.\n */\nexport async function reviewWithValidation<T>(\n model: ReviewModel,\n request: ModelReviewRequest<T>,\n decorate: (result: ModelReviewResult<T>) => ModelReviewResult<T> = (result) => result,\n): Promise<ModelReviewResult<T>> {\n const validation = request.validation;\n const { validation: _validation, tools: _tools, ...baseRequest } = request;\n if (validation === undefined) return decorate(await model.review<T>(baseRequest));\n\n const maximumAttempts = validation.maximumAttempts ?? DEFAULT_VALIDATION_MAXIMUM_ATTEMPTS;\n requireIntegerRange(\n maximumAttempts,\n \"validation.maximumAttempts\",\n 1,\n MAX_VALIDATION_MAXIMUM_ATTEMPTS,\n );\n const timeoutMs = request.budget?.timeoutMs ?? DEFAULT_MODEL_TIMEOUT_MS;\n const startedAt = Date.now();\n let usage: ModelReviewUsage = {};\n let feedback: string | undefined;\n\n for (let attempt = 1; attempt <= maximumAttempts; attempt += 1) {\n const elapsed = Date.now() - startedAt;\n const remainingTimeoutMs = timeoutMs - elapsed;\n if (remainingTimeoutMs <= 0) throw modelTimeoutError(timeoutMs);\n const result = decorate(\n await model.review<T>({\n ...baseRequest,\n prompt:\n feedback === undefined\n ? baseRequest.prompt\n : `${baseRequest.prompt}\\n\\nSDK VALIDATION FEEDBACK:\\nThe previous response failed adversary-defined validation. Correct the response using this trusted validation result and return the complete response again.\\n${JSON.stringify({ attempt, error: feedback })}`,\n budget: {\n ...baseRequest.budget,\n timeoutMs: remainingTimeoutMs,\n },\n }),\n );\n usage = addModelUsage(usage, result.usage);\n try {\n await validation.validate(result);\n return {\n ...result,\n ...(usage.inputTokens === undefined && usage.outputTokens === undefined ? {} : { usage }),\n };\n } catch (error) {\n feedback = boundedValidationFeedback(error);\n if (attempt === maximumAttempts) {\n throw new ModelReviewError(\n `Model output failed adversary validation after ${maximumAttempts} attempts: ${feedback}`,\n { code: \"model_validation_failed\", retryable: false },\n );\n }\n }\n }\n throw new ModelReviewError(\"Model validation retry loop exhausted unexpectedly.\", {\n code: \"model_validation_failed\",\n retryable: false,\n });\n}\n\nfunction boundedValidationFeedback(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const encoded = Buffer.from(message, \"utf8\");\n return encoded.byteLength <= MAX_VALIDATION_FEEDBACK_BYTES\n ? message\n : `${encoded.subarray(0, MAX_VALIDATION_FEEDBACK_BYTES).toString(\"utf8\")}…`;\n}\n\nfunction addModelUsage(\n total: ModelReviewUsage,\n next: ModelReviewUsage | undefined,\n): ModelReviewUsage {\n if (next === undefined) return total;\n return {\n ...(total.inputTokens === undefined && next.inputTokens === undefined\n ? {}\n : { inputTokens: (total.inputTokens ?? 0) + (next.inputTokens ?? 0) }),\n ...(total.outputTokens === undefined && next.outputTokens === undefined\n ? {}\n : { outputTokens: (total.outputTokens ?? 0) + (next.outputTokens ?? 0) }),\n };\n}\n\nasync function waitForRetry(\n delayMs: number,\n signal: AbortSignal,\n timeoutMs: number,\n): Promise<void> {\n if (signal.aborted) {\n throw modelTimeoutError(timeoutMs);\n }\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(modelTimeoutError(timeoutMs));\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, delayMs);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction modelTimeoutError(timeoutMs: number): ModelReviewError {\n return new ModelReviewError(`Model review exceeded its ${timeoutMs}ms timeout.`, {\n code: \"model_timeout\",\n retryable: true,\n });\n}\n\nfunction normalizeRequest(request: ModelReviewRequest): NormalizedModelReviewRequest {\n if (typeof request !== \"object\" || request === null) {\n throw new ModelReviewError(\"Model review request must be an object.\", {\n code: \"invalid_model_request\",\n });\n }\n if (typeof request.prompt !== \"string\" || request.prompt.trim() === \"\") {\n throw new ModelReviewError(\"Model review prompt must be a non-empty string.\", {\n code: \"invalid_model_request\",\n });\n }\n const promptBytes = Buffer.byteLength(request.prompt, \"utf8\");\n if (promptBytes > MAX_PROMPT_BYTES) {\n throw new ModelReviewError(`Model review prompt exceeds ${MAX_PROMPT_BYTES} bytes.`, {\n code: \"model_request_too_large\",\n });\n }\n requireJsonSize(request.input, \"input\", MAX_INPUT_BYTES);\n if (\n typeof request.schema !== \"object\" ||\n request.schema === null ||\n Array.isArray(request.schema)\n ) {\n throw new ModelReviewError(\"Model review schema must be a JSON Schema object.\", {\n code: \"invalid_model_schema\",\n });\n }\n requireJsonSize(request.schema, \"schema\", MAX_SCHEMA_BYTES);\n\n const maximumOutputTokens = request.budget?.maximumOutputTokens ?? DEFAULT_MAXIMUM_OUTPUT_TOKENS;\n const timeoutMs = request.budget?.timeoutMs ?? DEFAULT_MODEL_TIMEOUT_MS;\n requireIntegerRange(\n maximumOutputTokens,\n \"budget.maximumOutputTokens\",\n 1,\n MAX_MAXIMUM_OUTPUT_TOKENS,\n );\n requireIntegerRange(timeoutMs, \"budget.timeoutMs\", 1, MAX_MODEL_TIMEOUT_MS);\n return {\n prompt: request.prompt,\n input: request.input,\n schema: request.schema,\n budget: { maximumOutputTokens, timeoutMs },\n };\n}\n\nfunction requireJsonSize(value: unknown, name: string, maximum: number): void {\n let encoded: string | undefined;\n try {\n encoded = JSON.stringify(value);\n } catch (error) {\n throw new ModelReviewError(\n `Model review ${name} must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"invalid_model_request\" },\n );\n }\n if (encoded === undefined) {\n throw new ModelReviewError(`Model review ${name} must be JSON-serializable.`, {\n code: \"invalid_model_request\",\n });\n }\n if (Buffer.byteLength(encoded, \"utf8\") > maximum) {\n throw new ModelReviewError(`Model review ${name} exceeds ${maximum} bytes.`, {\n code: \"model_request_too_large\",\n });\n }\n}\n\nfunction requireIntegerRange(value: number, name: string, minimum: number, maximum: number): void {\n if (!Number.isInteger(value) || value < minimum || value > maximum) {\n throw new ModelReviewError(`${name} must be an integer from ${minimum} through ${maximum}.`, {\n code: \"invalid_model_budget\",\n });\n }\n}\n\nasync function readBoundedResponse(response: Response): Promise<string> {\n const declared = response.headers.get(\"content-length\");\n if (declared !== null && Number(declared) > MAX_RESPONSE_BYTES) {\n throw new ModelReviewError(`Model broker response exceeds ${MAX_RESPONSE_BYTES} bytes.`, {\n code: \"model_response_too_large\",\n });\n }\n if (response.body === null) {\n return \"\";\n }\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n size += value.byteLength;\n if (size > MAX_RESPONSE_BYTES) {\n await reader.cancel();\n throw new ModelReviewError(`Model broker response exceeds ${MAX_RESPONSE_BYTES} bytes.`, {\n code: \"model_response_too_large\",\n });\n }\n chunks.push(value);\n }\n const joined = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n joined.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(joined);\n}\n\nfunction requireBrokerResponse(value: unknown): ModelBrokerResponse {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ModelReviewError(\"Model broker response must be an object.\", {\n code: \"invalid_broker_response\",\n });\n }\n const response = value as Partial<ModelBrokerResponse>;\n if (response.protocolVersion !== ADVERSARY_MODEL_PROTOCOL_VERSION) {\n throw new ModelReviewError(\n `Model broker protocol version must be ${ADVERSARY_MODEL_PROTOCOL_VERSION}.`,\n { code: \"unsupported_model_protocol\" },\n );\n }\n if (typeof response.provider !== \"string\" || response.provider.trim() === \"\") {\n throw new ModelReviewError(\"Model broker response provider must be a non-empty string.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (typeof response.model !== \"string\" || response.model.trim() === \"\") {\n throw new ModelReviewError(\"Model broker response model must be a non-empty string.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (!Object.hasOwn(response, \"output\")) {\n throw new ModelReviewError(\"Model broker response is missing output.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (response.usage !== undefined) {\n validateUsage(response.usage);\n }\n return response as ModelBrokerResponse;\n}\n\nfunction validateUsage(value: unknown): asserts value is ModelReviewUsage {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ModelReviewError(\"Model broker response usage must be an object.\", {\n code: \"invalid_broker_response\",\n });\n }\n for (const field of [\"inputTokens\", \"outputTokens\"] as const) {\n const count = (value as ModelReviewUsage)[field];\n if (count !== undefined && (!Number.isInteger(count) || count < 0)) {\n throw new ModelReviewError(\n `Model broker response usage.${field} must be a non-negative integer.`,\n {\n code: \"invalid_broker_response\",\n },\n );\n }\n }\n}\n\nfunction validateModelOutput(schema: Record<string, unknown>, output: unknown): void {\n const ajv = new Ajv2020({ allErrors: true, strict: true });\n let validate: ReturnType<Ajv2020[\"compile\"]>;\n try {\n validate = ajv.compile(schema);\n } catch (error) {\n throw new ModelReviewError(\n `Model review schema is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"invalid_model_schema\" },\n );\n }\n if (!validate(output)) {\n const detail = ajv.errorsText(validate.errors, { separator: \"; \" });\n throw new ModelReviewError(`Model output does not match the requested schema: ${detail}`, {\n code: \"invalid_model_output\",\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv2020 } from \"ajv/dist/2020.js\";\nimport { Agent, type Dispatcher } from \"undici\";\nimport { modelAttemptDiagnostics } from \"./model-diagnostics.js\";\nimport type {\n ModelRepositoryCitation,\n ModelRepositoryRetrieval,\n ModelRepositoryToolOptions,\n} from \"./repository-model.js\";\n\nexport const ADVERSARY_MODEL_PROTOCOL_VERSION = 1;\nexport const ADVERSARY_MODEL_ENDPOINT_ENV = \"ADVERSARY_MODEL_ENDPOINT\";\nexport const ADVERSARY_MODEL_TOKEN_ENV = \"ADVERSARY_MODEL_TOKEN\";\n\nconst DEFAULT_MODEL_TIMEOUT_MS = 600_000;\nconst MAX_MODEL_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAXIMUM_OUTPUT_TOKENS = 8_192;\nconst MAX_MAXIMUM_OUTPUT_TOKENS = 65_536;\nconst MAX_PROMPT_BYTES = 256 << 10;\nconst MAX_INPUT_BYTES = 4 << 20;\nconst MAX_SCHEMA_BYTES = 512 << 10;\nconst MAX_RESPONSE_BYTES = 4 << 20;\nconst DEFAULT_BROKER_MAXIMUM_ATTEMPTS = 3;\nconst DEFAULT_BROKER_RETRY_DELAY_MS = 250;\nconst MAX_BROKER_RETRY_DELAY_MS = 5_000;\nconst DEFAULT_VALIDATION_MAXIMUM_ATTEMPTS = 3;\nconst MAX_VALIDATION_MAXIMUM_ATTEMPTS = 5;\nconst MAX_VALIDATION_FEEDBACK_BYTES = 8 << 10;\n\n// Fetch supplies its own five-minute header timeout, overriding Agent defaults.\n// Override dispatch options for this review only; its shared AbortSignal remains\n// the authoritative deadline across connection, headers, body, and retries.\nclass ModelBrokerDispatcher extends Agent {\n constructor(private readonly deadlineMs: number) {\n super({ connectTimeout: deadlineMs });\n }\n\n override dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandlers,\n ): boolean {\n return super.dispatch(\n {\n ...options,\n headersTimeout: this.deadlineMs,\n bodyTimeout: this.deadlineMs,\n },\n handler,\n );\n }\n}\n\nexport interface ModelReviewBudget {\n maximumOutputTokens?: number;\n timeoutMs?: number;\n}\n\nexport interface ModelReviewValidation<T = unknown> {\n /** Validate a completed model result. Throw to retry generation with the error as feedback. */\n validate(result: ModelReviewResult<T>): void | Promise<void>;\n /** Total generation attempts, including the first. Defaults to 3 and is capped at 5. */\n maximumAttempts?: number;\n}\n\nexport interface ModelReviewRequest<T = unknown> {\n /** Local timing classification only; never sent to the broker or model. */\n diagnosticStage?: \"model_review\" | \"repository_planning\";\n prompt: string;\n input: unknown;\n schema: Record<string, unknown>;\n budget?: ModelReviewBudget;\n validation?: ModelReviewValidation<T>;\n tools?: {\n repository: ModelRepositoryToolOptions;\n };\n}\n\nexport interface ModelReviewUsage {\n inputTokens?: number;\n outputTokens?: number;\n}\n\nexport interface ModelReviewResult<T = unknown> {\n output: T;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n citations?: readonly ModelRepositoryCitation[];\n retrieval?: ModelRepositoryRetrieval;\n}\n\nexport interface ReviewModel {\n review<T = unknown>(request: ModelReviewRequest<T>): Promise<ModelReviewResult<T>>;\n}\n\nexport interface BrokerReviewModelOptions {\n maximumAttempts?: number;\n initialRetryDelayMs?: number;\n random?: () => number;\n}\n\n/**\n * Request a short noun-phrase concern suitable after \"I would address …\".\n * Implemented by the SDK via {@link ReviewModel.review} (CLI broker pass-through).\n */\nexport interface ModelConcernRequest {\n /** Free-form title, clause, or draft concern to rewrite. */\n text: string;\n budget?: ModelReviewBudget;\n /**\n * Extra attempts when the model returns a phrase that fails noun-phrase validation.\n * Defaults to 1 retry (2 total attempts).\n */\n maxAttempts?: number;\n}\n\nexport interface ModelConcernResult {\n /** Validated noun phrase (see requireOpinionConcern). */\n concern: string;\n /** False when `text` was already a valid noun phrase (no broker call). */\n rewritten: boolean;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n}\n\n/** Rule-context model: broker review plus opinion-concern rewrite. */\nexport type ContextualReviewModel = ReviewModel & {\n concern(request: ModelConcernRequest): Promise<ModelConcernResult>;\n};\n\nexport type ModelEnvironment = Readonly<Record<string, string | undefined>>;\n\ninterface ModelBrokerRequest\n extends Omit<ModelReviewRequest, \"validation\" | \"tools\" | \"diagnosticStage\"> {\n protocolVersion: typeof ADVERSARY_MODEL_PROTOCOL_VERSION;\n}\n\ninterface ModelBrokerResponse {\n protocolVersion: typeof ADVERSARY_MODEL_PROTOCOL_VERSION;\n output: unknown;\n provider: string;\n model: string;\n usage?: ModelReviewUsage;\n}\n\ninterface ModelBrokerErrorResponse {\n error?: {\n code?: string;\n message?: string;\n retryable?: boolean;\n };\n}\n\ntype NormalizedModelReviewRequest = Omit<\n ModelReviewRequest,\n \"budget\" | \"validation\" | \"tools\" | \"diagnosticStage\"\n> & {\n budget: Required<ModelReviewBudget>;\n};\n\nexport class ModelUnavailableError extends Error {\n constructor(message = \"Model review is unavailable for this adversary execution.\") {\n super(message);\n this.name = \"ModelUnavailableError\";\n }\n}\n\nexport class ModelReviewError extends Error {\n readonly code?: string;\n readonly retryable: boolean;\n readonly diagnostics?: Readonly<Record<string, unknown>>;\n\n constructor(\n message: string,\n options: {\n code?: string;\n retryable?: boolean;\n diagnostics?: Readonly<Record<string, unknown>>;\n } = {},\n ) {\n super(message);\n this.name = \"ModelReviewError\";\n this.code = options.code;\n this.diagnostics = options.diagnostics;\n this.retryable = options.retryable ?? false;\n }\n}\n\n// The message carries the code because subprocess runners may only retain stderr.\n// Never include an upstream error body, prompt, or validator feedback here.\nfunction exhaustedModelRecovery(\n attempts: number,\n reason: \"deadline\" | \"attempt_limit\",\n): ModelReviewError {\n return new ModelReviewError(\n `model_request_recovery_exhausted: Model request recovery exhausted after ${attempts} attempt(s) (${reason}).`,\n {\n code: \"model_request_recovery_exhausted\",\n retryable: false,\n diagnostics: Object.freeze({ attempts, reason }),\n },\n );\n}\n\nexport function createModelFromEnvironment(\n environment: ModelEnvironment = process.env,\n): ReviewModel {\n const endpoint = environment[ADVERSARY_MODEL_ENDPOINT_ENV]?.trim();\n const token = environment[ADVERSARY_MODEL_TOKEN_ENV]?.trim();\n if (endpoint === undefined || endpoint === \"\" || token === undefined || token === \"\") {\n return unavailableModel();\n }\n return new BrokerReviewModel(endpoint, token);\n}\n\nexport function unavailableModel(): ReviewModel {\n return Object.freeze({\n async review(): Promise<never> {\n throw new ModelUnavailableError();\n },\n });\n}\n\nexport class BrokerReviewModel implements ReviewModel {\n readonly endpoint: string;\n readonly #token: string;\n readonly #maximumAttempts: number;\n readonly #initialRetryDelayMs: number;\n readonly #random: () => number;\n\n constructor(endpoint: string, token: string, options: BrokerReviewModelOptions = {}) {\n const parsed = new URL(endpoint);\n if (\n parsed.protocol !== \"http:\" ||\n (parsed.hostname !== \"127.0.0.1\" &&\n parsed.hostname !== \"::1\" &&\n parsed.hostname !== \"[::1]\" &&\n parsed.hostname !== \"localhost\")\n ) {\n throw new ModelReviewError(\n \"The model broker endpoint must use HTTP on the local loopback interface.\",\n { code: \"invalid_broker_endpoint\" },\n );\n }\n if (token.trim() === \"\") {\n throw new ModelReviewError(\"The model broker token must not be empty.\", {\n code: \"invalid_broker_token\",\n });\n }\n this.endpoint = parsed.toString();\n this.#token = token;\n const maximumAttempts = options.maximumAttempts ?? DEFAULT_BROKER_MAXIMUM_ATTEMPTS;\n const initialRetryDelayMs = options.initialRetryDelayMs ?? DEFAULT_BROKER_RETRY_DELAY_MS;\n requireIntegerRange(maximumAttempts, \"maximumAttempts\", 1, 5);\n requireIntegerRange(initialRetryDelayMs, \"initialRetryDelayMs\", 0, MAX_BROKER_RETRY_DELAY_MS);\n this.#maximumAttempts = maximumAttempts;\n this.#initialRetryDelayMs = initialRetryDelayMs;\n this.#random = options.random ?? Math.random;\n }\n\n async review<T = unknown>(request: ModelReviewRequest<T>): Promise<ModelReviewResult<T>> {\n if (request.tools?.repository !== undefined) {\n throw new ModelReviewError(\n \"Repository model tools require ctx.model so the SDK can enforce the repository boundary.\",\n { code: \"invalid_model_request\" },\n );\n }\n const normalized = normalizeRequest(request);\n const diagnostics = modelAttemptDiagnostics(\n normalized.budget.timeoutMs,\n request.diagnosticStage === \"repository_planning\" ? \"repository_planning\" : \"model_review\",\n );\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), normalized.budget.timeoutMs);\n const dispatcher = new ModelBrokerDispatcher(normalized.budget.timeoutMs);\n try {\n for (let attempt = 1; attempt <= this.#maximumAttempts; attempt += 1) {\n const outcome = await this.#reviewAttempt<T>(\n normalized,\n controller.signal,\n dispatcher,\n diagnostics,\n attempt,\n );\n if (outcome.ok) return outcome.result;\n const error = outcome.error;\n if (!(error instanceof ModelReviewError) || !error.retryable) throw error;\n if (controller.signal.aborted) {\n throw exhaustedModelRecovery(attempt, \"deadline\");\n }\n if (attempt === this.#maximumAttempts) {\n throw exhaustedModelRecovery(attempt, \"attempt_limit\");\n }\n await this.#waitForRetry(\n attempt,\n controller.signal,\n normalized.budget.timeoutMs,\n diagnostics,\n );\n }\n throw exhaustedModelRecovery(this.#maximumAttempts, \"attempt_limit\");\n } finally {\n clearTimeout(timeout);\n // Cleanup must not replace the typed request error or a successful response.\n try {\n await dispatcher.destroy();\n } catch {\n // The dispatcher is no longer used after this request.\n }\n }\n }\n\n // One attempt owns its timing and error outcome; retry decisions belong to review().\n async #reviewAttempt<T>(\n normalized: NormalizedModelReviewRequest,\n signal: AbortSignal,\n dispatcher: ModelBrokerDispatcher,\n diagnostics: ReturnType<typeof modelAttemptDiagnostics>,\n attempt: number,\n ): Promise<{ ok: true; result: ModelReviewResult<T> } | { ok: false; error: unknown }> {\n const finish = diagnostics.start(attempt);\n try {\n const result = await this.#reviewOnce<T>(normalized, signal, dispatcher);\n finish(\"succeeded\", result.provider, result.model);\n return { ok: true, result };\n } catch (error) {\n finish(\n \"failed\",\n undefined,\n undefined,\n error instanceof ModelReviewError ? error.code : \"broker_unavailable\",\n );\n return { ok: false, error };\n }\n }\n\n // Keep backoff, timeout diagnostics, and error translation together.\n async #waitForRetry(\n attempt: number,\n signal: AbortSignal,\n timeoutMs: number,\n diagnostics: ReturnType<typeof modelAttemptDiagnostics>,\n ): Promise<void> {\n const exponential = Math.min(\n MAX_BROKER_RETRY_DELAY_MS,\n this.#initialRetryDelayMs * 2 ** (attempt - 1),\n );\n const jittered = Math.round(exponential * (0.75 + 0.5 * this.#random()));\n const retryDelayFailed = diagnostics.startRetryDelay(attempt);\n try {\n await waitForRetry(jittered, signal, timeoutMs);\n } catch (error) {\n retryDelayFailed(\n error instanceof ModelReviewError\n ? (error.code ?? \"model_review_failed\")\n : \"model_review_failed\",\n );\n if (error instanceof ModelReviewError && error.retryable) {\n throw exhaustedModelRecovery(attempt, \"deadline\");\n }\n throw error;\n }\n }\n\n async #reviewOnce<T>(\n normalized: NormalizedModelReviewRequest,\n signal: AbortSignal,\n dispatcher: ModelBrokerDispatcher,\n ): Promise<ModelReviewResult<T>> {\n let response: Response;\n try {\n response = await fetch(this.endpoint, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n authorization: `Bearer ${this.#token}`,\n \"content-type\": \"application/json\",\n \"x-adversary-model-protocol\": String(ADVERSARY_MODEL_PROTOCOL_VERSION),\n },\n body: JSON.stringify({\n protocolVersion: ADVERSARY_MODEL_PROTOCOL_VERSION,\n prompt: normalized.prompt,\n input: normalized.input,\n schema: normalized.schema,\n budget: normalized.budget,\n } satisfies ModelBrokerRequest),\n signal,\n dispatcher,\n } as RequestInit & { dispatcher: Dispatcher });\n } catch (error) {\n throw brokerTransportError(error, signal, normalized.budget.timeoutMs);\n }\n\n let body: string;\n try {\n body = await readBoundedResponse(response);\n } catch (error) {\n throw brokerTransportError(error, signal, normalized.budget.timeoutMs);\n }\n let decoded: unknown;\n try {\n decoded = JSON.parse(body);\n } catch {\n throw new ModelReviewError(\"Model broker returned malformed JSON.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (!response.ok) {\n const failure = decoded as ModelBrokerErrorResponse;\n throw new ModelReviewError(\n failure.error?.message ?? `Model broker returned HTTP ${response.status}.`,\n {\n code: failure.error?.code ?? \"model_review_failed\",\n retryable: failure.error?.retryable ?? response.status >= 500,\n },\n );\n }\n\n const envelope = requireBrokerResponse(decoded);\n validateModelOutput(normalized.schema, envelope.output);\n return {\n output: envelope.output as T,\n provider: envelope.provider,\n model: envelope.model,\n ...(envelope.usage === undefined ? {} : { usage: envelope.usage }),\n };\n }\n}\n\n/**\n * Run adversary-owned semantic validation with SDK-owned bounded regeneration.\n *\n * Each retry receives the validator failure as trusted SDK feedback while retaining the\n * original input. The original timeout is shared by all validation attempts, and usage is\n * aggregated across them. Repository callers may decorate the raw result with citations before\n * validation without repeating repository retrieval.\n */\nexport async function reviewWithValidation<T>(\n model: ReviewModel,\n request: ModelReviewRequest<T>,\n decorate: (result: ModelReviewResult<T>) => ModelReviewResult<T> = (result) => result,\n): Promise<ModelReviewResult<T>> {\n const validation = request.validation;\n const { validation: _validation, tools: _tools, ...baseRequest } = request;\n if (validation === undefined) return decorate(await model.review<T>(baseRequest));\n\n const maximumAttempts = validation.maximumAttempts ?? DEFAULT_VALIDATION_MAXIMUM_ATTEMPTS;\n requireIntegerRange(\n maximumAttempts,\n \"validation.maximumAttempts\",\n 1,\n MAX_VALIDATION_MAXIMUM_ATTEMPTS,\n );\n const timeoutMs = request.budget?.timeoutMs ?? DEFAULT_MODEL_TIMEOUT_MS;\n const startedAt = Date.now();\n let usage: ModelReviewUsage = {};\n let feedback: string | undefined;\n\n for (let attempt = 1; attempt <= maximumAttempts; attempt += 1) {\n const elapsed = Date.now() - startedAt;\n const remainingTimeoutMs = timeoutMs - elapsed;\n if (remainingTimeoutMs <= 0) throw exhaustedModelRecovery(attempt - 1, \"deadline\");\n const result = decorate(\n await model.review<T>({\n ...baseRequest,\n prompt:\n feedback === undefined\n ? baseRequest.prompt\n : `${baseRequest.prompt}\\n\\nSDK VALIDATION FEEDBACK:\\nThe previous response failed adversary-defined validation. Correct the response using this trusted validation result and return the complete response again.\\n${JSON.stringify({ attempt, error: feedback })}`,\n budget: {\n ...baseRequest.budget,\n timeoutMs: remainingTimeoutMs,\n },\n }),\n );\n usage = addModelUsage(usage, result.usage);\n try {\n await validation.validate(result);\n return {\n ...result,\n ...(usage.inputTokens === undefined && usage.outputTokens === undefined ? {} : { usage }),\n };\n } catch (error) {\n feedback = boundedValidationFeedback(error);\n if (attempt === maximumAttempts) {\n throw new ModelReviewError(\n `Model output failed adversary validation after ${maximumAttempts} attempts: ${feedback}`,\n { code: \"model_validation_failed\", retryable: false },\n );\n }\n }\n }\n throw new ModelReviewError(\"Model validation retry loop exhausted unexpectedly.\", {\n code: \"model_validation_failed\",\n retryable: false,\n });\n}\n\nfunction boundedValidationFeedback(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const encoded = Buffer.from(message, \"utf8\");\n return encoded.byteLength <= MAX_VALIDATION_FEEDBACK_BYTES\n ? message\n : `${encoded.subarray(0, MAX_VALIDATION_FEEDBACK_BYTES).toString(\"utf8\")}…`;\n}\n\nfunction addModelUsage(\n total: ModelReviewUsage,\n next: ModelReviewUsage | undefined,\n): ModelReviewUsage {\n if (next === undefined) return total;\n return {\n ...(total.inputTokens === undefined && next.inputTokens === undefined\n ? {}\n : { inputTokens: (total.inputTokens ?? 0) + (next.inputTokens ?? 0) }),\n ...(total.outputTokens === undefined && next.outputTokens === undefined\n ? {}\n : { outputTokens: (total.outputTokens ?? 0) + (next.outputTokens ?? 0) }),\n };\n}\n\nasync function waitForRetry(\n delayMs: number,\n signal: AbortSignal,\n timeoutMs: number,\n): Promise<void> {\n if (signal.aborted) {\n throw modelTimeoutError(timeoutMs);\n }\n await new Promise<void>((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timer);\n reject(modelTimeoutError(timeoutMs));\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve();\n }, delayMs);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\nfunction modelTimeoutError(timeoutMs: number): ModelReviewError {\n return new ModelReviewError(`Model review exceeded its ${timeoutMs}ms timeout.`, {\n code: \"model_timeout\",\n retryable: true,\n });\n}\n\nfunction normalizeRequest(request: ModelReviewRequest): NormalizedModelReviewRequest {\n if (typeof request !== \"object\" || request === null) {\n throw new ModelReviewError(\"Model review request must be an object.\", {\n code: \"invalid_model_request\",\n });\n }\n if (typeof request.prompt !== \"string\" || request.prompt.trim() === \"\") {\n throw new ModelReviewError(\"Model review prompt must be a non-empty string.\", {\n code: \"invalid_model_request\",\n });\n }\n const promptBytes = Buffer.byteLength(request.prompt, \"utf8\");\n if (promptBytes > MAX_PROMPT_BYTES) {\n throw new ModelReviewError(`Model review prompt exceeds ${MAX_PROMPT_BYTES} bytes.`, {\n code: \"model_request_too_large\",\n });\n }\n requireJsonSize(request.input, \"input\", MAX_INPUT_BYTES);\n if (\n typeof request.schema !== \"object\" ||\n request.schema === null ||\n Array.isArray(request.schema)\n ) {\n throw new ModelReviewError(\"Model review schema must be a JSON Schema object.\", {\n code: \"invalid_model_schema\",\n });\n }\n requireJsonSize(request.schema, \"schema\", MAX_SCHEMA_BYTES);\n\n const maximumOutputTokens = request.budget?.maximumOutputTokens ?? DEFAULT_MAXIMUM_OUTPUT_TOKENS;\n const timeoutMs = request.budget?.timeoutMs ?? DEFAULT_MODEL_TIMEOUT_MS;\n requireIntegerRange(\n maximumOutputTokens,\n \"budget.maximumOutputTokens\",\n 1,\n MAX_MAXIMUM_OUTPUT_TOKENS,\n );\n requireIntegerRange(timeoutMs, \"budget.timeoutMs\", 1, MAX_MODEL_TIMEOUT_MS);\n return {\n prompt: request.prompt,\n input: request.input,\n schema: request.schema,\n budget: { maximumOutputTokens, timeoutMs },\n };\n}\n\nfunction requireJsonSize(value: unknown, name: string, maximum: number): void {\n let encoded: string | undefined;\n try {\n encoded = JSON.stringify(value);\n } catch (error) {\n throw new ModelReviewError(\n `Model review ${name} must be JSON-serializable: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"invalid_model_request\" },\n );\n }\n if (encoded === undefined) {\n throw new ModelReviewError(`Model review ${name} must be JSON-serializable.`, {\n code: \"invalid_model_request\",\n });\n }\n if (Buffer.byteLength(encoded, \"utf8\") > maximum) {\n throw new ModelReviewError(`Model review ${name} exceeds ${maximum} bytes.`, {\n code: \"model_request_too_large\",\n });\n }\n}\n\nfunction requireIntegerRange(value: number, name: string, minimum: number, maximum: number): void {\n if (!Number.isInteger(value) || value < minimum || value > maximum) {\n throw new ModelReviewError(`${name} must be an integer from ${minimum} through ${maximum}.`, {\n code: \"invalid_model_budget\",\n });\n }\n}\n\nfunction brokerTransportError(\n error: unknown,\n signal: AbortSignal,\n timeoutMs: number,\n): ModelReviewError {\n if (signal.aborted) return modelTimeoutError(timeoutMs);\n if (error instanceof ModelReviewError) return error;\n return new ModelReviewError(\n `Model broker request failed: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"broker_unavailable\", retryable: true },\n );\n}\n\nasync function readBoundedResponse(response: Response): Promise<string> {\n const declared = response.headers.get(\"content-length\");\n if (declared !== null && Number(declared) > MAX_RESPONSE_BYTES) {\n throw new ModelReviewError(`Model broker response exceeds ${MAX_RESPONSE_BYTES} bytes.`, {\n code: \"model_response_too_large\",\n });\n }\n if (response.body === null) {\n return \"\";\n }\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n size += value.byteLength;\n if (size > MAX_RESPONSE_BYTES) {\n await reader.cancel();\n throw new ModelReviewError(`Model broker response exceeds ${MAX_RESPONSE_BYTES} bytes.`, {\n code: \"model_response_too_large\",\n });\n }\n chunks.push(value);\n }\n const joined = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n joined.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(joined);\n}\n\nfunction requireBrokerResponse(value: unknown): ModelBrokerResponse {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ModelReviewError(\"Model broker response must be an object.\", {\n code: \"invalid_broker_response\",\n });\n }\n const response = value as Partial<ModelBrokerResponse>;\n if (response.protocolVersion !== ADVERSARY_MODEL_PROTOCOL_VERSION) {\n throw new ModelReviewError(\n `Model broker protocol version must be ${ADVERSARY_MODEL_PROTOCOL_VERSION}.`,\n { code: \"unsupported_model_protocol\" },\n );\n }\n if (typeof response.provider !== \"string\" || response.provider.trim() === \"\") {\n throw new ModelReviewError(\"Model broker response provider must be a non-empty string.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (typeof response.model !== \"string\" || response.model.trim() === \"\") {\n throw new ModelReviewError(\"Model broker response model must be a non-empty string.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (!Object.hasOwn(response, \"output\")) {\n throw new ModelReviewError(\"Model broker response is missing output.\", {\n code: \"invalid_broker_response\",\n });\n }\n if (response.usage !== undefined) {\n validateUsage(response.usage);\n }\n return response as ModelBrokerResponse;\n}\n\nfunction validateUsage(value: unknown): asserts value is ModelReviewUsage {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ModelReviewError(\"Model broker response usage must be an object.\", {\n code: \"invalid_broker_response\",\n });\n }\n for (const field of [\"inputTokens\", \"outputTokens\"] as const) {\n const count = (value as ModelReviewUsage)[field];\n if (count !== undefined && (!Number.isInteger(count) || count < 0)) {\n throw new ModelReviewError(\n `Model broker response usage.${field} must be a non-negative integer.`,\n {\n code: \"invalid_broker_response\",\n },\n );\n }\n }\n}\n\nfunction validateModelOutput(schema: Record<string, unknown>, output: unknown): void {\n const ajv = new Ajv2020({ allErrors: true, strict: true });\n let validate: ReturnType<Ajv2020[\"compile\"]>;\n try {\n validate = ajv.compile(schema);\n } catch (error) {\n throw new ModelReviewError(\n `Model review schema is invalid: ${error instanceof Error ? error.message : String(error)}`,\n { code: \"invalid_model_schema\" },\n );\n }\n if (!validate(output)) {\n const detail = ajv.errorsText(validate.errors, { separator: \"; \" });\n throw new ModelReviewError(`Model output does not match the requested schema: ${detail}`, {\n code: \"invalid_model_output\",\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type RepositoryReadReason = "excluded_file" | "symlink_rejected" | "not_regular_file" | "unsafe_path" | "invalid_range" | "range_past_eof" | "binary_file" | "change_context_missing" | "file_not_changed" | "invalid_revision";
|
|
2
|
+
export declare class RepositoryReadError extends Error {
|
|
3
|
+
readonly reason: RepositoryReadReason;
|
|
4
|
+
constructor(reason: RepositoryReadReason, message: string);
|
|
5
|
+
}
|
|
6
|
+
export declare function readErrorReason(error: unknown): string;
|
|
7
|
+
export declare function safeDiagnosticPath(path: string, knownPaths: ReadonlySet<string>): string;
|
|
8
|
+
/** Optional diagnostics must never alter a review result or replace its error. */
|
|
9
|
+
export declare function writeRepositoryDiagnostic(record: Record<string, unknown>): void;
|
|
10
|
+
type Counts = {
|
|
11
|
+
rounds: number;
|
|
12
|
+
toolCalls: number;
|
|
13
|
+
bytes: number;
|
|
14
|
+
};
|
|
15
|
+
type Limits = {
|
|
16
|
+
maxRounds: number;
|
|
17
|
+
maxToolCalls: number;
|
|
18
|
+
maxTotalBytes: number;
|
|
19
|
+
maxBytesPerRead: number;
|
|
20
|
+
maxLinesPerRead: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function repositoryDiagnostics(reviewer: string | undefined, limits: Limits, enabled?: boolean): {
|
|
23
|
+
readingId: `${string}-${string}-${string}-${string}-${string}`;
|
|
24
|
+
emit: (details: Record<string, string | number | boolean>, counts: Counts) => void;
|
|
25
|
+
start: () => void;
|
|
26
|
+
finish: (counts: Counts, complete: boolean) => void;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=repository-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-diagnostics.d.ts","sourceRoot":"","sources":["../src/repository-diagnostics.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,oBAAoB,GAC5B,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,aAAa,GACb,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,wBAAwB,GACxB,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,MAAM,EAAE,oBAAoB;gBAA5B,MAAM,EAAE,oBAAoB,EACrC,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAIxF;AAED,kFAAkF;AAClF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAM/E;AAED,KAAK,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AACnE,KAAK,MAAM,GAAG;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AACF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,UAAO;;oBAMS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM;;qBAyB7D,MAAM,YAAY,OAAO;EAM7C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { normalizeRepositoryPath } from "./repository-path.js";
|
|
3
|
+
export class RepositoryReadError extends Error {
|
|
4
|
+
reason;
|
|
5
|
+
constructor(reason, message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.reason = reason;
|
|
8
|
+
this.name = "RepositoryReadError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function readErrorReason(error) {
|
|
12
|
+
if (error instanceof RepositoryReadError)
|
|
13
|
+
return error.reason;
|
|
14
|
+
const code = error?.code;
|
|
15
|
+
const codes = {
|
|
16
|
+
ENOENT: "file_missing",
|
|
17
|
+
EACCES: "permission_denied",
|
|
18
|
+
EPERM: "permission_denied",
|
|
19
|
+
ENOTDIR: "parent_not_directory",
|
|
20
|
+
EIO: "io_error",
|
|
21
|
+
ENOBUFS: "command_output_limit",
|
|
22
|
+
};
|
|
23
|
+
return typeof code === "string" && Object.hasOwn(codes, code) ? codes[code] : "read_failed";
|
|
24
|
+
}
|
|
25
|
+
export function safeDiagnosticPath(path, knownPaths) {
|
|
26
|
+
const normalized = normalizeRepositoryPath(path);
|
|
27
|
+
if (normalized === undefined)
|
|
28
|
+
return "[invalid repository path]";
|
|
29
|
+
return knownPaths.has(normalized) ? normalized : "[unverified repository path]";
|
|
30
|
+
}
|
|
31
|
+
/** Optional diagnostics must never alter a review result or replace its error. */
|
|
32
|
+
export function writeRepositoryDiagnostic(record) {
|
|
33
|
+
try {
|
|
34
|
+
process.stderr.write(`${JSON.stringify(record)}\n`);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// A failed diagnostic sink does not affect repository retrieval.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function repositoryDiagnostics(reviewer, limits, enabled = true) {
|
|
41
|
+
const readingId = randomUUID();
|
|
42
|
+
// Each retrieval is already bounded to 128 operations. Cap gap diagnostics too.
|
|
43
|
+
let records = 0;
|
|
44
|
+
let omitted = 0;
|
|
45
|
+
const emit = (details, counts) => {
|
|
46
|
+
if (!enabled)
|
|
47
|
+
return;
|
|
48
|
+
if (records++ >= 1024) {
|
|
49
|
+
omitted++;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
writeRepositoryDiagnostic({
|
|
53
|
+
event: "repository.read-detail",
|
|
54
|
+
readingId,
|
|
55
|
+
reviewer: reviewer && /^[A-Za-z0-9][A-Za-z0-9._/-]{0,95}$/.test(reviewer) ? reviewer : "unknown",
|
|
56
|
+
...details,
|
|
57
|
+
...counts,
|
|
58
|
+
callsRemaining: Math.max(0, limits.maxToolCalls - counts.toolCalls),
|
|
59
|
+
bytesRemaining: Math.max(0, limits.maxTotalBytes - counts.bytes),
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
readingId,
|
|
64
|
+
emit,
|
|
65
|
+
start: () => emit({ kind: "session", outcome: "started", ...limits }, { rounds: 0, toolCalls: 0, bytes: 0 }),
|
|
66
|
+
finish: (counts, complete) => {
|
|
67
|
+
// Reserve a completion record even when the diagnostic cap was reached.
|
|
68
|
+
records = Math.min(records, 1023);
|
|
69
|
+
emit({ kind: "session", outcome: "finished", complete, omittedRecords: omitted }, counts);
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=repository-diagnostics.js.map
|