@@ -206,7 +206,7 @@ def count_tokens(prompt):
206206 """fm's exact count (under 0.1 s), or None when it can't give one."""
207207 try:
208208 p = subprocess.run([FM, "count-tokens", "-q", "-i", prompt.instructions], input=prompt.text,
209− capture_output=True, text=True, timeout=10, env=fm_env())
209+ capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=10, env=fm_env())
210210 except (OSError, subprocess.TimeoutExpired):
211211 return None
212212 out = p.stdout.strip()
@@ -285,7 +285,7 @@ def _run_fm(prompt, schema, opts, extra):
285285 args = [FM, "respond", "--model", opts["model"], "--no-stream", *greedy, "--schema", schema, "-i", prompt.instructions, *extra]
286286 timeout_s = max(1.0, time_left(opts))
287287 try:
288− p = subprocess.run(args, input=prompt.text, capture_output=True, text=True, timeout=timeout_s, env=fm_env())
288+ p = subprocess.run(args, input=prompt.text, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=timeout_s, env=fm_env())
289289 except FileNotFoundError:
290290 raise Fail("MODEL_UNAVAILABLE", f"fm not found at {FM} — requires macOS 27")
291291 except subprocess.TimeoutExpired:
@@ -312,7 +312,7 @@ def op_ping(_payload, _opts):
312312 "fmMessage": f"fm not found at {FM} — requires macOS 27", "schemasOk": False, "organizeMode": organize_mode()}
313313 license_required = False
314314 try:
315− avail = subprocess.run([FM, "available", "--model", "system"], capture_output=True, text=True, timeout=15, env=fm_env())
315+ avail = subprocess.run([FM, "available", "--model", "system"], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15, env=fm_env())
316316 ok, msg = avail.returncode == 0, (avail.stdout + avail.stderr).strip()[:300]
317317 if not ok and license_needed(avail.returncode, avail.stdout + avail.stderr):
318318 license_required, msg = True, LICENSE_MESSAGE
@@ -499,7 +499,7 @@ def install_schemas():
499499 if "{%s}" % key not in args:
500500 continue
501501 try:
502− p = subprocess.run([FM, *sub_args], capture_output=True, text=True, timeout=30, env=fm_env())
502+ p = subprocess.run([FM, *sub_args], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30, env=fm_env())
503503 except (FileNotFoundError, subprocess.TimeoutExpired) as e:
504504 print(f" {name}: fm failed ({e})", file=sys.stderr)
505505 return "error"
@@ -511,7 +511,7 @@ def install_schemas():
511511 subs["{%s}" % key] = p.stdout.strip()
512512 args = [subs.get(a, a) for a in args]
513513 try:
514− p = subprocess.run([FM, *args], capture_output=True, text=True, timeout=30, env=fm_env())
514+ p = subprocess.run([FM, *args], capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=30, env=fm_env())
515515 except (FileNotFoundError, subprocess.TimeoutExpired) as e:
516516 print(f" {name}: fm failed ({e})", file=sys.stderr)
517517 return "error"