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 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',
@@ -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
- AG_AI_PACKAGE,
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.5",
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
- "dependencies": {
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",
@@ -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
@@ -9,7 +9,6 @@ export {
9
9
  normalizeModelCatalog,
10
10
  publicModelCatalog,
11
11
  requestDigest,
12
- toRunnerInput,
13
12
  } from './protocol.mjs';
14
13
  export { GenerationStore, GenerationStoreError } from './store.mjs';
15
14
  export {
@@ -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
  };