@pouchy_ai/world-sdk 0.20.0 → 0.22.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 +36 -0
- package/dist/index.d.ts +88 -1
- package/dist/index.js +17 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @pouchy_ai/world-sdk
|
|
2
2
|
|
|
3
|
+
## 0.22.0
|
|
4
|
+
|
|
5
|
+
- **`startNextEpisode(environmentId, worldInstanceId)`** — start the next
|
|
6
|
+
episode of a worldline that just finished one, and receive the CARRYOVER.
|
|
7
|
+
- The worldline does **not** restart. Its `worldInstanceId`, membership, state
|
|
8
|
+
and ledger all continue; the episode moves on. Nothing is copied and nothing
|
|
9
|
+
is deleted, so there is no migration to get wrong.
|
|
10
|
+
- **Idempotent.** The run id is derived from the worldline, the episode and the
|
|
11
|
+
revision it starts at, so a retry lands on the same run and answers
|
|
12
|
+
`created: false` rather than forking the story.
|
|
13
|
+
- **Owner token only** — no `/admin` mirror, same reasoning as `preflightWorld`:
|
|
14
|
+
the mirror carries reads, and this is the write that decides a story moves on.
|
|
15
|
+
- New types: `WorldCarryoverV1`, `WorldNextEpisodeResponse`. The carryover is a
|
|
16
|
+
**projection** of facts the worldline already holds — canon it established,
|
|
17
|
+
where the characters stand, threads left hanging, setups never paid off.
|
|
18
|
+
Role-private notes are never in it, and no memory is carried because the world
|
|
19
|
+
runtime writes none.
|
|
20
|
+
- Server-side this is world API 1.28.0.
|
|
21
|
+
|
|
22
|
+
## 0.21.0
|
|
23
|
+
|
|
24
|
+
- **`WorldProgressCheckpointV1.episode`** — which episode a serial worldline is
|
|
25
|
+
playing, its beats-spent and turn budget, and the ending once it has one.
|
|
26
|
+
Absent for every world whose pinned story is not a serial, which is most of
|
|
27
|
+
them, so nothing an existing integration reads has changed shape.
|
|
28
|
+
- **Type-only.** No new method, no new route: `getProgress` already returned
|
|
29
|
+
this checkpoint and now returns one more optional field.
|
|
30
|
+
- `beatsCommitted` and `turnBudget` are two numbers, **not a ratio** — the same
|
|
31
|
+
rule as `completedNodeCount` / `declaredNodeCount`. A budget is the ceiling at
|
|
32
|
+
which the author's fallback ending fires, not a denominator of progress.
|
|
33
|
+
- `endingId` is decided **server-side** from committed state and the package's
|
|
34
|
+
declared rules. No client, prompt or model supplies it.
|
|
35
|
+
- Server-side this is world API 1.26.0 — Story Contract v3 (`series`). Publishing
|
|
36
|
+
a v3 package needs `POUCHY_STORY_CONTRACT_V3_WRITE` on the deployment; until
|
|
37
|
+
then such a publish is refused with `code: "story_contract_v3_write_disabled"`.
|
|
38
|
+
|
|
3
39
|
## 0.20.0
|
|
4
40
|
|
|
5
41
|
- **Seven methods for routes that already existed.** `getWorldOverview`,
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* a project is running — which is exactly the field you reach for when a
|
|
5
5
|
* customer's integration behaves like an older SDK than they say they have.
|
|
6
6
|
* It sat at '0.1.0' for eight releases before anything compared the two. */
|
|
7
|
-
export declare const WORLD_SDK_VERSION = "0.
|
|
7
|
+
export declare const WORLD_SDK_VERSION = "0.22.0";
|
|
8
8
|
export declare const DEFAULT_BASE_URL = "https://pouchy.ai/v1";
|
|
9
9
|
/** One direction a beat could take. The WHOLE of what a deliberation shows a
|
|
10
10
|
* player: no reasoning, no role secrets, no simulated effects, no scores. */
|
|
@@ -216,8 +216,81 @@ export interface WorldProgressCheckpointV1 {
|
|
|
216
216
|
branchId: string;
|
|
217
217
|
condition: string;
|
|
218
218
|
}>;
|
|
219
|
+
/** The episode this worldline is playing, when its pinned story is a
|
|
220
|
+
* serial. ABSENT for every non-serial world, which is most of them.
|
|
221
|
+
*
|
|
222
|
+
* `beatsCommitted` and `turnBudget` are two numbers, not a ratio — same
|
|
223
|
+
* rule as `completedNodeCount` / `declaredNodeCount`. A budget is the
|
|
224
|
+
* ceiling at which the author's fallback ending fires, not a denominator
|
|
225
|
+
* of progress.
|
|
226
|
+
*
|
|
227
|
+
* `endingId` appears only once the episode is over. It is decided
|
|
228
|
+
* server-side from committed state and the package's declared rules; no
|
|
229
|
+
* client, prompt or model supplies it. */
|
|
230
|
+
episode?: {
|
|
231
|
+
seriesId: string;
|
|
232
|
+
episodeId: string;
|
|
233
|
+
title: string;
|
|
234
|
+
status: 'active' | 'ended';
|
|
235
|
+
beatsCommitted: number;
|
|
236
|
+
turnBudget: number;
|
|
237
|
+
endingId?: string;
|
|
238
|
+
endingTitle?: string;
|
|
239
|
+
};
|
|
219
240
|
rebuildable: true;
|
|
220
241
|
}
|
|
242
|
+
/** What the next episode gets to stand on. A PROJECTION of facts the worldline
|
|
243
|
+
* already holds, not a copy of them — nothing is moved and nothing is deleted.
|
|
244
|
+
*
|
|
245
|
+
* Role-private notes are never here. Neither is memory: the world runtime
|
|
246
|
+
* writes none, so there is nothing to inherit. */
|
|
247
|
+
export interface WorldCarryoverV1 {
|
|
248
|
+
contractVersion: 1;
|
|
249
|
+
fromEpisodeId: string;
|
|
250
|
+
fromEndingId: string;
|
|
251
|
+
toEpisodeId: string;
|
|
252
|
+
/** Canon the previous episode established — ids AND the author's text. */
|
|
253
|
+
canonFacts: Array<{
|
|
254
|
+
factId: string;
|
|
255
|
+
text: string;
|
|
256
|
+
}>;
|
|
257
|
+
canonFactsTruncated: boolean;
|
|
258
|
+
/** Where the characters stand. Public by definition. */
|
|
259
|
+
relations: Array<{
|
|
260
|
+
between: [string, string];
|
|
261
|
+
descriptor: string;
|
|
262
|
+
}>;
|
|
263
|
+
relationsTruncated: boolean;
|
|
264
|
+
/** Declared nodes the previous episode never completed. */
|
|
265
|
+
unresolvedThreads: Array<{
|
|
266
|
+
nodeId: string;
|
|
267
|
+
objective: string;
|
|
268
|
+
}>;
|
|
269
|
+
unresolvedThreadsTruncated: boolean;
|
|
270
|
+
/** Declared facts never revealed — setups it did not pay off. Not called
|
|
271
|
+
* "promises": a promise is something a character made, which this system
|
|
272
|
+
* does not model. */
|
|
273
|
+
unfulfilledSetups: Array<{
|
|
274
|
+
factId: string;
|
|
275
|
+
text: string;
|
|
276
|
+
}>;
|
|
277
|
+
unfulfilledSetupsTruncated: boolean;
|
|
278
|
+
}
|
|
279
|
+
export interface WorldNextEpisodeResponse {
|
|
280
|
+
/** False on a retry that landed on the run already started. */
|
|
281
|
+
created: boolean;
|
|
282
|
+
episode: {
|
|
283
|
+
seriesId: string;
|
|
284
|
+
episodeId: string;
|
|
285
|
+
episodeRunId: string;
|
|
286
|
+
status: 'active' | 'ended';
|
|
287
|
+
startedAt: string;
|
|
288
|
+
startedAtRevision: number;
|
|
289
|
+
startedFromEpisodeId?: string;
|
|
290
|
+
startedFromEndingId?: string;
|
|
291
|
+
};
|
|
292
|
+
carryover: WorldCarryoverV1;
|
|
293
|
+
}
|
|
221
294
|
export interface WorldTurnReadback {
|
|
222
295
|
turnId: string;
|
|
223
296
|
worldInstanceId: string;
|
|
@@ -949,6 +1022,20 @@ export declare class PouchyWorldClient {
|
|
|
949
1022
|
* around: `getWorldOverview` carries `ready` and `blockers` and IS
|
|
950
1023
|
* mirrored, so a machine has the readiness answer it needs. */
|
|
951
1024
|
preflightWorld(environmentId: string): Promise<unknown>;
|
|
1025
|
+
/** Start the NEXT episode of a worldline that just finished one.
|
|
1026
|
+
*
|
|
1027
|
+
* The worldline does NOT restart. Its `worldInstanceId`, membership, state
|
|
1028
|
+
* and ledger all continue — that is the point — and this moves the episode
|
|
1029
|
+
* on and hands back the CARRYOVER: what the next episode gets to stand on.
|
|
1030
|
+
*
|
|
1031
|
+
* Idempotent. The run id is derived from the worldline, the episode and the
|
|
1032
|
+
* revision it starts at, so a retried call lands on the same run and
|
|
1033
|
+
* answers `created: false` rather than forking the story.
|
|
1034
|
+
*
|
|
1035
|
+
* OWNER TOKEN ONLY — no `/admin` mirror, on the same reasoning as
|
|
1036
|
+
* `preflightWorld`: the mirror carries reads, and this is the write that
|
|
1037
|
+
* decides a story moves on. */
|
|
1038
|
+
startNextEpisode(environmentId: string, worldInstanceId: string): Promise<WorldNextEpisodeResponse>;
|
|
952
1039
|
/** Publish the next world revision. Existing world INSTANCES keep the
|
|
953
1040
|
* revision they were created on — a published change reaches new instances
|
|
954
1041
|
* only, which is what keeps a running story from changing runtime or rules
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import { createHash, createHmac, randomUUID } from 'node:crypto';
|
|
|
23
23
|
* a project is running — which is exactly the field you reach for when a
|
|
24
24
|
* customer's integration behaves like an older SDK than they say they have.
|
|
25
25
|
* It sat at '0.1.0' for eight releases before anything compared the two. */
|
|
26
|
-
export const WORLD_SDK_VERSION = '0.
|
|
26
|
+
export const WORLD_SDK_VERSION = '0.22.0';
|
|
27
27
|
export const DEFAULT_BASE_URL = 'https://pouchy.ai/v1';
|
|
28
28
|
/** Read the commit turn id out of an envelope, so the signature covers the id
|
|
29
29
|
* the server will commit under. The payload half is base64url JSON; the
|
|
@@ -346,6 +346,22 @@ export class PouchyWorldClient {
|
|
|
346
346
|
preflightWorld(environmentId) {
|
|
347
347
|
return this.owner('GET', `/projects/${this.projectId}/environments/${environmentId}/preflight`);
|
|
348
348
|
}
|
|
349
|
+
/** Start the NEXT episode of a worldline that just finished one.
|
|
350
|
+
*
|
|
351
|
+
* The worldline does NOT restart. Its `worldInstanceId`, membership, state
|
|
352
|
+
* and ledger all continue — that is the point — and this moves the episode
|
|
353
|
+
* on and hands back the CARRYOVER: what the next episode gets to stand on.
|
|
354
|
+
*
|
|
355
|
+
* Idempotent. The run id is derived from the worldline, the episode and the
|
|
356
|
+
* revision it starts at, so a retried call lands on the same run and
|
|
357
|
+
* answers `created: false` rather than forking the story.
|
|
358
|
+
*
|
|
359
|
+
* OWNER TOKEN ONLY — no `/admin` mirror, on the same reasoning as
|
|
360
|
+
* `preflightWorld`: the mirror carries reads, and this is the write that
|
|
361
|
+
* decides a story moves on. */
|
|
362
|
+
startNextEpisode(environmentId, worldInstanceId) {
|
|
363
|
+
return this.owner('POST', `/projects/${this.projectId}/environments/${environmentId}/instances/${worldInstanceId}/episodes/next`, {});
|
|
364
|
+
}
|
|
349
365
|
/** Publish the next world revision. Existing world INSTANCES keep the
|
|
350
366
|
* revision they were created on — a published change reaches new instances
|
|
351
367
|
* only, which is what keeps a running story from changing runtime or rules
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/world-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Server-side TypeScript client for Pouchy World \u2014 story packages, world definitions, world sessions, coordinated turns, trusted events, replay verification and script drafts. Node only: it holds a project Secret Key and a source signing key, which never belong in a browser or a mobile app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|