Joshua a une API intégrée : vos scripts, un robot, un boîtier domotique ou toute appli qui fonctionne avec les serveurs « OpenAI-compatible » peuvent lui envoyer une question et recevoir une réponse. Chaque demande exécute Joshua complet, avec recherche web, outils et mémoire, sur votre ordinateur.
http://127.0.0.1:7861/v1.Joshua doit être en marche pour que l'API réponde. La clé est enregistrée dans ~/AskJoshua/joshua/api.json.
Dans le Terminal, listez les modèles que vous pouvez utiliser, puis posez une question. Remplacez YOUR-KEY par la clé du panneau.
curl http://127.0.0.1:7861/v1/models \ -H "Authorization: Bearer YOUR-KEY"
curl http://127.0.0.1:7861/v1/chat/completions \
-H "Authorization: Bearer YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "joshua",
"messages": [{"role": "user", "content": "What is the weather in Turin today?"}]
}'La réponse revient au format standard ; le texte est dans choices[0].message.content :
{
"id": "chatcmpl-5f2c9a01",
"object": "chat.completion",
"model": "qwen3-vl:8b-instruct",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "Oggi è domenica, 8 novembre 2026."},
"finish_reason": "stop"
}]
}Joshua peut chercher sur le web, lire des pages ou exécuter du code avant de répondre, donc une réponse peut prendre de quelques secondes à quelques minutes, selon la question et votre ordinateur.
Le plus simple est la bibliothèque officielle openai : pointez-la vers Joshua au lieu d'OpenAI.
# pip install openai
from openai import OpenAI
joshua = OpenAI(base_url="http://127.0.0.1:7861/v1", api_key="YOUR-KEY")
reply = joshua.chat.completions.create(
model="joshua",
messages=[{"role": "user", "content": "Summarise today's main news in Italy in three lines."}],
)
print(reply.choices[0].message.content)Ou avec la simple requests, par exemple sur un robot Raspberry Pi qui poursuit la conversation en renvoyant l'historique à chaque fois :
# pip install requests
import requests
URL = "http://192.168.1.20:7861/v1/chat/completions" # your computer's address on the home network
KEY = "YOUR-KEY"
def ask_joshua(text, history=()):
messages = [*history, {"role": "user", "content": text}]
r = requests.post(URL, headers={"Authorization": f"Bearer {KEY}"},
json={"model": "joshua", "messages": messages}, timeout=600)
r.raise_for_status()
return r.json()["choices"][0]["message"]["content"]
print(ask_joshua("Which washing programme for a shirt marked 40 °C, gentle?"))const reply = await fetch("http://127.0.0.1:7861/v1/chat/completions", {
method: "POST",
headers: { "Authorization": "Bearer YOUR-KEY", "Content-Type": "application/json" },
body: JSON.stringify({
model: "joshua",
messages: [{ role: "user", content: "Write a haiku about Turin in the fog." }],
}),
}).then(r => r.json());
console.log(reply.choices[0].message.content);Une page web d'un autre site ne peut pas appeler Joshua directement ; exécutez ceci dans Node ou dans votre appli.
Envoyez une photo comme URL data: dans le message. Avec un modèle qui voit les images (qwen3-vl le fait), Joshua la regarde directement ; sinon il utilise son outil d'images local.
import base64
from openai import OpenAI
joshua = OpenAI(base_url="http://127.0.0.1:7861/v1", api_key="YOUR-KEY")
photo = base64.b64encode(open("label.jpg", "rb").read()).decode()
reply = joshua.chat.completions.create(model="joshua", messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What does this care label say?"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{photo}"}},
],
}])
print(reply.choices[0].message.content)Vous pouvez donner à Joshua des instructions supplémentaires avec un message system : elles s'ajoutent après les siennes. Et vous pouvez lui demander de ne pas enregistrer l'échange comme discussion :
reply = joshua.chat.completions.create(
model="joshua",
messages=[
{"role": "system", "content": "You are the voice of a small robot. Answer in one short sentence, in Italian."},
{"role": "user", "content": "Che ore sono?"},
],
extra_body={"joshua_save": False}, # don't keep this exchange as a chat
)| Champ | Ce qu'il fait |
|---|---|
| model | joshua = votre modèle local par défaut. Ou n'importe quel nom de /v1/models, comme qwen3-vl:8b-instruct. Les modèles cloud (qui finissent par cloud) ne sont utilisés que si vous en nommez un. |
| messages | La conversation : messages system, user et assistant, du plus ancien au plus récent. Joshua ne garde rien entre deux demandes, donc envoyez l'historique dont il doit se souvenir. |
| stream | true fonctionne avec les clients qui attendent le streaming, mais la réponse arrive d'un bloc à la fin. |
| joshua_save | false = ne pas enregistrer cet échange comme discussion 🔌. Par défaut true. |
Par défaut, seuls les programmes du même ordinateur peuvent se connecter. Pour utiliser Joshua depuis un robot, un téléphone ou un autre ordinateur de la maison :
~/AskJoshua/stop.sh, puis rouvrez Joshua).http://192.168.1.20:7861/v1. Utilisez cette adresse sur l'autre appareil, avec la même clé.Gardez-le dans le réseau de la maison. N'ouvrez pas le port 7861 sur votre box : la clé protège Joshua, mais la connexion n'est pas chiffrée.
| Demande | Ce qu'il fait |
|---|---|
| GET /v1/models | Liste joshua et chaque modèle installé qui sait utiliser des outils. owned_by indique this computer ou cloud. |
| POST /v1/chat/completions | Exécute Joshua sur les messages et renvoie sa réponse, au format chat d'OpenAI. |
| Erreur | Signification |
|---|---|
| 401 | La clé manque ou est fausse. Envoyez Authorization: Bearer YOUR-KEY. |
| 400 | Quelque chose ne va pas dans la demande, par exemple un nom de modèle inconnu. Le message dit quoi. |
| connection refused | Joshua n'est pas en marche, ou (depuis un autre appareil) « Autoriser les autres appareils » est désactivé ou Joshua n'a pas été redémarré. |
Vous voulez seulement le modèle nu, sans les outils et la mémoire de Joshua ? Ollama a sa propre API sur http://127.0.0.1:11434, compatible OpenAI aussi sur /v1, sans clé.
joshua_save: false.