@unchainedshop/api 5.0.0-alpha.1 → 5.0.0-alpha.3

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 (117) hide show
  1. package/README.md +6 -4
  2. package/lib/adminUiPlugins.d.ts +73 -0
  3. package/lib/adminUiPlugins.js +164 -0
  4. package/lib/adminUiTheme.d.ts +25 -0
  5. package/lib/adminUiTheme.js +34 -0
  6. package/lib/chat/generateImageHandler.d.ts +273 -7
  7. package/lib/chat/utils.d.ts +8 -0
  8. package/lib/chat/utils.js +54 -2
  9. package/lib/createGraphQLServer.js +6 -0
  10. package/lib/express/chatHandler.js +52 -61
  11. package/lib/express/createMCPMiddleware.js +19 -78
  12. package/lib/express/index.d.ts +8 -2
  13. package/lib/express/index.js +55 -7
  14. package/lib/fastify/chatHandler.js +52 -61
  15. package/lib/fastify/index.d.ts +7 -1
  16. package/lib/fastify/index.js +58 -11
  17. package/lib/fastify/mcpHandler.js +24 -75
  18. package/lib/loaders/cartLoader.d.ts +13 -0
  19. package/lib/loaders/cartLoader.js +8 -0
  20. package/lib/loaders/enrollmentByOrderLoader.d.ts +9 -0
  21. package/lib/loaders/enrollmentByOrderLoader.js +17 -0
  22. package/lib/loaders/index.d.ts +14 -0
  23. package/lib/loaders/index.js +4 -0
  24. package/lib/loaders/orderDeliveryLoader.d.ts +9 -0
  25. package/lib/loaders/orderDeliveryLoader.js +12 -0
  26. package/lib/loaders/orderDiscountsLoader.d.ts +9 -0
  27. package/lib/loaders/orderDiscountsLoader.js +17 -0
  28. package/lib/loaders/orderPaymentLoader.d.ts +9 -0
  29. package/lib/loaders/orderPaymentLoader.js +12 -0
  30. package/lib/loaders/orderPositionsLoader.d.ts +9 -0
  31. package/lib/loaders/orderPositionsLoader.js +17 -0
  32. package/lib/loaders/tokenExportStatusLoader.d.ts +9 -0
  33. package/lib/loaders/tokenExportStatusLoader.js +31 -0
  34. package/lib/locale-context.d.ts +2 -4
  35. package/lib/locale-context.js +2 -1
  36. package/lib/mcp/handleMcpHttpRequest.d.ts +2 -0
  37. package/lib/mcp/handleMcpHttpRequest.js +83 -0
  38. package/lib/mcp/index.d.ts +1 -1
  39. package/lib/mcp/nodeHttpBridge.d.ts +3 -0
  40. package/lib/mcp/nodeHttpBridge.js +64 -0
  41. package/lib/mcp/resources/localization.d.ts +5 -1
  42. package/lib/mcp/resources/localization.js +93 -69
  43. package/lib/mcp/tools/assortment/handlers/getAssortment.js +1 -1
  44. package/lib/mcp/tools/assortment/index.d.ts +1 -1
  45. package/lib/mcp/tools/assortment/index.js +4 -1
  46. package/lib/mcp/tools/assortment/schemas.d.ts +2 -2
  47. package/lib/mcp/tools/filter/handlers/createFilter.js +2 -4
  48. package/lib/mcp/tools/filter/handlers/createFilterOption.js +2 -4
  49. package/lib/mcp/tools/filter/handlers/removeFilterOption.js +2 -4
  50. package/lib/mcp/tools/filter/handlers/updateFilter.js +2 -2
  51. package/lib/mcp/tools/filter/index.d.ts +1 -1
  52. package/lib/mcp/tools/filter/index.js +4 -1
  53. package/lib/mcp/tools/filter/schemas.d.ts +2 -2
  54. package/lib/mcp/tools/localization/index.d.ts +1 -1
  55. package/lib/mcp/tools/localization/index.js +4 -1
  56. package/lib/mcp/tools/localization/schemas.d.ts +2 -2
  57. package/lib/mcp/tools/order/index.d.ts +1 -1
  58. package/lib/mcp/tools/order/index.js +4 -1
  59. package/lib/mcp/tools/order/schemas.d.ts +2 -2
  60. package/lib/mcp/tools/product/handlers/getProduct.js +1 -1
  61. package/lib/mcp/tools/product/index.d.ts +1 -1
  62. package/lib/mcp/tools/product/index.js +4 -1
  63. package/lib/mcp/tools/product/schemas.d.ts +7 -7
  64. package/lib/mcp/tools/product/schemas.js +3 -2
  65. package/lib/mcp/tools/provider/index.d.ts +1 -1
  66. package/lib/mcp/tools/provider/index.js +4 -1
  67. package/lib/mcp/tools/provider/schemas.d.ts +2 -2
  68. package/lib/mcp/tools/quotation/index.d.ts +1 -1
  69. package/lib/mcp/tools/quotation/index.js +4 -1
  70. package/lib/mcp/tools/quotation/schemas.d.ts +2 -2
  71. package/lib/mcp/tools/system/index.d.ts +1 -1
  72. package/lib/mcp/tools/system/index.js +4 -1
  73. package/lib/mcp/tools/users/index.d.ts +1 -1
  74. package/lib/mcp/tools/users/index.js +4 -1
  75. package/lib/mcp/tools/users/schemas.d.ts +2 -2
  76. package/lib/mcp/utils/sharedSchemas.d.ts +1 -0
  77. package/lib/mcp/utils/sharedSchemas.js +1 -0
  78. package/lib/middleware/createAuthMiddleware.js +1 -3
  79. package/lib/resolvers/index.js +2 -1
  80. package/lib/resolvers/mutations/bookmarks/createBookmark.d.ts +1 -1
  81. package/lib/resolvers/mutations/bookmarks/createBookmark.js +4 -3
  82. package/lib/resolvers/mutations/filters/createFilter.js +3 -4
  83. package/lib/resolvers/mutations/filters/createFilterOption.d.ts +1 -1
  84. package/lib/resolvers/mutations/filters/createFilterOption.js +3 -4
  85. package/lib/resolvers/mutations/filters/removeFilterOption.d.ts +1 -1
  86. package/lib/resolvers/mutations/filters/removeFilterOption.js +2 -8
  87. package/lib/resolvers/mutations/filters/updateFilter.d.ts +1 -1
  88. package/lib/resolvers/mutations/filters/updateFilter.js +2 -5
  89. package/lib/resolvers/mutations/index.js +3 -3
  90. package/lib/resolvers/mutations/products/updateProductCommerce.js +10 -1
  91. package/lib/resolvers/scalars/LowerCaseString.d.ts +1 -1
  92. package/lib/resolvers/scalars/index.d.ts +1 -1
  93. package/lib/resolvers/type/filter/loaded-filter-types.d.ts +1 -1
  94. package/lib/resolvers/type/filter/loaded-filter-types.js +1 -1
  95. package/lib/resolvers/type/index.d.ts +12 -8
  96. package/lib/resolvers/type/product/product-bundle-types.d.ts +1 -1
  97. package/lib/resolvers/type/product/product-plan-types.d.ts +1 -1
  98. package/lib/resolvers/type/product/product-simple-types.d.ts +1 -1
  99. package/lib/resolvers/type/product/product-tokenized-types.d.ts +1 -1
  100. package/lib/resolvers/type/quotation-types.d.ts +4 -0
  101. package/lib/resolvers/type/quotation-types.js +1 -0
  102. package/lib/resolvers/type/token-types.d.ts +3 -3
  103. package/lib/resolvers/type/token-types.js +6 -5
  104. package/lib/resolvers/type/user-types.d.ts +1 -1
  105. package/lib/resolvers/type/user-types.js +2 -2
  106. package/lib/roles/all.js +1 -1
  107. package/lib/roles/index.js +2 -0
  108. package/lib/roles/loggedIn.js +11 -0
  109. package/lib/schema/inputTypes.js +3 -3
  110. package/lib/schema/scalars.js +1 -0
  111. package/lib/schema/types/filter.js +2 -2
  112. package/lib/schema/types/product/product.js +1 -1
  113. package/lib/schema/types/quotation.js +5 -0
  114. package/lib/schema/types/user.js +1 -1
  115. package/lib/utils/optionalPeerError.d.ts +1 -0
  116. package/lib/utils/optionalPeerError.js +6 -0
  117. package/package.json +39 -15
package/README.md CHANGED
@@ -141,14 +141,16 @@ The API exposes a complete GraphQL schema with:
141
141
 
142
142
  ## MCP Server
143
143
 
144
- Model Context Protocol server for AI agent integrations:
144
+ Model Context Protocol server for AI agent integrations. `connect()` (Express or Fastify) automatically mounts a stateless MCP endpoint at `/mcp` (configurable via `MCP_API_PATH`). The endpoint requires an authenticated user with the `admin` role and serves 9 management tools plus the shop localization resources.
145
145
 
146
- ```typescript
147
- import { createMCPServer } from '@unchainedshop/api/mcp';
146
+ MCP support is an optional peer dependency:
148
147
 
149
- const mcpServer = createMCPServer(unchainedCore);
148
+ ```bash
149
+ npm install @modelcontextprotocol/server
150
150
  ```
151
151
 
152
+ Without it, the engine boots normally and `/mcp` responds with `503`. The chat handlers (`connect(..., { chat })`) additionally require the optional peers `ai` and `@ai-sdk/mcp` — and `@modelcontextprotocol/server` too, since chat derives its tool set through the engine's own `/mcp` endpoint.
153
+
152
154
  ## Security
153
155
 
154
156
  The API layer implements comprehensive security controls.
@@ -0,0 +1,73 @@
1
+ export interface AdminUIPluginEntityConfig {
2
+ path: string;
3
+ label: string;
4
+ icon?: string;
5
+ requiredRole?: string;
6
+ sortOrder?: number;
7
+ components: {
8
+ list: string;
9
+ detail: string;
10
+ create?: string;
11
+ };
12
+ }
13
+ export interface AdminUIPluginPageConfig {
14
+ path: string;
15
+ label: string;
16
+ icon?: string;
17
+ requiredRole?: string;
18
+ sortOrder?: number;
19
+ component: string;
20
+ }
21
+ export interface AdminUIPluginTabConfig {
22
+ label: string;
23
+ component: string;
24
+ requiredRole?: string;
25
+ }
26
+ export interface AdminUIPluginWidgetConfig {
27
+ component: string;
28
+ width?: 'full' | 'half' | 'third';
29
+ }
30
+ export interface AdminUIPluginSlotConfig {
31
+ component: string;
32
+ }
33
+ export interface AdminUIPluginConfig {
34
+ name: string;
35
+ version?: string;
36
+ bundlePath: string;
37
+ navigation?: {
38
+ label: string;
39
+ icon?: string;
40
+ requiredRole?: string;
41
+ sortOrder?: number;
42
+ };
43
+ slots: {
44
+ entities?: AdminUIPluginEntityConfig[];
45
+ pages?: AdminUIPluginPageConfig[];
46
+ 'dashboard:widgets'?: AdminUIPluginWidgetConfig[];
47
+ 'product:tabs'?: AdminUIPluginTabConfig[];
48
+ 'assortment:tabs'?: AdminUIPluginTabConfig[];
49
+ 'filter:tabs'?: AdminUIPluginTabConfig[];
50
+ 'user:tabs'?: AdminUIPluginTabConfig[];
51
+ 'order:tabs'?: AdminUIPluginTabConfig[];
52
+ [key: string]: AdminUIPluginTabConfig[] | AdminUIPluginSlotConfig[] | AdminUIPluginEntityConfig[] | AdminUIPluginPageConfig[] | AdminUIPluginWidgetConfig[] | undefined;
53
+ };
54
+ }
55
+ interface StaticAsset {
56
+ content: string | (() => string);
57
+ contentType: string;
58
+ cacheControl: string;
59
+ etag?: string;
60
+ }
61
+ export interface PreparedPluginAssets {
62
+ routes: Map<string, StaticAsset>;
63
+ validPlugins: AdminUIPluginConfig[];
64
+ }
65
+ export declare const resolveAdminUIPath: () => string | null;
66
+ export declare const parseBundleExports: (bundle: string) => Set<string> | null;
67
+ export declare function preparePluginAssets(plugins: AdminUIPluginConfig[], log: {
68
+ info: (...args: any[]) => void;
69
+ warn: (...args: any[]) => void;
70
+ }, options?: {
71
+ devMode?: boolean;
72
+ }): PreparedPluginAssets;
73
+ export {};
@@ -0,0 +1,164 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFileSync, statSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
+ const PLUGIN_NAME_RE = /^[a-z0-9]([a-z0-9_-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9_-]*[a-z0-9])?)*$/i;
5
+ const IMMUTABLE_CACHE = 'public, max-age=31536000, immutable';
6
+ export const resolveAdminUIPath = () => {
7
+ try {
8
+ const staticURL = import.meta.resolve('@unchainedshop/admin-ui');
9
+ return new URL(staticURL).pathname.split('/').slice(0, -1).join('/');
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ };
15
+ const contentHash = (content) => createHash('sha256').update(content).digest('hex').slice(0, 8);
16
+ export const parseBundleExports = (bundle) => {
17
+ const returnMatch = bundle.match(/return __toCommonJS\(([\w$]+)\);/);
18
+ if (!returnMatch)
19
+ return null;
20
+ const blockMatch = bundle.match(new RegExp(`__export\\(${returnMatch[1].replace(/\$/g, '\\$')},\\s*\\{([\\s\\S]*?)\\}\\);`));
21
+ if (!blockMatch)
22
+ return null;
23
+ const names = new Set();
24
+ for (const m of blockMatch[1].matchAll(/(?:^|,)\s*(?:"([^"]+)"|([\w$]+)):\s*\(\)\s*=>/g)) {
25
+ names.add(m[1] ?? m[2]);
26
+ }
27
+ return names.size > 0 ? names : null;
28
+ };
29
+ const collectReferencedComponents = (plugin) => {
30
+ const names = new Set();
31
+ for (const [slotId, configs] of Object.entries(plugin.slots || {})) {
32
+ if (!Array.isArray(configs))
33
+ continue;
34
+ for (const config of configs) {
35
+ if (slotId === 'entities') {
36
+ const components = config.components;
37
+ if (components?.list)
38
+ names.add(components.list);
39
+ if (components?.detail)
40
+ names.add(components.detail);
41
+ if (components?.create)
42
+ names.add(components.create);
43
+ }
44
+ else if (typeof config.component === 'string') {
45
+ names.add(config.component);
46
+ }
47
+ }
48
+ }
49
+ return [...names];
50
+ };
51
+ export function preparePluginAssets(plugins, log, options = {}) {
52
+ const { devMode = false } = options;
53
+ const routes = new Map();
54
+ const devCacheControl = 'no-cache, no-store, must-revalidate';
55
+ const validPlugins = plugins.filter((p) => {
56
+ if (!PLUGIN_NAME_RE.test(p.name)) {
57
+ log.warn(`Skipping admin-ui plugin with invalid name: "${p.name}"`);
58
+ return false;
59
+ }
60
+ return true;
61
+ });
62
+ const seenNames = new Set();
63
+ for (const plugin of validPlugins) {
64
+ if (seenNames.has(plugin.name)) {
65
+ log.warn(`Duplicate admin-ui plugin name "${plugin.name}": later entries override earlier ones`);
66
+ }
67
+ seenNames.add(plugin.name);
68
+ }
69
+ if (validPlugins.length > 0) {
70
+ const pluginList = validPlugins
71
+ .map((p) => `${p.name}${p.version ? `@${p.version}` : ''}`)
72
+ .join(', ');
73
+ log.info(`Loading ${validPlugins.length} admin-ui plugin(s): ${pluginList}`);
74
+ }
75
+ const resolvedBundlePaths = new Map();
76
+ const pluginBundles = new Map();
77
+ for (const plugin of validPlugins) {
78
+ try {
79
+ const bundlePath = resolve(plugin.bundlePath);
80
+ const content = readFileSync(bundlePath, 'utf-8');
81
+ resolvedBundlePaths.set(plugin.name, bundlePath);
82
+ pluginBundles.set(plugin.name, { content, hash: contentHash(content) });
83
+ }
84
+ catch (err) {
85
+ log.warn(`Failed to read bundle for plugin "${plugin.name}" at ${plugin.bundlePath}: ${err.message}`);
86
+ }
87
+ }
88
+ const pluginsWithBundles = validPlugins.filter((p) => pluginBundles.has(p.name));
89
+ for (const plugin of pluginsWithBundles) {
90
+ const exportNames = parseBundleExports(pluginBundles.get(plugin.name).content);
91
+ if (!exportNames)
92
+ continue;
93
+ const missing = collectReferencedComponents(plugin).filter((name) => !exportNames.has(name));
94
+ if (missing.length > 0) {
95
+ log.warn(`admin-ui plugin "${plugin.name}" references component(s) not exported by its bundle: ${missing.join(', ')}. Exported: ${[...exportNames].join(', ')}`);
96
+ }
97
+ }
98
+ const bundleMtimes = new Map();
99
+ const bundleHashes = new Map();
100
+ for (const [name, bundle] of pluginBundles) {
101
+ bundleHashes.set(name, bundle.hash);
102
+ try {
103
+ bundleMtimes.set(name, statSync(resolvedBundlePaths.get(name)).mtimeMs);
104
+ }
105
+ catch {
106
+ }
107
+ }
108
+ const refreshBundleHash = (name) => {
109
+ const bundlePath = resolvedBundlePaths.get(name);
110
+ try {
111
+ const currentMtime = statSync(bundlePath).mtimeMs;
112
+ const cachedMtime = bundleMtimes.get(name);
113
+ if (cachedMtime !== undefined && cachedMtime === currentMtime) {
114
+ return bundleHashes.get(name);
115
+ }
116
+ const hash = contentHash(readFileSync(bundlePath, 'utf-8'));
117
+ bundleMtimes.set(name, currentMtime);
118
+ bundleHashes.set(name, hash);
119
+ return hash;
120
+ }
121
+ catch {
122
+ return bundleHashes.get(name) ?? pluginBundles.get(name).hash;
123
+ }
124
+ };
125
+ const buildManifestJSON = () => JSON.stringify(pluginsWithBundles.map((plugin) => ({
126
+ ...Object.fromEntries(Object.entries(plugin).filter(([k]) => k !== 'bundlePath')),
127
+ bundleUrl: `/admin-plugins/${plugin.name}.js?v=${devMode ? refreshBundleHash(plugin.name) : pluginBundles.get(plugin.name).hash}`,
128
+ })));
129
+ if (devMode) {
130
+ routes.set('/admin-ui-plugins.json', {
131
+ content: buildManifestJSON,
132
+ contentType: 'application/json',
133
+ cacheControl: devCacheControl,
134
+ });
135
+ }
136
+ else {
137
+ const manifestJSON = buildManifestJSON();
138
+ routes.set('/admin-ui-plugins.json', {
139
+ content: manifestJSON,
140
+ contentType: 'application/json',
141
+ cacheControl: 'public, max-age=0, must-revalidate',
142
+ etag: `"${contentHash(manifestJSON)}"`,
143
+ });
144
+ }
145
+ for (const plugin of pluginsWithBundles) {
146
+ const bundlePath = resolvedBundlePaths.get(plugin.name);
147
+ if (devMode) {
148
+ routes.set(`/admin-plugins/${plugin.name}.js`, {
149
+ content: () => readFileSync(bundlePath, 'utf-8'),
150
+ contentType: 'application/javascript',
151
+ cacheControl: devCacheControl,
152
+ });
153
+ }
154
+ else {
155
+ const { content } = pluginBundles.get(plugin.name);
156
+ routes.set(`/admin-plugins/${plugin.name}.js`, {
157
+ content,
158
+ contentType: 'application/javascript',
159
+ cacheControl: IMMUTABLE_CACHE,
160
+ });
161
+ }
162
+ }
163
+ return { routes, validPlugins };
164
+ }
@@ -0,0 +1,25 @@
1
+ export interface AdminUIThemeTokens {
2
+ surface?: string;
3
+ 'surface-subtle'?: string;
4
+ 'surface-raised'?: string;
5
+ 'surface-input'?: string;
6
+ border?: string;
7
+ 'border-subtle'?: string;
8
+ 'text-primary'?: string;
9
+ 'text-secondary'?: string;
10
+ 'text-muted'?: string;
11
+ 'text-on-dark'?: string;
12
+ accent?: string;
13
+ 'accent-hover'?: string;
14
+ danger?: string;
15
+ 'danger-surface'?: string;
16
+ success?: string;
17
+ warning?: string;
18
+ 'focus-ring'?: string;
19
+ 'text-on-accent'?: string;
20
+ }
21
+ export interface AdminUIThemeConfig {
22
+ light?: AdminUIThemeTokens;
23
+ dark?: AdminUIThemeTokens;
24
+ }
25
+ export declare const generateThemeCSS: (theme?: AdminUIThemeConfig) => string;
@@ -0,0 +1,34 @@
1
+ const CSS_VALUE_RE = /^[a-zA-Z0-9#().,/%\s\-_]+$/;
2
+ const sanitizeCSSValue = (value) => {
3
+ const trimmed = value.trim();
4
+ if (!trimmed || !CSS_VALUE_RE.test(trimmed))
5
+ return null;
6
+ return trimmed;
7
+ };
8
+ const buildTokenBlock = (selector, tokens) => {
9
+ const vars = Object.entries(tokens)
10
+ .map(([key, value]) => {
11
+ const safe = sanitizeCSSValue(value);
12
+ return safe ? ` --token-${key}: ${safe};` : null;
13
+ })
14
+ .filter(Boolean);
15
+ if (vars.length === 0)
16
+ return null;
17
+ return `${selector} {\n${vars.join('\n')}\n}`;
18
+ };
19
+ export const generateThemeCSS = (theme) => {
20
+ if (!theme)
21
+ return '/* default theme */';
22
+ const blocks = [];
23
+ if (theme.light) {
24
+ const block = buildTokenBlock(':root:root', theme.light);
25
+ if (block)
26
+ blocks.push(block);
27
+ }
28
+ if (theme.dark) {
29
+ const block = buildTokenBlock('.dark.dark', theme.dark);
30
+ if (block)
31
+ blocks.push(block);
32
+ }
33
+ return blocks.length > 0 ? blocks.join('\n\n') : '/* default theme */';
34
+ };
@@ -2,11 +2,277 @@ import type * as aiTypes from 'ai';
2
2
  declare const generateImageHandler: (req: any) => ({ model, uploadUrl, }: {
3
3
  model: aiTypes.ImageModel;
4
4
  uploadUrl?: string;
5
- }) => aiTypes.Tool<{
6
- prompt: string;
7
- size?: "512x512" | "768x768" | "1024x1024" | "512x896" | "640x1120" | "768x1344" | "1024x1792" | "896x512" | "1120x640" | "1344x768" | "1792x1024" | undefined;
8
- }, string | {
9
- imageUrl: any;
10
- prompt: string;
11
- }>;
5
+ }) => ({
6
+ title?: string;
7
+ providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
8
+ metadata?: import("@ai-sdk/provider").JSONObject;
9
+ inputSchema: aiTypes.FlexibleSchema<{
10
+ prompt: any;
11
+ size?: string | undefined;
12
+ }>;
13
+ contextSchema?: aiTypes.FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
14
+ needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
15
+ prompt: any;
16
+ size?: string | undefined;
17
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
18
+ onInputStart?: ((options: aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
19
+ onInputDelta?: ((options: {
20
+ inputTextDelta: string;
21
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
22
+ onInputAvailable?: ((options: {
23
+ input: {
24
+ prompt: any;
25
+ size?: string | undefined;
26
+ };
27
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
28
+ toModelOutput?: ((options: {
29
+ toolCallId: string;
30
+ input: {
31
+ prompt: any;
32
+ size?: string | undefined;
33
+ };
34
+ output: NoInfer<string | {
35
+ imageUrl: any;
36
+ prompt: any;
37
+ }>;
38
+ }) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
39
+ } & {
40
+ outputSchema?: aiTypes.FlexibleSchema<string | {
41
+ imageUrl: any;
42
+ prompt: any;
43
+ }> | undefined;
44
+ execute: aiTypes.ToolExecuteFunction<{
45
+ prompt: any;
46
+ size?: string | undefined;
47
+ }, string | {
48
+ imageUrl: any;
49
+ prompt: any;
50
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
51
+ } & {
52
+ description?: string | ((options: {
53
+ context: NoInfer<import("@ai-sdk/provider-utils").Context>;
54
+ experimental_sandbox?: aiTypes.Experimental_SandboxSession;
55
+ }) => string) | undefined;
56
+ strict?: boolean;
57
+ inputExamples?: {
58
+ input: NoInfer<{
59
+ prompt: any;
60
+ size?: string | undefined;
61
+ }>;
62
+ }[] | undefined;
63
+ id?: never;
64
+ isProviderExecuted?: never;
65
+ args?: never;
66
+ supportsDeferredResults?: never;
67
+ } & {
68
+ type?: undefined | "function";
69
+ } & {
70
+ execute: aiTypes.ToolExecuteFunction<{
71
+ prompt: any;
72
+ size?: string | undefined;
73
+ }, string | {
74
+ imageUrl: any;
75
+ prompt: any;
76
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
77
+ }) | ({
78
+ title?: string;
79
+ providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
80
+ metadata?: import("@ai-sdk/provider").JSONObject;
81
+ inputSchema: aiTypes.FlexibleSchema<{
82
+ prompt: any;
83
+ size?: string | undefined;
84
+ }>;
85
+ contextSchema?: aiTypes.FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
86
+ needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
87
+ prompt: any;
88
+ size?: string | undefined;
89
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
90
+ onInputStart?: ((options: aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
91
+ onInputDelta?: ((options: {
92
+ inputTextDelta: string;
93
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
94
+ onInputAvailable?: ((options: {
95
+ input: {
96
+ prompt: any;
97
+ size?: string | undefined;
98
+ };
99
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
100
+ toModelOutput?: ((options: {
101
+ toolCallId: string;
102
+ input: {
103
+ prompt: any;
104
+ size?: string | undefined;
105
+ };
106
+ output: NoInfer<string | {
107
+ imageUrl: any;
108
+ prompt: any;
109
+ }>;
110
+ }) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
111
+ } & {
112
+ outputSchema?: aiTypes.FlexibleSchema<string | {
113
+ imageUrl: any;
114
+ prompt: any;
115
+ }> | undefined;
116
+ execute: aiTypes.ToolExecuteFunction<{
117
+ prompt: any;
118
+ size?: string | undefined;
119
+ }, string | {
120
+ imageUrl: any;
121
+ prompt: any;
122
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
123
+ } & {
124
+ description?: string | ((options: {
125
+ context: NoInfer<import("@ai-sdk/provider-utils").Context>;
126
+ experimental_sandbox?: aiTypes.Experimental_SandboxSession;
127
+ }) => string) | undefined;
128
+ strict?: boolean;
129
+ inputExamples?: {
130
+ input: NoInfer<{
131
+ prompt: any;
132
+ size?: string | undefined;
133
+ }>;
134
+ }[] | undefined;
135
+ id?: never;
136
+ isProviderExecuted?: never;
137
+ args?: never;
138
+ supportsDeferredResults?: never;
139
+ } & {
140
+ type: "dynamic";
141
+ } & {
142
+ execute: aiTypes.ToolExecuteFunction<{
143
+ prompt: any;
144
+ size?: string | undefined;
145
+ }, string | {
146
+ imageUrl: any;
147
+ prompt: any;
148
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
149
+ }) | ({
150
+ title?: string;
151
+ providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
152
+ metadata?: import("@ai-sdk/provider").JSONObject;
153
+ inputSchema: aiTypes.FlexibleSchema<{
154
+ prompt: any;
155
+ size?: string | undefined;
156
+ }>;
157
+ contextSchema?: aiTypes.FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
158
+ needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
159
+ prompt: any;
160
+ size?: string | undefined;
161
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
162
+ onInputStart?: ((options: aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
163
+ onInputDelta?: ((options: {
164
+ inputTextDelta: string;
165
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
166
+ onInputAvailable?: ((options: {
167
+ input: {
168
+ prompt: any;
169
+ size?: string | undefined;
170
+ };
171
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
172
+ toModelOutput?: ((options: {
173
+ toolCallId: string;
174
+ input: {
175
+ prompt: any;
176
+ size?: string | undefined;
177
+ };
178
+ output: NoInfer<string | {
179
+ imageUrl: any;
180
+ prompt: any;
181
+ }>;
182
+ }) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
183
+ } & {
184
+ outputSchema?: aiTypes.FlexibleSchema<string | {
185
+ imageUrl: any;
186
+ prompt: any;
187
+ }> | undefined;
188
+ execute: aiTypes.ToolExecuteFunction<{
189
+ prompt: any;
190
+ size?: string | undefined;
191
+ }, string | {
192
+ imageUrl: any;
193
+ prompt: any;
194
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
195
+ } & {
196
+ type: "provider";
197
+ id: `${string}.${string}`;
198
+ args: Record<string, unknown>;
199
+ description?: never;
200
+ strict?: never;
201
+ inputExamples?: never;
202
+ } & {
203
+ isProviderExecuted: false;
204
+ supportsDeferredResults?: never;
205
+ } & {
206
+ execute: aiTypes.ToolExecuteFunction<{
207
+ prompt: any;
208
+ size?: string | undefined;
209
+ }, string | {
210
+ imageUrl: any;
211
+ prompt: any;
212
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
213
+ }) | ({
214
+ title?: string;
215
+ providerOptions?: import("@ai-sdk/provider-utils").ProviderOptions;
216
+ metadata?: import("@ai-sdk/provider").JSONObject;
217
+ inputSchema: aiTypes.FlexibleSchema<{
218
+ prompt: any;
219
+ size?: string | undefined;
220
+ }>;
221
+ contextSchema?: aiTypes.FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
222
+ needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
223
+ prompt: any;
224
+ size?: string | undefined;
225
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>> | undefined;
226
+ onInputStart?: ((options: aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
227
+ onInputDelta?: ((options: {
228
+ inputTextDelta: string;
229
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
230
+ onInputAvailable?: ((options: {
231
+ input: {
232
+ prompt: any;
233
+ size?: string | undefined;
234
+ };
235
+ } & aiTypes.ToolExecutionOptions<NoInfer<import("@ai-sdk/provider-utils").Context>>) => void | PromiseLike<void>) | undefined;
236
+ toModelOutput?: ((options: {
237
+ toolCallId: string;
238
+ input: {
239
+ prompt: any;
240
+ size?: string | undefined;
241
+ };
242
+ output: NoInfer<string | {
243
+ imageUrl: any;
244
+ prompt: any;
245
+ }>;
246
+ }) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
247
+ } & {
248
+ outputSchema?: aiTypes.FlexibleSchema<string | {
249
+ imageUrl: any;
250
+ prompt: any;
251
+ }> | undefined;
252
+ execute: aiTypes.ToolExecuteFunction<{
253
+ prompt: any;
254
+ size?: string | undefined;
255
+ }, string | {
256
+ imageUrl: any;
257
+ prompt: any;
258
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
259
+ } & {
260
+ type: "provider";
261
+ id: `${string}.${string}`;
262
+ args: Record<string, unknown>;
263
+ description?: never;
264
+ strict?: never;
265
+ inputExamples?: never;
266
+ } & {
267
+ isProviderExecuted: true;
268
+ supportsDeferredResults?: boolean;
269
+ } & {
270
+ execute: aiTypes.ToolExecuteFunction<{
271
+ prompt: any;
272
+ size?: string | undefined;
273
+ }, string | {
274
+ imageUrl: any;
275
+ prompt: any;
276
+ }, NoInfer<import("@ai-sdk/provider-utils").Context>>;
277
+ });
12
278
  export default generateImageHandler;
@@ -1,4 +1,6 @@
1
1
  import type * as aiTypes from 'ai';
2
+ import type { ServerResponse } from 'node:http';
3
+ export declare const logOptionalPeerLoadError: (packageName: string, error: unknown) => void;
2
4
  export type StreamTextParams = Parameters<typeof aiTypes.streamText>[0];
3
5
  export type ChatConfiguration = Omit<StreamTextParams, 'messages'> & {
4
6
  unchainedMCPUrl?: string;
@@ -8,4 +10,10 @@ export type ChatConfiguration = Omit<StreamTextParams, 'messages'> & {
8
10
  };
9
11
  };
10
12
  export declare const errorHandler: (error: any) => string;
13
+ export declare const chatErrorStatus: (error: unknown) => number;
14
+ export declare const createChatRequestLifecycle: (response: ServerResponse, configuredSignal?: AbortSignal) => {
15
+ signal: AbortSignal;
16
+ setClientClose(closeClient: () => Promise<void>): void;
17
+ close: () => Promise<void>;
18
+ };
11
19
  export declare const categorizeTools: (toolName: string) => string;