versera-app 0.1.0

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 ADDED
@@ -0,0 +1,81 @@
1
+ # versera
2
+
3
+ Official JavaScript/TypeScript SDK for [Versera](https://versera.dev) — prompt version control for LLM apps.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install versera-app
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```typescript
14
+ import { Versera } from 'versera-app'
15
+
16
+ const versera = new Versera({
17
+ apiKey: process.env.VERSERA_API_KEY!
18
+ })
19
+
20
+ // Resolve a prompt at runtime
21
+ const { template } = await versera.resolve(
22
+ 'summarize-doc',
23
+ {
24
+ tone: 'professional',
25
+ document: userDocument
26
+ }
27
+ )
28
+
29
+ // Use with any LLM
30
+ const response = await anthropic.messages.create({
31
+ model: 'claude-sonnet-4-6',
32
+ messages: [{ role: 'user', content: template }]
33
+ })
34
+ ```
35
+
36
+ ## Methods
37
+
38
+ ### versera.resolve(slug, variables?, options?)
39
+ Resolves a prompt template with variables. Costs 1 credit per call.
40
+
41
+ ### versera.push(input)
42
+ Creates or updates a prompt.
43
+
44
+ ### versera.list(options?)
45
+ Lists all your prompts.
46
+
47
+ ### versera.get(slug)
48
+ Gets a single prompt with version history.
49
+
50
+ ### versera.saveVersion(slug, input)
51
+ Saves a new version of a prompt.
52
+
53
+ ### versera.rollback(slug, version)
54
+ Rolls back to a previous version.
55
+
56
+ ### versera.log(input)
57
+ Logs a quality score for A/B testing.
58
+
59
+ ## Error handling
60
+
61
+ ```typescript
62
+ import { Versera, VerseraError } from 'versera'
63
+
64
+ try {
65
+ const { template } = await versera.resolve(
66
+ 'my-prompt'
67
+ )
68
+ } catch (error) {
69
+ if (error instanceof VerseraError) {
70
+ if (error.status === 402) {
71
+ console.log('Out of credits!')
72
+ }
73
+ if (error.status === 404) {
74
+ console.log('Prompt not found')
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## License
81
+ MIT
@@ -0,0 +1,71 @@
1
+ export interface VerseraConfig {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ export interface ResolveOptions {
6
+ environment?: 'dev' | 'staging' | 'prod';
7
+ [key: string]: string | undefined;
8
+ }
9
+ export interface ResolveResponse {
10
+ versionId: string;
11
+ template: string;
12
+ variables: string[];
13
+ promptSlug: string;
14
+ environment: string;
15
+ resolvedAt: string;
16
+ }
17
+ export interface PromptInput {
18
+ name: string;
19
+ environment: 'dev' | 'staging' | 'prod';
20
+ template: string;
21
+ message?: string;
22
+ }
23
+ export interface PromptResponse {
24
+ id: string;
25
+ slug: string;
26
+ name: string;
27
+ environment: string;
28
+ status: string;
29
+ versions: VersionResponse[];
30
+ }
31
+ export interface VersionResponse {
32
+ id: string;
33
+ version: number;
34
+ isCurrent: boolean;
35
+ message: string;
36
+ template: string;
37
+ diff: string[];
38
+ savedAt: string;
39
+ }
40
+ export declare class VerseraError extends Error {
41
+ status: number;
42
+ code?: string | undefined;
43
+ constructor(message: string, status: number, code?: string | undefined);
44
+ }
45
+ export declare class Versera {
46
+ private apiKey;
47
+ private baseUrl;
48
+ constructor(config: VerseraConfig);
49
+ private request;
50
+ resolve(promptSlug: string, variables?: Record<string, string>, options?: {
51
+ environment?: 'dev' | 'staging' | 'prod';
52
+ }): Promise<ResolveResponse>;
53
+ push(input: PromptInput): Promise<PromptResponse>;
54
+ list(options?: {
55
+ search?: string;
56
+ environment?: string;
57
+ }): Promise<PromptResponse[]>;
58
+ get(slug: string): Promise<PromptResponse>;
59
+ saveVersion(slug: string, input: {
60
+ template: string;
61
+ message?: string;
62
+ }): Promise<VersionResponse>;
63
+ rollback(slug: string, version: number): Promise<VersionResponse>;
64
+ log(input: {
65
+ versionId: string;
66
+ score?: number;
67
+ metadata?: Record<string, unknown>;
68
+ }): Promise<void>;
69
+ }
70
+ export default Versera;
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Versera = exports.VerseraError = void 0;
4
+ class VerseraError extends Error {
5
+ constructor(message, status, code) {
6
+ super(message);
7
+ this.status = status;
8
+ this.code = code;
9
+ this.name = 'VerseraError';
10
+ }
11
+ }
12
+ exports.VerseraError = VerseraError;
13
+ class Versera {
14
+ constructor(config) {
15
+ if (!config.apiKey) {
16
+ throw new VerseraError('API key is required', 400);
17
+ }
18
+ if (!config.apiKey.startsWith('vrs_')) {
19
+ throw new VerseraError('Invalid API key format. ' +
20
+ 'Key must start with vrs_', 400);
21
+ }
22
+ this.apiKey = config.apiKey;
23
+ this.baseUrl = config.baseUrl ??
24
+ 'https://api.versera.dev';
25
+ }
26
+ async request(path, options = {}) {
27
+ const url = `${this.baseUrl}${path}`;
28
+ const response = await fetch(url, {
29
+ ...options,
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ 'x-api-key': this.apiKey,
33
+ ...options.headers
34
+ }
35
+ });
36
+ if (!response.ok) {
37
+ const error = await response.json()
38
+ .catch(() => ({
39
+ error: 'Unknown error'
40
+ }));
41
+ throw new VerseraError(error.error ?? 'Request failed', response.status);
42
+ }
43
+ if (response.status === 204) {
44
+ return undefined;
45
+ }
46
+ return response.json();
47
+ }
48
+ async resolve(promptSlug, variables, options) {
49
+ const params = new URLSearchParams();
50
+ if (options?.environment) {
51
+ params.set('env', options.environment);
52
+ }
53
+ if (variables) {
54
+ Object.entries(variables).forEach(([key, value]) => {
55
+ params.set(key, value);
56
+ });
57
+ }
58
+ const query = params.toString();
59
+ const path = `/v1/resolve/${promptSlug}` +
60
+ (query ? `?${query}` : '');
61
+ return this.request(path);
62
+ }
63
+ async push(input) {
64
+ return this.request('/v1/prompts', {
65
+ method: 'POST',
66
+ body: JSON.stringify(input)
67
+ });
68
+ }
69
+ async list(options) {
70
+ const params = new URLSearchParams();
71
+ if (options?.search) {
72
+ params.set('search', options.search);
73
+ }
74
+ if (options?.environment) {
75
+ params.set('environment', options.environment);
76
+ }
77
+ const query = params.toString();
78
+ const path = '/v1/prompts' +
79
+ (query ? `?${query}` : '');
80
+ return this.request(path);
81
+ }
82
+ async get(slug) {
83
+ return this.request(`/v1/prompts/${slug}`);
84
+ }
85
+ async saveVersion(slug, input) {
86
+ return this.request(`/v1/prompts/${slug}/versions`, {
87
+ method: 'POST',
88
+ body: JSON.stringify(input)
89
+ });
90
+ }
91
+ async rollback(slug, version) {
92
+ return this.request(`/v1/prompts/${slug}/versions/${version}/rollback`, { method: 'POST' });
93
+ }
94
+ async log(input) {
95
+ return this.request('/v1/prompts/log', {
96
+ method: 'POST',
97
+ body: JSON.stringify(input)
98
+ });
99
+ }
100
+ }
101
+ exports.Versera = Versera;
102
+ exports.default = Versera;
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "versera-app",
3
+ "version": "0.1.0",
4
+ "description": "Official JavaScript SDK for the Versera prompt version control API",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": ["dist"],
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "tsc --watch",
11
+ "test": "node test.js"
12
+ },
13
+ "keywords": [
14
+ "versera", "prompt", "llm",
15
+ "version-control", "ai"
16
+ ],
17
+ "author": "Versera",
18
+ "license": "MIT",
19
+ "devDependencies": {
20
+ "typescript": "^5.0.0"
21
+ }
22
+ }