flock-core 0.4.0b50__py3-none-any.whl → 0.4.1__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.

Files changed (34) hide show
  1. flock/adapter/__init__.py +14 -0
  2. flock/adapter/azure_adapter.py +68 -0
  3. flock/adapter/chroma_adapter.py +73 -0
  4. flock/adapter/faiss_adapter.py +97 -0
  5. flock/adapter/pinecone_adapter.py +51 -0
  6. flock/adapter/vector_base.py +47 -0
  7. flock/config.py +1 -1
  8. flock/core/context/context.py +20 -0
  9. flock/core/flock.py +71 -91
  10. flock/core/flock_agent.py +58 -3
  11. flock/core/flock_module.py +5 -0
  12. flock/di.py +41 -0
  13. flock/modules/enterprise_memory/README.md +99 -0
  14. flock/modules/enterprise_memory/enterprise_memory_module.py +526 -0
  15. flock/modules/mem0/mem0_module.py +79 -16
  16. flock/modules/mem0_async/async_mem0_module.py +126 -0
  17. flock/modules/memory/memory_module.py +28 -8
  18. flock/modules/performance/metrics_module.py +24 -1
  19. flock/modules/zep/__init__.py +1 -0
  20. flock/modules/zep/zep_module.py +192 -0
  21. flock/webapp/app/api/execution.py +79 -2
  22. flock/webapp/app/chat.py +83 -3
  23. flock/webapp/app/services/sharing_models.py +38 -0
  24. flock/webapp/app/services/sharing_store.py +60 -1
  25. flock/webapp/static/css/chat.css +2 -0
  26. flock/webapp/templates/partials/_chat_messages.html +50 -4
  27. flock/webapp/templates/partials/_results_display.html +39 -0
  28. {flock_core-0.4.0b50.dist-info → flock_core-0.4.1.dist-info}/METADATA +6 -4
  29. {flock_core-0.4.0b50.dist-info → flock_core-0.4.1.dist-info}/RECORD +33 -22
  30. flock/modules/mem0graph/mem0_graph_module.py +0 -63
  31. /flock/modules/{mem0graph → mem0_async}/__init__.py +0 -0
  32. {flock_core-0.4.0b50.dist-info → flock_core-0.4.1.dist-info}/WHEEL +0 -0
  33. {flock_core-0.4.0b50.dist-info → flock_core-0.4.1.dist-info}/entry_points.txt +0 -0
  34. {flock_core-0.4.0b50.dist-info → flock_core-0.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -26,6 +26,7 @@ from flock.core.util.spliter import parse_schema
26
26
  from flock.webapp.app.dependencies import (
27
27
  get_flock_instance,
28
28
  get_optional_flock_instance,
29
+ get_shared_link_store,
29
30
  )
30
31
 
31
32
  # Service function now takes app_state
@@ -33,6 +34,7 @@ from flock.webapp.app.services.flock_service import (
33
34
  run_current_flock_service,
34
35
  # get_current_flock_instance IS NO LONGER IMPORTED
35
36
  )
37
+ from flock.webapp.app.services.sharing_store import SharedLinkStoreInterface
36
38
 
37
39
  router = APIRouter()
38
40
  BASE_DIR = Path(__file__).resolve().parent.parent.parent
@@ -155,7 +157,16 @@ async def htmx_run_flock(
155
157
 
156
158
  return templates.TemplateResponse(
157
159
  "partials/_results_display.html",
158
- {"request": request, "result": result_data, "result_raw_json": result_data_raw_json_str} # Pass both
160
+ {
161
+ "request": request,
162
+ "result": result_data,
163
+ "result_raw_json": result_data_raw_json_str,
164
+ "feedback_endpoint": "/ui/api/flock/htmx/feedback",
165
+ "share_id": None,
166
+ "flock_name": current_flock_from_state.name,
167
+ "agent_name": start_agent_name,
168
+ "flock_definition": current_flock_from_state.to_yaml(),
169
+ }
159
170
  )
160
171
 
161
172
 
@@ -218,5 +229,71 @@ async def htmx_run_shared_flock(
218
229
 
219
230
  return templates.TemplateResponse(
220
231
  "partials/_results_display.html",
221
- {"request": request, "result": result_data, "result_raw_json": result_data_raw_json_str} # Pass both
232
+ {
233
+ "request": request,
234
+ "result": result_data,
235
+ "result_raw_json": result_data_raw_json_str,
236
+ "feedback_endpoint": "/ui/api/flock/htmx/feedback-shared",
237
+ "share_id": share_id,
238
+ "flock_name": temp_flock.name,
239
+ "agent_name": start_agent_name,
240
+ "flock_definition": temp_flock.to_yaml(),
241
+ }
242
+ )
243
+
244
+ # --- Feedback endpoints ---
245
+ @router.post("/htmx/feedback", response_class=HTMLResponse)
246
+ async def htmx_submit_feedback(
247
+ request: Request,
248
+ reason: str = Form(...),
249
+ expected_response: str | None = Form(None),
250
+ actual_response: str | None = Form(None),
251
+ flock_name: str | None = Form(None),
252
+ agent_name: str | None = Form(None),
253
+ flock_definition: str | None = Form(None),
254
+ store: SharedLinkStoreInterface = Depends(get_shared_link_store),
255
+ ):
256
+ from uuid import uuid4
257
+
258
+ from flock.webapp.app.services.sharing_models import FeedbackRecord
259
+
260
+ record = FeedbackRecord(
261
+ feedback_id=uuid4().hex,
262
+ share_id=None,
263
+ context_type="agent_run",
264
+ reason=reason,
265
+ expected_response=expected_response,
266
+ actual_response=actual_response,
267
+ flock_name=flock_name,
268
+ agent_name=agent_name,
269
+ flock_definition=flock_definition,
270
+ )
271
+ await store.save_feedback(record)
272
+ return HTMLResponse("<p>🙏 Feedback received – thank you!</p>")
273
+
274
+
275
+ @router.post("/htmx/feedback-shared", response_class=HTMLResponse)
276
+ async def htmx_submit_feedback_shared(
277
+ request: Request,
278
+ share_id: str = Form(...),
279
+ reason: str = Form(...),
280
+ expected_response: str | None = Form(None),
281
+ actual_response: str | None = Form(None),
282
+ flock_definition: str | None = Form(None),
283
+ store: SharedLinkStoreInterface = Depends(get_shared_link_store),
284
+ ):
285
+ from uuid import uuid4
286
+
287
+ from flock.webapp.app.services.sharing_models import FeedbackRecord
288
+
289
+ record = FeedbackRecord(
290
+ feedback_id=uuid4().hex,
291
+ share_id=share_id,
292
+ context_type="agent_run",
293
+ reason=reason,
294
+ expected_response=expected_response,
295
+ actual_response=actual_response,
296
+ flock_definition=flock_definition,
222
297
  )
298
+ await store.save_feedback(record)
299
+ return HTMLResponse("<p>🙏 Feedback received for shared run – thank you!</p>")
flock/webapp/app/chat.py CHANGED
@@ -14,7 +14,10 @@ from flock.core.flock import Flock
14
14
  from flock.core.logging.logging import get_logger
15
15
  from flock.webapp.app.dependencies import get_shared_link_store
16
16
  from flock.webapp.app.main import get_base_context_web, templates
17
- from flock.webapp.app.services.sharing_models import SharedLinkConfig
17
+ from flock.webapp.app.services.sharing_models import (
18
+ FeedbackRecord,
19
+ SharedLinkConfig,
20
+ )
18
21
  from flock.webapp.app.services.sharing_store import SharedLinkStoreInterface
19
22
 
20
23
  router = APIRouter()
@@ -224,7 +227,15 @@ async def chat_send(request: Request, message: str = Form(...)):
224
227
  # If even echo should be markdown, remove is_error=True here and let it pass through. For now, plain.
225
228
 
226
229
  duration_ms = int((datetime.now() - start_time).total_seconds() * 1000)
227
- history.append({"role": "bot", "text": bot_text, "timestamp": current_time, "agent": bot_agent or "echo", "duration_ms": duration_ms})
230
+ history.append({
231
+ "role": "bot",
232
+ "text": bot_text,
233
+ "timestamp": current_time,
234
+ "agent": bot_agent or "echo",
235
+ "duration_ms": duration_ms,
236
+ "raw_json": original_bot_text if 'original_bot_text' in locals() else bot_text,
237
+ "flock_yaml": getattr(flock_inst, 'to_yaml', lambda: "")()
238
+ })
228
239
  # Return updated history partial
229
240
  return templates.TemplateResponse(
230
241
  "partials/_chat_messages.html",
@@ -516,9 +527,78 @@ async def chat_send_shared(
516
527
  bot_text = f"Shared Echo: {message}"
517
528
 
518
529
  duration_ms = int((datetime.now() - start_time).total_seconds() * 1000)
519
- history.append({"role": "bot", "text": bot_text, "timestamp": current_time, "agent": bot_agent or "shared-echo", "duration_ms": duration_ms})
530
+ history.append({
531
+ "role": "bot",
532
+ "text": bot_text,
533
+ "timestamp": current_time,
534
+ "agent": bot_agent or "shared-echo",
535
+ "duration_ms": duration_ms,
536
+ "raw_json": original_bot_text if 'original_bot_text' in locals() else bot_text,
537
+ "flock_yaml": getattr(flock_inst, 'to_yaml', lambda: "")()
538
+ })
520
539
 
521
540
  return templates.TemplateResponse(
522
541
  "partials/_chat_messages.html",
523
542
  {"request": request, "history": history, "now": datetime.now}
524
543
  )
544
+
545
+ # ---------------- Feedback endpoints ----------------
546
+ @router.post("/chat/htmx/feedback", response_class=HTMLResponse, include_in_schema=False)
547
+ async def chat_feedback(request: Request,
548
+ reason: str = Form(...),
549
+ expected_response: str | None = Form(None),
550
+ actual_response: str | None = Form(None),
551
+ flock_definition: str | None = Form(None),
552
+ agent_name: str | None = Form(None),
553
+ store: SharedLinkStoreInterface = Depends(get_shared_link_store)):
554
+ from uuid import uuid4
555
+ rec = FeedbackRecord(
556
+ feedback_id=uuid4().hex,
557
+ share_id=None,
558
+ context_type="chat",
559
+ reason=reason,
560
+ expected_response=expected_response,
561
+ actual_response=actual_response,
562
+ flock_definition=flock_definition,
563
+ agent_name=agent_name,
564
+ )
565
+ await store.save_feedback(rec)
566
+ toast_event = {
567
+ "showGlobalToast": {
568
+ "message": "Feedback received! Thanks",
569
+ "type": "success"
570
+ }
571
+ }
572
+ headers = {"HX-Trigger": json.dumps(toast_event)}
573
+ return Response(status_code=204, headers=headers)
574
+
575
+
576
+ @router.post("/chat/htmx/feedback-shared", response_class=HTMLResponse, include_in_schema=False)
577
+ async def chat_feedback_shared(request: Request,
578
+ share_id: str = Form(...),
579
+ reason: str = Form(...),
580
+ expected_response: str | None = Form(None),
581
+ actual_response: str | None = Form(None),
582
+ flock_definition: str | None = Form(None),
583
+ agent_name: str | None = Form(None),
584
+ store: SharedLinkStoreInterface = Depends(get_shared_link_store)):
585
+ from uuid import uuid4
586
+ rec = FeedbackRecord(
587
+ feedback_id=uuid4().hex,
588
+ share_id=share_id,
589
+ context_type="chat",
590
+ reason=reason,
591
+ expected_response=expected_response,
592
+ actual_response=actual_response,
593
+ flock_definition=flock_definition,
594
+ agent_name=agent_name,
595
+ )
596
+ await store.save_feedback(rec)
597
+ toast_event = {
598
+ "showGlobalToast": {
599
+ "message": "Feedback received! Thanks",
600
+ "type": "success"
601
+ }
602
+ }
603
+ headers = {"HX-Trigger": json.dumps(toast_event)}
604
+ return Response(status_code=204, headers=headers)
@@ -41,3 +41,41 @@ class SharedLinkConfig(BaseModel):
41
41
  ]
42
42
  }
43
43
  }
44
+
45
+ # -----------------------------------------------------------
46
+ # Feedback model (user ratings / corrections)
47
+ # -----------------------------------------------------------
48
+
49
+
50
+ class FeedbackRecord(BaseModel):
51
+ """A user-submitted piece of feedback for an agent run or chat turn."""
52
+
53
+ feedback_id: str = Field(..., description="Unique identifier for this feedback entry.")
54
+ share_id: str | None = Field(None, description="If the feedback refers to a shared link, its ID; otherwise None.")
55
+ context_type: str = Field(
56
+ default="agent_run",
57
+ description="Where the feedback originates (agent_run | chat | other)",
58
+ )
59
+ reason: str = Field(..., description="User-supplied reason / comment.")
60
+ expected_response: str | None = Field(
61
+ None,
62
+ description="Desired or corrected response in JSON or plain text.",
63
+ )
64
+ actual_response: str | None = Field(
65
+ None,
66
+ description="Original response shown to the user (optional, for context).",
67
+ )
68
+ created_at: datetime = Field(default_factory=datetime.utcnow)
69
+ # When share_id is None store explicit target identifiers
70
+ flock_name: str | None = Field(
71
+ None,
72
+ description="Name of the flock that produced the result when no share_id is used.",
73
+ )
74
+ agent_name: str | None = Field(
75
+ None,
76
+ description="Name of the agent or chat involved in the feedback.",
77
+ )
78
+ flock_definition: str | None = Field(
79
+ None,
80
+ description="Full YAML definition of the flock when feedback was submitted.",
81
+ )
@@ -5,7 +5,10 @@ from pathlib import Path
5
5
 
6
6
  import aiosqlite
7
7
 
8
- from flock.webapp.app.services.sharing_models import SharedLinkConfig
8
+ from flock.webapp.app.services.sharing_models import (
9
+ FeedbackRecord,
10
+ SharedLinkConfig,
11
+ )
9
12
 
10
13
  # Get a logger instance
11
14
  logger = logging.getLogger(__name__)
@@ -33,6 +36,12 @@ class SharedLinkStoreInterface(ABC):
33
36
  """Deletes a shared link configuration by its ID. Returns True if deleted, False otherwise."""
34
37
  pass
35
38
 
39
+ # Feedback
40
+ @abstractmethod
41
+ async def save_feedback(self, record: FeedbackRecord):
42
+ """Persist a feedback record."""
43
+ pass
44
+
36
45
  class SQLiteSharedLinkStore(SharedLinkStoreInterface):
37
46
  """SQLite implementation for storing and retrieving shared link configurations."""
38
47
 
@@ -76,6 +85,25 @@ class SQLiteSharedLinkStore(SharedLinkStoreInterface):
76
85
  else:
77
86
  raise # Re-raise if it's a different operational error
78
87
 
88
+ # Feedback table
89
+ await db.execute(
90
+ """
91
+ CREATE TABLE IF NOT EXISTS feedback (
92
+ feedback_id TEXT PRIMARY KEY,
93
+ share_id TEXT,
94
+ context_type TEXT NOT NULL,
95
+ reason TEXT NOT NULL,
96
+ expected_response TEXT,
97
+ actual_response TEXT,
98
+ flock_name TEXT,
99
+ agent_name TEXT,
100
+ flock_definition TEXT,
101
+ created_at TEXT NOT NULL,
102
+ FOREIGN KEY(share_id) REFERENCES shared_links(share_id)
103
+ )
104
+ """
105
+ )
106
+
79
107
  await db.commit()
80
108
  logger.info(f"Database initialized and shared_links table schema ensured at {self.db_path}")
81
109
  except sqlite3.Error as e:
@@ -154,3 +182,34 @@ class SQLiteSharedLinkStore(SharedLinkStoreInterface):
154
182
  except sqlite3.Error as e:
155
183
  logger.error(f"SQLite error deleting config for ID {share_id}: {e}", exc_info=True)
156
184
  return False # Or raise
185
+
186
+ # ----------------------- Feedback methods -----------------------
187
+
188
+ async def save_feedback(self, record: FeedbackRecord) -> FeedbackRecord:
189
+ """Persist a feedback record to SQLite."""
190
+ try:
191
+ async with aiosqlite.connect(self.db_path) as db:
192
+ await db.execute(
193
+ """INSERT INTO feedback (
194
+ feedback_id, share_id, context_type, reason,
195
+ expected_response, actual_response, flock_name, agent_name, flock_definition, created_at
196
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
197
+ (
198
+ record.feedback_id,
199
+ record.share_id,
200
+ record.context_type,
201
+ record.reason,
202
+ record.expected_response,
203
+ record.actual_response,
204
+ record.flock_name,
205
+ record.agent_name,
206
+ record.flock_definition,
207
+ record.created_at.isoformat(),
208
+ ),
209
+ )
210
+ await db.commit()
211
+ logger.info(f"Saved feedback {record.feedback_id} (share={record.share_id})")
212
+ return record
213
+ except sqlite3.Error as e:
214
+ logger.error(f"SQLite error saving feedback {record.feedback_id}: {e}", exc_info=True)
215
+ raise
@@ -39,6 +39,8 @@ body.chat-page {
39
39
  background-position: 0 0, 10px 10px;
40
40
  }
41
41
 
42
+
43
+
42
44
  .bubble {
43
45
  position: relative;
44
46
  padding: 0.75rem 1rem;
@@ -5,9 +5,55 @@
5
5
  <span class="chat-timestamp">{{ entry.timestamp|default(now().strftime('%H:%M')) }}</span>
6
6
  </div>
7
7
  {% else %}
8
- <div class="bubble bot">
9
- {{ entry.text | safe }}
10
- <span class="chat-timestamp">{{ entry.timestamp|default(now().strftime('%H:%M')) }}{% if entry.agent %} - {{ entry.agent }}{% endif %}{% if entry.duration_ms is defined %} - {{ entry.duration_ms }}ms{% endif %}</span>
8
+ <div class="bubble bot" x-data="{showForm:false}">
9
+ <!-- Bubble content (visible when feedback form hidden) -->
10
+ <div x-show="!showForm">
11
+ <div>
12
+ {{ entry.text | safe }}
13
+ <span class="chat-timestamp">
14
+ {{ entry.timestamp|default(now().strftime('%H:%M')) }}{% if entry.agent %} - {{ entry.agent }}{% endif %}{% if entry.duration_ms is defined %} - {{ entry.duration_ms }}ms - {% endif %}
15
+ <!-- hidden meta form (used by thumbs links) -->
16
+ <form class="feedback-meta" style="display:none">
17
+ {% if share_id %}<input type="hidden" name="share_id" value="{{ share_id }}">{% endif %}
18
+ <input type="hidden" name="flock_definition" value="{{ entry.flock_yaml | replace('"', '&quot;') }}">
19
+ <input type="hidden" name="agent_name" value="{{ entry.agent }}">
20
+ <input type="hidden" name="actual_response" value='{{ entry.raw_json | replace("'", "&#39;") }}'>
21
+ <input type="hidden" name="reason" value="positive">
22
+ </form>
23
+
24
+ <a href="#"
25
+ hx-post="{% if share_id %}/chat/htmx/feedback-shared{% else %}/chat/htmx/feedback{% endif %}"
26
+ hx-include="closest .feedback-meta"
27
+ hx-target="closest .bubble"
28
+ hx-swap="innerHTML"
29
+ title="Looks good!" class="feedback-link">👍</a>
30
+ -
31
+ <a href="#" @click.prevent="showForm=true" title="Submit detailed feedback" class="feedback-link">👎</a>
32
+ </span>
33
+ </div>
34
+ </div>
35
+
36
+ <!-- Feedback form (initially hidden, toggled by 👎 link) -->
37
+ <div x-show="showForm" style="width:800px;">
38
+ <form
39
+ hx-post="{% if share_id %}/chat/htmx/feedback-shared{% else %}/chat/htmx/feedback{% endif %}"
40
+ hx-swap="outerHTML"
41
+ x-on:htmx:afterRequest="showForm=false"
42
+ style="display:block; width:800px;">
43
+ {% if share_id %}<input type="hidden" name="share_id" value="{{ share_id }}">{% endif %}
44
+ <input type="hidden" name="flock_definition" value='{{ entry.flock_yaml | tojson | safe }}'>
45
+ <input type="hidden" name="agent_name" value='{{ entry.agent | tojson | safe }}'>
46
+ <input type="hidden" name="actual_response" value='{{ entry.raw_json | tojson | safe }}'>
47
+ <label>Reason</label>
48
+ <textarea name="reason" required style="min-height:5rem;width:100%; white-space:pre-wrap;"></textarea>
49
+ <label>Expected / Correct Response</label>
50
+ <textarea name="expected_response" style="min-height:12rem;width:100%; white-space:pre-wrap;font-family:monospace;">{{ entry.raw_json }}</textarea>
51
+ <div style="margin-top:0.4rem; display:flex; gap:0.5rem;">
52
+ <button type="submit" class="secondary">Send</button>
53
+ <button type="button" class="outline" @click="showForm=false">Back...</button>
54
+ </div>
55
+ </form>
56
+ </div>
11
57
  </div>
12
58
  {% endif %}
13
- {% endfor %}
59
+ {% endfor %}
@@ -6,6 +6,22 @@
6
6
  <div style="text-align: right;">
7
7
  <button role="button" class="outline contrast" @click="viewMode = 'structured'" :aria-pressed="viewMode === 'structured'">Structured</button>
8
8
  <button role="button" class="outline contrast" @click="viewMode = 'json'" :aria-pressed="viewMode === 'json'">Raw JSON</button>
9
+
10
+ <div style="display:inline-block;margin-left:0.5rem;">
11
+ <!-- Quick thumbs-up feedback (inline form so we have the identifiers) -->
12
+ <form hx-post="{{ feedback_endpoint }}" hx-target="#results-display-content" hx-swap="innerHTML" style="display:inline-block;vertical-align:middle;margin:0;" hx-indicator="#feedback-loading-indicator">
13
+ {% if share_id %}<input type="hidden" name="share_id" value="{{ share_id }}">{% endif %}
14
+ <input type="hidden" name="flock_name" value="{{ flock_name }}">
15
+ <input type="hidden" name="agent_name" value="{{ agent_name }}">
16
+ <input type="hidden" name="flock_definition" value='{{ flock_definition | replace("'", "&#39;") }}'>
17
+ <input type="hidden" name="actual_response" value='{{ result_raw_json | replace("'", "&#39;") }}'>
18
+ <input type="hidden" name="reason" value="positive">
19
+ <button type="submit" role="button" class="outline contrast" title="Looks good!" style="padding:0.3rem 0.5rem;line-height:1;vertical-align:middle;margin:0;"><i class="fa fa-thumbs-up"></i></button>
20
+ </form>
21
+
22
+ <!-- Thumbs-down toggles detailed feedback form -->
23
+ <button role="button" class="outline contrast" @click="viewMode = 'feedback'" :aria-pressed="viewMode === 'feedback'" title="Something's wrong" style="padding:0.3rem 0.5rem;line-height:1;vertical-align:middle;margin:0;"><i class="fa fa-thumbs-down"></i></button>
24
+ </div>
9
25
  </div>
10
26
  </header>
11
27
 
@@ -36,4 +52,27 @@
36
52
  <p>No results to display yet.</p>
37
53
  {% endif %}
38
54
  </div>
55
+
56
+ <!-- ---------------- Feedback form ---------------- -->
57
+ <div x-show="viewMode === 'feedback'" style="margin-top: 1rem;">
58
+ <form hx-post="{{ feedback_endpoint }}" hx-target="#results-display-content" hx-swap="innerHTML" hx-indicator="#feedback-loading-indicator">
59
+ {# Hidden identifiers #}
60
+ {% if share_id %}
61
+ <input type="hidden" name="share_id" value="{{ share_id }}">
62
+ {% endif %}
63
+ <input type="hidden" name="flock_name" value="{{ flock_name }}">
64
+ <input type="hidden" name="agent_name" value="{{ agent_name }}">
65
+ <input type="hidden" name="flock_definition" value='{{ flock_definition | replace("'", "&#39;") }}'>
66
+ <input type="hidden" name="actual_response" value='{{ result_raw_json | replace("'", "&#39;") }}'>
67
+
68
+ <label for="feedback_reason">Reason / Comment</label>
69
+ <textarea id="feedback_reason" name="reason" placeholder="Why isn't the answer good?" required style="min-height:6rem;"></textarea>
70
+
71
+ <label for="expected_response" style="margin-top:0.5rem;">Correct / Expected Response (JSON or text)</label>
72
+ <textarea id="expected_response" name="expected_response" style="white-space: pre; font-family: monospace; min-height:10rem;">{{ result_raw_json }}</textarea>
73
+
74
+ <button type="submit" class="secondary" style="margin-top:0.5rem;">Send Feedback</button>
75
+ <span id="feedback-loading-indicator" class="htmx-indicator"><progress indeterminate></progress> Sending…</span>
76
+ </form>
77
+ </div>
39
78
  </article>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.4.0b50
3
+ Version: 0.4.1
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -21,7 +21,7 @@ Requires-Dist: litellm==1.69.3
21
21
  Requires-Dist: loguru>=0.7.3
22
22
  Requires-Dist: markdown2>=2.5.3
23
23
  Requires-Dist: matplotlib>=3.10.0
24
- Requires-Dist: mem0ai[graph]>=0.1.100
24
+ Requires-Dist: mem0ai[graph]>=0.1.101
25
25
  Requires-Dist: msgpack>=1.1.0
26
26
  Requires-Dist: notion-client>=2.3.0
27
27
  Requires-Dist: openai==1.75.0
@@ -50,6 +50,8 @@ Requires-Dist: tiktoken>=0.8.0
50
50
  Requires-Dist: toml>=0.10.2
51
51
  Requires-Dist: tqdm>=4.67.1
52
52
  Requires-Dist: uvicorn>=0.34.0
53
+ Requires-Dist: wd-di>=0.2.14
54
+ Requires-Dist: zep-python>=2.0.2
53
55
  Provides-Extra: all-tools
54
56
  Requires-Dist: azure-identity>=1.23.0; extra == 'all-tools'
55
57
  Requires-Dist: azure-search-documents>=11.5.2; extra == 'all-tools'
@@ -91,7 +93,7 @@ Description-Content-Type: text/markdown
91
93
 
92
94
  🐤 `pip install flock-core` will install the latest non-beta version 🐤
93
95
 
94
- 🐤 Expected Release for 0.4.0 `Magpie`: End of April 2025 🐤
96
+ 🐤 The 0.4.0 Magpie release is in the works! 🐤
95
97
 
96
98
  ---
97
99
 
@@ -296,7 +298,7 @@ Flock makes this easy with:
296
298
  * **Declarative Configuration:** Define Temporal timeouts, retry policies, and task queues directly within your `Flock` and `FlockAgent` configurations (YAML or Python).
297
299
  * **Correct Patterns:** Uses Temporal's recommended granular activity execution for better control and visibility.
298
300
  * **Clear Worker Separation:** Provides guidance and flags for running dedicated Temporal workers, separating development convenience from production best practices.
299
-
301
+
300
302
  Visit the [Temporal Documentation](https://learn.temporal.io/python/workflows/) for more information on how to use Temporal.
301
303
 
302
304
  Or check out the [Flock Showcase](https://github.com/whiteducksoftware/flock-showcase) for a complete example of a Flock that uses Temporal or our [docs](https://whiteducksoftware.github.io/flock/guides/temporal-configuration/) for more information.
@@ -1,5 +1,12 @@
1
1
  flock/__init__.py,sha256=jg2kcXIi1isxTtYdoQGgk0NYSA-BC0J6Xqy41viWpFg,7834
2
- flock/config.py,sha256=9aUYglHavosdTS212WXW9qc_snZVimvxaXZ3Z5NDGWM,1923
2
+ flock/config.py,sha256=FJZaxSXYdIqCDyyTMAsXk4Ks1fwZywzBjh_XEg3zeOU,1930
3
+ flock/di.py,sha256=47taQXcE2RSZ4yhqhQizJdPCdRcy4OvseuH9siVTx54,1384
4
+ flock/adapter/__init__.py,sha256=TAHmnom6H2pbv-A0DbhqOSqnBi_egR8WvFGxfOlDPOM,345
5
+ flock/adapter/azure_adapter.py,sha256=DuBlRHv-sACOZmbRaueR4edpJj6HvtKb6AhPgosEpnw,2092
6
+ flock/adapter/chroma_adapter.py,sha256=4cFa0Cv3liT_tGYZpeioHN5CqfrJjzXPjEhICYt8So8,2269
7
+ flock/adapter/faiss_adapter.py,sha256=TE4bwAsrMdHI16EAamHqsvyAydrWyO0SgHPH54MSLhI,3339
8
+ flock/adapter/pinecone_adapter.py,sha256=GiASSbiGjF3l3QBbjCFuBxROqYZQMEQd_Npf6iBwDcY,1561
9
+ flock/adapter/vector_base.py,sha256=3qcIuc4MumYUmhHMqNmNBUkzxV_yG03MCnQrP7iQnYI,1211
3
10
  flock/cli/config.py,sha256=5DvFLObOx3ObisHnc9JfnUBnK83y0CBsUQzXfxPZve0,138
4
11
  flock/cli/constants.py,sha256=ZyXtTW91P1hUMkbMwmOwp_JEL5e9-YkcuM3vHM5glP4,978
5
12
  flock/cli/create_agent.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
@@ -19,11 +26,11 @@ flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
19
26
  flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
20
27
  flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
21
28
  flock/core/__init__.py,sha256=p7lmQULRu9ejIAELfanZiyMhW0CougIPvyFHW2nqBFQ,847
22
- flock/core/flock.py,sha256=1U1on8aMuCjFNAkQQMyWk7vNa0FqttWDFqoqQ1QlhEc,35674
23
- flock/core/flock_agent.py,sha256=-gEfBKWc569ynqNdy7Gc1iqBrCYPHmC8qvzXkxTi5m4,41115
29
+ flock/core/flock.py,sha256=UOSfW2ztic4l9k-dxkaH_DAeGDLzObfRlOEz5b4-rMU,34455
30
+ flock/core/flock_agent.py,sha256=jjAbLQFod01GeyPZRoxtO0mfPkb6vGxnsX4dVOe9u_A,43649
24
31
  flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
25
32
  flock/core/flock_factory.py,sha256=_4zsjkEmJnCR7IvJ3SUHnDbX6c7Tt3E4P5ohxwKvE6w,3173
26
- flock/core/flock_module.py,sha256=UCK6TFe4viXs596zeng0GD3gln4ZNGu_gCWkXIIMREg,3090
33
+ flock/core/flock_module.py,sha256=TNbdhJDL580m6ycGTxtgBel9Pe38GBs5aiOXMAqEA4w,3238
27
34
  flock/core/flock_registry.py,sha256=WKfIYXowrtblQ0HIko2zGMU8FqkSxjgIxta_ywXaekk,25764
28
35
  flock/core/flock_router.py,sha256=1OAXDsdaIIFApEfo6SRfFEDoTuGt3Si7n2MXiySEfis,2644
29
36
  flock/core/api/__init__.py,sha256=KdzUwBOwhxqqy7lAMLpysKL5GvpIiwOy6CxXELZVWaY,186
@@ -37,7 +44,7 @@ flock/core/api/service.py,sha256=HRHs4xt-bGeSm5hdN92H1vWQtLzqZalhZxIh6iwww8Y,113
37
44
  flock/core/api/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
45
  flock/core/api/ui/routes.py,sha256=nS-wWO94mshE5ozWfOQZ-HOvtes_1qxDVcqpMZtU5JQ,8885
39
46
  flock/core/api/ui/utils.py,sha256=V7PqYHNK519hFJ8jvvwf7bGpbBXCRz_HQG3BDCCqlNA,4802
40
- flock/core/context/context.py,sha256=GFqMwYXLheqECGvWcxar7sQ2-GuY3RVynZ7kjwd65R0,6875
47
+ flock/core/context/context.py,sha256=zdQuB1YWPJmQVv_2_sm1HK7FSnusa3Jl-83PcTuaLUk,7791
41
48
  flock/core/context/context_manager.py,sha256=FANSWa6DEhdhtZ7t_9Gza0v80UdpoDOhHbfVOccmjkA,1181
42
49
  flock/core/context/context_vars.py,sha256=ASPA29hpENWub4mgRoG62FtTVakCHQZfn6IhJQKe3C8,347
43
50
  flock/core/evaluation/utils.py,sha256=ZJkIMC9YT-HA2SPCZ4_bQ98isW1i6nbltVEYbjze-b0,12827
@@ -84,18 +91,22 @@ flock/modules/assertion/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8
84
91
  flock/modules/assertion/assertion_module.py,sha256=2p9mIj8yBXRGgfe5pUWYXcLT86Ny13KyWHpRhe0Ehtg,12877
85
92
  flock/modules/callback/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
86
93
  flock/modules/callback/callback_module.py,sha256=FnTYQeL828uQgYlpgGUnwCz0OzW_DKdOnQ3nwQCcu5o,2956
94
+ flock/modules/enterprise_memory/README.md,sha256=8xKfUi0mjX8tfVe77E3n9IoM97OuhlaCc1QE7PHSF1s,3111
95
+ flock/modules/enterprise_memory/enterprise_memory_module.py,sha256=XieINLCdRIiybhwmNY1_elIf7uyIut-Pas8Pz6PKR-c,21304
87
96
  flock/modules/mem0/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
88
- flock/modules/mem0/mem0_module.py,sha256=KEGWURXcqB4aRUVUcje8Tua2JOcYOHIbC4TkZQ6cvJo,2043
89
- flock/modules/mem0graph/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
90
- flock/modules/mem0graph/mem0_graph_module.py,sha256=ni1pu5sj2Qk13H-alWFjmwhIwG9_48gje59ZvVpn788,2012
97
+ flock/modules/mem0/mem0_module.py,sha256=EoQcD6OgxLuv1AxdLh76XNXZ_4f9zGPRd9LMCPBfgzk,4818
98
+ flock/modules/mem0_async/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
99
+ flock/modules/mem0_async/async_mem0_module.py,sha256=F7RRzKgiOo1iySckTVVzOnqnv8epitVJjwalFWUFjzY,4936
91
100
  flock/modules/memory/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
92
- flock/modules/memory/memory_module.py,sha256=zxdA8RIwhwYIytB8bY0VW32j6xDToUuP9RRgk_mpCwo,15046
101
+ flock/modules/memory/memory_module.py,sha256=RhkiBOB0eOkiLZb3hV2meFUZ95euYoAKUxKkfBaq1V4,15922
93
102
  flock/modules/memory/memory_parser.py,sha256=FLH7GL8XThvHiCMfX3eQH7Sz-f62fzhAUmO6_gaDI7U,4372
94
103
  flock/modules/memory/memory_storage.py,sha256=CNcLDMmvv0x7Z3YMKr6VveS_VCa7rKPw8l2d-XgqokA,27246
95
104
  flock/modules/output/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
96
105
  flock/modules/output/output_module.py,sha256=gEn1_khPAJp-hqU6Rxdv1sQz0jTLVSzYJvNbK1uVNCY,7402
97
106
  flock/modules/performance/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
98
- flock/modules/performance/metrics_module.py,sha256=j4_xY4HTz_MsaduFCk7mmQAzFtDZ9pTgPxKTEW-d8fE,16993
107
+ flock/modules/performance/metrics_module.py,sha256=zSjaLLeeUpD-Q5Qc-It8ZQDdMEUfpWQTWBq39tS8hPY,18014
108
+ flock/modules/zep/__init__.py,sha256=Y0cEkx0dujRmy--TDpKoTqFSLzbyFz8BwEOv8kdSUhg,22
109
+ flock/modules/zep/zep_module.py,sha256=gJXOqdoWIXcWOyzJoyqykgq5gU-Y2Dze3tLuQM_tMQc,6572
99
110
  flock/platform/docker_tools.py,sha256=fpA7-6rJBjPOUBLdQP4ny2QPgJ_042nmqRn5GtKnoYw,1445
100
111
  flock/platform/jaeger_install.py,sha256=MyOMJQx4TQSMYvdUJxfiGSo3YCtsfkbNXcAcQ9bjETA,2898
101
112
  flock/routers/__init__.py,sha256=w9uL34Auuo26-q_EGlE8Z9iHsw6S8qutTAH_ZI7pn7M,39
@@ -458,7 +469,7 @@ flock/tools/zendesk_tools.py,sha256=HQ7qBVSrRfemwolz0IOXl8Z02vJCLE6mTd-cARVdX88,
458
469
  flock/webapp/__init__.py,sha256=YtRbbyciN3Z2oMB9fdXZuvM3e49R8m2mY5qHLDoapRA,37
459
470
  flock/webapp/run.py,sha256=Ekg-mQSl7RUDJAEDTBJMIlLyvhWqWPMjg8hPqmgFREE,8945
460
471
  flock/webapp/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
461
- flock/webapp/app/chat.py,sha256=NKSsrozVvnvxrLBtJjN4Ps_DMol66nw1eD5E8GmcOLU,26077
472
+ flock/webapp/app/chat.py,sha256=d5a_mr3H2nuWNFSpSlI_HyqX-J_4krndd4A-8S25EKM,28679
462
473
  flock/webapp/app/config.py,sha256=lqmneujnNZk-EFJV5cWpvxkqisxH3T3zT_YOI0JYThE,4809
463
474
  flock/webapp/app/dependencies.py,sha256=JUcwY1N6SZplU141lMN2wk9dOC9er5HCedrKTJN9wJk,5533
464
475
  flock/webapp/app/main.py,sha256=489cZ_N8ZACRSGjY2PQomXM7bKYZL1_6s4BLRl4XSkM,53828
@@ -467,15 +478,15 @@ flock/webapp/app/theme_mapper.py,sha256=QzWwLWpED78oYp3FjZ9zxv1KxCyj43m8MZ0fhfzz
467
478
  flock/webapp/app/utils.py,sha256=RF8DMKKAj1XPmm4txUdo2OdswI1ATQ7cqUm6G9JFDzA,2942
468
479
  flock/webapp/app/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
469
480
  flock/webapp/app/api/agent_management.py,sha256=5xqO94QjjAYvxImyjKV9EGUQOvo4n3eqs7pGwGPSQJ4,10394
470
- flock/webapp/app/api/execution.py,sha256=NNNG_ZqYS80WoLMD7MSCyDhqkkvCVMb_MfIm3dOs_HA,10381
481
+ flock/webapp/app/api/execution.py,sha256=sVBBaIQAt6xp9sorYdId3j6-2cuCCfe8-QbTZVfEGGw,12994
471
482
  flock/webapp/app/api/flock_management.py,sha256=1o-6-36kTnUjI3am_BqLpdrcz0aqFXrxE-hQHIFcCsg,4869
472
483
  flock/webapp/app/api/registry_viewer.py,sha256=IoInxJiRR0yFlecG_l2_eRc6l35RQQyEDMG9BcBkipY,1020
473
484
  flock/webapp/app/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
474
485
  flock/webapp/app/services/flock_service.py,sha256=G4JQBC6WFO4ajjvZSbedZvlgczsD5fKdbMHVzhG_IaY,14970
475
- flock/webapp/app/services/sharing_models.py,sha256=hXbi0gy2ARNKBoURRR3ZJSm7Uq5ID1YEgBfzFuhnB3A,2054
476
- flock/webapp/app/services/sharing_store.py,sha256=jGuPpy4VwXEf1qEn4cQ9p_qkgkBOl3AwhDfyDB3mSRs,7049
486
+ flock/webapp/app/services/sharing_models.py,sha256=XeJk1akILV_1l-cIUaG8k_eYhjV3EWBCWZ2kpwbdImA,3609
487
+ flock/webapp/app/services/sharing_store.py,sha256=lcamERCXfmDnLObdukXI4TWeJPAP7-2gm4IsN6R4DjI,9409
477
488
  flock/webapp/app/templates/theme_mapper.html,sha256=z8ZY7nmk6PiUGzD_-px7wSXcEnuBM121rMq6u-2oaCo,14249
478
- flock/webapp/static/css/chat.css,sha256=jbq1w2BrA9y5R6dPM2ZSXCLDCff82OCPS1F_excYN5E,8167
489
+ flock/webapp/static/css/chat.css,sha256=Njc9gXfQzbXMrqtFJH2Yda-IQlwNPd2z4apXxzfA0sY,8169
479
490
  flock/webapp/static/css/components.css,sha256=WnicEHy3ptPzggKmyG9_oZp3X30EMJBUW3KEXaiUCUE,6018
480
491
  flock/webapp/static/css/header.css,sha256=E9MgItZCk34S65NfMJ001ZsRz4oyFSJex8KvINMtCn0,1043
481
492
  flock/webapp/static/css/layout.css,sha256=ocDd7dmezdQzNAQDuQSv1xZ8-pcbNgYLUYJB1SKcfvw,1526
@@ -492,7 +503,7 @@ flock/webapp/templates/partials/_agent_list.html,sha256=comYjOeUxQvlJzS-3D4OruJK
492
503
  flock/webapp/templates/partials/_agent_manager_view.html,sha256=oUJ-t2Mk3o4xjQ_HtHz0glgaHM8eqZpPB4i24ToJiJ8,2565
493
504
  flock/webapp/templates/partials/_agent_tools_checklist.html,sha256=T60fb7OrJYHUw0hJLC_otskgvbH9dZXbv5klgWBkSWk,686
494
505
  flock/webapp/templates/partials/_chat_container.html,sha256=n4MzCHAYvTw7rpINIW1dw7LgMSC0ifRORTU47We0p4s,804
495
- flock/webapp/templates/partials/_chat_messages.html,sha256=zJ7Qbi7bcbrjyfncOd3OKImhZ1APWELOQADWJvWGVQc,600
506
+ flock/webapp/templates/partials/_chat_messages.html,sha256=iBADlysOqa14Piwd2uejl0GqgBeM_Rrj-UWcqJ4-NyQ,3741
496
507
  flock/webapp/templates/partials/_chat_settings_form.html,sha256=JAO1OXw654WusY871MtjfxAeSuraBEH_taf1tQ2zKhA,4479
497
508
  flock/webapp/templates/partials/_create_flock_form.html,sha256=nQVbuTWqOQ59q5zyGXkuBixikvCkaZIPVW8CRF6wCm0,2806
498
509
  flock/webapp/templates/partials/_dashboard_flock_detail.html,sha256=c7srF0nL8ETmP0ATsIxF8MMHMtHVXJqWVzdrnu2i-1Q,1012
@@ -510,7 +521,7 @@ flock/webapp/templates/partials/_header_flock_status.html,sha256=reNB4Prsu9lObz5
510
521
  flock/webapp/templates/partials/_load_manager_view.html,sha256=2u4lufQMEpUlQOThUzo1zrE3AulDQ-aErruS6t91W44,2909
511
522
  flock/webapp/templates/partials/_registry_table.html,sha256=z4EW5G3DTknymBeSlpL2PZLcb2143P35upMnmHFfeJs,715
512
523
  flock/webapp/templates/partials/_registry_viewer_content.html,sha256=iQyxaLUzz1IcZouRLcMg73k-xcOZvOHVPfpuU7uXgYo,1891
513
- flock/webapp/templates/partials/_results_display.html,sha256=zwWF7uhYfOSsPWDdG9A11ccBBgu-Pz6cupvJ1f4xTB0,2103
524
+ flock/webapp/templates/partials/_results_display.html,sha256=1UJvCeyJTPxuJYUcGUM8O8uhNvCxxOfxpCjC-PCr80U,5268
514
525
  flock/webapp/templates/partials/_settings_env_content.html,sha256=Q1Xr6wLHLlqiduqNk6PyF1B4juP-vvqLOLZyiHHNRLc,572
515
526
  flock/webapp/templates/partials/_settings_theme_content.html,sha256=-y5vGRKBZf3Cp5DDE1M4Qw-yunuMtCG54Sa7r60XfJE,807
516
527
  flock/webapp/templates/partials/_settings_view.html,sha256=7Uy2EfAgVJ2Kac5S6nkeaIEr2tSagVyR5CBbf07fbSQ,1349
@@ -526,8 +537,8 @@ flock/workflow/agent_execution_activity.py,sha256=Gy6FtuVAjf0NiUXmC3syS2eJpNQF4R
526
537
  flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
527
538
  flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
528
539
  flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
529
- flock_core-0.4.0b50.dist-info/METADATA,sha256=iqhiWpNagA97dhguRWqDQOhMmlb3-PGKFYT-v0LY_aU,17879
530
- flock_core-0.4.0b50.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
531
- flock_core-0.4.0b50.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
532
- flock_core-0.4.0b50.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
533
- flock_core-0.4.0b50.dist-info/RECORD,,
540
+ flock_core-0.4.1.dist-info/METADATA,sha256=LB3EQsgRK43SzP1NY1Tv2C9JL3AtKrVYxMGCzV5M6OU,17922
541
+ flock_core-0.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
542
+ flock_core-0.4.1.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
543
+ flock_core-0.4.1.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
544
+ flock_core-0.4.1.dist-info/RECORD,,