Briyah SDK - v2.0.6
    Preparing search index...

    Interface AppService

    interface AppService {
        get packInstantiation(): PackInstantiationService;
        get packs(): PackService;
        get rpg(): RpgService;
        get userAuthoredToolsEnabled(): boolean;
        addBalance(amount: number): void;
        attachArtifactToAgent(agentId: string, artifactId: string): Promise<void>;
        attachDocument(
            agentId: string,
            fileName: string,
            fileData: Buffer,
        ): Promise<AttachDocumentResponse>;
        beginRoom(roomId: string, context?: unknown): Promise<SendMessageResult>;
        compactAgentConversation(agentId: string): Promise<void>;
        compactStory(
            storyId: string,
        ): Promise<{ details?: any; message?: string; success: boolean }>;
        convertPdfToMarkdownPages(
            pdfBuffer: Uint8Array<ArrayBufferLike> | Buffer<ArrayBufferLike>,
            options?: PdfMarkdownOptions,
        ): Promise<PdfMarkdownResult>;
        convertUserArtifact(name: string, pdfBuffer: Buffer): string;
        createAgent(
            aiServiceName: string,
            agentName: string,
            agentNickname: string,
            description: string,
            aiModel: string,
            promptName?: string,
            controlledByHuman?: boolean,
            reasoningEffort?: "low" | "medium" | "high",
            maxOutputTokens?: number,
            beginInstruction?: string,
            options?: AgentCreationOptions,
        ): Agent;
        createAgentFromFolder(
            options: {
                aiModel: string;
                aiServiceName: string;
                attachDocuments?: boolean;
                folder: string;
                overrides?: Partial<PromptFolderDefaults>;
            },
        ): Promise<Agent>;
        createPromptFolder(folderName: string): void;
        createRoom(
            roomName: string,
            goal: string,
            agentIds: string[],
            roomLeader?: string,
            turnMode?: RoomTurnMode,
            moderator?: string,
            beginInstruction?: string,
            imageModel?: string,
            illustrationMode?: RoomIllustrationMode,
        ): Promise<CreateRoomResponse>;
        createRoomAgent(
            roomId: string,
            request: CreateAgentRequest,
        ): Promise<CreateAgentResponse>;
        createRoomAgentFromFolder(
            roomId: string,
            options: {
                aiModel: string;
                aiServiceName: string;
                folder: string;
                overrides?: Partial<PromptFolderDefaults>;
                pack?: string;
                packAgentKey?: string;
                smallModelName?: string;
            },
        ): Promise<
            { agentId: string; nickname: string; unresolvedDocumentIds: string[] },
        >;
        createStory(
            name: string,
            idea: string,
            userCharacterDesc: string,
            otherCharactersDesc: string,
            illustrateStory: boolean,
            storyModel?: string,
            isImport?: boolean,
            imageModelName?: string,
            skipDetailedPlot?: boolean,
        ): Promise<StoryInfo>;
        createTool(tool: ToolDefinition): Promise<ToolDefinition>;
        createUserArtifact(name: string, content: string): string;
        declineCharacter(storyId: string, characterName: string): Promise<void>;
        deleteAgent(agentId: string): Promise<void>;
        deleteAttachedFile(agentId: string, fileName: string): Promise<void>;
        deleteAttachedFileById(documentId: string): Promise<void>;
        deleteChapter(storyId: string, chapterIndex: number): void;
        deleteCharacterFromStory(
            storyId: string,
            characterName: string,
        ): Promise<void>;
        deleteLastAgentMessage(agentId: string): Promise<AgentMessagesResponse>;
        deletePromptFile(folderName: string, fileName: string): void;
        deletePromptFolder(folderName: string): void;
        deleteRoom(roomId: string): Promise<void>;
        deleteStory(storyId: string): Promise<void>;
        deleteTool(name: string): Promise<void>;
        deleteUserArtifact(artifactId: string): boolean;
        detachArtifactFromAgent(agentId: string, artifactId: string): Promise<void>;
        downloadStoryMarkdown(storyId: string): Promise<string>;
        editRoom(
            roomId: string,
            roomName: string,
            goal: string,
            baseRoomDir?: string,
            agentIds?: string[],
            roomLeader?: string,
            turnMode?: RoomTurnMode,
            moderator?: string,
            pack?: string,
            beginInstruction?: string,
            imageModel?: string,
            illustrationMode?: RoomIllustrationMode,
        ): Promise<void>;
        enabledPacks(): readonly string[];
        ensureAgentStateCallback(agentId: string): Promise<void>;
        ensureRoomStateCallback(roomId: string): Promise<void>;
        exportStoryData(
            storyId: string,
        ): Promise<{ filename: string; stream: Readable }>;
        getAgentDetails(agentId: string): Promise<AgentInfo>;
        getAgentHistory(
            storyId: string,
            agentId: string,
        ): Promise<{ content: string }>;
        getAgentMessageEmitter(agentId: string): EventEmitter<DefaultEventMap>;
        getAgentMessages(
            agentId: string,
            fromIndex?: number,
        ): Promise<AgentMessagesResponse>;
        getAiServiceNames(): string[];
        getBalance(): number;
        getBalanceMessageEmitter(userId: string): EventEmitter;
        getChapter(storyId: string, chapterIndex: number): Promise<RoomMessage[]>;
        getCharacter(
            storyId: string,
            characterName: string,
        ): Promise<{ content: string }>;
        getCharacterInventory(
            storyId: string,
            characterName: string,
        ): Promise<{ content: string }>;
        getPlotPlan(storyId: string): Promise<{ content: string }>;
        getPromptFile(folderName: string, fileName: string): PromptFileContent;
        getPromptFolderDefaults(folderName: string): PromptFolderDefaultsResponse;
        getPublishedInstances(templateId: string): Promise<AgentInfo[]>;
        getPublishedRoomInstances(templateId: string): Promise<RoomInfo[]>;
        getRandomStoryIdea(): StoryIdea;
        getRandomStoryIdeaByGenre(genreName: string): StoryIdea;
        getRoomArtifacts(roomId: string): Promise<{ artifacts: any[] }>;
        getRoomById(roomId: string): Promise<Room>;
        getRoomDetails(roomId: string): Promise<RoomDetails>;
        getRoomImage(
            roomId: string,
            artifactId: string,
        ): Promise<{ content: string | Buffer<ArrayBufferLike>; mimeType: string }>;
        getRoomMessageEmitter(roomId: string): EventEmitter<DefaultEventMap>;
        getRoomMessages(
            roomId: string,
            fromIndex?: number,
            includeThoughts?: boolean,
        ): Promise<RoomMessagesResponse>;
        getStoryArtifact(
            storyId: string,
            artifactId: string,
        ): string | Buffer<ArrayBufferLike>;
        getStoryInfo(storyId: string): Promise<StoryInfo>;
        getStoryMessageEmitter(storyId: string): EventEmitter<DefaultEventMap>;
        getStoryMessages(
            storyId: string,
            fromIndex: number,
        ): Promise<RoomMessagesResponse>;
        getStoryProgressEmitter(storyId: string): EventEmitter<DefaultEventMap>;
        getStoryState(storyId: string): Promise<StoryState>;
        getTransactionByPaymentId(paymentId: string): Promise<Transaction>;
        getTransactions(
            limit?: number,
            offset?: number,
        ): Promise<TransactionHistoryResponse>;
        getUserArtifact(artifactId: string): string | Buffer<ArrayBufferLike>;
        getUserPreferences(): any;
        importStoryFromZip(zipBuffer: Buffer): Promise<StoryInfo>;
        interruptStory(storyId: string): Promise<void>;
        introduceCharacterToStory(
            storyId: string,
            name: string,
            description: string,
            storyModel?: string,
            fromNarratorSuggestion?: boolean,
        ): Promise<void>;
        listAgentArtifacts(agentId: string): Promise<ArtifactMetadata[]>;
        listAgents(includeRoomAgents?: boolean): Promise<AgentInfo[]>;
        listAiModels(aiServiceName: string): Promise<ModelInfo[]>;
        listAttachedFiles(agentId: string): Promise<FileList>;
        listChapters(storyId: string): { chapters: ChapterInfo[] };
        listCharacters(storyId: string): Promise<Character[]>;
        listImageModels(): Promise<ImageModelOption[]>;
        listNativeToolSummaries(): ToolSummary[];
        listPromptFiles(folderName: string): FileList;
        listPromptFilesWithScope(folderName: string): PromptFilesResponse;
        listPromptFolders(): string[];
        listPromptFoldersWithScope(scope?: PromptScope): PromptFoldersResponse;
        listPrompts(agentId: string): Promise<string[]>;
        listPublishedAgents(): Promise<AgentInfo[]>;
        listPublishedRooms(): Promise<RoomInfo[]>;
        listRooms(): Promise<RoomInfo[]>;
        listStories(): StoryInfo[];
        listStoryArtifacts(storyId: string): ArtifactMetadata[];
        listStoryGenres(): string[];
        listStoryModels(): Promise<ModelInfo[]>;
        listTools(): Promise<ToolDefinition[]>;
        listUserArtifacts(): ArtifactMetadata[];
        pauseRoom(roomId: string): Promise<void>;
        processText(agentId: string, text: string): Promise<ProcessTextResponse>;
        progressStory(storyId: string): Promise<{ chapterIndex: number }>;
        promptFolderExists(folderName: string): boolean;
        publishAgentInstance(
            templateId: string,
            instanceName: string,
        ): Promise<{ instanceId: string; publicUrl: string }>;
        publishArtifact(
            roomId: string,
            name: string,
            creator: string,
            body: string,
            viewers?: string[],
        ): Promise<void>;
        publishRoom(
            templateId: string,
            publishedName: string,
            userId: string,
        ): Promise<string>;
        recordTransaction(
            amount: number,
            paymentId: string,
            status?: "pending" | "succeeded" | "failed" | "cancelled",
        ): Promise<Transaction>;
        reloadAgent(agentId: string): Promise<void>;
        removeRoomAgent(roomId: string, agentId: string): Promise<void>;
        renameUserArtifact(artifactId: string, newName: string): boolean;
        resetPublishedInstance(instanceId: string): Promise<void>;
        resetPublishedRoomInstance(instanceId: string): Promise<void>;
        resetRoom(roomId: string): Promise<void>;
        resetStory(storyId: string): Promise<void>;
        respondToStory(storyId: string, content: string): Promise<void>;
        resumePausedStories(): Promise<number>;
        resumeRoom(roomId: string): Promise<void>;
        revertStoryChapter(storyId: string): Promise<void>;
        runPreparedPrompt(
            agentId: string,
            promptName: string,
            variables?: any,
        ): Promise<PreparedPromptResponse>;
        saveChapter(storyId: string, chapterIndex: number, content: string): void;
        saveCharacter(
            storyId: string,
            characterName: string,
            content: string,
        ): void;
        saveCharacterInventory(
            storyId: string,
            characterName: string,
            content: string,
        ): Promise<void>;
        savePlotPlan(storyId: string, content: string): Promise<void>;
        savePromptFile(
            folderName: string,
            fileName: string,
            content: string,
            fileType: string,
        ): void;
        saveUserPreferences(preferences: any): void;
        sendRoomMessage(
            roomId: string,
            content: string,
            sender: string,
            action?: string,
            targets?: string[],
            clearQueue?: boolean,
            context?: unknown,
        ): Promise<SendMessageResult>;
        setPackInstantiation(service: PackInstantiationService): void;
        setRoomLeader(roomId: string, agentNickname: string): Promise<void>;
        setRpg(service: RpgService): void;
        testTool(name: string, args: Record<string, any>): Promise<ToolRunResult>;
        updateAgent(agentId: string, updates: UpdateAgentRequest): Promise<void>;
        updateTool(name: string, tool: ToolDefinition): Promise<ToolDefinition>;
        updateTransactionStatus(
            paymentId: string,
            status: "pending" | "succeeded" | "failed" | "cancelled",
        ): Promise<void>;
        updateUserArtifact(artifactId: string, content: string): boolean;
    }
    Index
    addBalance attachArtifactToAgent attachDocument beginRoom compactAgentConversation compactStory convertPdfToMarkdownPages convertUserArtifact createAgent createAgentFromFolder createPromptFolder createRoom createRoomAgent createRoomAgentFromFolder createStory createTool createUserArtifact declineCharacter deleteAgent deleteAttachedFile deleteAttachedFileById deleteChapter deleteCharacterFromStory deleteLastAgentMessage deletePromptFile deletePromptFolder deleteRoom deleteStory deleteTool deleteUserArtifact detachArtifactFromAgent downloadStoryMarkdown editRoom enabledPacks ensureAgentStateCallback ensureRoomStateCallback exportStoryData getAgentDetails getAgentHistory getAgentMessageEmitter getAgentMessages getAiServiceNames getBalance getBalanceMessageEmitter getChapter getCharacter getCharacterInventory getPlotPlan getPromptFile getPromptFolderDefaults getPublishedInstances getPublishedRoomInstances getRandomStoryIdea getRandomStoryIdeaByGenre getRoomArtifacts getRoomById getRoomDetails getRoomImage getRoomMessageEmitter getRoomMessages getStoryArtifact getStoryInfo getStoryMessageEmitter getStoryMessages getStoryProgressEmitter getStoryState getTransactionByPaymentId getTransactions getUserArtifact getUserPreferences importStoryFromZip interruptStory introduceCharacterToStory listAgentArtifacts listAgents listAiModels listAttachedFiles listChapters listCharacters listImageModels listNativeToolSummaries listPromptFiles listPromptFilesWithScope listPromptFolders listPromptFoldersWithScope listPrompts listPublishedAgents listPublishedRooms listRooms listStories listStoryArtifacts listStoryGenres listStoryModels listTools listUserArtifacts pauseRoom processText progressStory promptFolderExists publishAgentInstance publishArtifact publishRoom recordTransaction reloadAgent removeRoomAgent renameUserArtifact resetPublishedInstance resetPublishedRoomInstance resetRoom resetStory respondToStory resumePausedStories resumeRoom revertStoryChapter runPreparedPrompt saveChapter saveCharacter saveCharacterInventory savePlotPlan savePromptFile saveUserPreferences sendRoomMessage setPackInstantiation setRoomLeader setRpg testTool updateAgent updateTool updateTransactionStatus updateUserArtifact
    • get packs(): PackService

      Packs, as this user sees them.

      Returns PackService

    • get rpg(): RpgService

      Campaigns: the streamlined D&D surface, built on packs and published rooms.

      Returns RpgService

    • get userAuthoredToolsEnabled(): boolean

      Whether this deployment permits users to author and run their own tools. Native (host-registered) tools are always available regardless.

      Returns boolean

    • Adds funds to the user's balance.

      Use this to credit a user after a payment is processed by your application.

      Parameters

      • amount: number

        Dollar amount to add (must be positive)

      Returns void

    • Attaches a user artifact to an agent so the agent can read its content in prompts.

      The attachment is persisted immediately via agent.save(). The artifact content is injected into the agent's context on each subsequent call.

      Parameters

      • agentId: string

        The agent's ID

      • artifactId: string

        The artifact's ID (from listUserArtifacts)

      Returns Promise<void>

      If the agent or artifact does not exist

    • Attaches a document to an agent so it can reference the file's contents in prompts.

      The file is stored on disk and uploaded to the AI provider if required (e.g. OpenAI file uploads, Grok file uploads). The agent state is persisted after attachment.

      Parameters

      • agentId: string

        The agent's ID

      • fileName: string

        File name including extension (e.g. 'report.pdf')

      • fileData: Buffer

        Raw file bytes as a Buffer

      Returns Promise<AttachDocumentResponse>

      Object containing a documentId that can be used with deleteAttachedFileById

      If no agent with the given ID exists

    • Opens a room by sending its begin instruction to the room leader.

      A room is pull-driven: an agent is prompted only when a message arrives. So a room nobody has spoken in never moves, however complete its configuration — which for a turn-based table means the leader is waiting to be asked to lead. This is the ask.

      Sent as System rather than as a person, and addressed by targets rather than left for the room to place: in broadcast mode an untargeted message prompts every agent, which for an opening move is one call per member to decide one reply.

      The already-begun check is here rather than left to the client because a published room is one link the whole party holds. Two people looking at the same empty transcript both press Begin, and only a check the room makes itself stops the leader being opened twice. isProcessingInProgress() is the half of it that covers the window before the first message lands.

      Parameters

      • roomId: string

        The room's ID

      • Optionalcontext: unknown

        Opaque host value threaded to any tool the turn invokes

      Returns Promise<SendMessageResult>

      Whether the message was accepted, as sendRoomMessage reports it

      If the room does not exist

      If the room has no begin instruction, or no agent to address

      If the room has already begun

    • Compacts an agent's conversation history into a single summary message. Uses the compact_agent prompt (role folder first, common-root as fallback).

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<void>

      If no agent with the given ID exists

    • Summarizes and compresses agent conversation histories to reduce token usage.

      Uses story-specific prompts: the narrator summarizes plot events, characters summarize their relationships and experiences. The original messages are replaced with a compact summary block.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<{ details?: any; message?: string; success: boolean }>

      Object with success flag, optional message, and compaction details

    • Converts a PDF to Markdown a page at a time and returns the pages.

      The building block under convertUserArtifact, public because a host embedding Briyah usually wants the pages and the cost rather than an artifact — to extract records from each page, to cache the result under its own key, or to show progress. Every page is converted by its own throwaway agent, so nothing accumulates history and pages stay independent.

      Bounded, retried and non-fatal: at most PdfMarkdownOptions.concurrency pages are in flight, each page is retried on an empty response, a thrown error or a timeout, and a page that exhausts its attempts is reported in failedPages rather than failing the document.

      Parameters

      • pdfBuffer: Uint8Array<ArrayBufferLike> | Buffer<ArrayBufferLike>

        The raw PDF

      • options: PdfMarkdownOptions = {}

        Models, prompt, hints and limits; every field has a default

      Returns Promise<PdfMarkdownResult>

      The pages, the assembled Markdown, what failed, and the cost

      If no conversion service or model is configured

      const result = await appService.convertPdfToMarkdownPages(buffer, {
      concurrency: 8,
      fidelityHints: 'chapter and verse numbers',
      onProgress: (message) => console.log(message),
      });
      if (result.failedPages.length) console.warn('Re-run pages', result.failedPages);
    • Creates an artifact from a PDF by converting it to Markdown, running the conversion in the background.

      Returns the artifact ID immediately with placeholder content. The artifact content is replaced with the converted Markdown when the background job finishes. If conversion fails, the artifact content is replaced with an error message.

      Requires the DOC_CONVERSION_AI_SERVICE and DOC_CONVERSION_AI_MODEL environment variables to be set to an AI service that supports PDF documents.

      A PDF over ten pages is converted page by page, at most PDF_CONVERT_CONCURRENCY at a time, with each page retried before it is given up on. A page that is given up on does not fail the document: the artifact still lands, naming the pages that are missing from it so they can be re-run. Only a conversion that produces nothing at all replaces the artifact with an error.

      Parameters

      • name: string

        Display name for the artifact

      • pdfBuffer: Buffer

        Buffer containing the raw PDF data

      Returns string

      The new artifact's ID (content is a placeholder until conversion completes)

    • Creates a new AI agent and registers it in memory.

      The agent is immediately findable by ID but not persisted to disk. Call agent.save() when you want to write it to storage.

      Parameters

      • aiServiceName: string

        Provider name (e.g. 'Anthropic', 'OpenAI'). Use getAiServiceNames for valid values.

      • agentName: string

        Full name of the agent (used in conversation logs and file storage)

      • agentNickname: string

        Short display name shown in the UI

      • description: string

        Brief description of the agent's role or personality

      • aiModel: string

        Model identifier (e.g. 'claude-haiku-4-5', 'gpt-4o')

      • promptName: string = 'default'

        Prompt folder under data/prompts/ that provides the agent's system instruction. Defaults to 'default'.

      • OptionalcontrolledByHuman: boolean

        If true, the agent's responses are driven by a human rather than the AI. Defaults to false.

      • OptionalreasoningEffort: "low" | "medium" | "high"

        Extended-thinking effort level for models that support it (e.g. Claude 3.7 Sonnet, o1/o3). Pass null to disable. Defaults to undefined (model default).

      • OptionalmaxOutputTokens: number

        Override the model's default maximum output token limit

      • OptionalbeginInstruction: string

        Optional prompt stored with the agent and sent when the host app triggers a "Begin" action (e.g. 'Begin by reading the attached documents and asking the user the first question.')

      • Optionaloptions: AgentCreationOptions

        Everything else an agent can be created with: tool grants, private context, prompt cache TTL, search, the history window and the small-model override. Add new settings here rather than as further positional parameters.

      Returns Agent

      The newly created Agent instance

      const agent = appService.createAgent(
      'Anthropic',
      'AI Assistant',
      'James',
      'A helpful AI assistant',
      'claude-haiku-4-5',
      );
      if (!agent.id) throw new Error('Agent creation failed');
      agent.save(); // persist to disk
    • Creates an agent from a prompt folder, applying everything that folder declares.

      A folder's defaults_config.json names the role: what it is called, which tools it needs, which documents it carries. createAgent takes none of that — it takes eleven positional arguments and an options object, and leaves the mapping to the caller. Every caller then writes the same mapping: the web client's create-agent dialog, and every SDK host after it. Hard-coding the result instead is worse, because a pack's tool and document lists change and a transcribed copy does not.

      Differences from createAgent, each deliberate:

      • It saves. A convenience constructor that leaves the agent in memory only loses it on restart, which is not what a caller reaching for one expects.
      • It attaches the folder's documents, unless attachDocuments is false. PromptFolderDefaults.documentIds describes them as a pre-tick that stays the user's choice, which is right for a dialog where somebody can untick a box; headless there is nobody to untick, and a character creator without its class documents builds sheets with no spells and no class features.
      • It is async, only because attaching is.

      Parameters

      • options: {
            aiModel: string;
            aiServiceName: string;
            attachDocuments?: boolean;
            folder: string;
            overrides?: Partial<PromptFolderDefaults>;
        }
        • aiModel: string

          Model id for this agent

        • aiServiceName: string

          Provider name, e.g. 'Anthropic'

        • OptionalattachDocuments?: boolean

          Attach the folder's documentIds (default true)

        • folder: string

          Prompt folder name, e.g. 'dungeon_master'

        • Optionaloverrides?: Partial<PromptFolderDefaults>

          Fields to override the folder's declared defaults; the same shape, so {agentNickname: 'Homer', controlledByHuman: true} is all a human-controlled player needs

      Returns Promise<Agent>

      The created, saved agent

      If the folder does not exist. Unlike createAgent, which warns and carries on, this refuses: the whole point of the call is the folder's recipe, and a folder that is not there has none — the agent would come out with no tools, no documents and the shared root prompts

      If the agent could not be created

      const dm = await appService.createAgentFromFolder({
      folder: 'dungeon_master',
      aiServiceName: 'Anthropic',
      aiModel: 'claude-sonnet-5',
      });
      const you = await appService.createAgentFromFolder({
      folder: 'dnd_player',
      aiServiceName: 'Anthropic',
      aiModel: 'claude-haiku-4-5',
      overrides: { agentNickname: 'Homer', controlledByHuman: true },
      });
    • Creates a new prompt folder in the user prompts directory.

      An empty system_instruction.prompt file is created inside the folder so that it is immediately usable as a prompt source for agents.

      Parameters

      • folderName: string

        Name of the folder to create

      Returns void

      If a folder with that name already exists

    • Parameters

      • roomName: string
      • goal: string
      • agentIds: string[]
      • OptionalroomLeader: string
      • OptionalturnMode: RoomTurnMode
      • Optionalmoderator: string
      • OptionalbeginInstruction: string
      • OptionalimageModel: string
      • OptionalillustrationMode: RoomIllustrationMode

      Returns Promise<CreateRoomResponse>

    • Creates an agent that belongs to a room and adds it to that room.

      This is the only way an agent joins a room. The agent is owned by it: it is left out of listAgents and deleted with the room, so a room is a self-contained cast rather than a set of references to a shared pool.

      request.agentName is the bare name. It is stored prefixed with the room's name, while the nickname is derived from the bare name — otherwise every agent in the room would be addressed by the room's first word.

      Parameters

      • roomId: string

        The room the agent will belong to

      • request: CreateAgentRequest

        The same fields createAgent takes

      Returns Promise<CreateAgentResponse>

      Object containing the new agentId

      If the room does not exist

      If the room is a published instance, or another agent in the room already answers to the same nickname

    • Adds an agent to a room, built from a prompt folder's declared defaults.

      The room-scoped counterpart to createAgentFromFolder, and the piece a pack's room template is instantiated through. Everything a folder already declares — name, nickname, description, tool grants, documents, cache TTL — comes from its defaults_config.json, so a template only has to say what differs.

      Routed through createRoomAgent rather than createAgentFromFolder, which does none of what a room member needs: the stored name is prefixed with the room's, the nickname is derived from the bare name, ownerRoomId is set, the moderator requirement is checked, and an agent whose nickname collides is removed again instead of being left behind belonging to a room it never joined.

      Parameters

      • roomId: string

        The room to add to

      • options: {
            aiModel: string;
            aiServiceName: string;
            folder: string;
            overrides?: Partial<PromptFolderDefaults>;
            pack?: string;
            packAgentKey?: string;
            smallModelName?: string;
        }

        The folder to build from, the model to use, and any overrides

        • aiModel: string
        • aiServiceName: string
        • folder: string
        • Optionaloverrides?: Partial<PromptFolderDefaults>
        • Optionalpack?: string

          Files the new agent under a pack, so it is listed and hidden with it.

        • OptionalpackAgentKey?: string

          The pack template's key, when this agent came from one.

        • OptionalsmallModelName?: string

      Returns Promise<{ agentId: string; nickname: string; unresolvedDocumentIds: string[] }>

      The new agent's id, its resolved nickname, and any document ids that resolved to nothing — returned rather than swallowed, because a document that silently fails to attach is a capability the agent appears to have and does not

      If the room does not exist, or the folder does not. See createAgentFromFolder for why a missing folder is fatal here

      If the agent needs a moderator the room does not have

      If the nickname is already taken in the room

    • Creates a new interactive story with AI-driven characters.

      When this method returns, the story is immediately playable: brief character backgrounds and the opening scene have already been generated. A background job then generates the detailed plot plan and full character profiles; subscribe to getStoryProgressEmitter to be notified when that finishes (step === 'complete'), but there is no need to wait for it before letting the player interact.

      Parameters

      • name: string

        Display name for the story

      • idea: string

        Brief premise or concept for the story

      • userCharacterDesc: string

        Description of the character the human player will portray

      • otherCharactersDesc: string

        Description of other prominent characters to generate

      • illustrateStory: boolean
      • OptionalstoryModel: string

        Model identifier from story_models.json (e.g. 'claude-haiku-4-5'). Defaults to the configured default.

      • OptionalisImport: boolean

        Set true when reconstructing a story from exported data. Default false.

      • OptionalimageModelName: string

        Optional image model name from image_models.json (supplies both the generation and editing models)

      • OptionalskipDetailedPlot: boolean

        Set true to generate a simple plot scenario instead of a detailed plot plan with secrets, twists, and events. Default false.

      Returns Promise<StoryInfo>

      Story metadata including the new id - story is ready to play immediately

      // Story is playable as soon as createStory returns
      const story = await appService.createStory(
      'The Lost Kingdom',
      'A medieval fantasy adventure',
      'A young knight seeking redemption',
      'A wise wizard and a cunning rogue',
      );

      // Optionally listen for background completion (plot plan + detailed profiles)
      const emitter = appService.getStoryProgressEmitter(story.id);
      emitter?.on('progress', ({ step, message }) => {
      if (step === 'complete') console.log('Background setup finished');
      });
    • Creates a new user-authored tool.

      Parameters

      Returns Promise<ToolDefinition>

      The created tool definition

      If authoring is disabled or the name already exists

    • Creates a new named artifact and returns its ID.

      The artifact is persisted immediately. Use the returned ID to attach it to agents (attachArtifactToAgent) or reference it in room messages.

      Parameters

      • name: string

        Human-readable display name for the artifact

      • content: string

        Initial text content (typically Markdown)

      Returns string

      The new artifact's ID

    • Records that the player declined a narrator-suggested character introduction.

      Prevents the narrator from suggesting the same character again in this story.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character name that was declined

      Returns Promise<void>

    • Permanently deletes an agent and all its stored data.

      If the agent is a published instance, its entry is also removed from the published agents mapping.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<void>

      If no agent with the given ID exists

    • Removes a file from an agent by its file name.

      Deletes the file from storage and updates the agent's metadata. Use deleteAttachedFileById if you have the document ID instead.

      Parameters

      • agentId: string

        The agent's ID

      • fileName: string

        Name of the file to remove (e.g. 'report.pdf')

      Returns Promise<void>

      If the agent or file is not found

    • Removes an attached file by its document ID (as returned by attachDocument).

      Searches all agents to locate the owner, removes the file from storage, and updates the agent's metadata.

      Parameters

      Returns Promise<void>

      If no file with the given ID exists

      If deletion fails

    • Deletes a chapter checkpoint from a story.

      Parameters

      • storyId: string

        The story's ID

      • chapterIndex: number

        The chapter number to delete

      Returns void

      If the chapter does not exist

    • Removes a character's agent from the story while preserving their profile file.

      The character can be reintroduced later via introduceCharacterToStory and their profile will be available.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character's name

      Returns Promise<void>

    • Removes the newest message from an agent's conversation.

      Returns the conversation as it now stands rather than nothing, because the caller is a button somebody clicks repeatedly: a second round trip for the new transcript would show the list lagging a click behind on a slow connection.

      Parameters

      • agentId: string

        The agent whose history to shorten

      Returns Promise<AgentMessagesResponse>

      The remaining messages and the agent's running totals

      If there is no such agent

    • Deletes a prompt file from the user prompts directory.

      Removes both the .prompt and .json variants if they exist. This is a no-op if neither file is present.

      Parameters

      • folderName: string

        Prompt folder name, or 'shared' for the root prompts directory

      • fileName: string

        Base name of the file to delete (without extension)

      Returns void

    • Deletes a prompt folder and all its contents from the user prompts directory.

      Only user-owned folders can be deleted; common folders are not affected.

      Parameters

      • folderName: string

        Name of the folder to delete

      Returns void

      If folderName is 'shared'

      If the folder does not exist in the user prompts directory

    • Permanently deletes a room and all its data.

      If the room is a template, all of its published instances are deleted first. The agents the room owns, its attached files and its published room mapping are also cleaned up.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<void>

      If the room does not exist

      If deletion fails

    • Permanently deletes a story, its room, all characters, chapters, and artifacts.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<void>

    • Deletes a user-authored tool. Agents granted the tool keep the (now dangling) grant; the room silently drops missing tools from their prompts.

      Parameters

      • name: string

        The tool's name

      Returns Promise<void>

      If the tool does not exist

      If authoring is disabled

    • Permanently deletes a user artifact.

      Any agents that have the artifact attached will lose access to it after deletion.

      Parameters

      Returns boolean

      true on success, false if no artifact with that ID exists

    • Removes an artifact attachment from an agent.

      The artifact itself is not deleted - only the link between the agent and the artifact is removed. Changes are persisted immediately via agent.save().

      Parameters

      • agentId: string

        The agent's ID

      • artifactId: string

        The artifact's ID to detach

      Returns Promise<void>

      If no agent with the given ID exists

    • Generates the full story as a single markdown document.

      Combines all chapters and room messages in narrative order.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<string>

      The complete story formatted as markdown text

    • Updates the name, goal, and/or agent membership of an existing room.

      Published room instances cannot be edited - edit the template instead.

      Parameters

      • roomId: string

        The room's ID

      • roomName: string

        New display name

      • goal: string

        New goal description

      • OptionalbaseRoomDir: string

        Optional override for the room's base storage directory

      • OptionalagentIds: string[]

        Replacement list of agent IDs (replaces current membership entirely). Omit to leave membership unchanged, which is what the client does: membership is managed through createRoomAgent and removeRoomAgent, not by re-sending the roster with every rename.

      • OptionalroomLeader: string

        Nickname (or name) of the member agent to lead the room. Omit to leave the current leader unchanged.

      • OptionalturnMode: RoomTurnMode

        How the room chooses who responds. Omit to leave unchanged. See RoomTurnMode.

      • Optionalmoderator: string

        Nickname of the moderator agent. Omit to leave unchanged.

      • Optionalpack: string

        The pack to file the room under. Empty string clears it.

      • OptionalbeginInstruction: string

        What beginRoom sends to the leader. Empty string clears it, which withdraws the room's Begin. Omit to leave unchanged.

      • OptionalimageModel: string
      • OptionalillustrationMode: RoomIllustrationMode

      Returns Promise<void>

      If the room does not exist

      If attempting to edit a published room instance

    • The packs this user has enabled, as a thunk.

      Handed to the prompt resolver and to every agent this service creates. A thunk rather than an array because both outlive a toggle — see Agent.enabledPacks.

      Returns readonly string[]

    • Ensures the real-time state callback is registered for an agent.

      Normally called automatically by processText and getAgentMessages. Call this explicitly when connecting a new SSE client to an agent that was loaded from disk (not yet touched in this session).

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<void>

    • Ensures the real-time state callback is registered for a room.

      Normally called automatically. Call this explicitly when connecting a new SSE client to a room that was loaded from disk (not yet touched in this session).

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<void>

    • Exports the complete story data as a downloadable zip archive.

      The archive can be re-imported via importStoryFromZip.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<{ filename: string; stream: Readable }>

      Object with a stream (readable zip stream) and filename for the download

    • Returns detailed metadata for a specific agent.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<AgentInfo>

      Agent metadata object, or null if no agent with the given ID exists

    • Returns the formatted conversation history for a specific character in a story.

      Parameters

      • storyId: string

        The story's ID

      • agentId: string

        The character agent's ID

      Returns Promise<{ content: string }>

      Object with content containing the formatted history text

    • Returns a Node.js EventEmitter that fires whenever this agent's state changes (new message, token count update, etc.).

      Useful for building real-time UIs. Subscribe to the 'update' event to receive agent state payloads without polling.

      Parameters

      • agentId: string

        The agent's ID

      Returns EventEmitter<DefaultEventMap>

      EventEmitter that emits 'update' events with agent state payloads

      const emitter = appService.getAgentMessageEmitter(agent.id);
      emitter.on('update', (state) => {
      console.log('New message:', state.latestMessage);
      });
    • Returns an agent's conversation history starting from a given index.

      Pass the messageIndex from a previous response as fromIndex to retrieve only new messages since the last poll.

      Parameters

      • agentId: string

        The agent's ID

      • fromIndex: number = 0

        Zero-based index to start from (default 0 returns all messages)

      Returns Promise<AgentMessagesResponse>

      Object with the messages array and cumulative token/cost totals. Returns empty messages with zero counts if the agent is not found.

    • Returns the names of all available AI service providers.

      Only providers that have a configured API key are included.

      Returns string[]

      Array of provider names (e.g. 'Anthropic', 'OpenAI', 'GoogleAI')

    • Returns the user's current credit balance in dollars.

      The balance is decremented automatically after each AI call based on token usage and any configured markup. Calls that would exceed the balance throw InsufficientBalanceError before the request is sent.

      Returns number

      Current balance in dollars

    • Returns a Node.js EventEmitter that fires whenever the user's balance changes.

      Subscribe to the 'update' event to push real-time balance updates to a connected client (e.g. via SSE) without polling.

      Parameters

      • userId: string

        The user's ID (typically the same ID used with getAppService)

      Returns EventEmitter

      EventEmitter that emits 'update' events with the new balance value

    • Returns the messages from a specific chapter checkpoint.

      Parameters

      • storyId: string

        The story's ID

      • chapterIndex: number

        The chapter number (1-based, as returned by listChapters)

      Returns Promise<RoomMessage[]>

      Array of room messages from that chapter

    • Returns the profile for a specific character.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character's name

      Returns Promise<{ content: string }>

      Object with content containing the character profile markdown

    • Returns the inventory for a specific character.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character's name

      Returns Promise<{ content: string }>

      Object with content containing the inventory markdown

    • Returns the story's plot plan.

      The plot plan is a room artifact generated by the narrator at story creation and updated as the story progresses.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<{ content: string }>

      Object with content containing the plot plan markdown

    • Reads a prompt file, applying the shared lookup order (prompt-resolver.ts).

      For a bare folder that is the historical four levels — user/{folder}, user/root, common/{folder}, common/root — plus the folders of any pack this user has enabled. For a pack-qualified folder (dnd5e:battle_master) it is the pack's own tiers, then the shared roots.

      The returned scope collapses the four tiers onto the two the client knows: a pack overlay reports 'user', a pack's own file reports 'common'. pack and tier carry the detail, and are populated even when the reference was bare. Returns { content: '' } if the file does not exist in any location.

      Parameters

      • folderName: string

        Prompt folder name, 'shared' for the root prompts directory, or a pack-qualified name like dnd5e:dungeon_master

      • fileName: string

        Base name of the prompt file (with or without .prompt/.json extension)

      Returns PromptFileContent

      { content, scope, pack, tier } where all but content are omitted when not found

    • Reads a prompt folder's defaults_config.json — the agent settings the create-agent form pre-fills when that folder is chosen.

      Resolved through the same 4-level fallback as any other prompt file, so a user copy overrides the shipped one and a file at the prompts root supplies defaults for every folder that has none of its own.

      A missing file and an unparseable one both return { defaults: {} }: defaults are a convenience, and a folder must stay usable when its config is broken. Unparseable is logged; missing is not, since most folders have no config at all.

      Every field is coerced to its declared type and unknown keys are dropped, so a typo in a hand-edited file cannot ride through to the create-agent request.

      Parameters

      • folderName: string

        Prompt folder name, or 'shared' for the root prompts directory

      Returns PromptFolderDefaultsResponse

      The declared defaults, and the scope the file was read from

    • Returns all published instances created from a template agent.

      Parameters

      • templateId: string

        ID of the template agent

      Returns Promise<AgentInfo[]>

      Array of agent metadata objects for each published instance

    • Returns all published instances created from a template room.

      Parameters

      • templateId: string

        ID of the template room

      Returns Promise<RoomInfo[]>

      Array of room summary objects for each published instance

    • Returns a random story idea from a randomly selected genre.

      Returns StoryIdea

      A random StoryIdea object, or null if no genres/ideas are available

    • Returns a random story idea from the specified genre.

      Parameters

      • genreName: string

        Genre name as returned by listStoryGenres (e.g. 'fantasy')

      Returns StoryIdea

      A random StoryIdea object, or null if the genre file is empty

      If the genre does not exist

      If the genre file cannot be read

    • Returns all artifacts published in a room.

      Artifacts are collaborative documents created by agents via the 'publish' action.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<{ artifacts: any[] }>

      Object with an artifacts array. Returns { artifacts: [] } if the room is not found.

    • Returns the raw Room object for a given ID.

      Use getRoomDetails for a plain metadata object. This method exposes the full Room instance, which is useful for advanced operations.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<Room>

      The Room instance, or null if not found

    • Returns full details for a room, including the metadata of each member agent.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<RoomDetails>

      Room details object, or null if no room with the given ID exists

    • Returns one of a room's generated images, with the metadata needed to serve it. Rooms keep their images in their own directory, separate from the .artifact text files, so this does not go through the artifact store.

      Parameters

      • roomId: string

        The room's ID

      • artifactId: string

        The image's ID, as it appears in the message markdown

      Returns Promise<{ content: string | Buffer<ArrayBufferLike>; mimeType: string }>

      The bytes and MIME type, or null when there is no such image

    • Returns a Node.js EventEmitter that fires whenever a new message arrives in the room.

      Subscribe to the 'update' event to receive room message payloads in real time without polling.

      Parameters

      • roomId: string

        The room's ID

      Returns EventEmitter<DefaultEventMap>

      EventEmitter that emits 'update' events with room message payloads

    • Returns messages from a room's conversation log starting from a given index.

      Pass the index of the last message you received as fromIndex to poll for new messages only.

      Parameters

      • roomId: string

        The room's ID

      • fromIndex: number = 0

        Zero-based index to start from (default 0 returns all messages)

      • includeThoughts: boolean = false

        If true, includes 'think' action messages which are normally hidden (agents' internal reasoning). Default false.

      Returns Promise<RoomMessagesResponse>

      Object with the messages array and total cost across all agents. Returns empty messages with zero cost if the room is not found.

    • Returns the content of a specific story artifact.

      Parameters

      • storyId: string

        The story's ID

      • artifactId: string

        The artifact's ID (from listStoryArtifacts)

      Returns string | Buffer<ArrayBufferLike>

      The artifact content as a string or Buffer, or null if not found

    • Returns metadata for a specific story.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<StoryInfo>

      Story metadata, or undefined if not found

    • Returns the EventEmitter for real-time story updates.

      The emitter fires four named events. Each payload includes a timestamp field.


      'story-state' - StoryStateEvent Fires after every room turn with the complete updated game state.

      emitter.on('story-state', (event: StoryStateEvent) => {
      const myTurn = event.state.currentSpeaker === event.state.userAgentName;
      });

      Use state.currentSpeaker === state.userAgentName to detect the player's turn. Do not use state.humanPrompt for turn detection - it is a UI display string (e.g. "What does Elena do next?") present even when it is not the player's turn.


      'suggest-introduce-character' - StoryIntroduceCharacterEvent Fires when the narrator wants to add a new character. The host app should surface this to the player before acting.

      emitter.on('suggest-introduce-character', (event: StoryIntroduceCharacterEvent) => {
      // event.characterName is the narrator-chosen name
      });

      'suggest-progress-chapter' - StoryProgressChapterEvent Fires when the narrator wants to advance to the next chapter. The host app should surface this to the player before acting.

      • Accept: call progressStory
      • Stay in current chapter: ignore the event (no rejection call needed)

      'story-error' - StoryErrorEvent Fires when the story engine encounters a fatal error during room processing. Named 'story-error' rather than 'error' to avoid Node.js throwing an uncaught exception when no listener is attached to 'error'. Check event.errorType === 'InsufficientBalanceError' for balance failures.


      Parameters

      • storyId: string

        The story's ID

      Returns EventEmitter<DefaultEventMap>

      EventEmitter emitting 'story-state', 'suggest-introduce-character', 'suggest-progress-chapter', and 'story-error' events

    • Gets messages from a story's room starting from a specific index

      Parameters

      • storyId: string

        The story ID

      • fromIndex: number

        The index to start from (0-based)

      Returns Promise<RoomMessagesResponse>

      Array of indexed messages and total story cost

    • Returns the EventEmitter for tracking background story work.

      Subscribe to the 'progress' event. Each event payload is { step: string, message: string, timestamp: number }.

      step values emitted after createStory returns:

      The story is already playable when createStory returns. There is no 'ready' step for story creation - the storyId does not exist until createStory returns, so the client cannot subscribe to the progress emitter until after that point. These steps describe the optional background job (plot plan + detailed profiles) that continues after the method returns:

      • 'start' - background job has begun
      • 'profiles' - generating detailed character profiles
      • 'portraits' - generating character portrait images (only if an image model is configured)
      • 'complete' - background job finished; detailed profiles and plot plan are now available
      • 'error' - background job failed; message contains the error text

      step values emitted during progressStory:

      'ready' fires just before progressStory returns, so the story is playable as soon as the Promise resolves - no need to separately listen for 'ready'. The event is emitted for the benefit of SSE clients that want to update their UI in real time. After 'ready', a background job continues:

      • 'opening-scene' - writing the new chapter's opening scene
      • 'chapter-backup' - saving chapter checkpoint data
      • 'ready' - chapter ready; fired just before progressStory resolves
      • 'profiles' - (background) recreating plot plan and character profiles
      • 'complete' - (background) all chapter work done
      • 'error' - progression failed

      The emitter is removed after the terminal step ('complete', 'ready', or 'error'), so this method returns undefined once a terminal step has fired.

      Parameters

      • storyId: string

        The story's ID

      Returns EventEmitter<DefaultEventMap>

      EventEmitter emitting 'progress' events, or undefined if already complete

    • Returns the current runtime state of a story.

      Includes messages, pending message count, processing status, and story metadata. Useful for restoring UI state after reconnecting.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<StoryState>

      Full story state object

    • Retrieves a single transaction by its payment provider ID.

      Parameters

      • paymentId: string

        The payment provider ID used when the transaction was recorded

      Returns Promise<Transaction>

      The matching Transaction, or null if not found

    • Returns paginated transaction history for this user, sorted newest-first.

      Parameters

      • limit: number = 50

        Maximum number of records to return (default: 50)

      • offset: number = 0

        Number of records to skip for pagination (default: 0)

      Returns Promise<TransactionHistoryResponse>

      Object with a transactions array and a total count

    • Returns the content of a user artifact.

      Text artifacts are returned as string; binary artifacts (e.g. converted PDFs in intermediate state) may be returned as Buffer.

      Parameters

      Returns string | Buffer<ArrayBufferLike>

      The artifact content, or null if no artifact with that ID exists

    • Returns the user's stored preferences object.

      Preferences are application-defined - Briyah stores and returns them as-is. Returns {} if no preferences have been saved yet.

      Returns any

      The preferences object previously written by saveUserPreferences, or an empty object if none exist

    • Reconstructs a story from a previously exported zip archive.

      Parameters

      Returns Promise<StoryInfo>

      Story metadata for the newly imported story

    • Cancels any pending AI turns and forces the human's turn.

      Drops the room's pending message queue and pauses processing so the human-controlled agent becomes the current speaker. Any in-flight LLM calls (perceive or moderator) will discard their responses on return.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<void>

    • Adds a new AI character to an existing story.

      Creates a character agent and integrates it into the story's room. The character profile is generated by the AI based on the provided description.

      When getStoryMessageEmitter fires a 'suggestion' update with suggestion.type === 'introduce_character', pass suggestion.characterName as name and set fromNarratorSuggestion: true to accept the suggestion. To reject it instead, call declineCharacter.

      Parameters

      • storyId: string

        The story's ID

      • name: string

        The character's name

      • description: string

        Brief description of the character's personality and role

      • OptionalstoryModel: string

        Optional model override from story_models.json

      • OptionalfromNarratorSuggestion: boolean

        Set true when accepting a narrator 'suggestion' update. Default false.

      Returns Promise<void>

    • Returns metadata for all artifacts currently attached to an agent.

      Attached artifacts are included in the agent's context on every prompt, allowing the agent to reference their content. Use attachArtifactToAgent and detachArtifactFromAgent to manage attachments.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<ArtifactMetadata[]>

      Array of artifact metadata objects for the agent's attached artifacts

      If no agent with the given ID exists

    • Lists all top-level agents belonging to this user.

      Agents that are owned by a room or story are excluded - use getRoomDetails or story methods to access those agents.

      Parameters

      • includeRoomAgents: boolean = false

        Also return the agents owned by a room or story. Only for offering an existing agent as something to copy; the agent list a user manages is the default, unowned one.

      Returns Promise<AgentInfo[]>

      Array of agent metadata objects

    • Fetches available models from the specified AI service provider.

      Parameters

      Returns Promise<ModelInfo[]>

      Array of model descriptors including name, description, and service

    • Lists the files currently attached to an agent.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<FileList>

      Object with a files array of file names. Returns { files: [] } if the agent is not found.

    • Returns all chapter checkpoints for a story.

      Chapters are created by progressStory and can be read with getChapter.

      Parameters

      • storyId: string

        The story's ID

      Returns { chapters: ChapterInfo[] }

      Object with a chapters array of chapter info objects

    • Returns all current characters in a story.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<Character[]>

      Array of character objects (derived from the story's room agents)

    • Returns models available for image generation, as configured in common/config/image_models.json.

      Returns Promise<ImageModelOption[]>

      Array of model descriptors. Returns an empty array if the config file is missing.

    • Native tools this user may grant.

      Filtered to the packs they have enabled. Two kinds are always listed: a tool with no group, registered by the host directly rather than by a pack, and a core tool, which belongs to the engine rather than to a domain and so has no pack to enable. Filtering core out would hide rename_agent from every user permanently, since core never appears in anyone's enabled list.

      Listing only. ToolExecutionService and Room.buildAvailableTools deliberately do not filter, so disabling a pack hides its tools from the pickers without stopping an agent that already holds one from calling it.

      Returns ToolSummary[]

      Code-free summaries of the grantable native tools

    • Returns the names of all prompt files in a folder, merged from both the common and user prompt directories.

      Pass 'shared' as folderName to list files in the root prompts directory. Files that exist in both directories appear once in the result.

      Parameters

      • folderName: string

        Folder to list, or 'shared' for the root prompts directory

      Returns FileList

      Object with a files array of base names (no extension), sorted alphabetically

    • Returns prompt file names in a folder annotated with their origin scope.

      When the same file name exists in both the common and user directories, the user copy wins and the entry is reported as scope: 'user'. Pass 'shared' as folderName to list files in the root prompts directory.

      Parameters

      • folderName: string

        Folder to list, or 'shared' for the root prompts directory

      Returns PromptFilesResponse

      Object with a files array of { name, scope } entries, sorted alphabetically

    • Returns every prompt folder name this user can reach.

      Covers the common and user prompt directories plus the folders of any pack the user has enabled, which appear pack-qualified (dnd5e:dungeon_master). A folder in more than one directory appears once.

      Returns string[]

      Sorted array of folder names

    • Returns prompt folder names annotated with where they came from.

      When the same folder name exists in both the user and common directories the user copy wins and the entry reports scope: 'user'. A pack's folder is a separate entry under its qualified name, so a pack shipping a witness folder does not collide with a witness folder the user wrote.

      Pack folders are listed only for enabled packs. That is the difference between listing and resolving: a disabled pack's folder still resolves when an agent names it, it just stops being offered.

      Parameters

      • Optionalscope: PromptScope

        Optional filter: 'common' returns only system-provided folders (including packs', which are read-only in the same way), 'user' returns only the user's own folders and their pack overlays, omit to return all

      Returns PromptFoldersResponse

      Object with a folders array, sorted by name

    • Returns all prepared prompt template names available to a specific agent.

      Merges prompts from the agent's own prompt folder and the root prompts directory, deduplicating across both. These names can be passed to runPreparedPrompt.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<string[]>

      Array of prompt template names (without file extension)

      If no agent with the given ID exists

    • Lists all published agent instances belonging to this user.

      Published agents are clones of template agents that are accessible via the public API (e.g. for end-users to chat with). Agents owned by rooms are excluded from this list.

      Returns Promise<AgentInfo[]>

      Array of agent metadata objects for all published instances

    • Lists every published room instance this user owns.

      The room counterpart to listPublishedAgents, and the only view of them that is not filtered by which template they came from — a published room is a live public link, and the point of the list is seeing all of them and what they have cost.

      Returns Promise<RoomInfo[]>

      Array of room summary objects, one per published instance

    • Lists the rooms this user builds and owns.

      Published instances are excluded — use getPublishedRoomInstances for those, which is also how the client reaches them.

      Returns Promise<RoomInfo[]>

      Array of room summary objects (id, name, goal, agent count)

    • Lists all stories belonging to this user.

      Returns StoryInfo[]

      Array of story metadata objects

    • Returns all artifacts associated with a story.

      Story artifacts include the plot plan and any documents published by agents during the narrative.

      Parameters

      • storyId: string

        The story's ID

      Returns ArtifactMetadata[]

      Array of artifact metadata objects

    • Returns the available story genre names.

      Genres are read from common/story_ideas/ - each .json file corresponds to a genre. Pass a genre name to getRandomStoryIdeaByGenre to get a story idea.

      Returns string[]

      Array of genre names (e.g. ['fantasy', 'sci-fi', 'mystery'])

    • Returns models available for story generation, as configured in common/config/story_models.json.

      Returns Promise<ModelInfo[]>

      Array of model descriptors. Returns an empty array if the config file is missing.

    • Lists user-authored tools (with code). Empty when authoring is disabled.

      Returns Promise<ToolDefinition[]>

      Array of user-authored tool definitions

    • Returns metadata for all artifacts owned by this user.

      Artifacts are persistent named documents that can be attached to agents (see attachArtifactToAgent) or shared with rooms via the 'publish' action. Use getUserArtifact to retrieve the actual content.

      Returns ArtifactMetadata[]

      Array of artifact metadata objects (ID, name, creation date, etc.)

    • Pauses message processing in a room.

      Pending messages remain in the queue. Call resumeRoom to continue processing.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<void>

      If the room does not exist

    • Sends a text prompt to an agent and returns its response.

      The exchange is added to the agent's conversation history and persisted to disk.

      Parameters

      Returns Promise<ProcessTextResponse>

      Object containing the agent's reply text (result), the latest formatted message, its index in the history, and cumulative token counts and cost

      If no agent with the given ID exists

      const result = await appService.processText(agent.id, 'What is the capital of France?');
      console.log(result.result); // 'Paris'
      console.log(result.totalCost); // e.g. 0.000023
    • Advances the story to the next chapter.

      Creates a checkpoint of the current chapter state and rebuilds the opening scene. The story is immediately playable when this Promise resolves - the 'ready' progress event fires just before the function returns, so awaiting this call is sufficient; there is no need to separately wait for the event.

      After the function returns, a background job recreates the plot plan and character profiles for the new chapter ('profiles' --> 'complete'). Agent conversation histories are not compacted here - each agent compacts independently on demand when it individually reaches the compaction threshold (see compactStory for manual compaction).

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<{ chapterIndex: number }>

      Object with the new chapterIndex

    • Whether a prompt folder reference reaches a folder that exists.

      The check every "build an agent from a folder" path makes before it builds one: a reference that reaches nothing does not fail, it falls back to the shared root prompts and produces a generic conversational agent. A bare name for a pack this user has not enabled counts as not existing, because that is how it will behave.

      Parameters

      • folderName: string

        Prompt folder name, bare or pack:folder

      Returns boolean

      True when the folder exists, or names the prompts root

    • Creates a publicly accessible clone of a template agent.

      The new instance is independent of the template's conversation history. Multiple instances can be created from a single template. Use resetPublishedInstance to restore an instance to the template's current state.

      Parameters

      • templateId: string

        ID of the template agent to clone

      • instanceName: string

        Display name for the new instance

      Returns Promise<{ instanceId: string; publicUrl: string }>

      Object with the new instanceId and the publicUrl path

      If the template agent does not exist

    • Programmatically publishes an artifact to a room.

      This is the imperative equivalent of an agent sending a 'publish' action message. Agents in the room can read and reference the artifact in subsequent prompts.

      Parameters

      • roomId: string

        The room's ID

      • name: string

        Artifact name (unique within the room)

      • creator: string

        Display name of the creator

      • body: string

        The artifact's text content

      • viewers: string[] = []

        Agent names that can view this artifact (empty array = all agents)

      Returns Promise<void>

      If the room does not exist

      If name is empty

    • Creates a publicly accessible clone of a template room.

      The instance is a full copy of the template including all agents. Use resetPublishedRoomInstance to restore it to the template's state.

      Parameters

      • templateId: string

        ID of the template room to clone

      • publishedName: string

        Display name for the instance (defaults to the template's name)

      • userId: string

        The owning user's ID (used for public access mapping)

      Returns Promise<string>

      The new instance's room ID

      If the template room does not exist

    • Records a new payment transaction.

      Call this when your payment provider confirms a payment has been initiated. The paymentId should be the unique identifier issued by your payment provider (e.g. a Stripe Payment Intent ID). Use updateTransactionStatus to update the status once the provider confirms success or failure.

      Parameters

      • amount: number

        Dollar amount of the transaction

      • paymentId: string

        Unique payment identifier from your payment provider

      • status: "pending" | "succeeded" | "failed" | "cancelled" = 'pending'

        Initial status; defaults to 'pending'

      Returns Promise<Transaction>

      The created Transaction record

    • Clears an agent's conversation history while preserving its configuration and re-attaching any previously uploaded files.

      Useful for starting a fresh conversation without recreating the agent. If the history begins with a summary block (from a prior compaction), only messages after the summary are cleared.

      Parameters

      • agentId: string

        The agent's ID

      Returns Promise<void>

      If no agent with the given ID exists

    • Removes an agent from a room, and deletes it if the room owns it.

      Parameters

      • roomId: string

        The room's ID

      • agentId: string

        The agent's ID

      Returns Promise<void>

      If the room does not exist, or the agent is not in it

      If the room is a published instance

      If removing the moderator would leave an agent that sends MODERATE messages with nothing to route them

    • Changes the display name of an artifact.

      Parameters

      • artifactId: string

        The artifact's ID (from listUserArtifacts)

      • newName: string

        New display name for the artifact

      Returns boolean

      true on success, false if no artifact with that ID exists

    • Resets a published agent instance to its template's current state.

      Clears the instance's conversation history and regenerates it from the template agent. Does not affect the template itself.

      Parameters

      • instanceId: string

        ID of the published instance to reset

      Returns Promise<void>

      If the instance does not exist

      If the agent is not a published instance

    • Resets a published room instance to a clean state.

      Clears the instance's messages and artifacts, and resets all of its cloned agents to their template state. Does not affect the template room.

      Parameters

      • instanceId: string

        ID of the published room instance to reset

      Returns Promise<void>

      If the instance does not exist

      If the room is not a published instance

    • Clears a room's message history and artifacts, and resets all member agents.

      Agent configurations (model, prompt, files) are preserved; only conversation history and artifacts are removed.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<void>

      If the room does not exist

    • Resets a story to the beginning while preserving artifacts and the opening scene.

      If a chapter 1 backup exists, agents are restored from it; otherwise their conversation histories are cleared. The list of declined characters is also cleared.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<void>

      If the story or its room does not exist

    • Submits the human player's response to the story.

      Adds the content as a player message and triggers the AI characters to continue the narrative.

      Pass the literal string 'PASS' (case-insensitive) to skip the player's turn and let the AI characters continue without player input.

      Parameters

      • storyId: string

        The story's ID

      • content: string

        The player's message or action, or 'PASS' to skip the turn

      Returns Promise<void>

    • Resumes any stories that were paused due to insufficient balance.

      Call this after adding balance via addBalance to allow stories that stalled mid-processing to continue from where they left off.

      Returns Promise<number>

      The number of stories that were resumed

    • Resumes message processing in a room that was previously paused.

      Parameters

      • roomId: string

        The room's ID

      Returns Promise<void>

      If the room does not exist

    • Reverts the most recent chapter progression for a story. Restores room messages, artifacts, and agent histories from the previous chapter backup, then deletes that backup. Only valid when the current chapter has not been played past the opening scene.

      Parameters

      • storyId: string

        The story's ID

      Returns Promise<void>

      If the story or its room does not exist

      If revert is not currently valid

    • Executes a named Handlebars prompt template against an agent.

      The template is loaded from the agent's prompt folder (with the standard 4-level fallback). variables are substituted into the template before sending.

      Parameters

      • agentId: string

        The agent's ID

      • promptName: string

        Template name returned by listPrompts (without extension)

      • variables: any = {}

        Key-value pairs substituted into the template's {{variable}} placeholders

      Returns Promise<PreparedPromptResponse>

      Object with a result string containing the agent's response

      If no agent with the given ID exists

    • Overwrites the content of a chapter checkpoint.

      Parameters

      • storyId: string

        The story's ID

      • chapterIndex: number

        The chapter number to overwrite

      • content: string

        The new chapter content

      Returns void

      If the chapter cannot be saved

    • Saves a character's profile markdown.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character's name

      • content: string

        Markdown content for the character profile

      Returns void

    • Saves a character's inventory markdown.

      Parameters

      • storyId: string

        The story's ID

      • characterName: string

        The character's name

      • content: string

        Markdown content for the character inventory

      Returns Promise<void>

    • Saves the story's plot plan.

      Persists the content as a room artifact via the publish mechanism.

      Parameters

      • storyId: string

        The story's ID

      • content: string

        The plot plan markdown to save

      Returns Promise<void>

    • Writes content to a prompt file in the user prompt directory.

      Always saves to the user directory - common prompt files are never overwritten. If the target folder does not exist it is created automatically. Passing 'shared' as folderName writes to the root user prompts directory.

      Special case: passing an empty content for a 'json' file deletes the file rather than writing an empty document.

      Parameters

      • folderName: string

        Prompt folder name, or 'shared' for the root user prompts directory

      • fileName: string

        Base name of the file (without extension)

      • content: string

        File content to write

      • fileType: string

        'prompt' (writes a .prompt file) or 'json' (writes a .json file)

      Returns void

    • Persists the user's preferences object to disk.

      The shape of preferences is application-defined. Pass any serializable object; it will be stored as JSON and returned verbatim by getUserPreferences.

      Parameters

      • preferences: any

        Serializable preferences object to store

      Returns void

    • Adds a message to a room's pending queue to be processed by the agents.

      Action values:

      • 'moderate' (default) - routes the message through the room's moderator (story rooms only)
      • 'speak' - all agents hear the message; targets (if provided) restricts which agents may respond
      • 'whisper' - only agents listed in targets hear the message
      • 'think' - inaudible; stays only in the sender's history, not shown to other agents
      • 'shout' - overrides all other conversations; all agents hear and respond
      • 'adjourn' - signals intent to halt the conversation; the room adjourns once every agent agrees

      Anything else is sent as 'speak'. To create an artifact use publishArtifact rather than this method.

      Parameters

      • roomId: string

        The room's ID

      • content: string

        The message text (or artifact body when action is 'publish')

      • sender: string

        Display name of the sender (e.g. 'User', 'System')

      • action: string = 'moderate'

        Message action type (default 'moderate')

      • targets: string[] = []

        Agent names to receive or respond to the message (behavior varies by action)

      • clearQueue: boolean = false

        If true, clears any pending messages before adding this one. Default false.

      • Optionalcontext: unknown

      Returns Promise<SendMessageResult>

      Whether the message was accepted. A human agent's message is rejected (accepted: false with a reason) when it is not the human's turn to speak.

      If the room does not exist

      // Broadcast a message that all agents can respond to
      await appService.sendRoomMessage(roomId, 'Hello everyone!', 'User', 'speak');

      // Whisper to a specific agent
      const result = await appService.sendRoomMessage(roomId, 'Just between us...', 'User', 'whisper', ['James']);
      if (!result.accepted) {
      console.log(result.reason); // e.g. "It is James's turn to speak"
      }
    • Supplies the service that builds agents and rooms from pack templates.

      Set after construction rather than injected: it drives this service, so it cannot also be one of its constructor arguments.

      Parameters

      Returns void

    • Sets which agent leads the room's conversation and persists the change.

      The room leader is given conversational authority in the default room prompts (other agents defer to it) and is consulted on adjournment.

      Parameters

      • roomId: string

        The room's ID

      • agentNickname: string

        Nickname of the member agent to make leader

      Returns Promise<void>

      If the room does not exist

    • Supplies the service that builds and reads campaigns.

      Set after construction for the same reason pack instantiation is: it drives this service, so it cannot also be one of its constructor arguments.

      Parameters

      • service: RpgService

      Returns void

    • Runs a tool with the given arguments for testing from the Tools page. Failures are returned in-band as { ok: false, error }.

      Parameters

      • name: string

        The tool's name

      • args: Record<string, any>

        Named arguments for the tool

      Returns Promise<ToolRunResult>

      The tool run result

    • Updates one or more properties of an existing agent and persists the changes.

      Only fields that are present in the updates object are changed; omitted fields are left as-is.

      Parameters

      • agentId: string

        The agent's ID

      • updates: UpdateAgentRequest

        Fields to update:

        • agentNickname - short display name
        • description - role or personality description
        • modelName - model identifier (e.g. 'claude-haiku-4-5')
        • reasoningEffort - 'low' | 'medium' | 'high' | null
        • isControlledByHuman - whether a human drives this agent's responses
        • maxOutputTokens - override the model's default output token limit
        • allowSearch - enable web search capability (provider must support it)
        • beginInstruction - prompt sent when the host app triggers a "Begin" action

      Returns Promise<void>

      If no agent with the given ID exists

    • Updates an existing user-authored tool.

      Parameters

      • name: string

        The tool's name

      • tool: ToolDefinition

        The updated tool definition

      Returns Promise<ToolDefinition>

      The saved tool definition

      If the tool does not exist

      If authoring is disabled

    • Updates the status of an existing transaction.

      Call this when your payment provider webhook confirms the final outcome of a payment.

      Parameters

      • paymentId: string

        The payment provider ID used when the transaction was recorded

      • status: "pending" | "succeeded" | "failed" | "cancelled"

        New status ('succeeded', 'failed', or 'cancelled')

      Returns Promise<void>

    • Replaces the content of an existing artifact.

      Parameters

      • artifactId: string

        The artifact's ID (from listUserArtifacts)

      • content: string

        New content to write

      Returns boolean

      true on success, false if no artifact with that ID exists