Lexic
DocumentationGet Started
OverviewAuthenticationQuery EndpointCollaborate EndpointPluginsKnowledge DocsDecision TreesCollaboration RoomsAPI KeysSandboxPlugin ExportMarketplaceSDK ReferenceSDK CollaborationLangChainAutoGPTTypeScript TypesErrors

Install SDK

npm i lexic-sdk
Lexic HDK

API Reference

The Lexic API enables you to integrate subject matter expert plugins into any AI agent. Every response is backed by source citations, decision-tree reasoning, and a hallucination guard. Multi-expert collaboration lets you pit domain experts against each other for adversarial reasoning.

Base URL

https://dawk-ps2.vercel.app

SDK Package

lexic-sdk

Two auth modes: Dashboard routes use Clerk JWT sessions. The /api/v1/query and /api/v1/collaborate endpoints use Bearer token API key auth for external agent integrations.


Authentication

The external API endpoints (/api/v1/query and /api/v1/collaborate) authenticate via API key sent as a Bearer token. Generate keys from the API Keys page in the dashboard.

http
Authorization: Bearer lx_a1b2c3d4e5f6...

All other /api/* endpoints (plugins, documents, trees, collaboration rooms, api-keys) require a Clerk session cookie — they are for the web dashboard, not for external agent calls.


POST

/api/v1/query

The core endpoint. Send a question and a plugin slug, and get back a cited, decision-tree-backed expert answer. Supports both JSON and SSE streaming responses, conversation context for multi-turn dialogues, and per-request query options.

Request Body

ParamTypeRequiredDescription
pluginstringRequiredSlug of the expert plugin to query (e.g. "structural-eng-v1")
querystringRequiredThe domain question to ask. Max 4,000 characters.
streambooleanOptionalSet to true to receive SSE streaming response. Also enabled by Accept: text/event-stream header.
contextarrayOptionalConversation history for multi-turn dialogues. Array of { role: "user" | "assistant", content: string } objects.

Example Request

bash
curl -X POST https://dawk-ps2.vercel.app/api/v1/query \
  -H "Authorization: Bearer lx_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "plugin": "structural-eng-v1",
    "query": "What is the minimum cover for a beam in severe exposure?"
  }'

Multi-Turn Conversation

bash
curl -X POST https://dawk-ps2.vercel.app/api/v1/query \
  -H "Authorization: Bearer lx_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "plugin": "structural-eng-v1",
    "query": "What about for a column instead?",
    "context": [
      { "role": "user", "content": "What is the minimum cover for a beam in severe exposure?" },
      { "role": "assistant", "content": "According to IS 456 Table 16, the minimum nominal cover for a beam in severe exposure is 45mm." }
    ]
  }'

Streaming Request

bash
curl -X POST https://dawk-ps2.vercel.app/api/v1/query \
  -H "Authorization: Bearer lx_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "plugin": "structural-eng-v1",
    "query": "What is the minimum cover for a beam in severe exposure?",
    "stream": true
  }'

JSON Response

json
{
  "answer": "According to IS 456 Table 16, the minimum nominal cover for a beam in severe exposure is 45mm. [Source 1]",
  "citations": [
    {
      "id": "chunk_abc123",
      "document": "IS-456-2000.pdf",
      "page": 34,
      "section": "Table 16 — Nominal Cover",
      "excerpt": "For severe exposure conditions, beams require 45mm minimum cover..."
    }
  ],
  "decisionPath": [
    { "step": 1, "node": "q1", "label": "Member Type", "value": "beam" },
    { "step": 2, "node": "q2", "label": "Exposure Class", "value": "severe" },
    { "step": 3, "node": "a1", "label": "Cover Recommendation", "result": "45mm nominal cover" }
  ],
  "confidence": "high",
  "pluginVersion": "1"
}

SSE Stream Events

When streaming is enabled, events are delivered as Server-Sent Events:

text
data: {"type":"status","status":"retrieving","message":"Found 5 relevant sources","sourceCount":5}

data: {"type":"delta","text":"According to "}

data: {"type":"delta","text":"IS 456 Table 16..."}

data: {"type":"done","answer":"...full answer...","citations":[...],"decisionPath":[...],"confidence":"high","pluginVersion":"1"}

Response Fields

FieldTypeDescription
answerstringThe expert answer with inline [Source N] citations
citationsCitation[]Array of source references with document, page, section, and excerpt
decisionPathDecisionStep[]Steps the decision tree walked to reach the answer
confidence"high" | "medium" | "low"Hallucination guard score. Low = answer was refused/replaced.
pluginVersionstringPlugin version at time of query (for audit trails)

Error Responses

401Missing or invalid API key
400Missing plugin or query, or query exceeds 4,000 chars
404Plugin not found or access denied (not published and not owned by key holder)

POST

/api/v1/collaborate

Multi-expert adversarial reasoning. Send a query to multiple expert plugins simultaneously — they deliberate across rounds, critique each other, and an AI moderator synthesizes a final consensus. Supports three modes: debate (multi-round adversarial), consensus (single round + synthesis), and review (one leads, others critique).

Request Body

ParamTypeRequiredDescription
expertsstring[]RequiredArray of 2–5 plugin slugs (e.g. ["structural-eng-v1", "geotech-v1"])
querystringRequiredThe domain question. Max 4,000 characters.
modestringOptional"debate" (default), "consensus", or "review". Controls deliberation strategy.
maxRoundsnumberOptionalMax deliberation rounds (1–3). Default: 3.
streambooleanOptionalSet to true for SSE streaming. Also enabled by Accept: text/event-stream header.

Example Request

bash
curl -X POST https://dawk-ps2.vercel.app/api/v1/collaborate \
  -H "Authorization: Bearer lx_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "experts": ["structural-eng-v1", "geotech-v1"],
    "query": "What foundation type is best for a 5-story building on expansive clay soil?",
    "mode": "debate",
    "maxRounds": 2
  }'

JSON Response

json
{
  "rounds": [
    {
      "roundNumber": 1,
      "responses": [
        {
          "pluginSlug": "structural-eng-v1",
          "pluginName": "Structural Engineering Expert",
          "domain": "Structural Engineering",
          "answer": "For a 5-story building on expansive clay...",
          "citations": [...],
          "confidence": "high",
          "revised": false
        },
        {
          "pluginSlug": "geotech-v1",
          "pluginName": "Geotechnical Expert",
          "domain": "Geotechnical Engineering",
          "answer": "Expansive clay soils require...",
          "citations": [...],
          "confidence": "high",
          "revised": false
        }
      ]
    }
  ],
  "consensus": {
    "answer": "Both experts agree that a mat/raft foundation is recommended...",
    "confidence": "high",
    "agreementLevel": 0.85,
    "citations": [...],
    "conflicts": [
      {
        "topic": "Pile depth requirements",
        "positions": [
          { "expert": "structural-eng-v1", "stance": "Minimum 15m driven piles" },
          { "expert": "geotech-v1", "stance": "12m bored piles sufficient" }
        ],
        "resolved": true,
        "resolution": "Bored piles at 12-15m depth recommended pending soil investigation"
      }
    ],
    "expertContributions": [
      { "expert": "structural-eng-v1", "domain": "Structural Engineering", "keyPoints": ["Load analysis", "Foundation sizing"] },
      { "expert": "geotech-v1", "domain": "Geotechnical Engineering", "keyPoints": ["Soil bearing capacity", "Settlement analysis"] }
    ]
  },
  "latencyMs": 12450
}

SSE Stream Events

Streaming delivers real-time progress through the deliberation:

text
data: {"type":"status","status":"resolving","message":"Resolving expert plugins..."}

data: {"type":"experts_resolved","experts":[{"slug":"structural-eng-v1","name":"Structural Engineering Expert","domain":"Structural Engineering","sourceCount":42,"hasDecisionTree":true},{"slug":"geotech-v1",...}]}

data: {"type":"round_start","round":1,"totalRounds":2}

data: {"type":"expert_thinking","expert":"structural-eng-v1","expertName":"Structural Engineering Expert","domain":"Structural Engineering","message":"Analyzing with 42 sources..."}

data: {"type":"expert_response","round":1,"expert":"structural-eng-v1","expertName":"Structural Engineering Expert","domain":"Structural Engineering","answer":"...","citations":[...],"confidence":"high","revised":false}

data: {"type":"round_complete","round":1}

data: {"type":"done","rounds":[...],"consensus":{...},"latencyMs":12450}

Collaboration Modes

debate

Multi-round adversarial. Each expert independently answers, then in subsequent rounds they see all prior responses and can revise their positions. An AI moderator synthesizes the final consensus.

consensus

Single round only. All experts answer independently, then the moderator synthesizes a consensus without further deliberation.

review

One expert leads with a full answer, the remaining experts critique and suggest revisions. Best for getting peer review on a primary expert's analysis.

Error Responses

401Missing or invalid API key
400Fewer than 2 experts, more than 5 experts, invalid mode, or query exceeds 4,000 chars
404One or more expert plugins not found or access denied

Plugins

CRUD endpoints for managing expert plugins. All require Clerk session auth (dashboard use only).

GET/api/plugins

List all plugins owned by the authenticated user, ordered by creation date (newest first).

Response

Array of plugin objects with all fields (id, name, slug, domain, description, systemPrompt, citationMode, version, isPublished, config, createdAt, updatedAt).

POST/api/plugins

Create a new expert plugin. A unique slug is auto-generated from the name.

Request Body

namestringRequiredDisplay name of the plugin
domainstringRequiredDomain/field of expertise (e.g. "Structural Engineering")
systemPromptstringRequiredExpert persona prompt for the LLM
descriptionstringOptionalOptional description of the plugin
citationModestringOptional"mandatory" (default) or "optional"
json
{
  "name": "Structural Engineering Expert",
  "domain": "Structural Engineering",
  "systemPrompt": "You are an expert structural engineer specializing in IS 456 code compliance...",
  "description": "Expert on IS 456 concrete design standards",
  "citationMode": "mandatory"
}
GET/api/plugins/:id

Get a single plugin by UUID, including its related knowledge documents and decision trees. Must be the plugin owner.

PUT/api/plugins/:id

Update a plugin. Supports partial updates — only send the fields you want to change.

Updatable Fields

namestringOptionalNew display name
descriptionstringOptionalNew description
domainstringOptionalNew domain
systemPromptstringOptionalNew system prompt
citationModestringOptional"mandatory" or "optional"
isPublishedbooleanOptionalPublish/unpublish the plugin
DELETE/api/plugins/:id

Delete a plugin and all associated data (documents, chunks, decision trees) via cascade. Must be the plugin owner.


Knowledge Documents

Upload reference documents to a plugin's knowledge base. Documents are automatically chunked and embedded for vector similarity search.

GET/api/plugins/:id/documents

List all knowledge documents for a plugin. Requires ownership.

POST/api/plugins/:id/documents

Upload a document. Accepts multipart/form-data. The document is chunked, embedded with OpenAI text-embedding-3-small (1536 dimensions), and stored for pgvector retrieval.

Form Fields

fileFileOptionalA PDF, markdown, or text file to upload
textstringOptionalAlternatively, send raw text content directly
fileNamestringOptionalOverride the file name (defaults to uploaded file name)
fileTypestringOptionalDocument type: "pdf", "markdown", etc. (defaults to "markdown")

Either file or text must be provided.

Response (201)

json
{
  "id": "doc_uuid",
  "pluginId": "plugin_uuid",
  "fileName": "IS-456-2000.pdf",
  "fileType": "pdf",
  "rawText": "...",
  "metadata": null,
  "createdAt": "2026-02-28T...",
  "chunksCreated": 42
}
DELETE/api/plugins/:id/documents?docId=...

Delete a document and all its chunks (cascade). Requires docId query param.


Decision Trees

Decision trees add structured reasoning on top of RAG retrieval. Define condition/question/action nodes as JSON, and the engine walks the tree during each query. The decision path is included in every query response, giving full auditability of the reasoning chain.

GET/api/plugins/:id/trees

List all decision trees for a plugin. Returns an array of tree objects with id, name, description, treeData, isActive, and createdAt.

POST/api/plugins/:id/trees

Create a new decision tree for the plugin.

Request Body

namestringRequiredName of the decision tree
treeDataobjectRequiredJSON decision graph (see structure below)
descriptionstringOptionalOptional description

Tree Data Structure

json
{
  "rootNodeId": "q1",
  "nodes": {
    "q1": {
      "type": "question",
      "label": "Member Type",
      "question": { "text": "What type of member?", "options": ["beam", "column", "slab"], "extractFrom": "member_type" },
      "childrenByAnswer": { "beam": "q2", "column": "q3", "slab": "a3" }
    },
    "q2": {
      "type": "condition",
      "label": "Check Exposure",
      "condition": { "field": "exposure", "operator": "eq", "value": "severe" },
      "trueChildId": "a2",
      "falseChildId": "a1"
    },
    "a1": {
      "type": "action",
      "label": "Cover Recommendation",
      "action": { "recommendation": "20mm nominal cover", "severity": "info" }
    },
    "a2": {
      "type": "action",
      "label": "Cover Recommendation",
      "action": { "recommendation": "45mm nominal cover", "severity": "warning" }
    }
  }
}

Node Types

condition

Evaluates a field with an operator (eq, gt, lt, contains, in). Branches to trueChildId or falseChildId.

question

Extracts an answer from the query parameters. Routes to the matching child in childrenByAnswer.

action

Terminal node. Returns a recommendation with optional severity and sourceHint. Ends the tree walk.

GET/api/plugins/:id/trees/:treeId

Get a single decision tree by ID. Returns the full tree object including treeData.

PUT/api/plugins/:id/trees/:treeId

Update a decision tree. Supports partial updates.

Updatable Fields

namestringOptionalNew tree name
descriptionstringOptionalNew description
treeDataobjectOptionalUpdated decision graph JSON
isActivebooleanOptionalActivate/deactivate the tree
DELETE/api/plugins/:id/trees/:treeId

Delete a decision tree permanently.


Collaboration Rooms

Persistent rooms for multi-expert collaboration sessions. Create a room with a set of experts, then run multiple queries against it. Sessions are stored with full round history and consensus results. All endpoints require Clerk session auth.

GET/api/collaboration-rooms

List all collaboration rooms owned by the authenticated user. Returns rooms with session counts and resolved expert names.

Response

json
[
  {
    "id": "room_uuid",
    "name": "Foundation Design Panel",
    "mode": "debate",
    "expertSlugs": ["structural-eng-v1", "geotech-v1"],
    "maxRounds": 3,
    "createdAt": "2026-02-28T...",
    "updatedAt": "2026-02-28T...",
    "sessionCount": 5,
    "expertNames": ["Structural Engineering Expert", "Geotechnical Expert"]
  }
]
POST/api/collaboration-rooms

Create a new collaboration room.

Request Body

namestringRequiredRoom display name
expertSlugsstring[]RequiredArray of 2–5 expert plugin slugs
modestringOptional"debate" (default), "consensus", or "review"
maxRoundsnumberOptionalMax deliberation rounds (1–3). Default: 3.

Response (201)

json
{
  "id": "room_uuid",
  "creatorId": "user_uuid",
  "name": "Foundation Design Panel",
  "mode": "debate",
  "expertSlugs": ["structural-eng-v1", "geotech-v1"],
  "maxRounds": 3,
  "createdAt": "2026-02-28T...",
  "updatedAt": "2026-02-28T..."
}
GET/api/collaboration-rooms/:id

Get a room with its expert details (slug, name, domain) and all collaboration sessions ordered by most recent.

DELETE/api/collaboration-rooms/:id

Delete a collaboration room and all its sessions (cascade).

POST/api/collaboration-rooms/sandbox

Run a collaboration query inside a room. Creates a new session, runs the multi-expert deliberation, and streams results as SSE. The session is persisted with rounds, consensus, and latency.

Request Body

roomIdstringRequiredUUID of the collaboration room
querystringRequiredThe question to ask the expert panel

Response

SSE stream with the same event types as /api/v1/collaborate — status, experts_resolved, round_start, expert_thinking, expert_response, round_complete, done.


API Keys

Manage API keys for authenticating external agent calls. Keys are prefixed with lx_ and stored as salted hashes. All endpoints require Clerk session auth.

GET/api/api-keys

List all API keys for the authenticated user. Returns id, name, key prefix (first 8 chars), last used timestamp, and created timestamp. Never returns the full key.

POST/api/api-keys

Generate a new API key. The full key is returned only once in the response — store it securely.

Request Body

namestringRequiredA label for this key (e.g. "production", "my-agent")

Response (201)

json
{
  "key": "lx_a1b2c3d4e5f6g7h8i9j0...",
  "prefix": "lx_a1b2c",
  "name": "production"
}
PATCH/api/api-keys

Decrypt and reveal the full API key (requires ownership). Body: { "id": "key_uuid" }

DELETE/api/api-keys?id=...

Delete an API key. Detaches it from query logs before removal. Requires id query param.


Sandbox

Test your plugin's query pipeline without publishing. Uses Clerk session auth — available from the dashboard only.

POST/api/sandbox/:pluginId

Run a test query against an unpublished (or published) plugin you own. Same pipeline as the production query endpoint, but bypasses the publish check. Returns SSE stream.

Request Body

querystringRequiredThe question to test

Response

SSE stream with the same event types as /api/v1/query — status, delta, done, error.


Plugin Export

Export a plugin as a JSON file containing the full plugin definition, all knowledge documents (with raw text), and all decision trees.

GET/api/plugins/:id/export

Download a complete plugin export as a JSON file attachment. Requires Clerk session auth and plugin ownership.

Response Headers

http
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment; filename="structural-eng-v1.json"

Response Body

json
{
  "version": 1,
  "exportedAt": "2026-02-28T...",
  "plugin": {
    "id": "uuid",
    "name": "Structural Engineering Expert",
    "slug": "structural-eng-v1",
    "description": "...",
    "domain": "Structural Engineering",
    "systemPrompt": "...",
    "citationMode": "mandatory",
    "isPublished": true,
    "config": {},
    "createdAt": "...",
    "updatedAt": "..."
  },
  "documents": [
    {
      "id": "doc_uuid",
      "fileName": "IS-456-2000.pdf",
      "fileType": "pdf",
      "rawText": "...",
      "metadata": {},
      "createdAt": "..."
    }
  ],
  "decisionTrees": [
    {
      "id": "tree_uuid",
      "name": "Cover Determination",
      "description": "...",
      "treeData": { "rootNodeId": "q1", "nodes": {...} },
      "isActive": true,
      "createdAt": "..."
    }
  ]
}

Marketplace

Download shared plugins from the marketplace. Plugins must be published and have config.marketplaceShared set to true to be downloadable.

GET/api/marketplace/:slug/download

Download a marketplace-shared plugin as a JSON file. Requires Clerk session auth. Returns the same structure as plugin export, plus a source: "marketplace" field and the creator's display name.

Response (200)

json
{
  "version": 1,
  "exportedAt": "2026-02-28T...",
  "source": "marketplace",
  "plugin": {
    "id": "uuid",
    "name": "Structural Engineering Expert",
    "slug": "structural-eng-v1",
    "creator": "John Doe",
    ...
  },
  "documents": [...],
  "decisionTrees": [...]
}

SDK Reference

The TypeScript SDK wraps the REST API with type-safe methods, streaming support, conversation context, timeout handling, and framework adapters.

Installation

bash
npm install lexic-sdk

Quick Start

typescript
import { Lexic } from "lexic-sdk";

const lexic = new Lexic({
  apiKey: "lx_your_api_key",
  defaultPlugin: "structural-eng-v1",
});

const result = await lexic.query({
  query: "Minimum cover for a beam in severe exposure?",
});

console.log(result.answer);       // Cited expert answer
console.log(result.citations);    // Source references
console.log(result.confidence);   // "high" | "medium" | "low"
console.log(result.decisionPath); // Decision tree steps

Constructor: new Lexic(config)

ParamTypeRequiredDescription
apiKeystringRequiredYour Lexic API key (starts with lx_)
baseUrlstringOptionalOverride the API base URL. Default: "https://dawk-ps2.vercel.app"
defaultPluginstringOptionalDefault plugin slug for all queries
timeoutnumberOptionalRequest timeout in ms. Default: 30000

Methods

query(options): Promise<QueryResult>

Send a question to an expert plugin. Returns a full result with answer, citations, decision path, and confidence.

options.pluginstringOptionalPlugin slug (overrides activePlugin for this call)
options.querystringRequiredThe domain question
options.contextarrayOptionalConversation history: [{ role: "user" | "assistant", content: string }]
options.optionsQueryRequestOptionsOptionalPer-request options (see below)
queryStream(options): AsyncGenerator<StreamEvent>

Stream a query response as an async generator. Yields status, delta (text chunks), and done events. Same options as query().

typescript
for await (const event of lexic.queryStream({ query: "..." })) {
  if (event.type === "delta") process.stdout.write(event.text);
  if (event.type === "done") console.log("\nConfidence:", event.confidence);
}
queryStreamToResult(options, onEvent?): Promise<QueryResult>

Streams a query but collects the final result as a QueryResult. Pass an optional onEvent callback to handle intermediate events (deltas, status updates).

typescript
const result = await lexic.queryStreamToResult(
  { query: "..." },
  (event) => {
    if (event.type === "delta") process.stdout.write(event.text);
  },
);
console.log(result.citations);
setActivePlugin(slug): void

Hot-swap the active plugin. All subsequent query() calls will use this plugin unless overridden.

getActivePlugin(): string | null

Returns the currently active plugin slug, or null if none is set.

Query Request Options

ParamTypeDescription
citationMode"inline" | "footnote" | "off"How citations appear in the answer text
maxSourcesnumberMaximum number of knowledge chunks to retrieve
includeDecisionPathbooleanWhether to include the decision tree path in the response

Hot-Swap Example

typescript
const lexic = new Lexic({ apiKey: "lx_..." });

// Query the structural engineering expert
lexic.setActivePlugin("structural-eng-v1");
const structResult = await lexic.query({
  query: "Max allowable deflection for a cantilever?",
});

// Instantly switch to a different domain expert
lexic.setActivePlugin("electrical-code-v2");
const elecResult = await lexic.query({
  query: "Wire sizing for a 30A circuit?",
});

Multi-Turn Conversation

typescript
const result1 = await lexic.query({
  query: "What is the minimum cover for a beam in severe exposure?",
});

const result2 = await lexic.query({
  query: "What about for a column instead?",
  context: [
    { role: "user", content: "What is the minimum cover for a beam in severe exposure?" },
    { role: "assistant", content: result1.answer },
  ],
});

Error Handling

typescript
import { Lexic, LexicAPIError } from "lexic-sdk";

try {
  const result = await lexic.query({ query: "..." });
} catch (err) {
  if (err instanceof LexicAPIError) {
    console.error(err.message); // "Plugin not found or access denied"
    console.error(err.status);  // 404
  }
}

SDK Collaboration

The SDK includes full support for multi-expert collaboration — the same adversarial reasoning available via the REST API, with typed methods and streaming.

Methods

collaborate(options): Promise<CollaborationResult>

Run a multi-expert collaboration. Returns full results with all rounds, expert responses, and consensus synthesis.

options.expertsstring[]RequiredArray of 2–5 expert plugin slugs
options.querystringRequiredThe domain question
options.modestringOptional"debate" (default), "consensus", or "review"
options.maxRoundsnumberOptionalMax deliberation rounds (1–3). Default: 3.
typescript
const result = await lexic.collaborate({
  experts: ["structural-eng-v1", "geotech-v1"],
  query: "Best foundation for a 5-story building on clay?",
  mode: "debate",
  maxRounds: 2,
});

console.log(result.consensus.answer);        // Synthesized answer
console.log(result.consensus.agreementLevel); // 0.0–1.0
console.log(result.consensus.conflicts);     // Disagreements
console.log(result.rounds);                  // Full deliberation history
console.log(result.latencyMs);               // Total time
collaborateStream(options): AsyncGenerator<CollaborationStreamEvent>

Stream a collaboration as an async generator. Yields real-time events as experts deliberate.

typescript
for await (const event of lexic.collaborateStream({
  experts: ["structural-eng-v1", "geotech-v1"],
  query: "Best foundation for a 5-story building on clay?",
})) {
  switch (event.type) {
    case "experts_resolved":
      console.log("Experts:", event.experts.map(e => e.name));
      break;
    case "expert_thinking":
      console.log(`${event.expertName} is analyzing...`);
      break;
    case "expert_response":
      console.log(`${event.expertName} (Round ${event.round}):`, event.answer);
      break;
    case "done":
      console.log("Consensus:", event.consensus.answer);
      break;
  }
}
collaborateStreamToResult(options, onEvent?): Promise<CollaborationResult>

Streams a collaboration but collects the final result. Pass an optional onEvent callback for intermediate events.

typescript
const result = await lexic.collaborateStreamToResult(
  {
    experts: ["structural-eng-v1", "geotech-v1"],
    query: "Best foundation for a 5-story building on clay?",
  },
  (event) => {
    if (event.type === "expert_thinking") {
      console.log(`${event.expertName}: ${event.message}`);
    }
  },
);
console.log(result.consensus);

LangChain Adapter

Drop Lexic into any LangChain agent as a tool. Zero-dependency wrapper — doesn't require langchain as a peer dependency. Includes both single-expert and multi-expert collaboration tools.

Installation

bash
npm install lexic-sdk

Single-Expert Tool

typescript
import { LexicTool } from "lexic-sdk/langchain";

const tool = new LexicTool({
  apiKey: "lx_your_api_key",
  plugin: "structural-eng-v1",
  name: "structural_expert",
  description: "Consult a structural engineering expert",
  queryOptions: {
    citationMode: "inline",
    maxSources: 5,
    includeDecisionPath: true,
  },
});

// Add to any LangChain agent
const agent = createOpenAIToolsAgent({ llm, tools: [tool], prompt });

// Hot-swap to a different expert
tool.setPlugin("electrical-code-v2");

Constructor: new LexicTool(config)

ParamTypeRequiredDescription
apiKeystringRequiredLexic API key
pluginstringRequiredPlugin slug to query
baseUrlstringOptionalOverride API base URL
namestringOptionalLangChain tool name. Default: "lexic_{slug}"
descriptionstringOptionalLangChain tool description shown to the LLM
queryOptionsQueryRequestOptionsOptionalDefault query options (citationMode, maxSources, includeDecisionPath)

Methods

call(input: string): Promise<string>

LangChain Tool interface. Takes the agent's string input, queries the plugin, and returns a JSON string with answer, citations, confidence, and decision path.

setPlugin(slug: string): void

Hot-swap which plugin this tool queries.

Multi-Expert Collaboration Tool

typescript
import { LexicCollaborationTool } from "lexic-sdk/langchain";

const collabTool = new LexicCollaborationTool({
  apiKey: "lx_your_api_key",
  experts: ["structural-eng-v1", "geotech-v1"],
  name: "expert_panel",
  description: "Consult multiple domain experts for adversarial analysis",
  mode: "debate",
  maxRounds: 2,
  onEvent: (event) => {
    if (event.type === "expert_thinking") {
      console.log(`${event.expertName}: ${event.message}`);
    }
  },
});

// Add to LangChain agent alongside single-expert tools
const agent = createOpenAIToolsAgent({
  llm,
  tools: [tool, collabTool],
  prompt,
});

// Dynamically change experts or mode
collabTool.setExperts(["structural-eng-v1", "fire-safety-v1"]);
collabTool.setMode("consensus");

Constructor: new LexicCollaborationTool(config)

ParamTypeRequiredDescription
apiKeystringRequiredLexic API key
expertsstring[]RequiredArray of 2–5 expert plugin slugs
baseUrlstringOptionalOverride API base URL
namestringOptionalLangChain tool name. Default: "lexic_collaboration"
descriptionstringOptionalTool description for the LLM agent
modeCollaborationModeOptional"debate" (default), "consensus", or "review"
maxRoundsnumberOptionalMax deliberation rounds (1–3). Default: 3.
onEventfunctionOptionalCallback for streaming events during collaboration

Collaboration Tool Methods

call(input: string): Promise<string>

LangChain Tool interface. Returns JSON with consensus answer, conflicts, expert contributions, and agreement level.

setExperts(slugs: string[]): void

Change the panel of experts at runtime.

setMode(mode: CollaborationMode): void

Switch between debate, consensus, and review modes.


AutoGPT Adapter

Register Lexic as an AutoGPT command with typed parameters and execution. Includes both single-expert and multi-expert collaboration adapters.

Single-Expert Usage

typescript
import { LexicAutoGPT } from "lexic-sdk/autogpt";

const adapter = new LexicAutoGPT({
  apiKey: "lx_your_api_key",
  plugin: "structural-eng-v1",
  commandName: "consult_structural_expert",
  commandDescription: "Ask the structural expert",
  queryOptions: {
    citationMode: "inline",
    maxSources: 5,
    includeDecisionPath: true,
  },
});

// Register as an AutoGPT command
const command = adapter.asCommand();
// command.name, command.description, command.parameters, command.execute

// Or execute directly
const answer = await adapter.execute(
  "What is the minimum reinforcement ratio for a slab?"
);

Constructor: new LexicAutoGPT(config)

ParamTypeRequiredDescription
apiKeystringRequiredLexic API key
pluginstringRequiredPlugin slug to query
baseUrlstringOptionalOverride API base URL
commandNamestringOptionalAutoGPT command name. Default: "consult_{slug}"
commandDescriptionstringOptionalCommand description for the agent
queryOptionsQueryRequestOptionsOptionalDefault query options (citationMode, maxSources, includeDecisionPath)

Methods

asCommand(): AutoGPTCommand

Returns an object with name, description, parameters, and execute — ready to register with AutoGPT.

execute(query: string): Promise<string>

Execute a query directly. Returns a human-readable string with the answer, citations, and decision path.

setPlugin(slug: string): void

Hot-swap which plugin this adapter queries.

Multi-Expert Collaboration

typescript
import { LexicCollaborationAutoGPT } from "lexic-sdk/autogpt";

const collabAdapter = new LexicCollaborationAutoGPT({
  apiKey: "lx_your_api_key",
  experts: ["structural-eng-v1", "geotech-v1"],
  commandName: "consult_expert_panel",
  commandDescription: "Ask multiple domain experts to debate and reach consensus",
  mode: "debate",
  maxRounds: 2,
  onEvent: (event) => {
    if (event.type === "expert_thinking") {
      console.log(`${event.expertName}: ${event.message}`);
    }
  },
});

// Register as AutoGPT command
const command = collabAdapter.asCommand();

// Or execute directly
const answer = await collabAdapter.execute(
  "Best foundation for a 5-story building on clay?"
);

// Change experts or mode at runtime
collabAdapter.setExperts(["structural-eng-v1", "fire-safety-v1"]);
collabAdapter.setMode("consensus");

Constructor: new LexicCollaborationAutoGPT(config)

ParamTypeRequiredDescription
apiKeystringRequiredLexic API key
expertsstring[]RequiredArray of 2–5 expert plugin slugs
baseUrlstringOptionalOverride API base URL
commandNamestringOptionalCommand name. Default: "consult_expert_panel"
commandDescriptionstringOptionalCommand description for the agent
modeCollaborationModeOptional"debate" (default), "consensus", or "review"
maxRoundsnumberOptionalMax deliberation rounds (1–3). Default: 3.
onEventfunctionOptionalCallback for streaming events during collaboration

Collaboration Methods

asCommand(): AutoGPTCommand

Returns an AutoGPT command for the expert panel. Input is the query string.

execute(query: string): Promise<string>

Execute collaboration directly. Returns human-readable text with consensus, conflicts, and per-expert contributions.

setExperts(slugs: string[]): void

Change the expert panel at runtime.

setMode(mode: CollaborationMode): void

Switch between debate, consensus, and review modes.


TypeScript Types

All types are exported from lexic-sdk. Import them directly for type-safe integrations.

Configuration

typescript
interface LexicConfig {
  apiKey: string;
  baseUrl?: string;
  defaultPlugin?: string;
  timeout?: number;
}

interface QueryRequestOptions {
  citationMode?: "inline" | "footnote" | "off";
  maxSources?: number;
  includeDecisionPath?: boolean;
}

interface QueryOptions {
  plugin?: string;
  query: string;
  context?: Array<{ role: "user" | "assistant"; content: string }>;
  options?: QueryRequestOptions;
}

Query Response

typescript
interface QueryResult {
  answer: string;
  citations: Citation[];
  decisionPath: DecisionStep[];
  confidence: "high" | "medium" | "low";
  pluginVersion: string;
}

interface Citation {
  id: string;
  document: string;
  page?: number;
  section?: string;
  excerpt: string;
}

interface DecisionStep {
  step: number;
  node: string;
  label: string;
  value?: string;
  result?: string;
}

interface LexicError {
  error: string;
  status?: number;
}

Stream Events

typescript
type StreamEvent =
  | { type: "status"; status: string; message: string; sourceCount?: number }
  | { type: "delta"; text: string }
  | { type: "done"; answer: string; citations: Citation[];
      decisionPath: DecisionStep[];
      confidence: "high" | "medium" | "low";
      pluginVersion: string }
  | { type: "error"; error: string };

Collaboration

typescript
type CollaborationMode = "debate" | "consensus" | "review";

interface CollaborateOptions {
  experts: string[];
  query: string;
  mode?: CollaborationMode;
  maxRounds?: number;
}

interface ExpertResponse {
  pluginSlug: string;
  pluginName: string;
  domain: string;
  answer: string;
  citations: Citation[];
  confidence: "high" | "medium" | "low";
  revised: boolean;
  revisionNote?: string;
}

interface CollaborationRound {
  roundNumber: number;
  responses: ExpertResponse[];
}

interface ConflictEntry {
  topic: string;
  positions: Array<{ expert: string; stance: string }>;
  resolved: boolean;
  resolution?: string;
}

interface ConsensusResult {
  answer: string;
  confidence: "high" | "medium" | "low";
  agreementLevel: number;
  citations: Citation[];
  conflicts: ConflictEntry[];
  expertContributions: Array<{
    expert: string;
    domain: string;
    keyPoints: string[];
  }>;
}

interface CollaborationResult {
  rounds: CollaborationRound[];
  consensus: ConsensusResult;
  latencyMs: number;
}

Collaboration Stream Events

typescript
type CollaborationStreamEvent =
  | { type: "status"; status: string; message: string }
  | { type: "experts_resolved"; experts: Array<{
      slug: string; name: string; domain: string;
      sourceCount: number; hasDecisionTree: boolean
    }> }
  | { type: "round_start"; round: number; totalRounds: number }
  | { type: "expert_thinking"; expert: string;
      expertName: string; domain: string; message: string }
  | { type: "expert_response"; round: number; expert: string;
      expertName: string; domain: string; answer: string;
      citations: Citation[];
      confidence: "high" | "medium" | "low"; revised: boolean }
  | { type: "round_complete"; round: number }
  | { type: "done"; rounds: CollaborationRound[];
      consensus: ConsensusResult; latencyMs: number }
  | { type: "error"; error: string };

Error Reference

All error responses follow the same shape. The SDK throws LexicAPIError with a status property.

json
{
  "error": "Human-readable error message"
}

Status Codes

CodeMeaningWhen
200OKSuccessful request
201CreatedResource successfully created (plugin, document, key, tree, room)
400Bad RequestMissing required fields, invalid JSON, query too long, <2 or >5 experts, invalid mode
401UnauthorizedMissing/invalid API key or Clerk session
403ForbiddenPlugin not published (for external query/collaborate endpoints)
404Not FoundPlugin, document, tree, room, or API key not found
408TimeoutSDK request exceeded timeout (default 30s)
500Server ErrorInternal error (LLM failure, database error, etc.)

Ready to integrate?

Create your first plugin and start querying in under 5 minutes.

Get StartedView SDK on GitHub
Lexic HDK v0.1.0 — Built for HackX 2026