Skip to content

v1.0.50

Choose a tag to compare

@github-actions github-actions released this 05 Mar 04:09
ef81ef6

Changes

Driver registration was copy-pasted across five files and three modalities deep -- the kind of sprawl that makes adding a new provider feel like filing taxes. This PR consolidates all provider definitions into a single ProviderDescriptor dataclass, replaces ~800 lines of scattered register_*() calls with one register_all_builtin_drivers() loop, and reworks the streaming layer to surface thinking deltas alongside text deltas.

Highlights

  • Streaming now emits thinking/reasoning chunks from Claude models in real time, not just the final text
  • New extract_with_models() function tries multiple models in priority order with full cost and attempt tracking
  • ExtractResult is now a proper class with attribute access instead of an anonymous type() hack created at every call site
Technical changes

Driver registration overhaul

  • New ProviderDescriptor dataclass in prompture/drivers/provider_descriptors.py is the single source of truth for all 17 providers and 9 aliases across LLM, STT, TTS, image-gen, and embedding modalities
  • register_all_builtin_drivers() iterates descriptors and registers factories for every modality, replacing ~200 lines of individual register_driver() / register_async_driver() calls previously in __init__.py, async_registry.py, audio_registry.py, embedding_registry.py, and img_gen_registry.py
  • PROVIDER_DRIVER_MAP and ASYNC_PROVIDER_DRIVER_MAP are now derived from descriptors via build_provider_driver_map(), replacing ~120 lines of hardcoded dicts
  • New DriverRegistry class in prompture/drivers/driver_registry.py encapsulates registry dict + entry-point loading, replacing 10 bare dicts and 4 _ensure_*_loaded() global-flag patterns in registry.py
  • registry.py delegates all operations to DriverRegistry instances; backwards-compat _SYNC_REGISTRY / _ASYNC_REGISTRY aliases point to the underlying dicts

Streaming architecture

  • Conversation._ask_stream_raw() and AsyncConversation._ask_stream_raw() yield typed dicts ({"type": "delta", "text": ...} / {"type": "thinking_delta", "text": ...}) instead of plain strings
  • Public ask_stream() remains unchanged (yields str) by filtering _ask_stream_raw() output
  • StreamEventType.thinking_delta added to the agent event enum
  • Agent and AsyncAgent propagate thinking_delta events from _ask_stream_raw() during no-tool streaming
  • ClaudeDriver and AsyncClaudeDriver now yield {"type": "thinking_delta", ...} chunks during extended thinking
  • Accumulated reasoning_content from done chunks is stored on _last_reasoning

Extraction

  • ExtractResult class in prompture/extraction/core.py replaces 14 inline type("ExtractResult", (dict,), {...}) constructions across sync/async core and conversation modules
  • _build_usage() and _merge_usage() helpers deduplicate usage-dict construction (was copy-pasted 6 times)
  • extract_with_models() (sync) and async variant auto-select stepwise vs single strategy per model based on supports_json_mode / supports_json_schema driver capabilities
  • manual_extract_and_jsonify() deprecated in favor of extract_and_jsonify(text, schema, driver=driver)
  • extract_and_jsonify() gains an explicit driver= kwarg; old positional Driver first-arg pattern emits DeprecationWarning
  • normalize_field_value() delegates type coercion to convert_value() / get_type_default() from tools.py, simplifying the function body
  • clean_json_text() now strips code fences even when they don't appear at position 0

Module reorganization

  • prompture/extraction/tukuy_bridge.py created, consolidating the tukuy bridge from prompture/integrations/tukuy_bridge.py
  • prompture/bridges/__init__.py deprecated with re-exports pointing to prompture.infra.tukuy_backend
  • Tukuy imports throughout (TukuyLLMBackend, create_tukuy_backend, TukuyTransformer) made lazy with ImportError guards so the library works without tukuy installed
  • prompture/infra/__init__.py exports TukuyLLMBackend, create_tukuy_backend, and display_available_models

Discovery

  • discovery.py refactored to derive provider configuration checks and list_models kwargs from ProviderDescriptor metadata instead of hardcoded per-provider blocks
  • display_available_models() added for formatted terminal output of discovered models

Other

  • dev.ps1 renames watch-lint mode to validate
  • VERSION file removed (versioning handled entirely by setuptools_scm)
  • .gitignore excludes .claude/settings.local.json
  • routing.py gains expanded model-to-provider mapping and fallback logic
  • extract_with_models exported from prompture.aio and prompture.extraction

Details