vino-sdk 0.0.0-stage → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Vinh Bui
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.
package/README.md CHANGED
@@ -1,3 +1,159 @@
1
- # Temporary Holding Version
1
+ # vino-sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Zero-dependency TypeScript client for the
4
+ [vino-backend](https://github.com/vinhbt241/vino-backend) HTTP API. Stream runs,
5
+ continue conversations, and read transcripts through one ergonomic client —
6
+ no hand-rolled SSE parsing or error mapping.
7
+
8
+ - **Runs on**: Node 18+, browsers, Deno, Bun (anything with `fetch`).
9
+ - **Dependencies**: none at runtime.
10
+ - **Types**: strict, handwritten from the server's documented wire contract.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install vino-sdk
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ The server defaults to `http://127.0.0.1:8080`.
21
+
22
+ ```ts
23
+ import { Vino } from "vino-sdk";
24
+
25
+ const vino = new Vino();
26
+
27
+ // One-shot: get the final answer and tool activity.
28
+ const result = await vino.run({
29
+ messages: [{ role: "user", content: "List the files in the current directory." }],
30
+ });
31
+
32
+ console.log(result.finalMessage.content);
33
+ console.log(result.text); // same text, streamed deltas concatenated
34
+ console.log(result.toolResults); // [{ id, name, result }]
35
+ console.log(result.conversationId);
36
+ ```
37
+
38
+ ### Stream a run
39
+
40
+ `stream()` returns an async generator of typed, discriminated events:
41
+
42
+ ```ts
43
+ for await (const event of vino.stream({
44
+ messages: [{ role: "user", content: "List the files in ." }],
45
+ })) {
46
+ switch (event.type) {
47
+ case "run_started": break;
48
+ case "text_delta": process.stdout.write(event.text); break;
49
+ case "tool_call_started": console.log("calling", event.name, event.arguments); break;
50
+ case "tool_result": console.log("result", event.result); break;
51
+ case "run_finished": console.log("done", event.finalMessage); break;
52
+ case "error": console.error(event.error); break;
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### Conversations
58
+
59
+ ```ts
60
+ // List, newest first (paginated).
61
+ const page = await vino.listConversations({ limit: 20, order: "desc" });
62
+ console.log(page.nextCursor); // null on the last page
63
+
64
+ // Read a transcript.
65
+ const conversation = await vino.getConversation("12");
66
+
67
+ // Continue a conversation: pass conversationId on a new run/resume.
68
+ const next = await vino.run({
69
+ conversationId: "12",
70
+ messages: [{ role: "user", content: "What next?" }],
71
+ });
72
+ ```
73
+
74
+ ### Health
75
+
76
+ ```ts
77
+ await vino.health(); // { ok: true }
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ ```ts
83
+ const vino = new Vino({
84
+ baseUrl: "http://127.0.0.1:8080", // default
85
+ headers: { "x-custom": "value" }, // merged into every request
86
+ apiKey: "sk-...", // sent as `Authorization: Bearer <key>`
87
+ timeout: 30_000, // default request timeout, ms
88
+ });
89
+ ```
90
+
91
+ `apiKey` is inert until the server grows auth; the SDK already sends it as a
92
+ bearer token so a future server change is a config update, not an SDK upgrade.
93
+
94
+ Every method accepts an optional `AbortSignal` as its last argument
95
+ (`run`/`stream` take it via `RunOptions.signal`):
96
+
97
+ ```ts
98
+ const controller = new AbortController();
99
+ const result = await vino.run({ messages: [...], signal: controller.signal });
100
+ // controller.abort() cancels the in-flight request.
101
+ ```
102
+
103
+ ## Run options
104
+
105
+ ```ts
106
+ interface RunOptions {
107
+ messages: OutgoingMessage[]; // { role: "user" | "assistant"; content: string }
108
+ systemPrompt?: string;
109
+ maxIterations?: number; // 0/absent -> server default (50)
110
+ toolTimeout?: string; // Go duration, e.g. "30s"
111
+ requestId?: string; // exactly-once: retries resume the same run
112
+ conversationId?: string; // present -> append to this conversation
113
+ signal?: AbortSignal;
114
+ }
115
+ ```
116
+
117
+ ## Errors
118
+
119
+ ```ts
120
+ import { VinoError, VinoHttpError, VinoStreamError } from "vino-sdk";
121
+
122
+ try {
123
+ await vino.run({ messages: [{ role: "user", content: "hi" }] });
124
+ } catch (err) {
125
+ if (err instanceof VinoHttpError) {
126
+ console.error(err.status, err.message); // non-2xx before streaming
127
+ } else if (err instanceof VinoStreamError) {
128
+ console.error(err.message); // terminal SSE error / premature end
129
+ }
130
+ }
131
+ ```
132
+
133
+ `stream()` yields the terminal `error` event rather than throwing it;
134
+ `run()` throws `VinoStreamError` instead.
135
+
136
+ ## Browser / CORS note
137
+
138
+ The vino-backend server sends CORS headers, so a browser client can call the
139
+ API cross-origin directly — no reverse proxy required. If the server is
140
+ configured to allow only specific origins, make sure your app's origin is in
141
+ the allow-list.
142
+
143
+ ## Development
144
+
145
+ ```bash
146
+ npm install
147
+ npm run typecheck
148
+ npm test # unit + integration (integration boots the real Go server)
149
+ npm run build # emit dist/
150
+ ```
151
+
152
+ Integration tests vendor the vino-backend server under
153
+ `test/fixture/vino-backend` and boot it with `go run` against a mock
154
+ OpenAI-compatible provider, so no API key is required. When Go is absent, the
155
+ integration suite auto-skips.
156
+
157
+ ## License
158
+
159
+ MIT
@@ -0,0 +1,42 @@
1
+ import type { Conversation, ListConversationsResult, ListQuery, RunEvent, RunOptions, RunResult, VinoOptions } from "./types.js";
2
+ /**
3
+ * Client for the vino-backend HTTP API.
4
+ *
5
+ * ```ts
6
+ * const vino = new Vino({ baseUrl: "http://127.0.0.1:8080" });
7
+ *
8
+ * // Stream a run as typed events:
9
+ * for await (const ev of vino.stream({ messages: [{ role: "user", content: "hi" }] })) {
10
+ * if (ev.type === "text_delta") process.stdout.write(ev.text);
11
+ * }
12
+ *
13
+ * // Or just the final result:
14
+ * const result = await vino.run({ messages: [{ role: "user", content: "hi" }] });
15
+ * console.log(result.finalMessage.content);
16
+ * ```
17
+ */
18
+ export declare class Vino {
19
+ private readonly transport;
20
+ constructor(options?: VinoOptions);
21
+ /** Liveness probe. Resolves `{ ok: true }` when the server is up. */
22
+ health(signal?: AbortSignal): Promise<{
23
+ ok: boolean;
24
+ }>;
25
+ /**
26
+ * Runs the agent and resolves the completed result, folding the stream into
27
+ * `finalMessage`, `text`, `toolResults`, and run metadata. Throws
28
+ * {@link VinoStreamError} if the run aborts.
29
+ */
30
+ run(options: RunOptions): Promise<RunResult>;
31
+ /**
32
+ * Streams a run as typed {@link RunEvent}s. The terminal `error` event is
33
+ * yielded (not thrown); use {@link run} to get a thrown {@link VinoStreamError}
34
+ * instead. Pass `conversationId` to append to an existing conversation.
35
+ */
36
+ stream(options: RunOptions): AsyncGenerator<RunEvent>;
37
+ /** Lists conversations, newest first by default. */
38
+ listConversations(query?: ListQuery, signal?: AbortSignal): Promise<ListConversationsResult>;
39
+ /** Fetches one conversation with its full transcript. */
40
+ getConversation(id: string, signal?: AbortSignal): Promise<Conversation>;
41
+ }
42
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,uBAAuB,EACvB,SAAS,EAET,QAAQ,EACR,UAAU,EAEV,SAAS,EAET,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,OAAO,GAAE,WAAgB;IAarC,qEAAqE;IACrE,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC;IAItD;;;;OAIG;IACG,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IA0ClD;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC;IAQrD,oDAAoD;IACpD,iBAAiB,CACf,KAAK,GAAE,SAAc,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,uBAAuB,CAAC;IAInC,yDAAyD;IACzD,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAGzE"}
package/dist/client.js ADDED
@@ -0,0 +1,108 @@
1
+ import { VinoStreamError } from "./errors.js";
2
+ import { Transport } from "./transport.js";
3
+ /**
4
+ * Client for the vino-backend HTTP API.
5
+ *
6
+ * ```ts
7
+ * const vino = new Vino({ baseUrl: "http://127.0.0.1:8080" });
8
+ *
9
+ * // Stream a run as typed events:
10
+ * for await (const ev of vino.stream({ messages: [{ role: "user", content: "hi" }] })) {
11
+ * if (ev.type === "text_delta") process.stdout.write(ev.text);
12
+ * }
13
+ *
14
+ * // Or just the final result:
15
+ * const result = await vino.run({ messages: [{ role: "user", content: "hi" }] });
16
+ * console.log(result.finalMessage.content);
17
+ * ```
18
+ */
19
+ export class Vino {
20
+ transport;
21
+ constructor(options = {}) {
22
+ const baseUrl = options.baseUrl ?? "http://127.0.0.1:8080";
23
+ const headers = { ...(options.headers ?? {}) };
24
+ if (options.apiKey)
25
+ headers["authorization"] = `Bearer ${options.apiKey}`;
26
+ this.transport = new Transport({
27
+ baseUrl,
28
+ headers,
29
+ timeout: options.timeout,
30
+ fetch: options.fetch,
31
+ });
32
+ }
33
+ /** Liveness probe. Resolves `{ ok: true }` when the server is up. */
34
+ health(signal) {
35
+ return this.transport.health(signal);
36
+ }
37
+ /**
38
+ * Runs the agent and resolves the completed result, folding the stream into
39
+ * `finalMessage`, `text`, `toolResults`, and run metadata. Throws
40
+ * {@link VinoStreamError} if the run aborts.
41
+ */
42
+ async run(options) {
43
+ let conversationId = "";
44
+ let submissionId = "";
45
+ let resumed = false;
46
+ let text = "";
47
+ const toolResults = [];
48
+ let finalMessage = { role: "assistant" };
49
+ let finished = false;
50
+ for await (const event of this.stream(options)) {
51
+ switch (event.type) {
52
+ case "run_started":
53
+ conversationId = event.conversationId;
54
+ submissionId = event.submissionId;
55
+ resumed = event.resumed;
56
+ break;
57
+ case "text_delta":
58
+ text += event.text;
59
+ break;
60
+ case "tool_result":
61
+ toolResults.push(event.error === undefined
62
+ ? { id: event.id, name: event.name, result: event.result }
63
+ : { id: event.id, name: event.name, result: event.result, error: event.error });
64
+ break;
65
+ case "run_finished":
66
+ finished = true;
67
+ finalMessage = event.finalMessage;
68
+ break;
69
+ case "error":
70
+ throw new VinoStreamError(event.error);
71
+ }
72
+ }
73
+ if (!finished) {
74
+ throw new VinoStreamError("run stream ended before run_finished");
75
+ }
76
+ return { conversationId, submissionId, resumed, finalMessage, text, toolResults };
77
+ }
78
+ /**
79
+ * Streams a run as typed {@link RunEvent}s. The terminal `error` event is
80
+ * yielded (not thrown); use {@link run} to get a thrown {@link VinoStreamError}
81
+ * instead. Pass `conversationId` to append to an existing conversation.
82
+ */
83
+ stream(options) {
84
+ const { conversationId, signal, ...rest } = options;
85
+ const path = conversationId
86
+ ? `/conversations/${encodeURIComponent(conversationId)}/runs`
87
+ : "/runs";
88
+ return this.transport.streamRun(path, toRunBody(rest), signal);
89
+ }
90
+ /** Lists conversations, newest first by default. */
91
+ listConversations(query = {}, signal) {
92
+ return this.transport.listConversations(query, signal);
93
+ }
94
+ /** Fetches one conversation with its full transcript. */
95
+ getConversation(id, signal) {
96
+ return this.transport.getConversation(id, signal);
97
+ }
98
+ }
99
+ function toRunBody(options) {
100
+ return {
101
+ systemPrompt: options.systemPrompt ?? "",
102
+ messages: options.messages,
103
+ maxIterations: options.maxIterations ?? 0,
104
+ toolTimeout: options.toolTimeout ?? "",
105
+ requestId: options.requestId ?? "",
106
+ };
107
+ }
108
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /** Base class for every error thrown by the SDK. */
2
+ export declare class VinoError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ /**
6
+ * A non-2xx HTTP response. Carries the HTTP status and, when present, the
7
+ * server's `{"error":"..."}` message.
8
+ */
9
+ export declare class VinoHttpError extends VinoError {
10
+ readonly status: number;
11
+ constructor(status: number, message: string);
12
+ }
13
+ /**
14
+ * A failure after the run stream opened: either a terminal SSE `error` event
15
+ * or a stream that ended before `run_finished`.
16
+ */
17
+ export declare class VinoStreamError extends VinoError {
18
+ }
19
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAI5C;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,SAAS;CAAG"}
package/dist/errors.js ADDED
@@ -0,0 +1,25 @@
1
+ /** Base class for every error thrown by the SDK. */
2
+ export class VinoError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = new.target.name;
6
+ }
7
+ }
8
+ /**
9
+ * A non-2xx HTTP response. Carries the HTTP status and, when present, the
10
+ * server's `{"error":"..."}` message.
11
+ */
12
+ export class VinoHttpError extends VinoError {
13
+ status;
14
+ constructor(status, message) {
15
+ super(message);
16
+ this.status = status;
17
+ }
18
+ }
19
+ /**
20
+ * A failure after the run stream opened: either a terminal SSE `error` event
21
+ * or a stream that ended before `run_finished`.
22
+ */
23
+ export class VinoStreamError extends VinoError {
24
+ }
25
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAS;IACjC,MAAM,CAAS;IAExB,YAAY,MAAc,EAAE,OAAe;QACzC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,SAAS;CAAG"}
@@ -0,0 +1,4 @@
1
+ export { Vino } from "./client.js";
2
+ export { VinoError, VinoHttpError, VinoStreamError } from "./errors.js";
3
+ export type { Conversation, ConversationSummary, Entry, ForkRef, LatestMessage, ListConversationsResult, ListQuery, Message, OutgoingMessage, OutgoingRole, OwnerRef, Role, RunEvent, RunOptions, RunResult, ToolCall, ToolResult, VinoOptions, } from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,KAAK,EACL,OAAO,EACP,aAAa,EACb,uBAAuB,EACvB,SAAS,EACT,OAAO,EACP,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Vino } from "./client.js";
2
+ export { VinoError, VinoHttpError, VinoStreamError } from "./errors.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { Conversation, ListConversationsResult, ListQuery, RunEvent, RunRequestBody } from "./types.js";
2
+ /** The subset of `fetch` the transport relies on, injectable for tests. */
3
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
4
+ /** Options for building a {@link Transport}. */
5
+ export interface TransportOptions {
6
+ baseUrl: string;
7
+ headers: Record<string, string>;
8
+ fetch?: FetchLike;
9
+ timeout?: number;
10
+ }
11
+ /**
12
+ * Internal HTTP layer. Owns base-URL joining, header/query handling, status
13
+ * to error mapping, and the SSE stream. Consumers use {@link Vino}, not this.
14
+ */
15
+ export declare class Transport {
16
+ private readonly baseUrl;
17
+ private readonly headers;
18
+ private readonly fetchImpl;
19
+ private readonly timeout?;
20
+ constructor(options: TransportOptions);
21
+ health(signal?: AbortSignal): Promise<{
22
+ ok: boolean;
23
+ }>;
24
+ streamRun(path: string, body: RunRequestBody, signal?: AbortSignal): AsyncGenerator<RunEvent>;
25
+ listConversations(query: ListQuery, signal?: AbortSignal): Promise<ListConversationsResult>;
26
+ getConversation(id: string, signal?: AbortSignal): Promise<Conversation>;
27
+ private url;
28
+ private queryParams;
29
+ private requestJSON;
30
+ }
31
+ /**
32
+ * Parses a byte stream of server-sent events into typed {@link RunEvent}s.
33
+ * Frames are `event: <name>\ndata: <json>\n\n`. Unknown event names are
34
+ * skipped (forward compatibility); malformed JSON raises {@link VinoStreamError}.
35
+ */
36
+ export declare function parseSSE(chunks: AsyncIterable<Uint8Array>): AsyncGenerator<RunEvent>;
37
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,uBAAuB,EACvB,SAAS,EAET,QAAQ,EACR,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;gBAEtB,OAAO,EAAE,gBAAgB;IAOrC,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC;IAItD,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,QAAQ,CAAC;IAI3B,iBAAiB,CACf,KAAK,EAAE,SAAS,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,uBAAuB,CAAC;IAUnC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IASxE,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,WAAW;YAQL,WAAW;CAsB1B;AAED;;;;GAIG;AACH,wBAAuB,QAAQ,CAC7B,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAChC,cAAc,CAAC,QAAQ,CAAC,CAqB1B"}
@@ -0,0 +1,217 @@
1
+ import { VinoHttpError, VinoStreamError } from "./errors.js";
2
+ /**
3
+ * Internal HTTP layer. Owns base-URL joining, header/query handling, status
4
+ * to error mapping, and the SSE stream. Consumers use {@link Vino}, not this.
5
+ */
6
+ export class Transport {
7
+ baseUrl;
8
+ headers;
9
+ fetchImpl;
10
+ timeout;
11
+ constructor(options) {
12
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
13
+ this.headers = { ...options.headers };
14
+ this.fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));
15
+ this.timeout = options.timeout;
16
+ }
17
+ health(signal) {
18
+ return this.requestJSON("GET", "/health", undefined, signal);
19
+ }
20
+ streamRun(path, body, signal) {
21
+ return streamEvents(this.fetchImpl, this.url(path), this.headers, this.timeout, body, signal);
22
+ }
23
+ listConversations(query, signal) {
24
+ return this.requestJSON("GET", "/conversations", undefined, signal, this.queryParams(query));
25
+ }
26
+ getConversation(id, signal) {
27
+ return this.requestJSON("GET", `/conversations/${encodeURIComponent(id)}`, undefined, signal);
28
+ }
29
+ url(path, query) {
30
+ const qs = query?.toString();
31
+ return qs ? `${this.baseUrl}${path}?${qs}` : `${this.baseUrl}${path}`;
32
+ }
33
+ queryParams(query) {
34
+ const params = new URLSearchParams();
35
+ if (query.limit !== undefined)
36
+ params.set("limit", String(query.limit));
37
+ if (query.cursor !== undefined)
38
+ params.set("cursor", query.cursor);
39
+ if (query.order !== undefined)
40
+ params.set("order", query.order);
41
+ return params;
42
+ }
43
+ async requestJSON(method, path, body, signal, query) {
44
+ const { signal: effective, cleanup } = withTimeout(signal, this.timeout);
45
+ try {
46
+ const headers = { ...this.headers };
47
+ const init = { method, headers, signal: effective };
48
+ if (body !== undefined) {
49
+ headers["content-type"] = "application/json";
50
+ init.body = JSON.stringify(body);
51
+ }
52
+ const res = await this.fetchImpl(this.url(path, query), init);
53
+ if (!res.ok)
54
+ throw await toHttpError(res);
55
+ return (await res.json());
56
+ }
57
+ finally {
58
+ cleanup();
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * Parses a byte stream of server-sent events into typed {@link RunEvent}s.
64
+ * Frames are `event: <name>\ndata: <json>\n\n`. Unknown event names are
65
+ * skipped (forward compatibility); malformed JSON raises {@link VinoStreamError}.
66
+ */
67
+ export async function* parseSSE(chunks) {
68
+ const decoder = new TextDecoder();
69
+ let buffer = "";
70
+ for await (const chunk of chunks) {
71
+ buffer += decoder.decode(chunk, { stream: true });
72
+ let sep = buffer.indexOf("\n\n");
73
+ while (sep !== -1) {
74
+ const frame = buffer.slice(0, sep);
75
+ buffer = buffer.slice(sep + 2);
76
+ const event = parseFrame(frame);
77
+ if (event)
78
+ yield event;
79
+ sep = buffer.indexOf("\n\n");
80
+ }
81
+ }
82
+ buffer += decoder.decode();
83
+ if (buffer.length > 0) {
84
+ const event = parseFrame(buffer);
85
+ if (event)
86
+ yield event;
87
+ }
88
+ }
89
+ function parseFrame(frame) {
90
+ let name = "message";
91
+ const dataLines = [];
92
+ for (const line of frame.split("\n")) {
93
+ if (line.startsWith("event:")) {
94
+ name = line.slice("event:".length).trim();
95
+ }
96
+ else if (line.startsWith("data:")) {
97
+ dataLines.push(line.slice("data:".length).replace(/^ /, ""));
98
+ }
99
+ }
100
+ if (dataLines.length === 0)
101
+ return null;
102
+ let payload;
103
+ try {
104
+ payload = JSON.parse(dataLines.join("\n"));
105
+ }
106
+ catch {
107
+ throw new VinoStreamError(`malformed SSE data for event "${name}"`);
108
+ }
109
+ return toEvent(name, payload);
110
+ }
111
+ function toEvent(name, payload) {
112
+ switch (name) {
113
+ case "run_started": {
114
+ const p = payload;
115
+ return {
116
+ type: "run_started",
117
+ conversationId: p.conversationId ?? "",
118
+ submissionId: p.submissionId ?? "",
119
+ resumed: p.resumed === true,
120
+ };
121
+ }
122
+ case "text_delta": {
123
+ const p = payload;
124
+ return { type: "text_delta", text: p.text ?? "" };
125
+ }
126
+ case "tool_call_started": {
127
+ const p = payload;
128
+ return {
129
+ type: "tool_call_started",
130
+ id: p.id ?? "",
131
+ name: p.name ?? "",
132
+ arguments: p.arguments ?? null,
133
+ };
134
+ }
135
+ case "tool_result": {
136
+ const p = payload;
137
+ const base = {
138
+ type: "tool_result",
139
+ id: p.id ?? "",
140
+ name: p.name ?? "",
141
+ result: p.result ?? "",
142
+ };
143
+ return p.error === undefined ? base : { ...base, error: p.error };
144
+ }
145
+ case "run_finished": {
146
+ const p = payload;
147
+ return {
148
+ type: "run_finished",
149
+ conversationId: p.conversationId ?? "",
150
+ finalMessage: p.finalMessage ?? { role: "assistant" },
151
+ };
152
+ }
153
+ case "error": {
154
+ const p = payload;
155
+ return { type: "error", error: p.error ?? "" };
156
+ }
157
+ default:
158
+ return null;
159
+ }
160
+ }
161
+ async function* streamEvents(fetchImpl, url, headers, timeout, body, signal) {
162
+ const { signal: effective, cleanup } = withTimeout(signal, timeout);
163
+ try {
164
+ const res = await fetchImpl(url, {
165
+ method: "POST",
166
+ headers: {
167
+ ...headers,
168
+ "content-type": "application/json",
169
+ accept: "text/event-stream",
170
+ },
171
+ body: JSON.stringify(body),
172
+ signal: effective,
173
+ });
174
+ if (!res.ok)
175
+ throw await toHttpError(res);
176
+ if (!res.body)
177
+ throw new VinoStreamError("response body is empty");
178
+ yield* parseSSE(res.body);
179
+ }
180
+ finally {
181
+ cleanup();
182
+ }
183
+ }
184
+ async function toHttpError(res) {
185
+ let message = `HTTP ${res.status}`;
186
+ try {
187
+ const data = (await res.json());
188
+ if (typeof data?.error === "string")
189
+ message = data.error;
190
+ }
191
+ catch {
192
+ // Non-JSON error body; keep the status-based message.
193
+ }
194
+ return new VinoHttpError(res.status, message);
195
+ }
196
+ function withTimeout(signal, timeoutMs) {
197
+ if (timeoutMs === undefined) {
198
+ return { signal, cleanup: () => { } };
199
+ }
200
+ const controller = new AbortController();
201
+ const timer = setTimeout(() => controller.abort(new VinoStreamError(`request timed out after ${timeoutMs}ms`)), timeoutMs);
202
+ if (signal === undefined) {
203
+ return { signal: controller.signal, cleanup: () => clearTimeout(timer) };
204
+ }
205
+ const onAbort = () => controller.abort(signal.reason);
206
+ signal.addEventListener("abort", onAbort, { once: true });
207
+ if (signal.aborted)
208
+ onAbort();
209
+ return {
210
+ signal: controller.signal,
211
+ cleanup: () => {
212
+ clearTimeout(timer);
213
+ signal.removeEventListener("abort", onAbort);
214
+ },
215
+ };
216
+ }
217
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Wire-level types for the vino-backend HTTP API. These mirror the JSON
3
+ * documented in the server's `docs/api.md` and are the single source of
4
+ * truth for the client's request/response shapes.
5
+ */
6
+ /** Author of a message as it appears in a server-side transcript. */
7
+ export type Role = "system" | "user" | "assistant" | "tool";
8
+ /** Role a caller is allowed to send in a run/resume request. */
9
+ export type OutgoingRole = "user" | "assistant";
10
+ /** A model tool call (part of an assistant message). */
11
+ export interface ToolCall {
12
+ id: string;
13
+ name: string;
14
+ arguments: unknown;
15
+ }
16
+ /**
17
+ * A single conversation turn, in the server's wire shape. All fields except
18
+ * `role` are optional because the server omits them when empty.
19
+ */
20
+ export interface Message {
21
+ role: Role;
22
+ content?: string;
23
+ tool_calls?: ToolCall[];
24
+ tool_call_id?: string;
25
+ name?: string;
26
+ }
27
+ /** A message the caller sends in a run/resume request. */
28
+ export interface OutgoingMessage {
29
+ role: OutgoingRole;
30
+ content: string;
31
+ }
32
+ /** Wire request body for `POST /runs` and `POST /conversations/{id}/runs`. */
33
+ export interface RunRequestBody {
34
+ systemPrompt: string;
35
+ messages: OutgoingMessage[];
36
+ maxIterations: number;
37
+ toolTimeout: string;
38
+ requestId: string;
39
+ }
40
+ /** One SSE event from a run stream, discriminated by `type`. */
41
+ export type RunEvent = {
42
+ type: "run_started";
43
+ conversationId: string;
44
+ submissionId: string;
45
+ resumed: boolean;
46
+ } | {
47
+ type: "text_delta";
48
+ text: string;
49
+ } | {
50
+ type: "tool_call_started";
51
+ id: string;
52
+ name: string;
53
+ arguments: Record<string, unknown> | null;
54
+ } | {
55
+ type: "tool_result";
56
+ id: string;
57
+ name: string;
58
+ result: string;
59
+ error?: string;
60
+ } | {
61
+ type: "run_finished";
62
+ conversationId: string;
63
+ finalMessage: Message;
64
+ } | {
65
+ type: "error";
66
+ error: string;
67
+ };
68
+ /** Outcome of a single tool call within a run. */
69
+ export interface ToolResult {
70
+ id: string;
71
+ name: string;
72
+ result: string;
73
+ error?: string;
74
+ }
75
+ /** Options for `Vino.run` and `Vino.stream`. */
76
+ export interface RunOptions {
77
+ /** Conversation turns, in order. Must be non-empty. */
78
+ messages: OutgoingMessage[];
79
+ /** System prompt prepended to the conversation. */
80
+ systemPrompt?: string;
81
+ /** Loop cap; 0/absent means the server default (50). */
82
+ maxIterations?: number;
83
+ /** Per-tool timeout as a Go duration string ("30s", "1m"). */
84
+ toolTimeout?: string;
85
+ /** Makes a run exactly-once: retries resume the original run. */
86
+ requestId?: string;
87
+ /** When set, the turns are appended to this conversation (resume). */
88
+ conversationId?: string;
89
+ /** Aborts the underlying request and stream. */
90
+ signal?: AbortSignal;
91
+ }
92
+ /** The resolved outcome of a completed run. */
93
+ export interface RunResult {
94
+ conversationId: string;
95
+ submissionId: string;
96
+ resumed: boolean;
97
+ finalMessage: Message;
98
+ /** All `text_delta` payloads concatenated in stream order. */
99
+ text: string;
100
+ toolResults: ToolResult[];
101
+ }
102
+ /** Options for constructing a {@link Vino} client. */
103
+ export interface VinoOptions {
104
+ /** Server base URL. Defaults to `http://127.0.0.1:8080`. */
105
+ baseUrl?: string;
106
+ /** Extra headers merged into every request. */
107
+ headers?: Record<string, string>;
108
+ /** Optional API key, sent as `Authorization: Bearer <key>`. */
109
+ apiKey?: string;
110
+ /** Default request timeout in milliseconds. */
111
+ timeout?: number;
112
+ /**
113
+ * Custom `fetch` implementation. Advanced: intended for testing and for
114
+ * runtimes without a global `fetch`. Defaults to the global `fetch`.
115
+ */
116
+ fetch?: (input: string, init?: RequestInit) => Promise<Response>;
117
+ }
118
+ /** Pagination/ordering query for listing conversations. */
119
+ export interface ListQuery {
120
+ limit?: number;
121
+ cursor?: string;
122
+ order?: "asc" | "desc";
123
+ }
124
+ /** Reference to a parent conversation (present when forked). */
125
+ export interface ForkRef {
126
+ conversationId: string;
127
+ at: string;
128
+ }
129
+ /** Reference to the task that owns a conversation. */
130
+ export interface OwnerRef {
131
+ conversationId: string;
132
+ taskId: string;
133
+ }
134
+ /** Truncated preview of a conversation's latest message. */
135
+ export interface LatestMessage {
136
+ role: string;
137
+ content: string;
138
+ truncated: boolean;
139
+ }
140
+ /** One conversation in a list response. */
141
+ export interface ConversationSummary {
142
+ id: string;
143
+ parent?: ForkRef;
144
+ owner?: OwnerRef;
145
+ latestMessage?: LatestMessage;
146
+ }
147
+ /** One entry in a conversation transcript. */
148
+ export interface Entry {
149
+ id: string;
150
+ kind: string;
151
+ message: Message;
152
+ }
153
+ /** A full conversation with its transcript. */
154
+ export interface Conversation {
155
+ id: string;
156
+ parent?: ForkRef;
157
+ owner?: OwnerRef;
158
+ entries: Entry[];
159
+ }
160
+ /** Response from listing conversations. */
161
+ export interface ListConversationsResult {
162
+ conversations: ConversationSummary[];
163
+ nextCursor: string | null;
164
+ }
165
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Wire-level types for the vino-backend HTTP API. These mirror the JSON
3
+ * documented in the server's `docs/api.md` and are the single source of
4
+ * truth for the client's request/response shapes.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "vino-sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Zero-dependency TypeScript client for the vino-backend HTTP API.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "engines": {
9
+ "node": ">=18"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "typecheck": "tsc -p tsconfig.json --noEmit",
25
+ "test": "node --import tsx --test test/unit/*.test.ts test/integration/*.test.ts"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.10.0",
29
+ "tsx": "^4.19.0",
30
+ "typescript": "^5.6.0"
31
+ }
32
+ }