juneau 0.1.0 → 0.1.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.
@@ -0,0 +1,88 @@
1
+ import type { AiBackendAdapter, AiAdapterInput, AiStreamEvent } from '../core/types';
2
+ /**
3
+ * How to map a raw text chunk from the response body to Juneau stream events.
4
+ *
5
+ * Return an array — a chunk may produce one event, multiple, or none (empty array to skip).
6
+ * The chunk is whatever the server sent — could be a full JSON line, a partial one,
7
+ * or plain text depending on your backend.
8
+ */
9
+ export type FetchChunkParser = (chunk: string) => AiStreamEvent[];
10
+ /**
11
+ * Options for createFetchStreamAdapter.
12
+ */
13
+ export type FetchStreamAdapterOptions = {
14
+ /**
15
+ * HTTP method. Defaults to 'POST'.
16
+ */
17
+ method?: string;
18
+ /**
19
+ * Static headers merged with Content-Type. Use for auth tokens etc.
20
+ * For dynamic headers (e.g. per-request auth), use getHeaders instead.
21
+ *
22
+ * @example { Authorization: 'Bearer sk-...' }
23
+ */
24
+ headers?: Record<string, string>;
25
+ /**
26
+ * Dynamic headers — called before every request with the current adapter input.
27
+ * Merged on top of `headers`. Use this when the token is fetched at runtime.
28
+ */
29
+ getHeaders?: (input: AiAdapterInput) => Record<string, string> | Promise<Record<string, string>>;
30
+ /**
31
+ * Override the request body. By default sends `{ messages, context }`.
32
+ * Return anything JSON-serialisable.
33
+ */
34
+ getBody?: (input: AiAdapterInput) => unknown;
35
+ /**
36
+ * How to parse each chunk from the response stream into Juneau events.
37
+ *
38
+ * Defaults to a newline-delimited JSON (NDJSON) parser that expects each
39
+ * line to be either `{ text: "..." }` or `{ done: true }`.
40
+ *
41
+ * @example
42
+ * // Plain text streaming — treat every chunk as raw text:
43
+ * parseChunk: (chunk) => chunk ? [{ type: 'text', text: chunk }] : []
44
+ *
45
+ * @example
46
+ * // Custom JSON lines format:
47
+ * parseChunk: (chunk) => {
48
+ * try {
49
+ * const json = JSON.parse(chunk);
50
+ * if (json.error) return [{ type: 'error', message: json.error }];
51
+ * if (json.done) return [{ type: 'done' }];
52
+ * if (json.delta) return [{ type: 'text', text: json.delta }];
53
+ * return [];
54
+ * } catch { return []; }
55
+ * }
56
+ */
57
+ parseChunk?: FetchChunkParser;
58
+ };
59
+ /**
60
+ * Creates an adapter that connects to a **raw chunked HTTP streaming** endpoint —
61
+ * for backends that stream newline-delimited JSON (NDJSON) or plain text,
62
+ * rather than SSE.
63
+ *
64
+ * Use `createSseAdapter` instead if your backend streams Server-Sent Events
65
+ * (the format used by OpenAI, Anthropic, and most AI APIs).
66
+ *
67
+ * @example
68
+ * // NDJSON backend streaming { text: "..." } lines — works with zero config:
69
+ * const adapter = createFetchStreamAdapter('/api/chat');
70
+ *
71
+ * @example
72
+ * // Plain text streaming (each chunk is raw text, no JSON):
73
+ * const adapter = createFetchStreamAdapter('/api/chat', {
74
+ * parseChunk: (chunk) => chunk ? [{ type: 'text', text: chunk }] : [],
75
+ * });
76
+ *
77
+ * @example
78
+ * // Custom body + auth:
79
+ * const adapter = createFetchStreamAdapter('/api/chat', {
80
+ * getHeaders: async () => ({ Authorization: `Bearer ${await getToken()}` }),
81
+ * getBody: ({ messages, context }) => ({
82
+ * history: messages,
83
+ * model: context?.model ?? 'default',
84
+ * }),
85
+ * });
86
+ */
87
+ export declare function createFetchStreamAdapter(url: string, options?: FetchStreamAdapterOptions): AiBackendAdapter;
88
+ //# sourceMappingURL=createFetchStreamAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createFetchStreamAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/createFetchStreamAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErF;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEjG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,yBAA8B,GACtC,gBAAgB,CAyClB"}
@@ -0,0 +1,94 @@
1
+ import type { AiBackendAdapter, AiAdapterInput, AiStreamEvent } from '../core/types';
2
+ /**
3
+ * How to map a parsed SSE data payload to Juneau stream events.
4
+ *
5
+ * Return an array — most lines produce one event, but you can return multiple
6
+ * or an empty array to skip a line entirely.
7
+ */
8
+ export type SseEventParser = (data: string) => AiStreamEvent[];
9
+ /**
10
+ * Options for createSseAdapter.
11
+ */
12
+ export type SseAdapterOptions = {
13
+ /**
14
+ * HTTP method. Defaults to 'POST'.
15
+ */
16
+ method?: string;
17
+ /**
18
+ * Static headers merged with Content-Type. Use for auth tokens etc.
19
+ * For dynamic headers (e.g. per-request auth), use getHeaders instead.
20
+ *
21
+ * @example { Authorization: 'Bearer sk-...' }
22
+ */
23
+ headers?: Record<string, string>;
24
+ /**
25
+ * Dynamic headers — called before every request with the current adapter input.
26
+ * Merged on top of `headers`. Use this when the token is fetched at runtime.
27
+ */
28
+ getHeaders?: (input: AiAdapterInput) => Record<string, string> | Promise<Record<string, string>>;
29
+ /**
30
+ * Override the request body. By default sends `{ messages, context }`.
31
+ * Return anything JSON-serialisable.
32
+ */
33
+ getBody?: (input: AiAdapterInput) => unknown;
34
+ /**
35
+ * Custom SSE line parser. Receives the raw string after `data: ` and returns
36
+ * zero or more Juneau stream events.
37
+ *
38
+ * Defaults to an OpenAI-compatible parser that reads
39
+ * `choices[0].delta.content` and handles `[DONE]`.
40
+ *
41
+ * @example
42
+ * // For a backend that streams { text: "..." } JSON lines:
43
+ * parseEvent: (data) => {
44
+ * const json = JSON.parse(data);
45
+ * return json.text ? [{ type: 'text', text: json.text }] : [];
46
+ * }
47
+ */
48
+ parseEvent?: SseEventParser;
49
+ };
50
+ /**
51
+ * Creates an adapter that connects to a **Server-Sent Events (SSE)** streaming
52
+ * endpoint — the format used by OpenAI, Anthropic, and most AI backend proxies.
53
+ *
54
+ * The default parser understands OpenAI's streaming format out of the box.
55
+ * Override `parseEvent` for any other SSE schema.
56
+ *
57
+ * @example
58
+ * // OpenAI-compatible backend proxy — works with zero configuration:
59
+ * const adapter = createSseAdapter('/api/chat');
60
+ *
61
+ * @example
62
+ * // With auth header:
63
+ * const adapter = createSseAdapter('/api/chat', {
64
+ * getHeaders: async () => ({
65
+ * Authorization: `Bearer ${await getToken()}`,
66
+ * }),
67
+ * });
68
+ *
69
+ * @example
70
+ * // Custom body shape:
71
+ * const adapter = createSseAdapter('/api/chat', {
72
+ * getBody: ({ messages, context }) => ({
73
+ * messages,
74
+ * model: 'gpt-4o',
75
+ * stream: true,
76
+ * ...(context?.systemPrompt ? { system: context.systemPrompt } : {}),
77
+ * }),
78
+ * });
79
+ *
80
+ * @example
81
+ * // Custom SSE schema (backend streams { text: "..." }):
82
+ * const adapter = createSseAdapter('/api/chat', {
83
+ * parseEvent: (data) => {
84
+ * try {
85
+ * const json = JSON.parse(data);
86
+ * return json.text ? [{ type: 'text', text: json.text }] : [];
87
+ * } catch {
88
+ * return [];
89
+ * }
90
+ * },
91
+ * });
92
+ */
93
+ export declare function createSseAdapter(url: string, options?: SseAdapterOptions): AiBackendAdapter;
94
+ //# sourceMappingURL=createSseAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSseAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/createSseAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAErF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEjG;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;IAE7C;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAyC/F"}