@whitesands/agent-player 1.1.0 → 1.3.0
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.
- package/CHANGELOG.md +17 -0
- package/README.md +60 -5
- package/dist/index.cjs +887 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +321 -5
- package/dist/index.d.ts +321 -5
- package/dist/index.js +883 -49
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs +16 -3
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +31 -3
- package/dist/protocol.d.ts +31 -3
- package/dist/protocol.js +14 -2
- package/dist/protocol.js.map +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/{types-D0p6GrVs.d.cts → types-BcH7_ozx.d.ts} +43 -2
- package/dist/{types-DXM_HZHu.d.ts → types-gmAkYoQr.d.cts} +43 -2
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
- `start()` takes `memory`, `maxActions`, `subgoals` and `ownInstructions`.
|
|
6
|
+
- With `memory: true` the platform keeps the character's memory and relationships. `handle.observe(text, about)` adds an event without a turn, `handle.relationships()` reads how it feels about people, and `memory` and `relationship` events are emitted.
|
|
7
|
+
- `TurnResult.steps` lists every action when a turn played more than one.
|
|
8
|
+
- `World`: describe places, things and characters once; it builds each character's view and standard actions, carries speech, and decides when a character gets a turn. Port of `WSI.World` from the Luau SDK.
|
|
9
|
+
- `examples/town`: Sandy Shores as a browser game on `World`.
|
|
10
|
+
- A refused `start_session` now rejects `start()` with the platform's reason instead of timing out.
|
|
11
|
+
- A reconnect that fails part-way can no longer end the process with an unhandled "Timed out waiting for session resume".
|
|
12
|
+
|
|
13
|
+
## 1.2.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- Register a tool from a name, description, Zod schema, and callback with `bindDynamic`.
|
|
18
|
+
- `start()` requires `playerId`, the character UUID from the web app. One platform key serves the game, and each session names the character to play.
|
|
19
|
+
|
|
3
20
|
## 1.1.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ Use the same Zod 3 the SDK depends on when you declare argument schemas. Zod 4 o
|
|
|
40
40
|
|
|
41
41
|
## Usage
|
|
42
42
|
|
|
43
|
-
Set the platform key, then start one agent per character. `turn()` grants that character one chance to act and resolves with what they did.
|
|
43
|
+
Set the platform key, then start one agent per character. The key belongs to the game. `playerId` is the character id from the Players page, and every `start()` sends it. `turn()` grants that character one chance to act and resolves with what they did.
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
46
|
export WSI_PLATFORM_KEY=pk_...
|
|
@@ -53,6 +53,7 @@ import { AgentServer } from "@whitesands/agent-player";
|
|
|
53
53
|
|
|
54
54
|
const agents = new AgentServer();
|
|
55
55
|
const ada = await agents.start(new Villager(world, "Ada"), {
|
|
56
|
+
playerId: "3f6c2d1e-8b7a-4c5d-9e0f-1a2b3c4d5e6f",
|
|
56
57
|
name: "Ada",
|
|
57
58
|
goal: "Stand on the tree and chop it",
|
|
58
59
|
});
|
|
@@ -127,6 +128,28 @@ class Villager {
|
|
|
127
128
|
}
|
|
128
129
|
```
|
|
129
130
|
|
|
131
|
+
### Tools from data
|
|
132
|
+
|
|
133
|
+
`bindDynamic` registers one tool when the action is data rather than a method. Call it on the player before `start()`. `see` is allowed, including when the player has no `see()` method. `wait`, an empty name, a name starting with `_`, and a missing callback are rejected. An empty description becomes `Action: <name>`. Registering the same name again replaces that tool, including a reflected method of the same name.
|
|
134
|
+
|
|
135
|
+
Arguments use the same Zod shape as `static agent`. A schema failure throws before the callback runs and uses the one retry. Extra keys are ignored.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { AgentServer, bindDynamic } from "@whitesands/agent-player";
|
|
139
|
+
import { z } from "zod";
|
|
140
|
+
|
|
141
|
+
const scout = { n: 1 };
|
|
142
|
+
const playerId = "3f6c2d1e-8b7a-4c5d-9e0f-1a2b3c4d5e6f";
|
|
143
|
+
bindDynamic(scout, "see", "", undefined, () => ({ n: scout.n }));
|
|
144
|
+
bindDynamic(scout, "add", "Add dx", { dx: z.number().int() }, (args) => {
|
|
145
|
+
scout.n += args.dx as number;
|
|
146
|
+
return { n: scout.n };
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const agents = new AgentServer();
|
|
150
|
+
const agent = await agents.start(scout, { playerId });
|
|
151
|
+
```
|
|
152
|
+
|
|
130
153
|
### Turns
|
|
131
154
|
|
|
132
155
|
`turn()` does not choose the action. It unblocks that session's `wait`. The platform reads `see()`, calls one action, and reports back.
|
|
@@ -176,11 +199,19 @@ try {
|
|
|
176
199
|
|
|
177
200
|
### Several characters
|
|
178
201
|
|
|
179
|
-
One `AgentServer`
|
|
202
|
+
One `AgentServer` and one platform key host every character in the game. Each `start()` is its own session and names that character with `playerId`. The id is a UUID, and it stays the same when the character is renamed. A missing id, a value that is not a UUID, or an id from another game is rejected and no session is created.
|
|
180
203
|
|
|
181
204
|
```ts
|
|
182
|
-
const ada = await agents.start(new Villager(world, "Ada"), {
|
|
183
|
-
|
|
205
|
+
const ada = await agents.start(new Villager(world, "Ada"), {
|
|
206
|
+
playerId: "3f6c2d1e-8b7a-4c5d-9e0f-1a2b3c4d5e6f",
|
|
207
|
+
name: "Ada",
|
|
208
|
+
goal: "Chop the tree",
|
|
209
|
+
});
|
|
210
|
+
const bea = await agents.start(new Villager(world, "Bea"), {
|
|
211
|
+
playerId: "6b1e2a30-0c1d-4e5f-8a9b-0c1d2e3f4a5b",
|
|
212
|
+
name: "Bea",
|
|
213
|
+
goal: "Carry wood home",
|
|
214
|
+
});
|
|
184
215
|
|
|
185
216
|
await ada.turn();
|
|
186
217
|
await bea.turn();
|
|
@@ -234,6 +265,7 @@ const agents = new AgentServer({
|
|
|
234
265
|
|
|
235
266
|
```ts
|
|
236
267
|
await agents.start(ferry, {
|
|
268
|
+
playerId: "3f6c2d1e-8b7a-4c5d-9e0f-1a2b3c4d5e6f",
|
|
237
269
|
name: "Ferryman",
|
|
238
270
|
goal: "Get the wolf, the goat, and the cabbage onto the far bank.",
|
|
239
271
|
});
|
|
@@ -241,7 +273,7 @@ await agents.start(ferry, {
|
|
|
241
273
|
|
|
242
274
|
### Testing without a platform
|
|
243
275
|
|
|
244
|
-
`@whitesands/agent-player/testing` runs the same wait, act, and retry loop in memory. The script is the list of tool calls, in order. No key and no socket.
|
|
276
|
+
`@whitesands/agent-player/testing` runs the same wait, act, and retry loop in memory. The script is the list of tool calls, in order. No key and no socket. `start()` still requires `playerId`.
|
|
245
277
|
|
|
246
278
|
```ts
|
|
247
279
|
import { AgentServer } from "@whitesands/agent-player";
|
|
@@ -309,3 +341,26 @@ PLATFORM_KEY=pk_... npm run forest -- --remote
|
|
|
309
341
|
```
|
|
310
342
|
|
|
311
343
|
Releases are recorded in [CHANGELOG.md](CHANGELOG.md).
|
|
344
|
+
|
|
345
|
+
## World
|
|
346
|
+
|
|
347
|
+
`World` builds a living world on top of the agent player, so a game does not write a view or actions per character. The game provides the engine: places, things with activities, and a body per character (`getPosition`, `moveTo`, `stop`, `say`). `World` serves each character's tools over MCP (`say`, `go_to`, `approach`, `use`, `give`, `emote`, `idle`), carries speech between characters and players, and decides when a character needs a turn. Who each character is comes from its role and story on the platform.
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
import { AgentServer, World } from "@whitesands/agent-player";
|
|
351
|
+
|
|
352
|
+
const world = new World(new AgentServer(), { name: "Sandy Shores", about: "A small beach town." });
|
|
353
|
+
world.addPlace("cafe", { description: "Mia's cafe", position: { x: 60, y: 0 } });
|
|
354
|
+
world.addThing("espresso_machine", {
|
|
355
|
+
place: "cafe",
|
|
356
|
+
position: { x: 64, y: -4 },
|
|
357
|
+
activities: { make_coffee: { description: "Make a coffee", seconds: 6, gives: "coffee" } },
|
|
358
|
+
});
|
|
359
|
+
await world.addCharacter({ id: miaCharacterId, name: "Mia", body: miaBody, home: "cafe" });
|
|
360
|
+
world.addPerson({ name: "Alex", getPosition: () => alexPosition });
|
|
361
|
+
world.on((event) => { /* speech, relationship, status, give, thinking, turn */ });
|
|
362
|
+
world.start();
|
|
363
|
+
world.say("Alex", "Hi Mia!");
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
`examples/town` is a complete browser game built this way: `npm run build && WSI_PLATFORM_KEY=pk_... npm run town`, then open `http://localhost:8080`.
|