rosetta-ai 0.1.0 → 1.0.1

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
@@ -1,2 +1,253 @@
1
- # rosetta-js
2
- The translation layer for LLM provider messages
1
+ # Rosetta
2
+
3
+ The translation layer for LLM provider messages.
4
+
5
+ Rosetta converts messages between different LLM providers using a standardized intermediate format (GenAI). Just pass in messages from any provider—OpenAI, Anthropic, Google, or even custom formats—and get consistent output. No manual mapping required.
6
+
7
+ ## Features
8
+
9
+ - 🔄 Convert messages from any supported provider to a unified GenAI format
10
+ - 🔀 Convert GenAI messages to any supported provider format
11
+ - 🪄 **Universal fallback** - Pass messages from *any* LLM provider or framework, even unsupported ones, and we'll attempt best-effort conversion
12
+ - 🔍 Automatic provider detection when source is not specified
13
+ - 📝 Full TypeScript support with strict types
14
+ - ✅ Runtime validation with Zod schemas
15
+ - 💾 Preserve provider-specific metadata for lossless round-trips
16
+ - 🌐 Works in Node.js and browsers
17
+ - 🌳 Tree-shakeable ESM build
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install rosetta-ai
23
+ # or
24
+ pnpm add rosetta-ai
25
+ # or
26
+ yarn add rosetta-ai
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```typescript
32
+ import { translate, Provider } from "rosetta-ai";
33
+
34
+ // Your messages
35
+ const messages = [
36
+ { role: "user", parts: [{ type: "text", content: "Hello!" }] },
37
+ ];
38
+
39
+ // Convert to GenAI (intermediate format) - auto-infers source
40
+ const { messages: genaiMessages } = translate(messages);
41
+
42
+ // Specify source provider explicitly
43
+ const { messages: result } = translate(messages, {
44
+ from: Provider.GenAI,
45
+ to: Provider.GenAI,
46
+ });
47
+ ```
48
+
49
+ ## API
50
+
51
+ ### translate / safeTranslate
52
+
53
+ ```typescript
54
+ import { translate, safeTranslate, Provider } from "rosetta-ai";
55
+
56
+ // translate throws on error
57
+ const { messages, system } = translate(inputMessages, {
58
+ from: Provider.GenAI, // Source provider (optional, auto-inferred if not provided)
59
+ to: Provider.GenAI, // Target provider (optional, defaults to GenAI)
60
+ system: systemInstructions, // Separated system instructions (optional)
61
+ direction: "input", // "input" (default) or "output" - affects role interpretation (e.g. "user" vs "assistant")
62
+ });
63
+
64
+ // safeTranslate returns error instead of throwing
65
+ const result = safeTranslate(inputMessages);
66
+
67
+ if (result.error) {
68
+ console.error("Translation failed:", result.error.message);
69
+ } else {
70
+ console.log("Translated:", result.messages);
71
+ }
72
+ ```
73
+
74
+ ### Input Flexibility
75
+
76
+ Messages and system instructions accept flexible input formats:
77
+
78
+ ```typescript
79
+ // Messages: string or array of provider messages
80
+ translate("Hello!"); // Simple string
81
+ translate([{ role: "user", content: "Hello!" }]); // Provider message array
82
+
83
+ // System: string, single object, or array
84
+ translate(messages, { system: "You are helpful" });
85
+ translate(messages, { system: { type: "text", content: "Be helpful" } });
86
+ translate(messages, { system: [{ type: "text", content: "Instructions" }] });
87
+ ```
88
+
89
+ Each provider validates messages with its own Zod schema at runtime.
90
+
91
+ ### Translator Class
92
+
93
+ For advanced configuration, use the `Translator` class:
94
+
95
+ ```typescript
96
+ import { Translator, Provider } from "rosetta-ai";
97
+
98
+ const translator = new Translator({
99
+ // Custom priority order for provider inference
100
+ inferPriority: [Provider.GenAI],
101
+ });
102
+
103
+ const { messages } = translator.translate(inputMessages);
104
+ ```
105
+
106
+ ## Supported Providers
107
+
108
+ | Provider | Status | toGenAI | fromGenAI |
109
+ | ------------------ | ------------ | ------- | --------- |
110
+ | GenAI | ✅ Available | ✅ | ✅ |
111
+ | Promptl | ✅ Available | ✅ | ✅ |
112
+ | VercelAI | ✅ Available | ✅ | ✅ |
113
+ | OpenAI Completions | ✅ Available | ✅ | - |
114
+ | OpenAI Responses | ✅ Available | ✅ | - |
115
+ | Anthropic | ✅ Available | ✅ | - |
116
+ | Google Gemini | ✅ Available | ✅ | - |
117
+ | Compat | ✅ Available | ✅ | - |
118
+
119
+ ### Universal Compatibility
120
+
121
+ The **Compat** provider is a universal fallback that handles messages from *any* LLM provider—even ones not explicitly supported. When you call `translate()` without specifying a source provider, Rosetta tries to match against known provider schemas. If none match, it automatically falls back to Compat, which:
122
+
123
+ - Normalizes field names across conventions (`tool_calls`, `toolCalls`, `tool-calls` all work)
124
+ - Detects common patterns: roles, content arrays, tool calls, images, reasoning, etc.
125
+ - Handles formats from Cohere, Mistral, Ollama, AWS Bedrock, LangChain, and more
126
+ - Preserves unrecognized data so nothing is lost
127
+
128
+ ```typescript
129
+ // Works with any provider - no need to specify the source
130
+ const weirdMessages = [
131
+ { role: "user", content: "Hello" },
132
+ { role: "assistant", tool_calls: [{ id: "1", function: { name: "search", arguments: "{}" } }] },
133
+ ];
134
+
135
+ const { messages } = translate(weirdMessages); // Just works™
136
+ ```
137
+
138
+ More providers will be added. See [AGENTS.md](./AGENTS.md) for contribution guidelines.
139
+
140
+ ## GenAI Format
141
+
142
+ GenAI is the intermediate format used for translation. It provides a unified representation of LLM messages:
143
+
144
+ ```typescript
145
+ import type { GenAIMessage, GenAIPart, GenAISystem } from "rosetta-ai";
146
+
147
+ const message: GenAIMessage = {
148
+ role: "user",
149
+ parts: [
150
+ { type: "text", content: "Hello!" },
151
+ { type: "blob", modality: "image", content: "base64...", mime_type: "image/png" },
152
+ ],
153
+ };
154
+
155
+ const system: GenAISystem = [
156
+ { type: "text", content: "You are a helpful assistant." },
157
+ ];
158
+ ```
159
+
160
+ ### Part Types
161
+
162
+ - `text` - Plain text content
163
+ - `blob` - Binary data (base64 encoded)
164
+ - `file` - File reference by ID
165
+ - `uri` - URI reference
166
+ - `reasoning` - Model reasoning/thinking
167
+ - `tool_call` - Tool call request
168
+ - `tool_call_response` - Tool call result
169
+ - `generic` - Custom/extensible part type
170
+
171
+ ### Provider Metadata
172
+
173
+ All GenAI entities support `_provider_metadata` to preserve provider-specific data:
174
+
175
+ ```typescript
176
+ const message: GenAIMessage = {
177
+ role: "assistant",
178
+ parts: [{ type: "text", content: "Hello!" }],
179
+ _provider_metadata: {
180
+ genai: { custom: "data" },
181
+ },
182
+ };
183
+ ```
184
+
185
+ ## Examples
186
+
187
+ Check out the [examples](./examples) folder for usage examples (requires building the package first).
188
+
189
+ ## Development
190
+
191
+ ### Prerequisites
192
+
193
+ - Node.js >= 20.0.0
194
+ - pnpm >= 10.0.0
195
+
196
+ ### Setup
197
+
198
+ ```bash
199
+ # Clone the repository
200
+ git clone https://github.com/latitude-dev/rosetta-ts.git
201
+ cd rosetta-ts
202
+
203
+ # Install dependencies
204
+ pnpm install
205
+ ```
206
+
207
+ ### Commands
208
+
209
+ | Command | Description |
210
+ | -------------- | -------------------------------------- |
211
+ | `pnpm install` | Install dependencies |
212
+ | `pnpm build` | Build the package |
213
+ | `pnpm dev` | Build in watch mode |
214
+ | `pnpm test` | Run tests |
215
+ | `pnpm lint` | Check for lint, format and type errors |
216
+ | `pnpm format` | Format code and fixable lint errors |
217
+
218
+ ## Adding a New Provider
219
+
220
+ The [AGENTS.md](./AGENTS.md) file contains extensively curated guidelines for AI coding agents, including detailed step-by-step instructions for adding new providers. The easiest way to add a provider is to give a coding agent (like Cursor, Claude, or similar) the provider's message schema along with a prompt like this:
221
+
222
+ ```
223
+ Based on the attached [Provider Name] message schema (see attached), add a
224
+ [Provider Name] provider to the package. Follow ALL the guidelines in AGENTS.md.
225
+
226
+ - This provider will be source-only / source and target.
227
+ - This provider does / does not separate system instructions from the message list.
228
+ - Build a unified schema if the provider has separate types for input and output.
229
+ ```
230
+
231
+ The schema can be in any format the agent can understand: TypeScript SDK types, JSON Schema, OpenAPI definitions, Python types, or even API documentation.
232
+
233
+ **Example prompt for adding Google Gemini:**
234
+
235
+ ```
236
+ Based on the attached Google Gemini TypeScript SDK types (specifically the
237
+ messages and system instructions for the GenerateContent function), add a
238
+ Google provider to the package. Follow ALL the guidelines in AGENTS.md.
239
+
240
+ - This provider will be source-only, not a target.
241
+ - This provider separates system instructions from the message list.
242
+ - Build a unified schema since the provider has different types for input and output.
243
+ ```
244
+
245
+ The agent will handle creating the schema files, implementing the specification, registering the provider, writing tests, and updating documentation—all following the project's conventions.
246
+
247
+ ## License
248
+
249
+ MIT - see [LICENSE](./LICENSE) for details.
250
+
251
+ ## Contributing
252
+
253
+ Contributions are welcome! Please read [AGENTS.md](./AGENTS.md) for detailed contribution guidelines, including architecture decisions, coding standards, and the step-by-step process for adding new providers.