65def _smoke_o1(base_url: str, model: str) -> tuple[bool, list[str]]:
66 """O1 — provider build, list_models, streamed turn, model_info, clean error."""
72 provider = OllamaProvider()
73 client = provider.build_client(api_key=
"", base_url=base_url)
74 ev.append(f
"O1a provider/client built — base_url={client.base_url!r}")
76 models = client.list_models()
77 has_model = model
in models
79 ev.append(f
"O1b list_models -> {len(models)} tags; {model!r} present: {has_model}")
81 chunks: list[str] = []
82 usage: dict[str, Any] = {}
83 for kind, data
in client.stream_chat(
84 [{
"role":
"user",
"content":
"Reply with exactly: smoke ok"}],
92 text =
"".join(chunks).strip()
93 streamed_ok = len(text) > 0
95 ev.append(f
"O1c streamed turn -> {len(text)} chars: {text[:60]!r}")
97 info = provider.model_info(model, client)
98 info_ok = info
is not None
101 ev.append(f
"O1d model_info -> family={info.family!r} params={info.parameter_count!r}")
103 ev.append(
"O1d model_info -> None (FAIL)")
105 dead = provider.build_client(api_key=
"", base_url=DEAD_URL)
108 ev.append(
"O1e clean-error path -> no error raised (FAIL)")
110 except RuntimeError
as exc:
111 friendly =
"unreachable" in str(exc).lower()
113 ev.append(f
"O1e unreachable host -> clean RuntimeError, friendly={friendly}: {str(exc)[:80]!r}")
114 except Exception
as exc:
115 ev.append(f
"O1e unreachable host -> non-clean {type(exc).__name__} (FAIL)")
119 _dbg(
"OC_CHAT.CLIENT", func, line, 3)
120 _dbg(
"OC_CHAT.CLIENT", func, f
"O1 ok={ok}", 2)
124def _smoke_o4(base_url: str, model: str) -> tuple[bool, list[str]]:
125 """O4 — generation options (top_k) reach the live /api/chat request body."""
132 provider = OllamaProvider()
133 extra_body = provider.translate_generation_options(GenerationOptions(top_k=10))
134 ev.append(f
"O4a translate_generation_options(top_k=10) -> {extra_body}")
136 captured: dict[str, Any] = {}
137 original_post = ollama_client._post
139 def _capturing_post(b_url: str, path: str, body: dict, timeout: int = 300) -> Any:
140 if path ==
"/api/chat":
141 captured.update(body)
142 return original_post(b_url, path, body, timeout)
144 ollama_client._post = _capturing_post
146 cli = provider.build_client(api_key=
"", base_url=base_url)
147 for _kind, _data
in cli.stream_chat(
148 [{
"role":
"user",
"content":
"hi"}], model,
149 extra_body=extra_body, max_tokens=8,
153 ollama_client._post = original_post
155 sent_top_k = (captured.get(
"options")
or {}).get(
"top_k")
156 ok = sent_top_k == 10
157 ev.append(f
"O4b live /api/chat body options={captured.get('options')!r} -> top_k={sent_top_k}")
159 _dbg(
"OC_CHAT.CLIENT", func, line, 3)
160 _dbg(
"OC_CHAT.CLIENT", func, f
"O4 ok={ok}", 2)
164def _smoke_o5(base_url: str, model: str) -> tuple[bool, list[str]]:
165 """O5 — PerformanceStats / tok-s footer from real generation timing."""
170 provider = OllamaProvider()
171 client = provider.build_client(api_key=
"", base_url=base_url)
173 usage: dict[str, Any] = {}
174 for kind, data
in client.stream_chat(
175 [{
"role":
"user",
"content":
"Count to five."}], model, max_tokens=64,
179 perf = provider.parse_performance(usage)
181 f
"O5a parse_performance -> eval_count={perf.eval_count} "
182 f
"eval_duration_ns={perf.eval_duration_ns} is_default={perf.is_default()}"
185 tps = perf.tokens_per_second
186 ok = (
not perf.is_default())
and tps
is not None and tps > 0
188 footer = f
"{perf.eval_count}tok@{tps:.1f}tok/s"
189 ev.append(f
"O5b tok/s footer -> {footer!r}")
191 ev.append(
"O5b tokens_per_second -> None (FAIL)")
193 _dbg(
"OC_CHAT.CLIENT", func, line, 3)
194 _dbg(
"OC_CHAT.CLIENT", func, f
"O5 ok={ok}", 2)
198def main(argv: list[str] |
None =
None) -> int:
199 """Run the O1/O4/O5 smokes; return 0 when all pass."""
201 parser = argparse.ArgumentParser(description=
"M0.11 Ollama live-smoke harness.")
202 parser.add_argument(
"--model", default=
"llama3.2:3b", help=
"Ollama model tag to smoke")
203 args = parser.parse_args(argv)
205 base_url = os.environ.get(
"OLLAMA_BASE_URL",
"http://localhost:11434")
206 print(f
"=== M0.11 Ollama live smoke — base_url={base_url} model={args.model} ===\n")
208 results: list[tuple[str, bool, list[str]]] = []
209 for name, fn
in ((
"O1", _smoke_o1), (
"O4", _smoke_o4), (
"O5", _smoke_o5)):
211 ok, ev = fn(base_url, args.model)
212 except Exception
as exc:
213 ok, ev =
False, [f
"{name} raised {type(exc).__name__}: {exc}"]
214 results.append((name, ok, ev))
215 print(f
"[{'PASS' if ok else 'FAIL'}] {name}")
220 all_ok = all(ok
for _name, ok, _ev
in results)
221 print(f
"=== {'ALL SMOKES PASS' if all_ok else 'SMOKE FAILURES PRESENT'} ===")
222 _dbg(
"OC_CHAT.CLIENT", func, f
"smoke complete all_ok={all_ok}", 2)
223 return 0
if all_ok
else 1