mycode-sdk 0.7.1__tar.gz → 0.7.2__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.7.1 → mycode_sdk-0.7.2}/PKG-INFO +1 -1
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/pyproject.toml +1 -1
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/agent.py +21 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/messages.py +2 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/.gitignore +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/LICENSE +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/README.md +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/__init__.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/hooks.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/models.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/models_catalog.json +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/__init__.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/anthropic_like.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/base.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/gemini.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/openai_chat.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/providers/openai_responses.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/py.typed +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/session.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/tools.py +0 -0
- {mycode_sdk-0.7.1 → mycode_sdk-0.7.2}/src/mycode/utils.py +0 -0
|
@@ -11,6 +11,7 @@ import asyncio
|
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
13
|
import tempfile
|
|
14
|
+
import time
|
|
14
15
|
from collections.abc import AsyncIterator, Awaitable, Callable, Sequence
|
|
15
16
|
from dataclasses import dataclass, field
|
|
16
17
|
from pathlib import Path
|
|
@@ -493,6 +494,8 @@ class Agent:
|
|
|
493
494
|
return
|
|
494
495
|
|
|
495
496
|
assistant_message: ConversationMessage | None = None
|
|
497
|
+
thinking_started_at: float | None = None
|
|
498
|
+
thinking_duration_ms: int | None = None
|
|
496
499
|
request = ProviderRequest(
|
|
497
500
|
provider=self.provider,
|
|
498
501
|
model=self.model,
|
|
@@ -518,12 +521,17 @@ class Agent:
|
|
|
518
521
|
if provider_event.type == "thinking_delta":
|
|
519
522
|
delta_text = str(provider_event.data.get("text") or "")
|
|
520
523
|
if delta_text:
|
|
524
|
+
if thinking_started_at is None:
|
|
525
|
+
thinking_started_at = time.monotonic()
|
|
521
526
|
yield Event("reasoning", {"delta": delta_text})
|
|
522
527
|
continue
|
|
523
528
|
|
|
524
529
|
if provider_event.type == "text_delta":
|
|
525
530
|
delta_text = str(provider_event.data.get("text") or "")
|
|
526
531
|
if delta_text:
|
|
532
|
+
if thinking_started_at is not None and thinking_duration_ms is None:
|
|
533
|
+
thinking_duration_ms = max(0, int((time.monotonic() - thinking_started_at) * 1000))
|
|
534
|
+
yield Event("reasoning_done", {"duration_ms": thinking_duration_ms})
|
|
527
535
|
yield Event("text", {"delta": delta_text})
|
|
528
536
|
continue
|
|
529
537
|
|
|
@@ -533,6 +541,10 @@ class Agent:
|
|
|
533
541
|
if provider_event.type != "message_done":
|
|
534
542
|
continue
|
|
535
543
|
|
|
544
|
+
if thinking_started_at is not None and thinking_duration_ms is None:
|
|
545
|
+
thinking_duration_ms = max(0, int((time.monotonic() - thinking_started_at) * 1000))
|
|
546
|
+
yield Event("reasoning_done", {"duration_ms": thinking_duration_ms})
|
|
547
|
+
|
|
536
548
|
message = provider_event.data.get("message")
|
|
537
549
|
if isinstance(message, dict):
|
|
538
550
|
assistant_message = message
|
|
@@ -549,6 +561,15 @@ class Agent:
|
|
|
549
561
|
yield Event("error", {"message": "provider produced no assistant message"})
|
|
550
562
|
return
|
|
551
563
|
|
|
564
|
+
if thinking_duration_ms is not None:
|
|
565
|
+
for block in reversed(assistant_message.get("content") or []):
|
|
566
|
+
if not isinstance(block, dict) or block.get("type") != "thinking":
|
|
567
|
+
continue
|
|
568
|
+
raw_meta = block.get("meta")
|
|
569
|
+
meta = cast(dict[str, Any], raw_meta) if isinstance(raw_meta, dict) else {}
|
|
570
|
+
block["meta"] = {**meta, "duration_ms": thinking_duration_ms}
|
|
571
|
+
break
|
|
572
|
+
|
|
552
573
|
self.messages.append(assistant_message)
|
|
553
574
|
await persist(assistant_message)
|
|
554
575
|
|
|
@@ -15,6 +15,8 @@ Metadata contract:
|
|
|
15
15
|
`provider`, `model`, `provider_message_id`, `stop_reason`, `usage`
|
|
16
16
|
- provider-specific assistant message extras live under `meta.native`
|
|
17
17
|
- provider-specific block replay hints live under `block.meta.native`
|
|
18
|
+
- local display metadata, such as `block.meta.duration_ms`, is never sent
|
|
19
|
+
upstream; provider adapters must explicitly project only supported fields
|
|
18
20
|
"""
|
|
19
21
|
|
|
20
22
|
from __future__ import annotations
|
|
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
|