oagi-core 0.10.1__py3-none-any.whl → 0.10.3__py3-none-any.whl

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.
@@ -0,0 +1,455 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Agent Execution Report</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ max-width: 1200px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ background: #f5f5f5;
14
+ }
15
+
16
+ h1 {
17
+ color: #333;
18
+ border-bottom: 2px solid #007bff;
19
+ padding-bottom: 10px;
20
+ }
21
+
22
+ .step, .plan {
23
+ background: white;
24
+ border-radius: 8px;
25
+ padding: 20px;
26
+ margin: 20px 0;
27
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
28
+ }
29
+
30
+ .step h2 {
31
+ margin-top: 0;
32
+ color: #007bff;
33
+ }
34
+
35
+ .plan {
36
+ background: #e7f3ff;
37
+ }
38
+
39
+ .plan h3 {
40
+ margin-top: 0;
41
+ color: #0056b3;
42
+ }
43
+
44
+ .timestamp {
45
+ color: #666;
46
+ font-size: 0.9em;
47
+ }
48
+
49
+ .screenshot-container {
50
+ position: relative;
51
+ display: inline-block;
52
+ margin: 10px 0;
53
+ }
54
+
55
+ .screenshot {
56
+ max-width: 100%;
57
+ border: 1px solid #ddd;
58
+ border-radius: 4px;
59
+ display: block;
60
+ }
61
+
62
+ .reasoning {
63
+ background: #f8f9fa;
64
+ padding: 10px;
65
+ border-left: 3px solid #007bff;
66
+ margin: 10px 0;
67
+ white-space: pre-wrap;
68
+ }
69
+
70
+ .actions {
71
+ margin: 10px 0;
72
+ }
73
+
74
+ .actions ul {
75
+ margin: 5px 0;
76
+ padding-left: 20px;
77
+ }
78
+
79
+ .actions code {
80
+ background: #e9ecef;
81
+ padding: 2px 6px;
82
+ border-radius: 3px;
83
+ }
84
+
85
+ .complete {
86
+ background: #d4edda;
87
+ color: #155724;
88
+ padding: 10px;
89
+ border-radius: 4px;
90
+ margin-top: 10px;
91
+ }
92
+
93
+ .action-result {
94
+ padding: 10px;
95
+ margin: 5px 0;
96
+ }
97
+
98
+ .success {
99
+ color: #155724;
100
+ }
101
+
102
+ .error {
103
+ color: #721c24;
104
+ background: #f8d7da;
105
+ padding: 10px;
106
+ border-radius: 4px;
107
+ }
108
+
109
+ .log {
110
+ background: #fff3cd;
111
+ padding: 10px;
112
+ margin: 10px 0;
113
+ border-radius: 4px;
114
+ }
115
+
116
+ .split {
117
+ text-align: center;
118
+ margin: 30px 0;
119
+ }
120
+
121
+ .split h3 {
122
+ color: #666;
123
+ }
124
+
125
+ .split-line {
126
+ border: none;
127
+ border-top: 2px dashed #ccc;
128
+ margin: 30px 0;
129
+ }
130
+
131
+ .url {
132
+ word-break: break-all;
133
+ }
134
+
135
+ .plan-result {
136
+ background: #d1ecf1;
137
+ color: #0c5460;
138
+ padding: 10px;
139
+ border-radius: 4px;
140
+ margin-top: 10px;
141
+ }
142
+
143
+ /* Cursor indicators */
144
+ .click-indicator {
145
+ position: absolute;
146
+ width: 20px;
147
+ height: 20px;
148
+ border-radius: 50%;
149
+ background: rgba(255, 0, 0, 0.8);
150
+ border: 2px solid #fff;
151
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.6);
152
+ transform: translate(-50%, -50%);
153
+ pointer-events: none;
154
+ z-index: 10;
155
+ }
156
+
157
+ .drag-indicator {
158
+ position: absolute;
159
+ width: 20px;
160
+ height: 20px;
161
+ border-radius: 50%;
162
+ border: 2px solid #fff;
163
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
164
+ transform: translate(-50%, -50%);
165
+ pointer-events: none;
166
+ z-index: 10;
167
+ }
168
+
169
+ .drag-start {
170
+ background: rgba(0, 255, 0, 0.8);
171
+ box-shadow: 0 0 10px rgba(0, 255, 0, 0.6);
172
+ }
173
+
174
+ .drag-end {
175
+ background: rgba(255, 0, 0, 0.8);
176
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.6);
177
+ }
178
+
179
+ .drag-line {
180
+ position: absolute;
181
+ background: rgba(255, 255, 0, 0.8);
182
+ height: 3px;
183
+ border-radius: 2px;
184
+ box-shadow: 0 0 5px rgba(255, 255, 0, 0.4);
185
+ pointer-events: none;
186
+ z-index: 9;
187
+ transform-origin: left center;
188
+ }
189
+
190
+ .scroll-indicator {
191
+ position: absolute;
192
+ width: 40px;
193
+ height: 40px;
194
+ border-radius: 50%;
195
+ background: rgba(138, 43, 226, 0.9);
196
+ border: 2px solid #fff;
197
+ box-shadow: 0 0 15px rgba(138, 43, 226, 0.6);
198
+ transform: translate(-50%, -50%);
199
+ pointer-events: none;
200
+ z-index: 10;
201
+ display: flex;
202
+ align-items: center;
203
+ justify-content: center;
204
+ font-size: 20px;
205
+ color: white;
206
+ font-weight: bold;
207
+ }
208
+ </style>
209
+ </head>
210
+ <body>
211
+ <h1>Agent Execution Report</h1>
212
+ <div id="content"></div>
213
+
214
+ <script>
215
+ const eventsData = {EVENTS_DATA};
216
+
217
+ function escapeHtml(text) {
218
+ const div = document.createElement('div');
219
+ div.textContent = text;
220
+ return div.innerHTML;
221
+ }
222
+
223
+ function removeIndicators(container) {
224
+ container.querySelectorAll('.click-indicator, .drag-indicator, .drag-line, .scroll-indicator')
225
+ .forEach(el => el.remove());
226
+ }
227
+
228
+ function addIndicators(container) {
229
+ const img = container.querySelector('.screenshot');
230
+ const actionsAttr = container.getAttribute('data-actions');
231
+ if (!actionsAttr || !img) return;
232
+
233
+ // Remove existing indicators before adding new ones
234
+ removeIndicators(container);
235
+
236
+ const actions = JSON.parse(actionsAttr);
237
+ const imgWidth = img.offsetWidth;
238
+ const imgHeight = img.offsetHeight;
239
+
240
+ actions.forEach(action => {
241
+ switch (action.type) {
242
+ case 'click':
243
+ addClickIndicator(container, action, imgWidth, imgHeight);
244
+ break;
245
+ case 'drag':
246
+ addDragIndicator(container, action, imgWidth, imgHeight);
247
+ break;
248
+ case 'scroll':
249
+ addScrollIndicator(container, action, imgWidth, imgHeight);
250
+ break;
251
+ }
252
+ });
253
+ }
254
+
255
+ // Recalculate indicator positions on window resize
256
+ let resizeTimeout;
257
+ window.addEventListener('resize', function () {
258
+ clearTimeout(resizeTimeout);
259
+ resizeTimeout = setTimeout(function () {
260
+ document.querySelectorAll('.screenshot-container').forEach(container => {
261
+ addIndicators(container);
262
+ });
263
+ }, 100);
264
+ });
265
+
266
+ function addClickIndicator(container, action, imgWidth, imgHeight) {
267
+ const x = (action.x / 1000) * imgWidth;
268
+ const y = (action.y / 1000) * imgHeight;
269
+
270
+ const indicator = document.createElement('div');
271
+ indicator.className = 'click-indicator';
272
+ indicator.style.left = x + 'px';
273
+ indicator.style.top = y + 'px';
274
+ container.appendChild(indicator);
275
+ }
276
+
277
+ function addDragIndicator(container, action, imgWidth, imgHeight) {
278
+ const x1 = (action.x1 / 1000) * imgWidth;
279
+ const y1 = (action.y1 / 1000) * imgHeight;
280
+ const x2 = (action.x2 / 1000) * imgWidth;
281
+ const y2 = (action.y2 / 1000) * imgHeight;
282
+
283
+ const startIndicator = document.createElement('div');
284
+ startIndicator.className = 'drag-indicator drag-start';
285
+ startIndicator.style.left = x1 + 'px';
286
+ startIndicator.style.top = y1 + 'px';
287
+ container.appendChild(startIndicator);
288
+
289
+ const endIndicator = document.createElement('div');
290
+ endIndicator.className = 'drag-indicator drag-end';
291
+ endIndicator.style.left = x2 + 'px';
292
+ endIndicator.style.top = y2 + 'px';
293
+ container.appendChild(endIndicator);
294
+
295
+ const line = document.createElement('div');
296
+ line.className = 'drag-line';
297
+ const deltaX = x2 - x1;
298
+ const deltaY = y2 - y1;
299
+ const length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
300
+ const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
301
+ line.style.left = x1 + 'px';
302
+ line.style.top = y1 + 'px';
303
+ line.style.width = length + 'px';
304
+ line.style.transform = 'rotate(' + angle + 'deg)';
305
+ container.appendChild(line);
306
+ }
307
+
308
+ function addScrollIndicator(container, action, imgWidth, imgHeight) {
309
+ const x = (action.x / 1000) * imgWidth;
310
+ const y = (action.y / 1000) * imgHeight;
311
+
312
+ const indicator = document.createElement('div');
313
+ indicator.className = 'scroll-indicator';
314
+ indicator.style.left = x + 'px';
315
+ indicator.style.top = y + 'px';
316
+
317
+ if (action.direction === 'up') {
318
+ indicator.innerHTML = '&#8593;';
319
+ indicator.title = 'Scroll Up';
320
+ } else if (action.direction === 'down') {
321
+ indicator.innerHTML = '&#8595;';
322
+ indicator.title = 'Scroll Down';
323
+ } else {
324
+ indicator.innerHTML = '&#8597;';
325
+ indicator.title = 'Scroll';
326
+ }
327
+ container.appendChild(indicator);
328
+ }
329
+
330
+ function renderEvents() {
331
+ const content = document.getElementById('content');
332
+ let html = '';
333
+
334
+ eventsData.forEach(event => {
335
+ const timestamp = event.timestamp;
336
+
337
+ switch (event.event_type) {
338
+ case 'step':
339
+ html += '<div class="step">';
340
+ html += `<h2>Step ${event.step_num}</h2>`;
341
+ html += `<span class="timestamp">${timestamp}</span>`;
342
+
343
+ if (event.image) {
344
+ const actionsJson = JSON.stringify(event.action_coords || []).replace(/"/g, '&quot;');
345
+ html += `<div class="screenshot-container" data-actions="${actionsJson}">`;
346
+ if (event.image.startsWith('data:') || event.image.startsWith('http')) {
347
+ html += `<img src="${event.image}" alt="Step ${event.step_num}" class="screenshot"/>`;
348
+ } else {
349
+ html += `<img src="data:image/png;base64,${event.image}" alt="Step ${event.step_num}" class="screenshot"/>`;
350
+ }
351
+ html += '</div>';
352
+ }
353
+
354
+ if (event.reason) {
355
+ html += '<div class="reasoning">';
356
+ html += `<strong>Reasoning:</strong><p>${escapeHtml(event.reason)}</p>`;
357
+ html += '</div>';
358
+ }
359
+
360
+ if (event.actions && event.actions.length > 0) {
361
+ html += '<div class="actions"><strong>Planned Actions:</strong><ul>';
362
+ event.actions.forEach(action => {
363
+ const countStr = action.count > 1 ? ` (x${action.count})` : '';
364
+ html += `<li><code>${action.type}</code>: ${escapeHtml(action.argument)}${countStr}</li>`;
365
+ });
366
+ html += '</ul></div>';
367
+ }
368
+
369
+ if (event.stop) {
370
+ html += '<div class="complete">Task Complete</div>';
371
+ }
372
+ html += '</div>';
373
+ break;
374
+
375
+ case 'action':
376
+ html += '<div class="action-result">';
377
+ html += `<span class="timestamp">${timestamp}</span>`;
378
+ if (event.error) {
379
+ html += `<div class="error">Error: ${escapeHtml(event.error)}</div>`;
380
+ } else {
381
+ html += '<div class="success">Actions executed successfully</div>';
382
+ }
383
+ html += '</div>';
384
+ break;
385
+
386
+ case 'log':
387
+ html += '<div class="log">';
388
+ html += `<span class="timestamp">${timestamp}</span>`;
389
+ html += `<p>${escapeHtml(event.message)}</p>`;
390
+ html += '</div>';
391
+ break;
392
+
393
+ case 'split':
394
+ if (event.label) {
395
+ html += `<div class="split"><h3>${escapeHtml(event.label)}</h3></div>`;
396
+ } else {
397
+ html += '<hr class="split-line"/>';
398
+ }
399
+ break;
400
+
401
+ case 'plan':
402
+ const phaseTitles = {
403
+ 'initial': 'Initial Planning',
404
+ 'reflection': 'Reflection',
405
+ 'summary': 'Summary'
406
+ };
407
+ const phaseTitle = phaseTitles[event.phase] || event.phase;
408
+
409
+ html += '<div class="plan">';
410
+ html += `<h3>${phaseTitle}</h3>`;
411
+ html += `<span class="timestamp">${timestamp}</span>`;
412
+
413
+ if (event.image) {
414
+ html += '<div class="screenshot-container">';
415
+ if (event.image.startsWith('data:') || event.image.startsWith('http')) {
416
+ html += `<img src="${event.image}" alt="${phaseTitle}" class="screenshot"/>`;
417
+ } else {
418
+ html += `<img src="data:image/png;base64,${event.image}" alt="${phaseTitle}" class="screenshot"/>`;
419
+ }
420
+ html += '</div>';
421
+ }
422
+
423
+ if (event.reasoning) {
424
+ html += '<div class="reasoning">';
425
+ html += `<strong>Reasoning:</strong><p>${escapeHtml(event.reasoning)}</p>`;
426
+ html += '</div>';
427
+ }
428
+
429
+ if (event.result) {
430
+ html += `<div class="plan-result"><strong>Result:</strong> ${escapeHtml(event.result)}</div>`;
431
+ }
432
+ html += '</div>';
433
+ break;
434
+ }
435
+ });
436
+
437
+ content.innerHTML = html;
438
+
439
+ // Add cursor indicators after images load
440
+ document.querySelectorAll('.screenshot-container').forEach(container => {
441
+ const img = container.querySelector('.screenshot');
442
+ if (img) {
443
+ if (img.complete) {
444
+ addIndicators(container);
445
+ } else {
446
+ img.onload = () => addIndicators(container);
447
+ }
448
+ }
449
+ });
450
+ }
451
+
452
+ document.addEventListener('DOMContentLoaded', renderEvents);
453
+ </script>
454
+ </body>
455
+ </html>
@@ -10,6 +10,7 @@ import json
10
10
  from typing import Any
11
11
 
12
12
  from ...client import AsyncClient
13
+ from ...constants import DEFAULT_REFLECTION_INTERVAL
13
14
  from ...types import URL, Image
14
15
  from .memory import PlannerMemory
15
16
  from .models import Action, PlannerOutput, ReflectionOutput
@@ -175,7 +176,7 @@ class Planner:
175
176
  memory: PlannerMemory | None = None,
176
177
  todo_index: int | None = None,
177
178
  current_instruction: str | None = None,
178
- reflection_interval: int = 4,
179
+ reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
179
180
  ) -> ReflectionOutput:
180
181
  """Reflect on recent actions and progress.
181
182
 
@@ -6,11 +6,19 @@
6
6
  # Licensed under the MIT License.
7
7
  # -----------------------------------------------------------------------------
8
8
 
9
+ import asyncio
9
10
  import logging
10
11
  from datetime import datetime
11
12
  from typing import Any
12
13
 
13
14
  from oagi import AsyncActor
15
+ from oagi.constants import (
16
+ DEFAULT_MAX_STEPS,
17
+ DEFAULT_REFLECTION_INTERVAL,
18
+ DEFAULT_STEP_DELAY,
19
+ DEFAULT_TEMPERATURE,
20
+ MODEL_ACTOR,
21
+ )
14
22
  from oagi.types import (
15
23
  URL,
16
24
  ActionEvent,
@@ -51,14 +59,15 @@ class TaskeeAgent(AsyncAgent):
51
59
  self,
52
60
  api_key: str | None = None,
53
61
  base_url: str | None = None,
54
- model: str = "lux-actor-1",
55
- max_steps: int = 20,
56
- reflection_interval: int = 4,
57
- temperature: float = 0.5,
62
+ model: str = MODEL_ACTOR,
63
+ max_steps: int = DEFAULT_MAX_STEPS,
64
+ reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
65
+ temperature: float = DEFAULT_TEMPERATURE,
58
66
  planner: Planner | None = None,
59
67
  external_memory: PlannerMemory | None = None,
60
68
  todo_index: int | None = None,
61
69
  step_observer: AsyncObserver | None = None,
70
+ step_delay: float = DEFAULT_STEP_DELAY,
62
71
  ):
63
72
  """Initialize the taskee agent.
64
73
 
@@ -73,6 +82,7 @@ class TaskeeAgent(AsyncAgent):
73
82
  external_memory: External memory from parent agent
74
83
  todo_index: Index of the todo being executed
75
84
  step_observer: Optional observer for step tracking
85
+ step_delay: Delay in seconds after actions before next screenshot
76
86
  """
77
87
  self.api_key = api_key
78
88
  self.base_url = base_url
@@ -84,6 +94,7 @@ class TaskeeAgent(AsyncAgent):
84
94
  self.external_memory = external_memory
85
95
  self.todo_index = todo_index
86
96
  self.step_observer = step_observer
97
+ self.step_delay = step_delay
87
98
 
88
99
  # Internal state
89
100
  self.actor: AsyncActor | None = None
@@ -327,6 +338,10 @@ class TaskeeAgent(AsyncAgent):
327
338
  self.total_actions += len(step.actions)
328
339
  self.since_reflection += len(step.actions)
329
340
 
341
+ # Wait after actions before next screenshot
342
+ if self.step_delay > 0:
343
+ await asyncio.sleep(self.step_delay)
344
+
330
345
  steps_taken += 1
331
346
 
332
347
  # Check if task is complete
@@ -9,6 +9,13 @@
9
9
  import logging
10
10
  from typing import Any
11
11
 
12
+ from oagi.constants import (
13
+ DEFAULT_MAX_STEPS_TASKER,
14
+ DEFAULT_REFLECTION_INTERVAL,
15
+ DEFAULT_STEP_DELAY,
16
+ DEFAULT_TEMPERATURE,
17
+ MODEL_ACTOR,
18
+ )
12
19
  from oagi.types import AsyncActionHandler, AsyncImageProvider, AsyncObserver, SplitEvent
13
20
 
14
21
  from ..protocol import AsyncAgent
@@ -34,12 +41,13 @@ class TaskerAgent(AsyncAgent):
34
41
  self,
35
42
  api_key: str | None = None,
36
43
  base_url: str | None = None,
37
- model: str = "lux-actor-1",
38
- max_steps: int = 60,
39
- temperature: float = 0.5,
40
- reflection_interval: int = 4,
44
+ model: str = MODEL_ACTOR,
45
+ max_steps: int = DEFAULT_MAX_STEPS_TASKER,
46
+ temperature: float = DEFAULT_TEMPERATURE,
47
+ reflection_interval: int = DEFAULT_REFLECTION_INTERVAL,
41
48
  planner: Planner | None = None,
42
49
  step_observer: AsyncObserver | None = None,
50
+ step_delay: float = DEFAULT_STEP_DELAY,
43
51
  ):
44
52
  """Initialize the tasker agent.
45
53
 
@@ -52,6 +60,7 @@ class TaskerAgent(AsyncAgent):
52
60
  reflection_interval: Actions before reflection
53
61
  planner: Planner for planning and reflection
54
62
  step_observer: Optional observer for step tracking
63
+ step_delay: Delay in seconds after actions before next screenshot
55
64
  """
56
65
  self.api_key = api_key
57
66
  self.base_url = base_url
@@ -61,6 +70,7 @@ class TaskerAgent(AsyncAgent):
61
70
  self.reflection_interval = reflection_interval
62
71
  self.planner = planner or Planner(api_key=api_key, base_url=base_url)
63
72
  self.step_observer = step_observer
73
+ self.step_delay = step_delay
64
74
 
65
75
  # Memory for tracking workflow
66
76
  self.memory = PlannerMemory()
@@ -184,6 +194,7 @@ class TaskerAgent(AsyncAgent):
184
194
  external_memory=self.memory, # Share memory with child
185
195
  todo_index=todo_index, # Pass the todo index
186
196
  step_observer=self.step_observer, # Pass step observer
197
+ step_delay=self.step_delay,
187
198
  )
188
199
 
189
200
  self.current_todo_index = todo_index
oagi/cli/agent.py CHANGED
@@ -14,6 +14,17 @@ import time
14
14
  import traceback
15
15
 
16
16
  from oagi.agent.observer import AsyncAgentObserver
17
+ from oagi.constants import (
18
+ API_KEY_HELP_URL,
19
+ DEFAULT_BASE_URL,
20
+ DEFAULT_MAX_STEPS,
21
+ DEFAULT_MAX_STEPS_THINKER,
22
+ DEFAULT_STEP_DELAY,
23
+ DEFAULT_TEMPERATURE,
24
+ MODE_ACTOR,
25
+ MODEL_ACTOR,
26
+ MODEL_THINKER,
27
+ )
17
28
  from oagi.exceptions import check_optional_dependency
18
29
 
19
30
  from .display import display_step_table
@@ -32,7 +43,7 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
32
43
  "instruction", type=str, help="Task instruction for the agent to execute"
33
44
  )
34
45
  run_parser.add_argument(
35
- "--model", type=str, help="Model to use (default: lux-actor-1)"
46
+ "--model", type=str, help=f"Model to use (default: {MODEL_ACTOR})"
36
47
  )
37
48
  run_parser.add_argument(
38
49
  "--max-steps", type=int, help="Maximum number of steps (default: 20)"
@@ -43,8 +54,8 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
43
54
  run_parser.add_argument(
44
55
  "--mode",
45
56
  type=str,
46
- default="actor",
47
- help="Agent mode to use (default: actor). Available modes: actor, planner",
57
+ default=MODE_ACTOR,
58
+ help=f"Agent mode to use (default: {MODE_ACTOR}). Available modes: actor, planner",
48
59
  )
49
60
  run_parser.add_argument(
50
61
  "--oagi-api-key", type=str, help="OAGI API key (default: OAGI_API_KEY env var)"
@@ -52,7 +63,7 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
52
63
  run_parser.add_argument(
53
64
  "--oagi-base-url",
54
65
  type=str,
55
- help="OAGI base URL (default: https://api.agiopen.org, or OAGI_BASE_URL env var)",
66
+ help=f"OAGI base URL (default: {DEFAULT_BASE_URL}, or OAGI_BASE_URL env var)",
56
67
  )
57
68
  run_parser.add_argument(
58
69
  "--export",
@@ -65,6 +76,11 @@ def add_agent_parser(subparsers: argparse._SubParsersAction) -> None:
65
76
  type=str,
66
77
  help="Output file path for export (default: execution_report.[md|html|json])",
67
78
  )
79
+ run_parser.add_argument(
80
+ "--step-delay",
81
+ type=float,
82
+ help=f"Delay in seconds after each step before next screenshot (default: {DEFAULT_STEP_DELAY})",
83
+ )
68
84
 
69
85
  # agent permission command
70
86
  agent_subparsers.add_parser(
@@ -184,18 +200,23 @@ def run_agent(args: argparse.Namespace) -> None:
184
200
  if not api_key:
185
201
  print(
186
202
  "Error: OAGI API key not provided.\n"
187
- "Set OAGI_API_KEY environment variable or use --oagi-api-key flag.",
203
+ "Set OAGI_API_KEY environment variable or use --oagi-api-key flag.\n"
204
+ f"Get your API key at {API_KEY_HELP_URL}",
188
205
  file=sys.stderr,
189
206
  )
190
207
  sys.exit(1)
191
208
 
192
- base_url = args.oagi_base_url or os.getenv(
193
- "OAGI_BASE_URL", "https://api.agiopen.org"
209
+ base_url = args.oagi_base_url or os.getenv("OAGI_BASE_URL", DEFAULT_BASE_URL)
210
+ model = args.model or MODEL_ACTOR
211
+ default_max_steps = (
212
+ DEFAULT_MAX_STEPS_THINKER if model == MODEL_THINKER else DEFAULT_MAX_STEPS
213
+ )
214
+ max_steps = args.max_steps or default_max_steps
215
+ temperature = (
216
+ args.temperature if args.temperature is not None else DEFAULT_TEMPERATURE
194
217
  )
195
- model = args.model or "lux-actor-1"
196
- max_steps = args.max_steps or 20
197
- temperature = args.temperature if args.temperature is not None else 0.5
198
- mode = args.mode or "actor"
218
+ mode = args.mode or MODE_ACTOR
219
+ step_delay = args.step_delay if args.step_delay is not None else DEFAULT_STEP_DELAY
199
220
  export_format = args.export
200
221
  export_file = args.export_file
201
222
 
@@ -221,6 +242,7 @@ def run_agent(args: argparse.Namespace) -> None:
221
242
  max_steps=max_steps,
222
243
  temperature=temperature,
223
244
  step_observer=observer,
245
+ step_delay=step_delay,
224
246
  )
225
247
 
226
248
  # Create handlers
@@ -229,7 +251,8 @@ def run_agent(args: argparse.Namespace) -> None:
229
251
 
230
252
  print(f"Starting agent with instruction: {args.instruction}")
231
253
  print(
232
- f"Mode: {mode}, Model: {model}, Max steps: {max_steps}, Temperature: {temperature}"
254
+ f"Mode: {mode}, Model: {model}, Max steps: {max_steps}, "
255
+ f"Temperature: {temperature}, Step delay: {step_delay}s"
233
256
  )
234
257
  print("-" * 60)
235
258