@zuplo/runtime 7.8.24 → 7.9.2

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.
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{E as p,J as c,M as u}from"../chunk-7NJIR6WX.js";import"../chunk-54HRCPVQ.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import"../chunk-6O4OZCO6.js";import{aa as i}from"../chunk-MWIJG5KC.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
25
+ import{E as p,J as c,M as u}from"../chunk-A7E4OVWK.js";import"../chunk-54HRCPVQ.js";import{a as d}from"../chunk-QGAJTUPE.js";import"../chunk-A3QGJZO7.js";import"../chunk-6O4OZCO6.js";import{aa as i}from"../chunk-MWIJG5KC.js";import{a as o}from"../chunk-TYV53J3B.js";function w(l={request:new Request("https://api.example.com")}){let e=[];function t(s){e.push(Promise.resolve(s))}return o(t,"waitUntil"),{context:new a({event:{waitUntil:t},route:l.route,originalRequest:l.request}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(w,"createMockContext");var g={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},a=class extends EventTarget{static{o(this,"MockZuploContext")}#e;#t;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=g,parentContext:n,originalRequest:r}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:i.console.info,log:i.console.log,debug:i.console.debug,warn:i.console.warn,error:i.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=n,this.#e=e,this.#t=r,this.analyticsContext=new c(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,n){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addPreRequestHandler(e,t){let n;try{n=u.getContextExtensions(this)}catch{n=u.initialize(this,new d(this.#t??new Request("https://api.example.com")))}n.preRequestPhase??="active",p(this,n,e,t)}get preRequestHandlers(){let e;try{e=u.getContextExtensions(this)}catch{return[]}return(e.preRequestState?.entries??[]).map(t=>({policyName:t.policyName,name:t.name}))}addEventListener(e,t,n){let r=o(s=>{try{typeof t=="function"?t(s):t.handleEvent(s)}catch(m){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),m}},"wrapped");super.addEventListener(e,r,n)}};export{a as MockZuploContext,w as createMockContext};
26
26
  //# sourceMappingURL=index.js.map
@@ -41,7 +41,7 @@ export declare type AiFormat =
41
41
  * mid-stream if harmful content is detected.
42
42
  *
43
43
  * Do not add this policy to the inbound chain of an app used as a Smart
44
- * Router classifier (`classifierAppID`). The firewall would inspect Smart
44
+ * Router classifier (`classifier.app`). The firewall would inspect Smart
45
45
  * Router's internal classification call as if it were a completion request,
46
46
  * and Smart Router fails open on the resulting denial — so this is rejected
47
47
  * with a `ConfigurationError` rather than silently degrading classification.
@@ -204,7 +204,7 @@ export declare type AIGatewayCapability =
204
204
  * gateway root.
205
205
  *
206
206
  * Place this policy on AI Gateway routes after optional authentication and
207
- * optional `ai-gateway-configuration-loader-v2-inbound`. When either of those
207
+ * optional `ai-gateway-configuration-loader-inbound`. When either of those
208
208
  * already populated the app-configuration channel, this policy reuses it.
209
209
  * Otherwise it loads the configuration with the route's `app_id` path
210
210
  * parameter. Applications select from policies pre-declared by the gateway.
@@ -246,7 +246,7 @@ export { AIGatewayConfigurationExecutorInboundPolicy as AIGatewayConfigurationEx
246
246
  */
247
247
  declare interface AIGatewayConfigurationExecutorInboundPolicyOptions {
248
248
  /**
249
- * The time in seconds to cache app configurations loaded by app_id. Defaults to 10 seconds when omitted. Higher values decrease latency; lower values pick up portal changes sooner. Cached results remain valid until the cache expires even if the configuration changes in the portal. This cache is only used when neither ai-gateway-auth-v2-inbound nor ai-gateway-configuration-loader-v2-inbound already loaded the configuration for the request.
249
+ * The time in seconds to cache app configurations loaded by app_id. Defaults to 10 seconds when omitted. Higher values decrease latency; lower values pick up portal changes sooner. Cached results remain valid until the cache expires even if the configuration changes in the portal. This cache is only used when neither ai-gateway-auth-inbound nor ai-gateway-configuration-loader-inbound already loaded the configuration for the request.
250
250
  */
251
251
  cacheTtlSeconds?: number;
252
252
  }
@@ -258,8 +258,8 @@ export { AIGatewayConfigurationExecutorInboundPolicyOptions as AIGatewayConfigur
258
258
  * request-scoped channel and does nothing else.
259
259
  *
260
260
  * Place this policy on AI Gateway routes before
261
- * `ai-gateway-configuration-executor-v2-inbound` when you want configuration
262
- * loading separated from chain execution. When `ai-gateway-auth-v2-inbound`
261
+ * `ai-gateway-configuration-executor-inbound` when you want configuration
262
+ * loading separated from chain execution. When `ai-gateway-auth-inbound`
263
263
  * already populated the channel, this policy reuses it. Otherwise it loads
264
264
  * the configuration with the route's `app_id` path parameter.
265
265
  *
@@ -291,7 +291,7 @@ export { AIGatewayConfigurationLoaderInboundPolicy as AIGatewayConfigurationLoad
291
291
  */
292
292
  declare interface AIGatewayConfigurationLoaderInboundPolicyOptions {
293
293
  /**
294
- * The time in seconds to cache app configurations loaded by app_id. Defaults to 10 seconds when omitted. Higher values decrease latency; lower values pick up portal changes sooner. Cached results remain valid until the cache expires even if the configuration changes in the portal. When ai-gateway-auth-v2-inbound already loaded the configuration for the request, this cache is not used.
294
+ * The time in seconds to cache app configurations loaded by app_id. Defaults to 10 seconds when omitted. Higher values decrease latency; lower values pick up portal changes sooner. Cached results remain valid until the cache expires even if the configuration changes in the portal. When ai-gateway-auth-inbound already loaded the configuration for the request, this cache is not used.
295
295
  */
296
296
  cacheTtlSeconds?: number;
297
297
  }
@@ -1203,17 +1203,20 @@ export declare type AIGatewaySmartRouterComplexity = "low" | "medium" | "high";
1203
1203
  * @product ai-gateway
1204
1204
  * @requiresAI
1205
1205
  *
1206
- * Classifies the last user prompt by calling a dedicated classifier AI
1207
- * Gateway app, stores the result on `AIGatewaySmartRouter`, and
1208
- * optionally overwrites completions routing from `modelsByComplexity`.
1209
- * Classification failures, timeouts, and invalid options fail open: the
1210
- * original request is forwarded.
1211
- *
1212
- * `classifierAppID` must not be this app's own id, and the classifier app it
1213
- * names must not run this policy itself. Both are rejected with a
1214
- * `ConfigurationError` — thrown, not logged and failed open like every other
1215
- * classifier failure — so a misconfigured routing loop is never mistaken for
1216
- * smart routing that is simply doing nothing.
1206
+ * Classifies the last user prompt with the classifier set in `classifier` —
1207
+ * another AI Gateway app, an OpenAI-compatible Chat Completions API, or Jev
1208
+ * from TypeSafe — stores the result on `AIGatewaySmartRouter`, and optionally
1209
+ * overwrites completions routing from `modelsByComplexity`. Classification
1210
+ * failures, timeouts, and incomplete options fail open: the original request
1211
+ * is forwarded.
1212
+ *
1213
+ * Some misconfigurations are rejected with a `ConfigurationError` — thrown,
1214
+ * not logged and failed open like every other classifier failure — because
1215
+ * failing open on them would look like smart routing that is simply doing
1216
+ * nothing: more than one classifier, a deprecated `classifierAppID`-style
1217
+ * option beside `classifier`, or `classifierPrompt` with Jev; a
1218
+ * `classifier.app.appId` that is this app's own id; and a classifier app that
1219
+ * runs this policy itself.
1217
1220
  *
1218
1221
  * @param request - The ZuploRequest
1219
1222
  * @param context - The ZuploContext
@@ -1229,25 +1232,30 @@ export declare function AIGatewaySmartRouterInboundPolicy(
1229
1232
  ): Promise<ZuploRequest | Response>;
1230
1233
 
1231
1234
  /**
1232
- * Options for the Smart Router policy: classify the last user prompt with a dedicated classifier AI Gateway app, then optionally route by complexity.
1235
+ * Options for the Smart Router policy: classify the last user prompt with an AI Gateway app, a Chat Completions API, or Jev, then optionally route by complexity.
1233
1236
  * @public
1234
1237
  */
1235
1238
  export declare interface AIGatewaySmartRouterInboundPolicyOptions {
1236
- classifierAppID: ClassifierAppID_2;
1237
- classifierModel: ClassifierModel_2;
1239
+ classifier?: Classifier;
1238
1240
  modelsByComplexity: ModelsByComplexity;
1239
- classifierAppApiKey?: ClassifierAppAPIKey;
1240
1241
  smartRoutingEnabled?: SmartRoutingEnabled;
1241
1242
  intents?: Intents;
1242
1243
  classifierPrompt?: ClassifierPrompt_2;
1243
1244
  minConfidenceForRouting?: MinimumConfidenceForRouting;
1244
1245
  classifierTimeoutMs?: ClassifierTimeoutMs_2;
1245
1246
  maxPromptChars?: MaxPromptCharacters;
1247
+ classifierAppID?: ClassifierAppIDDeprecated;
1248
+ classifierModel?: ClassifierModelDeprecated;
1249
+ classifierAppApiKey?: ClassifierAppAPIKeyDeprecated;
1246
1250
  }
1247
1251
 
1248
1252
  /**
1249
1253
  * Structured classification of the last user prompt.
1250
1254
  *
1255
+ * With the Jev classifier, `confidence` is the lower of Jev's confidence in
1256
+ * the intent and in the complexity, and `reasons` is empty: Jev answers typed
1257
+ * questions and writes no reasons.
1258
+ *
1251
1259
  * @public
1252
1260
  */
1253
1261
  export declare interface AIGatewaySmartRouterProfile {
@@ -1311,7 +1319,9 @@ export declare interface AIGatewaySmartRouterRoutingDecision {
1311
1319
  }
1312
1320
 
1313
1321
  /**
1314
- * Classifier token usage reported by the classifier chat/completions call.
1322
+ * Classifier token usage reported by the classifier call. For Jev,
1323
+ * `promptTokens` and `completionTokens` are the input and output tokens that
1324
+ * the Jev API reports.
1315
1325
  *
1316
1326
  * @public
1317
1327
  */
@@ -3739,6 +3749,34 @@ declare interface ChatCompletionResponse {
3739
3749
  provider?: string;
3740
3750
  }
3741
3751
 
3752
+ /**
3753
+ * Classify by calling an OpenAI-compatible Chat Completions API directly, outside the gateway. The model must support structured outputs (`response_format` with a JSON schema).
3754
+ * @public
3755
+ */
3756
+ declare interface ChatCompletionsAPI {
3757
+ apiKey: ChatCompletionsAPIKey;
3758
+ model: ChatCompletionsModel;
3759
+ baseUrl?: ChatCompletionsBaseURL;
3760
+ }
3761
+
3762
+ /**
3763
+ * API key for the service at `baseUrl`, sent as `Authorization: Bearer`.
3764
+ * @public
3765
+ */
3766
+ declare type ChatCompletionsAPIKey = string;
3767
+
3768
+ /**
3769
+ * Base URL of the OpenAI-compatible API. The classifier request is sent to `{baseUrl}/chat/completions`.
3770
+ * @public
3771
+ */
3772
+ declare type ChatCompletionsBaseURL = string;
3773
+
3774
+ /**
3775
+ * The model id the service expects, such as `gpt-4o-mini`. This is sent to the service as-is, not as a `providerName/model` reference.
3776
+ * @public
3777
+ */
3778
+ declare type ChatCompletionsModel = string;
3779
+
3742
3780
  /**
3743
3781
  * Time interval in milliseconds for periodic checks (alternative to chunk count).
3744
3782
  * @public
@@ -3757,12 +3795,38 @@ declare type Claim = string;
3757
3795
  */
3758
3796
  declare type ClaimCheck = EqualsRule | InRule | StartsWithRule;
3759
3797
 
3798
+ /**
3799
+ * Where the user's prompt is classified. Required unless the deprecated `classifierAppID` and `classifierModel` are set. Set exactly one of `app`, `chatCompletions`, or `jev`; setting more than one is a configuration error.
3800
+ * @public
3801
+ */
3802
+ declare interface Classifier {
3803
+ app?: ClassifierApp;
3804
+ chatCompletions?: ChatCompletionsAPI;
3805
+ jev?: JevTypeSafe;
3806
+ }
3807
+
3808
+ /**
3809
+ * Classify with another AI Gateway app in this project. The call runs in-process and never leaves the gateway, so the classifier uses that app's providers, routing, and quotas.
3810
+ * @public
3811
+ */
3812
+ declare interface ClassifierApp {
3813
+ appId: ClassifierAppID_2;
3814
+ model: ClassifierModel_2;
3815
+ apiKey?: ClassifierAppAPIKey;
3816
+ }
3817
+
3760
3818
  /**
3761
3819
  * API key sent as `Authorization: Bearer` when invoking the classifier app. Omit it when the classifier app runs the Ensure Gateway Internal Invocation Only policy: the classifier call never leaves the gateway, so that policy accepts it and rejects everything arriving over the network, and no credential is sent. Set it only when the classifier app authenticates callers with API keys.
3762
3820
  * @public
3763
3821
  */
3764
3822
  declare type ClassifierAppAPIKey = string;
3765
3823
 
3824
+ /**
3825
+ * **Deprecated**: use `classifier.app.apiKey` instead. Still honored when `classifier` is not set; setting both is a configuration error.
3826
+ * @public
3827
+ */
3828
+ declare type ClassifierAppAPIKeyDeprecated = string;
3829
+
3766
3830
  /**
3767
3831
  * Run the classifier on another AI Gateway app instead of calling an external API directly. The gateway invokes that app in-process — no outbound HTTP hop — so the classifier inherits its provider credentials, model routing, fallbacks and quotas, and provider keys stay on one app. Give that app the Ensure Gateway Internal Invocation Only policy and `apiKey` is not needed at all. When set, `model` must name a routed model as `provider/model` and `baseUrl` must not be set. The target app must not itself run this policy: it would be asked to classify its own classification request, which is rejected as a configuration error rather than silently skipped. Omit to call `baseUrl` directly.
3768
3832
  * @public
@@ -3770,11 +3834,17 @@ declare type ClassifierAppAPIKey = string;
3770
3834
  declare type ClassifierAppID = string;
3771
3835
 
3772
3836
  /**
3773
- * The AI Gateway application id used to run the classifier prompt and evaluate the user's request.
3837
+ * The id of the AI Gateway app that runs the classifier. It must not be this app, and that app must not run this policy.
3774
3838
  * @public
3775
3839
  */
3776
3840
  declare type ClassifierAppID_2 = string;
3777
3841
 
3842
+ /**
3843
+ * **Deprecated**: use `classifier.app.appId` instead. Still honored when `classifier` is not set; setting both is a configuration error.
3844
+ * @public
3845
+ */
3846
+ declare type ClassifierAppIDDeprecated = string;
3847
+
3778
3848
  /**
3779
3849
  * Tool-calling capable model used to classify prompts. Prefer a small, fast model; the classification runs before every inspected request reaches the upstream model. With `appId` set this must name a model the classifier app routes, written as `provider/model` (for example `openai/gpt-4o-mini`), and has no default.
3780
3850
  * @public
@@ -3782,11 +3852,17 @@ declare type ClassifierAppID_2 = string;
3782
3852
  declare type ClassifierModel = string;
3783
3853
 
3784
3854
  /**
3785
- * The model (`providerName/model`) the classifier uses to evaluate the user's request. E.g. `openai/gpt-4o-mini`.
3855
+ * The model (`providerName/model`) the classifier app uses to evaluate the user's request. E.g. `openai/gpt-4o-mini`.
3786
3856
  * @public
3787
3857
  */
3788
3858
  declare type ClassifierModel_2 = string;
3789
3859
 
3860
+ /**
3861
+ * **Deprecated**: use `classifier.app.model` instead. Still honored when `classifier` is not set; setting both is a configuration error.
3862
+ * @public
3863
+ */
3864
+ declare type ClassifierModelDeprecated = string;
3865
+
3790
3866
  /**
3791
3867
  * Replaces the built-in system prompt that tells the classifier what counts as a prompt injection. A string, or an array of lines joined with newlines. The inspected text is always sent as a separate user message and the verdict always comes back through the fixed SAFE/UNSAFE tool call, so a custom prompt changes what is flagged, never how the verdict is read. Omit to use the built-in prompt, which the policy documentation shows in full.
3792
3868
  * @public
@@ -3794,7 +3870,7 @@ declare type ClassifierModel_2 = string;
3794
3870
  declare type ClassifierPrompt = string | [string, ...string[]];
3795
3871
 
3796
3872
  /**
3797
- * Prompt used to analyze and classify the user message. Omit to use the built-in classifier prompt.
3873
+ * Prompt used to analyze and classify the user message with `classifier.app` or `classifier.chatCompletions`. Omit to use the built-in classifier prompt. Jev takes no prompt, so setting this with `classifier.jev` is a configuration error.
3798
3874
  * @public
3799
3875
  */
3800
3876
  declare type ClassifierPrompt_2 = string | [string, ...string[]];
@@ -8052,6 +8128,34 @@ declare type Iso3166Alpha2Code =
8052
8128
  | "ZM"
8053
8129
  | "ZW";
8054
8130
 
8131
+ /**
8132
+ * API key for the service at `baseUrl`, sent as `Authorization: Bearer`: a TypeSafe key by default, or an OpenRouter key when `baseUrl` is OpenRouter.
8133
+ * @public
8134
+ */
8135
+ declare type JevAPIKey = string;
8136
+
8137
+ /**
8138
+ * API root of the System One API that serves Jev, the same value the TypeSafe SDK's `baseURL` takes. The classifier request is sent to `{baseUrl}/v1/systemone`. Set it to `https://openrouter.ai/api` to call Jev through OpenRouter.
8139
+ * @public
8140
+ */
8141
+ declare type JevBaseURL = string;
8142
+
8143
+ /**
8144
+ * The Jev model to call. `jev-latest` follows the newest stable release on both TypeSafe and OpenRouter. Pin a versioned id to keep answers stable after tuning `minConfidenceForRouting`: `jev-1.13.0` on TypeSafe, or `jev-1.13` on OpenRouter.
8145
+ * @public
8146
+ */
8147
+ declare type JevModel = string;
8148
+
8149
+ /**
8150
+ * Classify with Jev, TypeSafe's classification model, by calling a System One API directly: TypeSafe's by default, or another host such as OpenRouter through `baseUrl`. Jev answers typed questions instead of generating text, so it takes no `classifierPrompt`.
8151
+ * @public
8152
+ */
8153
+ declare interface JevTypeSafe {
8154
+ apiKey: JevAPIKey;
8155
+ model?: JevModel;
8156
+ baseUrl?: JevBaseURL;
8157
+ }
8158
+
8055
8159
  declare type JsonArray = JsonValue[] | readonly JsonValue[];
8056
8160
 
8057
8161
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zuplo/runtime",
3
3
  "type": "module",
4
- "version": "7.8.24",
4
+ "version": "7.9.2",
5
5
  "repository": "https://github.com/zuplo/zuplo",
6
6
  "author": "Zuplo, Inc.",
7
7
  "exports": {