@datalayer/agent-runtimes 0.0.10 → 0.0.12

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 (138) hide show
  1. package/README.md +2 -2
  2. package/lib/Agent.d.ts +29 -0
  3. package/lib/Agent.js +131 -0
  4. package/lib/AgentLexical.d.ts +34 -0
  5. package/lib/AgentLexical.js +296 -0
  6. package/lib/AgentNotebook.d.ts +19 -0
  7. package/lib/AgentNotebook.js +192 -0
  8. package/lib/agent-lexical-main.d.ts +1 -0
  9. package/lib/agent-lexical-main.js +11 -0
  10. package/lib/agent-main.d.ts +1 -0
  11. package/lib/agent-main.js +11 -0
  12. package/lib/agent-notebook-main.d.ts +1 -0
  13. package/lib/agent-notebook-main.js +12 -0
  14. package/lib/components/AgentConfiguration.d.ts +33 -21
  15. package/lib/components/AgentConfiguration.js +76 -21
  16. package/lib/components/chat/components/AgentDetails.d.ts +3 -1
  17. package/lib/components/chat/components/AgentDetails.js +164 -6
  18. package/lib/components/chat/components/Chat.d.ts +29 -3
  19. package/lib/components/chat/components/Chat.js +64 -59
  20. package/lib/components/chat/components/ChatFloating.d.ts +34 -12
  21. package/lib/components/chat/components/ChatFloating.js +54 -21
  22. package/lib/components/chat/components/ChatInline.d.ts +5 -1
  23. package/lib/components/chat/components/ChatInline.js +8 -1
  24. package/lib/components/chat/components/ChatSidebar.d.ts +6 -1
  25. package/lib/components/chat/components/ChatSidebar.js +2 -2
  26. package/lib/components/chat/components/ChatStandalone.d.ts +6 -1
  27. package/lib/components/chat/components/ChatStandalone.js +2 -2
  28. package/lib/components/chat/components/ContextDistribution.js +2 -2
  29. package/lib/components/chat/components/ContextInspector.js +4 -2
  30. package/lib/components/chat/components/ContextPanel.js +1 -6
  31. package/lib/components/chat/components/base/ChatBase.d.ts +49 -8
  32. package/lib/components/chat/components/base/ChatBase.js +544 -149
  33. package/lib/components/chat/components/base/InputPrompt.d.ts +42 -0
  34. package/lib/components/chat/components/base/InputPrompt.js +131 -0
  35. package/lib/components/chat/components/index.d.ts +3 -3
  36. package/lib/components/chat/components/index.js +1 -1
  37. package/lib/components/chat/components/parts/ReasoningPart.js +2 -4
  38. package/lib/components/chat/components/parts/TextPart.js +2 -70
  39. package/lib/components/chat/components/styles/streamdownStyles.d.ts +23 -0
  40. package/lib/components/chat/components/styles/streamdownStyles.js +319 -0
  41. package/lib/components/chat/index.d.ts +1 -1
  42. package/lib/components/chat/index.js +1 -1
  43. package/lib/components/chat/inference/DatalayerInferenceProvider.js +16 -12
  44. package/lib/components/chat/inference/SelfHostedInferenceProvider.js +16 -12
  45. package/lib/components/chat/protocols/AGUIAdapter.d.ts +10 -3
  46. package/lib/components/chat/protocols/AGUIAdapter.js +123 -44
  47. package/lib/components/chat/types/tool.d.ts +5 -2
  48. package/lib/components/index.d.ts +2 -19
  49. package/lib/components/index.js +1 -10
  50. package/lib/config/index.d.ts +0 -3
  51. package/lib/config/index.js +0 -3
  52. package/lib/examples/A2UiRestaurantExample.js +1 -1
  53. package/lib/examples/AgentRuntimeChatExample.d.ts +15 -0
  54. package/lib/examples/AgentRuntimeChatExample.js +126 -0
  55. package/lib/examples/{AgentSpaceFormExample.d.ts → AgentRuntimeFormExample.d.ts} +3 -3
  56. package/lib/examples/{AgentSpaceFormExample.js → AgentRuntimeFormExample.js} +61 -17
  57. package/lib/examples/AgentRuntimeLexicalExample.js +6 -3
  58. package/lib/examples/AgentRuntimeLexicalSidebarExample.js +8 -1
  59. package/lib/examples/AgentRuntimeNotebookExample.js +6 -5
  60. package/lib/examples/CopilotKitNotebookExample.js +2 -2
  61. package/lib/examples/JupyterNotebookExample.js +2 -2
  62. package/lib/{components → examples/components}/Header.d.ts +2 -1
  63. package/lib/{components → examples/components}/HeaderControls.js +1 -1
  64. package/lib/{components → examples/components}/LexicalEditor.d.ts +6 -1
  65. package/lib/{components → examples/components}/LexicalEditor.js +4 -4
  66. package/lib/{components → examples/components}/MainContent.d.ts +1 -1
  67. package/lib/{components → examples/components}/MainContent.js +7 -5
  68. package/lib/examples/components/index.d.ts +16 -0
  69. package/lib/examples/components/index.js +13 -0
  70. package/lib/examples/example-selector.js +2 -1
  71. package/lib/examples/index.d.ts +1 -1
  72. package/lib/examples/index.js +1 -1
  73. package/lib/examples/main.js +2 -2
  74. package/lib/examples/stores/examplesStore.d.ts +2 -23
  75. package/lib/index.d.ts +2 -1
  76. package/lib/index.js +1 -0
  77. package/lib/lexical/ChatInlinePlugin.d.ts +13 -2
  78. package/lib/lexical/ChatInlinePlugin.js +41 -179
  79. package/lib/lexical/index.d.ts +1 -0
  80. package/lib/lexical/index.js +1 -0
  81. package/lib/lexical/useChatInlineToolbarItems.d.ts +28 -0
  82. package/lib/lexical/useChatInlineToolbarItems.js +163 -0
  83. package/lib/runtime/useAgentRuntime.d.ts +1 -1
  84. package/lib/runtime/useAgentRuntime.js +1 -1
  85. package/lib/specs/agents/codeai/agents.d.ts +28 -0
  86. package/lib/specs/agents/codeai/agents.js +151 -0
  87. package/lib/specs/agents/codeai/index.d.ts +1 -0
  88. package/lib/specs/agents/codeai/index.js +5 -0
  89. package/lib/{config → specs/agents/codemode-paper}/agents.d.ts +4 -6
  90. package/lib/specs/agents/codemode-paper/agents.js +308 -0
  91. package/lib/specs/agents/codemode-paper/index.d.ts +1 -0
  92. package/lib/specs/agents/codemode-paper/index.js +5 -0
  93. package/lib/specs/agents/datalayer-ai/agents.d.ts +31 -0
  94. package/lib/{config → specs/agents/datalayer-ai}/agents.js +42 -184
  95. package/lib/specs/agents/datalayer-ai/index.d.ts +1 -0
  96. package/lib/specs/agents/datalayer-ai/index.js +5 -0
  97. package/lib/specs/agents/index.d.ts +21 -0
  98. package/lib/specs/agents/index.js +47 -0
  99. package/lib/specs/envvars.d.ts +29 -0
  100. package/lib/specs/envvars.js +125 -0
  101. package/lib/specs/index.d.ts +5 -0
  102. package/lib/specs/index.js +9 -0
  103. package/lib/{config → specs}/mcpServers.d.ts +2 -1
  104. package/lib/{config → specs}/mcpServers.js +47 -1
  105. package/lib/specs/models.d.ts +68 -0
  106. package/lib/specs/models.js +239 -0
  107. package/lib/{config → specs}/skills.d.ts +2 -0
  108. package/lib/{config → specs}/skills.js +6 -0
  109. package/lib/state/substates/AIAgentState.d.ts +0 -1
  110. package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.d.ts +11 -22
  111. package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.js +5 -5
  112. package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +6 -6
  113. package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +4 -4
  114. package/lib/tools/adapters/agent-runtimes/notebookHooks.d.ts +6 -6
  115. package/lib/tools/adapters/agent-runtimes/notebookHooks.js +4 -4
  116. package/lib/{types.d.ts → types/Types.d.ts} +42 -8
  117. package/lib/types/index.d.ts +1 -0
  118. package/lib/types/index.js +1 -0
  119. package/package.json +11 -5
  120. package/scripts/codegen/generate_agents.py +608 -157
  121. package/scripts/codegen/generate_envvars.py +302 -0
  122. package/scripts/codegen/generate_mcp_servers.py +33 -21
  123. package/scripts/codegen/generate_models.py +486 -0
  124. package/scripts/codegen/generate_skills.py +21 -8
  125. package/style/primer-primitives.css +22 -0
  126. package/lib/components/chat/components/elements/ChatInputPrompt.d.ts +0 -37
  127. package/lib/components/chat/components/elements/ChatInputPrompt.js +0 -150
  128. /package/lib/{components → examples/components}/FooterMetrics.d.ts +0 -0
  129. /package/lib/{components → examples/components}/FooterMetrics.js +0 -0
  130. /package/lib/{components → examples/components}/Header.js +0 -0
  131. /package/lib/{components → examples/components}/HeaderControls.d.ts +0 -0
  132. /package/lib/{components → examples/components}/MockFileBrowser.d.ts +0 -0
  133. /package/lib/{components → examples/components}/MockFileBrowser.js +0 -0
  134. /package/lib/{components → examples/components}/SessionTabs.d.ts +0 -0
  135. /package/lib/{components → examples/components}/SessionTabs.js +0 -0
  136. /package/lib/{components → examples/components}/TimeTravel.d.ts +0 -0
  137. /package/lib/{components → examples/components}/TimeTravel.js +0 -0
  138. /package/lib/{types.js → types/Types.js} +0 -0
@@ -0,0 +1,486 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ """
6
+ Generate Python and TypeScript code from YAML AI model specifications.
7
+
8
+ Usage:
9
+ python generate_models.py \\
10
+ --specs-dir agentspecs/agentspecs/models \\
11
+ --python-output agent_runtimes/config/models.py \\
12
+ --typescript-output src/config/models.ts
13
+ """
14
+
15
+ import argparse
16
+ import sys
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import yaml
21
+
22
+
23
+ def load_model_specs(specs_dir: Path) -> list[dict[str, Any]]:
24
+ """Load all AI model YAML specifications from a directory."""
25
+ specs = []
26
+ for yaml_file in sorted(specs_dir.glob("*.yaml")):
27
+ with open(yaml_file) as f:
28
+ spec = yaml.safe_load(f)
29
+ specs.append(spec)
30
+ return specs
31
+
32
+
33
+ def _make_const_name(model_id: str) -> str:
34
+ """
35
+ Convert a model ID to a Python/TypeScript constant name.
36
+
37
+ E.g. 'anthropic:claude-sonnet-4-5-20250514' -> 'ANTHROPIC_CLAUDE_SONNET_4_5_20250514'
38
+ """
39
+ return model_id.upper().replace(":", "_").replace("-", "_").replace(".", "_")
40
+
41
+
42
+ def _make_enum_name(model_id: str) -> str:
43
+ """Convert a model ID to an enum member name (same as const name)."""
44
+ return _make_const_name(model_id)
45
+
46
+
47
+ def generate_python_code(specs: list[dict[str, Any]]) -> str:
48
+ """Generate Python code from AI model specifications."""
49
+ lines = [
50
+ "# Copyright (c) 2025-2026 Datalayer, Inc.",
51
+ "# Distributed under the terms of the Modified BSD License.",
52
+ '"""',
53
+ "AI Model Catalog.",
54
+ "",
55
+ "Predefined AI model configurations.",
56
+ "",
57
+ "This file is AUTO-GENERATED from YAML specifications.",
58
+ "DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
59
+ '"""',
60
+ "",
61
+ "import os",
62
+ "from enum import Enum",
63
+ "from typing import Dict, List, Optional",
64
+ "",
65
+ "from pydantic import BaseModel, Field",
66
+ "",
67
+ "",
68
+ "# " + "=" * 76,
69
+ "# AIModel Pydantic class",
70
+ "# " + "=" * 76,
71
+ "",
72
+ "",
73
+ "class AIModel(BaseModel):",
74
+ ' """Specification for an AI model."""',
75
+ "",
76
+ ' id: str = Field(..., description="Unique model identifier")',
77
+ ' name: str = Field(..., description="Display name")',
78
+ ' description: str = Field(default="", description="Model description")',
79
+ ' provider: str = Field(..., description="Provider name")',
80
+ ' default: bool = Field(default=False, description="Whether this is the default model")',
81
+ " required_env_vars: List[str] = Field(",
82
+ " default_factory=list,",
83
+ ' description="Required environment variable names",',
84
+ " )",
85
+ "",
86
+ "",
87
+ "# " + "=" * 76,
88
+ "# AIModels Enum",
89
+ "# " + "=" * 76,
90
+ "",
91
+ "",
92
+ "class AIModels(str, Enum):",
93
+ ' """Enumeration of all available AI model IDs."""',
94
+ "",
95
+ ]
96
+
97
+ # Generate enum members
98
+ for spec in specs:
99
+ enum_name = _make_enum_name(spec["id"])
100
+ lines.append(f' {enum_name} = "{spec["id"]}"')
101
+
102
+ lines.extend(
103
+ [
104
+ "",
105
+ "",
106
+ "# " + "=" * 76,
107
+ "# AI Model Definitions",
108
+ "# " + "=" * 76,
109
+ "",
110
+ ]
111
+ )
112
+
113
+ # Generate model constants
114
+ for spec in specs:
115
+ const_name = _make_const_name(spec["id"])
116
+
117
+ # Format required_env_vars
118
+ env_vars = spec.get("required_env_vars", [])
119
+ if env_vars:
120
+ env_vars_formatted = "[" + ", ".join(f'"{v}"' for v in env_vars) + "]"
121
+ else:
122
+ env_vars_formatted = "[]"
123
+
124
+ lines.extend(
125
+ [
126
+ f"{const_name} = AIModel(",
127
+ f' id="{spec["id"]}",',
128
+ f' name="{spec["name"]}",',
129
+ f' description="{spec.get("description", "")}",',
130
+ f' provider="{spec["provider"]}",',
131
+ f" default={spec.get('default', False)},",
132
+ f" required_env_vars={env_vars_formatted},",
133
+ ")",
134
+ "",
135
+ ]
136
+ )
137
+
138
+ # Generate catalog dictionary
139
+ lines.extend(
140
+ [
141
+ "# " + "=" * 76,
142
+ "# AI Model Catalog",
143
+ "# " + "=" * 76,
144
+ "",
145
+ "AI_MODEL_CATALOGUE: Dict[str, AIModel] = {",
146
+ ]
147
+ )
148
+
149
+ for spec in specs:
150
+ model_id = spec["id"]
151
+ const_name = _make_const_name(model_id)
152
+ lines.append(f' "{model_id}": {const_name},')
153
+
154
+ lines.extend(
155
+ [
156
+ "}",
157
+ "",
158
+ ]
159
+ )
160
+
161
+ # Find default model
162
+ default_specs = [s for s in specs if s.get("default", False)]
163
+ if default_specs:
164
+ default_id = default_specs[0]["id"]
165
+ default_enum = _make_enum_name(default_id)
166
+ lines.extend(
167
+ [
168
+ "",
169
+ f"DEFAULT_MODEL: AIModels = AIModels.{default_enum}",
170
+ "",
171
+ ]
172
+ )
173
+ else:
174
+ lines.extend(
175
+ [
176
+ "",
177
+ "DEFAULT_MODEL: Optional[AIModels] = None",
178
+ "",
179
+ ]
180
+ )
181
+
182
+ # Generate helper functions
183
+ lines.extend(
184
+ [
185
+ "",
186
+ "def check_env_vars_available(env_vars: list[str]) -> bool:",
187
+ ' """',
188
+ " Check if all required environment variables are set.",
189
+ "",
190
+ " Args:",
191
+ " env_vars: List of environment variable names to check.",
192
+ "",
193
+ " Returns:",
194
+ " True if all env vars are set (non-empty), False otherwise.",
195
+ ' """',
196
+ " if not env_vars:",
197
+ " return True",
198
+ " return all(os.environ.get(var) for var in env_vars)",
199
+ "",
200
+ "",
201
+ "def get_model(model_id: str) -> Optional[AIModel]:",
202
+ ' """',
203
+ " Get an AI model by ID.",
204
+ "",
205
+ " Args:",
206
+ " model_id: The unique identifier of the AI model.",
207
+ "",
208
+ " Returns:",
209
+ " The AIModel specification, or None if not found.",
210
+ ' """',
211
+ " return AI_MODEL_CATALOGUE.get(model_id)",
212
+ "",
213
+ "",
214
+ "def get_default_model() -> Optional[AIModel]:",
215
+ ' """',
216
+ " Get the default AI model.",
217
+ "",
218
+ " Returns:",
219
+ " The default AIModel, or None if no default is set.",
220
+ ' """',
221
+ " if DEFAULT_MODEL is None:",
222
+ " return None",
223
+ " return AI_MODEL_CATALOGUE.get(DEFAULT_MODEL.value)",
224
+ "",
225
+ "",
226
+ "def list_models() -> list[AIModel]:",
227
+ ' """',
228
+ " List all AI models with availability status.",
229
+ "",
230
+ " For each model, checks if the required environment variables are set.",
231
+ "",
232
+ " Returns:",
233
+ " List of all AIModel specifications.",
234
+ ' """',
235
+ " return list(AI_MODEL_CATALOGUE.values())",
236
+ "",
237
+ ]
238
+ )
239
+
240
+ return "\n".join(lines)
241
+
242
+
243
+ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
244
+ """Generate TypeScript code from AI model specifications."""
245
+ lines = [
246
+ "/*",
247
+ " * Copyright (c) 2025-2026 Datalayer, Inc.",
248
+ " * Distributed under the terms of the Modified BSD License.",
249
+ " */",
250
+ "",
251
+ "/**",
252
+ " * AI Model Catalog",
253
+ " *",
254
+ " * Predefined AI model configurations.",
255
+ " *",
256
+ " * This file is AUTO-GENERATED from YAML specifications.",
257
+ " * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
258
+ " */",
259
+ "",
260
+ "// " + "=" * 76,
261
+ "// AIModel Type",
262
+ "// " + "=" * 76,
263
+ "",
264
+ "export interface AIModel {",
265
+ " /** Unique model identifier (e.g., 'anthropic:claude-sonnet-4-5-20250514') */",
266
+ " id: string;",
267
+ " /** Display name for the model */",
268
+ " name: string;",
269
+ " /** Model description */",
270
+ " description: string;",
271
+ " /** Provider name (anthropic, openai, bedrock, azure-openai) */",
272
+ " provider: string;",
273
+ " /** Whether this is the default model */",
274
+ " default: boolean;",
275
+ " /** Required environment variable names */",
276
+ " requiredEnvVars: string[];",
277
+ "}",
278
+ "",
279
+ "// " + "=" * 76,
280
+ "// AIModels Enum",
281
+ "// " + "=" * 76,
282
+ "",
283
+ "export const AIModels = {",
284
+ ]
285
+
286
+ # Generate enum-like const object
287
+ for spec in specs:
288
+ enum_name = _make_enum_name(spec["id"])
289
+ lines.append(f" {enum_name}: '{spec['id']}',")
290
+
291
+ lines.extend(
292
+ [
293
+ "} as const;",
294
+ "",
295
+ "export type AIModelId = (typeof AIModels)[keyof typeof AIModels];",
296
+ "",
297
+ "// " + "=" * 76,
298
+ "// AI Model Definitions",
299
+ "// " + "=" * 76,
300
+ "",
301
+ ]
302
+ )
303
+
304
+ # Generate model constants
305
+ for spec in specs:
306
+ const_name = _make_const_name(spec["id"])
307
+
308
+ # Format required_env_vars
309
+ env_vars = spec.get("required_env_vars", [])
310
+ if env_vars:
311
+ env_vars_formatted = "[" + ", ".join(f"'{v}'" for v in env_vars) + "]"
312
+ else:
313
+ env_vars_formatted = "[]"
314
+
315
+ # Escape description for TypeScript
316
+ description = spec.get("description", "").replace("'", "\\'")
317
+
318
+ lines.extend(
319
+ [
320
+ f"export const {const_name}: AIModel = {{",
321
+ f" id: '{spec['id']}',",
322
+ f" name: '{spec['name']}',",
323
+ f" description: '{description}',",
324
+ f" provider: '{spec['provider']}',",
325
+ f" default: {str(spec.get('default', False)).lower()},",
326
+ f" requiredEnvVars: {env_vars_formatted},",
327
+ "};",
328
+ "",
329
+ ]
330
+ )
331
+
332
+ # Generate catalog object
333
+ lines.extend(
334
+ [
335
+ "// " + "=" * 76,
336
+ "// AI Model Catalog",
337
+ "// " + "=" * 76,
338
+ "",
339
+ "export const AI_MODEL_CATALOGUE: Record<string, AIModel> = {",
340
+ ]
341
+ )
342
+
343
+ for spec in specs:
344
+ model_id = spec["id"]
345
+ const_name = _make_const_name(model_id)
346
+ lines.append(f" '{model_id}': {const_name},")
347
+
348
+ lines.extend(
349
+ [
350
+ "};",
351
+ "",
352
+ ]
353
+ )
354
+
355
+ # Default model
356
+ default_specs = [s for s in specs if s.get("default", False)]
357
+ if default_specs:
358
+ default_id = default_specs[0]["id"]
359
+ default_const = _make_const_name(default_id)
360
+ lines.extend(
361
+ [
362
+ f"export const DEFAULT_MODEL: AIModelId = AIModels.{_make_enum_name(default_id)};",
363
+ f"export const DEFAULT_MODEL_SPEC: AIModel = {default_const};",
364
+ "",
365
+ ]
366
+ )
367
+
368
+ return "\n".join(lines)
369
+
370
+
371
+ def update_init_file(specs: list[dict[str, Any]], init_file: Path) -> None:
372
+ """Update the __init__.py file with correct imports based on generated specs."""
373
+ # Generate list of model constant names
374
+ model_constants = []
375
+ for spec in specs:
376
+ const_name = _make_const_name(spec["id"])
377
+ model_constants.append(const_name)
378
+
379
+ # Read the current __init__.py
380
+ init_content = init_file.read_text()
381
+
382
+ # Find the catalog_models import section
383
+ import_start = init_content.find("from .models import (")
384
+ if import_start == -1:
385
+ print(f"Warning: Could not find models import in {init_file}")
386
+ return
387
+
388
+ # Find the end of the import statement
389
+ import_end = init_content.find(")", import_start)
390
+ if import_end == -1:
391
+ print(f"Warning: Could not find end of models import in {init_file}")
392
+ return
393
+
394
+ # Generate new import lines - all names sorted alphabetically
395
+ all_names = sorted(
396
+ model_constants
397
+ + [
398
+ "AIModel",
399
+ "AIModels",
400
+ "AI_MODEL_CATALOGUE",
401
+ "DEFAULT_MODEL",
402
+ "check_env_vars_available",
403
+ "get_default_model",
404
+ "get_model",
405
+ "list_models",
406
+ ],
407
+ key=str.casefold,
408
+ )
409
+ new_imports = ["from .models import ("]
410
+ for name in all_names:
411
+ new_imports.append(f" {name},")
412
+ new_imports.append(")")
413
+
414
+ # Replace the import section
415
+ new_content = (
416
+ init_content[:import_start]
417
+ + "\n".join(new_imports)
418
+ + init_content[import_end + 1 :]
419
+ )
420
+
421
+ # Write updated content
422
+ init_file.write_text(new_content)
423
+ print(f"✓ Updated {init_file}")
424
+
425
+
426
+ def main():
427
+ """Main entry point."""
428
+ parser = argparse.ArgumentParser(
429
+ description="Generate Python and TypeScript code from YAML AI model specifications"
430
+ )
431
+ parser.add_argument(
432
+ "--specs-dir",
433
+ type=Path,
434
+ required=True,
435
+ help="Directory containing YAML model specification files",
436
+ )
437
+ parser.add_argument(
438
+ "--python-output",
439
+ type=Path,
440
+ required=True,
441
+ help="Output path for generated Python file",
442
+ )
443
+ parser.add_argument(
444
+ "--typescript-output",
445
+ type=Path,
446
+ required=True,
447
+ help="Output path for generated TypeScript file",
448
+ )
449
+
450
+ args = parser.parse_args()
451
+
452
+ # Validate specs directory
453
+ if not args.specs_dir.exists():
454
+ print(f"Error: Specs directory does not exist: {args.specs_dir}")
455
+ sys.exit(1)
456
+
457
+ # Load specifications
458
+ print(f"Loading AI model specs from {args.specs_dir}...")
459
+ specs = load_model_specs(args.specs_dir)
460
+ print(f"Loaded {len(specs)} AI model specifications")
461
+
462
+ # Generate Python code
463
+ print("Generating Python code...")
464
+ python_code = generate_python_code(specs)
465
+ args.python_output.parent.mkdir(parents=True, exist_ok=True)
466
+ args.python_output.write_text(python_code)
467
+ print(f"✓ Generated {args.python_output}")
468
+
469
+ # Generate TypeScript code
470
+ print("Generating TypeScript code...")
471
+ typescript_code = generate_typescript_code(specs)
472
+ args.typescript_output.parent.mkdir(parents=True, exist_ok=True)
473
+ args.typescript_output.write_text(typescript_code)
474
+ print(f"✓ Generated {args.typescript_output}")
475
+
476
+ # Update __init__.py with correct imports
477
+ init_file = args.python_output.parent / "__init__.py"
478
+ if init_file.exists():
479
+ print("Updating imports in __init__.py...")
480
+ update_init_file(specs, init_file)
481
+
482
+ print(f"\n✓ Successfully generated code from {len(specs)} AI model specs")
483
+
484
+
485
+ if __name__ == "__main__":
486
+ main()
@@ -64,10 +64,12 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
64
64
  " name: str",
65
65
  " description: str",
66
66
  " module: str",
67
- " required_env_vars: List[str]",
67
+ " envvars: List[str]",
68
68
  " optional_env_vars: List[str]",
69
69
  " dependencies: List[str]",
70
70
  " tags: List[str]",
71
+ " icon: str | None",
72
+ " emoji: str | None",
71
73
  " enabled: bool",
72
74
  "",
73
75
  "",
@@ -82,6 +84,9 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
82
84
  skill_id = spec["id"]
83
85
  const_name = f"{skill_id.upper().replace('-', '_')}_SKILL_SPEC"
84
86
 
87
+ icon = f'"{spec.get("icon")}"' if spec.get("icon") else "None"
88
+ emoji = f'"{spec.get("emoji")}"' if spec.get("emoji") else "None"
89
+
85
90
  lines.extend(
86
91
  [
87
92
  f"{const_name} = SkillSpec(",
@@ -89,10 +94,12 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
89
94
  f' name="{spec["name"]}",',
90
95
  f' description="{spec["description"]}",',
91
96
  f' module="{spec.get("module", "")}",',
92
- f" required_env_vars={_fmt_list(spec.get('required_env_vars', []))},",
97
+ f" envvars={_fmt_list(spec.get('envvars', []))},",
93
98
  f" optional_env_vars={_fmt_list(spec.get('optional_env_vars', []))},",
94
99
  f" dependencies={_fmt_list(spec.get('dependencies', []))},",
95
100
  f" tags={_fmt_list(spec.get('tags', []))},",
101
+ f" icon={icon},",
102
+ f" emoji={emoji},",
96
103
  f" enabled={spec.get('enabled', True)},",
97
104
  ")",
98
105
  "",
@@ -189,6 +196,8 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
189
196
  " optionalEnvVars: string[];",
190
197
  " dependencies: string[];",
191
198
  " tags: string[];",
199
+ " icon?: string;",
200
+ " emoji?: string;",
192
201
  " enabled: boolean;",
193
202
  "}",
194
203
  "",
@@ -204,15 +213,17 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
204
213
  const_name = f"{skill_id.upper().replace('-', '_')}_SKILL_SPEC"
205
214
 
206
215
  # Format arrays for TypeScript
207
- required_env_vars_json = str(spec.get("required_env_vars", [])).replace(
208
- "'", '"'
209
- )
216
+ envvars_json = str(spec.get("envvars", [])).replace("'", '"')
210
217
  optional_env_vars_json = str(spec.get("optional_env_vars", [])).replace(
211
218
  "'", '"'
212
219
  )
213
220
  dependencies_json = str(spec.get("dependencies", [])).replace("'", '"')
214
221
  tags_json = str(spec.get("tags", [])).replace("'", '"')
215
222
 
223
+ # Format optional fields
224
+ icon = f"'{spec.get('icon')}'" if spec.get("icon") else "undefined"
225
+ emoji = f"'{spec.get('emoji')}'" if spec.get("emoji") else "undefined"
226
+
216
227
  lines.extend(
217
228
  [
218
229
  f"export const {const_name}: SkillSpec = {{",
@@ -220,10 +231,12 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
220
231
  f" name: '{spec['name']}',",
221
232
  f" description: '{spec['description']}',",
222
233
  f" module: '{spec.get('module', '')}',",
223
- f" requiredEnvVars: {required_env_vars_json},",
234
+ f" requiredEnvVars: {envvars_json},",
224
235
  f" optionalEnvVars: {optional_env_vars_json},",
225
236
  f" dependencies: {dependencies_json},",
226
237
  f" tags: {tags_json},",
238
+ f" icon: {icon},",
239
+ f" emoji: {emoji},",
227
240
  f" enabled: {str(spec.get('enabled', True)).lower()},",
228
241
  "};",
229
242
  "",
@@ -301,14 +314,14 @@ def main():
301
314
  print(f"Loaded {len(specs)} skill specifications")
302
315
 
303
316
  # Generate Python code
304
- print(f"Generating Python code...")
317
+ print("Generating Python code...")
305
318
  python_code = generate_python_code(specs)
306
319
  args.python_output.parent.mkdir(parents=True, exist_ok=True)
307
320
  args.python_output.write_text(python_code)
308
321
  print(f"✓ Generated {args.python_output}")
309
322
 
310
323
  # Generate TypeScript code
311
- print(f"Generating TypeScript code...")
324
+ print("Generating TypeScript code...")
312
325
  typescript_code = generate_typescript_code(specs)
313
326
  args.typescript_output.parent.mkdir(parents=True, exist_ok=True)
314
327
  args.typescript_output.write_text(typescript_code)
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ /*
7
+ * Copyright (c) 2021-2024 Datalayer, Inc.
8
+ *
9
+ * Datalayer License
10
+ */
11
+
12
+ @import url('~@primer/primitives/dist/css/base/size/size.css');
13
+ @import url('~@primer/primitives/dist/css/base/typography/typography.css');
14
+ @import url('~@primer/primitives/dist/css/functional/size/border.css');
15
+ @import url('~@primer/primitives/dist/css/functional/size/breakpoints.css');
16
+ @import url('~@primer/primitives/dist/css/functional/size/size-coarse.css');
17
+ @import url('~@primer/primitives/dist/css/functional/size/size-fine.css');
18
+ @import url('~@primer/primitives/dist/css/functional/size/size.css');
19
+ @import url('~@primer/primitives/dist/css/functional/size/viewport.css');
20
+ @import url('~@primer/primitives/dist/css/functional/themes/light.css');
21
+ @import url('~@primer/primitives/dist/css/functional/themes/dark.css');
22
+ @import url('~@primer/primitives/dist/css/functional/typography/typography.css');
@@ -1,37 +0,0 @@
1
- /**
2
- * Chat input component.
3
- * Provides the message input area with send button and optional tool suggestions.
4
- *
5
- * @module components/chat/components/elements/ChatInputPrompt
6
- */
7
- import React from 'react';
8
- /**
9
- * ChatInputPrompt props
10
- */
11
- export interface ChatInputPromptProps {
12
- /** Placeholder text */
13
- placeholder?: string;
14
- /** Disable input */
15
- disabled?: boolean;
16
- /** Show tool suggestions */
17
- showToolSuggestions?: boolean;
18
- /** Show file upload button */
19
- showFileUpload?: boolean;
20
- /** Maximum rows for textarea */
21
- maxRows?: number;
22
- /** Custom class name */
23
- className?: string;
24
- /** Leading icon to display on the left of the input */
25
- leadingIcon?: React.ReactNode;
26
- /** Custom send button text */
27
- sendButtonText?: string;
28
- /** Callback before sending */
29
- onBeforeSend?: (content: string) => boolean | void;
30
- /** Callback after sending */
31
- onAfterSend?: (content: string) => void;
32
- }
33
- /**
34
- * Chat Input Prompt component
35
- */
36
- export declare function ChatInputPrompt({ placeholder, disabled, showToolSuggestions, showFileUpload, maxRows, className, leadingIcon, sendButtonText, onBeforeSend, onAfterSend, }: ChatInputPromptProps): import("react/jsx-runtime").JSX.Element;
37
- export default ChatInputPrompt;