You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Docs/azure_testing.md
+52-37Lines changed: 52 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,9 +28,11 @@ You need:
28
28
29
29
```bash
30
30
pip install -e ".[dev]"
31
-
pip install -r azure_functions/requirements.txt
31
+
pip install -r function_app/requirements.txt
32
32
```
33
33
34
+
> The recommended way to provision **all** required Azure resources is `azd up` from the repo root, which uses the Bicep templates under `infra/`. See [`infra/README.md`](../infra/README.md) for details. The manual `az ...` commands below are kept as a reference for operators who can't use `azd`.
35
+
34
36
---
35
37
36
38
## 1. Create Azure Resources
@@ -111,11 +113,17 @@ az functionapp config appsettings set \
`COSMOS_DB_THROUGHPUT_MODE=serverless` is the default and creates the `memories`, `counter`, and `leases` containers without specifying RU/s. Set `COSMOS_DB_THROUGHPUT_MODE=autoscale` to apply the shared `COSMOS_DB_AUTOSCALE_MAX_RU` cap to all required containers.
118
124
125
+
`MEMORY_PROCESSOR_OWNER=durable` tells the SDK that the deployed Function App owns processing, so any `CosmosMemoryClient` pointed at the same container will skip its in-process auto-trigger and avoid double-extraction. See the README's processor-ownership table for details.
126
+
119
127
### Change feed settings (optional)
120
128
121
129
To enable automatic processing via the change feed trigger, add these settings:
@@ -139,14 +147,16 @@ Set any threshold to `"0"` to disable that processing type.
139
147
140
148
The `leases` container is provisioned by `create_memory_store()` alongside the `memories` and `counter` containers, so the Function App should be configured to use that existing lease container.
141
149
142
-
If you use function-key auth for the HTTP trigger, keep the key for the client as `ADF_KEY`.
150
+
The Function App authenticates to Cosmos DB and Azure OpenAI via its managed identity — there's no shared key or function-key handoff between the SDK and the Function App.
143
151
144
152
---
145
153
146
154
## 4. Deploy the Functions Project
147
155
156
+
The recommended path is `azd up` (which builds and deploys the `function_app/` service automatically). For manual deployment:
Processing is no longer invoked directly from the SDK — write turns with `add_cosmos()` / `push_to_cosmos()` and the deployed Function App's change-feed trigger fires the `extract_memories`, `thread_summary`, and `user_summary` orchestrators per the configured thresholds.
Copy file name to clipboardExpand all lines: Docs/design_patterns.md
+7-15Lines changed: 7 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Design Patterns
2
2
3
-
This guide shows when and how to use the toolkit's main operations in real applications. All examples use the async API (`AsyncAgentMemory`); the sync API (`AgentMemory`) has the same method signatures without `await`.
3
+
This guide shows when and how to use the toolkit's main operations in real applications. All examples use the async API (`AsyncCosmosMemoryClient`); the sync API (`CosmosMemoryClient`) has the same method signatures without `await`.
4
4
5
5
---
6
6
@@ -11,26 +11,18 @@ This guide shows when and how to use the toolkit's main operations in real appli
11
11
Write a turn memory every time a user or agent message is produced. If the application runs locally first and syncs later, use the local + bulk-upload pattern.
12
12
13
13
```python
14
-
from azure.identity.aio import DefaultAzureCredential as AsyncDefaultAzureCredential
15
-
from agent_memory_toolkit.aio import AsyncAgentMemory
14
+
from agent_memory_toolkit.aio import AsyncCosmosMemoryClient
By default, the **InProcess processor** runs fact extraction after **every turn** (`FACT_EXTRACTION_EVERY_N=1`) and a thread summary every **10 turns** (`THREAD_SUMMARY_EVERY_N=10`). The trigger fires inside `push_to_cosmos()` after the turn is durably written, so calling `process_now()` is normally redundant — it remains as an explicit "flush now" hook. The Durable backend uses the same defaults via the change-feed function app.
210
+
By default, the **InProcess processor** runs each pipeline step independently as its own threshold trips inside `push_to_cosmos()`:
211
+
212
+
| Env var | Default | Step that fires | Async behavior |
|`THREAD_SUMMARY_EVERY_N`|`10`|`process_thread_summary`| scheduled via `asyncio.create_task`|
216
+
|`USER_SUMMARY_EVERY_N`|`20`|`process_user_summary`| scheduled via `asyncio.create_task`|
217
+
218
+
Each `*_EVERY_N=0` disables only that step. The Durable backend uses the same defaults via the change-feed function app, so the in-process and durable backends fire on the same turn boundaries — only the *where* differs. Calling `process_now()` is normally redundant — it remains as an explicit "process now" hook for tests, manual workflows, and operators who set every threshold to `0`.
219
+
220
+
The async client (`AsyncCosmosMemoryClient.push_to_cosmos`) does **not** await the auto-trigger; it schedules it as a background `asyncio.Task` so the write call returns as soon as the Cosmos upserts complete. Background failures are surfaced via `logger.warning` (search for `"Background auto-trigger task failed"`).
Both the SDK auto-trigger and the function-app change-feed processor write into the same `counter` container. If you accidentally point an `InProcessProcessor` at a Cosmos container that already has a function app attached, both backends will run the pipeline on the same writes — double extraction, double dedup, double counters.
225
+
226
+
Set the env var on **both sides** to make ownership explicit:
The default (unset) preserves backward compatibility. For any production deployment we recommend setting it on both sides so a misconfiguration produces a loud log line instead of silent double-work.
235
+
236
+
> **Advisory, not enforced.**`MEMORY_PROCESSOR_OWNER` is operator-configured exclusivity, not a server-side lock. Each backend reads its own env var; if the SDK is set to `inprocess` but the FA forgets to set `durable` (or vice versa), both still run. As a backstop, every counter write stamps `last_owner=<this backend>` on the doc — when the SDK observes a counter previously written by `durable` (or vice versa), it logs a one-shot `WARN` so misconfiguration surfaces in logs without spamming. Treat this as a configuration audit signal, not a hard guarantee.
0 commit comments