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