@otto-code/brain 0.8.3 → 0.8.4
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/config/schema.d.ts +12 -0
- package/dist/config/schema.js +1 -0
- package/dist/config/store.js +24 -2
- package/dist/models/enrich.js +1 -0
- package/dist/service/router.js +8 -2
- package/dist/types.d.ts +2 -0
- package/package.json +2 -2
package/dist/config/schema.d.ts
CHANGED
|
@@ -818,6 +818,7 @@ export declare const CatalogModelSchema: z.ZodObject<{
|
|
|
818
818
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
819
819
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
820
820
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
821
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
821
822
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
822
823
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
823
824
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -835,6 +836,7 @@ export declare const CatalogModelSchema: z.ZodObject<{
|
|
|
835
836
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
836
837
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
837
838
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
839
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
838
840
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
839
841
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
840
842
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -852,6 +854,7 @@ export declare const CatalogModelSchema: z.ZodObject<{
|
|
|
852
854
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
853
855
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
854
856
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
857
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
855
858
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
856
859
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
857
860
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -876,6 +879,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
876
879
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
877
880
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
878
881
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
882
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
879
883
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
880
884
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
881
885
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -893,6 +897,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
893
897
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
894
898
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
895
899
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
900
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
896
901
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
897
902
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
898
903
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -910,6 +915,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
910
915
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
911
916
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
912
917
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
918
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
913
919
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
914
920
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
915
921
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -933,6 +939,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
933
939
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
934
940
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
935
941
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
942
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
936
943
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
937
944
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
938
945
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -950,6 +957,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
950
957
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
951
958
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
952
959
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
960
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
953
961
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
954
962
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
955
963
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -967,6 +975,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
967
975
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
968
976
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
969
977
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
978
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
970
979
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
971
980
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
972
981
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -990,6 +999,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
990
999
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
991
1000
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
992
1001
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
1002
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
993
1003
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
994
1004
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
995
1005
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -1007,6 +1017,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
1007
1017
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
1008
1018
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
1009
1019
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
1020
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1010
1021
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
1011
1022
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1012
1023
|
tier: z.ZodOptional<z.ZodString>;
|
|
@@ -1024,6 +1035,7 @@ export declare const CatalogSchema: z.ZodObject<{
|
|
|
1024
1035
|
moe: z.ZodOptional<z.ZodBoolean>;
|
|
1025
1036
|
vision: z.ZodOptional<z.ZodBoolean>;
|
|
1026
1037
|
thinking: z.ZodOptional<z.ZodBoolean>;
|
|
1038
|
+
reasoningEfforts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1027
1039
|
contextMax: z.ZodOptional<z.ZodNumber>;
|
|
1028
1040
|
useCases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1029
1041
|
tier: z.ZodOptional<z.ZodString>;
|
package/dist/config/schema.js
CHANGED
|
@@ -172,6 +172,7 @@ export const CatalogModelSchema = z
|
|
|
172
172
|
moe: z.boolean().optional(),
|
|
173
173
|
vision: z.boolean().optional(),
|
|
174
174
|
thinking: z.boolean().optional(),
|
|
175
|
+
reasoningEfforts: z.array(z.string()).optional(),
|
|
175
176
|
contextMax: z.number().optional(),
|
|
176
177
|
useCases: z.array(z.string()).optional(),
|
|
177
178
|
tier: z.string().optional(),
|
package/dist/config/store.js
CHANGED
|
@@ -42,8 +42,30 @@ export function saveProfilesStore(store, paths = resolveBrainPaths()) {
|
|
|
42
42
|
// -------------------------------------------------------------------- catalog
|
|
43
43
|
export function loadCatalog(paths = resolveBrainPaths()) {
|
|
44
44
|
const current = readJson(paths.catalogFile, CatalogSchema);
|
|
45
|
-
if (current)
|
|
46
|
-
|
|
45
|
+
if (current) {
|
|
46
|
+
// The catalog is intentionally persisted so local Brain homes survive
|
|
47
|
+
// package updates, but additive metadata still needs to reach existing
|
|
48
|
+
// homes. Backfill only fields introduced by the seed catalog; user-owned
|
|
49
|
+
// catalog values remain authoritative.
|
|
50
|
+
const legacy = readJson(path.join(packageRoot(), "config", "downloads.json"), CatalogSchema);
|
|
51
|
+
if (!legacy)
|
|
52
|
+
return current;
|
|
53
|
+
const seedById = new Map(legacy.models.map((model) => [model.id, model]));
|
|
54
|
+
let changed = false;
|
|
55
|
+
const models = current.models.map((model) => {
|
|
56
|
+
const seed = seedById.get(model.id);
|
|
57
|
+
if (model.reasoningEfforts === undefined && seed?.reasoningEfforts !== undefined) {
|
|
58
|
+
changed = true;
|
|
59
|
+
return { ...model, reasoningEfforts: seed.reasoningEfforts };
|
|
60
|
+
}
|
|
61
|
+
return model;
|
|
62
|
+
});
|
|
63
|
+
if (!changed)
|
|
64
|
+
return current;
|
|
65
|
+
const merged = { ...current, models };
|
|
66
|
+
writeJson(paths.catalogFile, merged);
|
|
67
|
+
return merged;
|
|
68
|
+
}
|
|
47
69
|
const legacy = path.join(packageRoot(), "config", "downloads.json");
|
|
48
70
|
const migrated = readJson(legacy, CatalogSchema);
|
|
49
71
|
if (migrated) {
|
package/dist/models/enrich.js
CHANGED
package/dist/service/router.js
CHANGED
|
@@ -160,9 +160,15 @@ export function describeModel(model, options = {}) {
|
|
|
160
160
|
quantization: model.quant || null,
|
|
161
161
|
state,
|
|
162
162
|
max_context_length: md.contextLength ?? null,
|
|
163
|
-
|
|
163
|
+
// GGUF template detection is deliberately conservative. A false result
|
|
164
|
+
// means "not detected", not proof that a catalog-marked reasoner is not
|
|
165
|
+
// one, so preserve the catalog's positive capability metadata.
|
|
166
|
+
reasoning: Boolean(md.reasoning || model.thinking),
|
|
164
167
|
};
|
|
165
|
-
|
|
168
|
+
// Prefer explicit GGUF metadata when a runtime supplies it, but preserve
|
|
169
|
+
// catalog knowledge for models whose chat template does not encode the
|
|
170
|
+
// accepted request levels (GPT-OSS is one such model).
|
|
171
|
+
const reasoningEfforts = md["reasoning_efforts"] ?? model.reasoningEfforts;
|
|
166
172
|
if (Array.isArray(reasoningEfforts) &&
|
|
167
173
|
reasoningEfforts.every((value) => typeof value === "string")) {
|
|
168
174
|
entry.reasoning_efforts = reasoningEfforts;
|
package/dist/types.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface Model {
|
|
|
49
49
|
tier?: string;
|
|
50
50
|
/** Whether the catalog marks this as a thinking/reasoning model. */
|
|
51
51
|
thinking?: boolean;
|
|
52
|
+
/** Per-request reasoning levels accepted by the model's OpenAI-compatible API. */
|
|
53
|
+
reasoningEfforts?: string[];
|
|
52
54
|
/** The catalog's advertised max context, if known. */
|
|
53
55
|
contextMax?: number;
|
|
54
56
|
/** Back-reference: the id of the reconciled catalog entry, if matched. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@otto-code/brain",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"description": "Otto Brain - self-contained host for local GGUF models, with measured VRAM budgeting and reasoning-budget control",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^20.9.0",
|
|
52
52
|
"typescript": "^5.9.3",
|
|
53
|
-
"vitest": "^4.1.
|
|
53
|
+
"vitest": "^4.1.10"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
56
|
"node": ">=20.6.0"
|