mycode-sdk 0.8.5__tar.gz → 0.8.7__tar.gz
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.
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/PKG-INFO +1 -1
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/pyproject.toml +1 -1
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/agent.py +45 -5
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/.gitignore +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/LICENSE +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/README.md +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/__init__.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/compact.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/hooks.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/messages.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/models.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/models_catalog.json +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/__init__.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/anthropic_like.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/base.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/gemini.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/openai_chat.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/providers/openai_responses.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/py.typed +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/session.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/tools.py +0 -0
- {mycode_sdk-0.8.5 → mycode_sdk-0.8.7}/src/mycode/utils.py +0 -0
|
@@ -30,6 +30,8 @@ from mycode.messages import (
|
|
|
30
30
|
ConversationMessage,
|
|
31
31
|
build_message,
|
|
32
32
|
flatten_message_text,
|
|
33
|
+
text_block,
|
|
34
|
+
thinking_block,
|
|
33
35
|
tool_result_block,
|
|
34
36
|
user_text_message,
|
|
35
37
|
)
|
|
@@ -303,6 +305,7 @@ class Agent:
|
|
|
303
305
|
|
|
304
306
|
task = asyncio.create_task(run_in_thread())
|
|
305
307
|
was_cancelled = False
|
|
308
|
+
output_parts: list[str] = []
|
|
306
309
|
|
|
307
310
|
while True:
|
|
308
311
|
if self._cancel_event.is_set() and not was_cancelled:
|
|
@@ -319,6 +322,7 @@ class Agent:
|
|
|
319
322
|
if output is None:
|
|
320
323
|
break
|
|
321
324
|
if not was_cancelled:
|
|
325
|
+
output_parts.append(output)
|
|
322
326
|
yield Event("tool_output", {"tool_use_id": tool_id, "output": output})
|
|
323
327
|
|
|
324
328
|
if was_cancelled:
|
|
@@ -326,7 +330,8 @@ class Agent:
|
|
|
326
330
|
await task
|
|
327
331
|
except Exception:
|
|
328
332
|
pass
|
|
329
|
-
|
|
333
|
+
output = "\n".join([*output_parts, "error: cancelled"]) if output_parts else "error: cancelled"
|
|
334
|
+
result = ToolExecutionResult(output=output, is_error=True)
|
|
330
335
|
yield self._tool_done_event(tool_id, result)
|
|
331
336
|
return
|
|
332
337
|
else:
|
|
@@ -492,8 +497,10 @@ class Agent:
|
|
|
492
497
|
return
|
|
493
498
|
|
|
494
499
|
assistant_message: ConversationMessage | None = None
|
|
500
|
+
partial_content: list[dict[str, Any]] = []
|
|
495
501
|
thinking_started_at: float | None = None
|
|
496
502
|
thinking_duration_ms: int | None = None
|
|
503
|
+
provider_cancelled = False
|
|
497
504
|
request = ProviderRequest(
|
|
498
505
|
provider=self.provider,
|
|
499
506
|
model=self.model,
|
|
@@ -513,14 +520,18 @@ class Agent:
|
|
|
513
520
|
# Phase 1: ask the provider for exactly one assistant turn.
|
|
514
521
|
async for provider_event in self._stream_provider_turn(adapter, request):
|
|
515
522
|
if self._cancel_event.is_set():
|
|
516
|
-
|
|
517
|
-
|
|
523
|
+
provider_cancelled = True
|
|
524
|
+
break
|
|
518
525
|
|
|
519
526
|
if provider_event.type == "thinking_delta":
|
|
520
527
|
delta_text = str(provider_event.data.get("text") or "")
|
|
521
528
|
if delta_text:
|
|
522
529
|
if thinking_started_at is None:
|
|
523
530
|
thinking_started_at = time.monotonic()
|
|
531
|
+
if partial_content and partial_content[-1].get("type") == "thinking":
|
|
532
|
+
partial_content[-1]["text"] = f"{partial_content[-1].get('text') or ''}{delta_text}"
|
|
533
|
+
else:
|
|
534
|
+
partial_content.append(thinking_block(delta_text))
|
|
524
535
|
yield Event("reasoning", {"delta": delta_text})
|
|
525
536
|
continue
|
|
526
537
|
|
|
@@ -530,6 +541,10 @@ class Agent:
|
|
|
530
541
|
if thinking_started_at is not None and thinking_duration_ms is None:
|
|
531
542
|
thinking_duration_ms = max(0, int((time.monotonic() - thinking_started_at) * 1000))
|
|
532
543
|
yield Event("reasoning_done", {"duration_ms": thinking_duration_ms})
|
|
544
|
+
if partial_content and partial_content[-1].get("type") == "text":
|
|
545
|
+
partial_content[-1]["text"] = f"{partial_content[-1].get('text') or ''}{delta_text}"
|
|
546
|
+
else:
|
|
547
|
+
partial_content.append(text_block(delta_text))
|
|
533
548
|
yield Event("text", {"delta": delta_text})
|
|
534
549
|
continue
|
|
535
550
|
|
|
@@ -548,13 +563,38 @@ class Agent:
|
|
|
548
563
|
assistant_message = message
|
|
549
564
|
|
|
550
565
|
except asyncio.CancelledError:
|
|
551
|
-
|
|
552
|
-
return
|
|
566
|
+
provider_cancelled = True
|
|
553
567
|
except Exception as exc:
|
|
554
568
|
logger.exception("Provider request failed")
|
|
555
569
|
yield Event("error", {"message": str(exc)})
|
|
556
570
|
return
|
|
557
571
|
|
|
572
|
+
if provider_cancelled:
|
|
573
|
+
if partial_content:
|
|
574
|
+
if thinking_started_at is not None and thinking_duration_ms is None:
|
|
575
|
+
thinking_duration_ms = max(0, int((time.monotonic() - thinking_started_at) * 1000))
|
|
576
|
+
if thinking_duration_ms is not None:
|
|
577
|
+
for block in reversed(partial_content):
|
|
578
|
+
if block.get("type") != "thinking":
|
|
579
|
+
continue
|
|
580
|
+
raw_meta = block.get("meta")
|
|
581
|
+
meta = cast(dict[str, Any], raw_meta) if isinstance(raw_meta, dict) else {}
|
|
582
|
+
block["meta"] = {**meta, "duration_ms": thinking_duration_ms}
|
|
583
|
+
break
|
|
584
|
+
cancelled_message = build_message(
|
|
585
|
+
"assistant",
|
|
586
|
+
[dict(block) for block in partial_content],
|
|
587
|
+
meta={
|
|
588
|
+
"provider": self.provider,
|
|
589
|
+
"model": self.model,
|
|
590
|
+
"context_window": self.context_window,
|
|
591
|
+
},
|
|
592
|
+
)
|
|
593
|
+
self.messages.append(cancelled_message)
|
|
594
|
+
await persist(cancelled_message)
|
|
595
|
+
yield Event("error", {"message": "cancelled"})
|
|
596
|
+
return
|
|
597
|
+
|
|
558
598
|
if not assistant_message:
|
|
559
599
|
yield Event("error", {"message": "provider produced no assistant message"})
|
|
560
600
|
return
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|