NEWpromptev for Android and Chrome: your agents on your phone and in your browser. Get the apps→

Context Engine TypeScript SDK

The knowledge parts of @promptev/client: upload documents and search your knowledge base, from Node or anywhere fetch runs. For a guided walk through, start with the guide.

Overview

The Context Engine is hosted by promptev. The SDK reaches it with a project API key: ingestion with uploadDocument and retrieval with searchKnowledgeBase. Both return promises.

MethodWhat it doesReturns
uploadDocument(files, options?)Put one file, or up to 20, into the key’s project.Promise<{ results: UploadResult[] }>
searchKnowledgeBase(action, fields?, options?)Read the key’s project knowledge base.Promise<Record<string, any>>

Install

Package @promptev/client, version 1.3.0. It runs anywhere fetch, FormData and Blob exist.

Shell
npm install @promptev/client

PromptevClient

The key belongs to one project, so no call names a project. Create it under the project’s API keys in the promptev console. It is sent as Authorization: Bearer, never in a URL.

TypeScript
import { PromptevClient } from "@promptev/client";

const client = new PromptevClient({
  apiKey: process.env.PROMPTEV_API_KEY!, // fk_...
  timeout: 120_000,                      // ms; uploads wait until the files are ready
});
OptionTypeDefaultMeaning
apiKeystringrequiredThe project API key (fk_...), from the project’s API keys in the console. Keep it on your server.
baseUrlstringhttps://api.promptev.aiWhere the API is.
headersRecord<string, string>noneExtra HTTP headers on every request.
timeoutnumber30000Milliseconds to wait for the response. Raise it for large uploads.
maxRetriesnumber2Retries on a 502, 503 or 504.

uploadDocument(files, options?)

Put files into the key’s project knowledge base, in the same Uploads source the console writes to. The project’s agents can use them on their next turn.

TypeScript
import { readFile } from "node:fs/promises";

// Node: name the bytes
const { results } = await client.uploadDocument(
  { name: "handbook.pdf", content: await readFile("handbook.pdf") },
);

// Several files, and build the Context Graph too
const batch = await client.uploadDocument(
  [
    { name: "refunds.pdf", content: await readFile("refunds.pdf") },
    { name: "notes.md", content: "# Release notes\n..." },
  ],
  { mode: "graph" },
);
for (const r of batch.results) console.log(r.filename, r.status, r.error ?? "");

// Browser or edge: a File or Blob from an <input type="file"> works too
await client.uploadDocument(fileInput.files![0]);
  • A file is a File or Blob, or { name, content, type? } where content is a Blob, ArrayBuffer, typed array (a Node Buffer) or string. The name’s extension decides how the file is read.
  • Limits: up to 20 files per call, 25 MB each (MAX_FILES_PER_REQUEST, MAX_UPLOAD_BYTES). Larger sets belong in a connector source.
  • options.mode: "hybrid" or "graph". Graph also extracts entities and relationships into the Context Graph. Leave it out for the workspace’s default. options.signal aborts the upload.
  • One result per file, in order. A file that fails is reported in its own row and never fails the batch.
  • Same bytes, same document: uploading an identical file again updates it instead of adding a copy, so a retry is safe.

UploadResult

FieldTypeMeaning
filenamestringThe file’s name.
statusstringWhat became of it. "failed" when it did not land.
document_idstring | nullThe document’s id, or null when it did not land.
chunksnumberHow many passages it was split into.
unitsnumberThe ingestion units counted for this file.
errorstring | nullWhy this file failed, or null.

Actions

The graph actions (get_neighbors, traverse, find_related, community_summary) need documents uploaded in graph mode. discover says which actions the project can run.

ActionWhat you getFields
discoverEach document and what is inside it (a sheet’s columns, a document’s sections), the extracted fields, and which actions the project can run. Call it first.source_ids, document_ids, limit, cursor
searchPassages by meaning or keywords, as hits. For an ID, code or invoice number, search the bare identifier.query, top_k, mode, source_ids, document_ids
get_docOne whole document by id.document_id
get_docsSeveral whole documents at once.document_ids, max_chars
get_chunksOne long document in order, up to 25 passages at a time.document_id, start, end
listBrowse the documents without searching.source_ids, document_ids, limit, cursor
query_metaThe structured fields a question names (dates, amounts, parties) and each document’s value. Compare the values yourself.query, source_ids, limit
computeA figure from the spreadsheets (total, average, count, ranking, margin) or the exact row for one value, over every row. Ask in plain words.query, source_ids, document_ids
map_reduceThe same question asked of every document in scope, one answer per document.query, source_ids, document_ids
get_neighborsWhat is one step from a named thing in the Context Graph.entity, limit
traverseEverything within a few steps of a named thing. For how two things connect, traverse from one.entity, depth, category, limit
find_relatedConnections of one kind across the knowledge base, with no starting thing.category, label, entity_type, limit
community_summaryThe main themes and groups the knowledge base falls into.query, limit

Fields

FieldTypeMeaning
querystringWhat you are looking for, in words, or a bare identifier you are looking up.
top_knumberHow many passages a search returns. Default 10.
mode"hybrid" | "graph"How a search ranks. Leave it out and the right one is chosen. "graph" also uses how things connect.
document_idstringOne document’s id, from discover, list or a search hit. Not a number written inside a document.
document_idsstring[]Narrow to these documents.
source_idsstring[]Narrow to these sources (an upload folder, a connector).
limitnumberHow many rows: documents for discover and list (default 50), candidates for query_meta (20), links for the graph actions (50), groups for community_summary (3).
cursorstringThe next_cursor a previous page returned.
entitystringWhere a graph action starts: an entity id from an earlier graph answer (best), or a name as written in the documents.
depthnumberHow many steps traverse walks, 1 to 5. Default 2.
categorystringThe kind of connection to follow or find. discover lists the ones in your knowledge base.
labelstringThe exact relationship wording, for example reports_to. Narrower than category.
entity_typestringKeep only connections with this type of entity on one end.
startnumberFirst passage to read, from 0. A search hit’s chunk_idx reads around that passage.
endnumberLast passage to read, inclusive.
max_charsnumberHow much text get_docs returns before it stops and hands back the ids it did not reach.

What comes back

An object, the knowledge base’s answer as sent. A search returns hits, best first:

JSON
{
  "hits": [
    {
      "document_id": "…",
      "document_name": "refund-policy.pdf",
      "chunk_text": "Refunds are accepted within 30 days …",
      "score": 0.82,
      "source_id": "…",
      "chunk_idx": 4
    }
  ]
}

discover and list return documents (each with id, name, source_id and kind), count and has_more. When there is more, send next_cursor back as cursor:

TypeScript
let page = await client.searchKnowledgeBase("list", { limit: 50 });
for (;;) {
  for (const d of page.documents) console.log(d.name);
  if (!page.has_more) break;
  page = await client.searchKnowledgeBase("list", { limit: 50, cursor: page.next_cursor });
}

Follow the answer. An answer may carry a next_action or next_page: the next call, already filled in. Cite document_name when you show a passage.

Errors

Every error extends PromptevError with message, statusCode, responseText and, when known, field. A 502, 503 or 504 is retried (maxRetries) before ServerError is thrown.

ErrorStatusWhen
ValidationError422 (or 400)An unknown action or a field it does not take; no files, more than 20, a file over 25 MB, a type that is not accepted, or a mode other than "hybrid" or "graph". Some are caught before the request is sent. e.field names the field.
AuthenticationError401 (or 403)The key is missing, malformed, revoked or expired.
InsufficientCreditsError402The workspace has no credits left. A top-up fixes it, a retry does not.
NotFoundError404The key reaches no project.
RateLimitError429Too many requests. e.retryAfter says how many seconds to wait.
ServerError5xxThe server failed, after the retries.
NetworkErrornoneNo answer: DNS, connection, abort or the client timeout.
TypeScript
import {
  ValidationError, AuthenticationError, InsufficientCreditsError,
  NotFoundError, RateLimitError,
} from "@promptev/client";

try {
  await client.searchKnowledgeBase("search", { query: "how many days do customers have to ask for a refund" });
} catch (e) {
  if (e instanceof ValidationError) console.error("Fix the request:", e.message, e.field);
  else if (e instanceof InsufficientCreditsError) console.error("Out of credits: top up");
  else if (e instanceof RateLimitError) console.error("Retry in", e.retryAfter, "s");
  else throw e;
}

Credits and costs are on the guide.

1,000 free credits for a 30-day trial · No card required · No subscription1,000 free credits · 30-day trial · No card