@bivelio/savings-layer 0.4.24 → 0.4.26
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/LICENSE +105 -21
- package/README.md +601 -28
- package/dist/adapters/ai-sdk.d.ts +46 -0
- package/dist/adapters/ai-sdk.js +84 -0
- package/dist/adapters/anthropic-sdk.d.ts +35 -0
- package/dist/adapters/anthropic-sdk.js +100 -0
- package/dist/adapters/langchain.d.ts +29 -0
- package/dist/adapters/langchain.js +58 -0
- package/dist/adapters/mastra.d.ts +41 -0
- package/dist/adapters/mastra.js +74 -0
- package/dist/gateway/bin.js +963 -630
- package/dist/index.d.ts +2912 -1516
- package/dist/index.js +1368 -865
- package/docs/terminales/README.md +173 -17
- package/docs/terminales/aider.md +74 -0
- package/docs/terminales/claude-code.md +7 -2
- package/docs/terminales/continue.md +47 -0
- package/docs/terminales/copilot.md +114 -0
- package/docs/terminales/kilo.md +54 -31
- package/docs/terminales/no-soportados.md +41 -0
- package/docs/terminales/opencode.md +33 -11
- package/package.json +89 -5
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
# opencode a través del gateway
|
|
2
2
|
|
|
3
|
-
**Fuente:** `docs/PASARELA-S3-TERMINALES.md` §3 [V]
|
|
4
|
-
|
|
5
|
-
`
|
|
3
|
+
**Fuente:** `docs/PASARELA-S3-TERMINALES.md` §3 [V] y
|
|
4
|
+
`docs/investigacion/2026-09-27/agentes-de-codigo.md` (código de
|
|
5
|
+
`anomalyco/opencode` v1.18.32, 2026-09-27). opencode enruta por **configuración**,
|
|
6
|
+
y su capa de protocolo añade `/messages` a `https://api.anthropic.com/v1` por
|
|
7
|
+
defecto: por eso aquí el URL lleva `/v1` [V].
|
|
6
8
|
|
|
7
9
|
## Qué necesitas
|
|
8
10
|
|
|
9
11
|
- `opencode` instalado, proveedor `anthropic` con tu **API key** de Anthropic.
|
|
10
12
|
- `bvsala` instalado, `BIVELIO_SERVICE_KEY` exportada y una licencia BiVelio activa (la recoge el gateway con la clave; ver [README](README.md)).
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## Envoltorio: `bvsala opencode [args…]`
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
export BIVELIO_SERVICE_KEY=bvk_…
|
|
18
|
+
bvsala opencode
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
opencode acepta la configuración entera en la variable `OPENCODE_CONFIG_CONTENT`
|
|
22
|
+
y la fusiona **por encima** de la global y de la de proyecto (`config.ts`: se
|
|
23
|
+
carga después de `opencode.json` global, del de proyecto y de `.opencode/`; solo
|
|
24
|
+
la config de cuenta remota y la gestionada por la empresa van después) [V]. El
|
|
25
|
+
envoltorio arranca un gateway efímero y lanza `opencode` con esa variable
|
|
26
|
+
apuntando `provider.anthropic.options.baseURL` a `http://127.0.0.1:<puerto>/v1`.
|
|
27
|
+
**No escribe nada en disco** y todo muere al salir.
|
|
28
|
+
|
|
29
|
+
- Si ya exportas tu propio `OPENCODE_CONFIG_CONTENT`, el envoltorio lo
|
|
30
|
+
**fusiona**: solo cambia `provider.anthropic.options.baseURL`; tu clave, tus
|
|
31
|
+
modelos y lo demás siguen igual. Si no es un objeto JSON (por ejemplo, JSONC
|
|
32
|
+
con comentarios), se niega antes de arrancar y no repite su valor.
|
|
33
|
+
- Solo pasa por el gateway el proveedor `anthropic`. Los demás proveedores
|
|
34
|
+
(OpenAI, OpenCode Zen, OpenRouter…) van directos y no se miden.
|
|
35
|
+
- Al salir imprime cuántas peticiones midió y cuáles reenvió sin medir, y por qué.
|
|
36
|
+
|
|
37
|
+
## Manual: `~/.config/opencode/opencode.json`
|
|
13
38
|
|
|
14
39
|
```json
|
|
15
40
|
{
|
|
@@ -27,11 +52,6 @@
|
|
|
27
52
|
[V]. El `opencode.json` de proyecto pisa al global: si tienes uno en el repo,
|
|
28
53
|
ahí es donde manda.
|
|
29
54
|
|
|
30
|
-
No hay envoltorio `bvsala opencode`: el enrutado es config de usuario. El
|
|
31
|
-
`bvsala doctor --write opencode` previsto en S3 hará un merge JSON conservador
|
|
32
|
-
de este bloque (con copia `.bak`) en tu config de usuario, nunca en archivos
|
|
33
|
-
del repo.
|
|
34
|
-
|
|
35
55
|
### Alternativa [V]: `baseURL` desde variable de entorno
|
|
36
56
|
|
|
37
57
|
```json
|
|
@@ -56,10 +76,12 @@ opencode
|
|
|
56
76
|
|
|
57
77
|
- **Sin `/v1`** → opencode pide `http://127.0.0.1:8402/messages` → `[gateway] POST /messages → 404`.
|
|
58
78
|
- **Barra final** (`…/v1/`) → no.
|
|
59
|
-
- **Config de proyecto** con otro `baseURL` pisando al global sin que lo sepas
|
|
79
|
+
- **Config de proyecto** con otro `baseURL` pisando al global sin que lo sepas
|
|
80
|
+
(con el envoltorio no pasa: su variable manda sobre los dos).
|
|
60
81
|
- **Gateway apagado con la config escrita**: opencode falla hasta que arranques
|
|
61
82
|
`bvsala gateway` de nuevo. La config es persistente; el gateway, no. (La
|
|
62
|
-
variante `{env:…}` sin exportar la variable también falla, por vacío.)
|
|
83
|
+
variante `{env:…}` sin exportar la variable también falla, por vacío.) El
|
|
84
|
+
envoltorio no tiene esta trampa.
|
|
63
85
|
|
|
64
86
|
## Nota BYOK
|
|
65
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bivelio/savings-layer",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.26",
|
|
4
4
|
"description": "The savings layer for your LLM bill: a library inside your code that lets through only what has to be paid for and returns a SavingsReport per call, measured with your provider's own meter and kept apart from estimates. Commercial license, paid per seat, commission only on measured savings. Your prompts never leave your infrastructure.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"llm",
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"email": "support@bivelio.com",
|
|
16
16
|
"url": "https://savings.bivelio.com"
|
|
17
17
|
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/BiVelio/bivelio-savings-layer.git"
|
|
21
|
+
},
|
|
18
22
|
"license": "SEE LICENSE IN LICENSE",
|
|
19
23
|
"author": "BiVelio Inc.",
|
|
20
24
|
"type": "module",
|
|
@@ -27,6 +31,26 @@
|
|
|
27
31
|
"import": "./dist/index.js",
|
|
28
32
|
"default": "./dist/index.js"
|
|
29
33
|
},
|
|
34
|
+
"./ai-sdk": {
|
|
35
|
+
"types": "./dist/adapters/ai-sdk.d.ts",
|
|
36
|
+
"import": "./dist/adapters/ai-sdk.js",
|
|
37
|
+
"default": "./dist/adapters/ai-sdk.js"
|
|
38
|
+
},
|
|
39
|
+
"./mastra": {
|
|
40
|
+
"types": "./dist/adapters/mastra.d.ts",
|
|
41
|
+
"import": "./dist/adapters/mastra.js",
|
|
42
|
+
"default": "./dist/adapters/mastra.js"
|
|
43
|
+
},
|
|
44
|
+
"./langchain": {
|
|
45
|
+
"types": "./dist/adapters/langchain.d.ts",
|
|
46
|
+
"import": "./dist/adapters/langchain.js",
|
|
47
|
+
"default": "./dist/adapters/langchain.js"
|
|
48
|
+
},
|
|
49
|
+
"./anthropic-sdk": {
|
|
50
|
+
"types": "./dist/adapters/anthropic-sdk.d.ts",
|
|
51
|
+
"import": "./dist/adapters/anthropic-sdk.js",
|
|
52
|
+
"default": "./dist/adapters/anthropic-sdk.js"
|
|
53
|
+
},
|
|
30
54
|
"./package.json": "./package.json"
|
|
31
55
|
},
|
|
32
56
|
"bin": {
|
|
@@ -52,13 +76,23 @@
|
|
|
52
76
|
"build:all": "pnpm run build:packages && pnpm run build:services && pnpm run build",
|
|
53
77
|
"typecheck": "tsc --noEmit",
|
|
54
78
|
"typecheck:packages": "pnpm -r --filter=./packages/* --filter=./services/* typecheck",
|
|
55
|
-
"typecheck:all": "pnpm run typecheck && pnpm run typecheck:packages",
|
|
79
|
+
"typecheck:all": "pnpm run typecheck && pnpm run typecheck:packages && pnpm run typecheck:ejemplos",
|
|
80
|
+
"typecheck:ejemplos": "tsc -p examples/stacks/tsconfig.json",
|
|
56
81
|
"test": "vitest run",
|
|
57
82
|
"test:watch": "vitest",
|
|
58
83
|
"lint": "tsc --noEmit",
|
|
59
84
|
"example:basic": "BVSALA_DEV_OPEN=1 tsx examples/basic/index.ts",
|
|
60
85
|
"example:handoff": "BVSALA_DEV_OPEN=1 tsx examples/multi-agent/handoff.ts",
|
|
61
86
|
"example:serialization": "BVSALA_DEV_OPEN=1 tsx examples/serialization/format-selector.ts",
|
|
87
|
+
"example:otel": "BVSALA_DEV_OPEN=1 tsx examples/exporters/otel.ts",
|
|
88
|
+
"example:focus": "BVSALA_DEV_OPEN=1 tsx examples/exporters/focus.ts",
|
|
89
|
+
"example:nextjs": "BVSALA_DEV_OPEN=1 tsx examples/stacks/nextjs/run.ts",
|
|
90
|
+
"example:express": "BVSALA_DEV_OPEN=1 tsx examples/stacks/express/server.ts",
|
|
91
|
+
"example:ai-sdk": "BVSALA_DEV_OPEN=1 tsx examples/stacks/ai-sdk/bivelio-check.ts",
|
|
92
|
+
"example:mastra": "BVSALA_DEV_OPEN=1 tsx examples/stacks/mastra/bivelio-check.ts",
|
|
93
|
+
"example:langchain": "BVSALA_DEV_OPEN=1 tsx examples/stacks/langchain/bivelio-check.ts",
|
|
94
|
+
"example:anthropic-sdk": "BVSALA_DEV_OPEN=1 tsx examples/stacks/anthropic-sdk/bivelio-check.ts",
|
|
95
|
+
"init:ejemplos": "tsx scripts/ejemplos-de-init.ts",
|
|
62
96
|
"example:licensed": "tsx examples/licensing/licensed.ts",
|
|
63
97
|
"license:demo": "tsx examples/licensing/demo.ts",
|
|
64
98
|
"example:revocation": "tsx examples/licensing/revocation.ts",
|
|
@@ -72,10 +106,13 @@
|
|
|
72
106
|
"web:dev": "node apps/web/serve.mjs",
|
|
73
107
|
"prepublishOnly": "pnpm run build",
|
|
74
108
|
"ab:publish": "tsx benchmarks/publish.ts",
|
|
109
|
+
"ab:sonda": "BVSALA_DEV_OPEN=1 tsx --env-file-if-exists=.env.bench benchmarks/sonda-del-banco.ts",
|
|
110
|
+
"medicion:reproducir": "node apps/web/public/measure/reproduce.mjs",
|
|
75
111
|
"verja:calibrar": "tsx corpus/calibrar-la-verja.ts",
|
|
76
112
|
"corpus:arnes": "tsx corpus/arnes/informe.ts",
|
|
77
113
|
"corpus:auditar": "tsx corpus/auditoria/auditar.ts",
|
|
78
114
|
"sombra:corpus": "tsx benchmarks/sombra-corpus.ts",
|
|
115
|
+
"compactacion:banco": "tsx benchmarks/compactacion-de-cola/banco.ts",
|
|
79
116
|
"sombra:diales": "tsx --env-file-if-exists=.env.bench benchmarks/sombra-diales.ts",
|
|
80
117
|
"anillo1": "tsx --env-file-if-exists=.env.bench benchmarks/anillo1/arnes.ts",
|
|
81
118
|
"anillo2": "tsx benchmarks/anillo2/arnes.ts",
|
|
@@ -84,25 +121,72 @@
|
|
|
84
121
|
"salida": "tsx --env-file-if-exists=.env.bench benchmarks/salida/arnes.ts",
|
|
85
122
|
"salida:anatomia": "tsx benchmarks/salida/anatomia.ts",
|
|
86
123
|
"salida:por-clase": "tsx benchmarks/salida/por-clase.ts",
|
|
124
|
+
"esfuerzo": "tsx --env-file-if-exists=.env.bench benchmarks/esfuerzo/banco.ts",
|
|
87
125
|
"luz-verde": "bash scripts/luz-verde.sh",
|
|
88
|
-
"sonda:sdk": "BVSALA_DEV_OPEN=1 tsx --env-file-if-exists=.env.bench benchmarks/sdk/sonda.ts"
|
|
126
|
+
"sonda:sdk": "BVSALA_DEV_OPEN=1 tsx --env-file-if-exists=.env.bench benchmarks/sdk/sonda.ts",
|
|
127
|
+
"sbom:tarball": "tsx scripts/sbom.ts",
|
|
128
|
+
"cache-semantica": "BVSALA_DEV_OPEN=1 tsx benchmarks/cache-semantica/arnes.ts",
|
|
129
|
+
"cache-semantica:publicar": "tsx benchmarks/cache-semantica/publicar.ts",
|
|
130
|
+
"latencia:gateways": "tsx benchmarks/latencia-gateways/arnes.ts",
|
|
131
|
+
"vigia:conexiones": "tsx benchmarks/latencia-gateways/vigia-conexiones.ts",
|
|
132
|
+
"cache-semantica:calibrada": "BVSALA_DEV_OPEN=1 tsx benchmarks/cache-semantica/calibrada.ts",
|
|
133
|
+
"cache-semantica:simulacion": "tsx benchmarks/cache-semantica/simulacion.ts"
|
|
89
134
|
},
|
|
90
135
|
"devDependencies": {
|
|
91
136
|
"@noble/curves": "^2.2.0",
|
|
137
|
+
"@opentelemetry/api": "^1.9.1",
|
|
138
|
+
"@opentelemetry/sdk-trace-base": "^2.11.0",
|
|
92
139
|
"@types/node": "^22.10.2",
|
|
93
140
|
"gpt-tokenizer": "^3.4.0",
|
|
141
|
+
"hyparquet": "^1.31.2",
|
|
94
142
|
"tsup": "^8.3.5",
|
|
95
143
|
"tsx": "^4.19.2",
|
|
96
144
|
"typescript": "^5.7.2",
|
|
97
|
-
"vitest": "^2.1.8"
|
|
145
|
+
"vitest": "^2.1.8",
|
|
146
|
+
"@ai-sdk/anthropic": "4.0.65",
|
|
147
|
+
"@ai-sdk/openai": "4.0.78",
|
|
148
|
+
"@anthropic-ai/sdk": "0.128.0",
|
|
149
|
+
"@langchain/core": "1.2.13",
|
|
150
|
+
"@langchain/openai": "1.6.0",
|
|
151
|
+
"@mastra/core": "1.71.0",
|
|
152
|
+
"ai": "7.0.118",
|
|
153
|
+
"ai-v6": "npm:ai@6.0.293",
|
|
154
|
+
"@types/express": "5.0.6",
|
|
155
|
+
"express": "5.2.1",
|
|
156
|
+
"langchain": "1.5.14",
|
|
157
|
+
"zod": "4.6.5"
|
|
98
158
|
},
|
|
99
159
|
"packageManager": "pnpm@10.17.1",
|
|
100
160
|
"peerDependencies": {
|
|
101
|
-
"
|
|
161
|
+
"@opentelemetry/api": "^1.9.0",
|
|
162
|
+
"gpt-tokenizer": "^3",
|
|
163
|
+
"@anthropic-ai/sdk": ">=0.103.0 <1",
|
|
164
|
+
"@langchain/core": ">=1.1.0 <2",
|
|
165
|
+
"@mastra/core": ">=1.68.0 <2",
|
|
166
|
+
"ai": "^6.0.0 || ^7.0.0",
|
|
167
|
+
"langchain": ">=1.1.0 <2"
|
|
102
168
|
},
|
|
103
169
|
"peerDependenciesMeta": {
|
|
170
|
+
"@opentelemetry/api": {
|
|
171
|
+
"optional": true
|
|
172
|
+
},
|
|
104
173
|
"gpt-tokenizer": {
|
|
105
174
|
"optional": true
|
|
175
|
+
},
|
|
176
|
+
"@anthropic-ai/sdk": {
|
|
177
|
+
"optional": true
|
|
178
|
+
},
|
|
179
|
+
"@langchain/core": {
|
|
180
|
+
"optional": true
|
|
181
|
+
},
|
|
182
|
+
"@mastra/core": {
|
|
183
|
+
"optional": true
|
|
184
|
+
},
|
|
185
|
+
"ai": {
|
|
186
|
+
"optional": true
|
|
187
|
+
},
|
|
188
|
+
"langchain": {
|
|
189
|
+
"optional": true
|
|
106
190
|
}
|
|
107
191
|
}
|
|
108
192
|
}
|