@game-infra/game-state-schemas 0.2.0 → 0.4.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/README.md +15 -1
- package/dist/freeformPayloads.d.ts +18 -0
- package/dist/freeformPayloads.d.ts.map +1 -1
- package/dist/freeformPayloads.js +15 -0
- package/dist/freeformPayloads.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/narrativeThreads.d.ts +458 -0
- package/dist/narrativeThreads.d.ts.map +1 -0
- package/dist/narrativeThreads.js +367 -0
- package/dist/narrativeThreads.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Keeping both in one resource meant one listing, one delete sweep and one retenti
|
|
|
24
24
|
// pnpm sibling checkout
|
|
25
25
|
"@game-infra/game-state-schemas": "link:../../game-infra/packages/schemas/game-state-schemas"
|
|
26
26
|
// or from npm
|
|
27
|
-
"@game-infra/game-state-schemas": "^0.
|
|
27
|
+
"@game-infra/game-state-schemas": "^0.2.0"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
`valibot` is a peer dependency (`^1.4.0`); the consumer provides it. `@game-infra/api-schemas-core` and `@game-infra/event-schemas` are runtime dependencies — the first for the success-response wrapper, the second for the `ActivationDTO` effect vocabulary a freeform turn shares with an authored story branch.
|
|
@@ -81,6 +81,20 @@ Memory is a synapse graph. Each `MemoryDTO` connects to **neurons** — `charact
|
|
|
81
81
|
|
|
82
82
|
None of these payload schemas is attached to an endpoint — the service stores `data` opaquely — but two clients reading the same session must agree on the shapes.
|
|
83
83
|
|
|
84
|
+
## Narrative threads — several scenes at once
|
|
85
|
+
|
|
86
|
+
A linear journal answers "what happened" with one list, which works until a player wants two things happening at once: a negotiation in the capital and a raid on the coast, each worth its own tab. Two of those cannot append to one list — whichever finished second would be narrated as though the first had already happened, and neither player intent was ever "and meanwhile, knowing that".
|
|
87
|
+
|
|
88
|
+
`NarrativeThreadPayloadSchema` makes a thread a **fork of the journal**. `baseSequence` is the whole of the fork: the number of canon turns the thread could see when it opened. Everything before it is shared; everything the thread writes lands after it and is invisible to its siblings until a merge. The trunk is the degenerate case — `CANON_THREAD_ID`, no parent, base zero. A turn records the thread that wrote it (`threadId`) and the index it held there before a merge renumbered it (`originSequence`); both are optional, so a journal written before threads existed still reads.
|
|
89
|
+
|
|
90
|
+
Convergence is where the honesty has to be. Two scenes written against the same past will sometimes contradict — a character killed in one and bargaining in the other, an item spent twice. `ThreadMergeReviewPayloadSchema` records the third answer between concatenating and refusing: the `ContradictionDTO`s found, graded `cosmetic` / `continuity` / `blocking`, and the `RetconDTO` amendments that reconcile them. A retcon may only `amend-narration`, `annotate`, `supersede-memory` or `reorder` — a merge agent that may rewrite anything can quietly delete a turn the player was proud of. Retcons are stored beside the journal rather than applied into it, so a reader sees both what was narrated and what was changed to make two scenes one story. `order` is the canon sequence the merge chose, recorded rather than re-derived: model finish times say when a call returned, not when a thing happened.
|
|
91
|
+
|
|
92
|
+
## Runs in flight
|
|
93
|
+
|
|
94
|
+
Resolving one turn is many model calls over many seconds, and a client that owns that work loses it whenever the browser reloads. `TurnRunPayloadSchema` is the run as a **server-owned, stage-checkpointed record**: `stages` in execution order with a `RunStageDTO` status each, and every partial output published the moment it exists — `check` as soon as the dice are rolled, `narration` as soon as the prose lands, `effects` once the consequences are interpreted, `memories` once the chronicler has been. A client renders whatever the record already carries and reattaches to a run in flight rather than restarting it.
|
|
95
|
+
|
|
96
|
+
`status` distinguishes the three states a progressive client actually needs: `running` (nothing to show yet), `narrated` (there is prose on screen) and `settling` (the prose is final, the bookkeeping is still going). `settling` is the one worth spelling out — chronicling and consolidation happen after the player is already reading, so the turn looks finished, but the next turn in the same thread must not start until they land or it is adjudicated against a memory graph missing the turn before it. `leaseUntil` tells a stalled run from a slow one: without it, a worker that dies mid-run leaves the record `running` forever and nothing else dares touch it.
|
|
97
|
+
|
|
84
98
|
## Savegames
|
|
85
99
|
|
|
86
100
|
Slot snapshots are `game-state-service`'s other half, but their contracts predate this package and stay where they are, in `@game-infra/api-schemas-core`: `savegameSaveContract`, `savegameLoadContract`, `savegameListSlotsContract`, at `/users/:userId/games/:gameId/saves/:saveSlot`. A published shape does not move just to sit next to its neighbours.
|
|
@@ -344,8 +344,26 @@ export declare const FreeformTurnPayloadSchema: import("valibot").ObjectSchema<{
|
|
|
344
344
|
readonly model: import("valibot").StringSchema<undefined>;
|
|
345
345
|
/** Milliseconds spent in each named generation-pipeline step. */
|
|
346
346
|
readonly timings: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").NumberSchema<undefined>, undefined>, undefined>;
|
|
347
|
+
/** Prompt and completion token counts spent in each named pipeline step. */
|
|
348
|
+
readonly tokenUsage: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").ObjectSchema<{
|
|
349
|
+
readonly inputTokens: import("valibot").NumberSchema<undefined>;
|
|
350
|
+
readonly outputTokens: import("valibot").NumberSchema<undefined>;
|
|
351
|
+
}, undefined>, undefined>, undefined>;
|
|
347
352
|
/** Effective canonical model used for each model-backed pipeline step. */
|
|
348
353
|
readonly stageModels: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
354
|
+
/**
|
|
355
|
+
* The narrative thread that wrote the turn, when the session runs more than
|
|
356
|
+
* one. Absent on a single-threaded journal, which is what every session
|
|
357
|
+
* written before threads existed is, so a reader treats absence as the canon
|
|
358
|
+
* thread rather than as a turn from nowhere.
|
|
359
|
+
*/
|
|
360
|
+
readonly threadId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
361
|
+
/**
|
|
362
|
+
* The index the turn held in its own thread, kept after a merge renumbers it
|
|
363
|
+
* into the canon. Without it a retcon addressed to `{ threadId, sequence }`
|
|
364
|
+
* stops naming anything the moment the merge lands.
|
|
365
|
+
*/
|
|
366
|
+
readonly originSequence: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
349
367
|
}, undefined>;
|
|
350
368
|
export type FreeformTurnPayload = InferOutput<typeof FreeformTurnPayloadSchema>;
|
|
351
369
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"freeformPayloads.d.ts","sourceRoot":"","sources":["../src/freeformPayloads.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"freeformPayloads.d.ts","sourceRoot":"","sources":["../src/freeformPayloads.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EASjB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAIxE;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,YAC3B,KAAK,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,OAAO,EACP,SAAS,EACT,OAAO,EACP,QAAQ,EACR,WAAW,EACX,QAAQ,CACA,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe;;IAE1B,iEAAiE;;IAEjE,sDAAsD;;IAEtD,+CAA+C;;IAE/C,qDAAqD;;aAErD,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,sBAAsB;IACjC,2CAA2C;;IAE3C,wCAAwC;;;QAvCxC,iEAAiE;;QAEjE,sDAAsD;;QAEtD,+CAA+C;;QAE/C,qDAAqD;;;aAmCrD,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;aAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE1E,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,YAAI,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,CAAU,CAAC;AAEpG,eAAO,MAAM,wBAAwB,6GAAkC,CAAC;AAExE,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE9E,iCAAiC;AACjC,eAAO,MAAM,iBAAiB,YAC5B,kBAAkB,EAClB,SAAS,EACT,SAAS,EACT,kBAAkB,CACV,CAAC;AAEX,eAAO,MAAM,qBAAqB,sHAA8B,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,sBAAsB;IACjC,0CAA0C;;IAE1C,4CAA4C;;;IAG5C,kDAAkD;;IAElD,2BAA2B;;IAE3B,gEAAgE;;;;;IAEhE,kCAAkC;;;aAGlC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB;;;aAGpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,yBAAyB;;IAEpC,wDAAwD;;IAExD,8DAA8D;;IAE9D,sDAAsD;;IAEtD,2EAA2E;;IAE3E,iEAAiE;;QAjFjE,0CAA0C;;QAE1C,4CAA4C;;;QAG5C,kDAAkD;;QAElD,2BAA2B;;QAE3B,gEAAgE;;;;;QAEhE,kCAAkC;;;;IAwElC,0EAA0E;;;;;IAE1E,wEAAwE;;;;;IAExE,qCAAqC;;;QAhMrC,iEAAiE;;QAEjE,sDAAsD;;QAEtD,+CAA+C;;QAE/C,qDAAqD;;;IA4LrD,gDAAgD;;QA7JhD,2CAA2C;;QAE3C,wCAAwC;;;YAvCxC,iEAAiE;;YAEjE,sDAAsD;;YAEtD,+CAA+C;;YAE/C,qDAAqD;;;;IA8LrD,+EAA+E;;IAE/E,iEAAiE;;IAEjE,4EAA4E;;;;;IAE5E,0EAA0E;;IAE1E;;;;;OAKG;;IAEH;;;;OAIG;;aAEH,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B;;IAEvC,kFAAkF;;aAElF,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,WAAW,CAAC,OAAO,4BAA4B,CAAC,CAAC"}
|
package/dist/freeformPayloads.js
CHANGED
|
@@ -296,8 +296,23 @@ export const FreeformTurnPayloadSchema = object({
|
|
|
296
296
|
model: string(),
|
|
297
297
|
/** Milliseconds spent in each named generation-pipeline step. */
|
|
298
298
|
timings: optional(record(string(), number())),
|
|
299
|
+
/** Prompt and completion token counts spent in each named pipeline step. */
|
|
300
|
+
tokenUsage: optional(record(string(), object({ inputTokens: number(), outputTokens: number() }))),
|
|
299
301
|
/** Effective canonical model used for each model-backed pipeline step. */
|
|
300
302
|
stageModels: optional(record(string(), string())),
|
|
303
|
+
/**
|
|
304
|
+
* The narrative thread that wrote the turn, when the session runs more than
|
|
305
|
+
* one. Absent on a single-threaded journal, which is what every session
|
|
306
|
+
* written before threads existed is, so a reader treats absence as the canon
|
|
307
|
+
* thread rather than as a turn from nowhere.
|
|
308
|
+
*/
|
|
309
|
+
threadId: optional(string()),
|
|
310
|
+
/**
|
|
311
|
+
* The index the turn held in its own thread, kept after a merge renumbers it
|
|
312
|
+
* into the canon. Without it a retcon addressed to `{ threadId, sequence }`
|
|
313
|
+
* stops naming anything the moment the merge lands.
|
|
314
|
+
*/
|
|
315
|
+
originSequence: optional(number()),
|
|
301
316
|
});
|
|
302
317
|
/**
|
|
303
318
|
* A freeform session's header payload — what goes inside a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"freeformPayloads.js","sourceRoot":"","sources":["../src/freeformPayloads.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"freeformPayloads.js","sourceRoot":"","sources":["../src/freeformPayloads.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -35,5 +35,7 @@ export { GameJournalAppendRequestSchema, GameJournalAppendResponseSchema, GameJo
|
|
|
35
35
|
export type { GameJournalAppendRequest, GameJournalAppendResponse, GameJournalEntryRecord, GameJournalListResponse, GameJournalTruncateResponse, GameSessionDeleteResponse, GameSessionListResponse, GameSessionLoadResponse, GameSessionRecord, GameSessionSaveRequest, GameSessionSaveResponse, JournalTruncation, } from "./sessionState.js";
|
|
36
36
|
export { CheckModifierDTOSchema, ConsolidationDTOSchema, FREEFORM_COMPLEXITIES, FREEFORM_DOMAINS, FREEFORM_OUTCOMES, FreeformComplexitySchema, FreeformOutcomeSchema, FreeformSessionPayloadSchema, FreeformTurnPayloadSchema, IntroducedEntityDTOSchema, MemoryDTOSchema, NEURON_KEY_SEPARATOR, ResolvedCheckDTOSchema, neuronKey, parseNeuronKey, } from "./freeformPayloads.js";
|
|
37
37
|
export type { CheckModifierDTO, ConsolidationDTO, FreeformComplexity, FreeformOutcome, FreeformSessionPayload, FreeformTurnPayload, IntroducedEntityDTO, MemoryDTO, ResolvedCheckDTO, } from "./freeformPayloads.js";
|
|
38
|
+
export { CANON_THREAD_ID, CONTRADICTION_SEVERITIES, ContradictionDTOSchema, ContradictionSeveritySchema, NarrativeThreadPayloadSchema, RETCON_KINDS, RUN_STAGE_STATUSES, RetconDTOSchema, RetconKindSchema, RunStageDTOSchema, RunStageStatusSchema, THREAD_STATUSES, TURN_RUN_STATUSES, ThreadMergeReviewPayloadSchema, ThreadStatusSchema, ThreadTurnRefSchema, TurnRunPayloadSchema, TurnRunStatusSchema, } from "./narrativeThreads.js";
|
|
39
|
+
export type { ContradictionDTO, ContradictionSeverity, NarrativeThreadPayload, RetconDTO, RetconKind, RunStageDTO, RunStageStatus, ThreadMergeReviewPayload, ThreadStatus, ThreadTurnRef, TurnRunPayload, TurnRunStatus, } from "./narrativeThreads.js";
|
|
38
40
|
export { gameJournalAppendContract, gameJournalListContract, gameJournalTruncateContract, gameSessionDeleteContract, gameSessionListContract, gameSessionLoadContract, gameSessionSaveContract, } from "./contracts.js";
|
|
39
41
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EACL,8BAA8B,EAC9B,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EACL,8BAA8B,EAC9B,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,8BAA8B,EAC9B,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,WAAW,EACX,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,10 @@ export { GameJournalAppendRequestSchema, GameJournalAppendResponseSchema, GameJo
|
|
|
38
38
|
// synapse memory graph — memories connected to neurons, consolidated over time
|
|
39
39
|
// — that decides what a narrator is reminded of.
|
|
40
40
|
export { CheckModifierDTOSchema, ConsolidationDTOSchema, FREEFORM_COMPLEXITIES, FREEFORM_DOMAINS, FREEFORM_OUTCOMES, FreeformComplexitySchema, FreeformOutcomeSchema, FreeformSessionPayloadSchema, FreeformTurnPayloadSchema, IntroducedEntityDTOSchema, MemoryDTOSchema, NEURON_KEY_SEPARATOR, ResolvedCheckDTOSchema, neuronKey, parseNeuronKey, } from "./freeformPayloads.js";
|
|
41
|
+
// Narrative threads: several scenes of one playthrough advancing at once, the
|
|
42
|
+
// merge that converges them (with the retcons that keep the canon honest), and
|
|
43
|
+
// the server-owned, stage-checkpointed record of the work in flight.
|
|
44
|
+
export { CANON_THREAD_ID, CONTRADICTION_SEVERITIES, ContradictionDTOSchema, ContradictionSeveritySchema, NarrativeThreadPayloadSchema, RETCON_KINDS, RUN_STAGE_STATUSES, RetconDTOSchema, RetconKindSchema, RunStageDTOSchema, RunStageStatusSchema, THREAD_STATUSES, TURN_RUN_STATUSES, ThreadMergeReviewPayloadSchema, ThreadStatusSchema, ThreadTurnRefSchema, TurnRunPayloadSchema, TurnRunStatusSchema, } from "./narrativeThreads.js";
|
|
41
45
|
// Typed endpoint contracts (toad-contracts). Each contract carries its own
|
|
42
46
|
// `pathResolver`; wire them into a client via @toad-contracts/frontend-http-client
|
|
43
47
|
// and into a Hono service via @toad-contracts/hono.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,2EAA2E;AAC3E,sDAAsD;AACtD,OAAO,EACL,8BAA8B,EAC9B,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAgB3B,0EAA0E;AAC1E,+EAA+E;AAC/E,iDAAiD;AACjD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,cAAc,GACf,MAAM,uBAAuB,CAAC;AAa/B,2EAA2E;AAC3E,mFAAmF;AACnF,oDAAoD;AACpD,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,2EAA2E;AAC3E,sDAAsD;AACtD,OAAO,EACL,8BAA8B,EAC9B,+BAA+B,EAC/B,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAgB3B,0EAA0E;AAC1E,+EAA+E;AAC/E,iDAAiD;AACjD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,cAAc,GACf,MAAM,uBAAuB,CAAC;AAa/B,8EAA8E;AAC9E,+EAA+E;AAC/E,qEAAqE;AACrE,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,8BAA8B,EAC9B,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAgB/B,2EAA2E;AAC3E,mFAAmF;AACnF,oDAAoD;AACpD,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import { type InferOutput } from "valibot";
|
|
2
|
+
/**
|
|
3
|
+
* **Narrative threads**: several scenes of one playthrough advancing at once,
|
|
4
|
+
* and the durable record of the work that advances them.
|
|
5
|
+
*
|
|
6
|
+
* A linear journal answers "what happened" with one list, which is the right
|
|
7
|
+
* shape right up until a player wants two things happening at once — a
|
|
8
|
+
* negotiation in the capital and a raid on the coast, each worth its own tab.
|
|
9
|
+
* Two of those cannot append to one list: whichever turn finished second would
|
|
10
|
+
* be narrated as though the first had already happened, and neither player
|
|
11
|
+
* intent was ever "and meanwhile, knowing that".
|
|
12
|
+
*
|
|
13
|
+
* So a thread is a **fork of the journal**, not a copy of the run. It records
|
|
14
|
+
* the point in the shared journal it forked from ({@link
|
|
15
|
+
* NarrativeThreadPayload.baseSequence}) and appends its own turns after it.
|
|
16
|
+
* Every thread reads the same state up to that point and none of them sees
|
|
17
|
+
* another's turns while they are still being written. Threads converge later,
|
|
18
|
+
* by a **merge**, which is the only moment their outputs meet.
|
|
19
|
+
*
|
|
20
|
+
* Convergence is where the honesty has to be. Two scenes written against the
|
|
21
|
+
* same past will sometimes contradict — a character killed in one and
|
|
22
|
+
* bargaining in the other, an item spent twice, two people in one room a
|
|
23
|
+
* province apart. A merge that simply concatenates produces a canon that reads
|
|
24
|
+
* as broken, and a merge that refuses produces a game that cannot use threads
|
|
25
|
+
* at all. {@link ThreadMergeReviewPayloadSchema} records the third answer: the
|
|
26
|
+
* contradictions found, and the {@link RetconDTOSchema} amendments that
|
|
27
|
+
* reconcile them, each naming the turn it rewrites and why. Retcons are stored
|
|
28
|
+
* rather than applied in place, so the journal keeps what was originally
|
|
29
|
+
* narrated and a reader can always see what was changed to make the two scenes
|
|
30
|
+
* one story.
|
|
31
|
+
*
|
|
32
|
+
* The third shape here is not about threads at all but about *time*. Resolving
|
|
33
|
+
* one turn is many model calls over many seconds, and a client that owns that
|
|
34
|
+
* work loses it whenever the browser reloads. {@link TurnRunPayloadSchema} is
|
|
35
|
+
* the run as a **server-owned, stage-checkpointed record**: every stage's
|
|
36
|
+
* status, and every partial output the moment it exists — the roll before the
|
|
37
|
+
* prose, the prose before the consequences, the chronicle after both. A client
|
|
38
|
+
* renders whatever the record already carries and reattaches to a run in
|
|
39
|
+
* flight rather than restarting it.
|
|
40
|
+
*
|
|
41
|
+
* As everywhere else in this package these are payload shapes, not endpoints:
|
|
42
|
+
* `game-state-service` stores `data` opaquely. They live here because two
|
|
43
|
+
* clients reading one playthrough have to agree on what a thread is.
|
|
44
|
+
*/
|
|
45
|
+
/** The trunk every playthrough starts on, and the thread a merge lands in. */
|
|
46
|
+
export declare const CANON_THREAD_ID = "canon";
|
|
47
|
+
/**
|
|
48
|
+
* Where a thread is in its life.
|
|
49
|
+
*
|
|
50
|
+
* `open` accepts turns. `merging` is under review by the merge agent and
|
|
51
|
+
* accepts none — a turn written against a base that is being rewritten is a
|
|
52
|
+
* contradiction manufactured after the fact. `merged` has been folded into the
|
|
53
|
+
* canon and is kept for the record. `abandoned` was closed without merging, and
|
|
54
|
+
* its turns are read as what-ifs rather than as things that happened.
|
|
55
|
+
*/
|
|
56
|
+
export declare const THREAD_STATUSES: readonly ["open", "merging", "merged", "abandoned"];
|
|
57
|
+
export declare const ThreadStatusSchema: import("valibot").PicklistSchema<readonly ["open", "merging", "merged", "abandoned"], undefined>;
|
|
58
|
+
export type ThreadStatus = InferOutput<typeof ThreadStatusSchema>;
|
|
59
|
+
/**
|
|
60
|
+
* One thread of a playthrough: a tab in the story.
|
|
61
|
+
*
|
|
62
|
+
* `baseSequence` is the whole of the fork: the number of canon turns the thread
|
|
63
|
+
* could see when it opened. Everything before it is shared with every other
|
|
64
|
+
* thread; everything the thread writes lands after it and is invisible to its
|
|
65
|
+
* siblings until a merge. The canon thread itself is the degenerate case —
|
|
66
|
+
* {@link CANON_THREAD_ID}, no parent, base zero.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import { CANON_THREAD_ID, type NarrativeThreadPayload } from '@game-infra/game-state-schemas'
|
|
71
|
+
*
|
|
72
|
+
* const raid: NarrativeThreadPayload = {
|
|
73
|
+
* id: 'the-coast-raid',
|
|
74
|
+
* title: 'The coast raid',
|
|
75
|
+
* parentThreadId: CANON_THREAD_ID,
|
|
76
|
+
* baseSequence: 12,
|
|
77
|
+
* status: 'open',
|
|
78
|
+
* createdAt: '2026-08-31T09:00:00.000Z',
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare const NarrativeThreadPayloadSchema: import("valibot").ObjectSchema<{
|
|
83
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
84
|
+
/** What to call the tab. */
|
|
85
|
+
readonly title: import("valibot").StringSchema<undefined>;
|
|
86
|
+
/** The thread this one forked from. Absent on the canon thread. */
|
|
87
|
+
readonly parentThreadId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
88
|
+
/** Canon turns visible to this thread. Its own turns are numbered from here. */
|
|
89
|
+
readonly baseSequence: import("valibot").NumberSchema<undefined>;
|
|
90
|
+
readonly status: import("valibot").PicklistSchema<readonly ["open", "merging", "merged", "abandoned"], undefined>;
|
|
91
|
+
readonly createdAt: import("valibot").StringSchema<undefined>;
|
|
92
|
+
/** Canon length after the merge that closed this thread, when one has. */
|
|
93
|
+
readonly mergedAtSequence: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
94
|
+
}, undefined>;
|
|
95
|
+
export type NarrativeThreadPayload = InferOutput<typeof NarrativeThreadPayloadSchema>;
|
|
96
|
+
/** One turn, addressed the way a merge has to address it: thread, then index. */
|
|
97
|
+
export declare const ThreadTurnRefSchema: import("valibot").ObjectSchema<{
|
|
98
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
99
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
100
|
+
}, undefined>;
|
|
101
|
+
export type ThreadTurnRef = InferOutput<typeof ThreadTurnRefSchema>;
|
|
102
|
+
/**
|
|
103
|
+
* How badly two threads disagree.
|
|
104
|
+
*
|
|
105
|
+
* `cosmetic` is a difference a reader would not notice and a merge may keep as
|
|
106
|
+
* it is. `continuity` is a fact stated two ways, which reads as sloppy and is
|
|
107
|
+
* what a retcon is for. `blocking` is a fact stated two ways where *both* are
|
|
108
|
+
* load-bearing — a character who cannot be both dead and negotiating — and the
|
|
109
|
+
* merge is not honest until something is amended.
|
|
110
|
+
*/
|
|
111
|
+
export declare const CONTRADICTION_SEVERITIES: readonly ["cosmetic", "continuity", "blocking"];
|
|
112
|
+
export declare const ContradictionSeveritySchema: import("valibot").PicklistSchema<readonly ["cosmetic", "continuity", "blocking"], undefined>;
|
|
113
|
+
export type ContradictionSeverity = InferOutput<typeof ContradictionSeveritySchema>;
|
|
114
|
+
/**
|
|
115
|
+
* One disagreement between threads, named so a reader can check the judgement.
|
|
116
|
+
*
|
|
117
|
+
* `between` carries the turns that disagree rather than a prose description of
|
|
118
|
+
* them, so a client can link straight to both sides instead of asking the
|
|
119
|
+
* reader to find them.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* import type { ContradictionDTO } from '@game-infra/game-state-schemas'
|
|
124
|
+
*
|
|
125
|
+
* const clash: ContradictionDTO = {
|
|
126
|
+
* id: 'k1',
|
|
127
|
+
* severity: 'blocking',
|
|
128
|
+
* description: 'Warden Ilse dies on the coast and opens the ledger in the capital.',
|
|
129
|
+
* between: [
|
|
130
|
+
* { threadId: 'the-coast-raid', sequence: 3 },
|
|
131
|
+
* { threadId: 'the-ledger', sequence: 2 },
|
|
132
|
+
* ],
|
|
133
|
+
* }
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare const ContradictionDTOSchema: import("valibot").ObjectSchema<{
|
|
137
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
138
|
+
readonly severity: import("valibot").PicklistSchema<readonly ["cosmetic", "continuity", "blocking"], undefined>;
|
|
139
|
+
/** What the two turns each claim, in one sentence. */
|
|
140
|
+
readonly description: import("valibot").StringSchema<undefined>;
|
|
141
|
+
/** The turns that disagree. At least two, or there is no disagreement. */
|
|
142
|
+
readonly between: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
143
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
144
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
145
|
+
}, undefined>, undefined>;
|
|
146
|
+
}, undefined>;
|
|
147
|
+
export type ContradictionDTO = InferOutput<typeof ContradictionDTOSchema>;
|
|
148
|
+
/**
|
|
149
|
+
* What a retcon is allowed to do.
|
|
150
|
+
*
|
|
151
|
+
* The list is short on purpose. A merge agent that may rewrite anything is one
|
|
152
|
+
* that can quietly delete a turn the player is proud of, and "the story changed
|
|
153
|
+
* while you were reading it" is worse than the contradiction it fixed.
|
|
154
|
+
*
|
|
155
|
+
* - `amend-narration` rewrites one turn's prose, keeping its check, effects and
|
|
156
|
+
* memories exactly as they were rolled and recorded.
|
|
157
|
+
* - `annotate` adds a reconciling sentence without touching what is already
|
|
158
|
+
* written — the answer when both turns are fine and only their meeting needs
|
|
159
|
+
* explaining.
|
|
160
|
+
* - `supersede-memory` retires memories that the merged canon has made false,
|
|
161
|
+
* which is the memory graph's own vocabulary rather than a new one.
|
|
162
|
+
* - `reorder` states that a turn belongs elsewhere in the canon order, which
|
|
163
|
+
* resolves most "meanwhile" contradictions without changing a word.
|
|
164
|
+
*/
|
|
165
|
+
export declare const RETCON_KINDS: readonly ["amend-narration", "annotate", "supersede-memory", "reorder"];
|
|
166
|
+
export declare const RetconKindSchema: import("valibot").PicklistSchema<readonly ["amend-narration", "annotate", "supersede-memory", "reorder"], undefined>;
|
|
167
|
+
export type RetconKind = InferOutput<typeof RetconKindSchema>;
|
|
168
|
+
/**
|
|
169
|
+
* One amendment the merge agent proposes, against one turn.
|
|
170
|
+
*
|
|
171
|
+
* Stored beside the journal rather than applied into it. The turn keeps what it
|
|
172
|
+
* originally said, the retcon says what it says now, and a reader can see both
|
|
173
|
+
* — which is the difference between a story that was reconciled and a story
|
|
174
|
+
* that was silently edited.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* import type { RetconDTO } from '@game-infra/game-state-schemas'
|
|
179
|
+
*
|
|
180
|
+
* const patch: RetconDTO = {
|
|
181
|
+
* id: 'r1',
|
|
182
|
+
* kind: 'amend-narration',
|
|
183
|
+
* target: { threadId: 'the-coast-raid', sequence: 3 },
|
|
184
|
+
* reason: 'Ilse cannot die here and open the ledger in the capital two turns later.',
|
|
185
|
+
* narration: 'The blade takes her shoulder, not her throat; she goes down cursing you.',
|
|
186
|
+
* resolves: ['k1'],
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
export declare const RetconDTOSchema: import("valibot").ObjectSchema<{
|
|
191
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
192
|
+
readonly kind: import("valibot").PicklistSchema<readonly ["amend-narration", "annotate", "supersede-memory", "reorder"], undefined>;
|
|
193
|
+
/** The turn being amended. */
|
|
194
|
+
readonly target: import("valibot").ObjectSchema<{
|
|
195
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
196
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
197
|
+
}, undefined>;
|
|
198
|
+
/** Why the amendment is needed, in the merge agent's own words. */
|
|
199
|
+
readonly reason: import("valibot").StringSchema<undefined>;
|
|
200
|
+
/** Replacement prose, for `amend-narration`. */
|
|
201
|
+
readonly narration: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
202
|
+
/** The reconciling sentence, for `annotate`. */
|
|
203
|
+
readonly note: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
204
|
+
/** Memories the merged canon has made false, for `supersede-memory`. */
|
|
205
|
+
readonly memoryIds: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
206
|
+
/** Canon position the turn should hold, for `reorder`. */
|
|
207
|
+
readonly sequence: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
208
|
+
/** The {@link ContradictionDTO} ids this amendment answers. */
|
|
209
|
+
readonly resolves: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
210
|
+
}, undefined>;
|
|
211
|
+
export type RetconDTO = InferOutput<typeof RetconDTOSchema>;
|
|
212
|
+
/**
|
|
213
|
+
* One merge: the threads that converged, what disagreed, what was amended, and
|
|
214
|
+
* the order the canon ended up in.
|
|
215
|
+
*
|
|
216
|
+
* `order` is the whole merge decision made explicit. Threads produce turns
|
|
217
|
+
* concurrently and their timestamps say only when a model finished, which is
|
|
218
|
+
* not when a thing happened; the merge agent decides the sequence the canon
|
|
219
|
+
* reads in and records it, so a replay is deterministic without re-asking a
|
|
220
|
+
* model what order the day went in.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import type { ThreadMergeReviewPayload } from '@game-infra/game-state-schemas'
|
|
225
|
+
*
|
|
226
|
+
* const review: ThreadMergeReviewPayload = {
|
|
227
|
+
* id: 'merge-0003',
|
|
228
|
+
* threadIds: ['the-coast-raid', 'the-ledger'],
|
|
229
|
+
* baseSequence: 12,
|
|
230
|
+
* order: [
|
|
231
|
+
* { threadId: 'the-ledger', sequence: 0 },
|
|
232
|
+
* { threadId: 'the-coast-raid', sequence: 0 },
|
|
233
|
+
* ],
|
|
234
|
+
* contradictions: [],
|
|
235
|
+
* retcons: [],
|
|
236
|
+
* summary: 'Two scenes, one afternoon, nothing in conflict.',
|
|
237
|
+
* model: 'aion',
|
|
238
|
+
* createdAt: '2026-08-31T09:31:00.000Z',
|
|
239
|
+
* }
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
export declare const ThreadMergeReviewPayloadSchema: import("valibot").ObjectSchema<{
|
|
243
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
244
|
+
/** The threads folded in, in the order they were opened. */
|
|
245
|
+
readonly threadIds: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
246
|
+
/** Canon length the threads shared before the merge. */
|
|
247
|
+
readonly baseSequence: import("valibot").NumberSchema<undefined>;
|
|
248
|
+
/** The canon order the merge chose, one entry per turn folded in. */
|
|
249
|
+
readonly order: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
250
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
251
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
252
|
+
}, undefined>, undefined>;
|
|
253
|
+
readonly contradictions: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
254
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
255
|
+
readonly severity: import("valibot").PicklistSchema<readonly ["cosmetic", "continuity", "blocking"], undefined>;
|
|
256
|
+
/** What the two turns each claim, in one sentence. */
|
|
257
|
+
readonly description: import("valibot").StringSchema<undefined>;
|
|
258
|
+
/** The turns that disagree. At least two, or there is no disagreement. */
|
|
259
|
+
readonly between: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
260
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
261
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
262
|
+
}, undefined>, undefined>;
|
|
263
|
+
}, undefined>, undefined>;
|
|
264
|
+
readonly retcons: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
265
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
266
|
+
readonly kind: import("valibot").PicklistSchema<readonly ["amend-narration", "annotate", "supersede-memory", "reorder"], undefined>;
|
|
267
|
+
/** The turn being amended. */
|
|
268
|
+
readonly target: import("valibot").ObjectSchema<{
|
|
269
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
270
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
271
|
+
}, undefined>;
|
|
272
|
+
/** Why the amendment is needed, in the merge agent's own words. */
|
|
273
|
+
readonly reason: import("valibot").StringSchema<undefined>;
|
|
274
|
+
/** Replacement prose, for `amend-narration`. */
|
|
275
|
+
readonly narration: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
276
|
+
/** The reconciling sentence, for `annotate`. */
|
|
277
|
+
readonly note: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
278
|
+
/** Memories the merged canon has made false, for `supersede-memory`. */
|
|
279
|
+
readonly memoryIds: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
280
|
+
/** Canon position the turn should hold, for `reorder`. */
|
|
281
|
+
readonly sequence: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
282
|
+
/** The {@link ContradictionDTO} ids this amendment answers. */
|
|
283
|
+
readonly resolves: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
284
|
+
}, undefined>, undefined>;
|
|
285
|
+
/** What the merge did, for a reader who does not want to read every retcon. */
|
|
286
|
+
readonly summary: import("valibot").StringSchema<undefined>;
|
|
287
|
+
/** The model that reviewed the merge. */
|
|
288
|
+
readonly model: import("valibot").StringSchema<undefined>;
|
|
289
|
+
readonly createdAt: import("valibot").StringSchema<undefined>;
|
|
290
|
+
}, undefined>;
|
|
291
|
+
export type ThreadMergeReviewPayload = InferOutput<typeof ThreadMergeReviewPayloadSchema>;
|
|
292
|
+
/**
|
|
293
|
+
* Where a run is. The three middle values are what a progressive client needs:
|
|
294
|
+
* they are the difference between "nothing to show yet", "there is prose on
|
|
295
|
+
* screen" and "the prose is final and the bookkeeping is still going".
|
|
296
|
+
*
|
|
297
|
+
* `settling` is the one worth spelling out. Chronicling and consolidation
|
|
298
|
+
* happen after the player is already reading, so the turn looks finished; but
|
|
299
|
+
* the next turn in the same thread must not start until they land, or it is
|
|
300
|
+
* adjudicated against a memory graph missing the turn before it.
|
|
301
|
+
*/
|
|
302
|
+
export declare const TURN_RUN_STATUSES: readonly ["queued", "running", "narrated", "settling", "completed", "failed", "cancelled"];
|
|
303
|
+
export declare const TurnRunStatusSchema: import("valibot").PicklistSchema<readonly ["queued", "running", "narrated", "settling", "completed", "failed", "cancelled"], undefined>;
|
|
304
|
+
export type TurnRunStatus = InferOutput<typeof TurnRunStatusSchema>;
|
|
305
|
+
/** Where one stage of a run is. `skipped` is a stage the turn did not need. */
|
|
306
|
+
export declare const RUN_STAGE_STATUSES: readonly ["pending", "running", "completed", "skipped", "failed"];
|
|
307
|
+
export declare const RunStageStatusSchema: import("valibot").PicklistSchema<readonly ["pending", "running", "completed", "skipped", "failed"], undefined>;
|
|
308
|
+
export type RunStageStatus = InferOutput<typeof RunStageStatusSchema>;
|
|
309
|
+
/**
|
|
310
|
+
* One stage of a run, as the server checkpoints it.
|
|
311
|
+
*
|
|
312
|
+
* `attempt` is stored rather than derived because a resumed run has to know
|
|
313
|
+
* whether it is retrying or starting: a stage that has already burnt its
|
|
314
|
+
* retries should fail the run rather than loop for as long as the storage
|
|
315
|
+
* keeps the record.
|
|
316
|
+
*/
|
|
317
|
+
export declare const RunStageDTOSchema: import("valibot").ObjectSchema<{
|
|
318
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
319
|
+
/** What to show a player waiting on it. */
|
|
320
|
+
readonly label: import("valibot").StringSchema<undefined>;
|
|
321
|
+
/** Which agent does the work — or the engine, for a local stage. */
|
|
322
|
+
readonly agent: import("valibot").StringSchema<undefined>;
|
|
323
|
+
/** The canonical model behind it, or `local` for a stage that asks nobody. */
|
|
324
|
+
readonly model: import("valibot").StringSchema<undefined>;
|
|
325
|
+
readonly status: import("valibot").PicklistSchema<readonly ["pending", "running", "completed", "skipped", "failed"], undefined>;
|
|
326
|
+
/** Epoch milliseconds; absent until the stage starts. */
|
|
327
|
+
readonly startedAt: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
328
|
+
readonly durationMs: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
329
|
+
/** Total prompt tokens consumed by successful calls in this stage. */
|
|
330
|
+
readonly inputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
331
|
+
/** Total completion tokens produced by successful calls in this stage. */
|
|
332
|
+
readonly outputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
333
|
+
readonly attempt: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
334
|
+
readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
335
|
+
}, undefined>;
|
|
336
|
+
export type RunStageDTO = InferOutput<typeof RunStageDTOSchema>;
|
|
337
|
+
/**
|
|
338
|
+
* One turn's adjudication, owned by the server and readable at any moment.
|
|
339
|
+
*
|
|
340
|
+
* This is the record that makes a reload survivable. The work belongs to the
|
|
341
|
+
* service rather than to the tab that asked for it, every stage is written down
|
|
342
|
+
* as it finishes, and each output is published the moment it exists rather than
|
|
343
|
+
* at the end: `check` as soon as the dice are rolled, `narration` as soon as
|
|
344
|
+
* the prose lands, `effects` once the consequences are interpreted, `memories`
|
|
345
|
+
* once the chronicler has been. A client that reconnects renders whatever is
|
|
346
|
+
* already here and waits only for what is genuinely still missing.
|
|
347
|
+
*
|
|
348
|
+
* `leaseUntil` is how a stalled run is told from a slow one. A worker that dies
|
|
349
|
+
* mid-run leaves the record `running` forever otherwise, and nothing else dares
|
|
350
|
+
* touch it; with a lease, whoever finds it expired may resume from the last
|
|
351
|
+
* completed stage.
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```ts
|
|
355
|
+
* import type { TurnRunPayload } from '@game-infra/game-state-schemas'
|
|
356
|
+
*
|
|
357
|
+
* const run: TurnRunPayload = {
|
|
358
|
+
* id: 'run-8f2c',
|
|
359
|
+
* threadId: 'the-coast-raid',
|
|
360
|
+
* sequence: 3,
|
|
361
|
+
* input: 'I put my shoulder to the door and shout for Ilse.',
|
|
362
|
+
* status: 'narrated',
|
|
363
|
+
* stages: [
|
|
364
|
+
* { id: 'assessment', label: 'Choosing whether and how to roll',
|
|
365
|
+
* agent: 'Assessor', model: 'aion-mini', status: 'completed', durationMs: 1840 },
|
|
366
|
+
* ],
|
|
367
|
+
* traceId: 'turn-8f2c',
|
|
368
|
+
* startedAt: '2026-08-31T09:12:00.000Z',
|
|
369
|
+
* updatedAt: '2026-08-31T09:12:09.000Z',
|
|
370
|
+
* }
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
export declare const TurnRunPayloadSchema: import("valibot").ObjectSchema<{
|
|
374
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
375
|
+
readonly threadId: import("valibot").StringSchema<undefined>;
|
|
376
|
+
/** The index this turn takes in its thread. */
|
|
377
|
+
readonly sequence: import("valibot").NumberSchema<undefined>;
|
|
378
|
+
/** What the player wrote. Empty on a session's opening turn. */
|
|
379
|
+
readonly input: import("valibot").StringSchema<undefined>;
|
|
380
|
+
readonly status: import("valibot").PicklistSchema<readonly ["queued", "running", "narrated", "settling", "completed", "failed", "cancelled"], undefined>;
|
|
381
|
+
/** Every stage, in execution order, whether or not it has run. */
|
|
382
|
+
readonly stages: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
383
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
384
|
+
/** What to show a player waiting on it. */
|
|
385
|
+
readonly label: import("valibot").StringSchema<undefined>;
|
|
386
|
+
/** Which agent does the work — or the engine, for a local stage. */
|
|
387
|
+
readonly agent: import("valibot").StringSchema<undefined>;
|
|
388
|
+
/** The canonical model behind it, or `local` for a stage that asks nobody. */
|
|
389
|
+
readonly model: import("valibot").StringSchema<undefined>;
|
|
390
|
+
readonly status: import("valibot").PicklistSchema<readonly ["pending", "running", "completed", "skipped", "failed"], undefined>;
|
|
391
|
+
/** Epoch milliseconds; absent until the stage starts. */
|
|
392
|
+
readonly startedAt: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
393
|
+
readonly durationMs: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
394
|
+
/** Total prompt tokens consumed by successful calls in this stage. */
|
|
395
|
+
readonly inputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
396
|
+
/** Total completion tokens produced by successful calls in this stage. */
|
|
397
|
+
readonly outputTokens: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
398
|
+
readonly attempt: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
399
|
+
readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
400
|
+
}, undefined>, undefined>;
|
|
401
|
+
/** Joins every model call this run made. */
|
|
402
|
+
readonly traceId: import("valibot").StringSchema<undefined>;
|
|
403
|
+
readonly startedAt: import("valibot").StringSchema<undefined>;
|
|
404
|
+
readonly updatedAt: import("valibot").StringSchema<undefined>;
|
|
405
|
+
/** Epoch milliseconds after which an unfinished run may be resumed by anyone. */
|
|
406
|
+
readonly leaseUntil: import("valibot").OptionalSchema<import("valibot").NumberSchema<undefined>, undefined>;
|
|
407
|
+
/** The neurons the assessor judged relevant. */
|
|
408
|
+
readonly focus: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
409
|
+
/** The roll — available before a word of prose has been written. */
|
|
410
|
+
readonly check: import("valibot").OptionalSchema<import("valibot").ObjectSchema<{
|
|
411
|
+
readonly skillId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
412
|
+
readonly statId: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
413
|
+
readonly complexity: import("valibot").PicklistSchema<readonly ["trivial", "easy", "moderate", "hard", "formidable"], undefined>;
|
|
414
|
+
readonly difficulty: import("valibot").NumberSchema<undefined>;
|
|
415
|
+
readonly roll: import("valibot").NumberSchema<undefined>;
|
|
416
|
+
readonly modifiers: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
417
|
+
readonly label: import("valibot").StringSchema<undefined>;
|
|
418
|
+
readonly amount: import("valibot").NumberSchema<undefined>;
|
|
419
|
+
}, undefined>, undefined>;
|
|
420
|
+
readonly total: import("valibot").NumberSchema<undefined>;
|
|
421
|
+
readonly outcome: import("valibot").PicklistSchema<readonly ["critical-success", "success", "failure", "critical-failure"], undefined>;
|
|
422
|
+
}, undefined>, undefined>;
|
|
423
|
+
readonly title: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
424
|
+
readonly narration: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
425
|
+
readonly effects: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
426
|
+
readonly type: import("valibot").StringSchema<undefined>;
|
|
427
|
+
readonly params: import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").UnknownSchema, undefined>;
|
|
428
|
+
}, undefined>, undefined>, undefined>;
|
|
429
|
+
readonly introduced: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").LooseObjectSchema<{
|
|
430
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
431
|
+
readonly name: import("valibot").StringSchema<undefined>;
|
|
432
|
+
}, undefined>, undefined>, undefined>;
|
|
433
|
+
readonly memories: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
434
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
435
|
+
readonly text: import("valibot").StringSchema<undefined>;
|
|
436
|
+
readonly neuronIds: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
437
|
+
readonly turn: import("valibot").NumberSchema<undefined>;
|
|
438
|
+
readonly weight: import("valibot").NumberSchema<undefined>;
|
|
439
|
+
}, undefined>, undefined>, undefined>;
|
|
440
|
+
readonly consolidations: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
441
|
+
readonly memoryIds: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
442
|
+
readonly memory: import("valibot").ObjectSchema<{
|
|
443
|
+
readonly id: import("valibot").StringSchema<undefined>;
|
|
444
|
+
readonly text: import("valibot").StringSchema<undefined>;
|
|
445
|
+
readonly neuronIds: import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
446
|
+
readonly turn: import("valibot").NumberSchema<undefined>;
|
|
447
|
+
readonly weight: import("valibot").NumberSchema<undefined>;
|
|
448
|
+
}, undefined>;
|
|
449
|
+
}, undefined>, undefined>, undefined>;
|
|
450
|
+
/** The model that narrated, once one has. */
|
|
451
|
+
readonly model: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
452
|
+
/** Milliseconds per named stage, as they complete. */
|
|
453
|
+
readonly timings: import("valibot").OptionalSchema<import("valibot").RecordSchema<import("valibot").StringSchema<undefined>, import("valibot").NumberSchema<undefined>, undefined>, undefined>;
|
|
454
|
+
/** Why the run failed, when it did. */
|
|
455
|
+
readonly error: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
456
|
+
}, undefined>;
|
|
457
|
+
export type TurnRunPayload = InferOutput<typeof TurnRunPayloadSchema>;
|
|
458
|
+
//# sourceMappingURL=narrativeThreads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"narrativeThreads.d.ts","sourceRoot":"","sources":["../src/narrativeThreads.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { ActivationDTOSchema } from "@game-infra/event-schemas";
|
|
2
|
+
import { array, number, object, optional, picklist, record, string, } from "valibot";
|
|
3
|
+
import { ConsolidationDTOSchema, IntroducedEntityDTOSchema, MemoryDTOSchema, ResolvedCheckDTOSchema, } from "./freeformPayloads.js";
|
|
4
|
+
/**
|
|
5
|
+
* **Narrative threads**: several scenes of one playthrough advancing at once,
|
|
6
|
+
* and the durable record of the work that advances them.
|
|
7
|
+
*
|
|
8
|
+
* A linear journal answers "what happened" with one list, which is the right
|
|
9
|
+
* shape right up until a player wants two things happening at once — a
|
|
10
|
+
* negotiation in the capital and a raid on the coast, each worth its own tab.
|
|
11
|
+
* Two of those cannot append to one list: whichever turn finished second would
|
|
12
|
+
* be narrated as though the first had already happened, and neither player
|
|
13
|
+
* intent was ever "and meanwhile, knowing that".
|
|
14
|
+
*
|
|
15
|
+
* So a thread is a **fork of the journal**, not a copy of the run. It records
|
|
16
|
+
* the point in the shared journal it forked from ({@link
|
|
17
|
+
* NarrativeThreadPayload.baseSequence}) and appends its own turns after it.
|
|
18
|
+
* Every thread reads the same state up to that point and none of them sees
|
|
19
|
+
* another's turns while they are still being written. Threads converge later,
|
|
20
|
+
* by a **merge**, which is the only moment their outputs meet.
|
|
21
|
+
*
|
|
22
|
+
* Convergence is where the honesty has to be. Two scenes written against the
|
|
23
|
+
* same past will sometimes contradict — a character killed in one and
|
|
24
|
+
* bargaining in the other, an item spent twice, two people in one room a
|
|
25
|
+
* province apart. A merge that simply concatenates produces a canon that reads
|
|
26
|
+
* as broken, and a merge that refuses produces a game that cannot use threads
|
|
27
|
+
* at all. {@link ThreadMergeReviewPayloadSchema} records the third answer: the
|
|
28
|
+
* contradictions found, and the {@link RetconDTOSchema} amendments that
|
|
29
|
+
* reconcile them, each naming the turn it rewrites and why. Retcons are stored
|
|
30
|
+
* rather than applied in place, so the journal keeps what was originally
|
|
31
|
+
* narrated and a reader can always see what was changed to make the two scenes
|
|
32
|
+
* one story.
|
|
33
|
+
*
|
|
34
|
+
* The third shape here is not about threads at all but about *time*. Resolving
|
|
35
|
+
* one turn is many model calls over many seconds, and a client that owns that
|
|
36
|
+
* work loses it whenever the browser reloads. {@link TurnRunPayloadSchema} is
|
|
37
|
+
* the run as a **server-owned, stage-checkpointed record**: every stage's
|
|
38
|
+
* status, and every partial output the moment it exists — the roll before the
|
|
39
|
+
* prose, the prose before the consequences, the chronicle after both. A client
|
|
40
|
+
* renders whatever the record already carries and reattaches to a run in
|
|
41
|
+
* flight rather than restarting it.
|
|
42
|
+
*
|
|
43
|
+
* As everywhere else in this package these are payload shapes, not endpoints:
|
|
44
|
+
* `game-state-service` stores `data` opaquely. They live here because two
|
|
45
|
+
* clients reading one playthrough have to agree on what a thread is.
|
|
46
|
+
*/
|
|
47
|
+
/** The trunk every playthrough starts on, and the thread a merge lands in. */
|
|
48
|
+
export const CANON_THREAD_ID = "canon";
|
|
49
|
+
/**
|
|
50
|
+
* Where a thread is in its life.
|
|
51
|
+
*
|
|
52
|
+
* `open` accepts turns. `merging` is under review by the merge agent and
|
|
53
|
+
* accepts none — a turn written against a base that is being rewritten is a
|
|
54
|
+
* contradiction manufactured after the fact. `merged` has been folded into the
|
|
55
|
+
* canon and is kept for the record. `abandoned` was closed without merging, and
|
|
56
|
+
* its turns are read as what-ifs rather than as things that happened.
|
|
57
|
+
*/
|
|
58
|
+
export const THREAD_STATUSES = ["open", "merging", "merged", "abandoned"];
|
|
59
|
+
export const ThreadStatusSchema = picklist(THREAD_STATUSES);
|
|
60
|
+
/**
|
|
61
|
+
* One thread of a playthrough: a tab in the story.
|
|
62
|
+
*
|
|
63
|
+
* `baseSequence` is the whole of the fork: the number of canon turns the thread
|
|
64
|
+
* could see when it opened. Everything before it is shared with every other
|
|
65
|
+
* thread; everything the thread writes lands after it and is invisible to its
|
|
66
|
+
* siblings until a merge. The canon thread itself is the degenerate case —
|
|
67
|
+
* {@link CANON_THREAD_ID}, no parent, base zero.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* import { CANON_THREAD_ID, type NarrativeThreadPayload } from '@game-infra/game-state-schemas'
|
|
72
|
+
*
|
|
73
|
+
* const raid: NarrativeThreadPayload = {
|
|
74
|
+
* id: 'the-coast-raid',
|
|
75
|
+
* title: 'The coast raid',
|
|
76
|
+
* parentThreadId: CANON_THREAD_ID,
|
|
77
|
+
* baseSequence: 12,
|
|
78
|
+
* status: 'open',
|
|
79
|
+
* createdAt: '2026-08-31T09:00:00.000Z',
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export const NarrativeThreadPayloadSchema = object({
|
|
84
|
+
id: string(),
|
|
85
|
+
/** What to call the tab. */
|
|
86
|
+
title: string(),
|
|
87
|
+
/** The thread this one forked from. Absent on the canon thread. */
|
|
88
|
+
parentThreadId: optional(string()),
|
|
89
|
+
/** Canon turns visible to this thread. Its own turns are numbered from here. */
|
|
90
|
+
baseSequence: number(),
|
|
91
|
+
status: ThreadStatusSchema,
|
|
92
|
+
createdAt: string(),
|
|
93
|
+
/** Canon length after the merge that closed this thread, when one has. */
|
|
94
|
+
mergedAtSequence: optional(number()),
|
|
95
|
+
});
|
|
96
|
+
/** One turn, addressed the way a merge has to address it: thread, then index. */
|
|
97
|
+
export const ThreadTurnRefSchema = object({
|
|
98
|
+
threadId: string(),
|
|
99
|
+
sequence: number(),
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* How badly two threads disagree.
|
|
103
|
+
*
|
|
104
|
+
* `cosmetic` is a difference a reader would not notice and a merge may keep as
|
|
105
|
+
* it is. `continuity` is a fact stated two ways, which reads as sloppy and is
|
|
106
|
+
* what a retcon is for. `blocking` is a fact stated two ways where *both* are
|
|
107
|
+
* load-bearing — a character who cannot be both dead and negotiating — and the
|
|
108
|
+
* merge is not honest until something is amended.
|
|
109
|
+
*/
|
|
110
|
+
export const CONTRADICTION_SEVERITIES = ["cosmetic", "continuity", "blocking"];
|
|
111
|
+
export const ContradictionSeveritySchema = picklist(CONTRADICTION_SEVERITIES);
|
|
112
|
+
/**
|
|
113
|
+
* One disagreement between threads, named so a reader can check the judgement.
|
|
114
|
+
*
|
|
115
|
+
* `between` carries the turns that disagree rather than a prose description of
|
|
116
|
+
* them, so a client can link straight to both sides instead of asking the
|
|
117
|
+
* reader to find them.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* import type { ContradictionDTO } from '@game-infra/game-state-schemas'
|
|
122
|
+
*
|
|
123
|
+
* const clash: ContradictionDTO = {
|
|
124
|
+
* id: 'k1',
|
|
125
|
+
* severity: 'blocking',
|
|
126
|
+
* description: 'Warden Ilse dies on the coast and opens the ledger in the capital.',
|
|
127
|
+
* between: [
|
|
128
|
+
* { threadId: 'the-coast-raid', sequence: 3 },
|
|
129
|
+
* { threadId: 'the-ledger', sequence: 2 },
|
|
130
|
+
* ],
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export const ContradictionDTOSchema = object({
|
|
135
|
+
id: string(),
|
|
136
|
+
severity: ContradictionSeveritySchema,
|
|
137
|
+
/** What the two turns each claim, in one sentence. */
|
|
138
|
+
description: string(),
|
|
139
|
+
/** The turns that disagree. At least two, or there is no disagreement. */
|
|
140
|
+
between: array(ThreadTurnRefSchema),
|
|
141
|
+
});
|
|
142
|
+
/**
|
|
143
|
+
* What a retcon is allowed to do.
|
|
144
|
+
*
|
|
145
|
+
* The list is short on purpose. A merge agent that may rewrite anything is one
|
|
146
|
+
* that can quietly delete a turn the player is proud of, and "the story changed
|
|
147
|
+
* while you were reading it" is worse than the contradiction it fixed.
|
|
148
|
+
*
|
|
149
|
+
* - `amend-narration` rewrites one turn's prose, keeping its check, effects and
|
|
150
|
+
* memories exactly as they were rolled and recorded.
|
|
151
|
+
* - `annotate` adds a reconciling sentence without touching what is already
|
|
152
|
+
* written — the answer when both turns are fine and only their meeting needs
|
|
153
|
+
* explaining.
|
|
154
|
+
* - `supersede-memory` retires memories that the merged canon has made false,
|
|
155
|
+
* which is the memory graph's own vocabulary rather than a new one.
|
|
156
|
+
* - `reorder` states that a turn belongs elsewhere in the canon order, which
|
|
157
|
+
* resolves most "meanwhile" contradictions without changing a word.
|
|
158
|
+
*/
|
|
159
|
+
export const RETCON_KINDS = ["amend-narration", "annotate", "supersede-memory", "reorder"];
|
|
160
|
+
export const RetconKindSchema = picklist(RETCON_KINDS);
|
|
161
|
+
/**
|
|
162
|
+
* One amendment the merge agent proposes, against one turn.
|
|
163
|
+
*
|
|
164
|
+
* Stored beside the journal rather than applied into it. The turn keeps what it
|
|
165
|
+
* originally said, the retcon says what it says now, and a reader can see both
|
|
166
|
+
* — which is the difference between a story that was reconciled and a story
|
|
167
|
+
* that was silently edited.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* import type { RetconDTO } from '@game-infra/game-state-schemas'
|
|
172
|
+
*
|
|
173
|
+
* const patch: RetconDTO = {
|
|
174
|
+
* id: 'r1',
|
|
175
|
+
* kind: 'amend-narration',
|
|
176
|
+
* target: { threadId: 'the-coast-raid', sequence: 3 },
|
|
177
|
+
* reason: 'Ilse cannot die here and open the ledger in the capital two turns later.',
|
|
178
|
+
* narration: 'The blade takes her shoulder, not her throat; she goes down cursing you.',
|
|
179
|
+
* resolves: ['k1'],
|
|
180
|
+
* }
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export const RetconDTOSchema = object({
|
|
184
|
+
id: string(),
|
|
185
|
+
kind: RetconKindSchema,
|
|
186
|
+
/** The turn being amended. */
|
|
187
|
+
target: ThreadTurnRefSchema,
|
|
188
|
+
/** Why the amendment is needed, in the merge agent's own words. */
|
|
189
|
+
reason: string(),
|
|
190
|
+
/** Replacement prose, for `amend-narration`. */
|
|
191
|
+
narration: optional(string()),
|
|
192
|
+
/** The reconciling sentence, for `annotate`. */
|
|
193
|
+
note: optional(string()),
|
|
194
|
+
/** Memories the merged canon has made false, for `supersede-memory`. */
|
|
195
|
+
memoryIds: optional(array(string())),
|
|
196
|
+
/** Canon position the turn should hold, for `reorder`. */
|
|
197
|
+
sequence: optional(number()),
|
|
198
|
+
/** The {@link ContradictionDTO} ids this amendment answers. */
|
|
199
|
+
resolves: array(string()),
|
|
200
|
+
});
|
|
201
|
+
/**
|
|
202
|
+
* One merge: the threads that converged, what disagreed, what was amended, and
|
|
203
|
+
* the order the canon ended up in.
|
|
204
|
+
*
|
|
205
|
+
* `order` is the whole merge decision made explicit. Threads produce turns
|
|
206
|
+
* concurrently and their timestamps say only when a model finished, which is
|
|
207
|
+
* not when a thing happened; the merge agent decides the sequence the canon
|
|
208
|
+
* reads in and records it, so a replay is deterministic without re-asking a
|
|
209
|
+
* model what order the day went in.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* import type { ThreadMergeReviewPayload } from '@game-infra/game-state-schemas'
|
|
214
|
+
*
|
|
215
|
+
* const review: ThreadMergeReviewPayload = {
|
|
216
|
+
* id: 'merge-0003',
|
|
217
|
+
* threadIds: ['the-coast-raid', 'the-ledger'],
|
|
218
|
+
* baseSequence: 12,
|
|
219
|
+
* order: [
|
|
220
|
+
* { threadId: 'the-ledger', sequence: 0 },
|
|
221
|
+
* { threadId: 'the-coast-raid', sequence: 0 },
|
|
222
|
+
* ],
|
|
223
|
+
* contradictions: [],
|
|
224
|
+
* retcons: [],
|
|
225
|
+
* summary: 'Two scenes, one afternoon, nothing in conflict.',
|
|
226
|
+
* model: 'aion',
|
|
227
|
+
* createdAt: '2026-08-31T09:31:00.000Z',
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export const ThreadMergeReviewPayloadSchema = object({
|
|
232
|
+
id: string(),
|
|
233
|
+
/** The threads folded in, in the order they were opened. */
|
|
234
|
+
threadIds: array(string()),
|
|
235
|
+
/** Canon length the threads shared before the merge. */
|
|
236
|
+
baseSequence: number(),
|
|
237
|
+
/** The canon order the merge chose, one entry per turn folded in. */
|
|
238
|
+
order: array(ThreadTurnRefSchema),
|
|
239
|
+
contradictions: array(ContradictionDTOSchema),
|
|
240
|
+
retcons: array(RetconDTOSchema),
|
|
241
|
+
/** What the merge did, for a reader who does not want to read every retcon. */
|
|
242
|
+
summary: string(),
|
|
243
|
+
/** The model that reviewed the merge. */
|
|
244
|
+
model: string(),
|
|
245
|
+
createdAt: string(),
|
|
246
|
+
});
|
|
247
|
+
/**
|
|
248
|
+
* Where a run is. The three middle values are what a progressive client needs:
|
|
249
|
+
* they are the difference between "nothing to show yet", "there is prose on
|
|
250
|
+
* screen" and "the prose is final and the bookkeeping is still going".
|
|
251
|
+
*
|
|
252
|
+
* `settling` is the one worth spelling out. Chronicling and consolidation
|
|
253
|
+
* happen after the player is already reading, so the turn looks finished; but
|
|
254
|
+
* the next turn in the same thread must not start until they land, or it is
|
|
255
|
+
* adjudicated against a memory graph missing the turn before it.
|
|
256
|
+
*/
|
|
257
|
+
export const TURN_RUN_STATUSES = [
|
|
258
|
+
"queued",
|
|
259
|
+
"running",
|
|
260
|
+
"narrated",
|
|
261
|
+
"settling",
|
|
262
|
+
"completed",
|
|
263
|
+
"failed",
|
|
264
|
+
"cancelled",
|
|
265
|
+
];
|
|
266
|
+
export const TurnRunStatusSchema = picklist(TURN_RUN_STATUSES);
|
|
267
|
+
/** Where one stage of a run is. `skipped` is a stage the turn did not need. */
|
|
268
|
+
export const RUN_STAGE_STATUSES = ["pending", "running", "completed", "skipped", "failed"];
|
|
269
|
+
export const RunStageStatusSchema = picklist(RUN_STAGE_STATUSES);
|
|
270
|
+
/**
|
|
271
|
+
* One stage of a run, as the server checkpoints it.
|
|
272
|
+
*
|
|
273
|
+
* `attempt` is stored rather than derived because a resumed run has to know
|
|
274
|
+
* whether it is retrying or starting: a stage that has already burnt its
|
|
275
|
+
* retries should fail the run rather than loop for as long as the storage
|
|
276
|
+
* keeps the record.
|
|
277
|
+
*/
|
|
278
|
+
export const RunStageDTOSchema = object({
|
|
279
|
+
id: string(),
|
|
280
|
+
/** What to show a player waiting on it. */
|
|
281
|
+
label: string(),
|
|
282
|
+
/** Which agent does the work — or the engine, for a local stage. */
|
|
283
|
+
agent: string(),
|
|
284
|
+
/** The canonical model behind it, or `local` for a stage that asks nobody. */
|
|
285
|
+
model: string(),
|
|
286
|
+
status: RunStageStatusSchema,
|
|
287
|
+
/** Epoch milliseconds; absent until the stage starts. */
|
|
288
|
+
startedAt: optional(number()),
|
|
289
|
+
durationMs: optional(number()),
|
|
290
|
+
/** Total prompt tokens consumed by successful calls in this stage. */
|
|
291
|
+
inputTokens: optional(number()),
|
|
292
|
+
/** Total completion tokens produced by successful calls in this stage. */
|
|
293
|
+
outputTokens: optional(number()),
|
|
294
|
+
attempt: optional(number()),
|
|
295
|
+
error: optional(string()),
|
|
296
|
+
});
|
|
297
|
+
/**
|
|
298
|
+
* One turn's adjudication, owned by the server and readable at any moment.
|
|
299
|
+
*
|
|
300
|
+
* This is the record that makes a reload survivable. The work belongs to the
|
|
301
|
+
* service rather than to the tab that asked for it, every stage is written down
|
|
302
|
+
* as it finishes, and each output is published the moment it exists rather than
|
|
303
|
+
* at the end: `check` as soon as the dice are rolled, `narration` as soon as
|
|
304
|
+
* the prose lands, `effects` once the consequences are interpreted, `memories`
|
|
305
|
+
* once the chronicler has been. A client that reconnects renders whatever is
|
|
306
|
+
* already here and waits only for what is genuinely still missing.
|
|
307
|
+
*
|
|
308
|
+
* `leaseUntil` is how a stalled run is told from a slow one. A worker that dies
|
|
309
|
+
* mid-run leaves the record `running` forever otherwise, and nothing else dares
|
|
310
|
+
* touch it; with a lease, whoever finds it expired may resume from the last
|
|
311
|
+
* completed stage.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```ts
|
|
315
|
+
* import type { TurnRunPayload } from '@game-infra/game-state-schemas'
|
|
316
|
+
*
|
|
317
|
+
* const run: TurnRunPayload = {
|
|
318
|
+
* id: 'run-8f2c',
|
|
319
|
+
* threadId: 'the-coast-raid',
|
|
320
|
+
* sequence: 3,
|
|
321
|
+
* input: 'I put my shoulder to the door and shout for Ilse.',
|
|
322
|
+
* status: 'narrated',
|
|
323
|
+
* stages: [
|
|
324
|
+
* { id: 'assessment', label: 'Choosing whether and how to roll',
|
|
325
|
+
* agent: 'Assessor', model: 'aion-mini', status: 'completed', durationMs: 1840 },
|
|
326
|
+
* ],
|
|
327
|
+
* traceId: 'turn-8f2c',
|
|
328
|
+
* startedAt: '2026-08-31T09:12:00.000Z',
|
|
329
|
+
* updatedAt: '2026-08-31T09:12:09.000Z',
|
|
330
|
+
* }
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
export const TurnRunPayloadSchema = object({
|
|
334
|
+
id: string(),
|
|
335
|
+
threadId: string(),
|
|
336
|
+
/** The index this turn takes in its thread. */
|
|
337
|
+
sequence: number(),
|
|
338
|
+
/** What the player wrote. Empty on a session's opening turn. */
|
|
339
|
+
input: string(),
|
|
340
|
+
status: TurnRunStatusSchema,
|
|
341
|
+
/** Every stage, in execution order, whether or not it has run. */
|
|
342
|
+
stages: array(RunStageDTOSchema),
|
|
343
|
+
/** Joins every model call this run made. */
|
|
344
|
+
traceId: string(),
|
|
345
|
+
startedAt: string(),
|
|
346
|
+
updatedAt: string(),
|
|
347
|
+
/** Epoch milliseconds after which an unfinished run may be resumed by anyone. */
|
|
348
|
+
leaseUntil: optional(number()),
|
|
349
|
+
// Partial outputs, each published the moment it exists.
|
|
350
|
+
/** The neurons the assessor judged relevant. */
|
|
351
|
+
focus: optional(array(string())),
|
|
352
|
+
/** The roll — available before a word of prose has been written. */
|
|
353
|
+
check: optional(ResolvedCheckDTOSchema),
|
|
354
|
+
title: optional(string()),
|
|
355
|
+
narration: optional(string()),
|
|
356
|
+
effects: optional(array(ActivationDTOSchema)),
|
|
357
|
+
introduced: optional(array(IntroducedEntityDTOSchema)),
|
|
358
|
+
memories: optional(array(MemoryDTOSchema)),
|
|
359
|
+
consolidations: optional(array(ConsolidationDTOSchema)),
|
|
360
|
+
/** The model that narrated, once one has. */
|
|
361
|
+
model: optional(string()),
|
|
362
|
+
/** Milliseconds per named stage, as they complete. */
|
|
363
|
+
timings: optional(record(string(), number())),
|
|
364
|
+
/** Why the run failed, when it did. */
|
|
365
|
+
error: optional(string()),
|
|
366
|
+
});
|
|
367
|
+
//# sourceMappingURL=narrativeThreads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"narrativeThreads.js","sourceRoot":"","sources":["../src/narrativeThreads.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@game-infra/game-state-schemas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Play-state API contract: the sessions a player has in progress, the journal each one is rebuilt from, and freeform mode's turn and memory payloads",
|
|
5
5
|
"homepage": "https://github.com/kibertoad/game-infra/tree/main/packages/schemas/game-state-schemas#readme",
|
|
6
6
|
"bugs": {
|