teapot-coding-agent 0.37.77 → 0.37.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent.js +74 -3
- package/dist/agent/llm.js +51 -5
- package/dist/agent/tool-catalog.js +210 -0
- package/dist/agent/tools.js +128 -4
- package/dist/config-schema.js +8 -0
- package/dist/master.js +3 -0
- package/dist/model-meta.js +84 -6
- package/package.json +1 -1
- package/public/assets/{index-Betlb5cN.js → index-CmaAIX0k.js} +9 -9
- package/public/assets/index-CmaAIX0k.js.map +1 -0
- package/public/assets/{shiki-nwPgnhe1.js → shiki-CWqNrHE6.js} +2 -2
- package/public/assets/{shiki-nwPgnhe1.js.map → shiki-CWqNrHE6.js.map} +1 -1
- package/public/index.html +1 -1
- package/public/assets/index-Betlb5cN.js.map +0 -1
package/dist/model-meta.js
CHANGED
|
@@ -173,13 +173,91 @@ export function metaFrom(m) {
|
|
|
173
173
|
...(m.reasoning === true ? { reasoning: true } : {}),
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
/**
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
/**
|
|
177
|
+
* The model list for a provider: the PROVIDER's own catalogue, enriched by models.dev.
|
|
178
|
+
*
|
|
179
|
+
* The provider is the authority on which models exist — models.dev lags and omits entries. MEASURED:
|
|
180
|
+
* `reflection/beam:free` is served by Command Code (94 models) and absent from models.dev's
|
|
181
|
+
* `commandcode` record (72), so a models.dev-only list silently drops models the operator can
|
|
182
|
+
* actually call.
|
|
183
|
+
*
|
|
184
|
+
* models.dev is still needed for CAPABILITY, because most providers publish none: Command Code's
|
|
185
|
+
* `/models` returns only `{context_length, created, id, name, object, owned_by, supported_endpoints}`
|
|
186
|
+
* while OpenRouter publishes `architecture` (modalities) and `supported_parameters`. So:
|
|
187
|
+
*
|
|
188
|
+
* - provider list wins for MEMBERSHIP;
|
|
189
|
+
* - a provider field, when present, wins for that field;
|
|
190
|
+
* - models.dev fills only what the provider did not say.
|
|
191
|
+
*
|
|
192
|
+
* When the provider cannot be reached at all we fall back to the models.dev list rather than showing
|
|
193
|
+
* nothing.
|
|
194
|
+
*/
|
|
195
|
+
export async function fetchModelList(baseUrl, apiKey) {
|
|
196
|
+
const [snap, upstream] = await Promise.all([
|
|
197
|
+
loadDb(),
|
|
198
|
+
fetchProviderModels(baseUrl, apiKey).catch(() => null),
|
|
199
|
+
]);
|
|
179
200
|
const provider = providerFor(snap.providers, baseUrl);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
201
|
+
const dbModels = provider?.models ? Object.values(provider.models).map(metaFrom).filter((m) => m.id) : [];
|
|
202
|
+
if (!upstream)
|
|
203
|
+
return dbModels;
|
|
204
|
+
const byId = new Map(dbModels.map((m) => [m.id, m]));
|
|
205
|
+
return upstream
|
|
206
|
+
.map((m) => mergeMeta(m, byId.get(m.id)))
|
|
207
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
208
|
+
}
|
|
209
|
+
/** a provider's own `/models`, normalised, or null when it does not answer usefully */
|
|
210
|
+
async function fetchProviderModels(baseUrl, apiKey) {
|
|
211
|
+
const url = `${String(baseUrl).replace(/\/+$/, "")}/models`;
|
|
212
|
+
const res = await fetch(url, {
|
|
213
|
+
headers: { ...(apiKey ? { authorization: `Bearer ${apiKey}` } : {}), ...providerHeaders(baseUrl) },
|
|
214
|
+
signal: AbortSignal.timeout(15_000),
|
|
215
|
+
});
|
|
216
|
+
if (!res.ok)
|
|
217
|
+
return null;
|
|
218
|
+
const j = (await res.json());
|
|
219
|
+
const out = [];
|
|
220
|
+
for (const m of j.data ?? []) {
|
|
221
|
+
if (typeof m.id !== "string" || !m.id)
|
|
222
|
+
continue;
|
|
223
|
+
const input = strings(m.architecture?.input_modalities);
|
|
224
|
+
const output = strings(m.architecture?.output_modalities);
|
|
225
|
+
const ctx = typeof m.context_length === "number" ? m.context_length : undefined;
|
|
226
|
+
// `reasoning` in supported_parameters means the model accepts a reasoning_effort-style control
|
|
227
|
+
const params = strings(m.supported_parameters);
|
|
228
|
+
out.push({
|
|
229
|
+
id: m.id,
|
|
230
|
+
...(typeof m.name === "string" ? { name: m.name } : {}),
|
|
231
|
+
...(ctx !== undefined ? { contextLength: ctx } : {}),
|
|
232
|
+
...(input ? { modalities: { input, output: output ?? ["text"] } } : {}),
|
|
233
|
+
...(params?.some((p) => p === "reasoning" || p === "reasoning_effort") ? { reasoning: true } : {}),
|
|
234
|
+
...(params ? { supportedParameters: params } : {}),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return out.length ? out : null;
|
|
238
|
+
}
|
|
239
|
+
/** provider fields win; models.dev fills only the gaps */
|
|
240
|
+
function mergeMeta(own, db) {
|
|
241
|
+
if (!db)
|
|
242
|
+
return own;
|
|
243
|
+
return {
|
|
244
|
+
id: own.id,
|
|
245
|
+
...(own.name ?? db.name ? { name: own.name ?? db.name } : {}),
|
|
246
|
+
...(own.contextLength ?? db.contextLength ? { contextLength: own.contextLength ?? db.contextLength } : {}),
|
|
247
|
+
...(own.modalities ?? db.modalities
|
|
248
|
+
? { modalities: own.modalities ?? db.modalities }
|
|
249
|
+
: {}),
|
|
250
|
+
/**
|
|
251
|
+
* Efforts come from models.dev even when the provider listed the model: no provider publishes the
|
|
252
|
+
* effort LEVELS, only that reasoning exists. `own.reasoning` still wins for the yes/no question.
|
|
253
|
+
*/
|
|
254
|
+
...(db.supportedEfforts ? { supportedEfforts: db.supportedEfforts } : {}),
|
|
255
|
+
...(own.supportedParameters ?? db.supportedParameters
|
|
256
|
+
? { supportedParameters: own.supportedParameters ?? db.supportedParameters }
|
|
257
|
+
: {}),
|
|
258
|
+
...(own.reasoning ?? db.reasoning ? { reasoning: own.reasoning ?? db.reasoning } : {}),
|
|
259
|
+
...(db.pricing ? { pricing: db.pricing } : {}),
|
|
260
|
+
};
|
|
183
261
|
}
|
|
184
262
|
export function peekModelList(baseUrl) {
|
|
185
263
|
if (!fresh(db))
|