diff --git a/docs/docs/agents/getting-started.md b/docs/docs/agents/getting-started.md index 0f79a9e..c9dd2b9 100644 --- a/docs/docs/agents/getting-started.md +++ b/docs/docs/agents/getting-started.md @@ -115,10 +115,14 @@ Replace the Wrangler config with one of these: ) ``` -Each agent class needs a Durable Object binding and a migration that creates -it as a SQLite-backed class. `route_agent_request` finds the agent by the +Each agent class needs a Durable Object +[binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/) +and a [migration](https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/) +that creates it as a SQLite-backed class. `route_agent_request` finds the agent by the binding's `name`, converted to kebab case, so the binding `Counter` answers at -`/agents/counter/...`. +`/agents/counter/...`. In `cloudflare.config.py`, the `env` and `exports` +entries take the place of both, as +[Write config in Python](../wynd/python-config.md#add-bindings) explains. ## 4. Run it locally diff --git a/docs/docs/agents/pydantic-ai.md b/docs/docs/agents/pydantic-ai.md index f7540b6..c5a3418 100644 --- a/docs/docs/agents/pydantic-ai.md +++ b/docs/docs/agents/pydantic-ai.md @@ -80,6 +80,10 @@ Add the Workers AI binding to your Wrangler config: } ``` +`"remote": true` makes `dev` call the real Workers AI service, which has no +local version. See +[Remote bindings](https://developers.cloudflare.com/workers/development-testing/#remote-bindings). + Then talk to it: ```sh diff --git a/docs/docs/agents/state.md b/docs/docs/agents/state.md index 868388d..7257377 100644 --- a/docs/docs/agents/state.md +++ b/docs/docs/agents/state.md @@ -103,7 +103,13 @@ exception doesn't undo the change. ## Store rows with SQL `self.sql(query, *params)` runs one statement against the agent's SQLite -database and returns a list of dicts. Use `?` placeholders for values: +database and returns a list of dicts. Each agent instance has its own +database and handles one request at a time, so data every request reads, kept +in one instance such as `"main"`, puts all your traffic through that one +instance. Cloudflare compares D1, KV and the other options in +[Choosing a data or storage product](https://developers.cloudflare.com/workers/platform/storage-options/). + +Use `?` placeholders for values: ```python from workers import Request, Response diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index fd763ed..3d6df75 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -27,13 +27,13 @@ Each Crosswind SDK speaks the same wire protocols as it's official counter-part. ## Picking a Runtime SDK and a Build Tool -Cloudflare ships [`pywrangler`]() and [`workers-runtime-sdk`](). They're both great! +Cloudflare ships [`pywrangler`](https://github.com/cloudflare/workers-py) and [`workers-runtime-sdk`](https://pypi.org/project/workers-runtime-sdk/). They're both great! -Crosswind provides it's own opinionated build tool [`wynd`](), and it's own runtime SDK, [`crosswind-workers`](). They are not required, but they were built to make working with Python Workers that bit nicer: +Crosswind provides its own opinionated build tool [`wynd`](wynd/overview.md), and its own runtime SDK, [`crosswind-workers`](workers/overview.md). They are not required, but they were built to make working with Python Workers that bit nicer: - [x] Auto-magically generate typed `Env` stub. Workers using `crosswind-workers` can accept this as a generic! - [x] Keep Node.js build artifacts out of your Python codebase. -- [x] Write your worker configurations with a typed [`cloudflare.config.py`]() instead of using JSONC or TOML. +- [x] Write your worker configurations with a typed [`cloudflare.config.py`](wynd/python-config.md) instead of using JSONC or TOML. This is just a few things Crosswind gives you. You can choose to either `wynd` or `crosswind-workers`, both, or neither! All of Crosswind is still compatible with the official tools. diff --git a/docs/docs/wynd/python-config.md b/docs/docs/wynd/python-config.md index ae9222e..227507f 100644 --- a/docs/docs/wynd/python-config.md +++ b/docs/docs/wynd/python-config.md @@ -174,10 +174,34 @@ class Default(WorkerEntrypoint[Env]): leaves the binding out, so `"DEBUG": staging and bindings.Text("1")` exists only in staging. -`bindings.DurableObject("Counter")` names a class in `exports`, and -`exports.DurableObject()` declares that class with SQLite storage. Wynd -compiles both into the Wrangler config, so the Worker needs no -`migrations`. +A Durable Object, an agent included, needs two entries: + +```python +env={"COUNTER": bindings.DurableObject("Counter")}, # self.env.COUNTER in your code +exports={"Counter": exports.DurableObject()}, # the Counter class in src/main.py +``` + +- The `exports` key is the class name in your entry module. + `exports.DurableObject()` tells Cloudflare the class exists and gives it + SQLite storage. +- The `env` key is the binding name your code reads, as `self.env.COUNTER`. + `bindings.DurableObject("Counter")` points that name at the export. + +Wynd compiles these into Wrangler's `exports` and `durable_objects.bindings`. +A Wrangler file declares the class with a `migrations` entry instead, and you +add a new `tag` for each change. With Wynd you write no `migrations` and no +`tag`: + +- To add a class, add it to `exports` and give it a binding in `env`. +- To rename or remove a class, change its export to + `exports.RenamedDurableObject(...)` or `exports.DeletedDurableObject()`. + Don't delete the line, because the deployed class still holds data. See + [Exports](#exports). + +Cloudflare explains bindings in +[Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) +and Durable Objects in +[What are Durable Objects?](https://developers.cloudflare.com/durable-objects/concepts/what-are-durable-objects/). Set the secret's local value in `.dev.vars`, beside `cloudflare.config.py`: