Add AI-assisted world and character drafting flows
All checks were successful
CI / validate (push) Successful in 14m3s

This commit is contained in:
2026-08-17 09:25:37 +05:00
parent 830aa5dc1f
commit cdeea8653c
23 changed files with 811 additions and 92 deletions

View File

@@ -56,11 +56,14 @@ function appRequest(path, token, options = {}) {
}
async function servicePatch(path, body) {
const serviceAuthorization = serviceKey.split('.').length === 3
? { Authorization: `Bearer ${serviceKey}` }
: {}
await jsonRequest(`${supabaseUrl}/rest/v1/${path}`, {
method: 'PATCH',
headers: {
apikey: serviceKey,
Authorization: `Bearer ${serviceKey}`,
...serviceAuthorization,
'Content-Type': 'application/json',
Prefer: 'return=representation',
},
@@ -130,9 +133,22 @@ const playerCharacter = await appRequest(`/api/v1/campaigns/${campaignId}/charac
method: 'POST', body: characterBody('Rowan Pike', 'A curious xenobotanist.'),
})
console.log('[smoke] Drafting and adding a persistent AI companion…')
const suggested = await appRequest(`/api/v1/campaigns/${campaignId}/characters/suggest`, owner.token, {
method: 'POST',
body: JSON.stringify({ controller: 'ai', concept: 'A damaged garden caretaker who values living things over orders.' }),
})
if (!suggested?.character?.name || !suggested.character?.persona?.motivation) {
throw new Error('[smoke] Character coauthor returned an incomplete draft.')
}
await appRequest(`/api/v1/campaigns/${campaignId}/characters`, owner.token, {
method: 'POST',
body: JSON.stringify({ ...suggested.character, controller: 'ai', statuses: [] }),
})
const initial = await appRequest(`/api/v1/campaigns/${campaignId}`, owner.token)
if (initial.members.length !== 2) throw new Error(`[smoke] Expected 2 members, received ${initial.members.length}.`)
if (initial.characters.length !== 2 || initial.round?.status !== 'open') throw new Error('[smoke] Multiplayer lobby did not expose two characters and an open round.')
if (initial.characters.length !== 3 || initial.round?.status !== 'open') throw new Error('[smoke] Multiplayer lobby did not expose two humans, one AI companion, and an open round.')
const roundId = initial.round.id
console.log('[smoke] Verifying that the round waits for both humans…')
@@ -167,4 +183,4 @@ while (Date.now() < deadline) {
if (!completed) throw new Error('[smoke] Multiplayer round did not resolve within 120 seconds.')
if (!completed.rounds.find(round => round.id === roundId)?.narration) throw new Error('[smoke] Resolved round has no narration.')
console.log(`[smoke] PASS — 2 players joined, shared readiness, worker resolution, and next round all work (campaign ${campaignId}).`)
console.log(`[smoke] PASS — 2 players, AI character drafting, persistent companion, shared readiness, worker resolution, and next round all work (campaign ${campaignId}).`)