promptguard-sdk 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -13
- package/dist/auto.d.ts +1 -0
- package/dist/auto.d.ts.map +1 -1
- package/dist/auto.js +5 -0
- package/dist/auto.js.map +1 -1
- package/dist/generated/api-types.d.ts +175 -0
- package/dist/generated/api-types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +37 -1
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +64 -5
- package/dist/integrations/langchain.js.map +1 -1
- package/dist/integrations/session.d.ts +33 -0
- package/dist/integrations/session.d.ts.map +1 -0
- package/dist/integrations/session.js +71 -0
- package/dist/integrations/session.js.map +1 -0
- package/dist/integrations/vercel-ai-output.d.ts +109 -0
- package/dist/integrations/vercel-ai-output.d.ts.map +1 -0
- package/dist/integrations/vercel-ai-output.js +330 -0
- package/dist/integrations/vercel-ai-output.js.map +1 -0
- package/dist/integrations/vercel-ai.d.ts +114 -24
- package/dist/integrations/vercel-ai.d.ts.map +1 -1
- package/dist/integrations/vercel-ai.js +200 -82
- package/dist/integrations/vercel-ai.js.map +1 -1
- package/dist/patches/base.d.ts +5 -0
- package/dist/patches/base.d.ts.map +1 -1
- package/dist/patches/base.js +5 -2
- package/dist/patches/base.js.map +1 -1
- package/dist/patches/openai.d.ts +8 -0
- package/dist/patches/openai.d.ts.map +1 -1
- package/dist/patches/openai.js +16 -0
- package/dist/patches/openai.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -4
|
@@ -16,12 +16,19 @@
|
|
|
16
16
|
* // or
|
|
17
17
|
* await chain.invoke({ input: '...' }, { callbacks: [handler] });
|
|
18
18
|
* ```
|
|
19
|
+
*
|
|
20
|
+
* Every scan names its Conversation in `session_id` with the call's own
|
|
21
|
+
* thread id: the `thread_id` LangGraph puts in every callback's metadata, or a
|
|
22
|
+
* `thread_id` / `session_id` / `conversation_id` set in `config.metadata`. A
|
|
23
|
+
* call that names no thread sends no session id, unless the handler was given
|
|
24
|
+
* a `sessionId` of its own.
|
|
19
25
|
*/
|
|
20
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
27
|
exports.PromptGuardCallbackHandler = void 0;
|
|
22
28
|
const guard_1 = require("../guard");
|
|
23
29
|
const logger_1 = require("../logger");
|
|
24
30
|
const resolve_1 = require("../resolve");
|
|
31
|
+
const session_1 = require("./session");
|
|
25
32
|
// ---------------------------------------------------------------------------
|
|
26
33
|
// Helpers
|
|
27
34
|
// ---------------------------------------------------------------------------
|
|
@@ -88,6 +95,11 @@ class PromptGuardCallbackHandler {
|
|
|
88
95
|
this.awaitHandlers = true;
|
|
89
96
|
/** Chain context per run ID for richer threat detection. */
|
|
90
97
|
this.chainContext = new Map();
|
|
98
|
+
/**
|
|
99
|
+
* The session id each in-flight LLM or tool run started with: its end
|
|
100
|
+
* callback carries no metadata, and must name the same Conversation.
|
|
101
|
+
*/
|
|
102
|
+
this.runSessions = new Map();
|
|
91
103
|
if (options.silent)
|
|
92
104
|
(0, logger_1.setLogLevel)("silent");
|
|
93
105
|
else if (options.logLevel)
|
|
@@ -105,6 +117,7 @@ class PromptGuardCallbackHandler {
|
|
|
105
117
|
// (least surprise + no unexpected per-response Guard API cost).
|
|
106
118
|
this.scanResponses = options.scanResponses ?? false;
|
|
107
119
|
this.failOpen = options.failOpen ?? true;
|
|
120
|
+
this.sessionId = (0, session_1.validateSessionId)(options.sessionId);
|
|
108
121
|
}
|
|
109
122
|
// -- LLM callbacks -------------------------------------------------------
|
|
110
123
|
async handleLLMStart(serialized, prompts, runId, parentRunId, _extraParams, tags, metadata) {
|
|
@@ -116,6 +129,7 @@ class PromptGuardCallbackHandler {
|
|
|
116
129
|
const context = this.buildContext(runId, parentRunId, "llm", tags, metadata);
|
|
117
130
|
const decision = await this.safeScan(messages, "input", model, context);
|
|
118
131
|
this.handleDecision(decision, runId);
|
|
132
|
+
this.rememberRun(runId, context.sessionId);
|
|
119
133
|
}
|
|
120
134
|
async handleChatModelStart(serialized, messages, runId, parentRunId, _extraParams, tags, metadata) {
|
|
121
135
|
const guardMessages = [];
|
|
@@ -131,27 +145,33 @@ class PromptGuardCallbackHandler {
|
|
|
131
145
|
const context = this.buildContext(runId, parentRunId, "chat_model", tags, metadata);
|
|
132
146
|
const decision = await this.safeScan(guardMessages, "input", model, context);
|
|
133
147
|
this.handleDecision(decision, runId);
|
|
148
|
+
this.rememberRun(runId, context.sessionId);
|
|
134
149
|
}
|
|
135
150
|
async handleLLMEnd(output, runId) {
|
|
151
|
+
const sessionId = this.endRun(runId);
|
|
136
152
|
if (!this.scanResponses)
|
|
137
153
|
return;
|
|
138
154
|
const text = this.extractLLMResponse(output);
|
|
139
155
|
if (!text)
|
|
140
156
|
return;
|
|
141
|
-
const context = this.buildContext(runId, undefined, "llm_response"
|
|
157
|
+
const context = this.buildContext(runId, undefined, "llm_response", undefined, undefined, {
|
|
158
|
+
sessionId,
|
|
159
|
+
});
|
|
142
160
|
const decision = await this.safeScan([{ role: "assistant", content: text }], "output", undefined, context);
|
|
143
161
|
this.handleDecision(decision, runId);
|
|
144
162
|
}
|
|
145
163
|
handleLLMError(_error, runId) {
|
|
146
164
|
this.chainContext.delete(runId);
|
|
165
|
+
this.runSessions.delete(runId);
|
|
147
166
|
}
|
|
148
167
|
// -- Chain callbacks -----------------------------------------------------
|
|
149
|
-
async handleChainStart(serialized, _inputs, runId, parentRunId, tags) {
|
|
168
|
+
async handleChainStart(serialized, _inputs, runId, parentRunId, tags, metadata) {
|
|
150
169
|
const chainName = serialized?.id?.slice(-1)[0] ?? "unknown";
|
|
151
170
|
this.chainContext.set(runId, {
|
|
152
171
|
chain_name: chainName,
|
|
153
172
|
parent_run_id: parentRunId,
|
|
154
173
|
tags,
|
|
174
|
+
session_id: (0, session_1.sessionIdFromMetadata)(metadata),
|
|
155
175
|
});
|
|
156
176
|
}
|
|
157
177
|
handleChainEnd(_outputs, runId) {
|
|
@@ -171,19 +191,24 @@ class PromptGuardCallbackHandler {
|
|
|
171
191
|
});
|
|
172
192
|
const decision = await this.safeScan([{ role: "user", content: input }], "input", "tool", context);
|
|
173
193
|
this.handleDecision(decision, runId);
|
|
194
|
+
this.rememberRun(runId, context.sessionId);
|
|
174
195
|
}
|
|
175
196
|
async handleToolEnd(output, runId) {
|
|
197
|
+
const sessionId = this.endRun(runId);
|
|
176
198
|
if (!this.scanResponses)
|
|
177
199
|
return;
|
|
178
200
|
const text = output ? String(output) : "";
|
|
179
201
|
if (!text)
|
|
180
202
|
return;
|
|
181
|
-
const context = this.buildContext(runId, undefined, "tool_response"
|
|
203
|
+
const context = this.buildContext(runId, undefined, "tool_response", undefined, undefined, {
|
|
204
|
+
sessionId,
|
|
205
|
+
});
|
|
182
206
|
const decision = await this.safeScan([{ role: "assistant", content: text }], "output", undefined, context);
|
|
183
207
|
this.handleDecision(decision, runId);
|
|
184
208
|
}
|
|
185
209
|
handleToolError(_error, runId) {
|
|
186
210
|
this.chainContext.delete(runId);
|
|
211
|
+
this.runSessions.delete(runId);
|
|
187
212
|
}
|
|
188
213
|
// -- Internal helpers ----------------------------------------------------
|
|
189
214
|
async safeScan(messages, direction, model, context) {
|
|
@@ -224,14 +249,48 @@ class PromptGuardCallbackHandler {
|
|
|
224
249
|
`(event=${decision.eventId}, run=${runId})`);
|
|
225
250
|
}
|
|
226
251
|
}
|
|
227
|
-
|
|
252
|
+
/**
|
|
253
|
+
* Keep a run's session id for its end scan.
|
|
254
|
+
*
|
|
255
|
+
* Called only once the start scan has returned: @langchain/core starts a
|
|
256
|
+
* run outside the block whose error path calls `handleLLMError`, so a
|
|
257
|
+
* start that throws gets no end or error callback, and anything stored
|
|
258
|
+
* before it would never be removed. Nothing is stored when the end scan
|
|
259
|
+
* will not run, or would name no session.
|
|
260
|
+
*/
|
|
261
|
+
rememberRun(runId, sessionId) {
|
|
262
|
+
if (sessionId !== undefined && this.scanResponses)
|
|
263
|
+
this.runSessions.set(runId, sessionId);
|
|
264
|
+
}
|
|
265
|
+
/** Forget a finished LLM or tool run; return the session id it started with. */
|
|
266
|
+
endRun(runId) {
|
|
267
|
+
const sessionId = this.runSessions.get(runId);
|
|
268
|
+
this.runSessions.delete(runId);
|
|
269
|
+
return sessionId;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The scan's context. A start callback passes its `metadata`, and the
|
|
273
|
+
* session id is read from it; an end callback passes the `sessionId` its
|
|
274
|
+
* start remembered. Nothing is stored here.
|
|
275
|
+
*/
|
|
276
|
+
buildContext(runId, parentRunId, component = "unknown", tags, metadata, end) {
|
|
228
277
|
const chainInfo = this.chainContext.get(runId) ??
|
|
229
278
|
(parentRunId ? this.chainContext.get(parentRunId) : undefined) ??
|
|
230
279
|
{};
|
|
280
|
+
let sessionId;
|
|
281
|
+
if (end) {
|
|
282
|
+
sessionId = end.sessionId;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
sessionId =
|
|
286
|
+
(0, session_1.sessionIdFromMetadata)(metadata) ??
|
|
287
|
+
chainInfo.session_id ??
|
|
288
|
+
this.sessionId;
|
|
289
|
+
}
|
|
231
290
|
return {
|
|
232
291
|
framework: "langchain",
|
|
233
292
|
chainName: chainInfo.chain_name,
|
|
234
|
-
sessionId:
|
|
293
|
+
...(sessionId !== undefined ? { sessionId } : {}),
|
|
235
294
|
metadata: {
|
|
236
295
|
component,
|
|
237
296
|
tags: tags ?? chainInfo.tags,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../src/integrations/langchain.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../src/integrations/langchain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Conversation a framework integration's scans belong to.
|
|
3
|
+
*
|
|
4
|
+
* The Guard API remembers a Conversation's turns when a scan names it in
|
|
5
|
+
* `context.session_id`. An integration must send the framework's real
|
|
6
|
+
* conversation id there — the same value on every turn of one conversation, a
|
|
7
|
+
* different one for another — or nothing at all. A per-call run id would make
|
|
8
|
+
* every scan a conversation of its own.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The longest session id sent: the Guard API refuses a longer one, matching
|
|
12
|
+
* the column that stores it, so it is dropped before the scan.
|
|
13
|
+
*/
|
|
14
|
+
export declare const MAX_SESSION_ID_CHARS = 255;
|
|
15
|
+
/**
|
|
16
|
+
* The metadata keys a LangChain call carries its conversation id under, in
|
|
17
|
+
* the order they are read. LangGraph copies the checkpointer's `thread_id`
|
|
18
|
+
* into every callback's metadata; `session_id` and `conversation_id` are the
|
|
19
|
+
* other two keys LangSmith groups a thread by, set through `config.metadata`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CONVERSATION_METADATA_KEYS: readonly ["thread_id", "session_id", "conversation_id"];
|
|
22
|
+
/**
|
|
23
|
+
* `value` as a session id, or `undefined` when it cannot be one: a non-empty
|
|
24
|
+
* string as it is, a finite number in its decimal form, anything else not.
|
|
25
|
+
* Nor an id over {@link MAX_SESSION_ID_CHARS}: it is dropped with a debug log
|
|
26
|
+
* and the scan goes ahead without one, never failing the call (ADR-0002).
|
|
27
|
+
*/
|
|
28
|
+
export declare function asSessionId(value: unknown): string | undefined;
|
|
29
|
+
/** The conversation id a LangChain call's metadata names, if any. */
|
|
30
|
+
export declare function sessionIdFromMetadata(metadata: Record<string, unknown> | undefined): string | undefined;
|
|
31
|
+
/** Check a `sessionId` an application passed to an integration. */
|
|
32
|
+
export declare function validateSessionId(sessionId: string | undefined): string | undefined;
|
|
33
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/integrations/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,yDAA0D,CAAA;AAEjG;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAc9D;AAED,qEAAqE;AACrE,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC5C,MAAM,GAAG,SAAS,CAOpB;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUnF"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The Conversation a framework integration's scans belong to.
|
|
4
|
+
*
|
|
5
|
+
* The Guard API remembers a Conversation's turns when a scan names it in
|
|
6
|
+
* `context.session_id`. An integration must send the framework's real
|
|
7
|
+
* conversation id there — the same value on every turn of one conversation, a
|
|
8
|
+
* different one for another — or nothing at all. A per-call run id would make
|
|
9
|
+
* every scan a conversation of its own.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CONVERSATION_METADATA_KEYS = exports.MAX_SESSION_ID_CHARS = void 0;
|
|
13
|
+
exports.asSessionId = asSessionId;
|
|
14
|
+
exports.sessionIdFromMetadata = sessionIdFromMetadata;
|
|
15
|
+
exports.validateSessionId = validateSessionId;
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
/**
|
|
18
|
+
* The longest session id sent: the Guard API refuses a longer one, matching
|
|
19
|
+
* the column that stores it, so it is dropped before the scan.
|
|
20
|
+
*/
|
|
21
|
+
exports.MAX_SESSION_ID_CHARS = 255;
|
|
22
|
+
/**
|
|
23
|
+
* The metadata keys a LangChain call carries its conversation id under, in
|
|
24
|
+
* the order they are read. LangGraph copies the checkpointer's `thread_id`
|
|
25
|
+
* into every callback's metadata; `session_id` and `conversation_id` are the
|
|
26
|
+
* other two keys LangSmith groups a thread by, set through `config.metadata`.
|
|
27
|
+
*/
|
|
28
|
+
exports.CONVERSATION_METADATA_KEYS = ["thread_id", "session_id", "conversation_id"];
|
|
29
|
+
/**
|
|
30
|
+
* `value` as a session id, or `undefined` when it cannot be one: a non-empty
|
|
31
|
+
* string as it is, a finite number in its decimal form, anything else not.
|
|
32
|
+
* Nor an id over {@link MAX_SESSION_ID_CHARS}: it is dropped with a debug log
|
|
33
|
+
* and the scan goes ahead without one, never failing the call (ADR-0002).
|
|
34
|
+
*/
|
|
35
|
+
function asSessionId(value) {
|
|
36
|
+
const id = typeof value === "number" && Number.isFinite(value)
|
|
37
|
+
? String(value)
|
|
38
|
+
: typeof value === "string" && value.trim()
|
|
39
|
+
? value
|
|
40
|
+
: undefined;
|
|
41
|
+
if (id !== undefined && id.length > exports.MAX_SESSION_ID_CHARS) {
|
|
42
|
+
logger_1.logger.debug(`session id of ${id.length} characters is over ${exports.MAX_SESSION_ID_CHARS}; scanning without one`);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
/** The conversation id a LangChain call's metadata names, if any. */
|
|
48
|
+
function sessionIdFromMetadata(metadata) {
|
|
49
|
+
if (!metadata)
|
|
50
|
+
return undefined;
|
|
51
|
+
for (const key of exports.CONVERSATION_METADATA_KEYS) {
|
|
52
|
+
const sessionId = asSessionId(metadata[key]);
|
|
53
|
+
if (sessionId !== undefined)
|
|
54
|
+
return sessionId;
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/** Check a `sessionId` an application passed to an integration. */
|
|
59
|
+
function validateSessionId(sessionId) {
|
|
60
|
+
if (sessionId === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
if (typeof sessionId !== "string" || !sessionId.trim()) {
|
|
63
|
+
throw new TypeError(`sessionId must be a non-empty string, got ${JSON.stringify(sessionId)}`);
|
|
64
|
+
}
|
|
65
|
+
if (sessionId.length > exports.MAX_SESSION_ID_CHARS) {
|
|
66
|
+
// Configuration, not a request: refused when the integration is built.
|
|
67
|
+
throw new TypeError(`sessionId must be at most ${exports.MAX_SESSION_ID_CHARS} characters`);
|
|
68
|
+
}
|
|
69
|
+
return sessionId;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/integrations/session.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAwBH,kCAcC;AAGD,sDASC;AAGD,8CAUC;AA7DD,sCAAkC;AAElC;;;GAGG;AACU,QAAA,oBAAoB,GAAG,GAAG,CAAA;AAEvC;;;;;GAKG;AACU,QAAA,0BAA0B,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,iBAAiB,CAAU,CAAA;AAEjG;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,KAAc;IACxC,MAAM,EAAE,GACN,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjD,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACf,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE;YACzC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,SAAS,CAAA;IACjB,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,CAAC,MAAM,GAAG,4BAAoB,EAAE,CAAC;QACzD,eAAM,CAAC,KAAK,CACV,iBAAiB,EAAE,CAAC,MAAM,uBAAuB,4BAAoB,wBAAwB,CAC9F,CAAA;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,qEAAqE;AACrE,SAAgB,qBAAqB,CACnC,QAA6C;IAE7C,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC/B,KAAK,MAAM,GAAG,IAAI,kCAA0B,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5C,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;IAC/C,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,mEAAmE;AACnE,SAAgB,iBAAiB,CAAC,SAA6B;IAC7D,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC7C,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,SAAS,CAAC,6CAA6C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IAC/F,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,4BAAoB,EAAE,CAAC;QAC5C,uEAAuE;QACvE,MAAM,IAAI,SAAS,CAAC,6BAA6B,4BAAoB,aAAa,CAAC,CAAA;IACrF,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output scanning for the Vercel AI SDK integration — generated and streamed.
|
|
3
|
+
*
|
|
4
|
+
* This is the one place that decides what a model's output is scanned as and
|
|
5
|
+
* what a decision about it does. The middleware (`vercel-ai.ts`) calls it from
|
|
6
|
+
* both `wrapGenerate` and `wrapStream`, and anything else that wraps an AI SDK
|
|
7
|
+
* model should call it too rather than restating the policy.
|
|
8
|
+
*
|
|
9
|
+
* Streams are scanned in windows, then once more in full:
|
|
10
|
+
*
|
|
11
|
+
* - **Enforce mode** holds back the stream parts that carry scanned text
|
|
12
|
+
* (text deltas, tool-call input) until that text has been scanned. Each
|
|
13
|
+
* time `windowChars` new characters have arrived, everything held is
|
|
14
|
+
* scanned and, if clean, released — except the last `WINDOW_OVERLAP_CHARS`
|
|
15
|
+
* characters, which stay held and are scanned again at the head of the next
|
|
16
|
+
* window. So every released character has been scanned together with at
|
|
17
|
+
* least the overlap that follows it, and a secret up to the overlap long is
|
|
18
|
+
* always seen whole before any of it is released. When the model finishes,
|
|
19
|
+
* the complete text is scanned — the same text, built the same way, as a
|
|
20
|
+
* generated result — before the held tail and the `finish` part are
|
|
21
|
+
* released. Parts that carry no scanned text (stream start, reasoning,
|
|
22
|
+
* sources, files, metadata) are delivered at once when nothing is held
|
|
23
|
+
* ahead of them, and queue behind held text otherwise, so order is kept.
|
|
24
|
+
* - **Monitor mode** never stops a call, so it never holds one: parts pass
|
|
25
|
+
* through as they arrive and only the complete text is scanned, at the end.
|
|
26
|
+
*
|
|
27
|
+
* Reasoning is not scanned, here or on the generated path.
|
|
28
|
+
*
|
|
29
|
+
* A block (or an output redact, which cannot be honoured on text already
|
|
30
|
+
* generated) stops the stream with `PromptGuardBlockedError`. A Guard API
|
|
31
|
+
* outage fails open by default (ADR-0002): the held parts are released and the
|
|
32
|
+
* rest of that stream passes unscanned, so an outage costs one failed scan per
|
|
33
|
+
* stream rather than one per window. With `failOpen: false` it stops the
|
|
34
|
+
* stream with the `GuardApiError` instead.
|
|
35
|
+
*
|
|
36
|
+
* How a stopped stream ends is the caller's choice (`StreamStop`): by
|
|
37
|
+
* erroring it, so whatever reads it throws, or by delivering one AI SDK
|
|
38
|
+
* `error` part and closing it. Either way nothing held is released and the
|
|
39
|
+
* `finish` part never arrives.
|
|
40
|
+
*/
|
|
41
|
+
import { type GuardClient } from "../guard";
|
|
42
|
+
/**
|
|
43
|
+
* Default new characters of streamed output per scanned window.
|
|
44
|
+
*
|
|
45
|
+
* Not taken from any external standard: 1000 was chosen as a balance between
|
|
46
|
+
* how long output is held and how many Guard API round trips a stream costs.
|
|
47
|
+
* At roughly four characters a token it is about 250 tokens, which takes a
|
|
48
|
+
* model a few seconds to generate — about as long as one Guard round trip, so
|
|
49
|
+
* scanning a window roughly keeps pace with generating the next. A smaller
|
|
50
|
+
* window delivers the first text sooner and costs more scans; a larger one
|
|
51
|
+
* costs fewer scans and holds output longer.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_STREAM_WINDOW_CHARS = 1000;
|
|
54
|
+
/**
|
|
55
|
+
* Characters of scanned text always kept held and rescanned at the head of
|
|
56
|
+
* the next window — the longest secret guaranteed to be seen whole across a
|
|
57
|
+
* window boundary.
|
|
58
|
+
*/
|
|
59
|
+
export declare const WINDOW_OVERLAP_CHARS = 200;
|
|
60
|
+
export interface OutputScanPolicy {
|
|
61
|
+
guard: GuardClient;
|
|
62
|
+
mode: "enforce" | "monitor";
|
|
63
|
+
failOpen: boolean;
|
|
64
|
+
/** Characters per streamed window; `Infinity` holds the whole response. */
|
|
65
|
+
windowChars: number;
|
|
66
|
+
}
|
|
67
|
+
/** Throws `RangeError` unless `value` is a usable `streamWindowChars`. */
|
|
68
|
+
export declare function validateWindowChars(value: number): number;
|
|
69
|
+
/**
|
|
70
|
+
* What happened to a piece of output that was allowed through: `"scanned"`
|
|
71
|
+
* when the Guard API saw it, `"failed-open"` when it was unreachable and
|
|
72
|
+
* fail-open let the output through unscanned.
|
|
73
|
+
*/
|
|
74
|
+
export type OutputScanOutcome = "scanned" | "failed-open";
|
|
75
|
+
/**
|
|
76
|
+
* Scan one piece of model output. Resolves when the output may be delivered;
|
|
77
|
+
* throws `PromptGuardBlockedError` when enforce mode stops it, and rethrows
|
|
78
|
+
* the `GuardApiError` when failing closed. `sessionId` names the
|
|
79
|
+
* Conversation the call belongs to, when it names one.
|
|
80
|
+
*/
|
|
81
|
+
export declare function scanOutputText(text: string, policy: OutputScanPolicy, modelId: string | undefined, what?: string, sessionId?: string): Promise<OutputScanOutcome>;
|
|
82
|
+
/**
|
|
83
|
+
* Extract all scannable text from a `doGenerate` result.
|
|
84
|
+
*
|
|
85
|
+
* Handles both AI SDK result shapes:
|
|
86
|
+
* - **v4 (LanguageModelV1):** top-level `text` string plus `toolCalls`
|
|
87
|
+
* (every tool call's `args`/`input` is scanned — not just the first).
|
|
88
|
+
* - **v5+ (LanguageModelV2/V3):** `content` is an array of parts
|
|
89
|
+
* (`{ type: "text", text }` / `{ type: "tool-call", input }`) with no
|
|
90
|
+
* top-level `text`.
|
|
91
|
+
*
|
|
92
|
+
* Returns the concatenated text, or `null` when nothing scannable exists.
|
|
93
|
+
*/
|
|
94
|
+
export declare function extractGeneratedText(result: Record<string, unknown> | null | undefined): string | null;
|
|
95
|
+
/**
|
|
96
|
+
* How a stream the policy stops ends: `"error"` errors the stream, so the
|
|
97
|
+
* reader's next read throws the error; `"error-part"` delivers one
|
|
98
|
+
* `{ type: "error", error }` stream part — the AI SDK's own way for a model to
|
|
99
|
+
* report a failure mid-stream — and then closes the stream.
|
|
100
|
+
*/
|
|
101
|
+
export type StreamStop = "error" | "error-part";
|
|
102
|
+
/**
|
|
103
|
+
* Wrap a model stream so its output is scanned as described in this module's
|
|
104
|
+
* header. Parts are passed through unchanged and in order; where the policy
|
|
105
|
+
* stops the output, the stream ends with `PromptGuardBlockedError` (or the
|
|
106
|
+
* `GuardApiError` when failing closed), as `stopAs` says.
|
|
107
|
+
*/
|
|
108
|
+
export declare function scanOutputStream<T>(stream: ReadableStream<T>, policy: OutputScanPolicy, modelId: string | undefined, stopAs?: StreamStop, sessionId?: string): ReadableStream<T>;
|
|
109
|
+
//# sourceMappingURL=vercel-ai-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-ai-output.d.ts","sourceRoot":"","sources":["../../src/integrations/vercel-ai-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAiB,KAAK,WAAW,EAA2C,MAAM,UAAU,CAAA;AAGnG;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE,SAAS,GAAG,SAAS,CAAA;IAC3B,QAAQ,EAAE,OAAO,CAAA;IACjB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,aAAa,CAAA;AAEzD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,SAAa,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC,CA4B5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GACjD,MAAM,GAAG,IAAI,CAgCf;AAuED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,YAAY,CAAA;AAE/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,MAAM,GAAE,UAAoB,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAAC,CAAC,CAAC,CAyGnB"}
|