flock-core 0.4.0b50__py3-none-any.whl → 0.4.2__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 (36) 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/cli/constants.py +1 -1
  8. flock/config.py +1 -1
  9. flock/core/context/context.py +20 -0
  10. flock/core/flock.py +71 -91
  11. flock/core/flock_agent.py +58 -3
  12. flock/core/flock_module.py +5 -0
  13. flock/core/util/cli_helper.py +1 -1
  14. flock/di.py +41 -0
  15. flock/modules/enterprise_memory/README.md +99 -0
  16. flock/modules/enterprise_memory/enterprise_memory_module.py +526 -0
  17. flock/modules/mem0/mem0_module.py +79 -16
  18. flock/modules/mem0_async/async_mem0_module.py +126 -0
  19. flock/modules/memory/memory_module.py +28 -8
  20. flock/modules/performance/metrics_module.py +24 -1
  21. flock/modules/zep/__init__.py +1 -0
  22. flock/modules/zep/zep_module.py +192 -0
  23. flock/webapp/app/api/execution.py +79 -2
  24. flock/webapp/app/chat.py +83 -3
  25. flock/webapp/app/services/sharing_models.py +38 -0
  26. flock/webapp/app/services/sharing_store.py +60 -1
  27. flock/webapp/static/css/chat.css +2 -0
  28. flock/webapp/templates/partials/_chat_messages.html +50 -4
  29. flock/webapp/templates/partials/_results_display.html +39 -0
  30. {flock_core-0.4.0b50.dist-info → flock_core-0.4.2.dist-info}/METADATA +5 -7
  31. {flock_core-0.4.0b50.dist-info → flock_core-0.4.2.dist-info}/RECORD +35 -24
  32. flock/modules/mem0graph/mem0_graph_module.py +0 -63
  33. /flock/modules/{mem0graph → mem0_async}/__init__.py +0 -0
  34. {flock_core-0.4.0b50.dist-info → flock_core-0.4.2.dist-info}/WHEEL +0 -0
  35. {flock_core-0.4.0b50.dist-info → flock_core-0.4.2.dist-info}/entry_points.txt +0 -0
  36. {flock_core-0.4.0b50.dist-info → flock_core-0.4.2.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.2
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'
@@ -87,11 +89,7 @@ Description-Content-Type: text/markdown
87
89
  <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>
88
90
  </p>
89
91
 
90
- 🐤 Flock 0.4.0 currently in beta - use `pip install flock-core==0.4.0b5` 🐤
91
92
 
92
- 🐤 `pip install flock-core` will install the latest non-beta version 🐤
93
-
94
- 🐤 Expected Release for 0.4.0 `Magpie`: End of April 2025 🐤
95
93
 
96
94
  ---
97
95
 
@@ -296,7 +294,7 @@ Flock makes this easy with:
296
294
  * **Declarative Configuration:** Define Temporal timeouts, retry policies, and task queues directly within your `Flock` and `FlockAgent` configurations (YAML or Python).
297
295
  * **Correct Patterns:** Uses Temporal's recommended granular activity execution for better control and visibility.
298
296
  * **Clear Worker Separation:** Provides guidance and flags for running dedicated Temporal workers, separating development convenience from production best practices.
299
-
297
+
300
298
  Visit the [Temporal Documentation](https://learn.temporal.io/python/workflows/) for more information on how to use Temporal.
301
299
 
302
300
  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.