llm-rosetta 0.1.0a0__tar.gz
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.
- llm_rosetta-0.1.0a0/LICENSE +21 -0
- llm_rosetta-0.1.0a0/PKG-INFO +173 -0
- llm_rosetta-0.1.0a0/README.md +134 -0
- llm_rosetta-0.1.0a0/pyproject.toml +59 -0
- llm_rosetta-0.1.0a0/setup.cfg +4 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/__init__.py +61 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/auto_detect.py +238 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/__init__.py +21 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/__init__.py +19 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/config_ops.py +330 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/content_ops.py +356 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/converter.py +778 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/message_ops.py +317 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/anthropic/tool_ops.py +298 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/__init__.py +38 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/configs.py +252 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/content.py +257 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/converter.py +279 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/messages.py +194 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/stream_context.py +80 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/base/tools.py +211 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/__init__.py +20 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/config_ops.py +348 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/content_ops.py +418 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/converter.py +900 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/message_ops.py +298 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/google_genai/tool_ops.py +401 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/__init__.py +19 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/config_ops.py +345 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/content_ops.py +285 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/converter.py +781 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/message_ops.py +446 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_chat/tool_ops.py +300 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/__init__.py +19 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/config_ops.py +349 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/content_ops.py +360 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/converter.py +915 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/message_ops.py +402 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/converters/openai_responses/tool_ops.py +437 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/py.typed +0 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/anthropic/__init__.py +75 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/anthropic/request_types.py +236 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/anthropic/response_types.py +134 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/google/__init__.py +96 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/google/content_types.py +290 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/google/request_types.py +315 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/google/response_types.py +317 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/__init__.py +290 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/configs.py +184 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/extensions.py +292 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/helpers.py +111 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/messages.py +336 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/parts.py +302 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/request.py +104 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/response.py +132 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/stream.py +202 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/tools.py +90 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/ir/type_guards.py +243 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/chat/__init__.py +129 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/chat/message_types.py +203 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/chat/request_types.py +252 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/chat/response_types.py +258 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/responses/__init__.py +144 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/responses/request_types.py +360 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta/types/openai/responses/response_types.py +902 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta.egg-info/PKG-INFO +173 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta.egg-info/SOURCES.txt +71 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta.egg-info/dependency_links.txt +1 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta.egg-info/requires.txt +23 -0
- llm_rosetta-0.1.0a0/src/llm_rosetta.egg-info/top_level.txt +1 -0
- llm_rosetta-0.1.0a0/tests/test_auto_detect.py +499 -0
- llm_rosetta-0.1.0a0/tests/test_converters_base.py +942 -0
- llm_rosetta-0.1.0a0/tests/test_ir_types.py +775 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Peng Ding
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: llm-rosetta
|
|
3
|
+
Version: 0.1.0a0
|
|
4
|
+
Summary: LLMIR: A library to convert between different LLM provider API standards using intermediate representation (IR).
|
|
5
|
+
Author-email: Oaklight <oaklight@gmx.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Documentation, https://llmir.readthedocs.io
|
|
8
|
+
Project-URL: Repository, https://github.com/Oaklight/llm-rosetta
|
|
9
|
+
Project-URL: Issues, https://github.com/Oaklight/llm-rosetta/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: typing_extensions>=4.0.0; python_version < "3.11"
|
|
23
|
+
Provides-Extra: openai
|
|
24
|
+
Requires-Dist: openai; extra == "openai"
|
|
25
|
+
Provides-Extra: anthropic
|
|
26
|
+
Requires-Dist: anthropic; extra == "anthropic"
|
|
27
|
+
Provides-Extra: google
|
|
28
|
+
Requires-Dist: google-genai; extra == "google"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: python-dotenv; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
33
|
+
Requires-Dist: ty>=0.0.21; extra == "dev"
|
|
34
|
+
Requires-Dist: build>=1.2.2.post1; extra == "dev"
|
|
35
|
+
Requires-Dist: twine>=6.1.0; extra == "dev"
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Requires-Dist: llm-rosetta[anthropic,dev,google,openai]; extra == "all"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# LLM-Rosetta
|
|
41
|
+
|
|
42
|
+
[](https://badge.fury.io/py/llm-rosetta)
|
|
43
|
+
[](https://badge.fury.io/gh/oaklight%2Fllmir)
|
|
44
|
+
[](https://opensource.org/licenses/MIT)
|
|
45
|
+
[](https://deepwiki.com/Oaklight/llmir)
|
|
46
|
+
|
|
47
|
+
[English Version](README_en.md) | [中文版](README_zh.md)
|
|
48
|
+
|
|
49
|
+
**Large Language Model Rosetta Stone** — A Python library for converting between different LLM provider API formats using a hub-and-spoke architecture with a central IR (Intermediate Representation).
|
|
50
|
+
|
|
51
|
+
## Full Documentation
|
|
52
|
+
|
|
53
|
+
Full documentation is available at:
|
|
54
|
+
|
|
55
|
+
- **English**: [https://llmir.readthedocs.io/en/latest/](https://llmir.readthedocs.io/en/latest/)
|
|
56
|
+
- **中文**: [https://llmir.readthedocs.io/zh-cn/latest/](https://llmir.readthedocs.io/zh-cn/latest/)
|
|
57
|
+
|
|
58
|
+
## The Problem
|
|
59
|
+
|
|
60
|
+
When building applications that work with multiple LLM providers, you face an N² conversion problem — every provider pair requires its own conversion logic. LLM-Rosetta solves this with a hub-and-spoke approach: each provider only needs a single converter to/from the shared IR format.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Provider A ──→ IR ──→ Provider B
|
|
64
|
+
Provider C ──→ IR ──→ Provider D
|
|
65
|
+
... and so on
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Supported Providers
|
|
69
|
+
|
|
70
|
+
| Provider | API Standard | Request | Response | Streaming |
|
|
71
|
+
|----------|-------------|:-------:|:--------:|:---------:|
|
|
72
|
+
| OpenAI | Chat Completions | ✅ | ✅ | ✅ |
|
|
73
|
+
| OpenAI | Responses API | ✅ | ✅ | ✅ |
|
|
74
|
+
| Anthropic | Messages API | ✅ | ✅ | ✅ |
|
|
75
|
+
| Google | GenAI API | ✅ | ✅ | ✅ |
|
|
76
|
+
|
|
77
|
+
## Features
|
|
78
|
+
|
|
79
|
+
- Unified IR format for messages, tool calls, and content parts
|
|
80
|
+
- Bidirectional conversion: requests to provider format, responses from provider format
|
|
81
|
+
- Streaming support with typed stream events
|
|
82
|
+
- Auto-detection of provider from request/response objects
|
|
83
|
+
- Support for text, images, tool calls, and tool results
|
|
84
|
+
- Zero required dependencies (only `typing_extensions`); provider SDKs are optional
|
|
85
|
+
|
|
86
|
+
## Installation
|
|
87
|
+
|
|
88
|
+
### Basic Installation
|
|
89
|
+
|
|
90
|
+
Install the core package (requires **Python >= 3.8**):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install llm-rosetta
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Installing with Provider SDKs
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Individual providers
|
|
100
|
+
pip install llm-rosetta[openai]
|
|
101
|
+
pip install llm-rosetta[anthropic]
|
|
102
|
+
pip install llm-rosetta[google]
|
|
103
|
+
|
|
104
|
+
# All providers
|
|
105
|
+
pip install llm-rosetta[openai,anthropic,google]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Optional Dependencies
|
|
109
|
+
|
|
110
|
+
| Extra | Packages | Description |
|
|
111
|
+
|-------|----------|-------------|
|
|
112
|
+
| `openai` | `openai` | OpenAI Chat Completions & Responses API |
|
|
113
|
+
| `anthropic` | `anthropic` | Anthropic Messages API |
|
|
114
|
+
| `google` | `google-genai` | Google GenAI API |
|
|
115
|
+
|
|
116
|
+
## Quick Start
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from llm_rosetta import OpenAIChatConverter, AnthropicConverter
|
|
120
|
+
|
|
121
|
+
# Create converters
|
|
122
|
+
openai_conv = OpenAIChatConverter()
|
|
123
|
+
anthropic_conv = AnthropicConverter()
|
|
124
|
+
|
|
125
|
+
# Convert an OpenAI response to IR, then to Anthropic format
|
|
126
|
+
ir_messages = openai_conv.response_from_provider(openai_response)
|
|
127
|
+
anthropic_request = anthropic_conv.request_to_provider(ir_messages)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Auto-Detection
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from llm_rosetta import convert, detect_provider
|
|
134
|
+
|
|
135
|
+
# Automatically detect provider and convert
|
|
136
|
+
provider = detect_provider(some_response)
|
|
137
|
+
ir_messages = convert(some_response, direction="from_provider")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Cross-Provider Conversation
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from llm_rosetta import OpenAIChatConverter, GoogleGenAIConverter
|
|
144
|
+
from llm_rosetta.types.ir import Message, ContentPart
|
|
145
|
+
|
|
146
|
+
# Shared IR message history
|
|
147
|
+
ir_messages = []
|
|
148
|
+
|
|
149
|
+
# Turn 1: Ask OpenAI
|
|
150
|
+
ir_messages.append(Message(role="user", content=[ContentPart(type="text", text="Hello!")]))
|
|
151
|
+
openai_request = openai_conv.request_to_provider({"messages": ir_messages})
|
|
152
|
+
openai_response = openai_client.chat.completions.create(**openai_request)
|
|
153
|
+
ir_messages.extend(openai_conv.response_from_provider(openai_response))
|
|
154
|
+
|
|
155
|
+
# Turn 2: Continue with Google — full context preserved
|
|
156
|
+
google_request = google_conv.request_to_provider({"messages": ir_messages})
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Related Projects
|
|
160
|
+
|
|
161
|
+
LLM-Rosetta is part of the ToolRegistry ecosystem:
|
|
162
|
+
|
|
163
|
+
- **[ToolRegistry](https://github.com/Oaklight/ToolRegistry)** — Tool registration and management for LLM function calling
|
|
164
|
+
- **[ToolRegistry Hub](https://github.com/Oaklight/toolregistry-hub)** — Ready-to-use tool collection
|
|
165
|
+
- **[ToolRegistry Server](https://github.com/Oaklight/toolregistry-server)** — OpenAPI and MCP server adapters
|
|
166
|
+
|
|
167
|
+
## Contributing
|
|
168
|
+
|
|
169
|
+
Contributions are welcome! Please visit the [GitHub repository](https://github.com/Oaklight/llmir) to get started.
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# LLM-Rosetta
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/llm-rosetta)
|
|
4
|
+
[](https://badge.fury.io/gh/oaklight%2Fllmir)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://deepwiki.com/Oaklight/llmir)
|
|
7
|
+
|
|
8
|
+
[English Version](README_en.md) | [中文版](README_zh.md)
|
|
9
|
+
|
|
10
|
+
**Large Language Model Rosetta Stone** — A Python library for converting between different LLM provider API formats using a hub-and-spoke architecture with a central IR (Intermediate Representation).
|
|
11
|
+
|
|
12
|
+
## Full Documentation
|
|
13
|
+
|
|
14
|
+
Full documentation is available at:
|
|
15
|
+
|
|
16
|
+
- **English**: [https://llmir.readthedocs.io/en/latest/](https://llmir.readthedocs.io/en/latest/)
|
|
17
|
+
- **中文**: [https://llmir.readthedocs.io/zh-cn/latest/](https://llmir.readthedocs.io/zh-cn/latest/)
|
|
18
|
+
|
|
19
|
+
## The Problem
|
|
20
|
+
|
|
21
|
+
When building applications that work with multiple LLM providers, you face an N² conversion problem — every provider pair requires its own conversion logic. LLM-Rosetta solves this with a hub-and-spoke approach: each provider only needs a single converter to/from the shared IR format.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Provider A ──→ IR ──→ Provider B
|
|
25
|
+
Provider C ──→ IR ──→ Provider D
|
|
26
|
+
... and so on
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Supported Providers
|
|
30
|
+
|
|
31
|
+
| Provider | API Standard | Request | Response | Streaming |
|
|
32
|
+
|----------|-------------|:-------:|:--------:|:---------:|
|
|
33
|
+
| OpenAI | Chat Completions | ✅ | ✅ | ✅ |
|
|
34
|
+
| OpenAI | Responses API | ✅ | ✅ | ✅ |
|
|
35
|
+
| Anthropic | Messages API | ✅ | ✅ | ✅ |
|
|
36
|
+
| Google | GenAI API | ✅ | ✅ | ✅ |
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
- Unified IR format for messages, tool calls, and content parts
|
|
41
|
+
- Bidirectional conversion: requests to provider format, responses from provider format
|
|
42
|
+
- Streaming support with typed stream events
|
|
43
|
+
- Auto-detection of provider from request/response objects
|
|
44
|
+
- Support for text, images, tool calls, and tool results
|
|
45
|
+
- Zero required dependencies (only `typing_extensions`); provider SDKs are optional
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
### Basic Installation
|
|
50
|
+
|
|
51
|
+
Install the core package (requires **Python >= 3.8**):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install llm-rosetta
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Installing with Provider SDKs
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Individual providers
|
|
61
|
+
pip install llm-rosetta[openai]
|
|
62
|
+
pip install llm-rosetta[anthropic]
|
|
63
|
+
pip install llm-rosetta[google]
|
|
64
|
+
|
|
65
|
+
# All providers
|
|
66
|
+
pip install llm-rosetta[openai,anthropic,google]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Optional Dependencies
|
|
70
|
+
|
|
71
|
+
| Extra | Packages | Description |
|
|
72
|
+
|-------|----------|-------------|
|
|
73
|
+
| `openai` | `openai` | OpenAI Chat Completions & Responses API |
|
|
74
|
+
| `anthropic` | `anthropic` | Anthropic Messages API |
|
|
75
|
+
| `google` | `google-genai` | Google GenAI API |
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from llm_rosetta import OpenAIChatConverter, AnthropicConverter
|
|
81
|
+
|
|
82
|
+
# Create converters
|
|
83
|
+
openai_conv = OpenAIChatConverter()
|
|
84
|
+
anthropic_conv = AnthropicConverter()
|
|
85
|
+
|
|
86
|
+
# Convert an OpenAI response to IR, then to Anthropic format
|
|
87
|
+
ir_messages = openai_conv.response_from_provider(openai_response)
|
|
88
|
+
anthropic_request = anthropic_conv.request_to_provider(ir_messages)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Auto-Detection
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from llm_rosetta import convert, detect_provider
|
|
95
|
+
|
|
96
|
+
# Automatically detect provider and convert
|
|
97
|
+
provider = detect_provider(some_response)
|
|
98
|
+
ir_messages = convert(some_response, direction="from_provider")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Cross-Provider Conversation
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from llm_rosetta import OpenAIChatConverter, GoogleGenAIConverter
|
|
105
|
+
from llm_rosetta.types.ir import Message, ContentPart
|
|
106
|
+
|
|
107
|
+
# Shared IR message history
|
|
108
|
+
ir_messages = []
|
|
109
|
+
|
|
110
|
+
# Turn 1: Ask OpenAI
|
|
111
|
+
ir_messages.append(Message(role="user", content=[ContentPart(type="text", text="Hello!")]))
|
|
112
|
+
openai_request = openai_conv.request_to_provider({"messages": ir_messages})
|
|
113
|
+
openai_response = openai_client.chat.completions.create(**openai_request)
|
|
114
|
+
ir_messages.extend(openai_conv.response_from_provider(openai_response))
|
|
115
|
+
|
|
116
|
+
# Turn 2: Continue with Google — full context preserved
|
|
117
|
+
google_request = google_conv.request_to_provider({"messages": ir_messages})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Related Projects
|
|
121
|
+
|
|
122
|
+
LLM-Rosetta is part of the ToolRegistry ecosystem:
|
|
123
|
+
|
|
124
|
+
- **[ToolRegistry](https://github.com/Oaklight/ToolRegistry)** — Tool registration and management for LLM function calling
|
|
125
|
+
- **[ToolRegistry Hub](https://github.com/Oaklight/toolregistry-hub)** — Ready-to-use tool collection
|
|
126
|
+
- **[ToolRegistry Server](https://github.com/Oaklight/toolregistry-server)** — OpenAPI and MCP server adapters
|
|
127
|
+
|
|
128
|
+
## Contributing
|
|
129
|
+
|
|
130
|
+
Contributions are welcome! Please visit the [GitHub repository](https://github.com/Oaklight/llmir) to get started.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "llm-rosetta"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
authors = [{ name = "Oaklight", email = "oaklight@gmx.com" }]
|
|
9
|
+
description = "LLMIR: A library to convert between different LLM provider API standards using intermediate representation (IR)."
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
license = "MIT"
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
]
|
|
24
|
+
dependencies = ['typing_extensions>=4.0.0; python_version < "3.11"']
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
openai = ["openai"]
|
|
28
|
+
anthropic = ["anthropic"]
|
|
29
|
+
google = ["google-genai"]
|
|
30
|
+
dev = [
|
|
31
|
+
"python-dotenv",
|
|
32
|
+
"pytest",
|
|
33
|
+
"pytest-cov",
|
|
34
|
+
"ty>=0.0.21",
|
|
35
|
+
"build>=1.2.2.post1",
|
|
36
|
+
"twine>=6.1.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
all = ["llm-rosetta[openai,anthropic,google,dev]"]
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Documentation = "https://llmir.readthedocs.io"
|
|
43
|
+
Repository = "https://github.com/Oaklight/llm-rosetta"
|
|
44
|
+
Issues = "https://github.com/Oaklight/llm-rosetta/issues"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["src"]
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
"llm_rosetta" = ["py.typed"]
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.dynamic]
|
|
53
|
+
version = { attr = "llm_rosetta.__version__" }
|
|
54
|
+
|
|
55
|
+
[tool.ty.environment]
|
|
56
|
+
python-version = "3.10"
|
|
57
|
+
|
|
58
|
+
[tool.ty.src]
|
|
59
|
+
include = ["src", "tests"]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
LLMIR
|
|
3
|
+
|
|
4
|
+
一个用于在不同LLM provider之间转换消息格式的库
|
|
5
|
+
A library for converting message formats between different LLM providers
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .auto_detect import (
|
|
9
|
+
ProviderType,
|
|
10
|
+
convert,
|
|
11
|
+
detect_provider,
|
|
12
|
+
get_converter_for_provider,
|
|
13
|
+
)
|
|
14
|
+
from .converters import (
|
|
15
|
+
AnthropicConverter,
|
|
16
|
+
BaseConverter,
|
|
17
|
+
GoogleConverter,
|
|
18
|
+
GoogleGenAIConverter,
|
|
19
|
+
OpenAIChatConverter,
|
|
20
|
+
OpenAIResponsesConverter,
|
|
21
|
+
)
|
|
22
|
+
from .types.ir import (
|
|
23
|
+
ContentPart,
|
|
24
|
+
ExtensionItem,
|
|
25
|
+
IRInput,
|
|
26
|
+
IRInputSimple,
|
|
27
|
+
Message,
|
|
28
|
+
ToolChoice,
|
|
29
|
+
ToolDefinition,
|
|
30
|
+
is_extension_item,
|
|
31
|
+
is_message,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__version__ = "0.1.0a0"
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
# 核心类型 Core types
|
|
38
|
+
"IRInput",
|
|
39
|
+
"IRInputSimple",
|
|
40
|
+
"Message",
|
|
41
|
+
"ContentPart",
|
|
42
|
+
"ExtensionItem",
|
|
43
|
+
"ToolDefinition",
|
|
44
|
+
"ToolChoice",
|
|
45
|
+
"ProviderType",
|
|
46
|
+
# 类型守卫函数 Type guard functions
|
|
47
|
+
"is_message",
|
|
48
|
+
"is_extension_item",
|
|
49
|
+
"is_part_type",
|
|
50
|
+
# 转换器 Converters
|
|
51
|
+
"BaseConverter",
|
|
52
|
+
"OpenAIChatConverter",
|
|
53
|
+
"AnthropicConverter",
|
|
54
|
+
"GoogleGenAIConverter",
|
|
55
|
+
"GoogleConverter",
|
|
56
|
+
"OpenAIResponsesConverter",
|
|
57
|
+
# 自动检测和转换 Auto-detection and conversion
|
|
58
|
+
"detect_provider",
|
|
59
|
+
"get_converter_for_provider",
|
|
60
|
+
"convert",
|
|
61
|
+
]
|