@datalayer/agent-runtimes 0.0.4 → 0.0.7

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 (36) hide show
  1. package/README.md +141 -22
  2. package/lib/components/chat/components/AgentDetails.d.ts +1 -1
  3. package/lib/components/chat/components/AgentDetails.js +7 -92
  4. package/lib/components/chat/components/Chat.d.ts +5 -1
  5. package/lib/components/chat/components/Chat.js +28 -19
  6. package/lib/components/chat/components/ContextDistribution.d.ts +47 -0
  7. package/lib/components/chat/components/ContextDistribution.js +146 -0
  8. package/lib/components/chat/components/ContextUsage.d.ts +33 -0
  9. package/lib/components/chat/components/ContextUsage.js +127 -0
  10. package/lib/components/chat/components/base/ChatBase.d.ts +5 -1
  11. package/lib/components/chat/components/base/ChatBase.js +40 -15
  12. package/lib/components/chat/components/index.d.ts +2 -0
  13. package/lib/components/chat/components/index.js +2 -0
  14. package/lib/examples/AgentSpaceFormExample.js +41 -6
  15. package/lib/examples/components/AgentConfiguration.d.ts +22 -0
  16. package/lib/examples/components/AgentConfiguration.js +37 -10
  17. package/lib/examples/components/Header.d.ts +0 -2
  18. package/lib/examples/components/Header.js +2 -16
  19. package/lib/index.d.ts +1 -0
  20. package/lib/index.js +1 -0
  21. package/lib/runtime/index.d.ts +35 -0
  22. package/lib/runtime/index.js +40 -0
  23. package/lib/runtime/runtimeStore.d.ts +77 -0
  24. package/lib/runtime/runtimeStore.js +184 -0
  25. package/lib/runtime/types.d.ts +84 -0
  26. package/lib/runtime/types.js +15 -0
  27. package/lib/runtime/useAgentConnection.d.ts +46 -0
  28. package/lib/runtime/useAgentConnection.js +112 -0
  29. package/lib/runtime/useAgentRuntime.d.ts +94 -0
  30. package/lib/runtime/useAgentRuntime.js +125 -0
  31. package/package.json +4 -2
  32. package/patches/.gitkeep +1 -0
  33. package/scripts/apply-patches.sh +26 -0
  34. package/scripts/create-patches.sh +40 -0
  35. package/scripts/download-ai-elements.py +86 -0
  36. package/scripts/sync-jupyter.sh +123 -0
@@ -0,0 +1,125 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ /**
6
+ * Combined hook for using a runtime with an AI agent.
7
+ *
8
+ * This is the main entry point for consumers who want a simple,
9
+ * all-in-one solution for cloud runtime + agent management.
10
+ *
11
+ * @module runtime/useAgentRuntime
12
+ */
13
+ import { useEffect, useRef, useCallback } from 'react';
14
+ import { useRuntimeStore, useRuntime, useAgent, useRuntimeStatus, useRuntimeError, useIsLaunching, } from './runtimeStore';
15
+ /**
16
+ * Combined hook for using a runtime with an AI agent.
17
+ *
18
+ * This hook provides everything needed to:
19
+ * 1. Connect to an existing runtime (or launch a new one)
20
+ * 2. Create an AI agent on the runtime
21
+ *
22
+ * Use this in conjunction with useNotebookTools or useLexicalTools
23
+ * for frontend tool execution.
24
+ *
25
+ * @param options - Configuration options
26
+ * @returns Complete agent runtime state and controls
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // For notebooks
31
+ * import { useAgentRuntime } from '@datalayer/agent-runtimes/lib/runtime';
32
+ * import { useNotebookTools } from '@datalayer/agent-runtimes/lib/tools/adapters/agent-runtimes';
33
+ *
34
+ * function NotebookEditor({ notebookId }) {
35
+ * const {
36
+ * isReady,
37
+ * endpoint,
38
+ * error,
39
+ * connectToRuntime,
40
+ * } = useAgentRuntime({
41
+ * autoCreateAgent: true,
42
+ * agentConfig: {
43
+ * model: 'anthropic:claude-sonnet-4-5',
44
+ * systemPrompt: 'You help users with Jupyter notebooks.',
45
+ * },
46
+ * });
47
+ *
48
+ * // Get tools separately
49
+ * const tools = useNotebookTools(notebookId);
50
+ *
51
+ * // Connect when user assigns a runtime
52
+ * const onRuntimeAssigned = (serviceManager, podName, poolName) => {
53
+ * connectToRuntime({ serviceManager, podName, jupyterpoolName: poolName });
54
+ * };
55
+ *
56
+ * return (
57
+ * <>
58
+ * <Notebook />
59
+ * {isReady && (
60
+ * <ChatFloating endpoint={endpoint} tools={tools} />
61
+ * )}
62
+ * {error && <ErrorBanner>{error}</ErrorBanner>}
63
+ * </>
64
+ * );
65
+ * }
66
+ * ```
67
+ */
68
+ export function useAgentRuntime(options = {}) {
69
+ const { agentConfig, autoCreateAgent = true } = options;
70
+ // Get store state
71
+ const runtime = useRuntime();
72
+ const agent = useAgent();
73
+ const status = useRuntimeStatus();
74
+ const error = useRuntimeError();
75
+ const isLaunching = useIsLaunching();
76
+ // Get store actions
77
+ const launchRuntime = useRuntimeStore(state => state.launchRuntime);
78
+ const connectToRuntime = useRuntimeStore(state => state.connectToRuntime);
79
+ const disconnect = useRuntimeStore(state => state.disconnect);
80
+ const createAgentAction = useRuntimeStore(state => state.createAgent);
81
+ // Track if we've created the agent to prevent duplicates
82
+ const hasCreatedAgentRef = useRef(false);
83
+ const agentConfigRef = useRef(agentConfig);
84
+ agentConfigRef.current = agentConfig;
85
+ // Auto-create agent when runtime is ready
86
+ useEffect(() => {
87
+ if (autoCreateAgent &&
88
+ runtime &&
89
+ status === 'ready' &&
90
+ !agent &&
91
+ !hasCreatedAgentRef.current) {
92
+ hasCreatedAgentRef.current = true;
93
+ createAgentAction(agentConfigRef.current).catch(err => {
94
+ console.error('[useAgentRuntime] Failed to auto-create agent:', err);
95
+ hasCreatedAgentRef.current = false;
96
+ });
97
+ }
98
+ }, [autoCreateAgent, runtime, status, agent, createAgentAction]);
99
+ // Reset agent creation tracking on disconnect
100
+ useEffect(() => {
101
+ if (status === 'disconnected' || status === 'idle') {
102
+ hasCreatedAgentRef.current = false;
103
+ }
104
+ }, [status]);
105
+ // Memoized create agent function
106
+ const createAgent = useCallback((config) => createAgentAction(config || agentConfig), [createAgentAction, agentConfig]);
107
+ // Derived state
108
+ const isReady = status === 'ready' && !!agent?.isReady;
109
+ const endpoint = agent?.endpoint || null;
110
+ const serviceManager = runtime?.serviceManager || null;
111
+ return {
112
+ runtime,
113
+ agent,
114
+ status,
115
+ error,
116
+ isLaunching,
117
+ isReady,
118
+ endpoint,
119
+ serviceManager,
120
+ launchRuntime,
121
+ connectToRuntime,
122
+ createAgent,
123
+ disconnect,
124
+ };
125
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "0.0.4",
3
+ "version": "0.0.7",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -28,7 +28,9 @@
28
28
  "files": [
29
29
  "lib/**/*.{css,d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
30
30
  "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
31
- "schema/*.json"
31
+ "schema/*.json",
32
+ "patches/",
33
+ "scripts/"
32
34
  ],
33
35
  "main": "lib/index.js",
34
36
  "types": "lib/index.d.ts",
@@ -0,0 +1 @@
1
+ # Patches directory for patch-package
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ # Apply patch-package patches for jupyter packages
6
+ # This is normally run automatically via npm's postinstall hook,
7
+ # but can be run manually if needed.
8
+
9
+ set -e
10
+
11
+ # Colors for output
12
+ GREEN='\033[0;32m'
13
+ BLUE='\033[0;34m'
14
+ NC='\033[0m' # No Color
15
+
16
+ echo -e "${BLUE}📝 Applying patches...${NC}"
17
+
18
+ # Get the script directory and project root
19
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
20
+ CORE_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
21
+
22
+ cd "$CORE_ROOT"
23
+
24
+ npx patch-package
25
+
26
+ echo -e "${GREEN}✅ Patches applied successfully${NC}"
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ # Create patch-package patches for locally modified jupyter packages
6
+ # This script generates patches that can be committed to the repo and
7
+ # applied automatically during npm install via the postinstall hook.
8
+
9
+ set -e
10
+
11
+ # Colors for output
12
+ GREEN='\033[0;32m'
13
+ BLUE='\033[0;34m'
14
+ YELLOW='\033[1;33m'
15
+ NC='\033[0m' # No Color
16
+
17
+ echo -e "${BLUE}🔧 Creating patches for jupyter packages...${NC}"
18
+
19
+ # Get the script directory and project root
20
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
21
+ CORE_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
22
+
23
+ cd "$CORE_ROOT"
24
+
25
+ # First, sync the latest changes from jupyter-ui to ensure patches include all modifications
26
+ echo -e "${BLUE}🔄 Syncing latest changes from jupyter-ui...${NC}"
27
+ bash "$SCRIPT_DIR/sync-jupyter.sh"
28
+
29
+ # Ensure package-lock.json exists (required by patch-package)
30
+ if [ ! -f "package-lock.json" ]; then
31
+ echo -e "${YELLOW}⚠️ No package-lock.json found. Creating one...${NC}"
32
+ npm i --package-lock-only
33
+ fi
34
+
35
+ # Create patches
36
+ echo -e "${BLUE}📝 Generating patches with patch-package...${NC}"
37
+ npx patch-package @datalayer/jupyter-lexical @datalayer/jupyter-react
38
+
39
+ echo -e "${GREEN}✅ Patches created successfully in patches/ directory${NC}"
40
+ echo -e "${BLUE}ℹ️ Patches will be applied automatically on 'npm install' via postinstall hook${NC}"
@@ -0,0 +1,86 @@
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
+ Download AI Elements components directly from the registry
7
+ """
8
+
9
+ import json
10
+ import os
11
+ import urllib.request
12
+ import sys
13
+
14
+ BASE_URL = "https://registry.ai-sdk.dev"
15
+ COMPONENTS_DIR = "src/components/ai-elements"
16
+
17
+ # Components to download
18
+ COMPONENTS = [
19
+ "message",
20
+ "conversation",
21
+ "prompt-input",
22
+ "model-selector",
23
+ "artifact",
24
+ "code-block",
25
+ "suggestion",
26
+ "sources",
27
+ "reasoning",
28
+ "tool",
29
+ "loader",
30
+ "shimmer",
31
+ ]
32
+
33
+ def download_component(component_name):
34
+ """Download a component from the registry"""
35
+ url = f"{BASE_URL}/{component_name}.json"
36
+ print(f"Downloading {component_name}...")
37
+
38
+ try:
39
+ with urllib.request.urlopen(url) as response:
40
+ data = json.loads(response.read())
41
+
42
+ # Get the first file (main component file)
43
+ if 'files' in data and len(data['files']) > 0:
44
+ file_data = data['files'][0]
45
+ content = file_data.get('content', '')
46
+ target = file_data.get('target', f"components/ai-elements/{component_name}.tsx")
47
+
48
+ # Adjust target path
49
+ target_path = os.path.join(COMPONENTS_DIR, f"{component_name}.tsx")
50
+
51
+ # Ensure directory exists
52
+ os.makedirs(os.path.dirname(target_path), exist_ok=True)
53
+
54
+ # Write file
55
+ with open(target_path, 'w') as f:
56
+ f.write(content)
57
+
58
+ print(f"✓ Downloaded {component_name} to {target_path}")
59
+ return True
60
+ else:
61
+ print(f"✗ No files found for {component_name}")
62
+ return False
63
+
64
+ except Exception as e:
65
+ print(f"✗ Error downloading {component_name}: {e}")
66
+ return False
67
+
68
+ def main():
69
+ print(f"Downloading AI Elements components to {COMPONENTS_DIR}")
70
+ print(f"Components: {', '.join(COMPONENTS)}\n")
71
+
72
+ # Create components directory
73
+ os.makedirs(COMPONENTS_DIR, exist_ok=True)
74
+
75
+ success_count = 0
76
+ for component in COMPONENTS:
77
+ if download_component(component):
78
+ success_count += 1
79
+
80
+ print(f"\n✓ Successfully downloaded {success_count}/{len(COMPONENTS)} components")
81
+
82
+ if success_count < len(COMPONENTS):
83
+ sys.exit(1)
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -0,0 +1,123 @@
1
+ #!/bin/bash
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ # Sync local jupyter-ui packages to @datalayer/agent-runtimes node_modules
6
+ # This script builds the local jupyter packages and copies their lib/ outputs
7
+ # into the core package's node_modules for quick testing during development.
8
+ #
9
+ # Usage:
10
+ # ./sync-jupyter.sh # Run once and exit
11
+ # ./sync-jupyter.sh --watch # Watch for changes and auto-sync
12
+
13
+ set -e
14
+
15
+ # Colors for output
16
+ GREEN='\033[0;32m'
17
+ BLUE='\033[0;34m'
18
+ YELLOW='\033[1;33m'
19
+ NC='\033[0m' # No Color
20
+
21
+ # Get the script directory and project root
22
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
23
+ CORE_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )"
24
+ JUPYTER_UI_ROOT="$( cd "$CORE_ROOT/../jupyter-ui" && pwd )"
25
+
26
+ # Function to perform the sync
27
+ sync_packages() {
28
+ echo -e "${BLUE}🔄 Syncing jupyter-ui packages to @datalayer/agent-runtimes...${NC}"
29
+
30
+ # Build jupyter-react FIRST (lexical depends on it)
31
+ echo -e "${BLUE}📦 Building @datalayer/jupyter-react...${NC}"
32
+ cd "$JUPYTER_UI_ROOT/packages/react"
33
+ echo -e "${YELLOW}[DEBUG] Current directory: $(pwd)${NC}"
34
+ rm -f tsconfig.tsbuildinfo
35
+ rm -rf lib
36
+ echo -e "${YELLOW}[DEBUG] Running gulp resources-to-lib...${NC}"
37
+ npx gulp resources-to-lib
38
+ echo -e "${YELLOW}[DEBUG] Running TypeScript...${NC}"
39
+ npx tsc --noEmitOnError false
40
+ TSC_EXIT=$?
41
+ echo -e "${YELLOW}[DEBUG] TypeScript exit code: $TSC_EXIT${NC}"
42
+ echo -e "${YELLOW}[DEBUG] Checking if lib exists...${NC}"
43
+ ls -la lib 2>&1 | head -5
44
+
45
+ # Verify lib was created
46
+ if [ ! -d "lib" ]; then
47
+ echo -e "${YELLOW}⚠️ lib directory was not created by TypeScript!${NC}"
48
+ exit 1
49
+ fi
50
+ echo -e "${YELLOW}[DEBUG] lib directory verified!${NC}"
51
+
52
+ # Copy react to core's node_modules for patch-package
53
+ echo -e "${BLUE}📋 Copying react to core/node_modules...${NC}"
54
+ cd "$CORE_ROOT"
55
+ # Only replace lib/ directory, preserving LICENSE, README.md, etc.
56
+ rm -rf node_modules/@datalayer/jupyter-react/lib
57
+ mkdir -p node_modules/@datalayer/jupyter-react/lib
58
+ cp -r "$JUPYTER_UI_ROOT/packages/react/lib/." node_modules/@datalayer/jupyter-react/lib/
59
+ cp "$JUPYTER_UI_ROOT/packages/react/package.json" node_modules/@datalayer/jupyter-react/
60
+
61
+ # Now build jupyter-lexical (finds react via workspace hoisting)
62
+ echo -e "${BLUE}📦 Building @datalayer/jupyter-lexical...${NC}"
63
+ cd "$JUPYTER_UI_ROOT/packages/lexical"
64
+ rm -f tsconfig.tsbuildinfo
65
+ rm -rf lib
66
+ echo -e "${YELLOW}[DEBUG] Running gulp resources-to-lib...${NC}"
67
+ npx gulp resources-to-lib
68
+ echo -e "${YELLOW}[DEBUG] Running TypeScript...${NC}"
69
+ npx tsc --noEmitOnError false
70
+
71
+ # Copy lexical to node_modules
72
+ echo -e "${BLUE}📋 Copying lexical to node_modules...${NC}"
73
+ cd "$CORE_ROOT"
74
+ # Only replace lib/ directory, preserving LICENSE, README.md, etc.
75
+ rm -rf node_modules/@datalayer/jupyter-lexical/lib
76
+ mkdir -p node_modules/@datalayer/jupyter-lexical/lib
77
+ cp -r "$JUPYTER_UI_ROOT/packages/lexical/lib/." node_modules/@datalayer/jupyter-lexical/lib/
78
+ cp "$JUPYTER_UI_ROOT/packages/lexical/package.json" node_modules/@datalayer/jupyter-lexical/
79
+
80
+ echo -e "${GREEN}✅ Successfully synced at $(date +"%H:%M:%S")${NC}"
81
+ }
82
+
83
+ # Check if watch mode is requested
84
+ if [[ "$1" == "--watch" ]]; then
85
+ # Check if fswatch is installed
86
+ if ! command -v fswatch &> /dev/null; then
87
+ echo -e "${YELLOW}⚠️ fswatch not found. Installing via Homebrew...${NC}"
88
+ if command -v brew &> /dev/null; then
89
+ brew install fswatch
90
+ else
91
+ echo -e "${YELLOW}⚠️ Homebrew not found. Please install fswatch manually:${NC}"
92
+ echo -e "${YELLOW} brew install fswatch${NC}"
93
+ echo -e "${YELLOW} or visit: https://github.com/emcrisostomo/fswatch${NC}"
94
+ exit 1
95
+ fi
96
+ fi
97
+
98
+ echo -e "${BLUE}👁️ Watch mode enabled. Monitoring jupyter-ui packages for changes...${NC}"
99
+ echo -e "${YELLOW}📁 Watching:${NC}"
100
+ echo -e "${YELLOW} - $JUPYTER_UI_ROOT/packages/lexical/src${NC}"
101
+ echo -e "${YELLOW} - $JUPYTER_UI_ROOT/packages/react/src${NC}"
102
+ echo -e "${YELLOW}Press Ctrl+C to stop${NC}"
103
+ echo ""
104
+
105
+ # Initial sync
106
+ sync_packages
107
+
108
+ # Watch for changes in src directories and trigger sync
109
+ # Using fswatch with:
110
+ # -r: recursive
111
+ # -e: exclude patterns (node_modules, lib, etc.)
112
+ # -l 1: latency 1 second (debounce rapid changes)
113
+ fswatch -r -l 1 \
114
+ -e ".*" -i "\\.tsx?$" -i "\\.jsx?$" -i "\\.css$" \
115
+ "$JUPYTER_UI_ROOT/packages/lexical/src" \
116
+ "$JUPYTER_UI_ROOT/packages/react/src" | while read -r file; do
117
+ echo -e "\n${YELLOW}📝 Change detected in: $(basename "$file")${NC}"
118
+ sync_packages
119
+ done
120
+ else
121
+ # Single run mode
122
+ sync_packages
123
+ fi