flock-core 0.4.0b17__py3-none-any.whl → 0.4.0b19__py3-none-any.whl

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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.4
2
+ Name: flock-core
3
+ Version: 0.4.0b19
4
+ Summary: Declarative LLM Orchestration at Scale
5
+ Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
+ License-File: LICENSE
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: azure-search-documents>=11.5.2
12
+ Requires-Dist: chromadb>=0.6.3
13
+ Requires-Dist: cloudpickle>=3.1.1
14
+ Requires-Dist: datasets>=3.2.0
15
+ Requires-Dist: devtools>=0.12.2
16
+ Requires-Dist: dspy==2.6.16
17
+ Requires-Dist: duckduckgo-search>=7.3.2
18
+ Requires-Dist: fastapi>=0.115.8
19
+ Requires-Dist: httpx>=0.28.1
20
+ Requires-Dist: litellm==1.63.7
21
+ Requires-Dist: loguru>=0.7.3
22
+ Requires-Dist: matplotlib>=3.10.0
23
+ Requires-Dist: msgpack>=1.1.0
24
+ Requires-Dist: nltk>=3.9.1
25
+ Requires-Dist: notion-client>=2.3.0
26
+ Requires-Dist: opentelemetry-api>=1.30.0
27
+ Requires-Dist: opentelemetry-exporter-jaeger-proto-grpc>=1.21.0
28
+ Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0
29
+ Requires-Dist: opentelemetry-exporter-otlp>=1.30.0
30
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
31
+ Requires-Dist: opentelemetry-sdk>=1.30.0
32
+ Requires-Dist: pandas>=2.2.3
33
+ Requires-Dist: pillow>=10.4.0
34
+ Requires-Dist: prometheus-client>=0.21.1
35
+ Requires-Dist: psutil>=6.1.1
36
+ Requires-Dist: pydantic-settings>=2.7.1
37
+ Requires-Dist: pydantic>=2.10.5
38
+ Requires-Dist: python-box>=7.3.2
39
+ Requires-Dist: python-decouple>=3.8
40
+ Requires-Dist: python-dotenv>=1.0.1
41
+ Requires-Dist: python-fasthtml>=0.12.6
42
+ Requires-Dist: pyyaml>=6.0
43
+ Requires-Dist: questionary>=2.1.0
44
+ Requires-Dist: rich>=13.9.4
45
+ Requires-Dist: sentence-transformers>=3.4.1
46
+ Requires-Dist: temporalio>=1.9.0
47
+ Requires-Dist: tiktoken>=0.8.0
48
+ Requires-Dist: toml>=0.10.2
49
+ Requires-Dist: tqdm>=4.67.1
50
+ Requires-Dist: uvicorn>=0.34.0
51
+ Requires-Dist: zep-python>=2.0.2
52
+ Provides-Extra: all
53
+ Requires-Dist: docling>=2.18.0; extra == 'all'
54
+ Requires-Dist: markdownify>=0.14.1; extra == 'all'
55
+ Requires-Dist: tavily-python>=0.5.0; extra == 'all'
56
+ Provides-Extra: tools
57
+ Requires-Dist: markdownify>=0.14.1; extra == 'tools'
58
+ Requires-Dist: tavily-python>=0.5.0; extra == 'tools'
59
+ Description-Content-Type: text/markdown
60
+
61
+ # 🚀 Flock: The Declarative AI Agent Framework 🚀
62
+
63
+ <p align="center">
64
+ <!-- Placeholder for your Flock Logo/Banner - Replace URL -->
65
+ <img alt="Flock Banner" src="https://raw.githubusercontent.com/whiteducksoftware/flock/master/docs/assets/images/flock.png" width="600">
66
+ </p>
67
+ <p align="center">
68
+ <!-- Update badges -->
69
+ <a href="https://pypi.org/project/flock-core/" target="_blank"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/flock-core?style=for-the-badge&logo=pypi&label=pip%20version"></a>
70
+ <img alt="Python Version" src="https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge&logo=python">
71
+ <a href="https://github.com/whiteducksoftware/flock/actions/workflows/deploy-whiteduck-pypi.yml" target="_blank"><img alt="CI Status" src="https://img.shields.io/github/actions/workflow/status/whiteducksoftware/flock/deploy-whiteduck-pypi.yml?branch=master&style=for-the-badge&logo=githubactions&logoColor=white"></a>
72
+ <a href="https://github.com/whiteducksoftware/flock/blob/master/LICENSE" target="_blank"><img alt="License" src="https://img.shields.io/pypi/l/flock-core?style=for-the-badge"></a>
73
+ <a href="https://whiteduck.de" target="_blank"><img alt="Built by white duck" src="https://img.shields.io/badge/Built%20by-white%20duck%20GmbH-white?style=for-the-badge&labelColor=black"></a>
74
+ <a href="https://www.linkedin.com/company/whiteduck" target="_blank"><img alt="LinkedIn" src="https://img.shields.io/badge/linkedin-%230077B5.svg?style=for-the-badge&logo=linkedin&logoColor=white&label=whiteduck"></a>
75
+ <a href="https://bsky.app/profile/whiteduck-gmbh.bsky.social" target="_blank"><img alt="Bluesky" src="https://img.shields.io/badge/bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF&label=whiteduck-gmbh"></a>
76
+ </p>
77
+
78
+ 🐤 Flock 0.4.0 currently in beta - use `pip install flock-core==0.4.0b5` 🐤
79
+
80
+ 🐤 `pip install flock-core` will install the latest non-beta version 🐤
81
+
82
+ 🐤 Expected Release for 0.4.0 `Magpie`: End of April 2025 🐤
83
+
84
+ ---
85
+
86
+ **Tired of wrestling with paragraphs of prompt text just to get your AI agent to perform a specific, structured task?** 😫
87
+
88
+ Enter **Flock**, the agent framework that lets you ditch the prompt-palaver and focus on **what** you want your agents to achieve through a **declarative approach**. Define your agent's inputs, outputs, and available tools using clear Python structures (including type hints!), and let Flock handle the complex LLM interactions and orchestration.
89
+
90
+ Built with real-world deployment in mind, Flock integrates seamlessly with tools like **Temporal** (optional) for building robust, fault-tolerant, and scalable agent systems right out of the box.
91
+
92
+ **Looking for examples and tutorials?** Check out the dedicated [**👉 flock-showcase Repository**](https://github.com/whiteducksoftware/flock-showcase)!
93
+
94
+ ## ✨ Why Join the Flock?
95
+
96
+ Flock offers a different way to build agentic systems:
97
+
98
+ | Traditional Agent Frameworks 😟 | Flock Framework 🐤🐧🐓🦆 |
99
+ | :------------------------------------- | :------------------------------------ |
100
+ | 🤯 **Prompt Nightmare** | ✅ **Declarative Simplicity** |
101
+ | *Long, brittle, hard-to-tune prompts* | *Clear input/output specs (typed!)* |
102
+ | 💥 **Fragile & Unpredictable** | ⚡ **Robust & Production-Ready** |
103
+ | *Single errors can halt everything* | *Fault-tolerant via Temporal option* |
104
+ | 🧩 **Monolithic & Rigid** | 🔧 **Modular & Flexible** |
105
+ | *Hard to extend or modify logic* | *Pluggable Evaluators, Modules, Tools*|
106
+ | ⛓️ **Basic Chaining** | 🚀 **Advanced Orchestration** |
107
+ | *Often just linear workflows* | *Dynamic Routing, Batch Processing* |
108
+ | 🧪 **Difficult Testing** | ✅ **Testable Components** |
109
+ | *Hard to unit test prompt logic* | *Clear I/O contracts aid testing* |
110
+ | 📄 **Unstructured Output** | ✨ **Structured Data Handling** |
111
+ | *Parsing unreliable LLM text output* | *Native Pydantic/Typed Dict support* |
112
+
113
+ ## 💡 Core Concepts
114
+
115
+ Flock's power comes from a few key ideas (Learn more in the [Full Documentation](https://whiteducksoftware.github.io/flock/)):
116
+
117
+ 1. **Declarative Agents:** Define agents by *what* they do (inputs/outputs), not *how*. Flock uses **Evaluators** (like the default `DeclarativeEvaluator` powered by DSPy) to handle the underlying logic.
118
+ 2. **Typed Signatures:** Specify agent inputs and outputs using Python type hints and optional descriptions (e.g., `"query: str | User request, context: Optional[List[MyType]]"`).
119
+ 3. **Modular Components:** Extend agent capabilities with pluggable **Modules** (e.g., for memory, metrics, output formatting) that hook into the agent's lifecycle.
120
+ 4. **Intelligent Workflows:** Chain agents explicitly or use **Routers** (LLM-based, Agent-based, or custom) for dynamic decision-making.
121
+ 5. **Reliable Execution:** Run locally for easy debugging or seamlessly switch to **Temporal** (optional) for production-grade fault tolerance, retries, and state management.
122
+ 6. **Tool Integration:** Equip agents with standard or custom Python functions (`@flock_tool`) registered via the `FlockRegistry`.
123
+ 7. **Registry:** A central place (`@flock_component`, `@flock_type`, `@flock_tool`) to register your custom classes, types, and functions, enabling robust serialization and dynamic loading.
124
+
125
+ ## 💾 Installation
126
+
127
+ Get started with the core Flock library:
128
+
129
+ ```bash
130
+ # Using uv (recommended)
131
+ uv pip install flock-core
132
+
133
+ # Using pip
134
+ pip install flock-core
135
+ ```
136
+
137
+ Extras: Install optional dependencies for specific features:
138
+
139
+ ```bash
140
+ # Common tools (Tavily, Markdownify)
141
+ uv pip install flock-core[tools]
142
+
143
+ # All optional dependencies (including tools, docling, etc.)
144
+ uv pip install flock-core[all]
145
+ ```
146
+
147
+ Environment Setup:
148
+
149
+ Flock uses environment variables (typically in a .env file) for configuration, especially API keys. Create a .env file in your project root:
150
+
151
+ ```bash
152
+ # .env - Example
153
+
154
+ # --- LLM Provider API Keys (Required by most examples) ---
155
+ # Add keys for providers you use (OpenAI, Anthropic, Gemini, Azure, etc.)
156
+ # Refer to litellm docs (https://docs.litellm.ai/docs/providers) for names
157
+ OPENAI_API_KEY="your-openai-api-key"
158
+ # ANTHROPIC_API_KEY="your-anthropic-api-key"
159
+
160
+ # --- Tool-Specific Keys (Optional) ---
161
+ # TAVILY_API_KEY="your-tavily-search-key"
162
+ # GITHUB_PAT="your-github-personal-access-token"
163
+
164
+ # --- Default Flock Settings (Optional) ---
165
+ DEFAULT_MODEL="openai/gpt-4o" # Default LLM if agent doesn't specify
166
+
167
+ # --- Flock CLI Settings (Managed by `flock settings`) ---
168
+ # SHOW_SECRETS="False"
169
+ # VARS_PER_PAGE="20"
170
+ ```
171
+
172
+ Remember to add .env to your .gitignore!
173
+
174
+ ## ⚡ Quick Start Syntax
175
+
176
+ While detailed examples and tutorials now live in the flock-showcase repository, here's a minimal example to illustrate the core syntax:
177
+
178
+ ```python
179
+ from flock.core import Flock, FlockFactory
180
+
181
+ # 1. Create the main orchestrator
182
+ # Uses DEFAULT_MODEL from .env or defaults to "openai/gpt-4o" if not set
183
+ my_flock = Flock(name="SimpleFlock")
184
+
185
+ # 2. Declaratively define an agent using the Factory
186
+ # Input: a topic (string)
187
+ # Output: a title (string) and bullet points (list of strings)
188
+ brainstorm_agent = FlockFactory.create_default_agent(
189
+ name="idea_generator",
190
+ description="Generates titles and key points for a given topic.",
191
+ input="topic: str | The subject to brainstorm about",
192
+ output="catchy_title: str, key_points: list[str] | 3-5 main bullet points"
193
+ )
194
+
195
+ # 3. Add the agent to the Flock
196
+ my_flock.add_agent(brainstorm_agent)
197
+
198
+ # 4. Run the agent!
199
+ if __name__ == "__main__":
200
+ input_data = {"topic": "The future of AI agents"}
201
+ try:
202
+ # The result is a Box object (dot-accessible dict)
203
+ result = my_flock.run(start_agent="idea_generator", input=input_data)
204
+ print(f"Generated Title: {result.catchy_title}")
205
+ print("Key Points:")
206
+ for point in result.key_points:
207
+ print(f"- {point}")
208
+ except Exception as e:
209
+ print(f"An error occurred: {e}")
210
+ print("Ensure your LLM API key (e.g., OPENAI_API_KEY) is set in your .env file!")
211
+ ```
212
+
213
+ ## ✨ Utility: @flockclass Hydrator
214
+
215
+ Flock also provides conveniences. The @flockclass decorator allows you to easily populate Pydantic models using an LLM:
216
+
217
+ ```python
218
+ from pydantic import BaseModel
219
+ from flock.util.hydrator import flockclass # Assuming hydrator utility exists
220
+ import asyncio
221
+
222
+ @flockclass(model="openai/gpt-4o") # Decorate your Pydantic model
223
+ class CharacterIdea(BaseModel):
224
+ name: str
225
+ char_class: str
226
+ race: str
227
+ backstory_hook: str | None = None # Field to be filled by hydrate
228
+ personality_trait: str | None = None # Field to be filled by hydrate
229
+
230
+ async def create_character():
231
+ # Create with minimal data
232
+ char = CharacterIdea(name="Gorok", char_class="Barbarian", race="Orc")
233
+ print(f"Before Hydration: {char}")
234
+
235
+ # Call hydrate to fill in the None fields using the LLM
236
+ hydrated_char = await char.hydrate()
237
+
238
+ print(f"\nAfter Hydration: {hydrated_char}")
239
+ print(f"Backstory Hook: {hydrated_char.backstory_hook}")
240
+
241
+ # asyncio.run(create_character())
242
+ ```
243
+
244
+ ## 📚 Examples & Tutorials
245
+
246
+ For a comprehensive set of examples, ranging from basic usage to complex projects and advanced features, please visit our dedicated showcase repository:
247
+
248
+ ➡️ [github.com/whiteducksoftware/flock-showcase](https://github.com/whiteducksoftware/flock-showcase) ⬅️
249
+
250
+ The showcase includes:
251
+
252
+ - Step-by-step guides for core concepts.
253
+ - Examples of tool usage, routing, memory, and more.
254
+ - Complete mini-projects demonstrating practical applications.
255
+
256
+ ## 📖 Documentation
257
+
258
+ Full documentation, including API references and conceptual explanations, can be found at:
259
+
260
+ ➡️ [whiteducksoftware.github.io/flock/](https://whiteducksoftware.github.io/flock/) ⬅️
261
+
262
+ ## 🤝 Contributing
263
+
264
+ We welcome contributions! Please see the CONTRIBUTING.md file (if available) or open an issue/pull request on GitHub.
265
+
266
+ Ways to contribute:
267
+
268
+ - Report bugs or suggest features.
269
+ - Improve documentation.
270
+ - Contribute new Modules, Evaluators, or Routers.
271
+ - Add examples to the flock-showcase repository.
272
+ - Join our Discord Community to discuss development! <!-- Add Discord link -->
273
+
274
+ ## 📜 License
275
+
276
+ Flock is licensed under the Apache License 2.0. See the LICENSE file for details.
277
+
278
+ ## 🏢 About
279
+
280
+ Flock is developed and maintained by white duck GmbH, your partner for cloud-native solutions and AI integration.
@@ -12,7 +12,7 @@ flock/cli/load_release_notes.py,sha256=qFcgUrMddAE_TP6x1P-6ZywTUjTknfhTDW5LTxtg1
12
12
  flock/cli/loaded_flock_cli.py,sha256=IkeYvw52Bh3uFIm2O5xgppJ9KaY7jfh0VSFkiI46tTg,6855
13
13
  flock/cli/manage_agents.py,sha256=Psl014LCrJmBgwrjsp7O3WNlWvQmVd_IDud3rd0lnLI,12786
14
14
  flock/cli/registry_management.py,sha256=mAHy3wT97YgODR0gVOkTXDqR5NIPzM-E-z9dEtw9-tw,29790
15
- flock/cli/runner.py,sha256=TebsqwAfc_bTGzr-id6frgZXPCDJ5Xu1pBd9bZnqIDg,1120
15
+ flock/cli/runner.py,sha256=TgiuhRLkpa6dn3C-3eCmWx-bWUlTjaH0sD7Y-O7MrYM,1122
16
16
  flock/cli/settings.py,sha256=Z_TXBzCYlCmSaKrJ_CQCdYy-Cj29gpI4kbC_2KzoKqg,27025
17
17
  flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
18
18
  flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
@@ -44,7 +44,7 @@ flock/core/execution/local_executor.py,sha256=rnIQvaJOs6zZORUcR3vvyS6LPREDJTjayg
44
44
  flock/core/execution/temporal_executor.py,sha256=OF_uXgQsoUGp6U1ZkcuaidAEKyH7XDtbfrtdF10XQ_4,1675
45
45
  flock/core/interpreter/python_interpreter.py,sha256=RaUMZuufsKBNQ4FAeSaOgUuxzs8VYu5TgUUs-xwaxxM,26376
46
46
  flock/core/logging/__init__.py,sha256=Q8hp9-1ilPIUIV0jLgJ3_cP7COrea32cVwL7dicPnlM,82
47
- flock/core/logging/logging.py,sha256=-ViLNLTm5wqbvVsc6xYekOsAY38ZCIn6j1wciC7lgeM,15417
47
+ flock/core/logging/logging.py,sha256=-Mzft9GOahe0cOQtNbdlh0yLH-00ZAl713xHugtRFeQ,15527
48
48
  flock/core/logging/telemetry.py,sha256=3E9Tyj6AUR6A5RlIufcdCdWm5BAA7tbOsCa7lHoUQaU,5404
49
49
  flock/core/logging/trace_and_logged.py,sha256=5vNrK1kxuPMoPJ0-QjQg-EDJL1oiEzvU6UNi6X8FiMs,2117
50
50
  flock/core/logging/formatters/enum_builder.py,sha256=LgEYXUv84wK5vwHflZ5h8HBGgvLH3sByvUQe8tZiyY0,981
@@ -63,7 +63,7 @@ flock/core/serialization/flock_serializer.py,sha256=TEePKaJqU-_XWHTMWyMHloDNwmkK
63
63
  flock/core/serialization/json_encoder.py,sha256=gAKj2zU_8wQiNvdkby2hksSA4fbPNwTjup_yz1Le1Vw,1229
64
64
  flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
65
65
  flock/core/serialization/serializable.py,sha256=qlv8TsTqRuklXiNuCMrvro5VKz764xC2i3FlgLJSkdk,12129
66
- flock/core/serialization/serialization_utils.py,sha256=ONv7KUhc66e4sKYu9uFc3qU1jOg4DvIXRJ5QXaTIQj0,10298
66
+ flock/core/serialization/serialization_utils.py,sha256=n5q6P18dEK1JHejgFhAv-87mODjKuz36GYV1n6p-VO4,12924
67
67
  flock/core/tools/azure_tools.py,sha256=hwLnI2gsEq6QzUoWj5eCGDKTdXY1XUf6K-H5Uwva2MY,17093
68
68
  flock/core/tools/basic_tools.py,sha256=Ye7nlI4RRkqWRy8nH9CKuItBmh_ZXxUpouGnCOfx0s0,9050
69
69
  flock/core/tools/llm_tools.py,sha256=Bdt4Dpur5dGpxd2KFEQyxjfZazvW1HCDKY6ydMj6UgQ,21811
@@ -72,7 +72,7 @@ flock/core/tools/zendesk_tools.py,sha256=deZAyUi9j-_yZaTayLQVJaFXIqIct-P6C8IGN5U
72
72
  flock/core/tools/dev_tools/github.py,sha256=a2OTPXS7kWOVA4zrZHynQDcsmEi4Pac5MfSjQOLePzA,5308
73
73
  flock/core/util/cli_helper.py,sha256=P3-lncS1J78MuPpDQ0D8qmfxMTCRxKkGdo9QRkzrp6A,49797
74
74
  flock/core/util/file_path_utils.py,sha256=Odf7uU32C-x1KNighbNERSiMtkzW4h8laABIoFK7A5M,6246
75
- flock/core/util/hydrator.py,sha256=6qNwOwCZB7r6y25BZ--0PGofrAlfMaXbDKFQeP5NLts,11196
75
+ flock/core/util/hydrator.py,sha256=z0kvqr4j3piExOb_T5EgATuNm77ZlqIKvLpt4PJusO8,10949
76
76
  flock/core/util/input_resolver.py,sha256=g9vDPdY4OH-G7qjas5ksGEHueokHGFPMoLOvC-ngeLo,5984
77
77
  flock/core/util/loader.py,sha256=j3q2qem5bFMP2SmMuYjb-ISxsNGNZd1baQmpvAnRUUk,2244
78
78
  flock/evaluators/declarative/declarative_evaluator.py,sha256=j3xCEOhKHMvYtI43K2uqqJk068Lw94ch8GtWOmmJX7g,4803
@@ -86,7 +86,6 @@ flock/modules/callback/callback_module.py,sha256=volGGgHtY19qj1wHR6m5a_hmXSbV3Ca
86
86
  flock/modules/memory/memory_module.py,sha256=bSkdFBW-Pp5ldHhXi8v4kfRM7zknfLR2fsOtbTosucI,14916
87
87
  flock/modules/memory/memory_parser.py,sha256=FLH7GL8XThvHiCMfX3eQH7Sz-f62fzhAUmO6_gaDI7U,4372
88
88
  flock/modules/memory/memory_storage.py,sha256=CNcLDMmvv0x7Z3YMKr6VveS_VCa7rKPw8l2d-XgqokA,27246
89
- flock/modules/output/output_module.py,sha256=tpNqkL8cB0cvikr1fmEJ-5E2SAeb-rYhht8IP90mEF0,7281
90
89
  flock/modules/performance/metrics_module.py,sha256=UD9OjY4-zAvauMD7YyDYqE1gyIhzpdr3JkBT8j9knxY,16790
91
90
  flock/modules/zep/zep_module.py,sha256=x7JG6O6xnwwum0RETIqKYbA3xzdcvX2aUuns0Cl0c2Q,6014
92
91
  flock/platform/docker_tools.py,sha256=fpA7-6rJBjPOUBLdQP4ny2QPgJ_042nmqRn5GtKnoYw,1445
@@ -440,8 +439,8 @@ flock/workflow/activities.py,sha256=eVZDnxGJl_quNO-UTV3YgvTV8LrRaHN3QDAA1ANKzac,
440
439
  flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
441
440
  flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
442
441
  flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
443
- flock_core-0.4.0b17.dist-info/METADATA,sha256=E4VmDMbJkqZ3CQCVQy3KFnWGYIW6xfLfHX-wKKZpbDU,21101
444
- flock_core-0.4.0b17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
445
- flock_core-0.4.0b17.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
446
- flock_core-0.4.0b17.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
447
- flock_core-0.4.0b17.dist-info/RECORD,,
442
+ flock_core-0.4.0b19.dist-info/METADATA,sha256=AxxdPGiZnMvkFqmHKNmVLN4FH07NWjUSPXHGhamhF54,12697
443
+ flock_core-0.4.0b19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
444
+ flock_core-0.4.0b19.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
445
+ flock_core-0.4.0b19.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
446
+ flock_core-0.4.0b19.dist-info/RECORD,,
@@ -1,194 +0,0 @@
1
- """Output formatting and display functionality for agents."""
2
-
3
- from typing import TYPE_CHECKING, Any
4
-
5
- from pydantic import Field
6
-
7
- from flock.core.context.context_vars import FLOCK_BATCH_SILENT_MODE
8
-
9
- if TYPE_CHECKING:
10
- from flock.core import FlockAgent
11
-
12
- from flock.core.context.context import FlockContext
13
- from flock.core.flock_module import FlockModule, FlockModuleConfig
14
- from flock.core.logging.formatters.themed_formatter import (
15
- ThemedAgentResultFormatter,
16
- )
17
- from flock.core.logging.formatters.themes import OutputTheme
18
- from flock.core.logging.logging import get_logger
19
-
20
- # from flock.core.logging.formatters.themes import OutputTheme
21
- # from flock.core.logging.logging import get_logger
22
- # from flock.core.serialization.json_encoder import FlockJSONEncoder
23
-
24
- logger = get_logger("module.output")
25
-
26
-
27
- class OutputModuleConfig(FlockModuleConfig):
28
- """Configuration for output formatting and display."""
29
-
30
- theme: OutputTheme = Field(
31
- default=OutputTheme.afterglow, description="Theme for output formatting"
32
- )
33
- render_table: bool = Field(
34
- default=False, description="Whether to render output as a table"
35
- )
36
- max_length: int = Field(
37
- default=1000, description="Maximum length for displayed output"
38
- )
39
- truncate_long_values: bool = Field(
40
- default=True, description="Whether to truncate long values in display"
41
- )
42
- show_metadata: bool = Field(
43
- default=True, description="Whether to show metadata like timestamps"
44
- )
45
- format_code_blocks: bool = Field(
46
- default=True,
47
- description="Whether to apply syntax highlighting to code blocks",
48
- )
49
- custom_formatters: dict[str, str] = Field(
50
- default_factory=dict,
51
- description="Custom formatters for specific output types",
52
- )
53
- no_output: bool = Field(
54
- default=False,
55
- description="Whether to suppress output",
56
- )
57
- print_context: bool = Field(
58
- default=False,
59
- description="Whether to print the context",
60
- )
61
-
62
-
63
- class OutputModule(FlockModule):
64
- """Module that handles output formatting and display."""
65
-
66
- name: str = "output"
67
- config: OutputModuleConfig = Field(
68
- default_factory=OutputModuleConfig, description="Output configuration"
69
- )
70
-
71
- def __init__(self, name: str, config: OutputModuleConfig):
72
- super().__init__(name=name, config=config)
73
- self._formatter = ThemedAgentResultFormatter(
74
- theme=self.config.theme,
75
- max_length=self.config.max_length,
76
- render_table=self.config.render_table,
77
- )
78
-
79
- def _format_value(self, value: Any, key: str) -> str:
80
- """Format a single value based on its type and configuration."""
81
- # Check for custom formatter
82
- if key in self.config.custom_formatters:
83
- formatter_name = self.config.custom_formatters[key]
84
- if hasattr(self, f"_format_{formatter_name}"):
85
- return getattr(self, f"_format_{formatter_name}")(value)
86
-
87
- # Default formatting based on type
88
- if isinstance(value, dict):
89
- return self._format_dict(value)
90
- elif isinstance(value, list):
91
- return self._format_list(value)
92
- elif isinstance(value, str) and self.config.format_code_blocks:
93
- return self._format_potential_code(value)
94
- else:
95
- return str(value)
96
-
97
- def _format_dict(self, d: dict[str, Any], indent: int = 0) -> str:
98
- """Format a dictionary with proper indentation."""
99
- lines = []
100
- for k, v in d.items():
101
- formatted_value = self._format_value(v, k)
102
- if (
103
- self.config.truncate_long_values
104
- and len(formatted_value) > self.config.max_length
105
- ):
106
- formatted_value = (
107
- formatted_value[: self.config.max_length] + "..."
108
- )
109
- lines.append(f"{' ' * indent}{k}: {formatted_value}")
110
- return "\n".join(lines)
111
-
112
- def _format_list(self, lst: list[Any]) -> str:
113
- """Format a list with proper indentation."""
114
- return "\n".join(f"- {self._format_value(item, '')}" for item in lst)
115
-
116
- def _format_potential_code(self, text: str) -> str:
117
- """Format text that might contain code blocks."""
118
- import re
119
-
120
- def replace_code_block(match):
121
- code = match.group(2)
122
- lang = match.group(1) if match.group(1) else ""
123
- # Here you could add syntax highlighting
124
- return f"```{lang}\n{code}\n```"
125
-
126
- # Replace code blocks with formatted versions
127
- text = re.sub(
128
- r"```(\w+)?\n(.*?)\n```", replace_code_block, text, flags=re.DOTALL
129
- )
130
- return text
131
-
132
- async def post_evaluate(
133
- self,
134
- agent: "FlockAgent",
135
- inputs: dict[str, Any],
136
- result: dict[str, Any],
137
- context: FlockContext | None = None,
138
- ) -> dict[str, Any]:
139
- """Format and display the output."""
140
- logger.debug("Formatting and displaying output")
141
-
142
- # Determine if output should be suppressed
143
- is_silent = self.config.no_output or (
144
- context and context.get_variable(FLOCK_BATCH_SILENT_MODE, False)
145
- )
146
-
147
- if is_silent:
148
- logger.debug("Output suppressed (config or batch silent mode).")
149
- return result # Skip console output
150
-
151
- logger.debug("Formatting and displaying output to console.")
152
-
153
- if self.config.print_context and context:
154
- # Add context snapshot if requested (be careful with large contexts)
155
- try:
156
- # Create a copy or select relevant parts to avoid modifying original result dict directly
157
- display_result = result.copy()
158
- display_result["context_snapshot"] = (
159
- context.to_dict()
160
- ) # Potential performance hit
161
- except Exception:
162
- display_result = result.copy()
163
- display_result["context_snapshot"] = (
164
- "[Error serializing context]"
165
- )
166
- result_to_display = display_result
167
- else:
168
- result_to_display = result
169
-
170
- if not hasattr(self, "_formatter") or self._formatter is None:
171
- self._formatter = ThemedAgentResultFormatter(
172
- theme=self.config.theme,
173
- max_length=self.config.max_length,
174
- render_table=self.config.render_table,
175
- wait_for_input=self.config.wait_for_input,
176
- )
177
- self._formatter.display_result(result_to_display, agent.name)
178
-
179
- return result # Return the original, unmodified result
180
-
181
- def update_theme(self, new_theme: OutputTheme) -> None:
182
- """Update the output theme."""
183
- self.config.theme = new_theme
184
- self._formatter = ThemedAgentResultFormatter(
185
- theme=self.config.theme,
186
- max_length=self.config.max_length,
187
- render_table=self.config.render_table,
188
- wait_for_input=self.config.wait_for_input,
189
- write_to_file=self.config.write_to_file,
190
- )
191
-
192
- def add_custom_formatter(self, key: str, formatter_name: str) -> None:
193
- """Add a custom formatter for a specific output key."""
194
- self.config.custom_formatters[key] = formatter_name