orchid-ai 1.2.8 → 1.3.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/dist/cli/server/contextual-service.d.ts +1 -0
- package/dist/cli/types/types.d.ts +2 -0
- package/dist/index.esm.js +3 -3
- package/dist/index.js +3 -3
- package/dist/server/contextual-service.d.ts +1 -0
- package/dist/server/index.esm.js +17 -0
- package/dist/server/index.js +17 -0
- package/dist/server/server/contextual-service.d.ts +1 -0
- package/dist/server/types/types.d.ts +2 -0
- package/dist/types/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -483,6 +483,8 @@ export interface SchemaProperty {
|
|
|
483
483
|
maxLength?: number;
|
|
484
484
|
minimum?: number;
|
|
485
485
|
maximum?: number;
|
|
486
|
+
/** If true, this field is not to be generated by AI (e.g. auto-generated fields) */
|
|
487
|
+
skip?: boolean;
|
|
486
488
|
}
|
|
487
489
|
/**
|
|
488
490
|
* Simplified config for ContextualCommandService
|
package/dist/index.esm.js
CHANGED
|
@@ -3323,7 +3323,7 @@ theme, isOpen, }) {
|
|
|
3323
3323
|
}, [onModelSelectionChange]);
|
|
3324
3324
|
return (jsxs("div", { className: `px-3 py-2 border-t flex flex-col gap-2 transition-all duration-500 delay-500 ${isOpen ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`, style: { borderColor: theme.colors.border.primary }, children: [attachedFiles.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 mb-2", children: attachedFiles.map((file, index) => (jsxs("div", { className: "relative group", children: [jsx("div", { className: "w-16 h-16 rounded-lg border border-gray-200 bg-gray-50 flex items-center justify-center overflow-hidden", children: file.type.startsWith('image/') ? (jsx("img", { src: URL.createObjectURL(file), alt: `Attached ${index + 1}`, className: "w-full h-full object-cover" })) : (jsx("div", { className: "flex items-center justify-center", children: FileHandler.getFileIcon(file) })) }), jsx("button", { onClick: () => removeFile(index), className: "absolute -top-2 -right-2 w-5 h-5 bg-red-500 text-white rounded-full flex items-center justify-center text-xs hover:bg-red-600 transition-colors", title: "Remove file", children: "\u00D7" }), jsx("div", { className: "absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none z-10 mt-2", children: jsxs("div", { className: "bg-gray-900 text-white text-xs rounded-lg px-2 py-1 whitespace-nowrap shadow-lg", children: [jsx("div", { className: "font-medium truncate max-w-32", title: file.name, children: file.name }), jsxs("div", { className: "text-gray-300", children: [FileHandler.getFileTypeDescription(file), " \u2022", ' ', FileHandler.formatFileSize(file.size)] }), jsx("div", { className: "absolute -top-1 left-1/2 transform -translate-x-1/2 w-2 h-2 bg-gray-900 rotate-45" })] }) })] }, index))) })), incompatibleFiles.length > 0 && (jsxs("div", { className: "relative flex flex-col gap-1 text-sm text-orange-700 bg-orange-50 border border-orange-200 rounded px-3 py-2 mb-2", children: [jsx("button", { onClick: () => setIncompatibleFiles([]), className: "absolute top-1 right-1 w-5 h-5 flex items-center justify-center text-orange-500 hover:text-orange-700 hover:bg-orange-200 rounded-full transition-colors", title: "Dismiss", type: "button", children: "\u00D7" }), jsxs("div", { className: "flex items-center gap-2 pr-6", children: [jsx("span", { children: "\u26A0\uFE0F" }), jsx("span", { className: "font-medium", children: incompatibleFiles.length === 1
|
|
3325
3325
|
? 'File not supported'
|
|
3326
|
-
: 'Some files not supported' })] }), jsxs("div", { className: "text-xs", children: [jsx("div", { className: "mb-1", children: "These files were skipped:" }), jsxs("ul", { className: "list-disc list-inside ml-2 space-y-0.5", children: [incompatibleFiles.slice(0, 3).map((fileName, index) => (jsx("li", { className: "truncate", children: fileName }, index))), incompatibleFiles.length > 3 && (jsxs("li", { children: ["... and ", incompatibleFiles.length - 3, " more"] }))] }), jsxs("div", { className: "mt-1 text-orange-600", children: ["\uD83D\uDCA1 Only ", FileHandler.getAcceptedTypesDescription(), " are supported", incompatibleFiles.some((name) => name.includes('images not supported by current model')) && (
|
|
3326
|
+
: 'Some files not supported' })] }), jsxs("div", { className: "text-xs", children: [jsx("div", { className: "mb-1", children: "These files were skipped:" }), jsxs("ul", { className: "list-disc list-inside ml-2 space-y-0.5", children: [incompatibleFiles.slice(0, 3).map((fileName, index) => (jsx("li", { className: "truncate", children: fileName }, index))), incompatibleFiles.length > 3 && (jsxs("li", { children: ["... and ", incompatibleFiles.length - 3, " more"] }))] }), jsxs("div", { className: "mt-1 text-orange-600", children: ["\uD83D\uDCA1 Only ", FileHandler.getAcceptedTypesDescription(), " are supported", incompatibleFiles.some((name) => name.includes('images not supported by current model')) && (jsx("div", { className: "mt-1", children: "\uD83D\uDD04 Switch to a model showing the image icon in the model switcher to enable image uploads" }))] })] })] })), jsxs("div", { className: `relative flex flex-col gap-1 rounded border px-2 pt-1 pb-1 cursor-text transition-all duration-200 border-2 focus-within:shadow-sm ${isDragOver ? 'border-dashed bg-opacity-20' : 'border-transparent'}`, style: {
|
|
3327
3327
|
backgroundColor: theme.colors.surface.primary,
|
|
3328
3328
|
borderColor: isDragOver
|
|
3329
3329
|
? theme.colors.primary[400]
|
|
@@ -3350,7 +3350,7 @@ theme, isOpen, }) {
|
|
|
3350
3350
|
e.currentTarget.style.color = theme.colors.text.tertiary;
|
|
3351
3351
|
}, title: imageSupported
|
|
3352
3352
|
? 'Attach images - AI can analyze image content'
|
|
3353
|
-
: "Current model doesn't support images. Switch to GPT-4O, Claude
|
|
3353
|
+
: "Current model doesn't support images. Switch to GPT-4O, Claude, or Gemini to use image attachments.", tabIndex: -1, type: "button", onClick: () => imageSupported && imageInputRef.current?.click(), disabled: !imageSupported, children: jsx(Icon, { name: "image", size: "sm" }) })), jsx("button", { className: "p-1 cursor-pointer disabled:opacity-50 disabled:cursor-default transition-colors", style: { color: theme.colors.text.tertiary }, title: "Record audio (coming soon)", tabIndex: -1, type: "button", onClick: handleAudioRecord, disabled: true, children: jsx(Icon, { name: "microphone", size: "sm" }) })] }), jsx("button", { onClick: () => onSend(), disabled: (!query.trim() && attachedFiles.length === 0) || isLoading, className: "rounded-full transition disabled:opacity-50 p-2", style: {
|
|
3354
3354
|
color: theme.colors.text.primary,
|
|
3355
3355
|
}, onMouseEnter: (e) => {
|
|
3356
3356
|
if (!e.currentTarget.disabled) {
|
|
@@ -3365,7 +3365,7 @@ theme, isOpen, }) {
|
|
|
3365
3365
|
features.imageAnalysis !== false &&
|
|
3366
3366
|
features.enableImageUploads !== false &&
|
|
3367
3367
|
!imageSupported &&
|
|
3368
|
-
!imageTipDismissed && (jsxs("div", { className: "relative px-2 py-1 bg-amber-50 border border-amber-200 rounded text-amber-700 text-xs flex items-center gap-2", children: [jsx(Icon, { name: "image", size: "xs", className: "opacity-50" }), jsxs("span", { className: "flex-1 pr-4", children: ["\uD83D\uDCA1 ", jsx("strong", { children: "Tip:" }), " Switch to
|
|
3368
|
+
!imageTipDismissed && (jsxs("div", { className: "relative px-2 py-1 bg-amber-50 border border-amber-200 rounded text-amber-700 text-xs flex items-center gap-2", children: [jsx(Icon, { name: "image", size: "xs", className: "opacity-50" }), jsxs("span", { className: "flex-1 pr-4", children: ["\uD83D\uDCA1 ", jsx("strong", { children: "Tip:" }), " Switch to a model showing the image icon in the model switcher below to enable image uploads"] }), jsx("button", { onClick: () => setImageTipDismissed(true), className: "absolute top-1 right-1 w-4 h-4 flex items-center justify-center text-amber-500 hover:text-amber-700 hover:bg-amber-200 rounded-full transition-colors text-xs font-bold", title: "Dismiss tip", type: "button", children: "\u00D7" })] })), jsxs("div", { className: "flex items-center justify-between text-xs px-0 pt-0", style: { color: theme.colors.text.tertiary }, children: [jsx("div", { className: "flex gap-4", children: features.modelSwitching !== false && (jsx(ModelSwitcher, { models: models, defaultModel: defaultModel, showUsageStats: features.usageTracking !== false && showUsageStats !== false, theme: theme, onModelSelectionChange: modelSelectionHandler })) }), jsx("div", { className: "flex items-center gap-2", children: jsxs("span", { children: [jsx("kbd", { className: "px-1 rounded", style: {
|
|
3369
3369
|
backgroundColor: theme.colors.surface.secondary,
|
|
3370
3370
|
color: theme.colors.text.secondary,
|
|
3371
3371
|
}, children: "\u23CE" }), ' ', "to send,", ' ', jsx("kbd", { className: "px-1 rounded", style: {
|
package/dist/index.js
CHANGED
|
@@ -3325,7 +3325,7 @@ theme, isOpen, }) {
|
|
|
3325
3325
|
}, [onModelSelectionChange]);
|
|
3326
3326
|
return (jsxRuntime.jsxs("div", { className: `px-3 py-2 border-t flex flex-col gap-2 transition-all duration-500 delay-500 ${isOpen ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`, style: { borderColor: theme.colors.border.primary }, children: [attachedFiles.length > 0 && (jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 mb-2", children: attachedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: "relative group", children: [jsxRuntime.jsx("div", { className: "w-16 h-16 rounded-lg border border-gray-200 bg-gray-50 flex items-center justify-center overflow-hidden", children: file.type.startsWith('image/') ? (jsxRuntime.jsx("img", { src: URL.createObjectURL(file), alt: `Attached ${index + 1}`, className: "w-full h-full object-cover" })) : (jsxRuntime.jsx("div", { className: "flex items-center justify-center", children: FileHandler.getFileIcon(file) })) }), jsxRuntime.jsx("button", { onClick: () => removeFile(index), className: "absolute -top-2 -right-2 w-5 h-5 bg-red-500 text-white rounded-full flex items-center justify-center text-xs hover:bg-red-600 transition-colors", title: "Remove file", children: "\u00D7" }), jsxRuntime.jsx("div", { className: "absolute bottom-0 left-1/2 transform -translate-x-1/2 translate-y-full opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none z-10 mt-2", children: jsxRuntime.jsxs("div", { className: "bg-gray-900 text-white text-xs rounded-lg px-2 py-1 whitespace-nowrap shadow-lg", children: [jsxRuntime.jsx("div", { className: "font-medium truncate max-w-32", title: file.name, children: file.name }), jsxRuntime.jsxs("div", { className: "text-gray-300", children: [FileHandler.getFileTypeDescription(file), " \u2022", ' ', FileHandler.formatFileSize(file.size)] }), jsxRuntime.jsx("div", { className: "absolute -top-1 left-1/2 transform -translate-x-1/2 w-2 h-2 bg-gray-900 rotate-45" })] }) })] }, index))) })), incompatibleFiles.length > 0 && (jsxRuntime.jsxs("div", { className: "relative flex flex-col gap-1 text-sm text-orange-700 bg-orange-50 border border-orange-200 rounded px-3 py-2 mb-2", children: [jsxRuntime.jsx("button", { onClick: () => setIncompatibleFiles([]), className: "absolute top-1 right-1 w-5 h-5 flex items-center justify-center text-orange-500 hover:text-orange-700 hover:bg-orange-200 rounded-full transition-colors", title: "Dismiss", type: "button", children: "\u00D7" }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pr-6", children: [jsxRuntime.jsx("span", { children: "\u26A0\uFE0F" }), jsxRuntime.jsx("span", { className: "font-medium", children: incompatibleFiles.length === 1
|
|
3327
3327
|
? 'File not supported'
|
|
3328
|
-
: 'Some files not supported' })] }), jsxRuntime.jsxs("div", { className: "text-xs", children: [jsxRuntime.jsx("div", { className: "mb-1", children: "These files were skipped:" }), jsxRuntime.jsxs("ul", { className: "list-disc list-inside ml-2 space-y-0.5", children: [incompatibleFiles.slice(0, 3).map((fileName, index) => (jsxRuntime.jsx("li", { className: "truncate", children: fileName }, index))), incompatibleFiles.length > 3 && (jsxRuntime.jsxs("li", { children: ["... and ", incompatibleFiles.length - 3, " more"] }))] }), jsxRuntime.jsxs("div", { className: "mt-1 text-orange-600", children: ["\uD83D\uDCA1 Only ", FileHandler.getAcceptedTypesDescription(), " are supported", incompatibleFiles.some((name) => name.includes('images not supported by current model')) && (jsxRuntime.
|
|
3328
|
+
: 'Some files not supported' })] }), jsxRuntime.jsxs("div", { className: "text-xs", children: [jsxRuntime.jsx("div", { className: "mb-1", children: "These files were skipped:" }), jsxRuntime.jsxs("ul", { className: "list-disc list-inside ml-2 space-y-0.5", children: [incompatibleFiles.slice(0, 3).map((fileName, index) => (jsxRuntime.jsx("li", { className: "truncate", children: fileName }, index))), incompatibleFiles.length > 3 && (jsxRuntime.jsxs("li", { children: ["... and ", incompatibleFiles.length - 3, " more"] }))] }), jsxRuntime.jsxs("div", { className: "mt-1 text-orange-600", children: ["\uD83D\uDCA1 Only ", FileHandler.getAcceptedTypesDescription(), " are supported", incompatibleFiles.some((name) => name.includes('images not supported by current model')) && (jsxRuntime.jsx("div", { className: "mt-1", children: "\uD83D\uDD04 Switch to a model showing the image icon in the model switcher to enable image uploads" }))] })] })] })), jsxRuntime.jsxs("div", { className: `relative flex flex-col gap-1 rounded border px-2 pt-1 pb-1 cursor-text transition-all duration-200 border-2 focus-within:shadow-sm ${isDragOver ? 'border-dashed bg-opacity-20' : 'border-transparent'}`, style: {
|
|
3329
3329
|
backgroundColor: theme.colors.surface.primary,
|
|
3330
3330
|
borderColor: isDragOver
|
|
3331
3331
|
? theme.colors.primary[400]
|
|
@@ -3352,7 +3352,7 @@ theme, isOpen, }) {
|
|
|
3352
3352
|
e.currentTarget.style.color = theme.colors.text.tertiary;
|
|
3353
3353
|
}, title: imageSupported
|
|
3354
3354
|
? 'Attach images - AI can analyze image content'
|
|
3355
|
-
: "Current model doesn't support images. Switch to GPT-4O, Claude
|
|
3355
|
+
: "Current model doesn't support images. Switch to GPT-4O, Claude, or Gemini to use image attachments.", tabIndex: -1, type: "button", onClick: () => imageSupported && imageInputRef.current?.click(), disabled: !imageSupported, children: jsxRuntime.jsx(Icon, { name: "image", size: "sm" }) })), jsxRuntime.jsx("button", { className: "p-1 cursor-pointer disabled:opacity-50 disabled:cursor-default transition-colors", style: { color: theme.colors.text.tertiary }, title: "Record audio (coming soon)", tabIndex: -1, type: "button", onClick: handleAudioRecord, disabled: true, children: jsxRuntime.jsx(Icon, { name: "microphone", size: "sm" }) })] }), jsxRuntime.jsx("button", { onClick: () => onSend(), disabled: (!query.trim() && attachedFiles.length === 0) || isLoading, className: "rounded-full transition disabled:opacity-50 p-2", style: {
|
|
3356
3356
|
color: theme.colors.text.primary,
|
|
3357
3357
|
}, onMouseEnter: (e) => {
|
|
3358
3358
|
if (!e.currentTarget.disabled) {
|
|
@@ -3367,7 +3367,7 @@ theme, isOpen, }) {
|
|
|
3367
3367
|
features.imageAnalysis !== false &&
|
|
3368
3368
|
features.enableImageUploads !== false &&
|
|
3369
3369
|
!imageSupported &&
|
|
3370
|
-
!imageTipDismissed && (jsxRuntime.jsxs("div", { className: "relative px-2 py-1 bg-amber-50 border border-amber-200 rounded text-amber-700 text-xs flex items-center gap-2", children: [jsxRuntime.jsx(Icon, { name: "image", size: "xs", className: "opacity-50" }), jsxRuntime.jsxs("span", { className: "flex-1 pr-4", children: ["\uD83D\uDCA1 ", jsxRuntime.jsx("strong", { children: "Tip:" }), " Switch to
|
|
3370
|
+
!imageTipDismissed && (jsxRuntime.jsxs("div", { className: "relative px-2 py-1 bg-amber-50 border border-amber-200 rounded text-amber-700 text-xs flex items-center gap-2", children: [jsxRuntime.jsx(Icon, { name: "image", size: "xs", className: "opacity-50" }), jsxRuntime.jsxs("span", { className: "flex-1 pr-4", children: ["\uD83D\uDCA1 ", jsxRuntime.jsx("strong", { children: "Tip:" }), " Switch to a model showing the image icon in the model switcher below to enable image uploads"] }), jsxRuntime.jsx("button", { onClick: () => setImageTipDismissed(true), className: "absolute top-1 right-1 w-4 h-4 flex items-center justify-center text-amber-500 hover:text-amber-700 hover:bg-amber-200 rounded-full transition-colors text-xs font-bold", title: "Dismiss tip", type: "button", children: "\u00D7" })] })), jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs px-0 pt-0", style: { color: theme.colors.text.tertiary }, children: [jsxRuntime.jsx("div", { className: "flex gap-4", children: features.modelSwitching !== false && (jsxRuntime.jsx(ModelSwitcher, { models: models, defaultModel: defaultModel, showUsageStats: features.usageTracking !== false && showUsageStats !== false, theme: theme, onModelSelectionChange: modelSelectionHandler })) }), jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx("kbd", { className: "px-1 rounded", style: {
|
|
3371
3371
|
backgroundColor: theme.colors.surface.secondary,
|
|
3372
3372
|
color: theme.colors.text.secondary,
|
|
3373
3373
|
}, children: "\u23CE" }), ' ', "to send,", ' ', jsxRuntime.jsx("kbd", { className: "px-1 rounded", style: {
|
package/dist/server/index.esm.js
CHANGED
|
@@ -8231,6 +8231,10 @@ function sanitizeFormData(formData, schema) {
|
|
|
8231
8231
|
// If schema is provided, use it for validation
|
|
8232
8232
|
if (schema && schema.properties && schema.properties[key]) {
|
|
8233
8233
|
const fieldSchema = schema.properties[key];
|
|
8234
|
+
// Skip client-generated fields - they should not be included in formState
|
|
8235
|
+
if (fieldSchema.skip) {
|
|
8236
|
+
return; // Skip this field
|
|
8237
|
+
}
|
|
8234
8238
|
sanitized[key] = validateAndConvertField(value, fieldSchema);
|
|
8235
8239
|
}
|
|
8236
8240
|
else {
|
|
@@ -13486,6 +13490,7 @@ ${allRoutesInfo}
|
|
|
13486
13490
|
- Match exact field names and types from the chosen schema
|
|
13487
13491
|
- Respect required vs optional fields
|
|
13488
13492
|
- If a field has enum values, only use those exact values
|
|
13493
|
+
- **DO NOT generate fields marked with skip: true** - these are auto-generated on the client side and should never appear in your suggestions
|
|
13489
13494
|
|
|
13490
13495
|
**🚨 CRITICAL CURRENCY FORMATTING:**
|
|
13491
13496
|
- ALL currency amounts (amount, buyRate, sellRate) MUST be NUMBERS in CENTS
|
|
@@ -13565,6 +13570,7 @@ ${this.formatSchemaFields(singleSchema)}${routesInfo}
|
|
|
13565
13570
|
- For nested objects/arrays, follow the nested schema structure
|
|
13566
13571
|
- If a field has enum values, only use those exact values
|
|
13567
13572
|
- When suggesting navigation, use the routes defined in the schema above
|
|
13573
|
+
- **DO NOT generate fields marked with skip: true** - these are auto-generated on the client side and should never appear in your suggestions
|
|
13568
13574
|
|
|
13569
13575
|
**🚨 CRITICAL CURRENCY FORMATTING:**
|
|
13570
13576
|
- ALL currency amounts (amount, buyRate, sellRate) MUST be NUMBERS in CENTS
|
|
@@ -13589,10 +13595,17 @@ ${additionalContext}
|
|
|
13589
13595
|
}
|
|
13590
13596
|
/**
|
|
13591
13597
|
* Format schema fields into readable descriptions
|
|
13598
|
+
* Excludes client-generated fields from the output
|
|
13592
13599
|
*/
|
|
13593
13600
|
formatSchemaFields(schema) {
|
|
13594
13601
|
const fields = [];
|
|
13602
|
+
const clientGeneratedFields = [];
|
|
13595
13603
|
for (const [fieldName, fieldDef] of Object.entries(schema.properties || {})) {
|
|
13604
|
+
// Skip client-generated fields - they should not be shown to AI
|
|
13605
|
+
if (typeof fieldDef === 'object' && fieldDef.skip) {
|
|
13606
|
+
clientGeneratedFields.push(fieldName);
|
|
13607
|
+
continue;
|
|
13608
|
+
}
|
|
13596
13609
|
const required = schema.required?.includes(fieldName) ? '**REQUIRED**' : 'optional';
|
|
13597
13610
|
const type = typeof fieldDef === 'object' ? fieldDef.type || 'unknown' : 'unknown';
|
|
13598
13611
|
const description = typeof fieldDef === 'object' ? fieldDef.description || '' : '';
|
|
@@ -13601,6 +13614,10 @@ ${additionalContext}
|
|
|
13601
13614
|
: '';
|
|
13602
13615
|
fields.push(`- **${fieldName}** (${type}) ${required}${enumValues}${description ? `: ${description}` : ''}`);
|
|
13603
13616
|
}
|
|
13617
|
+
// Add note about client-generated fields if any exist
|
|
13618
|
+
if (clientGeneratedFields.length > 0) {
|
|
13619
|
+
fields.push(`\n**NOTE:** The following fields are auto-generated on the client side and should NOT be included in your suggestions: ${clientGeneratedFields.join(', ')}`);
|
|
13620
|
+
}
|
|
13604
13621
|
return fields.join('\n');
|
|
13605
13622
|
}
|
|
13606
13623
|
/**
|
package/dist/server/index.js
CHANGED
|
@@ -8251,6 +8251,10 @@ function sanitizeFormData(formData, schema) {
|
|
|
8251
8251
|
// If schema is provided, use it for validation
|
|
8252
8252
|
if (schema && schema.properties && schema.properties[key]) {
|
|
8253
8253
|
const fieldSchema = schema.properties[key];
|
|
8254
|
+
// Skip client-generated fields - they should not be included in formState
|
|
8255
|
+
if (fieldSchema.skip) {
|
|
8256
|
+
return; // Skip this field
|
|
8257
|
+
}
|
|
8254
8258
|
sanitized[key] = validateAndConvertField(value, fieldSchema);
|
|
8255
8259
|
}
|
|
8256
8260
|
else {
|
|
@@ -13506,6 +13510,7 @@ ${allRoutesInfo}
|
|
|
13506
13510
|
- Match exact field names and types from the chosen schema
|
|
13507
13511
|
- Respect required vs optional fields
|
|
13508
13512
|
- If a field has enum values, only use those exact values
|
|
13513
|
+
- **DO NOT generate fields marked with skip: true** - these are auto-generated on the client side and should never appear in your suggestions
|
|
13509
13514
|
|
|
13510
13515
|
**🚨 CRITICAL CURRENCY FORMATTING:**
|
|
13511
13516
|
- ALL currency amounts (amount, buyRate, sellRate) MUST be NUMBERS in CENTS
|
|
@@ -13585,6 +13590,7 @@ ${this.formatSchemaFields(singleSchema)}${routesInfo}
|
|
|
13585
13590
|
- For nested objects/arrays, follow the nested schema structure
|
|
13586
13591
|
- If a field has enum values, only use those exact values
|
|
13587
13592
|
- When suggesting navigation, use the routes defined in the schema above
|
|
13593
|
+
- **DO NOT generate fields marked with skip: true** - these are auto-generated on the client side and should never appear in your suggestions
|
|
13588
13594
|
|
|
13589
13595
|
**🚨 CRITICAL CURRENCY FORMATTING:**
|
|
13590
13596
|
- ALL currency amounts (amount, buyRate, sellRate) MUST be NUMBERS in CENTS
|
|
@@ -13609,10 +13615,17 @@ ${additionalContext}
|
|
|
13609
13615
|
}
|
|
13610
13616
|
/**
|
|
13611
13617
|
* Format schema fields into readable descriptions
|
|
13618
|
+
* Excludes client-generated fields from the output
|
|
13612
13619
|
*/
|
|
13613
13620
|
formatSchemaFields(schema) {
|
|
13614
13621
|
const fields = [];
|
|
13622
|
+
const clientGeneratedFields = [];
|
|
13615
13623
|
for (const [fieldName, fieldDef] of Object.entries(schema.properties || {})) {
|
|
13624
|
+
// Skip client-generated fields - they should not be shown to AI
|
|
13625
|
+
if (typeof fieldDef === 'object' && fieldDef.skip) {
|
|
13626
|
+
clientGeneratedFields.push(fieldName);
|
|
13627
|
+
continue;
|
|
13628
|
+
}
|
|
13616
13629
|
const required = schema.required?.includes(fieldName) ? '**REQUIRED**' : 'optional';
|
|
13617
13630
|
const type = typeof fieldDef === 'object' ? fieldDef.type || 'unknown' : 'unknown';
|
|
13618
13631
|
const description = typeof fieldDef === 'object' ? fieldDef.description || '' : '';
|
|
@@ -13621,6 +13634,10 @@ ${additionalContext}
|
|
|
13621
13634
|
: '';
|
|
13622
13635
|
fields.push(`- **${fieldName}** (${type}) ${required}${enumValues}${description ? `: ${description}` : ''}`);
|
|
13623
13636
|
}
|
|
13637
|
+
// Add note about client-generated fields if any exist
|
|
13638
|
+
if (clientGeneratedFields.length > 0) {
|
|
13639
|
+
fields.push(`\n**NOTE:** The following fields are auto-generated on the client side and should NOT be included in your suggestions: ${clientGeneratedFields.join(', ')}`);
|
|
13640
|
+
}
|
|
13624
13641
|
return fields.join('\n');
|
|
13625
13642
|
}
|
|
13626
13643
|
/**
|
|
@@ -483,6 +483,8 @@ export interface SchemaProperty {
|
|
|
483
483
|
maxLength?: number;
|
|
484
484
|
minimum?: number;
|
|
485
485
|
maximum?: number;
|
|
486
|
+
/** If true, this field is not to be generated by AI (e.g. auto-generated fields) */
|
|
487
|
+
skip?: boolean;
|
|
486
488
|
}
|
|
487
489
|
/**
|
|
488
490
|
* Simplified config for ContextualCommandService
|
package/dist/types/types.d.ts
CHANGED
|
@@ -483,6 +483,8 @@ export interface SchemaProperty {
|
|
|
483
483
|
maxLength?: number;
|
|
484
484
|
minimum?: number;
|
|
485
485
|
maximum?: number;
|
|
486
|
+
/** If true, this field is not to be generated by AI (e.g. auto-generated fields) */
|
|
487
|
+
skip?: boolean;
|
|
486
488
|
}
|
|
487
489
|
/**
|
|
488
490
|
* Simplified config for ContextualCommandService
|