thoughtflow 0.1.2__tar.gz → 0.2.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.
Files changed (98) hide show
  1. thoughtflow-0.2.2/CHANGELOG.md +207 -0
  2. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/PKG-INFO +369 -185
  3. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/README.md +367 -171
  4. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/pyproject.toml +2 -12
  5. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/__init__.py +15 -6
  6. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/_util.py +298 -6
  7. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/action.py +3 -3
  8. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/agent.py +57 -9
  9. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/agents/react.py +2 -9
  10. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/chat.py +3 -3
  11. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/embed.py +188 -11
  12. thoughtflow-0.2.2/src/thoughtflow/eval/__init__.py +38 -0
  13. thoughtflow-0.2.2/src/thoughtflow/eval/harness.py +223 -0
  14. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/llm.py +488 -73
  15. thoughtflow-0.2.2/src/thoughtflow/llm_cache.py +211 -0
  16. thoughtflow-0.2.2/src/thoughtflow/llm_params.py +156 -0
  17. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/memory.py +184 -10
  18. thoughtflow-0.2.2/src/thoughtflow/providers/README.md +15 -0
  19. thoughtflow-0.2.2/src/thoughtflow/providers/__init__.py +16 -0
  20. thoughtflow-0.2.2/src/thoughtflow/providers/cerebras.py +75 -0
  21. thoughtflow-0.2.2/src/thoughtflow/providers/groq.py +63 -0
  22. thoughtflow-0.2.2/src/thoughtflow/providers/openrouter.py +36 -0
  23. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/this.py +4 -4
  24. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/thought.py +413 -76
  25. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/thoughts/plan.py +69 -20
  26. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/workflow.py +1 -1
  27. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/conftest.py +0 -92
  28. thoughtflow-0.2.2/tests/integration/smoke_helpers.py +104 -0
  29. thoughtflow-0.2.2/tests/integration/test_embed_providers.py +123 -0
  30. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/integration/test_llm_providers.py +227 -28
  31. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_actions.py +4 -2
  32. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_agent.py +100 -1
  33. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_embed.py +118 -0
  34. thoughtflow-0.2.2/tests/unit/test_eval.py +162 -0
  35. thoughtflow-0.2.2/tests/unit/test_foundation_agent_response.py +240 -0
  36. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_llm.py +194 -0
  37. thoughtflow-0.2.2/tests/unit/test_llm_provider_integration.py +288 -0
  38. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_memory.py +187 -4
  39. thoughtflow-0.2.2/tests/unit/test_replay.py +247 -0
  40. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_this.py +4 -4
  41. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_thought.py +105 -1
  42. thoughtflow-0.1.2/CHANGELOG.md +0 -93
  43. thoughtflow-0.1.2/src/thoughtflow/eval/__init__.py +0 -34
  44. thoughtflow-0.1.2/src/thoughtflow/eval/harness.py +0 -200
  45. thoughtflow-0.1.2/src/thoughtflow/eval/replay.py +0 -137
  46. thoughtflow-0.1.2/src/thoughtflow/trace/__init__.py +0 -34
  47. thoughtflow-0.1.2/src/thoughtflow/trace/events.py +0 -183
  48. thoughtflow-0.1.2/src/thoughtflow/trace/schema.py +0 -111
  49. thoughtflow-0.1.2/src/thoughtflow/trace/session.py +0 -141
  50. thoughtflow-0.1.2/tests/integration/test_anthropic_adapter.py +0 -73
  51. thoughtflow-0.1.2/tests/integration/test_openai_adapter.py +0 -71
  52. thoughtflow-0.1.2/tests/unit/test_trace.py +0 -174
  53. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/.gitignore +0 -0
  54. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/LICENSE +0 -0
  55. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/_cron_expr.py +0 -0
  56. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/__init__.py +0 -0
  57. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/_http.py +0 -0
  58. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/_substitution.py +0 -0
  59. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/ask.py +0 -0
  60. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/call.py +0 -0
  61. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/fetch.py +0 -0
  62. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/noop.py +0 -0
  63. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/notify.py +0 -0
  64. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/post.py +0 -0
  65. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/read_file.py +0 -0
  66. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/run.py +0 -0
  67. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/say.py +0 -0
  68. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/scrape.py +0 -0
  69. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/search.py +0 -0
  70. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/sleep.py +0 -0
  71. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/wait.py +0 -0
  72. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/actions/write_file.py +0 -0
  73. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/agents/__init__.py +0 -0
  74. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/agents/planact.py +0 -0
  75. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/agents/reflect.py +0 -0
  76. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/chron.py +0 -0
  77. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/delegate.py +0 -0
  78. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/mcp.py +0 -0
  79. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/message.py +0 -0
  80. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/py.typed +0 -0
  81. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/thoughts/__init__.py +0 -0
  82. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/thoughts/decide.py +0 -0
  83. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/src/thoughtflow/tool.py +0 -0
  84. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/__init__.py +0 -0
  85. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/integration/__init__.py +0 -0
  86. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/integration/test_chron.py +0 -0
  87. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/integration/test_scrape.py +0 -0
  88. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/integration/test_search_providers.py +0 -0
  89. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/__init__.py +0 -0
  90. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_action.py +0 -0
  91. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_chat.py +0 -0
  92. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_chron.py +0 -0
  93. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_delegate.py +0 -0
  94. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_mcp.py +0 -0
  95. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_message.py +0 -0
  96. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_tool.py +0 -0
  97. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_util.py +0 -0
  98. {thoughtflow-0.1.2 → thoughtflow-0.2.2}/tests/unit/test_workflow.py +0 -0
@@ -0,0 +1,207 @@
1
+ # Changelog
2
+
3
+ All notable changes to ThoughtFlow will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.2] - 2026-07-10
9
+
10
+ Production-hardening release: THOUGHT/PLAN parsing improvements (Foundation Agent feedback) plus unified LLM param pipeline, prompt caching, and native provider convenience classes.
11
+
12
+ ### Added
13
+ - THOUGHT `on_failure=` hook and structured failure events on MEMORY (`{name}_last_error`, `{name}_attempts`)
14
+ - THOUGHT opt-in production lane: `validation_mode='rescue'`, `strict_schema=True`, `hold_msg=True`, `repair_target=`
15
+ - `valid_extract` optional `oneOf` schema dialect for branch-shaped responses
16
+ - PLAN `normalize_plan()` subclass hook and aggregate missing-param error messages
17
+ - LLM `last_error`, `last_usage`, opt-in `request_timeout=`, `on_usage=` callback
18
+ - Unified model-param pipeline (`split_call_params`) — transport keys never leak into JSON bodies
19
+ - Prompt caching: `cached_system()`, `cached_message()`, `cache=True` on messages; Anthropic `cache_control` wire adapter
20
+ - Native provider classes: `GroqLLM`, `CerebrasLLM`, `OpenRouterLLM`
21
+ - `docs/concepts/thought.md` — parse-validate pipeline guide
22
+ - Regression tests: `test_foundation_agent_response.py`, `test_llm_provider_integration.py`
23
+ - Example: `examples/scripts/15_thought_integration_test.py`
24
+ - Integration smoke tests: `tests/integration/test_llm_providers.py`, `test_embed_providers.py`
25
+
26
+ ### Changed
27
+ - Validation callables may return bare `bool` (coerced to tuple automatically)
28
+ - Parse-failure and repair-suffix messages are model-friendly
29
+ - `parser='json'` uses balanced JSON extraction
30
+ - Execution events include `failed: true` when retries exhausted with error
31
+ - OpenAI-compatible choice extraction falls back to `message.reasoning` when `content` is empty
32
+ - Expanded `docs/concepts/llm.md`, `primitives/LLM.md`, `primitives/THOUGHT.md`, `primitives/PLAN.md`
33
+
34
+ ### Fixed
35
+ - Bare-bool `validation=` lambdas no longer crash unpack
36
+ - PLAN param validation reports all missing params at once
37
+ - OpenRouter `referer`/`title` no longer leak into request JSON body
38
+ - EMBED Groq calls include User-Agent (Cloudflare HTTP 1010 without it)
39
+ - EMBED `text-embedding-004` aliases to `gemini-embedding-001`; `last_error` surfaced on failures
40
+
41
+ ## [Unreleased]
42
+
43
+ _Nothing yet._
44
+
45
+ ---
46
+
47
+ ## [0.2.0] - 2026-06-10
48
+
49
+ The release where ThoughtFlow's deterministic-replay story becomes real —
50
+ grown from MEMORY itself, with zero new concepts.
51
+
52
+ ### Added
53
+ - **Record/replay system.** `llm.record(memory)` captures every LLM exchange
54
+ (request + response, keyed by content hash) as MEMORY events. `LLM.replay(memory)`
55
+ returns a `ReplayLLM` — a drop-in LLM that serves recorded responses
56
+ deterministically: offline, instant, no API keys. Misses fail loudly
57
+ (`ReplayMissError`) or fall back to a live LLM via `on_miss=`.
58
+ - `EMBED.record()` / `EMBED.replay()` / `ReplayEMBED` — the identical seam for
59
+ the embedding boundary
60
+ - `MEMORY.add_exchange()` / `MEMORY.get_exchanges()` — the event-sourced storage
61
+ powering record/replay; recordings survive `to_json`/`from_json` round-trips
62
+ - **Working eval harness.** `thoughtflow.eval.Harness` now actually runs:
63
+ a `TestCase` is a name + setup + check predicate over MEMORY; `Harness.run(flow)`
64
+ executes any `memory -> memory` callable per case in isolated MEMORYs,
65
+ containing exceptions as failures. The whole package is ~230 lines.
66
+ - **Streaming through THOUGHT.** New `on_token=` config hook: when set, the LLM
67
+ response streams through the hook chunk-by-chunk, then the complete text flows
68
+ through the normal parse/validate/store pipeline. LLMs without streaming
69
+ support fall back to a normal call automatically.
70
+ - `OpenAICompatibleLLM` exported from the package root (local servers: vLLM,
71
+ LM Studio, llama.cpp, MLX)
72
+ - Python 3.13 classifier
73
+ - Unit tests for record/replay (round-trips, hash stability, miss behavior,
74
+ end-to-end THOUGHT replay), the eval harness, on_token streaming, and
75
+ validation-spelling equivalence
76
+ - `MEMORY.add_augment()` — store context tagged for optional LLM-view merging
77
+ (e.g. RAG chunks) without mutating user messages in the event log
78
+ - `MEMORY.get_llm_msgs(merge_augments=False)` — build LLM-ready message dicts;
79
+ when `merge_augments=True`, fold `metadata['augments'] == 'last_user'`
80
+ events into the preceding user turn for the model payload only
81
+ - `AGENT(merge_augments=False)` — opt-in flag to use the merged LLM view in
82
+ `_build_messages()`; default behavior unchanged
83
+ - Addresses [#15](https://github.com/jrolf/thoughtflow/issues/15) — optional
84
+ support for prompt-injection-style RAG while preserving event-sourced storage
85
+
86
+ ### Changed
87
+ - `THOUGHT` validation: `validation=` is the canonical spelling and now accepts
88
+ both callables and built-in strings (`'any'`, `'has_keys:...'`,
89
+ `'list_min_len:N'`, `'summary_v1'`); the `validator=` config key remains fully
90
+ supported and behaves identically
91
+ - Standardized brand casing to "ThoughtFlow" across source docstrings, ZEN.md,
92
+ and project docs
93
+
94
+ ### Fixed
95
+ - `MEMORY.copy()` — no longer stores a module reference on the instance
96
+ (`bisect` is now a module-level import), so deep copy works; the previously
97
+ skipped test is restored and expanded
98
+ - Anthropic: system prompts now use the top-level `system` field (not `messages`)
99
+ - Gemini: map `max_tokens` / `temperature` / `top_p` to `generationConfig`
100
+ - `THOUGHT`: `parse='json'` now aliases `parser='json'`; fenced JSON parsing improved
101
+
102
+ ### Removed
103
+ - `thoughtflow.trace` (Session/Event/TraceSchema) — superseded by MEMORY-native
104
+ record/replay. The subsystem duplicated MEMORY's event log in a foreign idiom,
105
+ and its `load()`/`run()` methods were unimplemented stubs with no user surface.
106
+ MEMORY's JSON serialization already carries a schema version field.
107
+ - `thoughtflow.eval.Replay` stub — replaced by the working `ReplayLLM`
108
+ - Vestigial pyproject extras (`openai`, `anthropic`, `local`, `all-providers`) —
109
+ these installed SDKs the zero-dependency core never imports (leftovers from a
110
+ removed adapter-era design)
111
+ - Adapter-era integration test files (`test_openai_adapter.py`,
112
+ `test_anthropic_adapter.py`) and the legacy `MockAdapter` test fixture —
113
+ all referenced a `thoughtflow.adapters` module that no longer exists
114
+
115
+ ---
116
+
117
+ ## [0.1.3] - 2026-06-10
118
+
119
+ ### Added
120
+ - `MEMORY.last_result_msg()` — convenience accessor for the most recent `result` role message (mirrors `last_user_msg`, `last_log_msg`, etc.)
121
+ - `MEMORY.add_msg(..., metadata=...)` — optional per-message metadata dict for UI and RAG tagging (e.g. `{'internal': True}`)
122
+ - `MEMORY.get_msgs(..., metadata_filter=..., exclude_metadata=...)` — filter messages by metadata for UI-visible history
123
+ - `AGENT._strip_markdown_fences()` — strips wrapping markdown code fences before JSON tool-call parsing
124
+ - Unit tests for all of the above
125
+
126
+ ### Fixed
127
+ - Pre-commit `block-ai-trailer` hook now passes the commit message filename (required by `block-ai-contributors.sh`)
128
+ - Closes [#14](https://github.com/jrolf/thoughtflow/issues/14) — message metadata for UI filtering
129
+
130
+ ---
131
+
132
+ ## [0.1.2] - 2026-04-01
133
+
134
+ ### Added
135
+ - `LLM` constructor now accepts `**kwargs` for default call parameters — `temperature`, `max_tokens`, `top_p`, `frequency_penalty`, and `presence_penalty` (plus any provider-specific key) can be set once at construction and apply to every subsequent `.call()` invocation
136
+ - `LLM.default_params` attribute exposes the stored defaults for inspection
137
+ - Per-call `params` continue to override defaults on a per-key basis
138
+ - 8 new unit tests covering default storage, merge precedence, non-mutation between calls, and all five parameters passing through to the API payload
139
+ - Updated `primitives/LLM.md` with full parameter reference table and constructor-defaults usage examples
140
+ - Updated `docs/quickstart.md` with "Setting Default Parameters" section
141
+
142
+ ### Fixed
143
+ - Closes [#4](https://github.com/jrolf/thoughtflow/issues/4) — feature request: `temperature` argument for LLM creation
144
+
145
+ ---
146
+
147
+ ## [0.1.1] - 2026-04-01
148
+
149
+ ### Added
150
+ - `hooks/block-ai-contributors.sh` — portable pre-commit/commit-msg hook that blocks commits attributed to non-human identities (checks author name/email and Co-authored-by trailers against a configurable blocklist)
151
+ - `.pre-commit-config.yaml` now includes `block-ai-author` (pre-commit stage) and `block-ai-trailer` (commit-msg stage) hooks
152
+
153
+ ### Fixed
154
+ - Removed erroneous `Co-authored-by: Cursor` and `Made-with: Cursor` trailers from five historical commits; git history rewritten to ensure only human contributors are attributed
155
+
156
+ ---
157
+
158
+ ## [0.1.0] - 2026-04-01
159
+
160
+ ### Added
161
+ - `PlanActAgent` fenced-JSON fallback parsing -- silently recovers when the LLM wraps its plan output in markdown code fences (contributed by @cmgoffena13 via PR #5)
162
+ - `PlanActAgent` execution logging -- plan generation and replanning events are now recorded in `execution_log` and written to conversation memory for full traceability (contributed by @cmgoffena13 via PR #5)
163
+ - Pre-commit hooks via `prek` -- `ruff check` on commit, `pytest tests/unit/` on pre-push
164
+ - `ruff.toml` -- project-wide linter configuration (Pyflakes F-rules only; no style enforcement)
165
+ - `chore/` branch naming convention added to CONTRIBUTING.md
166
+
167
+ ### Changed
168
+ - Ruff configured as bug-catcher only (unused imports, undefined names, unused variables). No formatter, no style or modernization rules.
169
+ - `CONTRIBUTING.md` updated to reflect actual dev setup -- removed `ruff format`, type hints requirements, and `mypy` from the checklist
170
+ - Dev dependency swapped from `pre-commit` to `prek`
171
+
172
+ ### Fixed
173
+ - `LLM.__init__` now correctly parses model names containing colons (e.g. `ollama:mistral:7b`) by splitting on the first colon only (contributed by @cmgoffena13 via PR #3)
174
+ - `memory.render()` calls in example scripts corrected from stale `output_format=` argument to `format=` (contributed by @orliesaurus via PR #7)
175
+ - Dead code removed across `src/` and `tests/` -- unused imports, unused variables, and redefined names cleared
176
+
177
+ ---
178
+
179
+ ## [0.0.9] - 2026-03-18
180
+
181
+ ### Added
182
+ - `PROVIDER_ROLE_MAP` — module-level configuration in `llm.py` mapping ThoughtFlow-internal roles (`action`, `result`) to each provider's native role strings
183
+ - `LLM._map_roles()` — translates roles using `PROVIDER_ROLE_MAP` after structural normalization
184
+ - `LLM._prepare_messages()` — convenience pipeline: `_normalize_messages()` then `_map_roles()`; used by all `_call_*` methods
185
+ - `AGENT.LLM_ROLES` — class-level set controlling which MEMORY roles are forwarded to the LLM (default: `user`, `assistant`, `system`, `action`, `result`); subclasses can override
186
+ - Ollama `_message_to_choice()` — extracts `tool_calls` from Ollama responses into content text (contributed by @cmgoffena13 via PR #1)
187
+
188
+ ### Changed
189
+ - All `_call_*` methods and `_stream()` now use `_prepare_messages()` instead of `_normalize_messages()` directly
190
+ - `_call_gemini()` no longer has an inline role translation dict; Gemini roles are handled centrally by `PROVIDER_ROLE_MAP`
191
+ - `AGENT._build_messages()` and `ReactAgent._build_messages()` now filter memory messages to `LLM_ROLES`, preventing non-LLM roles from reaching the provider API
192
+
193
+ ### Fixed
194
+ - Agents using Ollama/Gemini no longer infinite-loop when tool calls produce `"action"`/`"result"` roles that the provider silently discards
195
+ - Ollama responses containing `tool_calls` are now correctly extracted and returned (previously only `content` was read)
196
+
197
+ ---
198
+
199
+ <!-- Release links -->
200
+ [Unreleased]: https://github.com/jrolf/thoughtflow/compare/v0.2.2...HEAD
201
+ [0.2.2]: https://github.com/jrolf/thoughtflow/compare/v0.2.0...v0.2.2
202
+ [0.2.0]: https://github.com/jrolf/thoughtflow/compare/v0.1.3...v0.2.0
203
+ [0.1.3]: https://github.com/jrolf/thoughtflow/compare/v0.1.2...v0.1.3
204
+ [0.1.2]: https://github.com/jrolf/thoughtflow/compare/v0.1.1...v0.1.2
205
+ [0.1.1]: https://github.com/jrolf/thoughtflow/compare/v0.1.0...v0.1.1
206
+ [0.1.0]: https://github.com/jrolf/thoughtflow/compare/v0.0.9...v0.1.0
207
+ [0.0.9]: https://github.com/jrolf/thoughtflow/compare/v0.0.8...v0.0.9