{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "intro",
      "metadata": {},
      "source": "# Case B · two fresh local-model requests\n\n**Run All sends exactly two inference requests.** It does not launch the 1,250-request study. Both requests use the same explicit prompt and settings, with no conversation history carried between them. Rerunning either request cell sends one additional request and records a new response.\n\nSelect **Aner — notebook**, **Shared variables** and **Prod**. A compatible native runtime and a running local Ollama service with the exact selected model are required. This notebook does not install models or start the service. There are no saved answers, outputs or timings.\n\nA language-model answer is a recorded choice, not evidence of uniform random sampling. See [the project README](../README.md) for the full study and its provenance."
    },
    {
      "cell_type": "markdown",
      "id": "settings-notes",
      "metadata": {},
      "source": "## Shared settings\n\nCreating a client sends no inference request. Change the model name to one that is installed in your own local service. Both request cells read these settings. Restart and Run All after changing settings if you want a fresh, consistent paired record."
    },
    {
      "cell_type": "code",
      "id": "settings",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": "import aner.llm\n\nlet model_name = \"llama3.2:latest\"\nlet endpoint = \"http://127.0.0.1:11434\"\nlet prompt = \"Pick a number between 1 and 10. Return only the integer.\"\nlet max_tokens = 256\nlet temperature = 1.0\nlet model = llm.client(provider: \"ollama\", model: model_name,\n    endpoint: endpoint, timeout_ms: 120_000)\nprint(\"Configured model: \" + model_name + \"; no request sent by this cell\")\n"
    },
    {
      "cell_type": "markdown",
      "id": "request-one-notes",
      "metadata": {},
      "source": "## Request one\n\nThis cell makes one fresh generation request, then prints the unmodified visible text, exact UTF-8 hex, returned model, finish reason and token usage. The elapsed interval surrounds only the native generate call."
    },
    {
      "cell_type": "code",
      "id": "request-one",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": "let started_one = Duration.monotonic()\nlet answer_one = model.generate(prompt, max_tokens: max_tokens, temperature: temperature)\nlet elapsed_one_ns = Duration.monotonic().subtract(started_one).nanoseconds()\nprint(\"Request one: raw visible answer follows\")\nprint(answer_one.text())\nprint(\"text_hex=\" + Bytes.encode_utf8(text: answer_one.text()).hex())\nprint(\"returned_model=\" + answer_one.model())\nprint(\"finish_reason=\" + answer_one.finish_reason())\nprint(\"elapsed_ns=\" + String(elapsed_one_ns))\nprint(\"input_tokens=\" + String(answer_one.input_tokens()))\nprint(\"output_tokens=\" + String(answer_one.output_tokens()))\nprint(\"total_tokens=\" + String(answer_one.total_tokens()))\nprint(\"cached_input_tokens=\" + String(answer_one.cached_input_tokens()))\nprint(\"cache_write_input_tokens=\" + String(answer_one.cache_write_input_tokens()))\nprint(\"reasoning_tokens=\" + String(answer_one.reasoning_tokens()))\n"
    },
    {
      "cell_type": "markdown",
      "id": "request-two-notes",
      "metadata": {},
      "source": "## Request two\n\nThis is another fresh request with the same prompt. It does not append request one's text to a conversation. The service still controls inference scheduling and any internal caching."
    },
    {
      "cell_type": "code",
      "id": "request-two",
      "metadata": {},
      "execution_count": null,
      "outputs": [],
      "source": "let started_two = Duration.monotonic()\nlet answer_two = model.generate(prompt, max_tokens: max_tokens, temperature: temperature)\nlet elapsed_two_ns = Duration.monotonic().subtract(started_two).nanoseconds()\nprint(\"Request two: raw visible answer follows\")\nprint(answer_two.text())\nprint(\"text_hex=\" + Bytes.encode_utf8(text: answer_two.text()).hex())\nprint(\"returned_model=\" + answer_two.model())\nprint(\"finish_reason=\" + answer_two.finish_reason())\nprint(\"elapsed_ns=\" + String(elapsed_two_ns))\nprint(\"input_tokens=\" + String(answer_two.input_tokens()))\nprint(\"output_tokens=\" + String(answer_two.output_tokens()))\nprint(\"total_tokens=\" + String(answer_two.total_tokens()))\nprint(\"cached_input_tokens=\" + String(answer_two.cached_input_tokens()))\nprint(\"cache_write_input_tokens=\" + String(answer_two.cache_write_input_tokens()))\nprint(\"reasoning_tokens=\" + String(answer_two.reasoning_tokens()))\n"
    },
    {
      "cell_type": "markdown",
      "id": "interpretation",
      "metadata": {},
      "source": "## Preserve what the service returned\n\nUsage **-1 means unavailable** and differs from a reported zero. Cached-input, cache-write and reasoning token counts are already subsets of their normalized parent counts; do not add them again. A token budget is a limit, not the observed output-token count.\n\nPreserve refusals, extra text and truncated answers. The [full benchmark](../benchmarks/benchmark_llm.aner) accepts a choice only when the finish reason is exactly stop and the trimmed complete answer is exactly one of the integer strings 1 through 10. It does not extract a digit from prose or retry rejected responses. The raw trace remains available even for invalid choices.\n\nThe full study uses five requested model identifiers, five balanced model-order rounds and 50 requests per model per round. This notebook sends only its two explicit requests. Its answers and timings are new observations, separate from the published study."
    }
  ],
  "metadata": {
    "kernelspec": {
      "name": "aner",
      "display_name": "Aner",
      "language": "aner"
    },
    "language_info": {
      "name": "aner",
      "file_extension": ".aner",
      "mimetype": "text/x-aner"
    },
    "aner": {
      "execution_mode": "persistent-session",
      "runtime_mode": "production",
      "source_file": "../examples/case_B_llm.aner",
      "status": "live-source-only"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
