orchid-ai 1.2.5 → 1.2.8

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.
@@ -1,4 +1,5 @@
1
1
  import type { ModelCapabilities } from '../types/types';
2
+ import type { ServerConfig } from '../types/types';
2
3
  /**
3
4
  * Hook to resolve tier-based default model config to actual model
4
5
  *
@@ -8,13 +9,14 @@ import type { ModelCapabilities } from '../types/types';
8
9
  * match for the provider and tier combination.
9
10
  *
10
11
  * @param defaultModel - The model configuration to resolve
12
+ * @param serverConfig - Optional server config to build the models endpoint URL
11
13
  * @returns The resolved model with provider, model name, and capabilities
12
14
  */
13
15
  export declare function useResolvedDefaultModel(defaultModel?: {
14
16
  provider: string;
15
17
  model?: string;
16
18
  tier?: 'fast' | 'balanced' | 'powerful';
17
- }): {
19
+ }, serverConfig?: ServerConfig): {
18
20
  provider: string;
19
21
  model: string;
20
22
  capabilities: ModelCapabilities;
@@ -10,5 +10,5 @@ export { mergeWithAi } from './utils';
10
10
  export { useAiMerge } from './hooks/useAiMerge';
11
11
  export { ErrorBoundary } from './components/ErrorBoundary';
12
12
  export { Icon as CommandIcon } from './components/Icon';
13
- export type { CommandConfig, TrainingData, AIProvider, CommandTheme, CommandSuggestion, CommandPopupProps, ChatMessage, ChatTheme, AIStatus, Action, ModelInfo, ServerConfig, SchemaDefinition, SchemaProperty, ContextualServiceConfig, ContextualRequest, } from './types/types';
13
+ export type { CommandConfig, TrainingData, AIProvider, CommandTheme, CommandSuggestion, CommandPopupProps, ChatMessage, ChatTheme, AIStatus, Action, ModelInfo, ServerConfig, ClientConfig, SchemaDefinition, SchemaProperty, ContextualServiceConfig, ContextualRequest, } from './types/types';
14
14
  export { defaultTheme as defaultCommandTheme } from './constants';
@@ -134,6 +134,24 @@ export interface ServerConfig {
134
134
  additionalContext?: string;
135
135
  stayOnPage?: boolean;
136
136
  }
137
+ export interface ClientConfig {
138
+ models?: Record<string, ModelInfo[]>;
139
+ defaultModel?: {
140
+ provider: string;
141
+ model?: string;
142
+ tier?: 'fast' | 'balanced' | 'powerful';
143
+ };
144
+ showUsageStats?: boolean;
145
+ maxFileSize?: string;
146
+ features?: {
147
+ modelSwitching?: boolean;
148
+ usageTracking?: boolean;
149
+ imageAnalysis?: boolean;
150
+ fileUploads?: boolean;
151
+ enableImageUploads?: boolean;
152
+ };
153
+ schemas?: Record<string, SchemaDefinition>;
154
+ }
137
155
  export interface TrainingDataPaths {
138
156
  components: string[];
139
157
  schemas: string[];
@@ -1,4 +1,5 @@
1
1
  import type { ModelCapabilities } from '../types/types';
2
+ import type { ServerConfig } from '../types/types';
2
3
  /**
3
4
  * Hook to resolve tier-based default model config to actual model
4
5
  *
@@ -8,13 +9,14 @@ import type { ModelCapabilities } from '../types/types';
8
9
  * match for the provider and tier combination.
9
10
  *
10
11
  * @param defaultModel - The model configuration to resolve
12
+ * @param serverConfig - Optional server config to build the models endpoint URL
11
13
  * @returns The resolved model with provider, model name, and capabilities
12
14
  */
13
15
  export declare function useResolvedDefaultModel(defaultModel?: {
14
16
  provider: string;
15
17
  model?: string;
16
18
  tier?: 'fast' | 'balanced' | 'powerful';
17
- }): {
19
+ }, serverConfig?: ServerConfig): {
18
20
  provider: string;
19
21
  model: string;
20
22
  capabilities: ModelCapabilities;
package/dist/index.d.ts CHANGED
@@ -10,5 +10,5 @@ export { mergeWithAi } from './utils';
10
10
  export { useAiMerge } from './hooks/useAiMerge';
11
11
  export { ErrorBoundary } from './components/ErrorBoundary';
12
12
  export { Icon as CommandIcon } from './components/Icon';
13
- export type { CommandConfig, TrainingData, AIProvider, CommandTheme, CommandSuggestion, CommandPopupProps, ChatMessage, ChatTheme, AIStatus, Action, ModelInfo, ServerConfig, SchemaDefinition, SchemaProperty, ContextualServiceConfig, ContextualRequest, } from './types/types';
13
+ export type { CommandConfig, TrainingData, AIProvider, CommandTheme, CommandSuggestion, CommandPopupProps, ChatMessage, ChatTheme, AIStatus, Action, ModelInfo, ServerConfig, ClientConfig, SchemaDefinition, SchemaProperty, ContextualServiceConfig, ContextualRequest, } from './types/types';
14
14
  export { defaultTheme as defaultCommandTheme } from './constants';
package/dist/index.esm.js CHANGED
@@ -1100,6 +1100,22 @@ function useDebouncedSuggestions(query, options) {
1100
1100
  };
1101
1101
  }
1102
1102
 
1103
+ // Helper function to build URL from config (reused from useModelSwitcher)
1104
+ function buildUrlFromConfig$1(config) {
1105
+ if (!config)
1106
+ return '';
1107
+ const suffix = config.suffix || '';
1108
+ if (suffix.startsWith('http://') || suffix.startsWith('https://')) {
1109
+ return suffix;
1110
+ }
1111
+ if (typeof window === 'undefined') {
1112
+ return suffix;
1113
+ }
1114
+ const protocol = window.location.protocol === 'https:' ? 'https:' : 'http:';
1115
+ const hostname = window.location.hostname;
1116
+ const port = window.location.port ? `:${window.location.port}` : '';
1117
+ return `${protocol}//${hostname}${port}${suffix}`;
1118
+ }
1103
1119
  /**
1104
1120
  * Hook to resolve tier-based default model config to actual model
1105
1121
  *
@@ -1109,9 +1125,10 @@ function useDebouncedSuggestions(query, options) {
1109
1125
  * match for the provider and tier combination.
1110
1126
  *
1111
1127
  * @param defaultModel - The model configuration to resolve
1128
+ * @param serverConfig - Optional server config to build the models endpoint URL
1112
1129
  * @returns The resolved model with provider, model name, and capabilities
1113
1130
  */
1114
- function useResolvedDefaultModel(defaultModel) {
1131
+ function useResolvedDefaultModel(defaultModel, serverConfig) {
1115
1132
  const [resolvedModel, setResolvedModel] = useState();
1116
1133
  useEffect(() => {
1117
1134
  if (!defaultModel || defaultModel.model) {
@@ -1128,7 +1145,11 @@ function useResolvedDefaultModel(defaultModel) {
1128
1145
  // Need to resolve tier to actual model
1129
1146
  const resolveModel = async () => {
1130
1147
  try {
1131
- const response = await fetch('/command/models');
1148
+ // Build models endpoint URL from serverConfig if provided, otherwise use default
1149
+ const endpoint = serverConfig
1150
+ ? `${buildUrlFromConfig$1(serverConfig)}/models`
1151
+ : '/command/models';
1152
+ const response = await fetch(endpoint);
1132
1153
  if (!response.ok)
1133
1154
  throw new Error('Failed to fetch models');
1134
1155
  const data = await response.json();
@@ -1155,7 +1176,7 @@ function useResolvedDefaultModel(defaultModel) {
1155
1176
  }
1156
1177
  };
1157
1178
  resolveModel();
1158
- }, [defaultModel]);
1179
+ }, [defaultModel, serverConfig]);
1159
1180
  return resolvedModel;
1160
1181
  }
1161
1182
 
@@ -2049,6 +2070,7 @@ customModels, serverConfig, } = {}) {
2049
2070
  const effectiveInitialModel = initialModel || '';
2050
2071
  // State for auto-fetched models
2051
2072
  const [fetchedModels, setFetchedModels] = useState(null);
2073
+ const [modelsByTier, setModelsByTier] = useState(null);
2052
2074
  const [isLoadingModels, setIsLoadingModels] = useState(false);
2053
2075
  const [modelsError, setModelsError] = useState(null);
2054
2076
  // Track if user explicitly switched models; prevents defaultModel overrides after first user action
@@ -2132,6 +2154,10 @@ customModels, serverConfig, } = {}) {
2132
2154
  });
2133
2155
  });
2134
2156
  setFetchedModels(modelsByProvider);
2157
+ // Store modelsByTier if provided (used for tier-based selection)
2158
+ if (data.modelsByTier) {
2159
+ setModelsByTier(data.modelsByTier);
2160
+ }
2135
2161
  }
2136
2162
  else {
2137
2163
  throw new Error('Invalid response format from models endpoint');
@@ -2150,17 +2176,28 @@ customModels, serverConfig, } = {}) {
2150
2176
  fetchModels();
2151
2177
  }, [customModels, serverConfig, fetchedModels, isLoadingModels]);
2152
2178
  // Update initial model if we fetched models and need to auto-select from tier
2153
- // BUT: If initialTier is specified, we should NOT auto-select here - let server handle tier selection
2179
+ // If tier is specified, resolve it using modelsByTier from server
2154
2180
  useEffect(() => {
2155
2181
  // Only auto-select if:
2156
2182
  // 1. We have fetched models
2157
2183
  // 2. We're using the default initial model (or no model specified)
2158
- // 3. NO tier is specified (tier-based selection should happen server-side)
2159
- // 4. Current model still has the initial model
2184
+ // 3. Current model still has the initial model
2160
2185
  if (fetchedModels && Object.keys(fetchedModels).length > 0) {
2161
- // If tier is specified, don't auto-select - server will handle tier selection
2162
- // This prevents the hook from selecting a model when tier-based selection is desired
2163
- if (initialTier) {
2186
+ // If tier is specified, resolve it using modelsByTier so UI can show selected model
2187
+ if (initialTier && modelsByTier) {
2188
+ const provider = initialProvider.toLowerCase();
2189
+ const tierModels = modelsByTier[provider];
2190
+ if (tierModels && tierModels[initialTier] && currentModel.model === '') {
2191
+ // Resolve tier to specific model ID from server's modelsByTier
2192
+ setCurrentModel({
2193
+ provider: initialProvider,
2194
+ model: tierModels[initialTier],
2195
+ });
2196
+ return;
2197
+ }
2198
+ }
2199
+ // If tier is specified but no modelsByTier, don't auto-select - server will handle tier selection
2200
+ if (initialTier && !modelsByTier) {
2164
2201
  return;
2165
2202
  }
2166
2203
  // Auto-select only if:
@@ -2207,7 +2244,7 @@ customModels, serverConfig, } = {}) {
2207
2244
  }
2208
2245
  }
2209
2246
  }
2210
- }, [fetchedModels, initialProvider, initialTier, effectiveInitialModel, currentModel.model]);
2247
+ }, [fetchedModels, modelsByTier, initialProvider, initialTier, effectiveInitialModel, currentModel.model]);
2211
2248
  // Switch model function - just updates local state
2212
2249
  const switchModel = useCallback((model, provider) => {
2213
2250
  const newProvider = provider || currentModel.provider;
package/dist/index.js CHANGED
@@ -1102,6 +1102,22 @@ function useDebouncedSuggestions(query, options) {
1102
1102
  };
1103
1103
  }
1104
1104
 
1105
+ // Helper function to build URL from config (reused from useModelSwitcher)
1106
+ function buildUrlFromConfig$1(config) {
1107
+ if (!config)
1108
+ return '';
1109
+ const suffix = config.suffix || '';
1110
+ if (suffix.startsWith('http://') || suffix.startsWith('https://')) {
1111
+ return suffix;
1112
+ }
1113
+ if (typeof window === 'undefined') {
1114
+ return suffix;
1115
+ }
1116
+ const protocol = window.location.protocol === 'https:' ? 'https:' : 'http:';
1117
+ const hostname = window.location.hostname;
1118
+ const port = window.location.port ? `:${window.location.port}` : '';
1119
+ return `${protocol}//${hostname}${port}${suffix}`;
1120
+ }
1105
1121
  /**
1106
1122
  * Hook to resolve tier-based default model config to actual model
1107
1123
  *
@@ -1111,9 +1127,10 @@ function useDebouncedSuggestions(query, options) {
1111
1127
  * match for the provider and tier combination.
1112
1128
  *
1113
1129
  * @param defaultModel - The model configuration to resolve
1130
+ * @param serverConfig - Optional server config to build the models endpoint URL
1114
1131
  * @returns The resolved model with provider, model name, and capabilities
1115
1132
  */
1116
- function useResolvedDefaultModel(defaultModel) {
1133
+ function useResolvedDefaultModel(defaultModel, serverConfig) {
1117
1134
  const [resolvedModel, setResolvedModel] = React.useState();
1118
1135
  React.useEffect(() => {
1119
1136
  if (!defaultModel || defaultModel.model) {
@@ -1130,7 +1147,11 @@ function useResolvedDefaultModel(defaultModel) {
1130
1147
  // Need to resolve tier to actual model
1131
1148
  const resolveModel = async () => {
1132
1149
  try {
1133
- const response = await fetch('/command/models');
1150
+ // Build models endpoint URL from serverConfig if provided, otherwise use default
1151
+ const endpoint = serverConfig
1152
+ ? `${buildUrlFromConfig$1(serverConfig)}/models`
1153
+ : '/command/models';
1154
+ const response = await fetch(endpoint);
1134
1155
  if (!response.ok)
1135
1156
  throw new Error('Failed to fetch models');
1136
1157
  const data = await response.json();
@@ -1157,7 +1178,7 @@ function useResolvedDefaultModel(defaultModel) {
1157
1178
  }
1158
1179
  };
1159
1180
  resolveModel();
1160
- }, [defaultModel]);
1181
+ }, [defaultModel, serverConfig]);
1161
1182
  return resolvedModel;
1162
1183
  }
1163
1184
 
@@ -2051,6 +2072,7 @@ customModels, serverConfig, } = {}) {
2051
2072
  const effectiveInitialModel = initialModel || '';
2052
2073
  // State for auto-fetched models
2053
2074
  const [fetchedModels, setFetchedModels] = React.useState(null);
2075
+ const [modelsByTier, setModelsByTier] = React.useState(null);
2054
2076
  const [isLoadingModels, setIsLoadingModels] = React.useState(false);
2055
2077
  const [modelsError, setModelsError] = React.useState(null);
2056
2078
  // Track if user explicitly switched models; prevents defaultModel overrides after first user action
@@ -2134,6 +2156,10 @@ customModels, serverConfig, } = {}) {
2134
2156
  });
2135
2157
  });
2136
2158
  setFetchedModels(modelsByProvider);
2159
+ // Store modelsByTier if provided (used for tier-based selection)
2160
+ if (data.modelsByTier) {
2161
+ setModelsByTier(data.modelsByTier);
2162
+ }
2137
2163
  }
2138
2164
  else {
2139
2165
  throw new Error('Invalid response format from models endpoint');
@@ -2152,17 +2178,28 @@ customModels, serverConfig, } = {}) {
2152
2178
  fetchModels();
2153
2179
  }, [customModels, serverConfig, fetchedModels, isLoadingModels]);
2154
2180
  // Update initial model if we fetched models and need to auto-select from tier
2155
- // BUT: If initialTier is specified, we should NOT auto-select here - let server handle tier selection
2181
+ // If tier is specified, resolve it using modelsByTier from server
2156
2182
  React.useEffect(() => {
2157
2183
  // Only auto-select if:
2158
2184
  // 1. We have fetched models
2159
2185
  // 2. We're using the default initial model (or no model specified)
2160
- // 3. NO tier is specified (tier-based selection should happen server-side)
2161
- // 4. Current model still has the initial model
2186
+ // 3. Current model still has the initial model
2162
2187
  if (fetchedModels && Object.keys(fetchedModels).length > 0) {
2163
- // If tier is specified, don't auto-select - server will handle tier selection
2164
- // This prevents the hook from selecting a model when tier-based selection is desired
2165
- if (initialTier) {
2188
+ // If tier is specified, resolve it using modelsByTier so UI can show selected model
2189
+ if (initialTier && modelsByTier) {
2190
+ const provider = initialProvider.toLowerCase();
2191
+ const tierModels = modelsByTier[provider];
2192
+ if (tierModels && tierModels[initialTier] && currentModel.model === '') {
2193
+ // Resolve tier to specific model ID from server's modelsByTier
2194
+ setCurrentModel({
2195
+ provider: initialProvider,
2196
+ model: tierModels[initialTier],
2197
+ });
2198
+ return;
2199
+ }
2200
+ }
2201
+ // If tier is specified but no modelsByTier, don't auto-select - server will handle tier selection
2202
+ if (initialTier && !modelsByTier) {
2166
2203
  return;
2167
2204
  }
2168
2205
  // Auto-select only if:
@@ -2209,7 +2246,7 @@ customModels, serverConfig, } = {}) {
2209
2246
  }
2210
2247
  }
2211
2248
  }
2212
- }, [fetchedModels, initialProvider, initialTier, effectiveInitialModel, currentModel.model]);
2249
+ }, [fetchedModels, modelsByTier, initialProvider, initialTier, effectiveInitialModel, currentModel.model]);
2213
2250
  // Switch model function - just updates local state
2214
2251
  const switchModel = React.useCallback((model, provider) => {
2215
2252
  const newProvider = provider || currentModel.provider;
@@ -1,4 +1,5 @@
1
1
  import type { ModelCapabilities } from '../types/types';
2
+ import type { ServerConfig } from '../types/types';
2
3
  /**
3
4
  * Hook to resolve tier-based default model config to actual model
4
5
  *
@@ -8,13 +9,14 @@ import type { ModelCapabilities } from '../types/types';
8
9
  * match for the provider and tier combination.
9
10
  *
10
11
  * @param defaultModel - The model configuration to resolve
12
+ * @param serverConfig - Optional server config to build the models endpoint URL
11
13
  * @returns The resolved model with provider, model name, and capabilities
12
14
  */
13
15
  export declare function useResolvedDefaultModel(defaultModel?: {
14
16
  provider: string;
15
17
  model?: string;
16
18
  tier?: 'fast' | 'balanced' | 'powerful';
17
- }): {
19
+ }, serverConfig?: ServerConfig): {
18
20
  provider: string;
19
21
  model: string;
20
22
  capabilities: ModelCapabilities;
@@ -134,6 +134,24 @@ export interface ServerConfig {
134
134
  additionalContext?: string;
135
135
  stayOnPage?: boolean;
136
136
  }
137
+ export interface ClientConfig {
138
+ models?: Record<string, ModelInfo[]>;
139
+ defaultModel?: {
140
+ provider: string;
141
+ model?: string;
142
+ tier?: 'fast' | 'balanced' | 'powerful';
143
+ };
144
+ showUsageStats?: boolean;
145
+ maxFileSize?: string;
146
+ features?: {
147
+ modelSwitching?: boolean;
148
+ usageTracking?: boolean;
149
+ imageAnalysis?: boolean;
150
+ fileUploads?: boolean;
151
+ enableImageUploads?: boolean;
152
+ };
153
+ schemas?: Record<string, SchemaDefinition>;
154
+ }
137
155
  export interface TrainingDataPaths {
138
156
  components: string[];
139
157
  schemas: string[];
@@ -134,6 +134,24 @@ export interface ServerConfig {
134
134
  additionalContext?: string;
135
135
  stayOnPage?: boolean;
136
136
  }
137
+ export interface ClientConfig {
138
+ models?: Record<string, ModelInfo[]>;
139
+ defaultModel?: {
140
+ provider: string;
141
+ model?: string;
142
+ tier?: 'fast' | 'balanced' | 'powerful';
143
+ };
144
+ showUsageStats?: boolean;
145
+ maxFileSize?: string;
146
+ features?: {
147
+ modelSwitching?: boolean;
148
+ usageTracking?: boolean;
149
+ imageAnalysis?: boolean;
150
+ fileUploads?: boolean;
151
+ enableImageUploads?: boolean;
152
+ };
153
+ schemas?: Record<string, SchemaDefinition>;
154
+ }
137
155
  export interface TrainingDataPaths {
138
156
  components: string[];
139
157
  schemas: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchid-ai",
3
- "version": "1.2.5",
3
+ "version": "1.2.8",
4
4
  "type": "module",
5
5
  "description": "AI-powered command processing and chat interface for React applications",
6
6
  "main": "dist/index.js",