This commit is contained in:
24
apps/web/server/api/rounds/demo/resolve.post.ts
Normal file
24
apps/web/server/api/rounds/demo/resolve.post.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { resolveCheck } from '@dng/game-engine'
|
||||
import { CharacterSchema, moderate13Plus } from '@dng/shared'
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const body = await readBody(event)
|
||||
const action = String(body?.action ?? '')
|
||||
if (!action.trim()) throw createError({ statusCode: 400, statusMessage: 'An action is required.' })
|
||||
if (!moderate13Plus(action).allowed) throw createError({ statusCode: 422, statusMessage: 'The action falls outside the 13+ boundary.' })
|
||||
|
||||
const actor = CharacterSchema.parse({
|
||||
id: 'char_mara', name: 'Mara Vale', concept: 'Salvage pilot', controller: 'human', userId: 'demo',
|
||||
abilities: { str: 10, dex: 16, con: 13, int: 12, wis: 14, cha: 11 }, hp: 11, maxHp: 11,
|
||||
defense: 14, proficiency: 2, inventory: ['Pulse cutter', 'Vacuum cloak'], statuses: [],
|
||||
})
|
||||
const check = resolveCheck({ actorId: actor.id, kind: 'ability', ability: 'int', difficulty: 13, mode: 'normal', reason: action }, actor)
|
||||
const success = check.success === true
|
||||
return {
|
||||
roll: `Intelligence check · ${check.formula} = ${check.total}`,
|
||||
outcome: `${success ? 'SUCCESS' : 'COMPLICATION'} · DC ${check.difficulty}`,
|
||||
narration: success
|
||||
? 'The transmission separates into two layers. Beneath your future voice is a maintenance handshake signed by Moth—dated eighty-seven years ago. Rook-7 turns toward the sealed archive as its door unlocks one deliberate centimeter. “That,” the machine says, “was not me.”'
|
||||
: 'The signal fractures when you isolate it. For one breath every screen shows a different version of the archive—open, burning, empty. Rook-7 catches one surviving packet before the rest vanish: a map leading below the station, marked in your own handwriting.',
|
||||
}
|
||||
})
|
||||
36
apps/web/server/api/worlds/generate.post.ts
Normal file
36
apps/web/server/api/worlds/generate.post.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { CreateWorldRequestSchema, WorldStarterSchema, moderate13Plus } from '@dng/shared'
|
||||
import { buildJsonCompletion, parseJsonCompletion } from '../../utils/ai-provider'
|
||||
|
||||
export default defineEventHandler(async event => {
|
||||
const raw = await readBody(event)
|
||||
const prompt = typeof raw?.prompt === 'string' ? raw.prompt : ''
|
||||
const answers = raw?.answers && typeof raw.answers === 'object' ? raw.answers : {}
|
||||
const moderation = moderate13Plus(`${prompt} ${Object.values(answers).join(' ')}`)
|
||||
if (!moderation.allowed) throw createError({ statusCode: 422, statusMessage: 'This concept falls outside the alpha’s 13+ content boundary.' })
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
const request = CreateWorldRequestSchema.parse({ messages: [{ role: 'user', content: `${prompt}\nPreferences: ${JSON.stringify(answers)}` }] })
|
||||
let completion
|
||||
try {
|
||||
completion = buildJsonCompletion(config, {
|
||||
system: 'Create an original 13+ TTRPG starting world. Return only valid JSON matching the supplied WorldStarter structure, with exactly 3 NPCs and 2 factions. Do not use protected franchises.',
|
||||
messages: request.messages,
|
||||
schemaName: 'world_starter',
|
||||
jsonSchema: WorldStarterSchema.toJSONSchema(),
|
||||
})
|
||||
} catch (error) {
|
||||
throw createError({ statusCode: 500, statusMessage: error instanceof Error ? error.message : 'Invalid AI provider configuration.' })
|
||||
}
|
||||
|
||||
const response = await fetch(completion.endpoint, {
|
||||
method: 'POST',
|
||||
headers: completion.headers,
|
||||
body: JSON.stringify(completion.body),
|
||||
})
|
||||
if (!response.ok) throw createError({ statusCode: 502, statusMessage: 'The coauthor is temporarily unavailable.' })
|
||||
try {
|
||||
return WorldStarterSchema.parse(parseJsonCompletion(await response.json()))
|
||||
} catch {
|
||||
throw createError({ statusCode: 502, statusMessage: 'The coauthor returned an invalid world structure.' })
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user