The OpenAI Assistants API is the easy onramp: an HTTP service holds the assistant, the thread, the run, and your tools. The price is lock-in. Your agent state lives in OpenAI's database, your tools are JSON Schema definitions you have to host yourself anyway, and the model list is just OpenAI. Digitorn keeps the assistant pattern and gives it back to you.
Two reasons. One, the Assistants API only runs on OpenAI models, so when DeepSeek ships a model that costs a tenth of GPT-5 you cannot use it without a rewrite. Two, your assistant config and your tool implementations live in two different places, the API and your server. Digitorn collapses both into a single YAML file you own.
Every OpenAI Assistants API primitive maps to a Digitorn equivalent. Where the mapping is not 1-to-1, the notes call out what changed.
Real apps in both stacks. The Digitorn version is what you would commit to a repo, no scaffolding hidden offscreen.
1import OpenAI from "openai";2const client = new OpenAI();34const assistant = await client.beta.assistants.create({5 name: "Support copilot",6 model: "gpt-4o-mini",7 instructions: "Answer using the docs. Cite the file.",8 tools: [9 { type: "file_search" },10 {11 type: "function",12 function: {13 name: "open_ticket",14 description: "Open a support ticket",15 parameters: {16 type: "object",17 properties: {18 subject: { type: "string" },19 severity: { type: "string", enum: ["low","high"] },20 },21 required: ["subject", "severity"],22 },23 },24 },25 ],26});2728// You still have to host /open_ticket on your server,29// poll runs, handle requires_action, and write file uploads.1app:2 app_id: support-copilot3 name: "Support copilot"45execution:6 mode: conversation78modules:9 rag:10 config:11 backend: { type: qdrant, path: ./kb }12 http: {} # for open_ticket call1314agents:15 - id: helper16 modules: [{rag: [search]}, {http: [post]}]17 brain:18 provider: openai19 model: gpt-4o-mini20 credential: openai_main21 system_prompt: |22 Answer using rag.search results. Cite the file.23 To open a ticket, http.post to {{env.TICKET_URL}}.Same assistant, no thread bookkeeping, no run polling, no separate function-host. The custom tool is just an http.post call configured by URL. Switching the model to claude-sonnet-4-6 or deepseek-chat is a one-line change.
Subtle differences that look the same on paper and break on first run. Read these before you start porting.
OpenAI's File Search hides the vector store. In Digitorn the rag module is local: you choose qdrant on disk or in-memory. Better control, but you back up the kb yourself.
The Assistants API uses run polling with requires_action handoffs. Digitorn streams every event as SSE, no polling logic to maintain.
Assistants accepts files via the API. Digitorn relies on filesystem.write or workspace.write, you upload through whichever channel fronts the agent.
# 1. install runtime
curl -sSL https://digitorn.ai/install | sh
# 2. copy the YAML above into a file
mkdir -p ~/.digitorn/apps/from-openai-assistants
# paste the YAML into app.yaml
# 3. deploy and chat
digitorn deploy from-openai-assistants
digitorn dev chat from-openai-assistantsEngineering notes from the Digitorn team. No marketing, no launch announcements, no "10 prompts that will change your life". Just the things we write that we'd want to read.