kepler.gl 3.1.0-alpha.6 → 3.1.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.
Files changed (190) hide show
  1. package/dist/src/actions/src/action-types.d.ts +2 -0
  2. package/dist/src/actions/src/ui-state-actions.d.ts +16 -0
  3. package/dist/src/ai-assistant/src/actions.d.ts +1 -1
  4. package/dist/src/ai-assistant/src/components/ai-assistant-component.d.ts +2 -1
  5. package/dist/src/ai-assistant/src/constants.d.ts +3 -3
  6. package/dist/src/ai-assistant/src/reducers/index.d.ts +1 -1
  7. package/dist/src/ai-assistant/src/tools/basemap-functions.d.ts +1 -1
  8. package/dist/src/ai-assistant/src/tools/filter-function.d.ts +1 -1
  9. package/dist/src/ai-assistant/src/tools/layer-creation-function.d.ts +1 -1
  10. package/dist/src/ai-assistant/src/tools/layer-style-function.d.ts +1 -1
  11. package/dist/src/ai-assistant/src/tools/loadurl-function.d.ts +1 -1
  12. package/dist/src/ai-assistant/src/tools/utils.d.ts +73 -0
  13. package/dist/src/components/src/common/data-table/index.d.ts +1 -1
  14. package/dist/src/components/src/common/data-table/option-dropdown.d.ts +3 -3
  15. package/dist/src/components/src/common/file-uploader/file-drop.d.ts +2 -2
  16. package/dist/src/components/src/kepler-gl.d.ts +5 -0
  17. package/dist/src/components/src/loading-indicator.d.ts +13 -0
  18. package/dist/src/components/src/map-container.d.ts +3 -0
  19. package/dist/src/constants/src/default-settings.d.ts +1 -0
  20. package/dist/src/duckdb/src/plugin.d.ts +1 -0
  21. package/dist/src/duckdb/src/table/duckdb-table-utils.d.ts +13 -0
  22. package/dist/src/duckdb/src/table/duckdb-table.d.ts +7 -2
  23. package/dist/src/reducers/src/ui-state-updaters.d.ts +10 -0
  24. package/dist/src/reducers/src/vis-state-updaters.d.ts +1 -0
  25. package/dist/src/reducers/src/vis-state.d.ts +4 -0
  26. package/dist/src/utils/src/application-config.d.ts +2 -0
  27. package/dist/src/utils/src/observe-dimensions.d.ts +2 -1
  28. package/package.json +5 -3
  29. package/src/actions/dist/action-types.d.ts +2 -0
  30. package/src/actions/dist/action-types.js +2 -1
  31. package/src/actions/dist/ui-state-actions.d.ts +16 -0
  32. package/src/actions/dist/ui-state-actions.js +17 -2
  33. package/src/actions/package.json +8 -8
  34. package/src/actions/src/action-types.ts +1 -0
  35. package/src/actions/src/ui-state-actions.ts +22 -0
  36. package/src/ai-assistant/README.md +76 -0
  37. package/src/ai-assistant/dist/actions.d.ts +1 -1
  38. package/src/ai-assistant/dist/actions.js +2 -2
  39. package/src/ai-assistant/dist/components/ai-assistant-component.d.ts +2 -1
  40. package/src/ai-assistant/dist/components/ai-assistant-component.js +64 -23
  41. package/src/ai-assistant/dist/components/ai-assistant-config.js +67 -54
  42. package/src/ai-assistant/dist/constants.d.ts +3 -3
  43. package/src/ai-assistant/dist/constants.js +4 -4
  44. package/src/ai-assistant/dist/reducers/index.d.ts +1 -1
  45. package/src/ai-assistant/dist/reducers/index.js +2 -2
  46. package/src/ai-assistant/dist/tools/basemap-functions.d.ts +1 -1
  47. package/src/ai-assistant/dist/tools/basemap-functions.js +1 -1
  48. package/src/ai-assistant/dist/tools/filter-function.d.ts +1 -1
  49. package/src/ai-assistant/dist/tools/filter-function.js +9 -6
  50. package/src/ai-assistant/dist/tools/layer-creation-function.d.ts +1 -1
  51. package/src/ai-assistant/dist/tools/layer-creation-function.js +1 -1
  52. package/src/ai-assistant/dist/tools/layer-style-function.d.ts +1 -1
  53. package/src/ai-assistant/dist/tools/layer-style-function.js +1 -1
  54. package/src/ai-assistant/dist/tools/loadurl-function.d.ts +1 -1
  55. package/src/ai-assistant/dist/tools/loadurl-function.js +1 -1
  56. package/src/ai-assistant/dist/tools/utils.d.ts +73 -0
  57. package/src/ai-assistant/dist/tools/utils.js +211 -3
  58. package/src/ai-assistant/package.json +13 -9
  59. package/src/ai-assistant/src/actions.ts +2 -2
  60. package/src/ai-assistant/src/components/ai-assistant-component.tsx +56 -23
  61. package/src/ai-assistant/src/components/ai-assistant-config.tsx +63 -46
  62. package/src/ai-assistant/src/config/models.json +32 -0
  63. package/src/ai-assistant/src/constants.ts +7 -2
  64. package/src/ai-assistant/src/reducers/index.ts +2 -2
  65. package/src/ai-assistant/src/tools/basemap-functions.tsx +1 -1
  66. package/src/ai-assistant/src/tools/filter-function.tsx +11 -7
  67. package/src/ai-assistant/src/tools/layer-creation-function.tsx +1 -1
  68. package/src/ai-assistant/src/tools/layer-style-function.tsx +1 -1
  69. package/src/ai-assistant/src/tools/loadurl-function.tsx +1 -1
  70. package/src/ai-assistant/src/tools/utils.ts +212 -2
  71. package/src/cloud-providers/package.json +2 -2
  72. package/src/common-utils/package.json +3 -3
  73. package/src/components/dist/common/data-table/header-cell.js +10 -10
  74. package/src/components/dist/common/data-table/index.d.ts +1 -1
  75. package/src/components/dist/common/data-table/index.js +1 -1
  76. package/src/components/dist/common/data-table/option-dropdown.d.ts +3 -3
  77. package/src/components/dist/common/data-table/option-dropdown.js +5 -5
  78. package/src/components/dist/common/file-uploader/file-drop.d.ts +2 -2
  79. package/src/components/dist/common/file-uploader/file-drop.js +1 -1
  80. package/src/components/dist/common/portaled.js +1 -1
  81. package/src/components/dist/editor/editor.js +1 -1
  82. package/src/components/dist/kepler-gl.d.ts +5 -0
  83. package/src/components/dist/kepler-gl.js +7 -2
  84. package/src/components/dist/loading-indicator.d.ts +13 -0
  85. package/src/components/dist/loading-indicator.js +40 -0
  86. package/src/components/dist/map-container.d.ts +3 -0
  87. package/src/components/dist/map-container.js +11 -3
  88. package/src/components/dist/modals/save-map-modal.js +4 -3
  89. package/src/components/package.json +15 -15
  90. package/src/components/src/common/data-table/header-cell.tsx +5 -3
  91. package/src/components/src/common/data-table/index.tsx +1 -1
  92. package/src/components/src/common/data-table/option-dropdown.tsx +7 -7
  93. package/src/components/src/common/file-uploader/file-drop.tsx +11 -11
  94. package/src/components/src/common/portaled.tsx +12 -12
  95. package/src/components/src/editor/editor.tsx +3 -3
  96. package/src/components/src/kepler-gl.tsx +7 -2
  97. package/src/components/src/loading-indicator.tsx +49 -0
  98. package/src/components/src/map-container.tsx +19 -1
  99. package/src/components/src/modals/save-map-modal.tsx +6 -2
  100. package/src/constants/dist/default-settings.d.ts +1 -0
  101. package/src/constants/dist/default-settings.js +13 -9
  102. package/src/constants/dist/keyevent.js +1 -1
  103. package/src/constants/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/72/80/7a7c561d7985e92aab7b9683e7baf5a0286b353a8f2609c4c71099f668d012be027929e4bbac937f9aa0c9a61be3bd4405136f582895f05aa0313c8efa42 +1 -0
  104. package/src/constants/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/8f/f6/b66955867599392dc69ff1db64419e83c087a82c2e3d4b6418d49ac6bc80e3200dd6c86cdfd4a2cf98ce573f71a5281b86ba3df8a7210e02544f63054191 +1 -0
  105. package/src/constants/node_modules/.cache/terser-webpack-plugin/index-v5/bd/ba/47ea8fcb11ecd5cd47ad867052e58b1f7e0c8dc5f8918a36fe90eaf45981 +2 -0
  106. package/src/constants/node_modules/.cache/terser-webpack-plugin/index-v5/f0/6e/aadf3c48345aa72e7b2fb92e8c9788d04986b55caf83daa3fbd749c37c44 +2 -0
  107. package/src/constants/package.json +2 -2
  108. package/src/constants/src/default-settings.ts +11 -5
  109. package/src/constants/src/keyevent.ts +2 -2
  110. package/src/constants/umd/keplergl.min.js +1 -1
  111. package/src/deckgl-arrow-layers/package.json +1 -1
  112. package/src/deckgl-layers/package.json +4 -4
  113. package/src/duckdb/dist/components/preview-data-panel.js +2 -11
  114. package/src/duckdb/dist/components/sql-panel.js +7 -3
  115. package/src/duckdb/dist/components/tree.js +5 -4
  116. package/src/duckdb/dist/plugin.d.ts +1 -0
  117. package/src/duckdb/dist/plugin.js +9 -2
  118. package/src/duckdb/dist/processors/data-processor.js +4 -5
  119. package/src/duckdb/dist/table/duckdb-table-utils.d.ts +13 -0
  120. package/src/duckdb/dist/table/duckdb-table-utils.js +110 -0
  121. package/src/duckdb/dist/table/duckdb-table.d.ts +7 -2
  122. package/src/duckdb/dist/table/duckdb-table.js +189 -44
  123. package/src/duckdb/package.json +6 -6
  124. package/src/duckdb/src/components/preview-data-panel.tsx +0 -5
  125. package/src/duckdb/src/components/sql-panel.tsx +4 -2
  126. package/src/duckdb/src/components/tree.tsx +5 -1
  127. package/src/duckdb/src/plugin.ts +8 -1
  128. package/src/duckdb/src/processors/data-processor.ts +3 -4
  129. package/src/duckdb/src/table/duckdb-table-utils.ts +106 -0
  130. package/src/duckdb/src/table/duckdb-table.ts +134 -33
  131. package/src/effects/package.json +5 -5
  132. package/src/layers/dist/icon-layer/icon-layer.js +1 -1
  133. package/src/layers/dist/index.d.ts +3 -0
  134. package/src/layers/dist/index.js +6 -7
  135. package/src/layers/dist/point-layer/point-layer.d.ts +1 -1
  136. package/src/layers/dist/point-layer/point-layer.js +8 -2
  137. package/src/layers/package.json +9 -9
  138. package/src/layers/src/icon-layer/icon-layer.ts +8 -10
  139. package/src/layers/src/index.ts +5 -5
  140. package/src/layers/src/point-layer/point-layer.ts +6 -1
  141. package/src/localization/package.json +1 -1
  142. package/src/processors/dist/data-processor.js +2 -4
  143. package/src/processors/package.json +7 -7
  144. package/src/processors/src/data-processor.ts +1 -3
  145. package/src/reducers/dist/ui-state-updaters.d.ts +10 -0
  146. package/src/reducers/dist/ui-state-updaters.js +22 -2
  147. package/src/reducers/dist/ui-state.js +2 -2
  148. package/src/reducers/dist/vis-state-updaters.d.ts +1 -0
  149. package/src/reducers/dist/vis-state-updaters.js +21 -5
  150. package/src/reducers/dist/vis-state.d.ts +4 -0
  151. package/src/reducers/package.json +16 -16
  152. package/src/reducers/src/ui-state-updaters.ts +24 -0
  153. package/src/reducers/src/ui-state.ts +3 -1
  154. package/src/reducers/src/vis-state-updaters.ts +24 -5
  155. package/src/schemas/dist/dataset-schema.js +38 -2
  156. package/src/schemas/package.json +8 -7
  157. package/src/schemas/src/dataset-schema.ts +43 -1
  158. package/src/styles/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/5f/aa/96c67b383dbcd2b95625113a5389c6078fd8a53e6fc73a054229709f2dac1e0a409e7117049485a569fbebf8434a319451842671398904bfe1a7f7b5991c +1 -0
  159. package/src/styles/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/af/aa/228fbff58007b23eea5eb6cc7d2da1f0af1d8a7024129a416ea88b4df0ad7afc7aec93b09f3dd42a98f1d6a6f4dce6b53204818da85ef5becc42f928a64d +1 -0
  160. package/src/styles/node_modules/.cache/terser-webpack-plugin/index-v5/40/72/cac221d8459e6b743bc62ecdb370ed854b21ec30d3f7f4c06c7d1d7ffde2 +2 -0
  161. package/src/styles/node_modules/.cache/terser-webpack-plugin/index-v5/c1/39/f7cd1d5947ec6e5d82bfa07041271344eb02f9e67bf5823acf2f22c2d01f +2 -0
  162. package/src/styles/package.json +2 -2
  163. package/src/styles/umd/keplergl.min.js +1 -1
  164. package/src/table/dist/dataset-utils.js +10 -4
  165. package/src/table/package.json +5 -5
  166. package/src/table/src/dataset-utils.ts +7 -1
  167. package/src/tasks/package.json +2 -2
  168. package/src/types/package.json +1 -1
  169. package/src/types/reducers.d.ts +2 -0
  170. package/src/utils/dist/application-config.d.ts +2 -0
  171. package/src/utils/dist/application-config.js +4 -2
  172. package/src/utils/dist/data-utils.js +14 -2
  173. package/src/utils/dist/dataset-utils.js +5 -3
  174. package/src/utils/dist/dom-to-image.js +1 -1
  175. package/src/utils/dist/dom-utils.js +1 -1
  176. package/src/utils/dist/map-style-utils/mapbox-gl-style-editor.js +7 -1
  177. package/src/utils/dist/observe-dimensions.d.ts +2 -1
  178. package/src/utils/dist/observe-dimensions.js +10 -4
  179. package/src/utils/dist/utils.js +1 -1
  180. package/src/utils/package.json +4 -4
  181. package/src/utils/src/application-config.ts +9 -1
  182. package/src/utils/src/data-utils.ts +13 -1
  183. package/src/utils/src/dataset-utils.ts +1 -1
  184. package/src/utils/src/dom-to-image.ts +5 -6
  185. package/src/utils/src/dom-utils.ts +15 -15
  186. package/src/utils/src/map-style-utils/mapbox-gl-style-editor.ts +6 -0
  187. package/src/utils/src/observe-dimensions.ts +9 -4
  188. package/src/utils/src/utils.ts +8 -8
  189. package/umd/keplergl.min.css +1 -1
  190. package/umd/keplergl.min.js +1499 -1428
@@ -14,23 +14,9 @@ import {
14
14
  } from '@kepler.gl/components';
15
15
  import {AiAssistantConfig} from '../index';
16
16
  import ApiKey from '../icons/api-key';
17
- import {testApiKey} from 'react-ai-assist';
18
-
19
- const PROVIDER_MODELS = {
20
- openai: ['gpt-4o', 'gpt-4o-mini', 'gpt-3.5-turbo-0125', 'gpt-3.5-turbo'],
21
- google: ['gemini-1.5-flash', 'gemini-1.5-pro', 'gemini-1.0-pro'],
22
- ollama: [
23
- 'qwen2.5-coder',
24
- 'llama3.2',
25
- 'llama3.1',
26
- 'llama3.1:70b',
27
- 'qwen2',
28
- 'llava',
29
- 'mistral',
30
- 'gemma2',
31
- 'phi3.5'
32
- ]
33
- };
17
+ import {testApiKey} from '@openassistant/core';
18
+ import PROVIDER_MODELS from '../config/models.json';
19
+ import {useLocalStorage} from 'usehooks-ts';
34
20
 
35
21
  type ThemeProps = {theme: any};
36
22
 
@@ -140,12 +126,27 @@ function AiAssistantConfigFactory(RangeSlider: ReturnType<typeof RangeSliderFact
140
126
  const AiAssistantConfig: React.FC<
141
127
  AiAssistantConfigProps & WrappedComponentProps & ThemeProps
142
128
  > = ({intl, aiAssistantConfig, updateAiAssistantConfig}) => {
143
- const [provider, setProvider] = useState(aiAssistantConfig.provider || 'openai');
144
- const [model, setModel] = useState(aiAssistantConfig.model || PROVIDER_MODELS[provider][0]);
145
- const [apiKey, setApiKey] = useState(aiAssistantConfig.apiKey || '');
146
- const [temperature, setTemperature] = useState(aiAssistantConfig.temperature || 0.8);
147
- const [topP, setTopP] = useState(aiAssistantConfig.topP || 0.8);
148
- const [baseUrl, setBaseUrl] = useState(aiAssistantConfig.baseUrl || 'http://localhost:11434');
129
+ const [provider, setProvider] = useLocalStorage(
130
+ 'ai-assistant-provider',
131
+ aiAssistantConfig.provider || 'openai'
132
+ );
133
+ const [model, setModel] = useLocalStorage(
134
+ 'ai-assistant-model',
135
+ aiAssistantConfig.model || PROVIDER_MODELS[provider][0]
136
+ );
137
+ const [apiKey, setApiKey] = useLocalStorage(
138
+ 'ai-assistant-api-key',
139
+ aiAssistantConfig.apiKey || ''
140
+ );
141
+ const [temperature, setTemperature] = useLocalStorage(
142
+ 'ai-assistant-temperature',
143
+ aiAssistantConfig.temperature || 0.8
144
+ );
145
+ const [topP, setTopP] = useLocalStorage('ai-assistant-top-p', aiAssistantConfig.topP || 0.8);
146
+ const [baseUrl, setBaseUrl] = useLocalStorage(
147
+ 'ai-assistant-base-url',
148
+ aiAssistantConfig.baseUrl || 'http://localhost:11434'
149
+ );
149
150
  const [connectionError, setConnectionError] = useState(false);
150
151
  const [errorMessage, setErrorMessage] = useState('');
151
152
  const [isRunning, setIsRunning] = useState(false);
@@ -188,29 +189,45 @@ function AiAssistantConfigFactory(RangeSlider: ReturnType<typeof RangeSliderFact
188
189
 
189
190
  const onStartChat = async () => {
190
191
  setIsRunning(true);
191
- const {success, service} = await testApiKey({
192
- modelProvider: provider,
193
- modelName: model,
194
- apiKey: apiKey,
195
- baseUrl: baseUrl
196
- });
197
- const errorMessage = !success
198
- ? service === 'ollama'
199
- ? 'Connection failed: maybe invalid Ollama Base URL'
200
- : 'Connection failed: maybe invalid API Key'
201
- : '';
202
- setConnectionError(!success);
203
- setErrorMessage(errorMessage);
204
- updateAiAssistantConfig({
205
- provider: provider,
206
- model: model,
207
- apiKey: apiKey,
208
- baseUrl: baseUrl,
209
- isReady: success,
210
- temperature: temperature,
211
- topP: topP
212
- });
213
- setIsRunning(false);
192
+ try {
193
+ const timeoutPromise = new Promise((_, reject) => {
194
+ setTimeout(() => reject(new Error('Connection timeout after 15 seconds')), 15000);
195
+ });
196
+
197
+ const testPromise = testApiKey({
198
+ modelProvider: provider,
199
+ modelName: model,
200
+ apiKey: apiKey,
201
+ baseUrl: baseUrl
202
+ });
203
+
204
+ const result = (await Promise.race([testPromise, timeoutPromise])) as {
205
+ success: boolean;
206
+ service: string;
207
+ };
208
+ const {success, service} = result;
209
+ const errorMessage = !success
210
+ ? service === 'ollama'
211
+ ? 'Connection failed: maybe invalid Ollama Base URL'
212
+ : 'Connection failed: maybe invalid API Key'
213
+ : '';
214
+ setConnectionError(!success);
215
+ setErrorMessage(errorMessage);
216
+ updateAiAssistantConfig({
217
+ provider: provider,
218
+ model: model,
219
+ apiKey: apiKey,
220
+ baseUrl: baseUrl,
221
+ isReady: success,
222
+ temperature: temperature,
223
+ topP: topP
224
+ });
225
+ } catch (error) {
226
+ setConnectionError(true);
227
+ setErrorMessage(error instanceof Error ? error.message : 'Connection failed');
228
+ } finally {
229
+ setIsRunning(false);
230
+ }
214
231
  };
215
232
 
216
233
  return (
@@ -0,0 +1,32 @@
1
+ {
2
+ "deepseek": ["deepseek-chat", "deepseek-reasoner"],
3
+ "openai": [
4
+ "o1-mini",
5
+ "o1-preview",
6
+ "o1",
7
+ "gpt-4o",
8
+ "gpt-4o-mini",
9
+ "gpt-3.5-turbo-0125",
10
+ "gpt-3.5-turbo"
11
+ ],
12
+ "google": ["gemini-2.0-flash-exp", "gemini-1.5-flash", "gemini-1.5-pro", "gemini-1.0-pro"],
13
+ "ollama": [
14
+ "deepseek-r1",
15
+ "deepseek-r1:14b",
16
+ "deepseek-r1:32b",
17
+ "deepseek-r1:70b",
18
+ "deepseek-r1:671b",
19
+ "phi4",
20
+ "qwen2.5-coder",
21
+ "qwq",
22
+ "llama3.3",
23
+ "llama3.2",
24
+ "llama3.1",
25
+ "llama3.1:70b",
26
+ "qwen2",
27
+ "llava",
28
+ "mistral",
29
+ "gemma2",
30
+ "phi3.5"
31
+ ]
32
+ }
@@ -2,18 +2,23 @@
2
2
  // Copyright contributors to the kepler.gl project
3
3
 
4
4
  export const TASK_LIST =
5
- '1. Show dataset/layer/variable info.\n2. Change the basemap style.\n3. Load data from url.\n4. Create a map layer using variable.\n5. Filter the data of a variable.\n6. Create a histogram.';
5
+ '1. Show dataset/layer/variable info.\n2. Change the basemap style.\n3. Load data from url.\n4. Create a map layer using variable.\n5. Create a histogram.\n6. Create a scatter plot with regression line.\n7. Classify the data of a variable.\n8. Spatial join two datasets.';
6
6
 
7
7
  export const WELCOME_MESSAGE = `Hi, I am Kepler.gl AI Assistant!\nHere are some tasks I can help you with:\n\n${TASK_LIST}`;
8
8
 
9
9
  export const INSTRUCTIONS = `You are a Kepler.gl AI Assistant that can answer questions and help with tasks of mapping and spatial data analysis.
10
10
 
11
+ Here are the tasks that you can help with:
12
+ ${TASK_LIST}
13
+
11
14
  When responding to user queries:
12
15
  1. Analyze if the task requires one or multiple function calls
13
16
  2. For each required function:
14
17
  - Identify the appropriate function to call
15
18
  - Determine all required parameters
16
19
  - If parameters are missing, ask the user to provide them
20
+ - Please ask the user to confirm the parameters
21
+ - If the user doesn't agree, try to provide variable functions to the user
17
22
  - Execute functions in a sequential order
18
23
 
19
24
  You can execute multiple functions to complete complex tasks, but execute them one at a time in a logical sequence. Always validate the success of each function call before proceeding to the next one.
@@ -52,4 +57,4 @@ export const ASSISTANT_NAME = 'kepler-gl-ai-assistant';
52
57
 
53
58
  export const ASSISTANT_DESCRIPTION = 'A Kepler.gl AI Assistant';
54
59
 
55
- export const ASSISTANT_VERSION = '0.0.1-9';
60
+ export const ASSISTANT_VERSION = '0.0.2';
@@ -8,7 +8,7 @@ import {
8
8
  SET_START_SCREEN_CAPTURE,
9
9
  SET_SCREEN_CAPTURED
10
10
  } from '../actions';
11
- import {MessageModel} from 'react-ai-assist';
11
+ import {MessageModel} from '@openassistant/core';
12
12
 
13
13
  export type AiAssistantConfig = {
14
14
  isReady: boolean;
@@ -24,7 +24,7 @@ export type AiAssistantConfig = {
24
24
  const initialConfig: AiAssistantConfig = {
25
25
  isReady: false,
26
26
  provider: 'openai',
27
- model: 'gpt-4o-mini',
27
+ model: 'gpt-4o',
28
28
  apiKey: '',
29
29
  baseUrl: 'http://localhost:11434',
30
30
  temperature: 1.0,
@@ -13,7 +13,7 @@ import {
13
13
  CustomFunctionOutputProps,
14
14
  ErrorCallbackResult,
15
15
  RegisterFunctionCallingProps
16
- } from 'react-ai-assist';
16
+ } from '@openassistant/core';
17
17
 
18
18
  export function basemapFunctionDefinition(
19
19
  context: CustomFunctionContext<ActionHandler<typeof mapStyleChange> | MapStyle>
@@ -14,7 +14,7 @@ import {
14
14
  CustomFunctionOutputProps,
15
15
  ErrorCallbackResult,
16
16
  RegisterFunctionCallingProps
17
- } from 'react-ai-assist';
17
+ } from '@openassistant/core';
18
18
  import {checkDatasetNotExists, checkFieldNotExists} from './utils';
19
19
  import {getDefaultFilter, getFilterProps, updateFilterPlot} from '@kepler.gl/utils';
20
20
  import {RangeFilterFactory, appInjector} from '@kepler.gl/components';
@@ -174,31 +174,35 @@ async function filterCallback({
174
174
  const RangeFilterComponent = appInjector.get(RangeFilterFactory);
175
175
 
176
176
  function FilterMessage({output}: CustomFunctionCall) {
177
- const outputData = output.data as OutputDataProps;
177
+ const outputData = output.data as OutputDataProps | undefined;
178
178
 
179
179
  // run this when the component is mounted
180
180
  useEffect(() => {
181
- outputData.createOrUpdateFilter(
181
+ outputData?.createOrUpdateFilter(
182
182
  outputData.filter.id,
183
183
  outputData.datasetId,
184
184
  outputData.fieldName,
185
185
  outputData.filter.value
186
186
  );
187
- }, [outputData, outputData.filter]);
187
+ }, [outputData]);
188
188
 
189
189
  const filters = useSelector(state => {
190
190
  // @ts-ignore TODO: fix this: we need to get the updated filters from the visState, but nicely
191
191
  return state.demo.keplerGl.map.visState.filters;
192
192
  });
193
193
 
194
- const filter = filters.find(f => f.id === outputData.filter.id);
194
+ const filter = filters.find(f => f.id === outputData?.filter.id);
195
195
 
196
- const onSetFilter = value => outputData.setFilter(outputData.filterIdx, 'value', value);
196
+ const onSetFilter = value => outputData?.setFilter(outputData.filterIdx, 'value', value);
197
197
 
198
198
  const onSetFilterPlot = (newProp, valueIndex) => {
199
- outputData.setFilterPlot(outputData.filterIdx, newProp, valueIndex);
199
+ outputData?.setFilterPlot(outputData.filterIdx, newProp, valueIndex);
200
200
  };
201
201
 
202
+ if (!outputData) {
203
+ return <div>Something went wrong, filter not created.</div>;
204
+ }
205
+
202
206
  return (
203
207
  filter && (
204
208
  <div>
@@ -11,7 +11,7 @@ import {
11
11
  CustomFunctionOutputProps,
12
12
  ErrorCallbackResult,
13
13
  RegisterFunctionCallingProps
14
- } from 'react-ai-assist';
14
+ } from '@openassistant/core';
15
15
  import {checkDatasetNotExists, checkFieldNotExists, interpolateColor} from './utils';
16
16
  import {findDefaultLayer} from '@kepler.gl/reducers';
17
17
  import React, {useEffect} from 'react';
@@ -8,7 +8,7 @@ import {
8
8
  CustomFunctionContext,
9
9
  CustomFunctionOutputProps,
10
10
  ErrorCallbackResult
11
- } from 'react-ai-assist';
11
+ } from '@openassistant/core';
12
12
  import {ActionHandler, layerVisualChannelConfigChange} from '@kepler.gl/actions';
13
13
  import {Layer, LayerBaseConfig} from '@kepler.gl/layers';
14
14
 
@@ -18,7 +18,7 @@ import {
18
18
  CustomFunctionOutputProps,
19
19
  ErrorCallbackResult,
20
20
  RegisterFunctionCallingProps
21
- } from 'react-ai-assist';
21
+ } from '@openassistant/core';
22
22
 
23
23
  export function loadUrlFunctionDefinition(
24
24
  context: CustomFunctionContext<ActionHandler<typeof loadFiles> | Loader[] | object>
@@ -5,7 +5,17 @@ import interpolate from 'color-interpolate';
5
5
 
6
6
  import {Layer} from '@kepler.gl/layers';
7
7
  import {Datasets, KeplerTable} from '@kepler.gl/table';
8
+ import {SpatialJoinGeometries} from '@openassistant/geoda';
9
+ import {ALL_FIELD_TYPES} from '@kepler.gl/constants';
10
+ import {AddDataToMapPayload, ProtoDataset, ProtoDatasetField} from '@kepler.gl/types';
8
11
 
12
+ /**
13
+ * Check if the dataset exists
14
+ * @param datasets The kepler.gl datasets
15
+ * @param datasetName The name of the dataset
16
+ * @param functionName The name of the function
17
+ * @returns The result of the check
18
+ */
9
19
  export function checkDatasetNotExists(
10
20
  datasets: Datasets,
11
21
  datasetName: string,
@@ -26,6 +36,13 @@ export function checkDatasetNotExists(
26
36
  return null;
27
37
  }
28
38
 
39
+ /**
40
+ * Check if the field exists
41
+ * @param dataset The kepler.gl dataset
42
+ * @param fieldName The name of the field
43
+ * @param functionName The name of the function
44
+ * @returns The result of the check
45
+ */
29
46
  export function checkFieldNotExists(dataset: KeplerTable, fieldName: string, functionName: string) {
30
47
  const field = dataset.fields.find(f => f.name === fieldName);
31
48
  if (!field) {
@@ -43,6 +60,12 @@ export function checkFieldNotExists(dataset: KeplerTable, fieldName: string, fun
43
60
  return null;
44
61
  }
45
62
 
63
+ /**
64
+ * Interpolate the colors from the original colors with the given number of colors
65
+ * @param originalColors The original colors
66
+ * @param numberOfColors The number of colors
67
+ * @returns The interpolated colors
68
+ */
46
69
  export function interpolateColor(originalColors: string[], numberOfColors: number) {
47
70
  if (originalColors.length === numberOfColors) {
48
71
  return originalColors;
@@ -57,6 +80,13 @@ export function interpolateColor(originalColors: string[], numberOfColors: numbe
57
80
  return hexColors;
58
81
  }
59
82
 
83
+ /**
84
+ * Get the values from a dataset for a variable
85
+ * @param datasets
86
+ * @param datasetName
87
+ * @param variableName
88
+ * @returns {number[]}
89
+ */
60
90
  export function getValuesFromDataset(
61
91
  datasets: Datasets,
62
92
  datasetName: string,
@@ -72,6 +102,33 @@ export function getValuesFromDataset(
72
102
  return [];
73
103
  }
74
104
 
105
+ /**
106
+ * Get the x and y values from a dataset for a scatterplot
107
+ * @param datasets
108
+ * @param datasetName
109
+ * @param xVariableName
110
+ * @param yVariableName
111
+ * @returns {x: number[], y: number[]}
112
+ */
113
+ export function getScatterplotValuesFromDataset(
114
+ datasets: Datasets,
115
+ datasetName: string,
116
+ xVariableName: string,
117
+ yVariableName: string
118
+ ): {x: number[]; y: number[]} {
119
+ const xValues = getValuesFromDataset(datasets, datasetName, xVariableName);
120
+ const yValues = getValuesFromDataset(datasets, datasetName, yVariableName);
121
+ return {x: xValues, y: yValues};
122
+ }
123
+
124
+ /**
125
+ * Highlight the rows in a dataset
126
+ * @param datasets The kepler.gl datasets
127
+ * @param layers The kepler.gl layers
128
+ * @param datasetName The name of the dataset
129
+ * @param selectedRowIndices The indices of the rows to highlight
130
+ * @param layerSetIsValid The function to set the layer validity
131
+ */
75
132
  export function highlightRows(
76
133
  datasets: Datasets,
77
134
  layers: Layer[],
@@ -91,11 +148,17 @@ export function highlightRows(
91
148
  selectLayers.forEach(layer => {
92
149
  layer.formatLayerData(datasets);
93
150
  // trigger a re-render using layerSetIsValid() to update the top layer
94
- layerSetIsValid(selectLayers[0], true);
151
+ layerSetIsValid(layer, true);
95
152
  });
96
153
  }
97
154
  }
98
155
 
156
+ /**
157
+ * Get the dataset context, which is used to provide the dataset information to the AI assistant
158
+ * @param datasets The kepler.gl datasets
159
+ * @param layers The kepler.gl layers
160
+ * @returns The dataset context
161
+ */
99
162
  export function getDatasetContext(datasets: Datasets, layers: Layer[]) {
100
163
  const context = 'Please remember the following dataset context:';
101
164
  const dataMeta = Object.values(datasets).map((dataset: KeplerTable) => ({
@@ -104,7 +167,154 @@ export function getDatasetContext(datasets: Datasets, layers: Layer[]) {
104
167
  fields: dataset.fields.map(field => ({[field.name]: field.type})),
105
168
  layers: layers
106
169
  .filter(layer => layer.config.dataId === dataset.id)
107
- .map(layer => ({id: layer.id, label: layer.config.label, type: layer.type}))
170
+ .map(layer => ({
171
+ id: layer.id,
172
+ label: layer.config.label,
173
+ type: layer.type,
174
+ geometryMode: layer.config.columnMode,
175
+ // get the valid geometry columns as string
176
+ geometryColumns: Object.fromEntries(
177
+ Object.entries(layer.config.columns)
178
+ .filter(([, value]) => value !== null)
179
+ .map(([key, value]) => [
180
+ key,
181
+ typeof value === 'object' && value !== null
182
+ ? Object.fromEntries(Object.entries(value).filter(([, v]) => v !== null))
183
+ : value
184
+ ])
185
+ )
186
+ }))
108
187
  }));
109
188
  return `${context}\n${JSON.stringify(dataMeta)}`;
110
189
  }
190
+
191
+ /**
192
+ * Get the geometries from a dataset
193
+ * @param datasets The kepler.gl datasets
194
+ * @param layers The kepler.gl layers
195
+ * @param layerData The layer data
196
+ * @param datasetName The name of the dataset
197
+ * @returns The geometries
198
+ */
199
+ export function getGeometriesFromDataset(
200
+ datasets: Datasets,
201
+ layers: Layer[],
202
+ layerData: any[],
203
+ datasetName: string
204
+ ): SpatialJoinGeometries {
205
+ const datasetId = Object.keys(datasets).find(dataId => datasets[dataId].label === datasetName);
206
+ if (!datasetId) return [];
207
+ const dataset = datasets[datasetId];
208
+
209
+ // get the index of the layer
210
+ const layerIndex = layers.findIndex(layer => layer.config.dataId === dataset.id);
211
+ if (layerIndex === -1) return [];
212
+
213
+ const geometries = layerData[layerIndex];
214
+
215
+ return geometries?.data;
216
+ }
217
+
218
+ /**
219
+ * Save the data as a new dataset by joining it with the left dataset
220
+ * @param datasets The kepler.gl datasets
221
+ * @param datasetName The name of the left dataset
222
+ * @param data The data to save
223
+ * @param addDataToMap The function to add the data to the map
224
+ */
225
+ export function saveAsDataset(
226
+ datasets: Datasets,
227
+ datasetName: string,
228
+ data: Record<string, number[]>,
229
+ addDataToMap: (data: AddDataToMapPayload) => void
230
+ ) {
231
+ // find datasetId from datasets
232
+ const datasetId = Object.keys(datasets).find(dataId => datasets[dataId].label === datasetName);
233
+ if (!datasetId) return;
234
+
235
+ const leftDataset = datasets[datasetId];
236
+ const numRows = leftDataset.length;
237
+
238
+ const fields: ProtoDatasetField[] = [
239
+ // New fields from data
240
+ ...Object.keys(data).map((fieldName, index) => ({
241
+ name: fieldName,
242
+ id: `${fieldName}_${index}`,
243
+ displayName: fieldName,
244
+ type: determineFieldType(data[fieldName][0])
245
+ })),
246
+ // Existing fields from leftDataset
247
+ ...leftDataset.fields.map((field, index) => ({
248
+ name: field.name,
249
+ id: field.id || `${field.name}_${index}`,
250
+ displayName: field.displayName,
251
+ type: field.type
252
+ }))
253
+ ];
254
+
255
+ // Pre-calculate data values array
256
+ const dataValues = Object.values(data);
257
+
258
+ const rows = Array(numRows)
259
+ .fill(null)
260
+ .map((_, rowIdx) => [
261
+ // New data values
262
+ ...dataValues.map(col => col[rowIdx]),
263
+ // Existing dataset values
264
+ ...leftDataset.fields.map(field => leftDataset.getValue(field.name, rowIdx))
265
+ ]);
266
+
267
+ // create new dataset
268
+ const newDatasetName = `${datasetName}_joined`;
269
+ const newDataset: ProtoDataset = {
270
+ info: {
271
+ id: newDatasetName,
272
+ label: newDatasetName
273
+ },
274
+ data: {
275
+ fields,
276
+ rows
277
+ }
278
+ };
279
+
280
+ addDataToMap({datasets: [newDataset], options: {autoCreateLayers: true, centerMap: true}});
281
+ }
282
+
283
+ /**
284
+ * Helper function to determine field type
285
+ * @param value The value to determine the field type
286
+ * @returns The field type
287
+ */
288
+ function determineFieldType(value: unknown): keyof typeof ALL_FIELD_TYPES {
289
+ return typeof value === 'number'
290
+ ? Number.isInteger(value)
291
+ ? ALL_FIELD_TYPES.integer
292
+ : ALL_FIELD_TYPES.real
293
+ : ALL_FIELD_TYPES.string;
294
+ }
295
+
296
+ export function highlightRowsByColumnValues(
297
+ datasets: Datasets,
298
+ layers: Layer[],
299
+ datasetName: string,
300
+ columnName: string,
301
+ selectedValues: unknown[],
302
+ layerSetIsValid: (layer: Layer, isValid: boolean) => void
303
+ ) {
304
+ const datasetId = Object.keys(datasets).find(dataId => datasets[dataId].label === datasetName);
305
+ if (!datasetId) return;
306
+ const dataset = datasets[datasetId];
307
+ if (dataset) {
308
+ // get the values of the column
309
+ const values = Array.from({length: dataset.length}, (_, i) => dataset.getValue(columnName, i));
310
+ // create a dict using the values
311
+ const valueDict = values.reduce((acc, value, index) => {
312
+ acc[value] = index;
313
+ return acc;
314
+ }, {});
315
+ // need to fix the type error of value here
316
+ const selectedIndices = selectedValues.map(value => valueDict[value as any]);
317
+ // highlight the rows
318
+ highlightRows(datasets, layers, datasetName, selectedIndices, layerSetIsValid);
319
+ }
320
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kepler.gl/cloud-providers",
3
3
  "author": "Shan He <shan@uber.com>",
4
- "version": "3.1.0-alpha.6",
4
+ "version": "3.1.0",
5
5
  "description": "kepler.gl constants used by kepler.gl components, actions and reducers",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "umd"
31
31
  ],
32
32
  "dependencies": {
33
- "@kepler.gl/types": "3.1.0-alpha.6",
33
+ "@kepler.gl/types": "3.1.0",
34
34
  "react": "^18.2.0"
35
35
  },
36
36
  "nyc": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kepler.gl/common-utils",
3
3
  "author": "Shan He <heshan0131@gmail.com>",
4
- "version": "3.1.0-alpha.6",
4
+ "version": "3.1.0",
5
5
  "description": "kepler.gl common utils",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -30,8 +30,8 @@
30
30
  "umd"
31
31
  ],
32
32
  "dependencies": {
33
- "@kepler.gl/constants": "3.1.0-alpha.6",
34
- "@kepler.gl/types": "3.1.0-alpha.6",
33
+ "@kepler.gl/constants": "3.1.0",
34
+ "@kepler.gl/types": "3.1.0",
35
35
  "d3-array": "^2.8.0",
36
36
  "global": "^4.3.0",
37
37
  "h3-js": "^3.1.0",