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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mycode-sdk
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: Lightweight Python SDK for building AI agents.
5
5
  Project-URL: Homepage, https://github.com/legibet/mycode
6
6
  Project-URL: Repository, https://github.com/legibet/mycode
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mycode-sdk"
7
- version = "0.7.1"
7
+ version = "0.7.2"
8
8
  description = "Lightweight Python SDK for building AI agents."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -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