@blastlauncher/protocol 0.0.0-stage → 3.0.0-alpha.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,57 @@
1
+ // Only attachment data needs a non-JSON representation. Tag strings too, so
2
+ // authored data can never be confused with an encoded value.
3
+ export function encodeModelRequest(request) {
4
+ return JSON.parse(JSON.stringify({
5
+ ...request,
6
+ messages: request.messages?.map((message) => ({
7
+ ...message,
8
+ content: typeof message.content === "string"
9
+ ? message.content
10
+ : message.content.map((part) => {
11
+ if (part.type !== "file")
12
+ return part;
13
+ const data = part.data;
14
+ const encoded = typeof data === "string"
15
+ ? { kind: "string", value: data }
16
+ : data instanceof URL
17
+ ? { kind: "url", value: data.href }
18
+ : {
19
+ kind: data instanceof ArrayBuffer ? "buffer" : "bytes",
20
+ value: Array.from(new Uint8Array(data instanceof ArrayBuffer ? data : data.buffer, data instanceof ArrayBuffer ? 0 : data.byteOffset, data.byteLength)),
21
+ };
22
+ return { ...part, data: encoded };
23
+ }),
24
+ })),
25
+ }));
26
+ }
27
+ export function decodeModelRequest(value) {
28
+ const request = value;
29
+ return {
30
+ ...request,
31
+ ...(request.messages === undefined
32
+ ? {}
33
+ : {
34
+ messages: request.messages.map((message) => ({
35
+ ...message,
36
+ content: typeof message.content === "string"
37
+ ? message.content
38
+ : message.content.map((part) => {
39
+ if (part.type !== "file")
40
+ return part;
41
+ const data = part.data;
42
+ if (data.kind === "string" && typeof data.value === "string")
43
+ return { ...part, data: data.value };
44
+ if (data.kind === "url" && typeof data.value === "string")
45
+ return { ...part, data: new URL(data.value) };
46
+ if ((data.kind === "bytes" || data.kind === "buffer") &&
47
+ Array.isArray(data.value) &&
48
+ data.value.every((n) => Number.isInteger(n) && n >= 0 && n <= 255)) {
49
+ const bytes = new Uint8Array(data.value);
50
+ return { ...part, data: data.kind === "buffer" ? bytes.buffer : bytes };
51
+ }
52
+ throw new Error("Invalid encoded attachment data");
53
+ }),
54
+ })),
55
+ }),
56
+ };
57
+ }
@@ -0,0 +1,236 @@
1
+ import type { JsonValue } from "./messages.js";
2
+ export type GetModels<TIcon = unknown> = () => RegisteredModel<TIcon>[] | Promise<RegisteredModel<TIcon>[]>;
3
+ export type RegisteredModel<TIcon = unknown> = {
4
+ id: string;
5
+ title: string;
6
+ isLocal?: boolean;
7
+ icon?: TIcon;
8
+ description?: string;
9
+ capabilities?: {
10
+ systemMessage?: {
11
+ supported: boolean;
12
+ };
13
+ temperature?: {
14
+ supported: boolean;
15
+ };
16
+ vision?: {
17
+ mediaTypes: Array<"image/png" | "image/jpeg" | "image/webp" | "image/gif">;
18
+ };
19
+ tools?: {
20
+ supported: boolean;
21
+ };
22
+ streaming?: {
23
+ supported: boolean;
24
+ };
25
+ reasoningEffort?: {
26
+ supported: boolean;
27
+ options: string[];
28
+ default: string;
29
+ };
30
+ };
31
+ contextWindow?: number;
32
+ sizeInBytes?: number;
33
+ };
34
+ export type ModelAssistantMessageContent = Array<{
35
+ type: "text";
36
+ text: string;
37
+ } | {
38
+ type: "file";
39
+ data: string | Uint8Array | ArrayBuffer | URL;
40
+ mediaType: string;
41
+ } | {
42
+ type: "reasoning";
43
+ text: string;
44
+ } | {
45
+ type: "tool-call";
46
+ toolCallId: string;
47
+ toolName: string;
48
+ input: unknown;
49
+ }>;
50
+ export type ModelFullStream = ReadableStream<ModelStreamPart> | AsyncIterable<ModelStreamPart>;
51
+ export type ModelMessage = {
52
+ role: "system";
53
+ content: string;
54
+ } | {
55
+ role: "user";
56
+ content: ModelUserMessageContent;
57
+ } | {
58
+ role: "assistant";
59
+ content: ModelAssistantMessageContent;
60
+ } | {
61
+ role: "tool";
62
+ content: Array<{
63
+ type: "tool-result";
64
+ toolCallId: string;
65
+ toolName: string;
66
+ input?: unknown;
67
+ output: {
68
+ type: "json";
69
+ value: JsonValue;
70
+ };
71
+ }>;
72
+ };
73
+ export type ModelProviderOptions = Record<string, Record<string, unknown>> & {
74
+ raycast: Record<string, unknown> & {
75
+ locale: string;
76
+ currentDate: string;
77
+ reasoningEffort?: string;
78
+ sessionId: string;
79
+ };
80
+ };
81
+ export type ModelRequest = {
82
+ system?: string;
83
+ messages?: ModelMessage[];
84
+ temperature?: number;
85
+ tools?: ModelToolSet;
86
+ toolChoice?: "auto" | "required";
87
+ providerOptions: ModelProviderOptions;
88
+ };
89
+ export type ModelStream = ModelFullStream | ModelTextStream | {
90
+ fullStream: ModelFullStream;
91
+ } | {
92
+ textStream: ModelTextStream;
93
+ };
94
+ export type ModelStreamPart = {
95
+ type: "text-start";
96
+ id: string;
97
+ [key: string]: unknown;
98
+ } | {
99
+ type: "text-end";
100
+ id: string;
101
+ [key: string]: unknown;
102
+ } | {
103
+ type: "text";
104
+ text: string;
105
+ } | {
106
+ type: "text-delta";
107
+ id?: string;
108
+ text?: string;
109
+ textDelta?: string;
110
+ [key: string]: unknown;
111
+ } | {
112
+ type: "reasoning-start";
113
+ id: string;
114
+ [key: string]: unknown;
115
+ } | {
116
+ type: "reasoning-end";
117
+ id: string;
118
+ [key: string]: unknown;
119
+ } | {
120
+ type: "reasoning";
121
+ text: string;
122
+ } | {
123
+ type: "reasoning-delta";
124
+ id?: string;
125
+ text?: string;
126
+ textDelta?: string;
127
+ [key: string]: unknown;
128
+ } | {
129
+ type: "source";
130
+ sourceType: "url";
131
+ id: string;
132
+ url: string;
133
+ title?: string;
134
+ [key: string]: unknown;
135
+ } | {
136
+ type: "source";
137
+ sourceType: "document";
138
+ id: string;
139
+ mediaType: string;
140
+ title?: string;
141
+ filename?: string;
142
+ [key: string]: unknown;
143
+ } | {
144
+ type: "file";
145
+ file: unknown;
146
+ } | {
147
+ type: "tool-call-streaming-start";
148
+ toolCallId: string;
149
+ toolName: string;
150
+ } | {
151
+ type: "tool-call-delta";
152
+ toolCallId: string;
153
+ toolName: string;
154
+ argsTextDelta: string;
155
+ } | {
156
+ type: "tool-input-start";
157
+ id: string;
158
+ toolName: string;
159
+ [key: string]: unknown;
160
+ } | {
161
+ type: "tool-input-end";
162
+ id: string;
163
+ [key: string]: unknown;
164
+ } | {
165
+ type: "tool-input-delta";
166
+ id: string;
167
+ delta: string;
168
+ [key: string]: unknown;
169
+ } | {
170
+ type: "tool-input-error";
171
+ id?: string;
172
+ error?: unknown;
173
+ [key: string]: unknown;
174
+ } | {
175
+ type: "tool-call";
176
+ toolCallId: string;
177
+ toolName: string;
178
+ input: unknown;
179
+ } | {
180
+ type: "tool-result";
181
+ toolCallId: string;
182
+ toolName: string;
183
+ input?: unknown;
184
+ output?: unknown;
185
+ } | {
186
+ type: "tool-error";
187
+ toolCallId: string;
188
+ toolName: string;
189
+ input?: unknown;
190
+ error: unknown;
191
+ [key: string]: unknown;
192
+ } | {
193
+ type: "tool-output-denied";
194
+ toolCallId: string;
195
+ toolName: string;
196
+ [key: string]: unknown;
197
+ } | {
198
+ type: "tool-approval-request";
199
+ approvalId: string;
200
+ toolCall: unknown;
201
+ [key: string]: unknown;
202
+ } | {
203
+ type: "finish";
204
+ finishReason: "stop" | "length" | "content-filter" | "tool-calls" | "error" | "other" | "unknown";
205
+ totalUsage?: {
206
+ inputTokens?: number;
207
+ outputTokens?: number;
208
+ totalTokens?: number;
209
+ [key: string]: unknown;
210
+ };
211
+ } | {
212
+ type: "error";
213
+ error: unknown;
214
+ } | {
215
+ type: "abort";
216
+ reason?: unknown;
217
+ } | {
218
+ type: "start" | "stream-start" | "response-metadata" | "start-step" | "finish-step" | "reasoning-part-finish" | "step-start" | "raw";
219
+ [key: string]: unknown;
220
+ };
221
+ export type ModelTextStream = ReadableStream<string> | AsyncIterable<string>;
222
+ export type ModelTool = {
223
+ type?: "function";
224
+ description?: string;
225
+ inputSchema?: unknown;
226
+ };
227
+ export type ModelToolSet = Record<string, ModelTool>;
228
+ export type ModelUserMessageContent = Array<{
229
+ type: "text";
230
+ text: string;
231
+ } | {
232
+ type: "file";
233
+ data: string | Uint8Array | ArrayBuffer | URL;
234
+ mediaType: string;
235
+ }>;
236
+ export type StreamCompletion<TIcon = unknown> = (model: RegisteredModel<TIcon>, request: ModelRequest) => ModelStream | Promise<ModelStream>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,22 @@
1
1
  {
2
2
  "name": "@blastlauncher/protocol",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "type": "module",
4
+ "exports": {
5
+ ".": {
6
+ "types": "./dist/index.d.ts",
7
+ "import": "./dist/index.js",
8
+ "default": "./dist/index.js"
9
+ }
10
+ },
11
+ "version": "3.0.0-alpha.0",
12
+ "license": "MIT",
13
+ "engines": {
14
+ "node": ">=24.20.0"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "schema",
19
+ "LICENSE",
20
+ "README.md"
21
+ ]
22
+ }