1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Harn provider capability matrix.
#
# One `[[provider.<name>]]` array entry per rule; first match wins per
# (provider, model). Place more specific `model_match` patterns before
# wildcards. `version_min = [major, minor]` narrows the match to a model
# ID whose `(major, minor)` version (parsed from the Anthropic / OpenAI
# naming schemes) is greater than or equal to the given tuple. Rules
# whose `version_min` is unparseable for the given model are skipped.
#
# `[provider_family]` declares the sibling providers that inherit rules
# from a canonical family when they have no rule of their own (OpenRouter
# et al. speak the same Responses API and forward `tool_search` /
# `defer_loading` unchanged — they fall through to `[[provider.openai]]`
# by default).
#
# Users override or extend this table per-project via
# `[[capabilities.provider.<name>]]` entries in `harn.toml`. Project
# overrides are checked before the built-in rules for the same provider
# name and are authoritative on overlap.
#
# Supported per-rule fields:
# model_match : glob pattern matched against the lowercased model ID.
# version_min : [major, minor] lower bound, provider-aware parse.
# native_tools : whether the model accepts native tool-call wire shape.
# defer_loading : whether `defer_loading: true` is honored on tool defs.
# tool_search : list of native tool-search variants, preferred first.
# Anthropic = ["bm25", "regex"];
# OpenAI = ["hosted", "client"].
# max_tools : cap on tool-definition count the provider will accept.
# Used by harn-lint to warn about oversized registries.
# prompt_caching : whether the provider honors cache_control blocks.
# thinking : whether extended / adaptive thinking is available.
# ---------- Anthropic (Claude) ------------------------------------------------
# Haiku 4.5+ supports server-side tool search.
[[]]
= "claude-haiku-*"
= [4, 5]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
# Opus 4.0+ supports tool search.
[[]]
= "claude-opus-*"
= [4, 0]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
# Sonnet 4.0+ supports tool search.
[[]]
= "claude-sonnet-*"
= [4, 0]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
# OpenRouter-style `anthropic/claude-...` prefixes.
[[]]
= "anthropic/claude-haiku-*"
= [4, 5]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
[[]]
= "anthropic/claude-opus-*"
= [4, 0]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
[[]]
= "anthropic/claude-sonnet-*"
= [4, 0]
= true
= true
= ["bm25", "regex"]
= 10000
= true
= true
# Catch-all for older Claude models — native tools + prompt caching +
# thinking, but no progressive tool disclosure.
[[]]
= "claude-*"
= true
= true
= true
# ---------- OpenAI family -----------------------------------------------------
#
# `provider.openai` rules are inherited by the sibling providers declared
# in `[provider_family]` below (OpenRouter, Together, Groq, DeepSeek,
# Fireworks, HuggingFace, local vLLM/SGLang). Siblings may still add their
# own `[[provider.<name>]]` rules and those win over the openai fallback.
# gpt-5.4+ exposes native `tool_search` on the Responses API.
[[]]
= "gpt-*"
= [5, 4]
= true
= true
= ["hosted", "client"]
# Legacy GPT: native tool calls only.
[[]]
= "gpt-*"
= true
# Reasoning family (o1, o3, o4, ...).
[[]]
= "o1*"
= true
[[]]
= "o3*"
= true
[[]]
= "o4*"
= true
# OpenRouter-style provider-prefixed IDs.
[[]]
= "openai/gpt-*"
= [5, 4]
= true
= true
= ["hosted", "client"]
[[]]
= "openai/gpt-*"
= true
# ---------- Local / Ollama ----------------------------------------------------
#
# Local providers don't advertise native tool_search or prompt caching.
# Native-tools coverage depends on the specific model; leave conservative
# (unset) at the default so users must opt in via a harn.toml override.
# ---------- Mock --------------------------------------------------------------
#
# Mock spoofs either Anthropic or OpenAI shape depending on the model ID.
# Handled specially in the loader (see `capabilities::lookup`): Claude-
# shape model strings route to the `anthropic` rule list first, otherwise
# fall through to the `openai` rule list.
# ---------- provider_family aliases ------------------------------------------
[]
= "openai"
= "openai"
= "openai"
= "openai"
= "openai"
= "openai"
= "openai"