@a3s-lab/code 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.
@@ -0,0 +1,263 @@
1
+ /**
2
+ * OpenAI-Compatible Types and Conversion Layer
3
+ *
4
+ * This module provides OpenAI-compatible type definitions and conversion
5
+ * functions to allow seamless integration with OpenAI-style APIs.
6
+ *
7
+ * OpenAI Message Format:
8
+ * {
9
+ * role: "user" | "assistant" | "system" | "tool",
10
+ * content: string | ContentPart[],
11
+ * name?: string,
12
+ * tool_calls?: ToolCall[],
13
+ * tool_call_id?: string,
14
+ * }
15
+ */
16
+ // ============================================================================
17
+ // Conversion Functions: OpenAI -> A3S
18
+ // ============================================================================
19
+ /**
20
+ * Convert OpenAI role to A3S MessageRole
21
+ * Since proto now uses OpenAI-compatible string roles, this is a simple passthrough
22
+ */
23
+ export function openAIRoleToA3S(role) {
24
+ switch (role) {
25
+ case 'user':
26
+ return 'user';
27
+ case 'assistant':
28
+ return 'assistant';
29
+ case 'system':
30
+ return 'system';
31
+ case 'tool':
32
+ case 'function':
33
+ return 'tool';
34
+ default:
35
+ return 'user';
36
+ }
37
+ }
38
+ /**
39
+ * Convert OpenAI message to A3S Message
40
+ */
41
+ export function openAIMessageToA3S(msg) {
42
+ let content;
43
+ if (typeof msg.content === 'string') {
44
+ content = msg.content;
45
+ }
46
+ else if (Array.isArray(msg.content)) {
47
+ // Extract text from content parts
48
+ content = msg.content
49
+ .filter((part) => part.type === 'text')
50
+ .map(part => part.text)
51
+ .join('\n');
52
+ }
53
+ else {
54
+ content = '';
55
+ }
56
+ return {
57
+ role: openAIRoleToA3S(msg.role),
58
+ content,
59
+ metadata: msg.name ? { name: msg.name } : undefined,
60
+ };
61
+ }
62
+ /**
63
+ * Convert array of OpenAI messages to A3S Messages
64
+ */
65
+ export function openAIMessagesToA3S(messages) {
66
+ return messages.map(openAIMessageToA3S);
67
+ }
68
+ /**
69
+ * Convert OpenAI tool call to A3S ToolCall
70
+ */
71
+ export function openAIToolCallToA3S(toolCall) {
72
+ return {
73
+ id: toolCall.id,
74
+ name: toolCall.function.name,
75
+ arguments: toolCall.function.arguments,
76
+ };
77
+ }
78
+ // ============================================================================
79
+ // Conversion Functions: A3S -> OpenAI
80
+ // ============================================================================
81
+ /**
82
+ * Convert A3S MessageRole to OpenAI role
83
+ * Since proto now uses OpenAI-compatible string roles, this is a simple passthrough
84
+ */
85
+ export function a3sRoleToOpenAI(role) {
86
+ switch (role) {
87
+ case 'user':
88
+ return 'user';
89
+ case 'assistant':
90
+ return 'assistant';
91
+ case 'system':
92
+ return 'system';
93
+ case 'tool':
94
+ return 'tool';
95
+ default:
96
+ return 'user';
97
+ }
98
+ }
99
+ /**
100
+ * Convert A3S Message to OpenAI message
101
+ */
102
+ export function a3sMessageToOpenAI(msg) {
103
+ const openAIMsg = {
104
+ role: a3sRoleToOpenAI(msg.role),
105
+ content: msg.content,
106
+ };
107
+ if (msg.metadata?.name) {
108
+ openAIMsg.name = msg.metadata.name;
109
+ }
110
+ return openAIMsg;
111
+ }
112
+ /**
113
+ * Convert A3S ToolCall to OpenAI tool call
114
+ */
115
+ export function a3sToolCallToOpenAI(toolCall) {
116
+ return {
117
+ id: toolCall.id,
118
+ type: 'function',
119
+ function: {
120
+ name: toolCall.name,
121
+ arguments: toolCall.arguments,
122
+ },
123
+ };
124
+ }
125
+ /**
126
+ * Convert A3S FinishReason to OpenAI finish_reason
127
+ * Since proto now uses OpenAI-compatible string values, this is a simple passthrough
128
+ */
129
+ export function a3sFinishReasonToOpenAI(reason) {
130
+ switch (reason) {
131
+ case 'stop':
132
+ return 'stop';
133
+ case 'length':
134
+ return 'length';
135
+ case 'tool_calls':
136
+ return 'tool_calls';
137
+ case 'content_filter':
138
+ return 'content_filter';
139
+ default:
140
+ return null;
141
+ }
142
+ }
143
+ /**
144
+ * Convert A3S Usage to OpenAI usage
145
+ */
146
+ export function a3sUsageToOpenAI(usage) {
147
+ if (!usage)
148
+ return undefined;
149
+ return {
150
+ prompt_tokens: usage.promptTokens || 0,
151
+ completion_tokens: usage.completionTokens || 0,
152
+ total_tokens: usage.totalTokens || 0,
153
+ };
154
+ }
155
+ /**
156
+ * Convert A3S GenerateResponse to OpenAI ChatCompletion
157
+ */
158
+ export function a3sResponseToOpenAI(response, model = 'unknown') {
159
+ const message = response.message
160
+ ? a3sMessageToOpenAI(response.message)
161
+ : { role: 'assistant', content: '' };
162
+ // Add tool calls if present
163
+ if (response.toolCalls && response.toolCalls.length > 0) {
164
+ message.tool_calls = response.toolCalls.map(a3sToolCallToOpenAI);
165
+ }
166
+ return {
167
+ id: `chatcmpl-${response.sessionId}`,
168
+ object: 'chat.completion',
169
+ created: Math.floor(Date.now() / 1000),
170
+ model,
171
+ choices: [
172
+ {
173
+ index: 0,
174
+ message,
175
+ finish_reason: a3sFinishReasonToOpenAI(response.finishReason),
176
+ },
177
+ ],
178
+ usage: a3sUsageToOpenAI(response.usage),
179
+ };
180
+ }
181
+ /**
182
+ * Convert A3S GenerateChunk to OpenAI ChatCompletionChunk
183
+ * Since proto now uses OpenAI-compatible string values, conversion is simplified
184
+ */
185
+ export function a3sChunkToOpenAI(chunk, model = 'unknown') {
186
+ const delta = {};
187
+ if (chunk.type === 'content' && chunk.content) {
188
+ delta.content = chunk.content;
189
+ }
190
+ if (chunk.type === 'tool_call' && chunk.toolCall) {
191
+ delta.tool_calls = [
192
+ {
193
+ id: chunk.toolCall.id,
194
+ type: 'function',
195
+ function: {
196
+ name: chunk.toolCall.name,
197
+ arguments: chunk.toolCall.arguments,
198
+ },
199
+ },
200
+ ];
201
+ }
202
+ let finishReason = null;
203
+ if (chunk.type === 'done' || chunk.finishReason) {
204
+ finishReason = chunk.finishReason ? a3sFinishReasonToOpenAI(chunk.finishReason) : 'stop';
205
+ }
206
+ return {
207
+ id: `chatcmpl-${chunk.sessionId}`,
208
+ object: 'chat.completion.chunk',
209
+ created: Math.floor(Date.now() / 1000),
210
+ model,
211
+ choices: [
212
+ {
213
+ index: 0,
214
+ delta,
215
+ finish_reason: finishReason,
216
+ },
217
+ ],
218
+ };
219
+ }
220
+ // ============================================================================
221
+ // Helper Functions
222
+ // ============================================================================
223
+ /**
224
+ * Check if a message uses OpenAI format (lowercase role)
225
+ * Since proto now uses OpenAI-compatible string roles, all messages are in OpenAI format
226
+ */
227
+ export function isOpenAIFormat(msg) {
228
+ const role = msg.role;
229
+ // Both A3S and OpenAI now use the same lowercase role strings
230
+ return ['user', 'assistant', 'system', 'tool', 'function'].includes(role);
231
+ }
232
+ /**
233
+ * Normalize message to A3S format (accepts both OpenAI and A3S formats)
234
+ * Since proto now uses OpenAI-compatible string roles, this is mostly a passthrough
235
+ */
236
+ export function normalizeMessage(msg) {
237
+ if (isOpenAIFormat(msg)) {
238
+ return openAIMessageToA3S(msg);
239
+ }
240
+ return msg;
241
+ }
242
+ /**
243
+ * Normalize array of messages to A3S format
244
+ */
245
+ export function normalizeMessages(messages) {
246
+ return messages.map(normalizeMessage);
247
+ }
248
+ // ============================================================================
249
+ // Type Guards
250
+ // ============================================================================
251
+ /**
252
+ * Type guard for OpenAI text content
253
+ */
254
+ export function isTextContent(content) {
255
+ return content.type === 'text';
256
+ }
257
+ /**
258
+ * Type guard for OpenAI image content
259
+ */
260
+ export function isImageContent(content) {
261
+ return content.type === 'image_url';
262
+ }
263
+ //# sourceMappingURL=openai-compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-compat.js","sourceRoot":"","sources":["../ts/openai-compat.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@a3s-lab/code",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for A3S Code Agent Service",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist",
10
+ "proto"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "clean": "rm -rf dist",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "dependencies": {
20
+ "@grpc/grpc-js": "^1.9.0",
21
+ "@grpc/proto-loader": "^0.7.0"
22
+ },
23
+ "devDependencies": {
24
+ "@vitest/coverage-v8": "^1.6.1",
25
+ "prettier": "^3.0.0",
26
+ "typescript": "^5.3.0",
27
+ "vitest": "^1.0.0"
28
+ },
29
+ "keywords": [
30
+ "a3s",
31
+ "code-agent",
32
+ "grpc",
33
+ "sdk"
34
+ ],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/a3s-lab/a3s"
39
+ },
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ }
43
+ }