flock-core 0.5.0b8__py3-none-any.whl → 0.5.0b10__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.

@@ -2,7 +2,9 @@
2
2
  """Unified component implementations for Flock agents."""
3
3
 
4
4
  # Evaluation components
5
- from .evaluation.declarative_evaluation_component import DeclarativeEvaluationComponent
5
+ from .evaluation.declarative_evaluation_component import (
6
+ DeclarativeEvaluationComponent,
7
+ )
6
8
 
7
9
  # Routing components
8
10
  from .routing.conditional_routing_component import ConditionalRoutingComponent
@@ -15,10 +17,10 @@ from .utility.metrics_utility_component import MetricsUtilityComponent
15
17
  from .utility.output_utility_component import OutputUtilityComponent
16
18
 
17
19
  __all__ = [
18
- # Evaluation
19
- "DeclarativeEvaluationComponent",
20
20
  # Routing
21
21
  "ConditionalRoutingComponent",
22
+ # Evaluation
23
+ "DeclarativeEvaluationComponent",
22
24
  "DefaultRoutingComponent",
23
25
  "LLMRoutingComponent",
24
26
  # Utility
@@ -7,6 +7,7 @@ from typing import Any, TypeVar
7
7
  from pydantic import BaseModel, Field, create_model
8
8
 
9
9
  from flock.core.context.context import FlockContext
10
+
10
11
  # HandOffRequest removed - using agent.next_agent directly
11
12
 
12
13
  T = TypeVar("T", bound="AgentComponentConfig")
@@ -58,7 +59,7 @@ class AgentComponent(BaseModel, ABC):
58
59
  Components can specialize by:
59
60
  - EvaluationComponentBase: Implements evaluate_core() for agent intelligence
60
61
  - RoutingComponentBase: Implements determine_next_step() for workflow routing
61
- - UtilityComponentBase: Uses standard lifecycle hooks for cross-cutting concerns
62
+ - UtilityComponentBase: Uses standard lifecycle hooks for cross-cutting concerns
62
63
  """
63
64
 
64
65
  name: str = Field(
@@ -4,6 +4,7 @@ import logging
4
4
  import sqlite3
5
5
  from abc import ABC, abstractmethod
6
6
  from pathlib import Path
7
+ from typing import Any
7
8
 
8
9
  import aiosqlite
9
10
 
@@ -227,7 +228,7 @@ class SQLiteSharedLinkStore(SharedLinkStoreInterface):
227
228
  except sqlite3.Error as e:
228
229
  logger.error(f"SQLite error saving feedback {record.feedback_id}: {e}", exc_info=True)
229
230
  raise
230
- # flock/webapp/app/services/sharing_store.py ← replace only this class
231
+
231
232
 
232
233
  # ---------------------------------------------------------------------------
233
234
  # Azure Table + Blob implementation
@@ -366,14 +367,42 @@ class AzureTableSharedLinkStore(SharedLinkStoreInterface):
366
367
 
367
368
  # -------------------------------------------------------- save_feedback --
368
369
  async def save_feedback(self, record: FeedbackRecord) -> FeedbackRecord:
370
+ """Persist a feedback record. If a flock_definition is present, upload it as a blob and
371
+ store only a reference in the table row to avoid oversized entities (64 KiB limit).
372
+ """
369
373
  tbl_client = self.table_svc.get_table_client(self._FEEDBACK_TBL_NAME)
370
- entity = {
374
+
375
+ # Core entity fields (avoid dumping the full Pydantic model – too many columns / large value)
376
+ entity: dict[str, Any] = {
371
377
  "PartitionKey": "feedback",
372
378
  "RowKey": record.feedback_id,
373
- **record.model_dump(exclude={"feedback_id"}) # all other fields
379
+ "share_id": record.share_id,
380
+ "context_type": record.context_type,
381
+ "reason": record.reason,
382
+ "expected_response": record.expected_response,
383
+ "actual_response": record.actual_response,
384
+ "created_at": record.created_at.isoformat(),
374
385
  }
386
+ if record.flock_name is not None:
387
+ entity["flock_name"] = record.flock_name
388
+ if record.agent_name is not None:
389
+ entity["agent_name"] = record.agent_name
390
+
391
+ # ------------------------------------------------------------------ YAML → Blob
392
+ if record.flock_definition:
393
+ blob_name = f"{record.feedback_id}.yaml"
394
+ blob_client = self.blob_svc.get_blob_client(self._CONTAINER_NAME, blob_name)
395
+ # Overwrite=true so repeated feedback_id uploads (shouldn't happen) won't error
396
+ await blob_client.upload_blob(record.flock_definition,
397
+ overwrite=True,
398
+ content_type="text/yaml")
399
+ entity["flock_blob_name"] = blob_name # lightweight reference only
400
+
401
+ # ------------------------------------------------------------------ Table upsert
375
402
  await tbl_client.upsert_entity(entity)
376
- logger.info("Saved feedback %s", record.feedback_id)
403
+ logger.info("Saved feedback %s%s",
404
+ record.feedback_id,
405
+ f" → blob '{entity['flock_blob_name']}'" if "flock_blob_name" in entity else "")
377
406
  return record
378
407
 
379
408
 
@@ -0,0 +1,271 @@
1
+ Metadata-Version: 2.4
2
+ Name: flock-core
3
+ Version: 0.5.0b10
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: aiosqlite>=0.21.0
12
+ Requires-Dist: azure-data-tables>=12.7.0
13
+ Requires-Dist: chromadb>=0.6.3
14
+ Requires-Dist: cloudpickle>=3.1.1
15
+ Requires-Dist: croniter>=6.0.0
16
+ Requires-Dist: datasets>=3.2.0
17
+ Requires-Dist: devtools>=0.12.2
18
+ Requires-Dist: dspy==2.6.23
19
+ Requires-Dist: fastapi>=0.115.8
20
+ Requires-Dist: httpx>=0.28.1
21
+ Requires-Dist: litellm==1.69.3
22
+ Requires-Dist: loguru>=0.7.3
23
+ Requires-Dist: markdown2>=2.5.3
24
+ Requires-Dist: mcp>=1.7.1
25
+ Requires-Dist: msgpack>=1.1.0
26
+ Requires-Dist: neo4j>=5.28.1
27
+ Requires-Dist: openai==1.75.0
28
+ Requires-Dist: opentelemetry-api>=1.30.0
29
+ Requires-Dist: opentelemetry-exporter-jaeger-proto-grpc>=1.21.0
30
+ Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0
31
+ Requires-Dist: opentelemetry-exporter-otlp>=1.30.0
32
+ Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
33
+ Requires-Dist: opentelemetry-sdk>=1.30.0
34
+ Requires-Dist: opik>=1.7.26
35
+ Requires-Dist: pandas>=2.2.3
36
+ Requires-Dist: pillow>=10.4.0
37
+ Requires-Dist: prometheus-client>=0.21.1
38
+ Requires-Dist: psutil>=6.1.1
39
+ Requires-Dist: pydantic-settings>=2.7.1
40
+ Requires-Dist: pydantic==2.10.5
41
+ Requires-Dist: python-box>=7.3.2
42
+ Requires-Dist: python-decouple>=3.8
43
+ Requires-Dist: python-dotenv>=1.0.1
44
+ Requires-Dist: pyyaml>=6.0
45
+ Requires-Dist: questionary>=2.1.0
46
+ Requires-Dist: rich>=13.9.4
47
+ Requires-Dist: rouge-score>=0.1.2
48
+ Requires-Dist: sentence-transformers>=3.4.1
49
+ Requires-Dist: temporalio>=1.9.0
50
+ Requires-Dist: thefuzz>=0.22.1
51
+ Requires-Dist: tiktoken>=0.8.0
52
+ Requires-Dist: toml>=0.10.2
53
+ Requires-Dist: tqdm>=4.60.1
54
+ Requires-Dist: uvicorn>=0.34.0
55
+ Requires-Dist: wd-di>=0.2.14
56
+ Requires-Dist: websockets>=15.0.1
57
+ Provides-Extra: memory
58
+ Requires-Dist: matplotlib>=3.10.0; extra == 'memory'
59
+ Requires-Dist: mem0ai[graph]>=0.1.101; extra == 'memory'
60
+ Requires-Dist: zep-python>=2.0.2; extra == 'memory'
61
+ Description-Content-Type: text/markdown
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
+
79
+ ---
80
+
81
+
82
+ ## The Problem You Know Too Well
83
+
84
+ 🤯 **Prompt Hell**: Brittle 500-line prompts that break with every model update.
85
+ 💥 **System Failures**: One bad LLM response crashes your entire workflow
86
+ 🧪 **Testing Nightmares**: "How do I unit test a prompt?" (You don't.)
87
+ 🧪 **Measuring Quality**: "How do I know my prompts are close to optimal?" (You also don't.)
88
+ 📄 **Output Chaos**: Parsing unstructured LLM responses into reliable data
89
+ ⛓️ **Orchestration Limits**: Moving beyond simple chains and DAGs? Good luck
90
+ 🚀 **Production Gap**: Jupyter notebooks don't scale to enterprise systems
91
+
92
+ *After building dozens of AI systems for enterprise clients, we realized the tooling was fundamentally broken.*
93
+
94
+
95
+ **Build with agents, not against them.**
96
+
97
+
98
+ ## The Flock Solution
99
+
100
+ **What if you could just skip that 'prompt engineering' step?**
101
+
102
+ Flock is an agent framework for declarative AI workflows. You define what goes in and what should come out, the how is handled by the agent.
103
+ No brittle prompts. No guesswork. Just reliable, testable AI agents.
104
+
105
+
106
+ ✅ **Declarative Contracts**: Define inputs/outputs with Pydantic models. Flock handles the LLM complexity.
107
+ ⚡ **Built-in Resilience**: Automatic retries, state persistence, and workflow resumption via Temporal.io
108
+ 🧪 **Actually Testable**: Clear contracts make agents unit-testable like any other code
109
+ 🧪 **Optimal Quality**: Agents posses multiple self-optimization algorithms based on latest research
110
+ 🚀 **Dynamic Workflows**: Self-correcting loops, conditional routing, and intelligent decision-making
111
+ 🔧 **Zero-Config Production**: Deploy as REST APIs with one command. Scale without rewriting.
112
+
113
+ **Ready to see it in action?**
114
+
115
+ ## ⚡ Quick Start
116
+
117
+ ```python
118
+ from flock.core import Flock, FlockFactory
119
+
120
+ # 1. Create the main orchestrator
121
+ my_flock = Flock(model="openai/gpt-4.1")
122
+
123
+ # 2. Declaratively define an agent
124
+ brainstorm_agent = FlockFactory.create_default_agent(
125
+ name="idea_generator",
126
+ input="topic",
127
+ output="catchy_title, key_points"
128
+ )
129
+
130
+ # 3. Add the agent to the Flock
131
+ my_flock.add_agent(brainstorm_agent)
132
+
133
+ # 4. Run the agent!
134
+ input_data = {"topic": "The future of AI agents"}
135
+ result = my_flock.run(start_agent="idea_generator", input=input_data)
136
+
137
+ # The result is a Box object (dot-accessible dict)
138
+ print(f"Generated Title: {result.catchy_title}")
139
+ print(f"Key Points: {result.key_points}")
140
+ ```
141
+
142
+ **No 20-line prompt fiddling. Just structured output, every time.**
143
+
144
+ ![image](https://github.com/user-attachments/assets/37a897cb-910f-49fc-89d4-510a780ad775)
145
+
146
+ **Explore more examples →** [**Flock Showcase Repository**](https://github.com/whiteducksoftware/flock-showcase)
147
+
148
+
149
+
150
+ ## 💾 Installation - Use Flock in your project
151
+
152
+ Get started with the core Flock library:
153
+
154
+ ```bash
155
+ # Using uv (recommended)
156
+ uv pip install flock-core
157
+
158
+ # Using pip
159
+ pip install flock-core
160
+ ```
161
+
162
+ Extras: Install optional dependencies for specific features:
163
+
164
+ ```bash
165
+ # Flock tools and mcp server
166
+ uv pip install flock-mcp
167
+ ```
168
+
169
+ ## 🔑 Installation - Develop Flock
170
+
171
+ ```bash
172
+ git clone https://github.com/whiteducksoftware/flock.git
173
+ cd flock
174
+
175
+ # One-liner dev setup after cloning
176
+ pip install poethepoet && poe install
177
+ ```
178
+
179
+ Additional provided `poe` tasks and commands:
180
+
181
+ ```bash
182
+ poe install # Install the project
183
+ poe build # Build the project
184
+ poe docs # Serve the docs
185
+ poe format # Format the code
186
+ poe lint # Lint the code
187
+ ```
188
+
189
+ ## 🔑 Environment Setup
190
+
191
+ Flock uses environment variables (typically in a .env file) for configuration, especially API keys. Create a .env file in your project root:
192
+
193
+ ```bash
194
+ # .env - Example
195
+
196
+ # --- LLM Provider API Keys (Required by most examples) ---
197
+ # Add keys for providers you use (OpenAI, Anthropic, Gemini, Azure, etc.)
198
+ # Refer to litellm docs (https://docs.litellm.ai/docs/providers) for names
199
+ OPENAI_API_KEY="your-openai-api-key"
200
+ # ANTHROPIC_API_KEY="your-anthropic-api-key"
201
+
202
+ # --- Tool-Specific Keys (Optional) ---
203
+ # TAVILY_API_KEY="your-tavily-search-key"
204
+ # GITHUB_PAT="your-github-personal-access-token"
205
+
206
+ # --- Default Flock Settings (Optional) ---
207
+ DEFAULT_MODEL="openai/gpt-4o" # Default LLM if agent doesn't specify
208
+
209
+ # --- Flock CLI Settings (Managed by `flock settings`) ---
210
+ # SHOW_SECRETS="False"
211
+ # VARS_PER_PAGE="20"
212
+ ```
213
+
214
+ Be sure that the .env file is added to your .gitignore!
215
+
216
+
217
+ ## 🐤 New in Flock 0.5.0 `Kea` 🐤
218
+
219
+ Keas are one of the smartest birds in the world famous for figuring out multi-step puzzles, unlatching doors, and coordinating in small groups to get what it wants.
220
+
221
+ <Insert Kea Logo>
222
+
223
+ ### Self-optimizing agents
224
+
225
+ ### Everything you need to evaluate and optimize agents
226
+
227
+ ### Benchmarks
228
+
229
+ ### Smooth Jupyter experience
230
+
231
+ ### Multi-Threading and Thread Safety
232
+
233
+
234
+ --------------------------------
235
+
236
+ ## 📚 Examples & Tutorials
237
+
238
+ For a comprehensive set of examples, ranging from basic usage to complex projects and advanced features, please visit our dedicated showcase repository:
239
+
240
+ ➡️ [github.com/whiteducksoftware/flock-showcase](https://github.com/whiteducksoftware/flock-showcase) ⬅️
241
+
242
+ The showcase includes:
243
+
244
+ - Step-by-step guides for core concepts.
245
+ - Examples of tool usage, routing, memory, and more.
246
+ - Complete mini-projects demonstrating practical applications.
247
+
248
+ ## 📖 Documentation
249
+
250
+ Full documentation, including API references and conceptual explanations, can be found at:
251
+
252
+ ➡️ [whiteducksoftware.github.io/flock/](https://whiteducksoftware.github.io/flock/) ⬅️
253
+
254
+ ## 🤝 Contributing
255
+
256
+ We welcome contributions! Please see the CONTRIBUTING.md file (if available) or open an issue/pull request on GitHub.
257
+
258
+ Ways to contribute:
259
+
260
+ - Report bugs or suggest features.
261
+ - Improve documentation.
262
+ - Contribute new Modules, Evaluators, or Routers.
263
+ - Add examples to the flock-showcase repository.
264
+
265
+ ## 📜 License
266
+
267
+ Flock is licensed under the MIT License. See the LICENSE file for details.
268
+
269
+ ## 🏢 About
270
+
271
+ Flock is developed and maintained by white duck GmbH, your partner for cloud-native solutions and AI integration.
@@ -25,7 +25,7 @@ flock/cli/utils.py,sha256=JJrvM-1D2tbWkicrtkhOgRqVqYb0MdA2XtHYGOYuPRw,4644
25
25
  flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
26
26
  flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
27
27
  flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
28
- flock/components/__init__.py,sha256=ZyTU6-haElMddsgCiL426z9qw2W9AnuFKvKkP3FuVSQ,954
28
+ flock/components/__init__.py,sha256=qDcaP0O7_b5RlUEXluqwskpKCkhM73kSMeNXReze63M,963
29
29
  flock/components/evaluation/__init__.py,sha256=_M3UlRFeNN90fEny6byt5VdLDE5o5khbd0EPT0o9S9k,303
30
30
  flock/components/evaluation/declarative_evaluation_component.py,sha256=yxDv1g4ue5VsnLCEAEZepu4frh8eBwZVqTDogawyxTo,8597
31
31
  flock/components/routing/__init__.py,sha256=BH_pFm9T6bUuf8HH4byDJ0dO0fzEVHv9m-ghUdDVdm0,542
@@ -57,7 +57,7 @@ flock/core/api/run_store.py,sha256=bFodJvVyWogzoezVy0cOoWWU3MdEBXf_6_5sBqCRWps,9
57
57
  flock/core/api/runner.py,sha256=3izg6cVk1RoR1hDIDwMAO1gi3lnLcp8DPv7AnJBYx6A,1443
58
58
  flock/core/api/service.py,sha256=52JBZ8jw4xgkrnY1nGgKr8MvtVgKnBsTrGRtop_SLZQ,11369
59
59
  flock/core/component/__init__.py,sha256=84fXB3tlxio1bvjFw8UvL4_Kl6wcYZ3Nzwyuyc89k_U,450
60
- flock/core/component/agent_component_base.py,sha256=u3Sztd9J5Q-MoeuPs-d9s66mhJuXfTv2JSjsXeGuimc,10660
60
+ flock/core/component/agent_component_base.py,sha256=ifHGcXI-7Q0JEcLCCS8OBrYNmLiuznHiKBhX5QpgInM,10665
61
61
  flock/core/component/evaluation_component.py,sha256=IvhS6NgUTH-UWft42Cmk3hK03xGM87kYAmKlQcIcOfs,2016
62
62
  flock/core/component/routing_component.py,sha256=gXUpMAf5Ty831FAQ20EAiAW8OkX8jjhgq7yCj4hGEBU,2669
63
63
  flock/core/component/utility_component.py,sha256=05DTltnp8-xNGOPVpmKIxG8ry0VNB3PjojOzLZMyrI0,2322
@@ -495,7 +495,7 @@ flock/webapp/app/api/registry_viewer.py,sha256=IoInxJiRR0yFlecG_l2_eRc6l35RQQyED
495
495
  flock/webapp/app/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
496
496
  flock/webapp/app/services/flock_service.py,sha256=cuJezcNvrRiyQM2f6Nu62NAmcqJBpqLydml6zI0_OuI,14935
497
497
  flock/webapp/app/services/sharing_models.py,sha256=XeJk1akILV_1l-cIUaG8k_eYhjV3EWBCWZ2kpwbdImA,3609
498
- flock/webapp/app/services/sharing_store.py,sha256=Ogc2MWFS1FDu8GQ89txMP32DvWZ5NcJjQAv4mwEroYs,18121
498
+ flock/webapp/app/services/sharing_store.py,sha256=CAxnCHqpKhpX7bLMZnwSBjkpr5MVFmU1g1gZNNFKSJc,19670
499
499
  flock/webapp/app/templates/theme_mapper.html,sha256=z8ZY7nmk6PiUGzD_-px7wSXcEnuBM121rMq6u-2oaCo,14249
500
500
  flock/webapp/static/css/chat.css,sha256=Njc9gXfQzbXMrqtFJH2Yda-IQlwNPd2z4apXxzfA0sY,8169
501
501
  flock/webapp/static/css/components.css,sha256=WnicEHy3ptPzggKmyG9_oZp3X30EMJBUW3KEXaiUCUE,6018
@@ -549,8 +549,8 @@ flock/workflow/agent_execution_activity.py,sha256=CzTkbjGqrPoAbldaQOS_doesosDK9m
549
549
  flock/workflow/flock_workflow.py,sha256=ZhAF82ewNRY2vvDjNpXT1D9lCVQsLOSMTaZVzdcogJc,9674
550
550
  flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
551
551
  flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
552
- flock_core-0.5.0b8.dist-info/METADATA,sha256=lkwytkrKpZNR3QpvzHQz8VHyjxI7cuxqlicP5oxU7Jo,20703
553
- flock_core-0.5.0b8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
554
- flock_core-0.5.0b8.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
555
- flock_core-0.5.0b8.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
556
- flock_core-0.5.0b8.dist-info/RECORD,,
552
+ flock_core-0.5.0b10.dist-info/METADATA,sha256=jBfT5Gn8ynYzdelP_t8WQ0mNEWZ6Hmdjm7rHfuuqFgg,9911
553
+ flock_core-0.5.0b10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
554
+ flock_core-0.5.0b10.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
555
+ flock_core-0.5.0b10.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
556
+ flock_core-0.5.0b10.dist-info/RECORD,,
@@ -1,635 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: flock-core
3
- Version: 0.5.0b8
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: aiosqlite>=0.21.0
12
- Requires-Dist: azure-data-tables>=12.7.0
13
- Requires-Dist: chromadb>=0.6.3
14
- Requires-Dist: cloudpickle>=3.1.1
15
- Requires-Dist: croniter>=6.0.0
16
- Requires-Dist: datasets>=3.2.0
17
- Requires-Dist: devtools>=0.12.2
18
- Requires-Dist: dspy==2.6.23
19
- Requires-Dist: fastapi>=0.115.8
20
- Requires-Dist: httpx>=0.28.1
21
- Requires-Dist: litellm==1.69.3
22
- Requires-Dist: loguru>=0.7.3
23
- Requires-Dist: markdown2>=2.5.3
24
- Requires-Dist: mcp>=1.7.1
25
- Requires-Dist: msgpack>=1.1.0
26
- Requires-Dist: neo4j>=5.28.1
27
- Requires-Dist: openai==1.75.0
28
- Requires-Dist: opentelemetry-api>=1.30.0
29
- Requires-Dist: opentelemetry-exporter-jaeger-proto-grpc>=1.21.0
30
- Requires-Dist: opentelemetry-exporter-jaeger>=1.21.0
31
- Requires-Dist: opentelemetry-exporter-otlp>=1.30.0
32
- Requires-Dist: opentelemetry-instrumentation-logging>=0.51b0
33
- Requires-Dist: opentelemetry-sdk>=1.30.0
34
- Requires-Dist: opik>=1.7.26
35
- Requires-Dist: pandas>=2.2.3
36
- Requires-Dist: pillow>=10.4.0
37
- Requires-Dist: prometheus-client>=0.21.1
38
- Requires-Dist: psutil>=6.1.1
39
- Requires-Dist: pydantic-settings>=2.7.1
40
- Requires-Dist: pydantic==2.10.5
41
- Requires-Dist: python-box>=7.3.2
42
- Requires-Dist: python-decouple>=3.8
43
- Requires-Dist: python-dotenv>=1.0.1
44
- Requires-Dist: pyyaml>=6.0
45
- Requires-Dist: questionary>=2.1.0
46
- Requires-Dist: rich>=13.9.4
47
- Requires-Dist: rouge-score>=0.1.2
48
- Requires-Dist: sentence-transformers>=3.4.1
49
- Requires-Dist: temporalio>=1.9.0
50
- Requires-Dist: thefuzz>=0.22.1
51
- Requires-Dist: tiktoken>=0.8.0
52
- Requires-Dist: toml>=0.10.2
53
- Requires-Dist: tqdm>=4.60.1
54
- Requires-Dist: uvicorn>=0.34.0
55
- Requires-Dist: wd-di>=0.2.14
56
- Requires-Dist: websockets>=15.0.1
57
- Provides-Extra: memory
58
- Requires-Dist: matplotlib>=3.10.0; extra == 'memory'
59
- Requires-Dist: mem0ai[graph]>=0.1.101; extra == 'memory'
60
- Requires-Dist: zep-python>=2.0.2; extra == 'memory'
61
- Description-Content-Type: text/markdown
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
-
79
- ---
80
-
81
-
82
- ## The Problem You Know Too Well
83
-
84
- 🤯 **Prompt Hell**: Brittle 500-line prompts that break with every model update.
85
- 💥 **System Failures**: One bad LLM response crashes your entire workflow
86
- 🧪 **Testing Nightmares**: "How do I unit test a prompt?" (You don't.)
87
- 🧪 **Measuring Quality**: "How do I know my prompts are close to optimal?" (You also don't.)
88
- 📄 **Output Chaos**: Parsing unstructured LLM responses into reliable data
89
- ⛓️ **Orchestration Limits**: Moving beyond simple chains and DAGs? Good luck
90
- 🚀 **Production Gap**: Jupyter notebooks don't scale to enterprise systems
91
-
92
- *After building dozens of AI systems for enterprise clients, we realized the tooling was fundamentally broken.*
93
-
94
-
95
- **Build with agents, not against them.**
96
-
97
-
98
- ## The Flock Solution
99
-
100
- **What if you could just skip that 'prompt engineering' step?**
101
-
102
- Flock is an agent framework for declarative AI workflows. You define what goes in and what should come out, the how is handled by the agent.
103
- No brittle prompts. No guesswork. Just reliable, testable AI agents.
104
-
105
-
106
- ✅ **Declarative Contracts**: Define inputs/outputs with Pydantic models. Flock handles the LLM complexity.
107
- ⚡ **Built-in Resilience**: Automatic retries, state persistence, and workflow resumption via Temporal.io
108
- 🧪 **Actually Testable**: Clear contracts make agents unit-testable like any other code
109
- 🧪 **Optimal Quality**: Agents posses multiple self-optimization algorithms based on latest research
110
- 🚀 **Dynamic Workflows**: Self-correcting loops, conditional routing, and intelligent decision-making
111
- 🔧 **Zero-Config Production**: Deploy as REST APIs with one command. Scale without rewriting.
112
-
113
- **Ready to see it in action?**
114
-
115
- ## ⚡ Quick Start
116
-
117
- ```python
118
- from flock.core import Flock, FlockFactory
119
-
120
- # 1. Create the main orchestrator
121
- my_flock = Flock(model="openai/gpt-4o")
122
-
123
- # 2. Declaratively define an agent
124
- brainstorm_agent = FlockFactory.create_default_agent(
125
- name="idea_generator",
126
- input="topic",
127
- output="catchy_title, key_points"
128
- )
129
-
130
- # 3. Add the agent to the Flock
131
- my_flock.add_agent(brainstorm_agent)
132
-
133
- # 4. Run the agent!
134
- input_data = {"topic": "The future of AI agents"}
135
- result = my_flock.run(start_agent="idea_generator", input=input_data)
136
-
137
- # The result is a Box object (dot-accessible dict)
138
- print(f"Generated Title: {result.catchy_title}")
139
- print(f"Key Points: {result.key_points}")
140
- ```
141
-
142
- **No 20-line prompt fiddling. Just structured output, every time.**
143
-
144
- ![image](https://github.com/user-attachments/assets/37a897cb-910f-49fc-89d4-510a780ad775)
145
-
146
- **Explore more examples →** [**Flock Showcase Repository**](https://github.com/whiteducksoftware/flock-showcase)
147
-
148
- ## 📹 Video Demo
149
-
150
- https://github.com/user-attachments/assets/bdab4786-d532-459f-806a-024727164dcc
151
-
152
-
153
-
154
- ## 💾 Installation - Use Flock in your project
155
-
156
- Get started with the core Flock library:
157
-
158
- ```bash
159
- # Using uv (recommended)
160
- uv pip install flock-core
161
-
162
- # Using pip
163
- pip install flock-core
164
- ```
165
-
166
- Extras: Install optional dependencies for specific features:
167
-
168
- ```bash
169
- # Common tools (Tavily, Markdownify)
170
- uv pip install flock-core[all-tools]
171
-
172
- # All optional dependencies (including tools, docling, etc.)
173
- uv sync --all-extras
174
- ```
175
-
176
- ## 🔑 Installation - Develop Flock
177
-
178
- ```bash
179
- git clone https://github.com/whiteducksoftware/flock.git
180
- cd flock
181
-
182
- # One-liner dev setup after cloning
183
- pip install poethepoet && poe install
184
- ```
185
-
186
- Additional provided `poe` tasks and commands:
187
-
188
- ```bash
189
- poe install # Install the project
190
- poe build # Build the project
191
- poe docs # Serve the docs
192
- poe format # Format the code
193
- poe lint # Lint the code
194
- ```
195
-
196
- ## 🔑 Environment Setup
197
-
198
- Flock uses environment variables (typically in a .env file) for configuration, especially API keys. Create a .env file in your project root:
199
-
200
- ```bash
201
- # .env - Example
202
-
203
- # --- LLM Provider API Keys (Required by most examples) ---
204
- # Add keys for providers you use (OpenAI, Anthropic, Gemini, Azure, etc.)
205
- # Refer to litellm docs (https://docs.litellm.ai/docs/providers) for names
206
- OPENAI_API_KEY="your-openai-api-key"
207
- # ANTHROPIC_API_KEY="your-anthropic-api-key"
208
-
209
- # --- Tool-Specific Keys (Optional) ---
210
- # TAVILY_API_KEY="your-tavily-search-key"
211
- # GITHUB_PAT="your-github-personal-access-token"
212
-
213
- # --- Default Flock Settings (Optional) ---
214
- DEFAULT_MODEL="openai/gpt-4o" # Default LLM if agent doesn't specify
215
-
216
- # --- Flock CLI Settings (Managed by `flock settings`) ---
217
- # SHOW_SECRETS="False"
218
- # VARS_PER_PAGE="20"
219
- ```
220
-
221
- Be sure that the .env file is added to your .gitignore!
222
-
223
-
224
- ## 🐤 New in Flock 0.4.0 `Magpie` 🐤
225
- <p align="center">
226
- <img width="300" alt="image" src="https://github.com/user-attachments/assets/34c2fe2f-6dd2-498c-a826-1687cb158755" />
227
- </p>
228
-
229
- ### 0.4.5 - MCP Support - Declaratively connect to 1000s of different tools!
230
-
231
- Create a server
232
-
233
- ```python
234
- ws_fetch_server = FlockFactory.create_mcp_server(
235
- name="fetch_server",
236
- enable_tools_feature=True,
237
- connection_params=FlockFactory.WebsocketParams(
238
- url="ws://localhost:4001/message"
239
- ),
240
- ```
241
-
242
- Add it to Flock
243
-
244
- ```python
245
- flock = Flock(
246
- name="mcp_testbed",
247
- servers=[
248
- ws_fetch_server
249
- ]
250
- )
251
- ```
252
-
253
- And tell the flock agents which server to use
254
-
255
- ```python
256
- webcrawler_agent = FlockFactory.create_default_agent(
257
- name="webcrawler_agent",
258
- description="Expert for looking up and retrieving web content",
259
- input="query: str | User-Query, initial_url: Optional[str] | Optional url to start search from.",
260
- output="answer: str | Answer to user-query, page_url: str | The url of the page where the answer was found on, page_content: str | Markdown content of the page where the answer was found.",
261
- servers=[ws_fetch_server], # servers are passed here.
262
- )
263
- ```
264
-
265
- Done! The Flock agent has now access to every tool the server offers.
266
-
267
-
268
- ### 🚀 REST API – Deploy Flock Agents as REST API Endpoints
269
-
270
- Easily deploy your Flock agents as scalable REST API endpoints. Interact with your agent workflows via standard HTTP requests.
271
-
272
- The all-in-one `flock.serve()` method turns your Flock into a proper REST API!
273
-
274
- <img width="1135" alt="image" src="https://github.com/user-attachments/assets/95a58e96-d866-4fd1-aca3-c7635843503c" />
275
-
276
- Need custom endpoints to wrap abstract agent logic or add business logic? We've got you.
277
- Define them. Declaratively.
278
-
279
- ```python
280
- word_count_route = FlockEndpoint(
281
- path="/api/word_count",
282
- methods=["GET"],
283
- callback=word_count,
284
- query_model=WordCountParams,
285
- response_model=WordCountResponse,
286
- summary="Counts words in a text",
287
- description="Takes a text and returns the number of words in it.",
288
- )
289
-
290
- flock.serve(custom_endpoints=[img_url_route, word_count_route, yoda_route])
291
- ```
292
-
293
- <img width="1135" alt="image" src="https://github.com/user-attachments/assets/d9315648-ac10-4129-aca4-1cb4c8835672" />
294
-
295
- Want chat and UI too? Just turn them on.
296
-
297
- ```python
298
- flock.serve(ui=True, chat=True)
299
- ```
300
-
301
- ---
302
-
303
- ### 🖥️ Web UI – Test Flock Agents in the Browser
304
-
305
- Test and interact with your Flock agents directly in your browser using an integrated web interface.
306
-
307
- ![image](https://github.com/user-attachments/assets/5746ae82-757b-43a3-931d-56d19d39371a)
308
-
309
- Highlights of this feature-rich interface:
310
-
311
- * Run all your agents and agent flows
312
- * Chat with your agents
313
- * Create sharable links – these freeze agent config so testers can focus on evaluation
314
- * Send direct feedback – includes everything needed to reproduce issues
315
- * Switch modes – like standalone chat mode, which hides all but the chat
316
-
317
- <img width="1135" alt="image" src="https://github.com/user-attachments/assets/398337ee-e56e-4bce-8bd8-d258c261cb64" />
318
-
319
- And much, much more... All features are based on real-world client feedback and serve actual business needs.
320
-
321
- ---
322
-
323
- ### ⌨️ CLI Tool – Manage Flock Agents via Command Line
324
-
325
- Manage configurations, run agents, and inspect results – all from your terminal. A quick way to test and validate serialized flocks.
326
-
327
- ![image](https://github.com/user-attachments/assets/9370e7e8-94c3-4e26-8c7e-46ff2edd667a)
328
-
329
- ---
330
-
331
- ### 💾 Enhanced Serialization – Share, Deploy, and Run Flocks from YAML
332
-
333
- Define and share entire Flock configurations using readable YAML files. Perfect for versioning, deployment, and portability.
334
-
335
- Take note how even custom types like `FantasyCharacter` are serialized so the target system doesn't even need your code! Everything portable!
336
-
337
- ```yaml
338
- name: pydantic_example
339
- model: openai/gpt-4o
340
- enable_temporal: false
341
- show_flock_banner: false
342
- temporal_start_in_process_worker: true
343
- agents:
344
- character_agent:
345
- name: character_agent
346
- model: openai/gpt-4o
347
- description: Generates fantasy RPG character profiles for a specified number of
348
- characters.
349
- input: 'number_of_characters: int | The number of fantasy character profiles to
350
- generate.'
351
- output: 'character_list: list[FantasyCharacter] | A list containing the generated
352
- character profiles.'
353
- write_to_file: false
354
- wait_for_input: false
355
- evaluator:
356
- name: default
357
- config:
358
- model: openai/gpt-4o
359
- use_cache: true
360
- temperature: 0.8
361
- max_tokens: 8192
362
- stream: false
363
- include_thought_process: false
364
- kwargs: {}
365
- type: DeclarativeEvaluator
366
- modules:
367
- output:
368
- name: output
369
- config:
370
- enabled: true
371
- theme: abernathy
372
- render_table: false
373
- max_length: 1000
374
- truncate_long_values: true
375
- show_metadata: true
376
- format_code_blocks: true
377
- custom_formatters: {}
378
- no_output: false
379
- print_context: false
380
- type: OutputModule
381
- metrics:
382
- name: metrics
383
- config:
384
- enabled: true
385
- collect_timing: true
386
- collect_memory: true
387
- collect_token_usage: true
388
- collect_cpu: true
389
- storage_type: json
390
- metrics_dir: metrics/
391
- aggregation_interval: 1h
392
- retention_days: 30
393
- alert_on_high_latency: true
394
- latency_threshold_ms: 30000
395
- type: MetricsModule
396
- types:
397
- FantasyCharacter:
398
- module_path: __main__
399
- type: pydantic.BaseModel
400
- schema:
401
- description: 'Data model for fantasy RPG character information.
402
-
403
- Docstrings and Field descriptions can help guide the LLM.'
404
- properties:
405
- name:
406
- description: A creative fantasy character name.
407
- title: Name
408
- type: string
409
- race:
410
- description: The character's race.
411
- enum:
412
- - human
413
- - elf
414
- - dwarf
415
- - orc
416
- - halfling
417
- title: Race
418
- type: string
419
- class_type:
420
- description: The character's class.
421
- enum:
422
- - warrior
423
- - mage
424
- - rogue
425
- - cleric
426
- - ranger
427
- title: Class Type
428
- type: string
429
- level:
430
- description: Character level
431
- title: Level
432
- type: integer
433
- strength:
434
- description: Strength stat
435
- title: Strength
436
- type: integer
437
- dexterity:
438
- description: Dexterity stat
439
- title: Dexterity
440
- type: integer
441
- constitution:
442
- description: Constitution stat
443
- title: Constitution
444
- type: integer
445
- intelligence:
446
- description: Intelligence stat
447
- title: Intelligence
448
- type: integer
449
- wisdom:
450
- description: Wisdom stat
451
- title: Wisdom
452
- type: integer
453
- charisma:
454
- description: Charisma stat
455
- title: Charisma
456
- type: integer
457
- weapons:
458
- description: A list of weapons the character carries.
459
- items:
460
- type: string
461
- title: Weapons
462
- type: array
463
- backstory:
464
- description: A brief, engaging backstory (2-3 sentences).
465
- title: Backstory
466
- type: string
467
- motivation:
468
- description: The character's motivation for their adventuring.
469
- title: Motivation
470
- type: string
471
- alignment:
472
- description: Character's moral alignment
473
- title: Alignment
474
- type: string
475
- required:
476
- - name
477
- - race
478
- - class_type
479
- - level
480
- - strength
481
- - dexterity
482
- - constitution
483
- - intelligence
484
- - wisdom
485
- - charisma
486
- - weapons
487
- - backstory
488
- - motivation
489
- - alignment
490
- type: object
491
- components:
492
- DeclarativeEvaluator:
493
- type: flock_component
494
- module_path: flock.evaluators.declarative.declarative_evaluator
495
- file_path: src\\flock\\evaluators\\declarative\\declarative_evaluator.py
496
- description: Evaluator that uses DSPy for generation.
497
- OutputModule:
498
- type: flock_component
499
- module_path: flock.modules.output.output_module
500
- file_path: src\\flock\\modules\\output\\output_module.py
501
- description: Module that handles output formatting and display.
502
- MetricsModule:
503
- type: flock_component
504
- module_path: flock.modules.performance.metrics_module
505
- file_path: src\\flock\\modules\\performance\\metrics_module.py
506
- description: Module for collecting and analyzing agent performance metrics.
507
- dependencies:
508
- - pydantic>=2.0.0
509
- - flock-core>=0.4.0
510
- metadata:
511
- path_type: relative
512
- flock_version: 0.4.0
513
-
514
- ```
515
-
516
- Why is text-based serialization cool? Because agents can manipulate their own config – go wild with meta agents and experiments.
517
-
518
- ---
519
-
520
- ### 🌀 New Execution Flows – Batch and Evaluation Modes
521
-
522
- Run Flock in batch mode to process multiple inputs or in evaluation mode to benchmark agents against question/answer pairs.
523
-
524
- ```python
525
- batch_data = [
526
- {"topic": "Robot Kittens", "audience": "Tech Enthusiasts"},
527
- {"topic": "AI in Gardening", "audience": "Homeowners"},
528
- ...
529
- ]
530
-
531
- static_data = {"number_of_slides": 6}
532
-
533
- silent_results = flock.run_batch(
534
- start_agent=presentation_agent,
535
- batch_inputs=batch_data,
536
- static_inputs=static_data,
537
- parallel=True,
538
- max_workers=5,
539
- silent_mode=True,
540
- return_errors=True,
541
- write_to_csv=".flock/batch_results.csv",
542
- )
543
- ```
544
-
545
- Supports CSV in and out. Combine with `.evaluate()` to benchmark Flock with known Q/A sets.
546
-
547
- ---
548
-
549
- ### ⏱️ First-Class Temporal Integration
550
-
551
- Flock 0.4.0 brings seamless integration with Temporal.io. Build production-grade, reliable, and scalable agent workflows.
552
-
553
- ```python
554
- flock = Flock(
555
- enable_temporal=True,
556
- temporal_config=TemporalWorkflowConfig(
557
- task_queue="flock-test-queue",
558
- workflow_execution_timeout=timedelta(minutes=10),
559
- default_activity_retry_policy=TemporalRetryPolicyConfig(
560
- maximum_attempts=2
561
- ),
562
- ),
563
- )
564
- ```
565
-
566
- Just set a flag. Add your constraints. Now you've got retry policies, timeout control, and error handling baked in.
567
-
568
- ---
569
-
570
- ### ✨ Utility – @flockclass Hydrator
571
-
572
- Flock also adds conveniences. With `@flockclass`, you can turn any Pydantic model into a self-hydrating agent.
573
-
574
- ```python
575
- from pydantic import BaseModel
576
- from flock.util.hydrator import flockclass
577
-
578
- @flockclass(model="openai/gpt-4o")
579
- class CharacterIdea(BaseModel):
580
- name: str
581
- char_class: str
582
- race: str
583
- backstory_hook: str | None = None
584
- personality_trait: str | None = None
585
-
586
- async def create_character():
587
- char = CharacterIdea(name="Gorok", char_class="Barbarian", race="Orc")
588
- print(f"Before Hydration: {char}")
589
-
590
- hydrated_char = await char.hydrate()
591
-
592
- print(f"\nAfter Hydration: {hydrated_char}")
593
- print(f"Backstory Hook: {hydrated_char.backstory_hook}")
594
- ```
595
-
596
-
597
-
598
- --------------------------------
599
-
600
- ## 📚 Examples & Tutorials
601
-
602
- For a comprehensive set of examples, ranging from basic usage to complex projects and advanced features, please visit our dedicated showcase repository:
603
-
604
- ➡️ [github.com/whiteducksoftware/flock-showcase](https://github.com/whiteducksoftware/flock-showcase) ⬅️
605
-
606
- The showcase includes:
607
-
608
- - Step-by-step guides for core concepts.
609
- - Examples of tool usage, routing, memory, and more.
610
- - Complete mini-projects demonstrating practical applications.
611
-
612
- ## 📖 Documentation
613
-
614
- Full documentation, including API references and conceptual explanations, can be found at:
615
-
616
- ➡️ [whiteducksoftware.github.io/flock/](https://whiteducksoftware.github.io/flock/) ⬅️
617
-
618
- ## 🤝 Contributing
619
-
620
- We welcome contributions! Please see the CONTRIBUTING.md file (if available) or open an issue/pull request on GitHub.
621
-
622
- Ways to contribute:
623
-
624
- - Report bugs or suggest features.
625
- - Improve documentation.
626
- - Contribute new Modules, Evaluators, or Routers.
627
- - Add examples to the flock-showcase repository.
628
-
629
- ## 📜 License
630
-
631
- Flock is licensed under the MIT License. See the LICENSE file for details.
632
-
633
- ## 🏢 About
634
-
635
- Flock is developed and maintained by white duck GmbH, your partner for cloud-native solutions and AI integration.