ag-ai 0.1.5 → 0.1.7
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/README.md +5 -1
- package/dist/k8s/index.js +1 -1
- package/dist/k8s/runner.js +7 -4
- package/package.json +11 -7
- package/runtime/bridge.mjs +0 -7
- package/runtime/index.mjs +0 -1
- package/runtime/protocol.mjs +0 -26
- package/runtime/tests/bridge.test.mjs +0 -554
- package/runtime/tests/image-adapter.test.mjs +0 -148
- package/runtime/tests/protocol.test.mjs +0 -156
- package/runtime/tests/server.test.mjs +0 -231
- package/runtime/tests/store.test.mjs +0 -114
- package/runtime/tests/telemetry.test.mjs +0 -138
package/README.md
CHANGED
|
@@ -9,13 +9,17 @@ Provider-neutral AI client and cluster runtime for the
|
|
|
9
9
|
| --------------- | --------------------------------------------------------------------- |
|
|
10
10
|
| `ag-ai` | Client SDK: generate, generateText, promptDirect, promptImage, models |
|
|
11
11
|
| `ag-ai/client` | Client SDK entry point |
|
|
12
|
-
| `ag-ai/runtime` | Cluster runtime: generation protocol, store, server, bridge (ESM) |
|
|
13
12
|
| `ag-ai/k8s` | Cluster plugin descriptor (`ClusterPlugin`) |
|
|
13
|
+
| `ag-ai/runtime` | Cluster runtime: generation protocol, store, server, bridge (ESM) |
|
|
14
14
|
| `ag-ai/image` | Neutral image-output adapter (provider per implementation) |
|
|
15
15
|
|
|
16
16
|
The client compiles to CommonJS. The runtime is hand-authored ESM and shipped
|
|
17
17
|
as-is, because it runs inside the pod with no build step.
|
|
18
18
|
|
|
19
|
+
The client-only dependencies (`@google/genai`, `node-cache`) are declared as
|
|
20
|
+
`optionalDependencies`; the cluster runtime install omits them because the
|
|
21
|
+
runtime imports only Node builtins.
|
|
22
|
+
|
|
19
23
|
## Boundaries
|
|
20
24
|
|
|
21
25
|
- No prompts. Prompt templates belong to consumers (gec.dev, bolt.garden, …).
|
package/dist/k8s/index.js
CHANGED
|
@@ -14,7 +14,7 @@ const t3code_1 = require("./t3code");
|
|
|
14
14
|
exports.plugin = {
|
|
15
15
|
name: 'ag-ai',
|
|
16
16
|
namespace: common_1.NAMESPACE,
|
|
17
|
-
requiredEnv: ['AG_AI_QUEUE_URL', 'AG_AI_GENERATION_CIDR'],
|
|
17
|
+
requiredEnv: ['AG_AI_QUEUE_URL', 'AG_AI_GENERATION_CIDR', 'AG_AI_PACKAGE'],
|
|
18
18
|
requiredSecrets: [
|
|
19
19
|
'runner-token',
|
|
20
20
|
'generation-token',
|
package/dist/k8s/runner.js
CHANGED
|
@@ -10,7 +10,6 @@ const ag_rpi_mega_1 = require("ag-rpi-mega");
|
|
|
10
10
|
const common_1 = require("./common");
|
|
11
11
|
const networkInitTemplate = (0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, 'assets', 'network-init.sh'), 'utf8');
|
|
12
12
|
/** The published runtime is installed into a writable emptyDir at pod start. */
|
|
13
|
-
const AG_AI_PACKAGE = 'ag-ai@^0.1.1';
|
|
14
13
|
const AG_AI_RUNTIME_DIR = '/opt/ag-ai';
|
|
15
14
|
const AG_AI_BRIDGE = `${AG_AI_RUNTIME_DIR}/node_modules/ag-ai/runtime/bridge.mjs`;
|
|
16
15
|
const networkInitScript = ({ generationCidr, generationPort, opencodePort, }) => networkInitTemplate
|
|
@@ -41,6 +40,9 @@ const runnerStack = (context) => {
|
|
|
41
40
|
throw new Error('AG_AI_GENERATION_CIDR is required');
|
|
42
41
|
const imageProvider = context.env.AG_AI_IMAGE_PROVIDER ?? 'openai';
|
|
43
42
|
const opencodeProvider = context.env.AG_AI_OPENCODE_PROVIDER;
|
|
43
|
+
const agAiPackage = context.env.AG_AI_PACKAGE;
|
|
44
|
+
if (!agAiPackage)
|
|
45
|
+
throw new Error('AG_AI_PACKAGE is required');
|
|
44
46
|
const metalLbAddress = facilities.metalLb(common_1.METAL_LB_KEY);
|
|
45
47
|
if (!metalLbAddress)
|
|
46
48
|
throw new Error(`no MetalLB address is configured for ${common_1.METAL_LB_KEY}`);
|
|
@@ -96,8 +98,6 @@ const runnerStack = (context) => {
|
|
|
96
98
|
(0, common_1.env)('AG_AI_RUNNER_ID', common_1.RUNNER_APP),
|
|
97
99
|
(0, common_1.env)('AG_AI_WORKSPACE', '/data/workspace'),
|
|
98
100
|
(0, common_1.env)('AG_AI_MAIN_WORKSPACE', '/data/workspace'),
|
|
99
|
-
(0, common_1.env)('AG_AI_GENERATED_IMAGES', '/data/generated-images'),
|
|
100
|
-
(0, common_1.env)('AG_AI_MAIN_GENERATED_IMAGES', '/data/generated-images'),
|
|
101
101
|
{ name: 'AG_AI_GENERATION_HOST', valueFrom: { fieldRef: { fieldPath: 'status.podIP' } } },
|
|
102
102
|
(0, common_1.env)('AG_AI_GENERATION_PORT', String(common_1.GENERATION_PORT)),
|
|
103
103
|
(0, common_1.env)('AG_AI_GENERATION_STORE', '/data/generation-jobs'),
|
|
@@ -168,6 +168,8 @@ const runnerStack = (context) => {
|
|
|
168
168
|
name: 'install-ag-ai',
|
|
169
169
|
image: facilities.image('ag-ai-runner'),
|
|
170
170
|
command: ['npm'],
|
|
171
|
+
// The runtime imports only Node builtins. Client-only dependencies are
|
|
172
|
+
// optional, so omitting them keeps the pod install lean.
|
|
171
173
|
args: [
|
|
172
174
|
'install',
|
|
173
175
|
'--prefix',
|
|
@@ -175,8 +177,9 @@ const runnerStack = (context) => {
|
|
|
175
177
|
'--no-audit',
|
|
176
178
|
'--no-fund',
|
|
177
179
|
'--omit=dev',
|
|
180
|
+
'--omit=optional',
|
|
178
181
|
'--ignore-scripts',
|
|
179
|
-
|
|
182
|
+
agAiPackage,
|
|
180
183
|
],
|
|
181
184
|
env: [(0, common_1.env)('HOME', '/tmp'), (0, common_1.env)('NPM_CONFIG_CACHE', '/tmp/npm-cache')],
|
|
182
185
|
volumeMounts: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ag-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Provider-neutral AI client and cluster runtime for the rpi-mega cluster.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "admin@gec.dev",
|
|
@@ -11,20 +11,20 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist/**/*",
|
|
13
13
|
"runtime/**/*",
|
|
14
|
+
"!runtime/tests",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"main": "./dist/index.js",
|
|
17
18
|
"types": "./dist/index.d.ts",
|
|
18
19
|
"exports": {
|
|
19
20
|
".": "./dist/index.js",
|
|
20
|
-
"./client": "./dist/index.js",
|
|
21
|
+
"./client": "./dist/client/index.js",
|
|
21
22
|
"./k8s": "./dist/k8s/index.js",
|
|
22
|
-
"./runtime": "./runtime/index.mjs"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"@google/genai": "^2.19.0",
|
|
26
|
-
"node-cache": "^5.1.2"
|
|
23
|
+
"./runtime": "./runtime/index.mjs",
|
|
24
|
+
"./image": "./runtime/image/adapter.mjs",
|
|
25
|
+
"./package.json": "./package.json"
|
|
27
26
|
},
|
|
27
|
+
"dependencies": {},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@kubernetes/client-node": "2.0.0",
|
|
30
30
|
"@types/node": "^26.4.1",
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
"optional": true
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
|
+
"optionalDependencies": {
|
|
46
|
+
"@google/genai": "^2.19.0",
|
|
47
|
+
"node-cache": "^5.1.2"
|
|
48
|
+
},
|
|
45
49
|
"scripts": {
|
|
46
50
|
"preinstall": "npx only-allow pnpm",
|
|
47
51
|
"format": "e7-oxfmt",
|
package/runtime/bridge.mjs
CHANGED
|
@@ -19,8 +19,6 @@ const DEFAULT_QUEUE_URL = 'https://queue.invalid/api/ai/runner';
|
|
|
19
19
|
const DEFAULT_TOKEN_FILE = '/var/run/secrets/ag-ai-runner/token';
|
|
20
20
|
const DEFAULT_WORKSPACE = '/workspace';
|
|
21
21
|
const DEFAULT_MAIN_WORKSPACE = '/data/workspace';
|
|
22
|
-
const DEFAULT_GENERATED_IMAGES = '/generated-images';
|
|
23
|
-
const DEFAULT_MAIN_GENERATED_IMAGES = '/data/ag-ai/generated_images';
|
|
24
22
|
const DEFAULT_GENERATION_PORT = 4501;
|
|
25
23
|
const DEFAULT_GENERATION_STORE = '/generation-jobs';
|
|
26
24
|
const DEFAULT_GENERATION_TOKEN_FILE = '/var/run/secrets/ag-ai-generation/token';
|
|
@@ -824,10 +822,6 @@ const readConfig = async (env = process.env) => {
|
|
|
824
822
|
runnerId: env.AG_AI_RUNNER_ID ?? `ag-ai-${os.hostname()}-${randomUUID()}`,
|
|
825
823
|
workspace: path.resolve(env.AG_AI_WORKSPACE ?? DEFAULT_WORKSPACE),
|
|
826
824
|
mainWorkspace: path.resolve(env.AG_AI_MAIN_WORKSPACE ?? DEFAULT_MAIN_WORKSPACE),
|
|
827
|
-
generatedImages: path.resolve(env.AG_AI_GENERATED_IMAGES ?? DEFAULT_GENERATED_IMAGES),
|
|
828
|
-
mainGeneratedImages: path.resolve(
|
|
829
|
-
env.AG_AI_MAIN_GENERATED_IMAGES ?? DEFAULT_MAIN_GENERATED_IMAGES,
|
|
830
|
-
),
|
|
831
825
|
generationHost: env.AG_AI_GENERATION_HOST,
|
|
832
826
|
generationPeerPrefix: env.AG_AI_GENERATION_PEER_PREFIX,
|
|
833
827
|
generationPort: env.AG_AI_GENERATION_PORT ?? DEFAULT_GENERATION_PORT,
|
|
@@ -847,7 +841,6 @@ const main = async () => {
|
|
|
847
841
|
const analytics = new AnalyticaEvents({ token: config.analyticaToken, source: config.runnerId });
|
|
848
842
|
void analytics.emit('pod', 'started');
|
|
849
843
|
await safeRoot(config.workspace, 'workspace root');
|
|
850
|
-
await safeRoot(config.generatedImages, 'generated-image root');
|
|
851
844
|
|
|
852
845
|
const imageApiKey = await readOptionalToken(config.imageApiKeyFile);
|
|
853
846
|
let imageAdapter;
|
package/runtime/index.mjs
CHANGED
package/runtime/protocol.mjs
CHANGED
|
@@ -217,31 +217,6 @@ const normalizeOutputSchema = (value) => {
|
|
|
217
217
|
return { name, schema: object.schema };
|
|
218
218
|
};
|
|
219
219
|
|
|
220
|
-
const toRunnerInput = (request, runId, models) => {
|
|
221
|
-
const normalized =
|
|
222
|
-
request?.model && request?.reasoningEffort && request?.version === GENERATION_VERSION
|
|
223
|
-
? request
|
|
224
|
-
: normalizeGenerationRequest(request, models);
|
|
225
|
-
const input = normalized.input.map((message) => ({
|
|
226
|
-
role: message.role,
|
|
227
|
-
content: message.content.map((part) => {
|
|
228
|
-
if (part.type === 'text') return { type: 'text', text: part.text };
|
|
229
|
-
if (part.type === 'image') return { type: 'image', mimeType: part.mimeType, data: part.data };
|
|
230
|
-
throw unsupported(`input ${part.type}`);
|
|
231
|
-
}),
|
|
232
|
-
}));
|
|
233
|
-
return {
|
|
234
|
-
runId,
|
|
235
|
-
instructions: normalized.instructions,
|
|
236
|
-
messages: input,
|
|
237
|
-
output: normalized.output,
|
|
238
|
-
imageGeneration: normalized.output.includes('image'),
|
|
239
|
-
model: normalized.model,
|
|
240
|
-
reasoningEffort: normalized.reasoningEffort,
|
|
241
|
-
...(normalized.outputSchema === undefined ? {} : { outputSchema: normalized.outputSchema }),
|
|
242
|
-
};
|
|
243
|
-
};
|
|
244
|
-
|
|
245
220
|
const normalizeGenerationRequest = (value, models) => {
|
|
246
221
|
const request = asObject(value);
|
|
247
222
|
if (request?.version !== GENERATION_VERSION) {
|
|
@@ -380,5 +355,4 @@ export {
|
|
|
380
355
|
normalizeModelCatalog,
|
|
381
356
|
publicModelCatalog,
|
|
382
357
|
requestDigest,
|
|
383
|
-
toRunnerInput,
|
|
384
358
|
};
|