flowscript-agents 0.2.8__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. flowscript_agents-0.3.0/.gitignore +19 -0
  2. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/PKG-INFO +60 -8
  3. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/README.md +59 -7
  4. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/__init__.py +6 -2
  5. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/audit.py +5 -1
  6. flowscript_agents-0.3.0/flowscript_agents/client.py +638 -0
  7. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/cloud.py +94 -28
  8. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/extract.py +26 -11
  9. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/explain.py +138 -2
  10. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/mcp.py +104 -3
  11. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/memory.py +12 -0
  12. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/query.py +147 -2
  13. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/tool-integrity.json +3 -1
  14. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/pyproject.toml +1 -1
  15. flowscript_agents-0.3.0/tests/test_client.py +470 -0
  16. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_cloud.py +137 -15
  17. flowscript_agents-0.3.0/tests/test_cloud_fixpoint.py +210 -0
  18. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_explain.py +69 -1
  19. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_mcp.py +66 -4
  20. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_memory.py +68 -0
  21. flowscript_agents-0.2.8/.gitignore +0 -12
  22. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/.github/workflows/test.yml +0 -0
  23. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/AUDIT_TRAIL_DESIGN.md +0 -0
  24. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/adapters.md +0 -0
  25. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/api-reference.md +0 -0
  26. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/audit-trail.md +0 -0
  27. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/brand/logo-512.png +0 -0
  28. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/brand/social-preview.png +0 -0
  29. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/flowscript-demo.png +0 -0
  30. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/docs/lifecycle.md +0 -0
  31. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/examples/CLAUDE.md.example +0 -0
  32. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/examples/langgraph_live_test.py +0 -0
  33. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/examples/temporal_e2e_test.py +0 -0
  34. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/camel_ai.py +0 -0
  35. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/crewai.py +0 -0
  36. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/__init__.py +0 -0
  37. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/_utils.py +0 -0
  38. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/consolidate.py +0 -0
  39. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/index.py +0 -0
  40. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/providers.py +0 -0
  41. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/embeddings/search.py +0 -0
  42. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/fixpoint.py +0 -0
  43. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/google_adk.py +0 -0
  44. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/haystack.py +0 -0
  45. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/langgraph.py +0 -0
  46. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/llamaindex.py +0 -0
  47. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/openai_agents.py +0 -0
  48. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/pydantic_ai.py +0 -0
  49. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/smolagents.py +0 -0
  50. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/types.py +0 -0
  51. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/flowscript_agents/unified.py +0 -0
  52. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/scripts/validate_dedup_threshold.py +0 -0
  53. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/conftest.py +0 -0
  54. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_audit.py +0 -0
  55. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_camel_ai.py +0 -0
  56. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_consolidation.py +0 -0
  57. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_crewai.py +0 -0
  58. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_embeddings.py +0 -0
  59. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_fixpoint.py +0 -0
  60. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_google_adk.py +0 -0
  61. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_haystack.py +0 -0
  62. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_langgraph.py +0 -0
  63. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_llamaindex.py +0 -0
  64. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_openai_agents.py +0 -0
  65. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_pydantic_ai.py +0 -0
  66. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_smolagents.py +0 -0
  67. {flowscript_agents-0.2.8 → flowscript_agents-0.3.0}/tests/test_temporal.py +0 -0
@@ -0,0 +1,19 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ *.tmp
9
+ .flowscript-*
10
+ *.jsonl
11
+
12
+ .DS_Store
13
+
14
+ # Development-only validation scripts (hardcoded local paths)
15
+ e2e_compliance_chain.py
16
+ validate_wrapper.py
17
+ validate_autonomous_agent.py
18
+ e2e_output/
19
+ validation_output/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowscript-agents
3
- Version: 0.2.8
3
+ Version: 0.3.0
4
4
  Summary: Complete agent memory: reasoning queries + vector search + auto-extraction. Decision intelligence for LangGraph, CrewAI, Google ADK, OpenAI Agents SDK, Pydantic AI, smolagents, LlamaIndex, Haystack, and CAMEL-AI.
5
5
  Project-URL: Homepage, https://flowscript.org
6
6
  Project-URL: Repository, https://github.com/phillipclapham/flowscript-agents
@@ -70,9 +70,11 @@ Description-Content-Type: text/markdown
70
70
 
71
71
  <p align="center"><strong>Your AI agents make decisions they can't explain. FlowScript makes those decisions queryable.</strong></p>
72
72
 
73
- <p align="center">Drop-in adapters for 9 agent frameworks. Plain text in, typed reasoning queries out.<br>Hash-chained audit trail. Structural compliance. MIT licensed.</p>
73
+ <p align="center">Drop-in adapters for 9 agent frameworks. Plain text in, typed reasoning queries out.<br>Hash-chained audit trail. Convergence certificates. CloudClient for independent witnessing. MIT licensed.</p>
74
74
 
75
- [![Tests](https://img.shields.io/badge/tests-584%20passing-brightgreen)](https://github.com/phillipclapham/flowscript-agents) [![PyPI](https://img.shields.io/pypi/v/flowscript-agents)](https://pypi.org/project/flowscript-agents/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/flowscript-agents/)
75
+ <p align="center"><em>EU AI Act enforcement begins August 2026. Audit trails can't be backdated.<br>FlowScript is the compliance engine that makes your agents audit-ready from day one.</em></p>
76
+
77
+ [![Tests](https://img.shields.io/badge/tests-590%2B%20passing-brightgreen)](https://github.com/phillipclapham/flowscript-agents) [![PyPI](https://img.shields.io/pypi/v/flowscript-agents)](https://pypi.org/project/flowscript-agents/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/flowscript-agents/)
76
78
 
77
79
  ---
78
80
 
@@ -357,6 +359,55 @@ Events are dispatched in order (single worker thread). Callback failures log to
357
359
 
358
360
  ---
359
361
 
362
+ ## @fix — Convergence Certificates
363
+
364
+ When FlowScript's consolidation engine resolves contradictions — creating tensions, updating beliefs, unblocking decisions — it produces **convergence certificates**: hash-chained attestations that prove how the reasoning graph changed and that the transformation hasn't been tampered with.
365
+
366
+ ```python
367
+ from flowscript_agents import Memory, MemoryOptions, AuditConfig
368
+
369
+ mem = Memory.load_or_create("agent.json", options=MemoryOptions(
370
+ audit=AuditConfig(retention_months=84)
371
+ ))
372
+
373
+ # UnifiedMemory consolidation produces certificates automatically:
374
+ # initial_graph_hash → delta_sequence → final_graph_hash → certificate_hash
375
+ ```
376
+
377
+ Each certificate records: the graph state before consolidation (`initial_hash`), what changed (`delta_sequence`), the graph state after (`final_hash`), and a hash proving the record is tamper-evident (`certificate_hash`). This is concrete Article 86 infrastructure — an auditor can verify not just what your agent decided, but how it got there.
378
+
379
+ **Underlying formal model:** FlowScript's `@fix` operator provides stratified fixpoint computation over typed reasoning graphs — L0 (pure description, always terminates), L1 (bounded fixpoint, Knaster-Tarski guarantees), L2 (general fixpoint, Turing-complete, bounded). Consolidation is a degenerate L1 fixpoint (single iteration). Full spec: [`fixpoint_spec.md`](https://github.com/phillipclapham/flowscript/blob/main/spec/fixpoint_spec.md).
380
+
381
+ ---
382
+
383
+ ## FlowScript Cloud — Independent Cryptographic Witnessing *(Coming Soon)*
384
+
385
+ Local audit trails are tamper-evident but self-attested. FlowScript Cloud will add independent verification: your SDK streams events to the Cloud service, which verifies chain continuity and stores witness attestations.
386
+
387
+ The CloudClient is included in the SDK and ready for integration. The Cloud service is under development.
388
+
389
+ ```python
390
+ from flowscript_agents import Memory, MemoryOptions, AuditConfig
391
+ from flowscript_agents.cloud import CloudClient
392
+
393
+ cloud = CloudClient() # reads FLOWSCRIPT_API_KEY from env
394
+
395
+ mem = Memory.load_or_create("agent.json", options=MemoryOptions(
396
+ audit=AuditConfig(on_event=cloud.queue_event)
397
+ ))
398
+ ```
399
+
400
+ **CloudClient features:**
401
+ - **Batch buffering** — events accumulate and flush in batches (configurable `batch_size`, default 50)
402
+ - **Lock-free I/O** — network operations never block your agent's main thread
403
+ - **Buffer overflow protection** — `max_buffer_size` cap prevents memory growth
404
+ - **Witness tracking** — `cloud.last_witness` returns the most recent attestation
405
+ - **Retry with backoff** — transient failures retry automatically
406
+
407
+ **Planned deployment tiers:** SaaS, self-hosted Cloudflare, or Docker on-premise. BSL 1.1 licensed.
408
+
409
+ ---
410
+
360
411
  ## Session Lifecycle — How Memory Gets Smarter
361
412
 
362
413
  Just like a mind needs sleep to consolidate memories, your agent's reasoning graph needs regular session wraps to develop intelligence over time. Without consolidation cycles, knowledge accumulates as noise instead of maturing.
@@ -497,14 +548,14 @@ text = explain(result, audience="legal")
497
548
  │ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
498
549
  │ │ Memory │ │ Queries │ │ Audit Trail │ │
499
550
  │ │ (graph) │ │ (5 ops) │ │ (SHA-256 hash chain) │ │
500
- │ │ explain() │ │ on_event_async
501
- │ └──────────┘ └──────────┘ └──────────────────────┘ │
551
+ │ │ @fix │ │explain() │ │ on_event_async ─────────→ FlowScript Cloud
552
+ │ └──────────┘ └──────────┘ └──────────────────────┘ │ (independent witness)
502
553
  ├─────────────────────────────────────────────────────┤
503
554
  │ Your Storage (files, database, cloud) │
504
555
  └─────────────────────────────────────────────────────┘
505
556
  ```
506
557
 
507
- FlowScript doesn't replace your stack. It sits between your agent framework and your storage, adding typed reasoning and audit to whatever you already use.
558
+ FlowScript doesn't replace your stack. It sits between your agent framework and your storage, adding typed reasoning and audit to whatever you already use. Optionally stream audit events to FlowScript Cloud *(coming soon)* for independent cryptographic witnessing.
508
559
 
509
560
  ---
510
561
 
@@ -550,11 +601,12 @@ The applications are what you install FlowScript for. The infrastructure is why
550
601
 
551
602
  | Package | What | Install |
552
603
  |:--------|:-----|:--------|
553
- | [flowscript-agents](https://pypi.org/project/flowscript-agents/) | Python SDK — 9 adapters, unified memory, consolidation, audit trail | `pip install flowscript-agents openai` |
604
+ | [flowscript-agents](https://pypi.org/project/flowscript-agents/) | Python SDK — 9 adapters, CloudClient, unified memory, consolidation, audit trail | `pip install flowscript-agents openai` |
554
605
  | [flowscript-core](https://www.npmjs.com/package/flowscript-core) | TypeScript SDK — Memory class, 15 tools, token budgeting, audit trail | `npm install flowscript-core` |
606
+ | [flowscript-cloud](https://github.com/phillipclapham/flowscript-cloud) | Cloud witnessing service — chain verification, witness attestations, RBAC | *Coming soon* |
555
607
  | [flowscript.org](https://flowscript.org) | Web editor, D3 visualization, live query panel | Browser |
556
608
 
557
- **1,315 tests** across Python (584) and TypeScript (731). Same audit trail format and canonical JSON serialization across both languages.
609
+ **~1,400+ tests** across Python (590+), TypeScript (779), and Cloud (68). Same audit trail format and canonical JSON serialization across both languages.
558
610
 
559
611
  ### Docs
560
612
 
@@ -6,9 +6,11 @@
6
6
 
7
7
  <p align="center"><strong>Your AI agents make decisions they can't explain. FlowScript makes those decisions queryable.</strong></p>
8
8
 
9
- <p align="center">Drop-in adapters for 9 agent frameworks. Plain text in, typed reasoning queries out.<br>Hash-chained audit trail. Structural compliance. MIT licensed.</p>
9
+ <p align="center">Drop-in adapters for 9 agent frameworks. Plain text in, typed reasoning queries out.<br>Hash-chained audit trail. Convergence certificates. CloudClient for independent witnessing. MIT licensed.</p>
10
10
 
11
- [![Tests](https://img.shields.io/badge/tests-584%20passing-brightgreen)](https://github.com/phillipclapham/flowscript-agents) [![PyPI](https://img.shields.io/pypi/v/flowscript-agents)](https://pypi.org/project/flowscript-agents/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/flowscript-agents/)
11
+ <p align="center"><em>EU AI Act enforcement begins August 2026. Audit trails can't be backdated.<br>FlowScript is the compliance engine that makes your agents audit-ready from day one.</em></p>
12
+
13
+ [![Tests](https://img.shields.io/badge/tests-590%2B%20passing-brightgreen)](https://github.com/phillipclapham/flowscript-agents) [![PyPI](https://img.shields.io/pypi/v/flowscript-agents)](https://pypi.org/project/flowscript-agents/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/flowscript-agents/)
12
14
 
13
15
  ---
14
16
 
@@ -293,6 +295,55 @@ Events are dispatched in order (single worker thread). Callback failures log to
293
295
 
294
296
  ---
295
297
 
298
+ ## @fix — Convergence Certificates
299
+
300
+ When FlowScript's consolidation engine resolves contradictions — creating tensions, updating beliefs, unblocking decisions — it produces **convergence certificates**: hash-chained attestations that prove how the reasoning graph changed and that the transformation hasn't been tampered with.
301
+
302
+ ```python
303
+ from flowscript_agents import Memory, MemoryOptions, AuditConfig
304
+
305
+ mem = Memory.load_or_create("agent.json", options=MemoryOptions(
306
+ audit=AuditConfig(retention_months=84)
307
+ ))
308
+
309
+ # UnifiedMemory consolidation produces certificates automatically:
310
+ # initial_graph_hash → delta_sequence → final_graph_hash → certificate_hash
311
+ ```
312
+
313
+ Each certificate records: the graph state before consolidation (`initial_hash`), what changed (`delta_sequence`), the graph state after (`final_hash`), and a hash proving the record is tamper-evident (`certificate_hash`). This is concrete Article 86 infrastructure — an auditor can verify not just what your agent decided, but how it got there.
314
+
315
+ **Underlying formal model:** FlowScript's `@fix` operator provides stratified fixpoint computation over typed reasoning graphs — L0 (pure description, always terminates), L1 (bounded fixpoint, Knaster-Tarski guarantees), L2 (general fixpoint, Turing-complete, bounded). Consolidation is a degenerate L1 fixpoint (single iteration). Full spec: [`fixpoint_spec.md`](https://github.com/phillipclapham/flowscript/blob/main/spec/fixpoint_spec.md).
316
+
317
+ ---
318
+
319
+ ## FlowScript Cloud — Independent Cryptographic Witnessing *(Coming Soon)*
320
+
321
+ Local audit trails are tamper-evident but self-attested. FlowScript Cloud will add independent verification: your SDK streams events to the Cloud service, which verifies chain continuity and stores witness attestations.
322
+
323
+ The CloudClient is included in the SDK and ready for integration. The Cloud service is under development.
324
+
325
+ ```python
326
+ from flowscript_agents import Memory, MemoryOptions, AuditConfig
327
+ from flowscript_agents.cloud import CloudClient
328
+
329
+ cloud = CloudClient() # reads FLOWSCRIPT_API_KEY from env
330
+
331
+ mem = Memory.load_or_create("agent.json", options=MemoryOptions(
332
+ audit=AuditConfig(on_event=cloud.queue_event)
333
+ ))
334
+ ```
335
+
336
+ **CloudClient features:**
337
+ - **Batch buffering** — events accumulate and flush in batches (configurable `batch_size`, default 50)
338
+ - **Lock-free I/O** — network operations never block your agent's main thread
339
+ - **Buffer overflow protection** — `max_buffer_size` cap prevents memory growth
340
+ - **Witness tracking** — `cloud.last_witness` returns the most recent attestation
341
+ - **Retry with backoff** — transient failures retry automatically
342
+
343
+ **Planned deployment tiers:** SaaS, self-hosted Cloudflare, or Docker on-premise. BSL 1.1 licensed.
344
+
345
+ ---
346
+
296
347
  ## Session Lifecycle — How Memory Gets Smarter
297
348
 
298
349
  Just like a mind needs sleep to consolidate memories, your agent's reasoning graph needs regular session wraps to develop intelligence over time. Without consolidation cycles, knowledge accumulates as noise instead of maturing.
@@ -433,14 +484,14 @@ text = explain(result, audience="legal")
433
484
  │ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │
434
485
  │ │ Memory │ │ Queries │ │ Audit Trail │ │
435
486
  │ │ (graph) │ │ (5 ops) │ │ (SHA-256 hash chain) │ │
436
- │ │ explain() │ │ on_event_async
437
- │ └──────────┘ └──────────┘ └──────────────────────┘ │
487
+ │ │ @fix │ │explain() │ │ on_event_async ─────────→ FlowScript Cloud
488
+ │ └──────────┘ └──────────┘ └──────────────────────┘ │ (independent witness)
438
489
  ├─────────────────────────────────────────────────────┤
439
490
  │ Your Storage (files, database, cloud) │
440
491
  └─────────────────────────────────────────────────────┘
441
492
  ```
442
493
 
443
- FlowScript doesn't replace your stack. It sits between your agent framework and your storage, adding typed reasoning and audit to whatever you already use.
494
+ FlowScript doesn't replace your stack. It sits between your agent framework and your storage, adding typed reasoning and audit to whatever you already use. Optionally stream audit events to FlowScript Cloud *(coming soon)* for independent cryptographic witnessing.
444
495
 
445
496
  ---
446
497
 
@@ -486,11 +537,12 @@ The applications are what you install FlowScript for. The infrastructure is why
486
537
 
487
538
  | Package | What | Install |
488
539
  |:--------|:-----|:--------|
489
- | [flowscript-agents](https://pypi.org/project/flowscript-agents/) | Python SDK — 9 adapters, unified memory, consolidation, audit trail | `pip install flowscript-agents openai` |
540
+ | [flowscript-agents](https://pypi.org/project/flowscript-agents/) | Python SDK — 9 adapters, CloudClient, unified memory, consolidation, audit trail | `pip install flowscript-agents openai` |
490
541
  | [flowscript-core](https://www.npmjs.com/package/flowscript-core) | TypeScript SDK — Memory class, 15 tools, token budgeting, audit trail | `npm install flowscript-core` |
542
+ | [flowscript-cloud](https://github.com/phillipclapham/flowscript-cloud) | Cloud witnessing service — chain verification, witness attestations, RBAC | *Coming soon* |
491
543
  | [flowscript.org](https://flowscript.org) | Web editor, D3 visualization, live query panel | Browser |
492
544
 
493
- **1,315 tests** across Python (584) and TypeScript (731). Same audit trail format and canonical JSON serialization across both languages.
545
+ **~1,400+ tests** across Python (590+), TypeScript (779), and Cloud (68). Same audit trail format and canonical JSON serialization across both languages.
494
546
 
495
547
  ### Docs
496
548
 
@@ -27,6 +27,7 @@ Usage:
27
27
  """
28
28
 
29
29
  from .audit import AuditConfig, AuditQueryResult, AuditVerifyResult
30
+ from .client import FlowScriptAnthropic, FlowScriptOpenAI
30
31
  from .cloud import CloudClient, CloudFlushResult, CloudWitness
31
32
  from .memory import (
32
33
  Memory,
@@ -43,14 +44,17 @@ from .memory import (
43
44
  SessionWrapResult,
44
45
  )
45
46
  from .unified import UnifiedMemory
46
- from .explain import explain
47
+ from .explain import explain, explain_counterfactual
47
48
 
48
- __version__ = "0.2.8"
49
+ __version__ = "0.3.0"
49
50
  __all__ = [
50
51
  "explain",
52
+ "explain_counterfactual",
51
53
  "AuditConfig",
52
54
  "AuditQueryResult",
53
55
  "AuditVerifyResult",
56
+ "FlowScriptAnthropic",
57
+ "FlowScriptOpenAI",
54
58
  "CloudClient",
55
59
  "CloudFlushResult",
56
60
  "CloudWitness",
@@ -19,6 +19,7 @@ File layout:
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
+ import copy
22
23
  import gzip
23
24
  import atexit
24
25
  import hashlib
@@ -407,7 +408,10 @@ class AuditWriter:
407
408
  # Fire on_event callback (failure must never block audit, but log to stderr)
408
409
  if self._config.on_event:
409
410
  if self._config.on_event_async:
410
- self._get_executor().submit(self._fire_on_event, entry)
411
+ # Deep copy to prevent caller mutation between write() return and
412
+ # async callback execution from producing different canonical JSON
413
+ # (which would break hash chain verification in CloudClient).
414
+ self._get_executor().submit(self._fire_on_event, copy.deepcopy(entry))
411
415
  else:
412
416
  self._fire_on_event(entry)
413
417