Call a tool from your app

Named AI tools, the kinds and providers, the files a tool takes, and model aliases.

Call a tool from your app

A tool file at gemmein/ai/tools/deep-research.json:

{
  "label": "Deep Research",
  "provider": "openai",
  "model": "gpt-4o",
  "credits": 20,
  "requires": "access:pro-max",
  "instructions": "You are a careful research assistant. Answer with sources.",
  "promptTemplate": "Research this for a {{audience}} reader:\n\n{{question}}",
  "inputs": [
    { "name": "question", "type": "text", "required": true, "maxLength": 2000 },
    { "name": "audience", "type": "text" }
  ],
  "bounds": { "maxOutputTokens": 4000 }
}

The app never sends a prompt or a provider request. It names the tool and passes the inputs the tool declares. Gemmein composes the request in the provider's own format, from the instructions and the template on the server. The answer comes back in the provider's own shape, so a streaming call streams:

const res = await g.ai.run("deep-research", { question: text, audience: "beginner" }, { stream: true })

for await (const chunk of res.body) render(chunk)   // the provider's SSE, byte for byte
res.headers.get("x-gemmein-credits-remaining")     // the balance after this call

What it is. A named AI operation, defined on the server, that you price in credits and restrict by access.

Does.

  • Composes the provider request from the tool's own instructions and template, with the inputs the app sent.
  • Runs it on your key with the pinned model, or the model alias the tool names, and the output cap.
  • Charges the tool's price, per call or per tokens (see Pricing).
  • Records every call on ai_calls (who, tool, tokens, units and unitCount, credits, outcome). It keeps the prompt and answer only when you switch that on for the tool.

Does not. Does not let the browser compose the request or see the prompt (raw calls are off unless the owner switches them on for a provider key); does not let the browser set a price, a model or the access it requires; does not run from a secret key; does not rename a tool after creation.

Needs something else when. You want a plan-dependent price for the same operation → make two tools, each with its own access requirement; you meter something that is not an AI call → spendCredits from your server; you need an image, audio, video or a transcript → a job tool and a run; you need embeddings → your server calls the provider directly.

Example. "Deep Research", openai, gpt-4o, 20 credits, requires access:pro-max, with instructions and a question input.

For a non-stream answer as one string, whichever provider answered, and for the person's own history:

const answer = await g.ai.runText("deep-research", { question: text })
const { calls } = await g.ai.calls()   // what they ran, when, what it cost, how it ended

g.ai.runText reads choices[0].message.content from OpenAI, joins content[].text from Anthropic, and joins candidates[0].content.parts[].text from Google.

A provider's non-2xx answer is returned as it came by g.ai.run, and is not thrown. g.ai.runText, like g.ai.text, throws it as provider_error with the provider's status and message. A refusal by Gemmein throws GemmeinError with one of the codes below. An unknown input, a missing required one, a wrong type or a value over its cap is refused by name before anything is spent (invalid_inputs).

What the person sees:

WhenMessage
They lack the access"Deep Research requires Pro Max."
They are short of the price"Deep Research costs 20 credits. You have 7."
They are short of a per-token tool's ceiling"Deep Research needs up to 12 credits. You have 7."
The ledger line after the call"20 credits spent · Deep Research · 87 remaining."

Tool kinds and providers

A tool is one of two kinds. A chat tool answers now. A job tool (generate or transcribe) answers with a run. A provider serves every kind its key sells:

KindAnswers withProviders
chat (the default)An answer nowopenai, anthropic, google, openai-compatible
generateA run: an image, a video or audio outopenai, google, replicate, fal, elevenlabs, runway, external
transcribeA run: audio in, text outopenai, google, deepgram, replicate, fal, assemblyai, elevenlabs, external

An OpenAI key makes chat, image, speech, transcription and video tools. A Google key makes chat, image, video and audio-transcription tools. external is your own pipeline.

When your own server makes the model call, or the call is neither chat nor a job (such as embeddings), call the provider directly with your key. Ask Gemmein's server methods in the SDK reference who the person is and what they hold. A chat model on any server that speaks the OpenAI Chat Completions format runs as provider openai-compatible (see Any OpenAI-compatible provider); a server that speaks another format runs as your own pipeline.

Files a tool takes

A tool says which kinds of file a person may hand it: image, audio, video and document. Each is a tick in the tool's file ("accepts": ["image", "document"]) and on the dashboard's AI page. A file input takes the ref of a file the person already uploaded, to any collection: g.ai.run("describe-photo", { photo: upload.ref }).

Gemmein checks the file's kind, the tool's model and the file's size before any credit moves, then hands the file to the provider. Most providers fetch a short-lived signed link made for that one call. Small files ride inline. Gemini files over 14 MB stream from storage into Gemini's own file store. A file is never sent as a public link, never converted, and never held whole in Gemmein's memory.

A tick is offered only where the tool's provider and model read that kind:

ProviderTakesModels
googleimage, audio, video, PDFGemini 1.5, 2.x and 3.x
openaiimage · audioimage: gpt-4o, gpt-4.1, gpt-5, o1, o3, o4-mini · audio: gpt-4o-audio models (mp3 or wav); transcription: whisper-1, gpt-4o-transcribe
anthropicimage · PDFimage: Claude 3 and later · PDF: Claude 3.5 Sonnet and later
assemblyai, deepgram, elevenlabsaudio, videotranscription models (ElevenLabs Scribe)
replicate, falimage, audio, videomodels that take a file link
runwayimageimage-to-video models
externalall fouryour own pipeline, by a short-lived signed link

npx gemmein dev and npx gemmein sync refuse a tick the model does not read and name the models that do. A file may be up to 500 MB of video, 100 MB of audio, or 25 MB of image or document, or the provider's own limit when lower. "inputMaxMb": { "video": 200 } in the tool's file sets a lower limit for one tool; the AI page has no size field. A tool that takes files is priced per run: a flat credit price per call, held and charged as that price whatever the file's size. A video input can cost more on your own provider key. A tool charged per token that ticks a kind is refused at gemmein dev, gemmein sync and on the AI page: "A tool that takes files is priced per run — set a credit price per call, and lower its file size limit if you want to cap your cost." Text-only tools keep per-token pricing. Files a person hands a tool count toward your app's storage; video fills it fastest, and you can add 50 GB storage packs under Usage. With ticks set, a file input takes only a Gemmein file ref, never a link. A tool created before ticks takes exactly the files it took before.

Create a tool

Create a tool on the dashboard's AI page, or have your AI write a file at gemmein/ai/tools/<name>.json. npx gemmein sync pushes it to Development. npx gemmein sync --live pushes it to your live app on its own approval: you approve the push in the browser, item by item, and anything different from what you approved is refused.

The file owns the implementation on every sync. After creation, the dashboard owns the commerce: label, credits, unit and per, access, on/off, record calls, and a transcribe tool's delete-after-run. Every field is in the field table.

A tool can be defined before its provider key exists. Runs are refused ai_not_configured until the key is added on the AI page, and the dashboard shows the tool as waiting on a key until then. A tool's name is fixed once created, because it is what the app calls.

Model aliases

What it is. A name of your own, such as fast or writer, that stands for one provider and one model. A tool names the alias in place of a model.

Does.

  • Resolves at call time to the alias's provider and model. Repointing the alias moves every tool on it, with no edit to any tool and no deploy.
  • Lives on the AI page or in gemmein/ai/aliases.json (one object of name → { provider, model }), and syncs with the tools.
  • Refuses at save a model the provider key's allowlist does not admit.
  • Keeps a tool and its alias on one provider.

Does not.

  • Span providers. An alias is on one provider, and a tool on another cannot name it.
  • Exist on external (your pipeline has no model).
  • Change a tool's price, access or inputs.
  • Sit beside a pinned model. A tool names a model or an alias, never both.
  • Stop an alias being removed while tools still name it. Such a tool answers 409 tool_incomplete until it is repointed.

Needs something else when.

  • You want a different model per plan → two tools, each with its own access requirement.
  • You want the app to choose the model → not offered; the model is the server's.
  • You want a model the allowlist lacks → add it to the provider key's models on the AI page first.

Example. fast → openai, gpt-4o-mini. "Quick answer" and "Summarise" both name fast. Move fast to gpt-4.1-mini on the AI page and both tools run on it from their next call.

Was this page helpful?

Last updated