-
Notifications
You must be signed in to change notification settings - Fork 0
Agent Feature- Project Plan #242
Description
The agent feature delegates characters to the AI. It adopts the voice, knowledge, and personality of an in-story character and proceeds toward the target without giving any spoilers. The function requires two arguments, target and character, both knots in the story. The target function plays the same role as the continue function: agent takes control of the story’s execution flow until the AI system determines that the story can continue at the target. The character knot is used as "lore", backstory, or an interview with the character, describing who they are.
User Story
As a writer, I want to delegate a character to the AI so that my readers can chat with an in-story character.
Syntax
->agent(->character,->target)
target: Works the same as continue(->target)
character: It is preprocessed as a sub-story, with a pre-qualified number of Monte Carlo runs of character generating text to be used as a sort of RAG. This is used as a backstory for the character.
Behavior
- Speaks in the voice of the delegated character
- Remembers the conversation as a character would
- Evaluates user input against narrative goals
- Resumes to normal story flow when target conditions are satisfied.
Character Preprocessing
- Run the character Knot 5 times using Monte Carlo sampling
- Collect diverse excerpts
- Store the excerpts as a character grounding dataset.
- Use the dataset to generate character-consistent responses
Directions for Responses
After each input, like continue, one of the 4 directions is chosen:
- Direct Continue: If the target is satisfied, then the story directly continues
- Bridge and Continue: If the target is close, add a bridge text and then continue the story
- Invalid input: If the target is irrelevant, then the agent brings the conversation back to the topic
- Needs input: If the target is relevant, the agent gives prompts to keep the conversation flowing
Backend Technical Components
Extend the Existing AI endpoint with the agent mode
#context The tag is used to show that the mentioned content should not be visible to the reader but should be included in the story’s state history or AI context.
story state This should rebuild the agent’s memory every turn so it stays consistent with the story.
character preprocessing This should run the character knot multiple times and collect example dialogues to build a character grounding dataset. This should help the AI imitate the author’s voice for the character.
target reached This should help the agent know that the story can safely resume without any further interaction from the agent.
evaluate This should check if the AI’s response is coherent with the story without giving any spoilers about the upcoming events.
bridge text This prompt will help generate the bridge text to continue the story
SEED_AI(number) This sets a seed for AI interfaces. Follows the SEED_RANDOM built-in function. A static default AI seed will be used when SEED_AI is not called. Backend AI calls will be memoized with (seed, prompt), substantially saving on AI API expenses. The default AI seed will be changed with each minor release of Unfold Studio, allowing for tweaks to AI params and meta-prompts.
agent session state This tracks what has been said, what worked, what failed, and where we are in the story. Ensures a coherent conversation.
Backend Task List
- Implement technical components
- Create edge cases for agent behavior
Frontend Technical Implementation
- Agent is called by the author in the story
(->agent(->character, ->target)) - The front-end shows a text input box or the player to type in responses.
- The player does not choose the character but the character is already chosen by the author in ->character.
- The input box is just for the player to talk to that character. Player types something → front-end sends it to the backend via /api//agent/decision with unique id.
- Backend evaluates the input:
a. Backend builds the prompt for AI which includes: character background, story context so far, target knot, player input
b. Backend calls AI with that prompt.
c. AI generates a response in the character’s voice and tries to move toward the target.
d. Backend evaluates AI’s output:
Is target satisfied → DIRECT
Needs a bridge → BRIDGE_AND_CONTINUE
Needs more input to reach the target → NEEDS_INPUT
Input invalid → INVALID_INPUT
e. Backend returns the response + outcome to front-end.
f. If the input is relevant → respond in character voice
g. If close but not on target → add a bridge message
h. If irrelevant → redirect conversation back to topic - Show backend response in frontend
- Show agent text in story
- Show bridge or rejection messages if needed
- Repeat
- If outcome requires player input i.e. INVALID OR NEEDS_INPUT→ input box stays → player types next message → repeat steps
- If outcome is DIRECT or BRIDGE_AND_CONTINUE → input box stops → continue story
Frontend Task List
- Story rendering
- Like create a new temporary state so that when agent hits, it switches to that mode.
- When agent mode is active:
- The story pauses
- The input box is shown continuously
- Messages appear turn-by-turn
- Story does will not move forward until backend says so.
- Handle input
- Display a text input box when the agent expects user input.
- Disable or hide input box when backend returns DIRECT or BRIDGE_AND_CONTINUE
- Stop user input while bridge text is being displayed.
- Agent called
- The story cannot continue
- The frontend should switch into agent mode
- The frontend should inform backend like starting an agent interaction now
- frontend sends story ID, character knot, target knot, context
- Call backend ai
- On each user turn:
- Send user input + id to backend.
- Append user message and agent response to UI.
- Once agent ends, leave agent mode and return to normal story flow
- Handling outputs
- NEEDS_INPUT: show agent reply, keep input box enabled
- INVALID: display rejection message, keep input box enabled
- BRIDGE_AND_CONTINUE: display bridge text, then continue story
- DIRECT_CONTINUE: immediately continue story without further input
- Ensure that the frontend doesn’t make any decisions to reach target.
- Error & edge-case handling
- Handle network/API errors gracefully (retry or show fallback message)
- Don’t let the player send multiple messages before the backend finishes responding to the previous one.
- Handle unexpected backend responses safely.