@archetypeai/ds-cli 0.3.7 → 0.3.10

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 (28) hide show
  1. package/README.md +25 -67
  2. package/commands/create.js +5 -27
  3. package/commands/init.js +5 -27
  4. package/files/AGENTS.md +19 -3
  5. package/files/CLAUDE.md +21 -3
  6. package/files/rules/accessibility.md +49 -0
  7. package/files/rules/frontend-architecture.md +77 -0
  8. package/files/skills/apply-ds/SKILL.md +92 -80
  9. package/files/skills/apply-ds/scripts/audit.sh +169 -0
  10. package/files/skills/apply-ds/scripts/setup.sh +48 -166
  11. package/files/skills/create-dashboard/SKILL.md +12 -0
  12. package/files/skills/embedding-from-file/SKILL.md +415 -0
  13. package/files/skills/embedding-from-sensor/SKILL.md +406 -0
  14. package/files/skills/embedding-upload/SKILL.md +414 -0
  15. package/files/skills/fix-accessibility/SKILL.md +57 -9
  16. package/files/skills/newton-activity-monitor-lens-on-video/SKILL.md +817 -0
  17. package/files/skills/newton-camera-frame-analysis/SKILL.md +611 -0
  18. package/files/skills/newton-camera-frame-analysis/scripts/activity-monitor-frame.py +165 -0
  19. package/files/skills/newton-camera-frame-analysis/scripts/captures/logs/api_responses_20260206_105610.json +62 -0
  20. package/files/skills/newton-camera-frame-analysis/scripts/continuous_monitor.py +119 -0
  21. package/files/skills/newton-direct-query/SKILL.md +212 -0
  22. package/files/skills/newton-direct-query/scripts/direct_query.py +129 -0
  23. package/files/skills/newton-machine-state-from-file/SKILL.md +545 -0
  24. package/files/skills/newton-machine-state-from-sensor/SKILL.md +707 -0
  25. package/files/skills/newton-machine-state-upload/SKILL.md +986 -0
  26. package/lib/add-ds-ui-svelte.js +5 -2
  27. package/lib/scaffold-ds-svelte-project.js +25 -18
  28. package/package.json +13 -2
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simplified webcam capture and analysis using ArchetypeAI Newton model
4
+ """
5
+ import cv2
6
+ import base64
7
+ import os
8
+ import sys
9
+ import json
10
+ import time
11
+ from datetime import datetime
12
+ from pathlib import Path
13
+ from archetypeai.api_client import ArchetypeAI
14
+ from archetypeai.utils import base64_encode
15
+
16
+ # Model configuration - defined once and reused
17
+ MODEL_CONFIG = {
18
+ "model_version": "Newton::c2_4_7b_251215a172f6d7",
19
+ "template_name": "image_qa_template_task",
20
+ "instruction": "Answer the following question about the image:",
21
+ "max_new_tokens": 512
22
+ }
23
+
24
+ def capture_webcam_image(camera_index=0, output_dir="captures"):
25
+ """Capture image from webcam and save it"""
26
+ Path(output_dir).mkdir(exist_ok=True)
27
+
28
+ cap = cv2.VideoCapture(camera_index)
29
+ ret, frame = cap.read()
30
+ cap.release()
31
+
32
+ if not ret:
33
+ raise Exception("Failed to capture image from webcam")
34
+
35
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
36
+ filename = f"{output_dir}/webcam_{timestamp}.jpg"
37
+ cv2.imwrite(filename, frame)
38
+ print(f"šŸ“ø Captured: {filename}")
39
+ return filename
40
+
41
+ def analyze_webcam_image(api_key, image_path, question="Describe what you see"):
42
+ """Analyze captured image using Newton model"""
43
+
44
+ client = ArchetypeAI(api_key)
45
+
46
+ # Lens configuration with model parameters
47
+ lens_config = {
48
+ "lens_name": f"webcam-analysis-{int(time.time())}",
49
+ "lens_config": {
50
+ "model_pipeline": [{
51
+ "processor_name": "lens_camera_processor",
52
+ "processor_config": {}
53
+ }],
54
+ "model_parameters": {
55
+ **MODEL_CONFIG,
56
+ "focus": question,
57
+ "camera_buffer_size": 1,
58
+ "min_replicas": 1,
59
+ "max_replicas": 1
60
+ }
61
+ }
62
+ }
63
+
64
+ lens_id = None
65
+ session_id = None
66
+
67
+ try:
68
+ # 1. Register lens
69
+ print("šŸ”§ Setting up analysis...")
70
+ lens = client.lens.register(lens_config)
71
+ lens_id = lens['lens_id']
72
+
73
+ # 2. Create session
74
+ session = client.lens.sessions.create(lens_id)
75
+ session_id = session['session_id']
76
+
77
+ # 3. Wait for session ready
78
+ print("ā³ Initializing...")
79
+ for _ in range(30):
80
+ try:
81
+ status = client.lens.sessions.process_event(
82
+ session_id, {"type": "session.status"}
83
+ )
84
+ if status.get('session_status') in ['3', 'LensSessionStatus.SESSION_STATUS_RUNNING']:
85
+ break
86
+ except:
87
+ pass
88
+ time.sleep(0.5)
89
+
90
+ # 4. Initialize processor
91
+ client.lens.sessions.process_event(session_id, {
92
+ "type": "session.modify",
93
+ "event_data": {"camera_buffer_size": 1}
94
+ })
95
+
96
+ # 5. Prepare image
97
+ base64_img = base64_encode(image_path).replace("data:image/jpeg;base64,", "")
98
+
99
+ # 6. Query with image
100
+ print("šŸ” Analyzing image...")
101
+ event = {
102
+ "type": "model.query",
103
+ "event_data": {
104
+ **MODEL_CONFIG,
105
+ "focus": question,
106
+ "data": [{
107
+ "type": "base64_img",
108
+ "base64_img": base64_img
109
+ }]
110
+ }
111
+ }
112
+
113
+ response = client.lens.sessions.process_event(session_id, event)
114
+
115
+ # 7. Extract result
116
+ if response.get('type') == 'model.query.response':
117
+ result = response.get('event_data', {}).get('response', '')
118
+ if isinstance(result, list):
119
+ result = result[0] if result else "No response"
120
+ print(f"\nšŸ’­ Answer: {result}")
121
+ return result
122
+ else:
123
+ print(f"Unexpected response: {json.dumps(response, indent=2)}")
124
+ return None
125
+
126
+ finally:
127
+ # Cleanup
128
+ if session_id:
129
+ try:
130
+ client.lens.sessions.destroy(session_id)
131
+ except:
132
+ pass
133
+ if lens_id:
134
+ try:
135
+ client.lens.delete(lens_id)
136
+ except:
137
+ pass
138
+
139
+ def main():
140
+ # Get API key
141
+ api_key = os.environ.get("ARCHETYPE_API_KEY") or os.environ.get("ATAI_API_KEY")
142
+
143
+ if not api_key:
144
+ print("Error: Please set ARCHETYPE_API_KEY or ATAI_API_KEY environment variable")
145
+ sys.exit(1)
146
+
147
+ # Parse arguments
148
+ question = sys.argv[1] if len(sys.argv) > 1 else "Describe what you see"
149
+ camera_index = int(sys.argv[2]) if len(sys.argv) > 2 else 0
150
+
151
+ print(f"šŸ“· Camera: {camera_index}")
152
+ print(f"ā“ Question: {question}")
153
+ print("-" * 40)
154
+
155
+ try:
156
+ # Capture and analyze
157
+ image_path = capture_webcam_image(camera_index)
158
+ analyze_webcam_image(api_key, image_path, question)
159
+
160
+ except Exception as e:
161
+ print(f"āŒ Error: {e}")
162
+ sys.exit(1)
163
+
164
+ if __name__ == "__main__":
165
+ main()
@@ -0,0 +1,62 @@
1
+ [
2
+ {
3
+ "timestamp": "2026-02-06T10:57:17.747432",
4
+ "frame_number": 1,
5
+ "response_time_seconds": 63.071,
6
+ "request": {
7
+ "type": "model.query",
8
+ "event_data": {
9
+ "model_version": "Newton::c2_3_7b_2508014e10af56",
10
+ "template_name": "image_qa_template_task",
11
+ "instruction": "Answer the following question about the image:",
12
+ "focus": "webcam_frame.py",
13
+ "max_new_tokens": 512,
14
+ "data": "[IMAGE DATA OMITTED]"
15
+ }
16
+ },
17
+ "response": {
18
+ "type": "model.query.response",
19
+ "message": "Response timed out for query"
20
+ }
21
+ },
22
+ {
23
+ "timestamp": "2026-02-06T10:57:26.154989",
24
+ "frame_number": 2,
25
+ "response_time_seconds": 1.968,
26
+ "request": {
27
+ "type": "model.query",
28
+ "event_data": {
29
+ "model_version": "Newton::c2_3_7b_2508014e10af56",
30
+ "template_name": "image_qa_template_task",
31
+ "instruction": "Answer the following question about the image:",
32
+ "focus": "webcam_frame.py",
33
+ "max_new_tokens": 512,
34
+ "data": "[IMAGE DATA OMITTED]"
35
+ }
36
+ },
37
+ "response": {
38
+ "type": "error",
39
+ "message": "Unknown session id: lsn-26020627e21501c0bdb5a9082b8cdd"
40
+ }
41
+ },
42
+ {
43
+ "timestamp": "2026-02-06T10:57:42.701721",
44
+ "frame_number": 3,
45
+ "response_time_seconds": 10.079,
46
+ "request": {
47
+ "type": "model.query",
48
+ "event_data": {
49
+ "model_version": "Newton::c2_3_7b_2508014e10af56",
50
+ "template_name": "image_qa_template_task",
51
+ "instruction": "Answer the following question about the image:",
52
+ "focus": "webcam_frame.py",
53
+ "max_new_tokens": 512,
54
+ "data": "[IMAGE DATA OMITTED]"
55
+ }
56
+ },
57
+ "response": {
58
+ "type": "error",
59
+ "message": "Unknown session id: lsn-26020627e21501c0bdb5a9082b8cdd"
60
+ }
61
+ }
62
+ ]
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env python3
2
+ """Continuous monitoring script that captures and analyzes frames every 5 seconds."""
3
+
4
+ import sys
5
+ import os
6
+ import time
7
+ import signal
8
+ import argparse
9
+ from datetime import datetime
10
+ from pathlib import Path
11
+
12
+ sys.path.append('skills/activity-monitor-frame-query/scripts')
13
+ from webcam_analyze import capture_webcam_image, analyze_image
14
+
15
+ class ContinuousMonitor:
16
+ def __init__(self, camera_index=0, output_dir="captures", interval=5, focus="Describe what you see"):
17
+ self.camera_index = camera_index
18
+ self.output_dir = output_dir
19
+ self.interval = interval
20
+ self.focus = focus
21
+ self.running = True
22
+ self.frame_count = 0
23
+
24
+ signal.signal(signal.SIGINT, self.signal_handler)
25
+ signal.signal(signal.SIGTERM, self.signal_handler)
26
+
27
+ Path(output_dir).mkdir(exist_ok=True)
28
+
29
+ self.api_key = os.environ.get("ATAI_API_KEY")
30
+ if not self.api_key:
31
+ raise RuntimeError("ATAI_API_KEY environment variable not set")
32
+
33
+ def signal_handler(self, signum, frame):
34
+ print("\n\nStopping continuous monitoring...")
35
+ self.running = False
36
+
37
+ def run(self):
38
+ """Run continuous monitoring loop."""
39
+ print(f"Starting continuous monitoring (Ctrl+C to stop)")
40
+ print(f"Camera: {self.camera_index}, Interval: {self.interval}s")
41
+ print(f"Output directory: {self.output_dir}")
42
+ print(f"Analysis focus: {self.focus}")
43
+ print("-" * 60)
44
+
45
+ while self.running:
46
+ try:
47
+ self.frame_count += 1
48
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
49
+ print(f"\n[Frame {self.frame_count}] {timestamp}")
50
+
51
+ image_path = capture_webcam_image(self.camera_index, self.output_dir)
52
+
53
+ analyze_image(self.api_key, image_path, self.focus)
54
+
55
+ if self.running:
56
+ print(f"Waiting {self.interval} seconds...")
57
+ time.sleep(self.interval)
58
+
59
+ except KeyboardInterrupt:
60
+ self.running = False
61
+ break
62
+ except Exception as e:
63
+ print(f"Error during capture/analysis: {e}")
64
+ if self.running:
65
+ print(f"Retrying in {self.interval} seconds...")
66
+ time.sleep(self.interval)
67
+
68
+ print(f"\nMonitoring complete. Captured {self.frame_count} frames.")
69
+ print(f"Images saved in: {self.output_dir}/")
70
+
71
+
72
+ def main():
73
+ parser = argparse.ArgumentParser(
74
+ description="Continuously capture and analyze webcam frames at regular intervals"
75
+ )
76
+ parser.add_argument(
77
+ "focus",
78
+ nargs="?",
79
+ default="Describe what you see and any changes from the previous frame",
80
+ help="Question or focus for analysis (default: describe changes)"
81
+ )
82
+ parser.add_argument(
83
+ "--camera", "-c",
84
+ type=int,
85
+ default=0,
86
+ help="Camera index (0 for built-in, 1+ for external)"
87
+ )
88
+ parser.add_argument(
89
+ "--interval", "-i",
90
+ type=float,
91
+ default=5.0,
92
+ help="Capture interval in seconds (default: 5)"
93
+ )
94
+ parser.add_argument(
95
+ "--output-dir", "-o",
96
+ default="captures",
97
+ help="Directory for saved captures (default: captures)"
98
+ )
99
+
100
+ args = parser.parse_args()
101
+
102
+ monitor = ContinuousMonitor(
103
+ camera_index=args.camera,
104
+ output_dir=args.output_dir,
105
+ interval=args.interval,
106
+ focus=args.focus
107
+ )
108
+
109
+ try:
110
+ monitor.run()
111
+ except Exception as e:
112
+ print(f"Fatal error: {e}")
113
+ return 1
114
+
115
+ return 0
116
+
117
+
118
+ if __name__ == "__main__":
119
+ exit(main())
@@ -0,0 +1,212 @@
1
+ ---
2
+ name: newton-direct-query
3
+ description: Simple direct query to Newton model using the /query API endpoint. Test API connectivity, run text queries, or post-process results from other lenses. No lens registration or session needed.
4
+ argument-hint: [query]
5
+ allowed-tools: Bash(python *), Read
6
+ ---
7
+
8
+ # Newton Direct Query (Newton /query endpoint)
9
+
10
+ Send a text query directly to Newton via `POST /v0.5/query`. No lens registration, no session, no SSE — just a simple request/response. Use for API testing, text Q&A, or post-processing results from other lenses.
11
+
12
+ ---
13
+
14
+ ## API Endpoint
15
+
16
+ ```
17
+ POST https://api.u1.archetypeai.app/v0.5/query
18
+ Authorization: Bearer {apiKey}
19
+ Content-Type: application/json
20
+ ```
21
+
22
+ ## Request Body
23
+
24
+ ```json
25
+ {
26
+ "query": "Your question or prompt here",
27
+ "system_prompt": "System-level instruction",
28
+ "instruction_prompt": "System-level instruction",
29
+ "file_ids": [],
30
+ "model": "Newton::c2_4_7b_251215a172f6d7",
31
+ "max_new_tokens": 1024,
32
+ "sanitize": false
33
+ }
34
+ ```
35
+
36
+ | Field | Type | Description |
37
+ |---|---|---|
38
+ | `query` | string | The user prompt / question (required) |
39
+ | `system_prompt` | string | System-level instruction guiding the model |
40
+ | `instruction_prompt` | string | Same as `system_prompt` — set both to the same value |
41
+ | `file_ids` | string[] | File IDs to include as context (empty for text-only) |
42
+ | `model` | string | Model ID (default: `Newton::c2_4_7b_251215a172f6d7`) |
43
+ | `max_new_tokens` | number | Max response length (default: 1024) |
44
+ | `sanitize` | boolean | Whether to sanitize input (default: false) |
45
+
46
+ **IMPORTANT:** The body uses `model` (not `model_version`) and `system_prompt` + `instruction_prompt` (not `instruction`). Both `system_prompt` and `instruction_prompt` should be set to the same value.
47
+
48
+ ## Response Structure
49
+
50
+ ```json
51
+ {
52
+ "response": {
53
+ "response": ["The model's answer text here"]
54
+ }
55
+ }
56
+ ```
57
+
58
+ Extract the text using this priority chain:
59
+ 1. `data.response.response[0]` (most common)
60
+ 2. `data.response[0]` (fallback)
61
+ 3. `data.response` as string (fallback)
62
+ 4. `data.text` (fallback)
63
+
64
+ ---
65
+
66
+ ## Web / JavaScript Implementation
67
+
68
+ Uses a config object pattern with `systemPrompt` (optional, defaults to `''`) and `fileIds` (optional, defaults to `[]`). Timeout is 120s since Newton queries can be slow for long prompts.
69
+
70
+ ```javascript
71
+ /**
72
+ * @param {Object} config
73
+ * @param {string} config.apiKey
74
+ * @param {string} config.query - The user prompt to send
75
+ * @param {string} [config.systemPrompt=''] - Optional system/instruction prompt
76
+ * @param {string[]} [config.fileIds=[]] - Optional file IDs to include as context
77
+ * @param {number} [config.maxNewTokens=1024]
78
+ * @returns {Promise<string>} The model's text response
79
+ */
80
+ async function runDirectQuery(config) {
81
+ const { apiKey, query, systemPrompt = '', fileIds = [], maxNewTokens = 1024 } = config
82
+
83
+ const response = await fetch('https://api.u1.archetypeai.app/v0.5/query', {
84
+ method: 'POST',
85
+ headers: {
86
+ Authorization: `Bearer ${apiKey}`,
87
+ 'Content-Type': 'application/json',
88
+ },
89
+ body: JSON.stringify({
90
+ query,
91
+ system_prompt: systemPrompt,
92
+ instruction_prompt: systemPrompt,
93
+ file_ids: fileIds,
94
+ model: 'Newton::c2_4_7b_251215a172f6d7',
95
+ max_new_tokens: maxNewTokens,
96
+ sanitize: false,
97
+ }),
98
+ signal: AbortSignal.timeout(120000),
99
+ })
100
+
101
+ if (!response.ok) {
102
+ const errorBody = await response.json().catch(() => ({}))
103
+ throw new Error(`Query failed: ${response.status} - ${JSON.stringify(errorBody)}`)
104
+ }
105
+
106
+ const data = await response.json()
107
+
108
+ // Extract response text — nested response.response[0] is most common
109
+ if (data.response?.response && Array.isArray(data.response.response)) {
110
+ return data.response.response[0] || ''
111
+ }
112
+ if (data.response && Array.isArray(data.response)) {
113
+ return data.response[0] || ''
114
+ }
115
+ if (data.response && typeof data.response === 'string') {
116
+ return data.response
117
+ }
118
+ if (data.text) {
119
+ return data.text
120
+ }
121
+
122
+ return JSON.stringify(data)
123
+ }
124
+
125
+ // Usage
126
+ const answer = await runDirectQuery({
127
+ apiKey,
128
+ query: 'What is the capital of France?',
129
+ systemPrompt: 'Answer the question concisely.',
130
+ })
131
+ console.log(answer) // "Paris"
132
+
133
+ // With file context
134
+ const summary = await runDirectQuery({
135
+ apiKey,
136
+ query: 'Summarize the sensor data patterns.',
137
+ systemPrompt: 'You are a sensor data analyst.',
138
+ fileIds: ['file-abc123'],
139
+ })
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Python Implementation
145
+
146
+ ```python
147
+ import os
148
+ import requests
149
+
150
+ API_URL = "https://api.u1.archetypeai.app/v0.5/query"
151
+
152
+ def query_newton(query: str, system_prompt: str, api_key: str, max_new_tokens: int = 1024) -> str:
153
+ """Send a direct text query to Newton."""
154
+ response = requests.post(
155
+ API_URL,
156
+ headers={
157
+ "Authorization": f"Bearer {api_key}",
158
+ "Content-Type": "application/json",
159
+ },
160
+ json={
161
+ "query": query,
162
+ "system_prompt": system_prompt,
163
+ "instruction_prompt": system_prompt,
164
+ "file_ids": [],
165
+ "model": "Newton::c2_4_7b_251215a172f6d7",
166
+ "max_new_tokens": max_new_tokens,
167
+ "sanitize": False,
168
+ },
169
+ timeout=60,
170
+ )
171
+ response.raise_for_status()
172
+ data = response.json()
173
+
174
+ # Extract response text (multiple possible shapes)
175
+ resp = data.get("response")
176
+ if isinstance(resp, dict) and isinstance(resp.get("response"), list):
177
+ return resp["response"][0] or ""
178
+ if isinstance(resp, list):
179
+ return resp[0] or ""
180
+ if isinstance(resp, str):
181
+ return resp
182
+ if data.get("text"):
183
+ return data["text"]
184
+
185
+ return str(data)
186
+
187
+
188
+ # Usage
189
+ api_key = os.getenv("ATAI_API_KEY") or os.getenv("ARCHETYPE_API_KEY")
190
+ answer = query_newton(
191
+ "What is the capital of France?",
192
+ "Answer the question concisely.",
193
+ api_key,
194
+ )
195
+ print(answer) # "Paris"
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Use Cases
201
+
202
+ - **API connectivity testing**: Verify your API key works
203
+ - **Quick text Q&A**: Get answers without lens/session setup
204
+ - **Post-processing**: Send results from other lenses (activity monitor, machine state) to Newton for summarization or comparison
205
+ - **Debugging**: Verify the `/query` endpoint behavior
206
+
207
+ ## Troubleshooting
208
+
209
+ - **"Failed to fetch"**: Check the request body format — use `model` (not `model_version`), `system_prompt` + `instruction_prompt` (not `instruction`), and `query` (not `focus`)
210
+ - **Empty response**: Check the response extraction chain — the text is typically in `data.response.response[0]`
211
+ - **Authentication error**: Verify API key is correct and has the `Bearer ` prefix
212
+ - **Timeout**: Newton queries can take 10-30s for long prompts; use a 60s timeout
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple direct query to Newton model using the /query API endpoint
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+
10
+ # Install requests if not available
11
+ try:
12
+ import requests
13
+ except ImportError:
14
+ print("Installing requests library...")
15
+ import subprocess
16
+ subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
17
+ import requests
18
+
19
+
20
+ def query_archetype_ai(
21
+ api_key: str,
22
+ system_prompt: str = "Answer the question",
23
+ user_prompt: str = "What's the capital of France?",
24
+ api_endpoint: str = "https://api.u1.archetypeai.app/v0.5"
25
+ ) -> dict:
26
+ """
27
+ Query ArchetypeAI Newton model
28
+
29
+ Args:
30
+ api_key: Your ArchetypeAI API key
31
+ system_prompt: The system instruction (default: "Answer the question")
32
+ user_prompt: The user query (default: "What's the capital of France?")
33
+ api_endpoint: API endpoint URL
34
+
35
+ Returns:
36
+ Dictionary with the API response
37
+ """
38
+
39
+ # Exact API URL
40
+ api_url = f"{api_endpoint}/query"
41
+
42
+ # Request payload
43
+ request_data = {
44
+ "query": user_prompt,
45
+ "system_prompt": system_prompt,
46
+ "instruction_prompt": system_prompt,
47
+ "file_ids": [],
48
+ "model": "Newton::c2_4_7b_251215a172f6d7",
49
+ "max_new_tokens": 1024,
50
+ "sanitize": False
51
+ }
52
+
53
+ headers = {
54
+ "Authorization": f"Bearer {api_key}",
55
+ "Content-Type": "application/json"
56
+ }
57
+
58
+ try:
59
+ response = requests.post(api_url, headers=headers, json=request_data, timeout=30)
60
+ response.raise_for_status()
61
+
62
+ data = response.json()
63
+
64
+ # Extract response text
65
+ response_text = ''
66
+ if data.get('response') and data['response'].get('response') and isinstance(data['response']['response'], list):
67
+ response_text = data['response']['response'][0] or ''
68
+ elif data.get('response') and isinstance(data.get('response'), list):
69
+ response_text = data['response'][0] or ''
70
+ elif data.get('response') and isinstance(data.get('response'), str):
71
+ response_text = data['response']
72
+ elif data.get('text'):
73
+ response_text = data['text']
74
+
75
+ return {
76
+ "success": True,
77
+ "response": response_text,
78
+ "full_response": data
79
+ }
80
+
81
+ except requests.exceptions.RequestException as e:
82
+ return {
83
+ "success": False,
84
+ "error": str(e),
85
+ "response": None
86
+ }
87
+
88
+
89
+ def main():
90
+ """Main function to run the query"""
91
+
92
+ # Get API key from environment
93
+ api_key = os.environ.get("ARCHETYPE_API_KEY") or os.environ.get("ATAI_API_KEY")
94
+
95
+ # Allow API key as first argument
96
+ if not api_key and len(sys.argv) > 1:
97
+ api_key = sys.argv[1]
98
+
99
+ if not api_key:
100
+ print("Error: Please provide API key either as:")
101
+ print(" 1. Environment variable: export ARCHETYPE_API_KEY=your_key")
102
+ print(" 2. Command line argument: python direct_query.py your_key")
103
+ sys.exit(1)
104
+
105
+ print("=" * 60)
106
+ print("ArchetypeAI Direct Query Test")
107
+ print("=" * 60)
108
+
109
+ system_prompt = "Answer the question"
110
+ user_prompt = "What's the capital of France?"
111
+
112
+ print(f"System Prompt: {system_prompt}")
113
+ print(f"User Prompt: {user_prompt}")
114
+ print("-" * 40)
115
+
116
+ result = query_archetype_ai(api_key, system_prompt, user_prompt)
117
+
118
+ if result["success"]:
119
+ print(f"Response: {result['response']}")
120
+ print("\nāœ“ API connection successful!")
121
+ else:
122
+ print(f"Error: {result['error']}")
123
+ print("\nāœ— API connection failed!")
124
+
125
+ return 0 if result["success"] else 1
126
+
127
+
128
+ if __name__ == "__main__":
129
+ sys.exit(main())