ollama:curl - chunhualiao/public-docs GitHub Wiki

ollama

Latest and greatest

#!/bin/bash
# Simple LLM client test: send JSON input to Ollama and print the response text only, collapsing lines
# Uses only the /api/chat endpoint (non-stream mode)
# example: bash tests/llm-client-basic.sh samples/llm-client-basic.input

set -e

INPUT_FILE="$1"
MODEL=$(jq -r .model "$INPUT_FILE")
PROMPT=$(jq -r .prompt "$INPUT_FILE")

# Use jq to safely construct the JSON payload, avoiding manual escaping
JSON_PAYLOAD=$(jq -n --arg model "$MODEL" --arg prompt "$PROMPT" \
  '{model: $model, messages: [{role: "user", content: $prompt}], stream: false}')

CURL_CMD="curl -s -X POST http://localhost:11434/api/chat -H \"Content-Type: application/json\" -d '$JSON_PAYLOAD'"

echo "==== LLMClient Basic Test ===="
echo "Model: $MODEL"
echo "Prompt:"
echo "-----------------------------"
echo "$PROMPT"
echo "-----------------------------"
echo "Curl command:"
echo "$CURL_CMD"

RAW_RESPONSE=$(eval "$CURL_CMD" 2>&1)
EXIT_CODE=$?

# Try to extract .message.content or .error from the JSON
RESPONSE=$(echo "$RAW_RESPONSE" | jq -r '.message.content // .error // empty' 2>/dev/null)

echo "Response:"
echo "-----------------------------"
if [ -n "$RESPONSE" ]; then
  echo "$RESPONSE"
else
  echo "$RAW_RESPONSE"
fi
if [ $EXIT_CODE -ne 0 ]; then
  echo "ERROR: curl command failed with exit code $EXIT_CODE"
fi
echo "============================="

Generate

curl http://localhost:11434/api/generate -d '{
  "model": "gemma3:27b",
  "prompt": "What is the capital of France?",
  "stream": false
}'

{"model":"gemma3:27b","created_at":"2025-08-28T23:25:20.616162533Z","response":"The capital of France is Paris. \n\nIt's also the country's most populous city! 🇫🇷\n\n\n\n","done":true,"done_reason":"stop","context":[105,2364,107,3689,563,506,5279,529,7001,236881,106,107,105,4368,107,818,5279,529,7001,563,5213,50429,84750,236743,108,1509,236789,236751,992,506,2891,236789,236751,1346,129093,3207,236888,236743,246598,242644,110],"total_duration":1055523618,"load_duration":95781290,"prompt_eval_count":16,"prompt_eval_duration":92355537,"eval_count":27,"eval_duration":866756758}

Chat

curl http://localhost:11434/api/chat -d '{
  "model": "gemma3:27b",
  "messages": [
    {
      "role": "user",
      "content": "What is the capital of France?"
    }
  ],
  "stream": false
}'

{"model":"gemma3:27b","created_at":"2025-08-28T23:29:21.260150245Z","message":{"role":"assistant","content":"The capital of France is Paris. \n\nIt's also the country's most populous city! 🇫🇷\n\n\n\n"},"done_reason":"stop","done":true,"total_duration":1001581583,"load_duration":98220358,"prompt_eval_count":16,"prompt_eval_duration":56346831,"eval_count":27,"eval_duration":846236455}

Multiple rounds

"messages": [
  {"role": "user", "content": "Hi, I have a question."},
  {"role": "assistant", "content": "Ask away!"},
  {"role": "user", "content": "What is the capital of France?"}
]

with system message

curl http://localhost:11434/api/chat -d '{
  "model": "llama3.1",
  "messages": [
    {
      "role": "system",
      "content": "You are a knowledgeable geography expert who provides concise and accurate answers about world capitals."
    },
    {
      "role": "user",
      "content": "What is the capital of Brazil?"
    }
  ],
  "stream": false
}'

combined together

"messages": [
  {"role": "system", "content": "You are a geography expert who provides concise and accurate answers about world capitals."},
  {"role": "user", "content": "What is the capital of Brazil?"},
  {"role": "assistant", "content": "The capital of Brazil is Brasília."},
  {"role": "user", "content": "And what about Japan?"}
]

extract content or error message

The command you provided is a Bash command that processes a JSON response (stored in the variable RAW_RESPONSE) using the jq command-line JSON processor to extract specific fields and store the result in the RESPONSE variable. Let's break it down step by step:

Command:

RESPONSE=$(echo "$RAW_RESPONSE" | jq -r '.message.content // .error // empty' 2>/dev/null)

Explanation:

  1. RESPONSE=$(...):

    • This assigns the output of the command inside $(...) to the Bash variable RESPONSE.
    • The $(...) syntax is command substitution, capturing the output of the enclosed command.
  2. echo "$RAW_RESPONSE" |:

    • The echo "$RAW_RESPONSE" command outputs the contents of the RAW_RESPONSE variable, which is presumed to contain a JSON string (e.g., the response from an API like Ollama’s /api/chat).
    • The | (pipe) sends this output to the jq command for processing.
  3. jq -r '.message.content // .error // empty':

    • jq is a tool for parsing and manipulating JSON data.
    • The -r flag tells jq to output raw text (without JSON string quotes) for the extracted value.
    • The expression .message.content // .error // empty is a jq filter that:
      • .message.content: Attempts to extract the content field from the message object in the JSON. For example, in an Ollama chat API response like {"message": {"role": "assistant", "content": "NO"}, "done": true}, this would extract "NO".
      • //: The alternative operator in jq. It tries the expression on the left, and if it fails (e.g., returns null or is undefined), it moves to the expression on the right.
      • .error: If .message.content is not found (e.g., in case of an error response like {"error": "invalid model"}), it attempts to extract the error field.
      • // empty: If both .message.content and .error are undefined or null, it returns an empty result (no output).
    • This ensures the command gracefully handles both successful responses (with .message.content) and error responses (with .error), avoiding errors if neither field exists.
  4. 2>/dev/null:

    • This redirects any error messages from jq (e.g., if the JSON is malformed or RAW_RESPONSE is empty) to /dev/null, suppressing them.
    • This prevents error output from cluttering the terminal, making the script more robust.

Purpose:

  • The command extracts the content of the message object from a successful API response or the error message from a failed API response.
  • It’s commonly used in scripts that process API responses (e.g., from Ollama’s /api/chat) to isolate the relevant output or error message for further use.
  • The use of // empty and 2>/dev/null ensures the script doesn’t fail if the JSON structure is unexpected or invalid.

Example Scenarios:

  1. Successful API Response:

    RAW_RESPONSE='{"model": "gemma3:27b", "message": {"role": "assistant", "content": "NO"}, "done": true}'
    RESPONSE=$(echo "$RAW_RESPONSE" | jq -r '.message.content // .error // empty' 2>/dev/null)
    echo "$RESPONSE"
    # Output: NO
    
    • Here, jq extracts .message.content, which is "NO".
  2. Error API Response:

    RAW_RESPONSE='{"error": "model not found"}'
    RESPONSE=$(echo "$RAW_RESPONSE" | jq -r '.message.content // .error // empty' 2>/dev/null)
    echo "$RESPONSE"
    # Output: model not found
    
    • Since .message.content is undefined, jq falls back to .error, extracting "model not found".
  3. Invalid or Empty JSON:

    RAW_RESPONSE=''
    RESPONSE=$(echo "$RAW_RESPONSE" | jq -r '.message.content // .error // empty' 2>/dev/null)
    echo "$RESPONSE"
    # Output: (nothing)
    
    • If RAW_RESPONSE is empty or invalid, jq returns empty, and errors are suppressed by 2>/dev/null, so RESPONSE is empty.

Notes:

  • Context: This command is likely part of a script processing responses from an API like Ollama’s chat API, where the JSON structure includes either a message.content field (for successful responses) or an error field (for failures).
  • Error Handling: The use of // empty and 2>/dev/null makes the command robust, preventing script failures due to missing fields or malformed JSON.
  • Alternative: If you want to handle errors differently (e.g., log them), you could remove 2>/dev/null and check RESPONSE for specific values.
  • Dependencies: Ensure jq is installed (sudo apt install jq on Debian/Ubuntu or brew install jq on macOS).

Let me know if you need help with scripting this further, integrating it with an Ollama API call, or handling specific edge cases!