@dbx-tools/appkit-model-gateway 0.9.36

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.
Files changed (44) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +63 -0
  3. package/index.ts +28 -0
  4. package/lib/index.d.ts +24 -0
  5. package/lib/index.js +21 -0
  6. package/lib/scripts/copy-manifest.d.ts +1 -0
  7. package/lib/scripts/copy-manifest.js +14 -0
  8. package/lib/src/gateway.d.ts +29 -0
  9. package/lib/src/gateway.js +127 -0
  10. package/lib/src/manifest.json +13 -0
  11. package/lib/src/models.d.ts +10 -0
  12. package/lib/src/models.js +119 -0
  13. package/lib/src/plugin.d.ts +32 -0
  14. package/lib/src/plugin.js +70 -0
  15. package/lib/src/protocols/decode.d.ts +17 -0
  16. package/lib/src/protocols/decode.js +262 -0
  17. package/lib/src/protocols/encode.d.ts +18 -0
  18. package/lib/src/protocols/encode.js +498 -0
  19. package/lib/src/reasoning-adapt.d.ts +27 -0
  20. package/lib/src/reasoning-adapt.js +61 -0
  21. package/lib/src/registry.d.ts +32 -0
  22. package/lib/src/registry.js +167 -0
  23. package/lib/src/router.d.ts +18 -0
  24. package/lib/src/router.js +139 -0
  25. package/lib/src/routes.d.ts +14 -0
  26. package/lib/src/routes.js +158 -0
  27. package/lib/src/translation.d.ts +8 -0
  28. package/lib/src/translation.js +156 -0
  29. package/lib/src/transport.d.ts +19 -0
  30. package/lib/src/transport.js +168 -0
  31. package/lib/tsconfig.tsbuildinfo +1 -0
  32. package/package.json +150 -0
  33. package/src/gateway.ts +167 -0
  34. package/src/manifest.json +13 -0
  35. package/src/models.ts +152 -0
  36. package/src/plugin.ts +95 -0
  37. package/src/protocols/decode.ts +281 -0
  38. package/src/protocols/encode.ts +515 -0
  39. package/src/reasoning-adapt.ts +87 -0
  40. package/src/registry.ts +225 -0
  41. package/src/router.ts +174 -0
  42. package/src/routes.ts +181 -0
  43. package/src/translation.ts +178 -0
  44. package/src/transport.ts +182 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * OpenAI and Codex model-list payloads derived from the live registry.
3
+ *
4
+ * @module
5
+ */
6
+ import { isChatClass } from "@dbx-tools/model/classes";
7
+ const CODEX_BASE_INSTRUCTIONS = "You are a coding agent. Follow the user's instructions and use the available tools to work in the current repository.";
8
+ const REASONING_DESCRIPTIONS = {
9
+ none: "Disable explicit reasoning",
10
+ minimal: "Use the smallest available reasoning budget",
11
+ low: "Use a low reasoning budget",
12
+ medium: "Use a medium reasoning budget",
13
+ high: "Use a high reasoning budget",
14
+ xhigh: "Use an extra-high reasoning budget",
15
+ max: "Use the largest available reasoning budget",
16
+ };
17
+ export function listModelsPayload(targets, includeCodex) {
18
+ const available = targets
19
+ .filter((target) => target.endpoint?.status?.deprecated !== true)
20
+ .filter((target) => !includeCodex || hasChatClass(target))
21
+ .slice()
22
+ .sort(compareCatalogueTargets);
23
+ if (includeCodex) {
24
+ return {
25
+ models: available.map((target, index) => codexModel(target, index + 1)),
26
+ };
27
+ }
28
+ return {
29
+ object: "list",
30
+ data: available.map(openAiModel),
31
+ };
32
+ }
33
+ function openAiModel(target) {
34
+ return {
35
+ id: target.id,
36
+ object: "model",
37
+ created: 0,
38
+ owned_by: "databricks",
39
+ name: target.displayName,
40
+ task: target.endpoint?.task,
41
+ status: target.endpoint?.status ?? { deprecated: false },
42
+ capabilities: {
43
+ tools: target.capabilities.tools,
44
+ reasoning: target.reasoningEfforts,
45
+ responses: target.capabilities.responses,
46
+ open_responses: target.capabilities.openResponses,
47
+ anthropic: target.capabilities.anthropic,
48
+ embeddings: target.capabilities.embeddings,
49
+ ai_gateway_codex: target.capabilities.aiGatewayCodex,
50
+ streaming: target.capabilities.streaming,
51
+ },
52
+ };
53
+ }
54
+ function codexModel(target, priority) {
55
+ const model = target.capabilities.aiGatewayCodex && target.modelServiceName
56
+ ? target.modelServiceName
57
+ : target.id;
58
+ const efforts = target.reasoningEfforts;
59
+ return {
60
+ slug: `databricks/${model}`,
61
+ display_name: target.displayName,
62
+ description: target.endpoint?.description ?? "Databricks model service",
63
+ base_instructions: CODEX_BASE_INSTRUCTIONS,
64
+ status: target.endpoint?.status ?? { deprecated: false },
65
+ supported_reasoning_levels: efforts.map((effort) => ({
66
+ effort,
67
+ description: REASONING_DESCRIPTIONS[effort] ?? `Use the ${effort} reasoning budget`,
68
+ })),
69
+ ...(efforts.length > 0
70
+ ? { default_reasoning_level: efforts.includes("medium") ? "medium" : efforts[0] }
71
+ : {}),
72
+ shell_type: "unified_exec",
73
+ visibility: "list",
74
+ supported_in_api: true,
75
+ priority,
76
+ availability_nux: null,
77
+ upgrade: null,
78
+ support_verbosity: false,
79
+ default_verbosity: null,
80
+ apply_patch_tool_type: target.capabilities.customTools ? "freeform" : null,
81
+ truncation_policy: { mode: "tokens", limit: 128_000 },
82
+ context_window: null,
83
+ experimental_supported_tools: [],
84
+ input_modalities: ["text"],
85
+ web_search_tool_type: "text",
86
+ supports_search_tool: false,
87
+ supports_image_detail_original: false,
88
+ };
89
+ }
90
+ /**
91
+ * Order listed models by family A-Z, then display name. Targets with no family
92
+ * follow every named family, still sorted by display name.
93
+ */
94
+ function compareCatalogueTargets(left, right) {
95
+ const leftFamily = catalogueFamily(left);
96
+ const rightFamily = catalogueFamily(right);
97
+ if (Boolean(leftFamily) !== Boolean(rightFamily))
98
+ return leftFamily ? -1 : 1;
99
+ if (leftFamily && rightFamily) {
100
+ const familyOrder = leftFamily.localeCompare(rightFamily, undefined, { sensitivity: "base" });
101
+ if (familyOrder !== 0)
102
+ return familyOrder;
103
+ }
104
+ return catalogueName(left).localeCompare(catalogueName(right), undefined, {
105
+ sensitivity: "base",
106
+ });
107
+ }
108
+ function catalogueFamily(target) {
109
+ const family = target.family?.trim() || target.endpoint?.family?.trim();
110
+ return family || undefined;
111
+ }
112
+ function catalogueName(target) {
113
+ return target.displayName.trim() || target.id;
114
+ }
115
+ function hasChatClass(target) {
116
+ const modelClass = target.endpoint?.class;
117
+ return modelClass !== undefined && isChatClass(modelClass);
118
+ }
119
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBVXZELE1BQU0sdUJBQXVCLEdBQzNCLHVIQUF1SCxDQUFDO0FBRTFILE1BQU0sc0JBQXNCLEdBQXFDO0lBQy9ELElBQUksRUFBRSw0QkFBNEI7SUFDbEMsT0FBTyxFQUFFLDZDQUE2QztJQUN0RCxHQUFHLEVBQUUsNEJBQTRCO0lBQ2pDLE1BQU0sRUFBRSwrQkFBK0I7SUFDdkMsSUFBSSxFQUFFLDZCQUE2QjtJQUNuQyxLQUFLLEVBQUUsb0NBQW9DO0lBQzNDLEdBQUcsRUFBRSw0Q0FBNEM7Q0FDbEQsQ0FBQztBQWVGLE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsT0FBK0IsRUFDL0IsWUFBcUI7SUFFckIsTUFBTSxTQUFTLEdBQUcsT0FBTztTQUN0QixNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFVBQVUsS0FBSyxJQUFJLENBQUM7U0FDaEUsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLFlBQVksSUFBSSxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDekQsS0FBSyxFQUFFO1NBQ1AsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDakMsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqQixPQUFPO1lBQ0wsTUFBTSxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztTQUN4RSxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU87UUFDTCxNQUFNLEVBQUUsTUFBTTtRQUNkLElBQUksRUFB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UyxhQUFhLENBQUMsTUFBbUI7SUFDeEMsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFLENBQUM7QUFDaEQsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE1BQW1CO0lBQ3ZDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDO0lBQzFDLE9BQU8sVUFBVSxLQUFLLFNBQVMsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDN0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3BlbkFJIGFuZCBDb2RleCBtb2RlbC1saXN0IHBheWxvYWRzIGRlcml2ZWQgZnJvbSB0aGUgbGl2ZSByZWdpc3RyeS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgaXNDaGF0Q2xhc3MgfSBmcm9tIFwiQGRieC10b29scy9tb2RlbC9jbGFzc2VzXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvZGV4TW9kZWwsXG4gIENvZGV4TW9kZWxMaXN0UmVzcG9uc2UsXG4gIE1vZGVsTGlzdFJlc3BvbnNlLFxuICBNb2RlbFRhcmdldCxcbiAgT3BlbkFJTW9kZWwsXG4gIE9wZW5BSU1vZGVsTGlzdFJlc3BvbnNlLFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuXG5jb25zdCBDT0RFWF9CQVNFX0lOU1RSVUNUSU9OUyA9XG4gIFwiWW91IGFyZSBhIGNvZGluZyBhZ2VudC4gRm9sbG93IHRoZSB1c2VyJ3MgaW5zdHJ1Y3Rpb25zIGFuZCB1c2UgdGhlIGF2YWlsYWJsZSB0b29scyB0byB3b3JrIGluIHRoZSBjdXJyZW50IHJlcG9zaXRvcnkuXCI7XG5cbmNvbnN0IFJFQVNPTklOR19ERVNDUklQVElPTlM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+ID0ge1xuICBub25lOiBcIkRpc2FibGUgZXhwbGljaXQgcmVhc29uaW5nXCIsXG4gIG1pbmltYWw6IFwiVXNlIHRoZSBzbWFsbGVzdCBhdmFpbGFibGUgcmVhc29uaW5nIGJ1ZGdldFwiLFxuICBsb3c6IFwiVXNlIGEgbG93IHJlYXNvbmluZyBidWRnZXRcIixcbiAgbWVkaXVtOiBcIlVzZSBhIG1lZGl1bSByZWFzb25pbmcgYnVkZ2V0XCIsXG4gIGhpZ2g6IFwiVXNlIGEgaGlnaCByZWFzb25pbmcgYnVkZ2V0XCIsXG4gIHhoaWdoOiBcIlVzZSBhbiBleHRyYS1oaWdoIHJlYXNvbmluZyBidWRnZXRcIixcbiAgbWF4OiBcIlVzZSB0aGUgbGFyZ2VzdCBhdmFpbGFibGUgcmVhc29uaW5nIGJ1ZGdldFwiLFxufTtcblxuLyoqIEJ1aWxkIHRoZSBjb21iaW5lZCBPcGVuQUkgYW5kIG9wdGlvbmFsIENvZGV4IG1vZGVsIGNhdGFsb2d1ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiB0cnVlLFxuKTogQ29kZXhNb2RlbExpc3RSZXNwb25zZTtcbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiBmYWxzZSxcbik6IE9wZW5BSU1vZGVsTGlzdFJlc3BvbnNlO1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RNb2RlbHNQYXlsb2FkKFxuICB0YXJnZXRzOiByZWFkb25seSBNb2RlbFRhcmdldFtdLFxuICBpbmNsdWRlQ29kZXg6IGJvb2xlYW4sXG4pOiBNb2RlbExpc3RSZXNwb25zZTtcbmV4cG9ydCBmdW5jdGlvbiBsaXN0TW9kZWxzUGF5bG9hZChcbiAgdGFyZ2V0czogcmVhZG9ubHkgTW9kZWxUYXJnZXRbXSxcbiAgaW5jbHVkZUNvZGV4OiBib29sZWFuLFxuKTogTW9kZWxMaXN0UmVzcG9uc2Uge1xuICBjb25zdCBhdmFpbGFibGUgPSB0YXJnZXRzXG4gICAgLmZpbHRlcigodGFyZ2V0KSA9PiB0YXJnZXQuZW5kcG9pbnQ/LnN0YXR1cz8uZGVwcmVjYXRlZCAhPT0gdHJ1ZSlcbiAgICAuZmlsdGVyKCh0YXJnZXQpID0+ICFpbmNsdWRlQ29kZXggfHwgaGFzQ2hhdENsYXNzKHRhcmdldCkpXG4gICAgLnNsaWNlKClcbiAgICAuc29ydChjb21wYXJlQ2F0YWxvZ3VlVGFyZ2V0cyk7XG4gIGlmIChpbmNsdWRlQ29kZXgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kZWxzOiBhdmFpbGFibGUubWFwKCh0YXJnZXQsIGluZGV4KSA9PiBjb2RleE1vZGVsKHRhcmdldCwgaW5kZXggKyAxKSksXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIG9iamVjdDogXCJsaXN0XCIsXG4gICAgZGF0YTogYXZhaWxhYmxlLm1hcChvcGVuQWlNb2RlbCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIG9wZW5BaU1vZGVsKHRhcmdldDogTW9kZWxUYXJnZXQpOiBPcGVuQUlNb2RlbCB7XG4gIHJldHVybiB7XG4gICAgaWQ6IHRhcmdldC5pZCxcbiAgICBvYmplY3Q6IFwibW9kZWxcIixcbiAgICBjcmVhdGVkOiAwLFxuICAgIG93bmVkX2J5OiBcImRhdGFicmlja3NcIixcbiAgICBuYW1lOiB0YXJnZXQuZGlzcGxheU5hbWUsXG4gICAgdGFzazogdGFyZ2V0LmVuZHBvaW50Py50YXNrLFxuICAgIHN0YXR1czogdGFyZ2V0LmVuZHBvaW50Py5zdGF0dXMgPz8geyBkZXByZWNhdGVkOiBmYWxzZSB9LFxuICAgIGNhcGFiaWxpdGllczoge1xuICAgICAgdG9vbHM6IHRhcmdldC5jYXBhYmlsaXRpZXMudG9vbHMsXG4gICAgICByZWFzb25pbmc6IHRhcmdldC5yZWFzb25pbmdFZmZvcnRzLFxuICAgICAgcmVzcG9uc2VzOiB0YXJnZXQuY2FwYWJpbGl0aWVzLnJlc3BvbnNlcyxcbiAgICAgIG9wZW5fcmVzcG9uc2VzOiB0YXJnZXQuY2FwYWJpbGl0aWVzLm9wZW5SZXNwb25zZXMsXG4gICAgICBhbnRocm9waWM6IHRhcmdldC5jYXBhYmlsaXRpZXMuYW50aHJvcGljLFxuICAgICAgZW1iZWRkaW5nczogdGFyZ2V0LmNhcGFiaWxpdGllcy5lbWJlZGRpbmdzLFxuICAgICAgYWlfZ2F0ZXdheV9jb2RleDogdGFyZ2V0LmNhcGFiaWxpdGllcy5haUdhdGV3YXlDb2RleCxcbiAgICAgIHN0cmVhbWluZzogdGFyZ2V0LmNhcGFiaWxpdGllcy5zdHJlYW1pbmcsXG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29kZXhNb2RlbCh0YXJnZXQ6IE1vZGVsVGFyZ2V0LCBwcmlvcml0eTogbnVtYmVyKTogQ29kZXhNb2RlbCB7XG4gIGNvbnN0IG1vZGVsID1cbiAgICB0YXJnZXQuY2FwYWJpbGl0aWVzLmFpR2F0ZXdheUNvZGV4ICYmIHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lXG4gICAgICA/IHRhcmdldC5tb2RlbFNlcnZpY2VOYW1lXG4gICAgICA6IHRhcmdldC5pZDtcbiAgY29uc3QgZWZmb3J0cyA9IHRhcmdldC5yZWFzb25pbmdFZmZvcnRzO1xuICByZXR1cm4ge1xuICAgIHNsdWc6IGBkYXRhYnJpY2tzLyR7bW9kZWx9YCxcbiAgICBkaXNwbGF5X25hbWU6IHRhcmdldC5kaXNwbGF5TmFtZSxcbiAgICBkZXNjcmlwdGlvbjogdGFyZ2V0LmVuZHBvaW50Py5kZXNjcmlwdGlvbiA/PyBcIkRhdGFicmlja3MgbW9kZWwgc2VydmljZVwiLFxuICAgIGJhc2VfaW5zdHJ1Y3Rpb25zOiBDT0RFWF9CQVNFX0lOU1RSVUNUSU9OUyxcbiAgICBzdGF0dXM6IHRhcmdldC5lbmRwb2ludD8uc3RhdHVzID8/IHsgZGVwcmVjYXRlZDogZmFsc2UgfSxcbiAgICBzdXBwb3J0ZWRfcmVhc29uaW5nX2xldmVsczogZWZmb3J0cy5tYXAoKGVmZm9ydCkgPT4gKHtcbiAgICAgIGVmZm9ydCxcbiAgICAgIGRlc2NyaXB0aW9uOiBSRUFTT05JTkdfREVTQ1JJUFRJT05TW2VmZm9ydF0gPz8gYFVzZSB0aGUgJHtlZmZvcnR9IHJlYXNvbmluZyBidWRnZXRgLFxuICAgIH0pKSxcbiAgICAuLi4oZWZmb3J0cy5sZW5ndGggPiAwXG4gICAgICA/IHsgZGVmYXVsdF9yZWFzb25pbmdfbGV2ZWw6IGVmZm9ydHMuaW5jbHVkZXMoXCJtZWRpdW1cIikgPyBcIm1lZGl1bVwiIDogZWZmb3J0c1swXSB9XG4gICAgICA6IHt9KSxcbiAgICBzaGVsbF90eXBlOiBcInVuaWZpZWRfZXhlY1wiLFxuICAgIHZpc2liaWxpdHk6IFwibGlzdFwiLFxuICAgIHN1cHBvcnRlZF9pbl9hcGk6IHRydWUsXG4gICAgcHJpb3JpdHksXG4gICAgYXZhaWxhYmlsaXR5X251eDogbnVsbCxcbiAgICB1cGdyYWRlOiBudWxsLFxuICAgIHN1cHBvcnRfdmVyYm9zaXR5OiBmYWxzZSxcbiAgICBkZWZhdWx0X3ZlcmJvc2l0eTogbnVsbCxcbiAgICBhcHBseV9wYXRjaF90b29sX3R5cGU6IHRhcmdldC5jYXBhYmlsaXRpZXMuY3VzdG9tVG9vbHMgPyBcImZyZWVmb3JtXCIgOiBudWxsLFxuICAgIHRydW5jYXRpb25fcG9saWN5OiB7IG1vZGU6IFwidG9rZW5zXCIsIGxpbWl0OiAxMjhfMDAwIH0sXG4gICAgY29udGV4dF93aW5kb3c6IG51bGwsXG4gICAgZXhwZXJpbWVudGFsX3N1cHBvcnRlZF90b29sczogW10sXG4gICAgaW5wdXRfbW9kYWxpdGllczogW1widGV4dFwiXSxcbiAgICB3ZWJfc2VhcmNoX3Rvb2xfdHlwZTogXCJ0ZXh0XCIsXG4gICAgc3VwcG9ydHNfc2VhcmNoX3Rvb2w6IGZhbHNlLFxuICAgIHN1cHBvcnRzX2ltYWdlX2RldGFpbF9vcmlnaW5hbDogZmFsc2UsXG4gIH07XG59XG5cbi8qKlxuICogT3JkZXIgbGlzdGVkIG1vZGVscyBieSBmYW1pbHkgQS1aLCB0aGVuIGRpc3BsYXkgbmFtZS4gVGFyZ2V0cyB3aXRoIG5vIGZhbWlseVxuICogZm9sbG93IGV2ZXJ5IG5hbWVkIGZhbWlseSwgc3RpbGwgc29ydGVkIGJ5IGRpc3BsYXkgbmFtZS5cbiAqL1xuZnVuY3Rpb24gY29tcGFyZUNhdGFsb2d1ZVRhcmdldHMobGVmdDogTW9kZWxUYXJnZXQsIHJpZ2h0OiBNb2RlbFRhcmdldCk6IG51bWJlciB7XG4gIGNvbnN0IGxlZnRGYW1pbHkgPSBjYXRhbG9ndWVGYW1pbHkobGVmdCk7XG4gIGNvbnN0IHJpZ2h0RmFtaWx5ID0gY2F0YWxvZ3VlRmFtaWx5KHJpZ2h0KTtcbiAgaWYgKEJvb2xlYW4obGVmdEZhbWlseSkgIT09IEJvb2xlYW4ocmlnaHRGYW1pbHkpKSByZXR1cm4gbGVmdEZhbWlseSA/IC0xIDogMTtcbiAgaWYgKGxlZnRGYW1pbHkgJiYgcmlnaHRGYW1pbHkpIHtcbiAgICBjb25zdCBmYW1pbHlPcmRlciA9IGxlZnRGYW1pbHkubG9jYWxlQ29tcGFyZShyaWdodEZhbWlseSwgdW5kZWZpbmVkLCB7IHNlbnNpdGl2aXR5OiBcImJhc2VcIiB9KTtcbiAgICBpZiAoZmFtaWx5T3JkZXIgIT09IDApIHJldHVybiBmYW1pbHlPcmRlcjtcbiAgfVxuICByZXR1cm4gY2F0YWxvZ3VlTmFtZShsZWZ0KS5sb2NhbGVDb21wYXJlKGNhdGFsb2d1ZU5hbWUocmlnaHQpLCB1bmRlZmluZWQsIHtcbiAgICBzZW5zaXRpdml0eTogXCJiYXNlXCIsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBjYXRhbG9ndWVGYW1pbHkodGFyZ2V0OiBNb2RlbFRhcmdldCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGZhbWlseSA9IHRhcmdldC5mYW1pbHk/LnRyaW0oKSB8fCB0YXJnZXQuZW5kcG9pbnQ/LmZhbWlseT8udHJpbSgpO1xuICByZXR1cm4gZmFtaWx5IHx8IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gY2F0YWxvZ3VlTmFtZSh0YXJnZXQ6IE1vZGVsVGFyZ2V0KTogc3RyaW5nIHtcbiAgcmV0dXJuIHRhcmdldC5kaXNwbGF5TmFtZS50cmltKCkgfHwgdGFyZ2V0LmlkO1xufVxuXG5mdW5jdGlvbiBoYXNDaGF0Q2xhc3ModGFyZ2V0OiBNb2RlbFRhcmdldCk6IGJvb2xlYW4ge1xuICBjb25zdCBtb2RlbENsYXNzID0gdGFyZ2V0LmVuZHBvaW50Py5jbGFzcztcbiAgcmV0dXJuIG1vZGVsQ2xhc3MgIT09IHVuZGVmaW5lZCAmJiBpc0NoYXRDbGFzcyhtb2RlbENsYXNzKTtcbn1cbiJdfQ==
@@ -0,0 +1,32 @@
1
+ /**
2
+ * AppKit model-gateway plugin.
3
+ *
4
+ * @module
5
+ */
6
+ import { Plugin, type BasePluginConfig, type IAppRouter } from "@databricks/appkit";
7
+ import type { ClientProtocol } from "@dbx-tools/shared-model-gateway";
8
+ import type express from "express";
9
+ import { type ModelGatewayOptions } from "./gateway.ts";
10
+ /** AppKit configuration for the model-gateway plugin. */
11
+ export interface ModelGatewayPluginConfig extends BasePluginConfig, ModelGatewayOptions {
12
+ }
13
+ /** AppKit plugin exposing dynamic model discovery and compatibility routes. */
14
+ export declare class ModelGatewayPlugin extends Plugin<ModelGatewayPluginConfig> {
15
+ static manifest: import("@databricks/appkit").PluginManifest<"modelGateway">;
16
+ private readonly gateway;
17
+ constructor(config?: ModelGatewayPluginConfig);
18
+ injectRoutes(router: IAppRouter): void;
19
+ /** Send the active principal's model catalogue. */
20
+ models(request: express.Request, response: express.Response): Promise<void>;
21
+ /** Execute one compatibility request in the active AppKit identity scope. */
22
+ inference(protocol: ClientProtocol, request: express.Request, response: express.Response): Promise<void>;
23
+ /** Refresh the active principal's model catalogue. */
24
+ refresh(): Promise<void>;
25
+ exports(): {
26
+ models: (request: express.Request, response: express.Response) => Promise<void>;
27
+ inference: (protocol: ClientProtocol, request: express.Request, response: express.Response) => Promise<void>;
28
+ refresh: () => Promise<void>;
29
+ };
30
+ }
31
+ /** AppKit plugin factory for the Databricks model gateway. */
32
+ export declare const modelGateway: import("@databricks/appkit").ToPlugin<typeof ModelGatewayPlugin, ModelGatewayPluginConfig | undefined, "modelGateway">;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * AppKit model-gateway plugin.
3
+ *
4
+ * @module
5
+ */
6
+ import { defineManifest, Plugin, toPlugin, } from "@databricks/appkit";
7
+ import { ModelGateway } from "./gateway.js";
8
+ import manifest from "./manifest.json" with { type: "json" };
9
+ import { sendHealth, sendInference, sendModels } from "./routes.js";
10
+ /** AppKit plugin exposing dynamic model discovery and compatibility routes. */
11
+ export class ModelGatewayPlugin extends Plugin {
12
+ static manifest = defineManifest(manifest);
13
+ gateway;
14
+ constructor(config = {}) {
15
+ super(config);
16
+ this.gateway = new ModelGateway({
17
+ ...(config.cacheTtlMs !== undefined ? { cacheTtlMs: config.cacheTtlMs } : {}),
18
+ ...(config.overrides ? { overrides: config.overrides } : {}),
19
+ });
20
+ }
21
+ injectRoutes(router) {
22
+ this.route(router, {
23
+ name: "health",
24
+ method: "get",
25
+ path: "/healthz",
26
+ handler: async (_request, response) => sendHealth(response),
27
+ });
28
+ this.route(router, {
29
+ name: "models",
30
+ method: "get",
31
+ path: "/v1/models",
32
+ handler: (request, response) => this.models(request, response),
33
+ });
34
+ for (const [name, path, protocol] of [
35
+ ["chatCompletions", "/v1/chat/completions", "openai-chat"],
36
+ ["responses", "/v1/responses", "openai-responses"],
37
+ ["messages", "/v1/messages", "anthropic-messages"],
38
+ ["embeddings", "/v1/embeddings", "openai-embeddings"],
39
+ ]) {
40
+ this.route(router, {
41
+ name,
42
+ method: "post",
43
+ path,
44
+ handler: (request, response) => this.inference(protocol, request, response),
45
+ });
46
+ }
47
+ }
48
+ /** Send the active principal's model catalogue. */
49
+ async models(request, response) {
50
+ await sendModels(this.gateway, request, response);
51
+ }
52
+ /** Execute one compatibility request in the active AppKit identity scope. */
53
+ async inference(protocol, request, response) {
54
+ await sendInference(this.gateway, protocol, request, response);
55
+ }
56
+ /** Refresh the active principal's model catalogue. */
57
+ async refresh() {
58
+ await this.gateway.refresh();
59
+ }
60
+ exports() {
61
+ return {
62
+ models: this.models,
63
+ inference: this.inference,
64
+ refresh: this.refresh,
65
+ };
66
+ }
67
+ }
68
+ /** AppKit plugin factory for the Databricks model gateway. */
69
+ export const modelGateway = toPlugin(ModelGatewayPlugin);
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUNMLGNBQWMsRUFDZCxNQUFNLEVBQ04sUUFBUSxHQUdULE1BQU0sb0JBQW9CLENBQUM7QUFJNUIsT0FBTyxFQUFFLFlBQVksRUFBNEIsTUFBTSxjQUFjLENBQUM7QUFDdEUsT0FBTyxRQUFRLE1BQU0saUJBQWlCLENBQUMsT0FBTyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBS3BFLCtFQUErRTtBQUMvRSxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsTUFBZ0M7SUFDdEUsTUFBTSxDQUFDLFFBQVEsR0FBRyxjQUFjLENBQWlCLFFBQVEsQ0FBQyxDQUFDO0lBRTFDLE9BQU8sQ0FBZTtJQUV2QyxZQUFZLFNBQW1DLEVBQUU7UUFDL0MsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2QsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksQ0FBQztZQUM5QixHQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdFLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUM3RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVEsWUFBWSxDQUFDLE1BQWtCO1FBQ3RDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQ2pCLElBQUksRUFBRSxRQUFRO1lBQ2QsTUFBTSxFQUFFLEtBQUs7WUFDYixJQUFJLEVBQUUsVUFBVTtZQUNoQixPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDNUQsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUU7WUFDakIsSUFBSSxFQUFFLFFBQVE7WUFDZCxNQUFNLEVBQUUsS0FBSztZQUNiLElBQUksRUFBRSxZQUFZO1lBQ2xCLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQztTQUMvRCxDQUFDLENBQUM7UUFDSCxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO1lBQ25DLENBQUMsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsYUFBYSxDQUFDO1lBQzFELENBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsQ0FBQztZQUNsRCxDQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsb0JBQW9CLENBQUM7WUFDbEQsQ0FBQyxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLENBQUM7U0FDN0MsRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pCLElBQUk7Z0JBQ0osTUFBTSxFQUFFLE1BQU07Z0JBQ2QsSUFBSTtnQkFDSixPQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDO2FBQzVFLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsbURBQW1EO0lBQ25ELEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBd0IsRUFBRSxRQUEwQjtRQUMvRCxNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsNkVBQTZFO0lBQzdFLEtBQUssQ0FBQyxTQUFTLENBQ2IsUUFBd0IsRUFDeEIsT0FBd0IsRUFDeEIsUUFBMEI7UUFFMUIsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsS0FBSyxDQUFDLE9BQU87UUFDWCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVRLE9BQU87UUFDZCxPQUFPO1lBQ0wsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87U0FDdEIsQ0FBQztJQUNKLENBQUM7O0FBR0gsOERBQThEO0FBQzlELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQXBwS2l0IG1vZGVsLWdhdGV3YXkgcGx1Z2luLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQge1xuICBkZWZpbmVNYW5pZmVzdCxcbiAgUGx1Z2luLFxuICB0b1BsdWdpbixcbiAgdHlwZSBCYXNlUGx1Z2luQ29uZmlnLFxuICB0eXBlIElBcHBSb3V0ZXIsXG59IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB0eXBlIHsgQ2xpZW50UHJvdG9jb2wgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuaW1wb3J0IHR5cGUgZXhwcmVzcyBmcm9tIFwiZXhwcmVzc1wiO1xuXG5pbXBvcnQgeyBNb2RlbEdhdGV3YXksIHR5cGUgTW9kZWxHYXRld2F5T3B0aW9ucyB9IGZyb20gXCIuL2dhdGV3YXkudHNcIjtcbmltcG9ydCBtYW5pZmVzdCBmcm9tIFwiLi9tYW5pZmVzdC5qc29uXCIgd2l0aCB7IHR5cGU6IFwianNvblwiIH07XG5pbXBvcnQgeyBzZW5kSGVhbHRoLCBzZW5kSW5mZXJlbmNlLCBzZW5kTW9kZWxzIH0gZnJvbSBcIi4vcm91dGVzLnRzXCI7XG5cbi8qKiBBcHBLaXQgY29uZmlndXJhdGlvbiBmb3IgdGhlIG1vZGVsLWdhdGV3YXkgcGx1Z2luLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbEdhdGV3YXlQbHVnaW5Db25maWcgZXh0ZW5kcyBCYXNlUGx1Z2luQ29uZmlnLCBNb2RlbEdhdGV3YXlPcHRpb25zIHt9XG5cbi8qKiBBcHBLaXQgcGx1Z2luIGV4cG9zaW5nIGR5bmFtaWMgbW9kZWwgZGlzY292ZXJ5IGFuZCBjb21wYXRpYmlsaXR5IHJvdXRlcy4gKi9cbmV4cG9ydCBjbGFzcyBNb2RlbEdhdGV3YXlQbHVnaW4gZXh0ZW5kcyBQbHVnaW48TW9kZWxHYXRld2F5UGx1Z2luQ29uZmlnPiB7XG4gIHN0YXRpYyBtYW5pZmVzdCA9IGRlZmluZU1hbmlmZXN0PFwibW9kZWxHYXRld2F5XCI+KG1hbmlmZXN0KTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGdhdGV3YXk6IE1vZGVsR2F0ZXdheTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IE1vZGVsR2F0ZXdheVBsdWdpbkNvbmZpZyA9IHt9KSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgICB0aGlzLmdhdGV3YXkgPSBuZXcgTW9kZWxHYXRld2F5KHtcbiAgICAgIC4uLihjb25maWcuY2FjaGVUdGxNcyAhPT0gdW5kZWZpbmVkID8geyBjYWNoZVR0bE1zOiBjb25maWcuY2FjaGVUdGxNcyB9IDoge30pLFxuICAgICAgLi4uKGNvbmZpZy5vdmVycmlkZXMgPyB7IG92ZXJyaWRlczogY29uZmlnLm92ZXJyaWRlcyB9IDoge30pLFxuICAgIH0pO1xuICB9XG5cbiAgb3ZlcnJpZGUgaW5qZWN0Um91dGVzKHJvdXRlcjogSUFwcFJvdXRlcik6IHZvaWQge1xuICAgIHRoaXMucm91dGUocm91dGVyLCB7XG4gICAgICBuYW1lOiBcImhlYWx0aFwiLFxuICAgICAgbWV0aG9kOiBcImdldFwiLFxuICAgICAgcGF0aDogXCIvaGVhbHRoelwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKF9yZXF1ZXN0LCByZXNwb25zZSkgPT4gc2VuZEhlYWx0aChyZXNwb25zZSksXG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZShyb3V0ZXIsIHtcbiAgICAgIG5hbWU6IFwibW9kZWxzXCIsXG4gICAgICBtZXRob2Q6IFwiZ2V0XCIsXG4gICAgICBwYXRoOiBcIi92MS9tb2RlbHNcIixcbiAgICAgIGhhbmRsZXI6IChyZXF1ZXN0LCByZXNwb25zZSkgPT4gdGhpcy5tb2RlbHMocmVxdWVzdCwgcmVzcG9uc2UpLFxuICAgIH0pO1xuICAgIGZvciAoY29uc3QgW25hbWUsIHBhdGgsIHByb3RvY29sXSBvZiBbXG4gICAgICBbXCJjaGF0Q29tcGxldGlvbnNcIiwgXCIvdjEvY2hhdC9jb21wbGV0aW9uc1wiLCBcIm9wZW5haS1jaGF0XCJdLFxuICAgICAgW1wicmVzcG9uc2VzXCIsIFwiL3YxL3Jlc3BvbnNlc1wiLCBcIm9wZW5haS1yZXNwb25zZXNcIl0sXG4gICAgICBbXCJtZXNzYWdlc1wiLCBcIi92MS9tZXNzYWdlc1wiLCBcImFudGhyb3BpYy1tZXNzYWdlc1wiXSxcbiAgICAgIFtcImVtYmVkZGluZ3NcIiwgXCIvdjEvZW1iZWRkaW5nc1wiLCBcIm9wZW5haS1lbWJlZGRpbmdzXCJdLFxuICAgIF0gYXMgY29uc3QpIHtcbiAgICAgIHRoaXMucm91dGUocm91dGVyLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIG1ldGhvZDogXCJwb3N0XCIsXG4gICAgICAgIHBhdGgsXG4gICAgICAgIGhhbmRsZXI6IChyZXF1ZXN0LCByZXNwb25zZSkgPT4gdGhpcy5pbmZlcmVuY2UocHJvdG9jb2wsIHJlcXVlc3QsIHJlc3BvbnNlKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZW5kIHRoZSBhY3RpdmUgcHJpbmNpcGFsJ3MgbW9kZWwgY2F0YWxvZ3VlLiAqL1xuICBhc3luYyBtb2RlbHMocmVxdWVzdDogZXhwcmVzcy5SZXF1ZXN0LCByZXNwb25zZTogZXhwcmVzcy5SZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHNlbmRNb2RlbHModGhpcy5nYXRld2F5LCByZXF1ZXN0LCByZXNwb25zZSk7XG4gIH1cblxuICAvKiogRXhlY3V0ZSBvbmUgY29tcGF0aWJpbGl0eSByZXF1ZXN0IGluIHRoZSBhY3RpdmUgQXBwS2l0IGlkZW50aXR5IHNjb3BlLiAqL1xuICBhc3luYyBpbmZlcmVuY2UoXG4gICAgcHJvdG9jb2w6IENsaWVudFByb3RvY29sLFxuICAgIHJlcXVlc3Q6IGV4cHJlc3MuUmVxdWVzdCxcbiAgICByZXNwb25zZTogZXhwcmVzcy5SZXNwb25zZSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgc2VuZEluZmVyZW5jZSh0aGlzLmdhdGV3YXksIHByb3RvY29sLCByZXF1ZXN0LCByZXNwb25zZSk7XG4gIH1cblxuICAvKiogUmVmcmVzaCB0aGUgYWN0aXZlIHByaW5jaXBhbCdzIG1vZGVsIGNhdGFsb2d1ZS4gKi9cbiAgYXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmdhdGV3YXkucmVmcmVzaCgpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZXhwb3J0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW9kZWxzOiB0aGlzLm1vZGVscyxcbiAgICAgIGluZmVyZW5jZTogdGhpcy5pbmZlcmVuY2UsXG4gICAgICByZWZyZXNoOiB0aGlzLnJlZnJlc2gsXG4gICAgfTtcbiAgfVxufVxuXG4vKiogQXBwS2l0IHBsdWdpbiBmYWN0b3J5IGZvciB0aGUgRGF0YWJyaWNrcyBtb2RlbCBnYXRld2F5LiAqL1xuZXhwb3J0IGNvbnN0IG1vZGVsR2F0ZXdheSA9IHRvUGx1Z2luKE1vZGVsR2F0ZXdheVBsdWdpbik7XG4iXX0=
@@ -0,0 +1,17 @@
1
+ /**
2
+ * External OpenAI and Anthropic request decoders for AI SDK fallback routes.
3
+ *
4
+ * @module
5
+ */
6
+ import type { ClientProtocol } from "@dbx-tools/shared-model-gateway";
7
+ import { type ModelMessage, type ToolSet } from "ai";
8
+ /** AI SDK call settings decoded from a gateway request. */
9
+ export interface DecodedGatewayRequest {
10
+ readonly messages: ModelMessage[];
11
+ readonly tools: ToolSet;
12
+ readonly maxOutputTokens?: number;
13
+ readonly temperature?: number;
14
+ readonly topP?: number;
15
+ }
16
+ /** Decode one supported external protocol into AI SDK model messages and tools. */
17
+ export declare function decodeGatewayRequest(protocol: ClientProtocol, body: Readonly<Record<string, unknown>>): DecodedGatewayRequest;
@@ -0,0 +1,262 @@
1
+ /**
2
+ * External OpenAI and Anthropic request decoders for AI SDK fallback routes.
3
+ *
4
+ * @module
5
+ */
6
+ import { dynamicTool, jsonSchema } from "ai";
7
+ /** Decode one supported external protocol into AI SDK model messages and tools. */
8
+ export function decodeGatewayRequest(protocol, body) {
9
+ const messages = protocol === "openai-responses"
10
+ ? decodeResponsesMessages(body)
11
+ : protocol === "anthropic-messages"
12
+ ? decodeAnthropicMessages(body)
13
+ : decodeChatMessages(body);
14
+ return {
15
+ messages: consolidateSystemMessages(messages),
16
+ tools: decodeTools(body.tools),
17
+ ...numberSetting(body, "max_output_tokens", "max_tokens", "max_tokens_to_sample"),
18
+ ...(finiteNumber(body.temperature) !== undefined
19
+ ? { temperature: finiteNumber(body.temperature) }
20
+ : {}),
21
+ ...(finiteNumber(body.top_p) !== undefined ? { topP: finiteNumber(body.top_p) } : {}),
22
+ };
23
+ }
24
+ function decodeResponsesMessages(body) {
25
+ const messages = [];
26
+ if (typeof body.instructions === "string" && body.instructions.trim()) {
27
+ messages.push({ role: "system", content: body.instructions });
28
+ }
29
+ if (typeof body.input === "string") {
30
+ messages.push({ role: "user", content: body.input });
31
+ return messages;
32
+ }
33
+ const toolNames = new Map();
34
+ for (const item of arrayRecords(body.input)) {
35
+ const type = item.type;
36
+ if (type === "function_call" || type === "custom_tool_call") {
37
+ const callId = stringValue(item.call_id) ?? stringValue(item.id) ?? crypto.randomUUID();
38
+ const toolName = stringValue(item.name) ?? "tool";
39
+ toolNames.set(callId, toolName);
40
+ messages.push({
41
+ role: "assistant",
42
+ content: [
43
+ {
44
+ type: "tool-call",
45
+ toolCallId: callId,
46
+ toolName,
47
+ input: parseToolInput(item.arguments ?? item.input),
48
+ },
49
+ ],
50
+ });
51
+ continue;
52
+ }
53
+ if (type === "function_call_output" || type === "custom_tool_call_output") {
54
+ const callId = stringValue(item.call_id) ?? stringValue(item.id) ?? crypto.randomUUID();
55
+ messages.push(toolResultMessage(callId, toolNames.get(callId) ?? "tool", item.output));
56
+ continue;
57
+ }
58
+ const role = messageRole(item.role);
59
+ if (role)
60
+ messages.push({ role, content: contentText(item.content) });
61
+ }
62
+ return messages;
63
+ }
64
+ function decodeChatMessages(body) {
65
+ const messages = [];
66
+ const toolNames = new Map();
67
+ for (const message of arrayRecords(body.messages)) {
68
+ const role = stringValue(message.role);
69
+ if (role === "tool") {
70
+ const callId = stringValue(message.tool_call_id) ?? crypto.randomUUID();
71
+ messages.push(toolResultMessage(callId, toolNames.get(callId) ?? "tool", message.content));
72
+ continue;
73
+ }
74
+ if (role === "assistant" && Array.isArray(message.tool_calls)) {
75
+ const content = [];
76
+ const text = contentText(message.content);
77
+ if (text)
78
+ content.push({ type: "text", text });
79
+ for (const toolCall of arrayRecords(message.tool_calls)) {
80
+ const fn = record(toolCall.function);
81
+ const callId = stringValue(toolCall.id) ?? crypto.randomUUID();
82
+ const toolName = stringValue(fn.name) ?? "tool";
83
+ toolNames.set(callId, toolName);
84
+ content.push({
85
+ type: "tool-call",
86
+ toolCallId: callId,
87
+ toolName,
88
+ input: parseToolInput(fn.arguments),
89
+ });
90
+ }
91
+ messages.push({ role: "assistant", content });
92
+ continue;
93
+ }
94
+ const normalized = messageRole(role);
95
+ if (normalized)
96
+ messages.push({ role: normalized, content: contentText(message.content) });
97
+ }
98
+ return messages;
99
+ }
100
+ function decodeAnthropicMessages(body) {
101
+ const messages = [];
102
+ if (body.system !== undefined) {
103
+ const system = contentText(body.system);
104
+ if (system)
105
+ messages.push({ role: "system", content: system });
106
+ }
107
+ const toolNames = new Map();
108
+ for (const message of arrayRecords(body.messages)) {
109
+ const role = stringValue(message.role);
110
+ const parts = Array.isArray(message.content) ? message.content : [];
111
+ if (role === "assistant") {
112
+ const content = [];
113
+ for (const part of parts) {
114
+ if (!record(part).type || record(part).type === "text") {
115
+ const text = contentText(part);
116
+ if (text)
117
+ content.push({ type: "text", text });
118
+ continue;
119
+ }
120
+ const value = record(part);
121
+ if (value.type !== "tool_use")
122
+ continue;
123
+ const callId = stringValue(value.id) ?? crypto.randomUUID();
124
+ const toolName = stringValue(value.name) ?? "tool";
125
+ toolNames.set(callId, toolName);
126
+ content.push({
127
+ type: "tool-call",
128
+ toolCallId: callId,
129
+ toolName,
130
+ input: value.input ?? {},
131
+ });
132
+ }
133
+ messages.push({ role: "assistant", content });
134
+ continue;
135
+ }
136
+ const textParts = [];
137
+ for (const part of parts) {
138
+ const value = record(part);
139
+ if (value.type === "tool_result") {
140
+ const callId = stringValue(value.tool_use_id) ?? crypto.randomUUID();
141
+ messages.push(toolResultMessage(callId, toolNames.get(callId) ?? "tool", value.content));
142
+ }
143
+ else {
144
+ const text = contentText(part);
145
+ if (text)
146
+ textParts.push(text);
147
+ }
148
+ }
149
+ if (textParts.length > 0)
150
+ messages.push({ role: "user", content: textParts.join("\n") });
151
+ }
152
+ return messages;
153
+ }
154
+ function decodeTools(value) {
155
+ const tools = {};
156
+ for (const entry of arrayRecords(value)) {
157
+ const fn = record(entry.function);
158
+ const name = stringValue(fn.name) ?? stringValue(entry.name);
159
+ if (!name)
160
+ continue;
161
+ const declaredSchema = record(fn.parameters ?? entry.input_schema);
162
+ const schema = Object.keys(declaredSchema).length > 0
163
+ ? declaredSchema
164
+ : entry.type === "custom"
165
+ ? {
166
+ type: "object",
167
+ properties: { input: { type: "string" } },
168
+ required: ["input"],
169
+ additionalProperties: false,
170
+ }
171
+ : { type: "object", properties: {}, additionalProperties: false };
172
+ tools[name] = dynamicTool({
173
+ description: stringValue(fn.description) ?? stringValue(entry.description),
174
+ inputSchema: jsonSchema(schema),
175
+ });
176
+ }
177
+ return tools;
178
+ }
179
+ function toolResultMessage(callId, toolName, output) {
180
+ return {
181
+ role: "tool",
182
+ content: [
183
+ {
184
+ type: "tool-result",
185
+ toolCallId: callId,
186
+ toolName,
187
+ output: { type: "text", value: contentText(output) },
188
+ },
189
+ ],
190
+ };
191
+ }
192
+ function numberSetting(body, ...names) {
193
+ for (const name of names) {
194
+ const value = finiteNumber(body[name]);
195
+ if (value !== undefined)
196
+ return { maxOutputTokens: Math.floor(value) };
197
+ }
198
+ return {};
199
+ }
200
+ function parseToolInput(value) {
201
+ if (typeof value !== "string")
202
+ return value ?? {};
203
+ try {
204
+ return JSON.parse(value);
205
+ }
206
+ catch {
207
+ return { input: value };
208
+ }
209
+ }
210
+ function contentText(value) {
211
+ if (typeof value === "string")
212
+ return value;
213
+ if (!Array.isArray(value)) {
214
+ const text = stringValue(record(value).text);
215
+ return text ?? (value === undefined || value === null ? "" : JSON.stringify(value));
216
+ }
217
+ return value
218
+ .map((part) => {
219
+ if (typeof part === "string")
220
+ return part;
221
+ const item = record(part);
222
+ return (stringValue(item.text) ?? stringValue(item.output_text) ?? stringValue(item.input_text));
223
+ })
224
+ .filter((text) => text !== undefined)
225
+ .join("");
226
+ }
227
+ function messageRole(value) {
228
+ if (value === "system" || value === "developer")
229
+ return "system";
230
+ if (value === "user" || value === "assistant")
231
+ return value;
232
+ return undefined;
233
+ }
234
+ function arrayRecords(value) {
235
+ return Array.isArray(value)
236
+ ? value.filter((item) => isRecord(item))
237
+ : [];
238
+ }
239
+ function record(value) {
240
+ return isRecord(value) ? value : {};
241
+ }
242
+ function isRecord(value) {
243
+ return value !== null && typeof value === "object" && !Array.isArray(value);
244
+ }
245
+ function stringValue(value) {
246
+ return typeof value === "string" ? value : undefined;
247
+ }
248
+ function finiteNumber(value) {
249
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
250
+ }
251
+ function consolidateSystemMessages(messages) {
252
+ const system = messages
253
+ .filter((message) => message.role === "system")
254
+ .map((message) => (typeof message.content === "string" ? message.content : ""))
255
+ .filter(Boolean)
256
+ .join("\n\n");
257
+ return [
258
+ ...(system ? [{ role: "system", content: system }] : []),
259
+ ...messages.filter((message) => message.role !== "system"),
260
+ ];
261
+ }
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Byb3RvY29scy9kZWNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUdILE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFtQyxNQUFNLElBQUksQ0FBQztBQVc5RSxtRkFBbUY7QUFDbkYsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxRQUF3QixFQUN4QixJQUF1QztJQUV2QyxNQUFNLFFBQVEsR0FDWixRQUFRLEtBQUssa0JBQWtCO1FBQzdCLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUM7UUFDL0IsQ0FBQyxDQUFDLFFBQVEsS0FBSyxvQkFBb0I7WUFDakMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQztZQUMvQixDQUFDLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsT0FBTztRQUNMLFFBQVEsRUFBRSx5QkFBeUIsQ0FBQyxRQUFRLENBQUM7UUFDN0MsS0FBSyxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzlCLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsc0JBQXNCLENBQUM7UUFDakYsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssU0FBUztZQUM5QyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUNqRCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1AsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUN0RixDQUFDO0FBQ0os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Q0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBb0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzVFLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7S0FDM0QsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4dGVybmFsIE9wZW5BSSBhbmQgQW50aHJvcGljIHJlcXVlc3QgZGVjb2RlcnMgZm9yIEFJIFNESyBmYWxsYmFjayByb3V0ZXMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgQ2xpZW50UHJvdG9jb2wgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWwtZ2F0ZXdheVwiO1xuaW1wb3J0IHsgZHluYW1pY1Rvb2wsIGpzb25TY2hlbWEsIHR5cGUgTW9kZWxNZXNzYWdlLCB0eXBlIFRvb2xTZXQgfSBmcm9tIFwiYWlcIjtcblxuLyoqIEFJIFNESyBjYWxsIHNldHRpbmdzIGRlY29kZWQgZnJvbSBhIGdhdGV3YXkgcmVxdWVzdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGVjb2RlZEdhdGV3YXlSZXF1ZXN0IHtcbiAgcmVhZG9ubHkgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdO1xuICByZWFkb25seSB0b29sczogVG9vbFNldDtcbiAgcmVhZG9ubHkgbWF4T3V0cHV0VG9rZW5zPzogbnVtYmVyO1xuICByZWFkb25seSB0ZW1wZXJhdHVyZT86IG51bWJlcjtcbiAgcmVhZG9ubHkgdG9wUD86IG51bWJlcjtcbn1cblxuLyoqIERlY29kZSBvbmUgc3VwcG9ydGVkIGV4dGVybmFsIHByb3RvY29sIGludG8gQUkgU0RLIG1vZGVsIG1lc3NhZ2VzIGFuZCB0b29scy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVHYXRld2F5UmVxdWVzdChcbiAgcHJvdG9jb2w6IENsaWVudFByb3RvY29sLFxuICBib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sXG4pOiBEZWNvZGVkR2F0ZXdheVJlcXVlc3Qge1xuICBjb25zdCBtZXNzYWdlcyA9XG4gICAgcHJvdG9jb2wgPT09IFwib3BlbmFpLXJlc3BvbnNlc1wiXG4gICAgICA/IGRlY29kZVJlc3BvbnNlc01lc3NhZ2VzKGJvZHkpXG4gICAgICA6IHByb3RvY29sID09PSBcImFudGhyb3BpYy1tZXNzYWdlc1wiXG4gICAgICAgID8gZGVjb2RlQW50aHJvcGljTWVzc2FnZXMoYm9keSlcbiAgICAgICAgOiBkZWNvZGVDaGF0TWVzc2FnZXMoYm9keSk7XG4gIHJldHVybiB7XG4gICAgbWVzc2FnZXM6IGNvbnNvbGlkYXRlU3lzdGVtTWVzc2FnZXMobWVzc2FnZXMpLFxuICAgIHRvb2xzOiBkZWNvZGVUb29scyhib2R5LnRvb2xzKSxcbiAgICAuLi5udW1iZXJTZXR0aW5nKGJvZHksIFwibWF4X291dHB1dF90b2tlbnNcIiwgXCJtYXhfdG9rZW5zXCIsIFwibWF4X3Rva2Vuc190b19zYW1wbGVcIiksXG4gICAgLi4uKGZpbml0ZU51bWJlcihib2R5LnRlbXBlcmF0dXJlKSAhPT0gdW5kZWZpbmVkXG4gICAgICA/IHsgdGVtcGVyYXR1cmU6IGZpbml0ZU51bWJlcihib2R5LnRlbXBlcmF0dXJlKSB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oZmluaXRlTnVtYmVyKGJvZHkudG9wX3ApICE9PSB1bmRlZmluZWQgPyB7IHRvcFA6IGZpbml0ZU51bWJlcihib2R5LnRvcF9wKSB9IDoge30pLFxuICB9O1xufVxuXG5mdW5jdGlvbiBkZWNvZGVSZXNwb25zZXNNZXNzYWdlcyhib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pOiBNb2RlbE1lc3NhZ2VbXSB7XG4gIGNvbnN0IG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXSA9IFtdO1xuICBpZiAodHlwZW9mIGJvZHkuaW5zdHJ1Y3Rpb25zID09PSBcInN0cmluZ1wiICYmIGJvZHkuaW5zdHJ1Y3Rpb25zLnRyaW0oKSkge1xuICAgIG1lc3NhZ2VzLnB1c2goeyByb2xlOiBcInN5c3RlbVwiLCBjb250ZW50OiBib2R5Lmluc3RydWN0aW9ucyB9KTtcbiAgfVxuICBpZiAodHlwZW9mIGJvZHkuaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcbiAgICBtZXNzYWdlcy5wdXNoKHsgcm9sZTogXCJ1c2VyXCIsIGNvbnRlbnQ6IGJvZHkuaW5wdXQgfSk7XG4gICAgcmV0dXJuIG1lc3NhZ2VzO1xuICB9XG4gIGNvbnN0IHRvb2xOYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBhcnJheVJlY29yZHMoYm9keS5pbnB1dCkpIHtcbiAgICBjb25zdCB0eXBlID0gaXRlbS50eXBlO1xuICAgIGlmICh0eXBlID09PSBcImZ1bmN0aW9uX2NhbGxcIiB8fCB0eXBlID09PSBcImN1c3RvbV90b29sX2NhbGxcIikge1xuICAgICAgY29uc3QgY2FsbElkID0gc3RyaW5nVmFsdWUoaXRlbS5jYWxsX2lkKSA/PyBzdHJpbmdWYWx1ZShpdGVtLmlkKSA/PyBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgICAgY29uc3QgdG9vbE5hbWUgPSBzdHJpbmdWYWx1ZShpdGVtLm5hbWUpID8/IFwidG9vbFwiO1xuICAgICAgdG9vbE5hbWVzLnNldChjYWxsSWQsIHRvb2xOYW1lKTtcbiAgICAgIG1lc3NhZ2VzLnB1c2goe1xuICAgICAgICByb2xlOiBcImFzc2lzdGFudFwiLFxuICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJ0b29sLWNhbGxcIixcbiAgICAgICAgICAgIHRvb2xDYWxsSWQ6IGNhbGxJZCxcbiAgICAgICAgICAgIHRvb2xOYW1lLFxuICAgICAgICAgICAgaW5wdXQ6IHBhcnNlVG9vbElucHV0KGl0ZW0uYXJndW1lbnRzID8/IGl0ZW0uaW5wdXQpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9IGFzIE1vZGVsTWVzc2FnZSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwiZnVuY3Rpb25fY2FsbF9vdXRwdXRcIiB8fCB0eXBlID09PSBcImN1c3RvbV90b29sX2NhbGxfb3V0cHV0XCIpIHtcbiAgICAgIGNvbnN0IGNhbGxJZCA9IHN0cmluZ1ZhbHVlKGl0ZW0uY2FsbF9pZCkgPz8gc3RyaW5nVmFsdWUoaXRlbS5pZCkgPz8gY3J5cHRvLnJhbmRvbVVVSUQoKTtcbiAgICAgIG1lc3NhZ2VzLnB1c2godG9vbFJlc3VsdE1lc3NhZ2UoY2FsbElkLCB0b29sTmFtZXMuZ2V0KGNhbGxJZCkgPz8gXCJ0b29sXCIsIGl0ZW0ub3V0cHV0KSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3Qgcm9sZSA9IG1lc3NhZ2VSb2xlKGl0ZW0ucm9sZSk7XG4gICAgaWYgKHJvbGUpIG1lc3NhZ2VzLnB1c2goeyByb2xlLCBjb250ZW50OiBjb250ZW50VGV4dChpdGVtLmNvbnRlbnQpIH0gYXMgTW9kZWxNZXNzYWdlKTtcbiAgfVxuICByZXR1cm4gbWVzc2FnZXM7XG59XG5cbmZ1bmN0aW9uIGRlY29kZUNoYXRNZXNzYWdlcyhib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pOiBNb2RlbE1lc3NhZ2VbXSB7XG4gIGNvbnN0IG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXSA9IFtdO1xuICBjb25zdCB0b29sTmFtZXMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgYXJyYXlSZWNvcmRzKGJvZHkubWVzc2FnZXMpKSB7XG4gICAgY29uc3Qgcm9sZSA9IHN0cmluZ1ZhbHVlKG1lc3NhZ2Uucm9sZSk7XG4gICAgaWYgKHJvbGUgPT09IFwidG9vbFwiKSB7XG4gICAgICBjb25zdCBjYWxsSWQgPSBzdHJpbmdWYWx1ZShtZXNzYWdlLnRvb2xfY2FsbF9pZCkgPz8gY3J5cHRvLnJhbmRvbVVVSUQoKTtcbiAgICAgIG1lc3NhZ2VzLnB1c2godG9vbFJlc3VsdE1lc3NhZ2UoY2FsbElkLCB0b29sTmFtZXMuZ2V0KGNhbGxJZCkgPz8gXCJ0b29sXCIsIG1lc3NhZ2UuY29udGVudCkpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChyb2xlID09PSBcImFzc2lzdGFudFwiICYmIEFycmF5LmlzQXJyYXkobWVzc2FnZS50b29sX2NhbGxzKSkge1xuICAgICAgY29uc3QgY29udGVudDogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSA9IFtdO1xuICAgICAgY29uc3QgdGV4dCA9IGNvbnRlbnRUZXh0KG1lc3NhZ2UuY29udGVudCk7XG4gICAgICBpZiAodGV4dCkgY29udGVudC5wdXNoKHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQgfSk7XG4gICAgICBmb3IgKGNvbnN0IHRvb2xDYWxsIG9mIGFycmF5UmVjb3JkcyhtZXNzYWdlLnRvb2xfY2FsbHMpKSB7XG4gICAgICAgIGNvbnN0IGZuID0gcmVjb3JkKHRvb2xDYWxsLmZ1bmN0aW9uKTtcbiAgICAgICAgY29uc3QgY2FsbElkID0gc3RyaW5nVmFsdWUodG9vbENhbGwuaWQpID8/IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgICAgIGNvbnN0IHRvb2xOYW1lID0gc3RyaW5nVmFsdWUoZm4ubmFtZSkgPz8gXCJ0b29sXCI7XG4gICAgICAgIHRvb2xOYW1lcy5zZXQoY2FsbElkLCB0b29sTmFtZSk7XG4gICAgICAgIGNvbnRlbnQucHVzaCh7XG4gICAgICAgICAgdHlwZTogXCJ0b29sLWNhbGxcIixcbiAgICAgICAgICB0b29sQ2FsbElkOiBjYWxsSWQsXG4gICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgaW5wdXQ6IHBhcnNlVG9vbElucHV0KGZuLmFyZ3VtZW50cyksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgbWVzc2FnZXMucHVzaCh7IHJvbGU6IFwiYXNzaXN0YW50XCIsIGNvbnRlbnQgfSBhcyBNb2RlbE1lc3NhZ2UpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBtZXNzYWdlUm9sZShyb2xlKTtcbiAgICBpZiAobm9ybWFsaXplZCkgbWVzc2FnZXMucHVzaCh7IHJvbGU6IG5vcm1hbGl6ZWQsIGNvbnRlbnQ6IGNvbnRlbnRUZXh0KG1lc3NhZ2UuY29udGVudCkgfSk7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2VzO1xufVxuXG5mdW5jdGlvbiBkZWNvZGVBbnRocm9waWNNZXNzYWdlcyhib2R5OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4pOiBNb2RlbE1lc3NhZ2VbXSB7XG4gIGNvbnN0IG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXSA9IFtdO1xuICBpZiAoYm9keS5zeXN0ZW0gIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IHN5c3RlbSA9IGNvbnRlbnRUZXh0KGJvZHkuc3lzdGVtKTtcbiAgICBpZiAoc3lzdGVtKSBtZXNzYWdlcy5wdXNoKHsgcm9sZTogXCJzeXN0ZW1cIiwgY29udGVudDogc3lzdGVtIH0pO1xuICB9XG4gIGNvbnN0IHRvb2xOYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgbWVzc2FnZSBvZiBhcnJheVJlY29yZHMoYm9keS5tZXNzYWdlcykpIHtcbiAgICBjb25zdCByb2xlID0gc3RyaW5nVmFsdWUobWVzc2FnZS5yb2xlKTtcbiAgICBjb25zdCBwYXJ0cyA9IEFycmF5LmlzQXJyYXkobWVzc2FnZS5jb250ZW50KSA/IG1lc3NhZ2UuY29udGVudCA6IFtdO1xuICAgIGlmIChyb2xlID09PSBcImFzc2lzdGFudFwiKSB7XG4gICAgICBjb25zdCBjb250ZW50OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdID0gW107XG4gICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgaWYgKCFyZWNvcmQocGFydCkudHlwZSB8fCByZWNvcmQocGFydCkudHlwZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgICBjb25zdCB0ZXh0ID0gY29udGVudFRleHQocGFydCk7XG4gICAgICAgICAgaWYgKHRleHQpIGNvbnRlbnQucHVzaCh7IHR5cGU6IFwidGV4dFwiLCB0ZXh0IH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcmVjb3JkKHBhcnQpO1xuICAgICAgICBpZiAodmFsdWUudHlwZSAhPT0gXCJ0b29sX3VzZVwiKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgY2FsbElkID0gc3RyaW5nVmFsdWUodmFsdWUuaWQpID8/IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgICAgIGNvbnN0IHRvb2xOYW1lID0gc3RyaW5nVmFsdWUodmFsdWUubmFtZSkgPz8gXCJ0b29sXCI7XG4gICAgICAgIHRvb2xOYW1lcy5zZXQoY2FsbElkLCB0b29sTmFtZSk7XG4gICAgICAgIGNvbnRlbnQucHVzaCh7XG4gICAgICAgICAgdHlwZTogXCJ0b29sLWNhbGxcIixcbiAgICAgICAgICB0b29sQ2FsbElkOiBjYWxsSWQsXG4gICAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgICAgaW5wdXQ6IHZhbHVlLmlucHV0ID8/IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIG1lc3NhZ2VzLnB1c2goeyByb2xlOiBcImFzc2lzdGFudFwiLCBjb250ZW50IH0gYXMgTW9kZWxNZXNzYWdlKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCB0ZXh0UGFydHM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlY29yZChwYXJ0KTtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSBcInRvb2xfcmVzdWx0XCIpIHtcbiAgICAgICAgY29uc3QgY2FsbElkID0gc3RyaW5nVmFsdWUodmFsdWUudG9vbF91c2VfaWQpID8/IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgICAgIG1lc3NhZ2VzLnB1c2godG9vbFJlc3VsdE1lc3NhZ2UoY2FsbElkLCB0b29sTmFtZXMuZ2V0KGNhbGxJZCkgPz8gXCJ0b29sXCIsIHZhbHVlLmNvbnRlbnQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBjb250ZW50VGV4dChwYXJ0KTtcbiAgICAgICAgaWYgKHRleHQpIHRleHRQYXJ0cy5wdXNoKHRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGV4dFBhcnRzLmxlbmd0aCA+IDApIG1lc3NhZ2VzLnB1c2goeyByb2xlOiBcInVzZXJcIiwgY29udGVudDogdGV4dFBhcnRzLmpvaW4oXCJcXG5cIikgfSk7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2VzO1xufVxuXG5mdW5jdGlvbiBkZWNvZGVUb29scyh2YWx1ZTogdW5rbm93bik6IFRvb2xTZXQge1xuICBjb25zdCB0b29sczogVG9vbFNldCA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGFycmF5UmVjb3Jkcyh2YWx1ZSkpIHtcbiAgICBjb25zdCBmbiA9IHJlY29yZChlbnRyeS5mdW5jdGlvbik7XG4gICAgY29uc3QgbmFtZSA9IHN0cmluZ1ZhbHVlKGZuLm5hbWUpID8/IHN0cmluZ1ZhbHVlKGVudHJ5Lm5hbWUpO1xuICAgIGlmICghbmFtZSkgY29udGludWU7XG4gICAgY29uc3QgZGVjbGFyZWRTY2hlbWEgPSByZWNvcmQoZm4ucGFyYW1ldGVycyA/PyBlbnRyeS5pbnB1dF9zY2hlbWEpO1xuICAgIGNvbnN0IHNjaGVtYSA9XG4gICAgICBPYmplY3Qua2V5cyhkZWNsYXJlZFNjaGVtYSkubGVuZ3RoID4gMFxuICAgICAgICA/IGRlY2xhcmVkU2NoZW1hXG4gICAgICAgIDogZW50cnkudHlwZSA9PT0gXCJjdXN0b21cIlxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7IGlucHV0OiB7IHR5cGU6IFwic3RyaW5nXCIgfSB9LFxuICAgICAgICAgICAgICByZXF1aXJlZDogW1wiaW5wdXRcIl0sXG4gICAgICAgICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHsgdHlwZTogXCJvYmplY3RcIiwgcHJvcGVydGllczoge30sIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSB9O1xuICAgIHRvb2xzW25hbWVdID0gZHluYW1pY1Rvb2woe1xuICAgICAgZGVzY3JpcHRpb246IHN0cmluZ1ZhbHVlKGZuLmRlc2NyaXB0aW9uKSA/PyBzdHJpbmdWYWx1ZShlbnRyeS5kZXNjcmlwdGlvbiksXG4gICAgICBpbnB1dFNjaGVtYToganNvblNjaGVtYShzY2hlbWEpLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiB0b29scztcbn1cblxuZnVuY3Rpb24gdG9vbFJlc3VsdE1lc3NhZ2UoY2FsbElkOiBzdHJpbmcsIHRvb2xOYW1lOiBzdHJpbmcsIG91dHB1dDogdW5rbm93bik6IE1vZGVsTWVzc2FnZSB7XG4gIHJldHVybiB7XG4gICAgcm9sZTogXCJ0b29sXCIsXG4gICAgY29udGVudDogW1xuICAgICAge1xuICAgICAgICB0eXBlOiBcInRvb2wtcmVzdWx0XCIsXG4gICAgICAgIHRvb2xDYWxsSWQ6IGNhbGxJZCxcbiAgICAgICAgdG9vbE5hbWUsXG4gICAgICAgIG91dHB1dDogeyB0eXBlOiBcInRleHRcIiwgdmFsdWU6IGNvbnRlbnRUZXh0KG91dHB1dCkgfSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSBhcyBNb2RlbE1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIG51bWJlclNldHRpbmcoXG4gIGJvZHk6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PixcbiAgLi4ubmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdXG4pOiBQaWNrPERlY29kZWRHYXRld2F5UmVxdWVzdCwgXCJtYXhPdXRwdXRUb2tlbnNcIj4ge1xuICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IGZpbml0ZU51bWJlcihib2R5W25hbWVdKTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHsgbWF4T3V0cHV0VG9rZW5zOiBNYXRoLmZsb29yKHZhbHVlKSB9O1xuICB9XG4gIHJldHVybiB7fTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUb29sSW5wdXQodmFsdWU6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHZhbHVlID8/IHt9O1xuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHsgaW5wdXQ6IHZhbHVlIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udGVudFRleHQodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSByZXR1cm4gdmFsdWU7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBjb25zdCB0ZXh0ID0gc3RyaW5nVmFsdWUocmVjb3JkKHZhbHVlKS50ZXh0KTtcbiAgICByZXR1cm4gdGV4dCA/PyAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCA/IFwiXCIgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICB9XG4gIHJldHVybiB2YWx1ZVxuICAgIC5tYXAoKHBhcnQpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcGFydCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHBhcnQ7XG4gICAgICBjb25zdCBpdGVtID0gcmVjb3JkKHBhcnQpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgc3RyaW5nVmFsdWUoaXRlbS50ZXh0KSA/PyBzdHJpbmdWYWx1ZShpdGVtLm91dHB1dF90ZXh0KSA/PyBzdHJpbmdWYWx1ZShpdGVtLmlucHV0X3RleHQpXG4gICAgICApO1xuICAgIH0pXG4gICAgLmZpbHRlcigodGV4dCk6IHRleHQgaXMgc3RyaW5nID0+IHRleHQgIT09IHVuZGVmaW5lZClcbiAgICAuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gbWVzc2FnZVJvbGUodmFsdWU6IHVua25vd24pOiBcInN5c3RlbVwiIHwgXCJ1c2VyXCIgfCBcImFzc2lzdGFudFwiIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHZhbHVlID09PSBcInN5c3RlbVwiIHx8IHZhbHVlID09PSBcImRldmVsb3BlclwiKSByZXR1cm4gXCJzeXN0ZW1cIjtcbiAgaWYgKHZhbHVlID09PSBcInVzZXJcIiB8fCB2YWx1ZSA9PT0gXCJhc3Npc3RhbnRcIikgcmV0dXJuIHZhbHVlO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBhcnJheVJlY29yZHModmFsdWU6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgPyB2YWx1ZS5maWx0ZXIoKGl0ZW0pOiBpdGVtIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+IGlzUmVjb3JkKGl0ZW0pKVxuICAgIDogW107XG59XG5cbmZ1bmN0aW9uIHJlY29yZCh2YWx1ZTogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIGlzUmVjb3JkKHZhbHVlKSA/IHZhbHVlIDoge307XG59XG5cbmZ1bmN0aW9uIGlzUmVjb3JkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gc3RyaW5nVmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGZpbml0ZU51bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBjb25zb2xpZGF0ZVN5c3RlbU1lc3NhZ2VzKG1lc3NhZ2VzOiByZWFkb25seSBNb2RlbE1lc3NhZ2VbXSk6IE1vZGVsTWVzc2FnZVtdIHtcbiAgY29uc3Qgc3lzdGVtID0gbWVzc2FnZXNcbiAgICAuZmlsdGVyKChtZXNzYWdlKSA9PiBtZXNzYWdlLnJvbGUgPT09IFwic3lzdGVtXCIpXG4gICAgLm1hcCgobWVzc2FnZSkgPT4gKHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQgPT09IFwic3RyaW5nXCIgPyBtZXNzYWdlLmNvbnRlbnQgOiBcIlwiKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmpvaW4oXCJcXG5cXG5cIik7XG4gIHJldHVybiBbXG4gICAgLi4uKHN5c3RlbSA/IChbeyByb2xlOiBcInN5c3RlbVwiLCBjb250ZW50OiBzeXN0ZW0gfV0gYXMgTW9kZWxNZXNzYWdlW10pIDogW10pLFxuICAgIC4uLm1lc3NhZ2VzLmZpbHRlcigobWVzc2FnZSkgPT4gbWVzc2FnZS5yb2xlICE9PSBcInN5c3RlbVwiKSxcbiAgXTtcbn1cbiJdfQ==
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Streaming and buffered protocol encoders for AI SDK fallback results.
3
+ *
4
+ * @module
5
+ */
6
+ import type { ClientProtocol } from "@dbx-tools/shared-model-gateway";
7
+ import type { FinishReason, LanguageModelUsage, TextStreamPart, ToolSet, TypedToolCall } from "ai";
8
+ /** Completed AI SDK generation data used by non-streaming encoders. */
9
+ export interface CompletedGeneration {
10
+ readonly text: string;
11
+ readonly toolCalls: readonly TypedToolCall<ToolSet>[];
12
+ readonly usage: LanguageModelUsage;
13
+ readonly finishReason: FinishReason;
14
+ }
15
+ /** Encode AI SDK events as the requested protocol while preserving backpressure. */
16
+ export declare function encodeGatewayStream(protocol: ClientProtocol, model: string, source: AsyncIterable<TextStreamPart<ToolSet>>): ReadableStream<Uint8Array>;
17
+ /** Encode a completed AI SDK generation as one protocol-native JSON response. */
18
+ export declare function encodeGatewayResponse(protocol: ClientProtocol, model: string, generation: CompletedGeneration): Record<string, unknown>;