feat: nation-op rename review — confirm/reject routes, client dialog, AGENTS.md (P4a, #16)
Wire the 'LLM proposes, player confirms' nation-rename flow end to end: - server: POST /api/games/:id/nation-op/confirm|reject (404/400, version-bumped SSE state) - client: confirmNationOp/rejectNationOp api helpers + NationOpDialog (editable rename) wired into the Action panel via a 'Nation proposals' trigger - AGENTS.md: document the pendingNationOps mechanism, routes, nationRef resolution, stub-never-proposes
This commit is contained in:
@@ -4,7 +4,6 @@ import { makeEvent, type NationOp, type TurnResult } from '../shared/protocol';
|
||||
import type { LlmClient, ToolDefinition, WireMessage } from './llm';
|
||||
import { makeStubLlmClient } from './stub';
|
||||
import {
|
||||
applyNationOp,
|
||||
applyTurnResult,
|
||||
buildSystemPrompt,
|
||||
buildUserPrompt,
|
||||
|
||||
+31
-1
@@ -12,13 +12,15 @@ import { deepClone } from '../shared/protocol';
|
||||
import type {
|
||||
AddActionRequest,
|
||||
AddDiplomacyRequest,
|
||||
ConfirmNationOpRequest,
|
||||
CreateGameRequest,
|
||||
RejectNationOpRequest,
|
||||
RemoveQueueItemRequest,
|
||||
} from '../shared/protocol';
|
||||
import type { GameState } from '../shared/types';
|
||||
import { createLlmClient } from './llm';
|
||||
import { makeStubLlmClient } from './stub';
|
||||
import { askAdvisor, queueRoundItem, removeRoundItem, runTurn } from './engine';
|
||||
import { askAdvisor, confirmNationOp, queueRoundItem, rejectNationOp, removeRoundItem, runTurn } from './engine';
|
||||
import { buildRegionMap } from './map';
|
||||
import { allTerritoryKeys, expandCountriesToKeys, hasAdjacency, loadRegions, neighboursOf, referenceForKeys, validKeys } from './regions';
|
||||
import { createPresetStore } from './presets';
|
||||
@@ -228,6 +230,34 @@ app.post('/api/games/:id/queue/remove', (req, res) => {
|
||||
res.json({ game: next });
|
||||
});
|
||||
|
||||
// (v0.23, #16 P4a) Resolve a pending nation-op proposal (a rename the LLM
|
||||
// proposed in an earlier turn, waiting in game.pendingNationOps). No LLM call,
|
||||
// no turn advance — same fast save → broadcast → respond order as
|
||||
// /queue/remove. The version bump lets "never go backwards" clients reconcile.
|
||||
app.post('/api/games/:id/nation-op/confirm', (req, res) => {
|
||||
const id = req.params.id;
|
||||
const game = db.load(id);
|
||||
if (!game) return res.status(404).json({ error: 'game not found' });
|
||||
const body = (req.body ?? {}) as ConfirmNationOpRequest;
|
||||
const next = confirmNationOp(game, body.index, body.edits);
|
||||
if (!next) return res.status(400).json({ error: 'invalid proposal index' });
|
||||
db.save(next);
|
||||
broadcast(id, 'state', { state: next });
|
||||
res.json({ game: next });
|
||||
});
|
||||
|
||||
app.post('/api/games/:id/nation-op/reject', (req, res) => {
|
||||
const id = req.params.id;
|
||||
const game = db.load(id);
|
||||
if (!game) return res.status(404).json({ error: 'game not found' });
|
||||
const body = (req.body ?? {}) as RejectNationOpRequest;
|
||||
const next = rejectNationOp(game, body.index);
|
||||
if (!next) return res.status(400).json({ error: 'invalid proposal index' });
|
||||
db.save(next);
|
||||
broadcast(id, 'state', { state: next });
|
||||
res.json({ game: next });
|
||||
});
|
||||
|
||||
// Jump forward: commit the whole pending round (or an empty one) to the model
|
||||
// in a single turn. applyTurnResult clears the pending queue on the returned
|
||||
// state. 404 for not-found/preset-missing; 502 for LLM/model (transport) errors.
|
||||
|
||||
Reference in New Issue
Block a user