- Introduce UpdateSessionRequest model for partial updates to session state, allowing modification of situation and characters. - Implement updateSession method in SessionService to handle updates, ensuring omitted fields remain unchanged. - Enhance InMemorySessionService to support scenario-based session creation, populating initial situation and characters. - Update SessionResource to delegate update requests to the SessionService. - Add corresponding API documentation for the update session endpoint in OpenAPI specification. - Enhance frontend components to allow editing of session scene and characters, integrating with the new update functionality. - Include unit tests to verify the behavior of session updates and scenario handling.
671 lines
20 KiB
YAML
671 lines
20 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: RolePlay API
|
|
description: |
|
|
Public REST API for the RolePlay service. Provides endpoints to discover
|
|
available AI models, manage role-play sessions, and submit user turns.
|
|
version: 1.0.0
|
|
contact:
|
|
name: RolePlay Project
|
|
|
|
servers:
|
|
- url: /api/v1
|
|
description: Default server base path
|
|
|
|
tags:
|
|
- name: models
|
|
description: Discover available Ollama models
|
|
- name: sessions
|
|
description: Manage role-play sessions
|
|
- name: turns
|
|
description: Submit user actions within a session
|
|
|
|
paths:
|
|
|
|
/models:
|
|
get:
|
|
operationId: listModels
|
|
summary: List available AI models
|
|
description: Returns all Ollama models currently installed on the backend server.
|
|
tags:
|
|
- models
|
|
responses:
|
|
"200":
|
|
description: Successful response with a list of available models.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ModelListResponse'
|
|
"500":
|
|
description: Server error while contacting Ollama.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/sessions:
|
|
post:
|
|
operationId: createSession
|
|
summary: Start a new role-play session
|
|
description: |
|
|
Initialises a new session with the given model and optional scenario
|
|
setup. The backend performs the two-call Ollama pattern (narrative +
|
|
state extraction) and returns the opening scene.
|
|
tags:
|
|
- sessions
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSessionRequest'
|
|
responses:
|
|
"201":
|
|
description: Session created; opening narrative and initial state returned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SessionResponse'
|
|
"400":
|
|
description: Invalid request body.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
"500":
|
|
description: Server error during session initialisation.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/sessions/{sessionId}:
|
|
get:
|
|
operationId: getSession
|
|
summary: Retrieve a session
|
|
description: Returns the full current state of an existing role-play session.
|
|
tags:
|
|
- sessions
|
|
parameters:
|
|
- $ref: '#/components/parameters/SessionId'
|
|
responses:
|
|
"200":
|
|
description: Session found and returned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SessionResponse'
|
|
"404":
|
|
description: Session not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
patch:
|
|
operationId: updateSession
|
|
summary: Update session state
|
|
description: |
|
|
Partially updates an existing session. Provide situation and/or characters
|
|
to replace the current values. Omitted fields are left unchanged.
|
|
tags:
|
|
- sessions
|
|
parameters:
|
|
- $ref: '#/components/parameters/SessionId'
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateSessionRequest'
|
|
responses:
|
|
"200":
|
|
description: Session updated; full state returned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SessionResponse'
|
|
"404":
|
|
description: Session not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
"400":
|
|
description: Invalid request body.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/sessions/{sessionId}/turns:
|
|
post:
|
|
operationId: submitTurn
|
|
summary: Submit a user action for the next turn
|
|
description: |
|
|
Submits the user's action (speech, physical action, or a chosen
|
|
suggestion) and an optional narrative recommendation. The backend
|
|
executes the two-call Ollama pattern and returns the resulting
|
|
narrative and updated suggestions.
|
|
tags:
|
|
- turns
|
|
parameters:
|
|
- $ref: '#/components/parameters/SessionId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TurnRequest'
|
|
responses:
|
|
"200":
|
|
description: Turn processed; narrative and new suggestions returned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TurnResponse'
|
|
"400":
|
|
description: Invalid request body.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
"404":
|
|
description: Session not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
"500":
|
|
description: Server error during turn processing.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
components:
|
|
|
|
parameters:
|
|
SessionId:
|
|
name: sessionId
|
|
in: path
|
|
required: true
|
|
description: Unique identifier of the role-play session.
|
|
schema:
|
|
type: string
|
|
|
|
schemas:
|
|
|
|
# ─── Model discovery ──────────────────────────────────────────────────────
|
|
|
|
ModelInfo:
|
|
type: object
|
|
description: Metadata about a single Ollama model.
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Technical model identifier (e.g. "llama3:latest").
|
|
example: llama3:latest
|
|
displayName:
|
|
type: string
|
|
description: Human-readable model name derived from the identifier.
|
|
example: Llama 3 (latest)
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
description: Model size in bytes.
|
|
example: 4000000000
|
|
family:
|
|
type: string
|
|
description: Model family (e.g. "llama").
|
|
example: llama
|
|
required:
|
|
- name
|
|
|
|
ModelListResponse:
|
|
type: object
|
|
description: Response containing all available models.
|
|
properties:
|
|
models:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ModelInfo'
|
|
required:
|
|
- models
|
|
|
|
# ─── Session ──────────────────────────────────────────────────────────────
|
|
|
|
CreateSessionRequest:
|
|
type: object
|
|
description: Request body for creating a new role-play session.
|
|
properties:
|
|
model:
|
|
type: string
|
|
description: The Ollama model name to use for this session.
|
|
example: llama3:latest
|
|
language:
|
|
type: string
|
|
description: BCP-47 language tag for the session (default "en").
|
|
example: en
|
|
default: en
|
|
safetyLevel:
|
|
type: string
|
|
description: Content safety level.
|
|
enum:
|
|
- standard
|
|
- strict
|
|
default: standard
|
|
scenario:
|
|
$ref: '#/components/schemas/ScenarioSetup'
|
|
required:
|
|
- model
|
|
|
|
ScenarioSetup:
|
|
type: object
|
|
description: |
|
|
Optional initial scenario definition. If omitted the backend uses
|
|
built-in defaults.
|
|
properties:
|
|
setting:
|
|
type: string
|
|
description: Place, time, and atmosphere description.
|
|
example: "A fog-covered harbour at dawn, 1923"
|
|
initialConflict:
|
|
type: string
|
|
description: The hook or starting conflict.
|
|
example: "Strange noises from the cargo hold"
|
|
userCharacter:
|
|
$ref: '#/components/schemas/CharacterDefinition'
|
|
aiCharacters:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CharacterDefinition'
|
|
|
|
UpdateSessionRequest:
|
|
type: object
|
|
description: Request body for partially updating a session.
|
|
properties:
|
|
situation:
|
|
$ref: '#/components/schemas/SituationState'
|
|
description: Replace session situation when provided.
|
|
characters:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CharacterState'
|
|
description: Replace session character list when provided.
|
|
|
|
CharacterDefinition:
|
|
type: object
|
|
description: Definition of a character for session initialisation.
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique character identifier.
|
|
example: captain_morgan
|
|
name:
|
|
type: string
|
|
description: Display name.
|
|
example: Captain Morgan
|
|
role:
|
|
type: string
|
|
description: Narrative role.
|
|
example: ship captain
|
|
backstory:
|
|
type: string
|
|
description: Character backstory (AI characters only).
|
|
personalityTraits:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Personality descriptors (AI characters only).
|
|
speakingStyle:
|
|
type: string
|
|
description: Tone and speech quirks (AI characters only).
|
|
goals:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Short- and long-term goals (AI characters only).
|
|
required:
|
|
- id
|
|
- name
|
|
- role
|
|
|
|
SessionResponse:
|
|
type: object
|
|
description: Current state of a role-play session.
|
|
properties:
|
|
sessionId:
|
|
type: string
|
|
description: Unique session identifier.
|
|
example: "550e8400-e29b-41d4-a716-446655440000"
|
|
model:
|
|
type: string
|
|
description: Ollama model in use.
|
|
example: llama3:latest
|
|
language:
|
|
type: string
|
|
description: Session language.
|
|
example: en
|
|
safetyLevel:
|
|
type: string
|
|
description: Content safety level.
|
|
example: standard
|
|
narrative:
|
|
type: string
|
|
description: Most recent narrative text (opening scene or latest turn).
|
|
situation:
|
|
$ref: '#/components/schemas/SituationState'
|
|
characters:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CharacterState'
|
|
suggestions:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Suggestion'
|
|
turnNumber:
|
|
type: integer
|
|
description: Current turn counter (0 = just initialised).
|
|
example: 0
|
|
required:
|
|
- sessionId
|
|
- model
|
|
- language
|
|
- safetyLevel
|
|
- turnNumber
|
|
|
|
SituationState:
|
|
type: object
|
|
description: Current world and scene state within a session.
|
|
properties:
|
|
setting:
|
|
type: string
|
|
description: Place, time, and atmosphere.
|
|
currentScene:
|
|
type: string
|
|
description: What is currently in focus for the scene.
|
|
timeline:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Ordered list of important events so far.
|
|
openThreads:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Unresolved plot lines, mysteries, or quests.
|
|
externalPressures:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Time-sensitive pressures such as deadlines or approaching threats.
|
|
worldStateFlags:
|
|
type: object
|
|
additionalProperties: true
|
|
description: Boolean or tag-style flags representing key world states.
|
|
|
|
CharacterState:
|
|
type: object
|
|
description: Current dynamic state of a single character within a session.
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique character identifier.
|
|
name:
|
|
type: string
|
|
description: Display name.
|
|
role:
|
|
type: string
|
|
description: Narrative role.
|
|
isUserCharacter:
|
|
type: boolean
|
|
description: Whether this is the user-controlled character.
|
|
currentMood:
|
|
type: string
|
|
description: Current emotional state.
|
|
status:
|
|
type: string
|
|
description: Physical or narrative status.
|
|
knowledge:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Facts the character has learned.
|
|
relationships:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Map from other character IDs to relationship descriptions.
|
|
recentActionsSummary:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Brief summary of recent behaviour.
|
|
required:
|
|
- id
|
|
- name
|
|
- isUserCharacter
|
|
|
|
# ─── Turn ─────────────────────────────────────────────────────────────────
|
|
|
|
TurnRequest:
|
|
type: object
|
|
description: User action submitted for the next story turn.
|
|
properties:
|
|
userAction:
|
|
$ref: '#/components/schemas/UserActionRequest'
|
|
recommendation:
|
|
$ref: '#/components/schemas/RecommendationRequest'
|
|
required:
|
|
- userAction
|
|
|
|
UserActionRequest:
|
|
type: object
|
|
description: The action the user performed this turn.
|
|
properties:
|
|
type:
|
|
type: string
|
|
description: Type of user action.
|
|
enum:
|
|
- speech
|
|
- action
|
|
- choice
|
|
content:
|
|
type: string
|
|
description: Free-text content of the action or dialogue.
|
|
selectedSuggestionId:
|
|
type: string
|
|
description: If the user chose a suggestion, its ID; otherwise omitted.
|
|
required:
|
|
- type
|
|
|
|
RecommendationRequest:
|
|
type: object
|
|
description: |
|
|
Optional narrative guidance the user attaches to a turn. Treated as a
|
|
soft hint by the model.
|
|
properties:
|
|
desiredTone:
|
|
type: string
|
|
description: Desired mood for the next beat (e.g. "tense", "humorous").
|
|
example: tense
|
|
preferredDirection:
|
|
type: string
|
|
description: Free-text direction hint.
|
|
example: "The captain should reveal a partial truth"
|
|
focusCharacters:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Character IDs that should play a prominent role.
|
|
|
|
TurnResponse:
|
|
type: object
|
|
description: Result of processing a user turn.
|
|
properties:
|
|
turnNumber:
|
|
type: integer
|
|
description: The turn number that was just completed.
|
|
example: 1
|
|
narrative:
|
|
type: string
|
|
description: Free-form narrative text produced by the model for this turn.
|
|
characterResponses:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CharacterResponseItem'
|
|
description: Per-character breakdown of what each AI character said or did.
|
|
updatedSituation:
|
|
$ref: '#/components/schemas/SituationUpdate'
|
|
updatedCharacters:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/CharacterUpdate'
|
|
suggestions:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Suggestion'
|
|
required:
|
|
- turnNumber
|
|
- narrative
|
|
|
|
CharacterResponseItem:
|
|
type: object
|
|
description: What a single AI character said or did during a turn.
|
|
properties:
|
|
characterId:
|
|
type: string
|
|
description: ID of the character who acted.
|
|
type:
|
|
type: string
|
|
description: Type of response.
|
|
enum:
|
|
- speech
|
|
- action
|
|
- reaction
|
|
content:
|
|
type: string
|
|
description: Quoted dialogue if type is "speech", otherwise null.
|
|
action:
|
|
type: string
|
|
description: Description of physical action, or null if none.
|
|
moodAfter:
|
|
type: string
|
|
description: The character's mood after this turn.
|
|
required:
|
|
- characterId
|
|
- type
|
|
|
|
SituationUpdate:
|
|
type: object
|
|
description: Diff-style situation changes for a single turn.
|
|
properties:
|
|
currentScene:
|
|
type: string
|
|
description: Updated scene description.
|
|
newTimelineEntries:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: New events to append to the timeline.
|
|
openThreadsChanges:
|
|
$ref: '#/components/schemas/OpenThreadsChanges'
|
|
worldStateFlags:
|
|
type: object
|
|
additionalProperties: true
|
|
description: Current world state flags after this turn.
|
|
|
|
OpenThreadsChanges:
|
|
type: object
|
|
description: Diff-style changes to open narrative threads.
|
|
properties:
|
|
added:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: New threads introduced this turn.
|
|
resolved:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Threads that were resolved or closed this turn.
|
|
|
|
CharacterUpdate:
|
|
type: object
|
|
description: Diff-style character state changes for a single character.
|
|
properties:
|
|
characterId:
|
|
type: string
|
|
description: ID of the character whose state changed.
|
|
currentMood:
|
|
type: string
|
|
description: The character's mood after this turn.
|
|
knowledgeGained:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: New facts the character learned this turn.
|
|
relationshipChanges:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
description: Changed relationships (character ID to new descriptor).
|
|
required:
|
|
- characterId
|
|
|
|
Suggestion:
|
|
type: object
|
|
description: A suggestion for what could happen next in the story.
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique suggestion identifier.
|
|
type:
|
|
type: string
|
|
description: Category of the suggestion.
|
|
enum:
|
|
- player_action
|
|
- world_event
|
|
- npc_action
|
|
- twist
|
|
title:
|
|
type: string
|
|
description: Short human-readable label.
|
|
description:
|
|
type: string
|
|
description: One- or two-sentence explanation.
|
|
consequences:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Brief list of possible outcomes.
|
|
riskLevel:
|
|
type: string
|
|
description: How risky this option is for the player.
|
|
enum:
|
|
- low
|
|
- medium
|
|
- high
|
|
required:
|
|
- id
|
|
- type
|
|
- title
|
|
|
|
# ─── Error ────────────────────────────────────────────────────────────────
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
description: Standard error response body.
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: Machine-readable error code.
|
|
example: SESSION_NOT_FOUND
|
|
message:
|
|
type: string
|
|
description: Human-readable error description.
|
|
example: "No session found with the given ID"
|
|
required:
|
|
- code
|
|
- message
|
|
|