Loading...
Loading...
MANDATORY recipe for every Caffeine build that calls an LLM, chatbot, GPT, or ChatGPT **on Caffeine Inference** (no user-pasted OpenAI key). The ONLY supported path is the `caffeineai-inference-client` mops package with `Config.fromEnv<system>()`, which hands the canister a ready-to-use authenticated config — the app never asks for, stores, or returns a key. Hand-rolling `ic.http_request` to `inference.caffeine.ai` (or `api.openai.com`) is a FORBIDDEN anti-pattern. Load this skill whenever the user, spec, or any prior task wants an LLM in a Caffeine app — and BEFORE writing any code that talks to an LLM host. Use `extension-openai` only when the spec explicitly requires a user- or admin-pasted `sk-...` key against `api.openai.com`.
npx skill4agent add caffeinelabs/skills extension-inference| User intent | Capability |
|---|---|
| Chat / summarise / classify with an LLM in a Caffeine app | |
Call | |
extension-openaisetApiKeycaffeineai-inference-clientmops.tomlmops add caffeineai-inference-client@0.1.0caffeineai-inference-client ≥ 0.1.0Config.fromEnv<system>()Configis_replicated = ?falsefromEnv<system>()shared<system>let config = fromEnvConfigConfigauthquerysharedis_replicated = ?falsefromEnv?truenullimport Inference "lib/inference";
actor {
public shared func chat(prompt : Text) : async Text {
await* Inference.runChat<system>(prompt);
};
};import { fromEnv } "mo:caffeineai-inference-client/Config";
import ChatApi "mo:caffeineai-inference-client/Apis/ChatApi";
import ChatCompletionRequest "mo:caffeineai-inference-client/Models/ChatCompletionRequest";
import ChatCompletionRequestMessageOneOf2 "mo:caffeineai-inference-client/Models/ChatCompletionRequestMessageOneOf2";
import Runtime "mo:core/Runtime";
module {
public func runChat<system>(prompt : Text) : async* Text {
let config = fromEnv<system>();
let userMessage = ChatCompletionRequestMessageOneOf2.JSON.init({
content = #string(prompt);
role = #user;
});
let req = ChatCompletionRequest.JSON.init({
messages = [#user(userMessage)];
model = "router";
});
let resp = await* ChatApi.createChatCompletion(config, req);
if (resp.choices.size() == 0) {
Runtime.trap("Inference returned no choices");
};
resp.choices[0].message.content
?? Runtime.trap("Inference returned no text content");
};
};model = "router""router""router"modelmodel = "router"modeltemperaturetop_pmax_completion_tokensChatApi.createChatCompletion(config, req) : async*await*let api = ChatApi(config); api.createChatCompletion(req) : asynccaffeineai-inference-client@0.1.0public-api-v0.1.0| Module | Entry point | Route |
|---|---|---|
| | |
| | |
import ChatApi "mo:caffeineai-inference-client/Apis/ChatApi";
import { fromEnv } "mo:caffeineai-inference-client/Config";ic.http_requestsk-...extension-openaidefaultConfig.cycles = 30_000_000_000{ fromEnv<system>() with cycles = 100_000_000_000 }stream = ?truestream = nullfromEnv<system>()shared<system>let config = fromEnvmodel = "router""gpt-4o-mini"#user(ChatCompletionRequestMessageOneOf2.JSON.init({ content = #string(prompt); role = #user }))JSON.initnullresp.choices[0].message.content?Textchoices.size()chat(prompt)