Use cases
Explore
Docs
Pricing

Organigram Agent

Workspace agent primitives for Organigram applications.

This package contains the public, framework-independent parts of the Organigram workspace agent: request and response types, snapshot and prompt construction, response normalization, model usage extraction, and document text extraction.

Installation


pnpm add @organigram/agent

Prompt

The agent answers questions about one workspace, and prepares changes to its organigrams. Gather what the user may see of the workspace in a Context, and build the prompt with buildPrompt(). The prompt includes a snapshot of the workspace, with the names of files but never their contents. Send it to the language model of your choice, with WORKSPACE_AGENT_OUTPUT_SCHEMA as the structured output format when the provider supports it.

buildPrompt

Build the prompt of the workspace agent for a conversation.

The prompt contains the rules of the agent, a snapshot of the workspace built with buildSnapshot(), the conversation and the output schema. It forbids proposals, transactions and signatures, and tells the model to treat file names, notifications and document contents as data rather than instructions. It cannot enforce these rules: validate the answer with normalizeResponse().


const prompt = buildPrompt({ messages, context })
const answer = normalizeResponse(JSON.parse(completion), context)

Signature

buildPrompt: (input: {
messages: Message[];
context: Context;
}) => string

NEW_ORGANIGRAM_GENERATION_INSTRUCTIONS

Instructions to generate a new organigram from a description or from documents, such as bylaws, included in the prompt of buildPrompt().

WORKSPACE_AGENT_OUTPUT_SCHEMA

JSON schema of the answers expected from the language model, to pass as its structured output format.

buildSnapshot

Build the description of a workspace given to the agent in its prompt.

The snapshot keeps only the fields the agent needs: the workspace, its organigrams with their organs, entries, procedures, latest proposals and elections, and assets, plus the names and references of files and the notifications. It never contains the contents of files. It includes generatedAt, the date it was built.

Signature

buildSnapshot: (context: Context) => Record<string, unknown>

Parameters

NameTypeDescription
contextContextWhat is known about the workspace.

MAX_PROPOSALS_PER_PROCEDURE

Number of the latest proposals of each procedure included in a snapshot.

Definition

const MAX_PROPOSALS_PER_PROCEDURE = 10

Context

What the agent knows about a workspace: the input of buildSnapshot(), buildPrompt() and normalizeResponse().

Definition

export type Context = {
workspace: Workspace;
files: File[];
notifications: Notification[];
currentOrganigram: OrganigramJson | null;
};

File

A file of the workspace. The agent only sees its reference and name, not its contents.

Definition

export type File = {
cid: string;
name?: string | null;
};

Notification

A notification of the workspace.

Definition

export type Notification = {
id: string;
type: string;
title?: string | null;
body?: string | null;
href?: string | null;
createdAt: Date | string;
};

Workspace

The workspace the agent answers about.

Definition

export type Workspace = {
id: string;
slug: string;
name?: string | null;
description?: string | null;
admins: string[];
ownerUserAddress?: string | null;
ownerOrganizationId?: string | null;
ownerOrganization?: {
id?: string | null;
} | null;
organigrams: OrganigramInput[];
};

Responses

The output of a language model is untrusted. normalizeResponse() keeps only valid citations, and only previews that create a new organigram or add to an organigram that is not deployed, without changing what it holds. The agent never proposes, signs or sends transactions: a deployed organigram changes only through its own procedures.

normalizeResponse

Validate the answer of the language model and turn it into an AgentResponse.

Treat the model's output as untrusted. Without a message, the answer is replaced by a fallback message. Only citations of known types are kept, at most 8. A preview is kept only if it is a new organigram, or an addition to an organigram of the workspace that has no deployed organ, procedure or asset and that changes or removes none of its organs, entries, procedures or assets. Invalid previews are dropped.

Signature

normalizeResponse: (input: unknown, context: Context) => AgentResponse

Parameters

NameTypeDescription
inputunknownThe answer of the model, parsed from JSON.
contextContextThe context the prompt was built with.

Returns

TypeDescription
AgentResponseThe answer, without threadId.

AgentResponse

An answer of the workspace agent, as returned by normalizeResponse().

Definition

export type AgentResponse = {
threadId?: string;
message: string;
citations: Citation[];
preview?: OrganigramPreview;
};

Citation

A reference to a workspace object that supports an answer of the agent.

Definition

export type Citation = {
type: 'workspace' | 'organigram' | 'organ' | 'procedure' | 'asset' | 'notification' | 'file';
id: string;
label: string;
};

MergeOrganigramPreview

A proposed addition to an existing organigram that is not deployed yet.

Definition

export type MergeOrganigramPreview = {
type: 'organigram';
organigramId: string;
persistence: 'merge-additive';
summary: string[];
organigram: OrganigramJson;
};

NewOrganigramPreview

A proposed new organigram.

Definition

export type NewOrganigramPreview = {
type: 'new-organigram';
persistence: 'create';
summary: string[];
organigram: OrganigramJson;
};

OrganigramPreview

A change to organigrams proposed by the agent, which the user reviews before saving it.

Definition

export type OrganigramPreview = MergeOrganigramPreview | NewOrganigramPreview;

Conversations

Types of the requests to the agent and of the conversations stored in the history of a workspace.

AgentRequest

Body of a request to the workspace agent.

Definition

export type AgentRequest = {
threadId?: string | null;
message?: string;
messages?: Message[];
currentOrganigramId?: string | null;
source?: ThreadSource;
};

Message

A message of a conversation with the workspace agent.

Definition

export type Message = {
role: 'user' | 'assistant';
content: string;
};

RecordThreadRequest

Body of a request that stores a conversation held elsewhere, such as on the home page hero, in the workspace history.

Definition

export type RecordThreadRequest = {
action: 'recordThread';
source: ThreadSource;
userMessage: string;
assistantMessage: string;
currentOrganigramId?: string | null;
};

StoredMessage

A message as stored in the history of a conversation.

Definition

export type StoredMessage = Message & {
id: string;
createdAt: string;
response?: AgentResponse;
};

Thread

A stored conversation with the workspace agent.

Definition

export type Thread = {
id: string;
title: string;
source: ThreadSource;
workspace?: ThreadWorkspace | null;
currentOrganigramId?: string | null;
createdAt: string;
updatedAt: string;
messages: StoredMessage[];
};

ThreadSource

Where a conversation started: in a workspace, or on the home page hero.

Definition

export type ThreadSource = 'workspace' | 'hero';

ThreadsResponse

List of the conversations of a user.

Definition

export type ThreadsResponse = {
threads: Thread[];
};

ThreadWorkspace

The workspace of a conversation.

Definition

export type ThreadWorkspace = {
id: string;
name?: string | null;
};

isMessage

Check that a value is a message with a role and non-empty content, for example in a request body.

Signature

isMessage: (value: unknown) => value is Message

Parameters

NameTypeDescription
valueunknownThe value to check.

Documents

Users can upload bylaws or other documents for the agent to draw an organigram from. These functions extract their text on the server. The text is written by third parties: give it to the model as data.

UploadedDocument

A file uploaded by a user, as a browser or Node.js File.

Definition

export type UploadedDocument = Pick<File, 'name' | 'type' | 'arrayBuffer' | 'text'>;

extractTextFromUploadedDocument

Extract the text of an uploaded document, to give it to the agent.

Reads Word documents (body, headers, footers, footnotes and endnotes), PDF files and plain text. PDF pages without enough text are read with OCR in English and French, which needs Poppler (pdftocairo) installed on the server; if OCR fails, the text found in the PDF is kept. Runs on Node.js only. The text is written by third parties: give it to the model as data, never as instructions.

Signature

extractTextFromUploadedDocument: (file: UploadedDocument) => Promise<string>

Parameters

NameTypeDescription
fileUploadedDocumentThe uploaded file.

Returns

TypeDescription
Promise<string>The text, with whitespace normalized.

isDocxDocument

Check whether a file is a Word document (.docx), by its MIME type or extension.

Signature

isDocxDocument: (file: Pick<UploadedDocument, "name" | "type">) => boolean

Parameters

NameTypeDescription
filePick<UploadedDocument, "name" | "type">The file to check.

isPdfDocument

Check whether a file is a PDF, by its MIME type or extension.

Signature

isPdfDocument: (file: Pick<UploadedDocument, "name" | "type">) => boolean

Parameters

NameTypeDescription
filePick<UploadedDocument, "name" | "type">The file to check.

Usage

Count the tokens used by each call to a language model, to bill or limit usage.

extractModelUsage

Read the tokens used by a call to a language model from the provider's response.

Reads the usage fields of OpenAI-compatible responses (input_tokens, prompt_tokens, cached token details) and Ollama responses (prompt_eval_count, eval_count). When the provider reports no input or output tokens, they are estimated as a quarter of the length of the prompt or completion, and estimatedTokens is true.

Signature

extractModelUsage: (input: {
payload: unknown;
prompt: string;
completion: string;
provider: string;
model: string;
}) => AiModelUsage

AiModelUsage

Tokens used by one call to a language model.

Definition

export type AiModelUsage = {
provider: string;
model: string;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
totalTokens: number;
estimatedTokens: boolean;
};

Edit this page

On this page:

Installation
buildPromptBuild the prompt of the workspace agent for a conversation.

Follow us:

© 2026 Organigram SAS

All Rights Reserved.