@zhivex-ai/gateway 0.9.2 → 1.0.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 +25 -3
- package/dist/compat.d.ts +1 -3
- package/dist/compat.d.ts.map +1 -1
- package/dist/compat.js +0 -16
- package/dist/compat.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +604 -361
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +21 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,14 +33,20 @@ const gateway = createGateway({
|
|
|
33
33
|
openai: createOpenAI({ apiKey: process.env.OPENAI_API_KEY }),
|
|
34
34
|
ollama: createOllama()
|
|
35
35
|
},
|
|
36
|
-
maxRetries: 1
|
|
36
|
+
maxRetries: 1,
|
|
37
|
+
attemptTimeoutMs: 15_000,
|
|
38
|
+
unknownCostPolicy: "reject"
|
|
37
39
|
});
|
|
38
40
|
|
|
41
|
+
const abortController = new AbortController();
|
|
42
|
+
|
|
39
43
|
const result = await gateway.generate({
|
|
40
44
|
primary: { provider: "openai", modelId: "gpt-4o-mini" },
|
|
41
45
|
fallbacks: [{ provider: "ollama", modelId: "llama3.2" }],
|
|
42
46
|
messages: [{ role: "user", content: "Summarize the benefits of fallback routing." }],
|
|
43
|
-
routingMode: "balanced"
|
|
47
|
+
routingMode: "balanced",
|
|
48
|
+
maxCostPer1kTokens: 0.01,
|
|
49
|
+
abortSignal: abortController.signal
|
|
44
50
|
});
|
|
45
51
|
|
|
46
52
|
console.log(result.text);
|
|
@@ -48,7 +54,17 @@ console.log(result.providerUsed);
|
|
|
48
54
|
console.log(result.attempts);
|
|
49
55
|
```
|
|
50
56
|
|
|
51
|
-
The gateway also supports `streamText()`, `generateObject()`, and `streamObject()`
|
|
57
|
+
The gateway also supports `streamText()`, `generateObject()`, and `streamObject()` through one Core generation loop. A provider is fixed once its stream emits, while a later model step in the same tool loop can still fail over before emitting provider output. Object routes skip incompatible targets before making a provider call: native mode requires `structuredOutput`, prompted mode requires `jsonMode`, and auto mode accepts either capability.
|
|
58
|
+
|
|
59
|
+
## Routing guarantees
|
|
60
|
+
|
|
61
|
+
- Text, object, and agent operations retry eligible failures on the current target and then continue through the ordered fallback targets. Agent routing happens inside one `runAgent()` or `streamAgent()` execution, so a fallback does not restart the agent, duplicate its run, or replay completed tools.
|
|
62
|
+
- Text and object streaming fallback is resolved before the first event is exposed. Agent streams may expose lifecycle events such as `agent-run-start` first, but provider fallback is resolved before the first provider event. Once a provider stream emits an event, an error from that stream is propagated without mixing in another provider's transcript.
|
|
63
|
+
- `attemptTimeoutMs` and the per-provider `attemptTimeoutsMs` do more than reject the gateway promise: they abort a non-streaming provider call or a streaming call that has not produced its first event. A request-level `abortSignal` remains active for the full operation and stops pending retries, backoff, fallback routing, and active streams.
|
|
64
|
+
- `ProviderHTTPError` is classified by its typed HTTP status. Status `408`, `429`, and `5xx` errors are retryable on the same target. Other `4xx` errors are not retried on that target, but an eligible fallback can still handle a provider- or model-specific rejection.
|
|
65
|
+
- When `maxCostPer1kTokens` is set, a target without configured or catalog pricing is rejected by default. Set `unknownCostPolicy: "allow"` on `createGateway()` only when routing to models with unknown cost is acceptable.
|
|
66
|
+
- Requests containing image attachments only route to models that declare `capabilities.vision: true`. The gateway never removes images to make a target appear compatible; if one target cannot accept the original request, it is skipped in favor of a compatible fallback.
|
|
67
|
+
- `scoreTarget(context)` can replace the built-in name-based heuristic with application metrics. It must return a finite number; higher scores route first.
|
|
52
68
|
|
|
53
69
|
For agent workloads, use `runAgent()` or `streamAgent()` to route by both regular model capabilities and agent-specific capabilities such as `supportTier`, `approvalRequests`, or `remoteMcp`.
|
|
54
70
|
|
|
@@ -69,6 +85,12 @@ console.log(agentResult.attempts);
|
|
|
69
85
|
console.log(agentResult.routeDecision);
|
|
70
86
|
```
|
|
71
87
|
|
|
88
|
+
Agent requests also forward the durable Core controls `runId`, `scope`, `idempotencyKey`, `parentRunId`, `policy`, and `toolApprovalPolicy`. Use a durable store plus `idempotencyKey` for effectful production runs.
|
|
89
|
+
|
|
90
|
+
## Migration note
|
|
91
|
+
|
|
92
|
+
`GatewayConfig.groundedAdapters` has been removed because it was not used by any gateway operation. Register provider adapters through `adapters`; `@zhivex-ai/gateway` does not currently expose a grounded-generation route.
|
|
93
|
+
|
|
72
94
|
This package is the SDK-local routing layer. It is not the Zhivex-hosted Gateway API and it is not re-exported from `@zhivex-ai/sdk`.
|
|
73
95
|
|
|
74
96
|
Repository and full documentation:
|
package/dist/compat.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { ModelMessage } from "@zhivex-ai/core";
|
|
2
|
-
import type { GatewayMessage, GatewayModelTarget,
|
|
3
|
-
export declare const supportsVisionInput: (provider: GatewayProviderId, modelId: string) => boolean;
|
|
4
|
-
export declare const stripImagesForUnsupportedModel: (messages: GatewayMessage[], provider: GatewayProviderId, modelId: string) => GatewayMessage[];
|
|
2
|
+
import type { GatewayMessage, GatewayModelTarget, GatewayResponse } from "./types.js";
|
|
5
3
|
export declare const gatewayMessagesToModelMessages: (messages: GatewayMessage[], systemPrompt?: string) => ModelMessage[];
|
|
6
4
|
export declare const createRouteDecision: (mode: GatewayResponse["routeDecision"]["mode"], intent: GatewayResponse["routeDecision"]["intent"], orderedTargets: GatewayModelTarget[]) => GatewayResponse["routeDecision"];
|
|
7
5
|
//# sourceMappingURL=compat.d.ts.map
|
package/dist/compat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,8BAA8B,GACzC,UAAU,cAAc,EAAE,EAC1B,eAAe,MAAM,KACpB,YAAY,EAyBd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAC9C,QAAQ,eAAe,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,EAClD,gBAAgB,kBAAkB,EAAE,KACnC,eAAe,CAAC,eAAe,CAMhC,CAAC"}
|
package/dist/compat.js
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
export const supportsVisionInput = (provider, modelId) => {
|
|
2
|
-
const model = modelId.toLowerCase();
|
|
3
|
-
if (provider === "gemini") {
|
|
4
|
-
return !model.includes("embedding");
|
|
5
|
-
}
|
|
6
|
-
if (provider === "bedrock") {
|
|
7
|
-
return model.includes("nova") || model.includes("claude-3") || model.includes("claude-4");
|
|
8
|
-
}
|
|
9
|
-
return true;
|
|
10
|
-
};
|
|
11
|
-
export const stripImagesForUnsupportedModel = (messages, provider, modelId) => {
|
|
12
|
-
if (supportsVisionInput(provider, modelId)) {
|
|
13
|
-
return messages;
|
|
14
|
-
}
|
|
15
|
-
return messages.map((message) => (message.images?.length ? { ...message, images: [] } : message));
|
|
16
|
-
};
|
|
17
1
|
export const gatewayMessagesToModelMessages = (messages, systemPrompt) => {
|
|
18
2
|
const mappedMessages = [];
|
|
19
3
|
if (systemPrompt) {
|
package/dist/compat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compat.js","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compat.js","sourceRoot":"","sources":["../src/compat.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,QAA0B,EAC1B,YAAqB,EACL,EAAE;IAClB,MAAM,cAAc,GAAmB,EAAE,CAAC;IAE1C,IAAI,YAAY,EAAE,CAAC;QACjB,cAAc,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,cAAc,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE;gBACL,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE;gBACvC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACzC,IAAI,EAAE,OAAgB;oBACtB,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,SAAS,EAAE,KAAK,CAAC,QAAQ;iBAC1B,CAAC,CAAC,IAAI,EAAE,CAAC;aACX;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,IAA8C,EAC9C,MAAkD,EAClD,cAAoC,EACF,EAAE,CAAC,CAAC;IACtC,IAAI;IACJ,MAAM;IACN,cAAc;IACd,UAAU,EAAE,WAAW,IAAI,EAAE;IAC7B,MAAM,EAAE,cAAc,IAAI,cAAc,MAAM,UAAU;CACzD,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ZodTypeAny } from "zod";
|
|
2
2
|
import { type GatewayAgentRequest, type GatewayAgentResponse, type GatewayAgentStreamResult, type GatewayConfig, type GatewayGenerateObjectRequest, type GatewayObjectResponse, type GatewayRequest, type GatewayResponse, type GatewayStreamObjectResult, type GatewayStreamTextResult } from "./types.js";
|
|
3
3
|
export { GatewayError } from "./types.js";
|
|
4
|
-
export type { GatewayAgentRequest, GatewayAgentResponse, GatewayAgentStreamResult, GatewayAttempt, GatewayAttemptReasonCode, GatewayConfig, GatewayGenerateObjectRequest, GatewayImageAttachment, GatewayMessage, GatewayModelTarget, GatewayObjectResponse, GatewayProviderId, GatewayRequest, GatewayResponse, GatewayRouteDecisionReasonCode, GatewayRoutingMode, GatewayStreamObjectResult, GatewayStreamTextResult, GatewayTaskIntent } from "./types.js";
|
|
4
|
+
export type { GatewayAgentRequest, GatewayAgentResponse, GatewayAgentStreamResult, GatewayAttempt, GatewayAttemptReasonCode, GatewayConfig, GatewayGenerateObjectRequest, GatewayImageAttachment, GatewayMessage, GatewayModelTarget, GatewayObjectResponse, GatewayProviderId, GatewayRequest, GatewayResponse, GatewayRouteDecisionReasonCode, GatewayRoutingMode, GatewayRoutingScoreContext, GatewayStreamObjectResult, GatewayStreamTextResult, GatewayTaskIntent, GatewayUnknownCostPolicy } from "./types.js";
|
|
5
5
|
export declare const createGateway: (config: GatewayConfig) => {
|
|
6
6
|
generate(request: GatewayRequest): Promise<GatewayResponse>;
|
|
7
7
|
streamText(request: GatewayRequest): GatewayStreamTextResult;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAGtC,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAG7B,KAAK,aAAa,EAClB,KAAK,4BAA4B,EAEjC,KAAK,qBAAqB,EAE1B,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAE7B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,4BAA4B,EAC5B,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,8BAA8B,EAC9B,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAslBpB,eAAO,MAAM,aAAa,GAAI,QAAQ,aAAa;sBAuXvB,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;wBAa7C,cAAc,GAAG,uBAAuB;mBAuBvC,OAAO,SAAS,UAAU,WACpC,4BAA4B,CAAC,OAAO,CAAC,GAC7C,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;iBAyB7B,OAAO,SAAS,UAAU,WAC5B,4BAA4B,CAAC,OAAO,CAAC,GAC7C,yBAAyB,CAAC,OAAO,CAAC;sBAkCb,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;yBAkDtD,mBAAmB,GAAG,wBAAwB;CA0DtE,CAAC"}
|