@devvibex/aiflow
v1.1.0
Published
First-party LLM gateway SDK for apps generated on the VibeX platform — chat, streaming, image, video, music (Lyria), sound effects (ElevenLabs) and embeddings without shipping any third-party API key.
Downloads
944
Maintainers
Readme
@devvibex/aiflow
First-party LLM gateway SDK for apps generated on the VibeX platform. No third-party API key is needed in the browser — every request is routed through the platform gateway, which attaches the provider key server-side and bills the project owner's credit balance.
Install
npm install @devvibex/aiflow
# or
yarn add @devvibex/aiflow
# or
pnpm add @devvibex/aiflowRequires Node.js 18+ (or any modern browser) — uses the native fetch
and ReadableStream APIs.
Quick start
import AIFlowClient from '@devvibex/aiflow';
// No model defaults needed — the SDK fetches them from the server on
// first use (cached for the life of the client). Override only if you
// want to pin a specific model.
const aiflow = new AIFlowClient({
appId: 'YOUR_APP_ID', // injected by the platform gateway
baseUrl: 'https://api.vibe-x.app/aiflow',
});
// Optional — inspect / pre-warm the server config
const config = await aiflow.getConfig();
console.log(config.models.chat); // ["claude-sonnet-4-6", "gpt-4o", ...]
console.log(config.defaults.chat); // "claude-sonnet-4-6"
// Non-streaming chat
const res = await aiflow.chat({
system: 'You are a helpful assistant.',
messages: [{ role: 'user', content: 'Hello, who are you?' }],
});
console.log(res.content);
// Streaming chat
for await (const chunk of aiflow.chatStream({
messages: [{ role: 'user', content: 'Write a haiku about the sea.' }],
})) {
if (chunk.delta) process.stdout.write(chunk.delta);
if (chunk.done) break;
}
// Image generation
const img = await aiflow.generateImage({
prompt: 'a cozy cabin in a snowy forest, watercolour',
size: '1024x1024',
});
console.log(img.images[0].url);
// Embeddings
const emb = await aiflow.embed({ input: ['hello world'] });
console.log(emb.data[0].embedding.length);API
new AIFlowClient(options)
| Option | Type | Default | Notes |
| ------------------- | -------------- | ------------------ | ------------------------------------------------- |
| appId | string | required | Public project app id. |
| baseUrl | string | required | Gateway URL, e.g. https://api.vibe-x.io/aiflow. |
| defaultModel | string | from GET /config | Override — wins over server config. |
| defaultImageModel | string | from GET /config | Override. |
| defaultEmbedModel | string | from GET /config | Override. |
| defaultVideoModel | string | from GET /config | Override. |
| defaultAudioModel | string | from GET /config | Override (music / Lyria). |
| defaultSfxModel | string | from GET /config | Override (sound effects / ElevenLabs). |
| timeout | number | 60000 | Per-request timeout (ms). |
| maxRetries | number | 2 | Retries on 429 / 5xx / network errors. |
| fetch | typeof fetch | globalThis.fetch | Custom fetch (Node <18, testing). |
When you don't pass a defaultModel, the SDK calls GET /config on the
first chat / chatStream / generateImage / embed and caches the
response. Concurrent first calls share a single in-flight config fetch.
aiflow.getConfig({ refresh? })
Returns the cached server config, fetching on demand. Pass { refresh: true }
to invalidate the cache.
{
appId: string,
models: {
chat: string[], // e.g. ["claude-sonnet-4-6", "gpt-4o", ...]
image: string[],
embed: string[],
video: string[],
audio: string[], // Lyria — e.g. ["lyria-3-clip-preview", ...]
sfx: string[], // ElevenLabs — e.g. ["eleven_text_to_sound_v2"]
},
defaults: { chat: string, image: string, embed: string, video: string, audio: string, sfx: string },
limits: {
maxTokens: number,
maxImageN: number,
maxEmbedInputs: number,
minSfxDurationSeconds: number,
maxSfxDurationSeconds: number,
},
creditValue: number,
}aiflow.chat({ messages, model?, system?, maxTokens?, temperature?, signal? })
Returns Promise<{ id, model, content, usage: { inputTokens, outputTokens, creditsUsed } }>.
aiflow.chatStream({ ... })
Async iterable of { delta: string, done: boolean } chunks. The final chunk
has done: true and carries the cumulative usage object.
aiflow.generateImage({ prompt, model?, size?, n?, image?, images?, system?, language?, signal? })
Returns { images: [{ url?, b64?, mimeType }], usage: { creditsUsed } }.
url is a short-lived signed URL (~1h). Pass image/images to edit an
existing image (image-to-image) instead of generating from text.
aiflow.generateVideo({ prompt, model?, aspectRatio?, image?, video?, signal? })
Returns { videoUrl, usage: { creditsUsed } }. Pass image for image-to-video
or video for video-to-video; omit both for pure text-to-video.
aiflow.generateAudio({ prompt, model?, negativePrompt?, seed?, signal?, timeout? })
Generate music / background audio from a text prompt (Google Vertex AI Lyria).
Returns { audioUrl, model, durationSeconds, usage: { creditsUsed } }. audioUrl
is a hosted mp3/wav on the CDN. prompt should be a musical description (mood,
genre, tempo/BPM, instrumentation). negativePrompt/seed apply to Lyria 2 only.
aiflow.generateSfx({ prompt, model?, durationSeconds?, signal?, timeout? })
Generate a one-shot sound effect from a text prompt (ElevenLabs). Returns
{ audioUrl, model, durationSeconds, usage: { creditsUsed } }. durationSeconds
is clamped to 0.5–30; omit it to let the model auto-decide. Cache/replay
repeated UI sounds client-side rather than calling per interaction.
aiflow.embed({ input, model?, signal? })
Returns { data: [{ embedding: number[], index }], usage: { creditsUsed } }.
Error handling
All failures throw AIFlowError with .status, .code, and .requestId.
import { AIFlowError } from '@devvibex/aiflow';
try {
await aiflow.chat({ messages });
} catch (err) {
if (err instanceof AIFlowError && err.status === 402) {
alert('AI credits exhausted — please contact the app owner.');
} else {
throw err;
}
}| Status | Meaning | Retry? | | ------ | ----------------------- | -------------------------------- | | 401 | Invalid / revoked appId | No — surface as a config error. | | 402 | Credits exhausted | No — never retry. | | 429 | Rate limited | Yes, auto (exponential backoff). | | 5xx | Transient server error | Yes, auto (exponential backoff). |
Cancellation
All methods accept an AbortSignal:
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 3000);
await aiflow.chat({ messages, signal: ctrl.signal });Publishing to npmjs
Owned by the
@devvibexorg. You must be a member to publish.
1. One-off setup
# Log in with an account that has access to the @devvibex org
npm loginEnable 2FA on the account — npm requires it for scoped org packages.
2. Bump the version
Follow semver. Bump in sdk/aiflow/package.json:
cd sdk/aiflow
npm version patch # or minor / majornpm version creates a git tag automatically — push it with
git push --follow-tags if you want the tag in the shared repo.
3. Dry-run the tarball
Double-check what will be uploaded before going public:
npm pack --dry-runOnly src/, README.md, LICENSE, and package.json should appear —
the files whitelist in package.json enforces this.
4. Publish
Scoped packages default to private on npm, so explicitly publish as public
(already set via publishConfig in package.json, but pass the flag in
case):
npm publish --access publicnpm will prompt for a 2FA code. On success the package appears at https://www.npmjs.com/package/@devvibex/aiflow.
5. Verify
# From any scratch dir
npm info @devvibex/aiflow
npm install @devvibex/aiflow@latest6. Deprecate / unpublish (if needed)
# Soft-deprecate a bad version
npm deprecate @devvibex/[email protected] 'bug in streaming parser — use 1.0.2+'
# Hard unpublish (only within 72h of publishing)
npm unpublish @devvibex/[email protected]CI publishing (optional)
Add an NPM_TOKEN (automation token) secret to the GitHub repo, then:
# .github/workflows/publish-aiflow.yml
name: Publish @devvibex/aiflow
on:
push:
tags: ['aiflow-v*']
jobs:
publish:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdk/aiflow
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}Trigger a release by pushing git tag aiflow-v1.0.1 && git push --tags.
License
MIT
