ag-ai 0.4.2 → 0.4.3
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/k8s/opencode.js +14 -9
- package/package.json +1 -1
- package/runtime/model-tiers.json +4 -0
- package/runtime/protocol.mjs +16 -16
package/dist/k8s/opencode.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.opencodeStack = void 0;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
4
9
|
const ag_rpi_mega_1 = require("ag-rpi-mega");
|
|
5
10
|
const common_1 = require("./common");
|
|
11
|
+
/** The runtime's tier table is the single source of truth for which model and effort each tier runs. */
|
|
12
|
+
const MODEL_TIERS = JSON.parse((0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, '..', '..', 'runtime', 'model-tiers.json'), 'utf8'));
|
|
6
13
|
/** The published OpenCode CLI is installed into a writable emptyDir at pod start. */
|
|
7
14
|
const OPENCODE_PACKAGE = 'opencode-ai@1.18.31';
|
|
8
15
|
const OPENCODE_PREFIX = '/opt/opencode';
|
|
@@ -49,19 +56,17 @@ const opencodeStack = (context) => {
|
|
|
49
56
|
(0, common_1.env)('XDG_CACHE_HOME', '/data/opencode/cache'),
|
|
50
57
|
// The unrestricted /provider response processes thousands of models from
|
|
51
58
|
// unconfigured providers on every request, exceeding the runner's budget.
|
|
52
|
-
// Each advertised model carries the reasoning effort
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
// with its model catalogue; it does not replace it.
|
|
59
|
+
// Each advertised model carries the reasoning effort of the tier that
|
|
60
|
+
// selects it. OpenCode merges these entries with its model catalogue; it
|
|
61
|
+
// does not replace it.
|
|
56
62
|
(0, common_1.env)('OPENCODE_CONFIG_CONTENT', JSON.stringify({
|
|
57
63
|
enabled_providers: ['openai', 'google'],
|
|
58
64
|
provider: {
|
|
59
65
|
openai: {
|
|
60
|
-
models: {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
66
|
+
models: Object.fromEntries(Object.values(MODEL_TIERS).map(({ model, reasoningEffort }) => [
|
|
67
|
+
model,
|
|
68
|
+
{ options: { reasoningEffort } },
|
|
69
|
+
])),
|
|
65
70
|
},
|
|
66
71
|
},
|
|
67
72
|
})),
|
package/package.json
CHANGED
package/runtime/protocol.mjs
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
// differ.
|
|
4
4
|
|
|
5
5
|
import { createHash } from 'node:crypto';
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The only place that names a model: each `prefer` tier maps to one model and
|
|
10
|
+
* effort. Callers send a tier; the model is resolved when the call is made.
|
|
11
|
+
*/
|
|
12
|
+
const MODEL_TIERS = JSON.parse(
|
|
13
|
+
readFileSync(new URL('./model-tiers.json', import.meta.url), 'utf8'),
|
|
14
|
+
);
|
|
6
15
|
|
|
7
16
|
const GENERATION_VERSION = 1;
|
|
8
17
|
const MAX_TEXT_BYTES = 2 * 1024 * 1024;
|
|
@@ -257,21 +266,9 @@ const normalizeGenerationRequest = (value, models) => {
|
|
|
257
266
|
if (prefer !== undefined && prefer !== 'fast' && prefer !== 'quality') {
|
|
258
267
|
throw new GenerationProtocolError(400, 'invalid_request', 'prefer is invalid');
|
|
259
268
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
} else if (prefer === 'fast') {
|
|
264
|
-
requestedModel = catalog.find((candidate) => candidate.prefer.includes('fast'))?.id;
|
|
265
|
-
requestedModel ??= catalog.find((candidate) => /(?:mini|luna)$/i.test(candidate.id))?.id;
|
|
266
|
-
if (!requestedModel) throw unsupported('fast model preference');
|
|
267
|
-
} else {
|
|
268
|
-
requestedModel =
|
|
269
|
-
catalog.find((candidate) => candidate.isDefault && candidate.prefer.includes('quality'))
|
|
270
|
-
?.id ??
|
|
271
|
-
catalog.find((candidate) => candidate.isDefault)?.id ??
|
|
272
|
-
catalog.find((candidate) => candidate.prefer.includes('quality'))?.id ??
|
|
273
|
-
catalog[0].id;
|
|
274
|
-
}
|
|
269
|
+
const tier = MODEL_TIERS[prefer ?? 'quality'];
|
|
270
|
+
const requestedModel =
|
|
271
|
+
request.model === undefined ? tier.model : boundedString(request.model, 160, 'model');
|
|
275
272
|
const model =
|
|
276
273
|
catalog.find((candidate) => candidate.id === requestedModel) ??
|
|
277
274
|
(requestedModel.includes('/') ? undefined : uniqueSuffixModel(catalog, requestedModel));
|
|
@@ -290,7 +287,9 @@ const normalizeGenerationRequest = (value, models) => {
|
|
|
290
287
|
const output = normalizeOutput(request.output, capabilities);
|
|
291
288
|
const reasoningEffort =
|
|
292
289
|
request.reasoningEffort === undefined
|
|
293
|
-
?
|
|
290
|
+
? request.model === undefined
|
|
291
|
+
? tier.reasoningEffort
|
|
292
|
+
: (capabilities.defaultReasoningEffort ?? capabilities.supportedReasoningEfforts[0])
|
|
294
293
|
: boundedString(request.reasoningEffort, 32, 'reasoningEffort');
|
|
295
294
|
if (!reasoningEffort) {
|
|
296
295
|
throw new GenerationProtocolError(
|
|
@@ -358,6 +357,7 @@ const publicModelCatalog = (models, { ready = true } = {}) => ({
|
|
|
358
357
|
|
|
359
358
|
export {
|
|
360
359
|
GENERATION_VERSION,
|
|
360
|
+
MODEL_TIERS,
|
|
361
361
|
MAX_INPUT_ATTACHMENT_BYTES,
|
|
362
362
|
MAX_INPUT_TOTAL_BYTES,
|
|
363
363
|
GenerationProtocolError,
|