afm-bridge 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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +348 -0
  3. package/dist/client.d.ts +74 -0
  4. package/dist/client.js +216 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/errors.d.ts +111 -0
  7. package/dist/errors.js +152 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/index.d.ts +8 -0
  10. package/dist/index.js +8 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/node/index.d.ts +28 -0
  13. package/dist/node/index.js +177 -0
  14. package/dist/node/index.js.map +1 -0
  15. package/dist/rpc.d.ts +37 -0
  16. package/dist/rpc.js +172 -0
  17. package/dist/rpc.js.map +1 -0
  18. package/dist/schema.d.ts +53 -0
  19. package/dist/schema.js +149 -0
  20. package/dist/schema.js.map +1 -0
  21. package/dist/session.d.ts +63 -0
  22. package/dist/session.js +202 -0
  23. package/dist/session.js.map +1 -0
  24. package/dist/tauri/index.d.ts +29 -0
  25. package/dist/tauri/index.js +80 -0
  26. package/dist/tauri/index.js.map +1 -0
  27. package/dist/tool.d.ts +39 -0
  28. package/dist/tool.js +48 -0
  29. package/dist/tool.js.map +1 -0
  30. package/dist/transport.d.ts +37 -0
  31. package/dist/transport.js +24 -0
  32. package/dist/transport.js.map +1 -0
  33. package/dist/types.d.ts +152 -0
  34. package/dist/types.js +2 -0
  35. package/dist/types.js.map +1 -0
  36. package/dist/zod/index.d.ts +21 -0
  37. package/dist/zod/index.js +44 -0
  38. package/dist/zod/index.js.map +1 -0
  39. package/package.json +79 -0
  40. package/src/client.ts +312 -0
  41. package/src/errors.ts +170 -0
  42. package/src/index.ts +22 -0
  43. package/src/node/index.ts +203 -0
  44. package/src/rpc.ts +204 -0
  45. package/src/schema.ts +206 -0
  46. package/src/session.ts +290 -0
  47. package/src/tauri/index.ts +100 -0
  48. package/src/tool.ts +80 -0
  49. package/src/transport.ts +60 -0
  50. package/src/types.ts +142 -0
  51. package/src/zod/index.ts +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Connection, Transport, TransportHandlers } from '../transport.js';
2
+ export interface TauriSidecarTransportOptions {
3
+ /**
4
+ * Sidecar name as listed in `tauri.conf.json > bundle > externalBin` (without the
5
+ * target-triple suffix). Default `binaries/afm-bridge-server`.
6
+ */
7
+ program?: string;
8
+ args?: string[];
9
+ /** Extra environment variables for the sidecar. */
10
+ env?: Record<string, string>;
11
+ /** Sidecar log level (stderr). Default `warn`. */
12
+ logLevel?: 'error' | 'warn' | 'info' | 'debug';
13
+ /** How long `close()` waits for the sidecar to exit after `shutdown` before killing it. Default 2000 ms. */
14
+ shutdownTimeoutMs?: number;
15
+ /**
16
+ * Kill the sidecar when the page goes away (reload, dev-server HMR, navigation).
17
+ * The Rust side keeps the process alive across reloads otherwise. Default true.
18
+ */
19
+ killOnPageHide?: boolean;
20
+ }
21
+ /**
22
+ * Runs the sidecar through Tauri's shell plugin, straight from the webview.
23
+ * Requires `@tauri-apps/plugin-shell` and the capabilities described in the README.
24
+ */
25
+ export declare class TauriSidecarTransport implements Transport {
26
+ private readonly options;
27
+ constructor(options?: TauriSidecarTransportOptions);
28
+ connect(handlers: TransportHandlers): Promise<Connection>;
29
+ }
@@ -0,0 +1,80 @@
1
+ import { Command } from '@tauri-apps/plugin-shell';
2
+ import { TransportError } from '../errors.js';
3
+ /**
4
+ * Runs the sidecar through Tauri's shell plugin, straight from the webview.
5
+ * Requires `@tauri-apps/plugin-shell` and the capabilities described in the README.
6
+ */
7
+ export class TauriSidecarTransport {
8
+ options;
9
+ constructor(options = {}) {
10
+ this.options = options;
11
+ }
12
+ async connect(handlers) {
13
+ const program = this.options.program ?? 'binaries/afm-bridge-server';
14
+ const command = Command.sidecar(program, this.options.args ?? [], {
15
+ env: { AFM_BRIDGE_LOG: this.options.logLevel ?? 'warn', ...this.options.env },
16
+ });
17
+ let exited = false;
18
+ let resolveExit = () => { };
19
+ const exit = new Promise((resolve) => {
20
+ resolveExit = resolve;
21
+ });
22
+ command.on('close', ({ code, signal }) => {
23
+ exited = true;
24
+ removePageHide();
25
+ handlers.onClose({ code, signal: signal === null ? null : String(signal) });
26
+ resolveExit();
27
+ });
28
+ command.on('error', (error) => handlers.onLog?.(`[tauri shell] ${error}`));
29
+ // The shell plugin emits one event per line; tolerate a trailing newline either way.
30
+ command.stdout.on('data', (data) => forEachLine(data, handlers.onMessage));
31
+ command.stderr.on('data', (data) => forEachLine(data, (line) => handlers.onLog?.(line)));
32
+ let child;
33
+ try {
34
+ child = await command.spawn();
35
+ }
36
+ catch (error) {
37
+ throw new TransportError(`Could not start sidecar '${program}': ${error}. Check bundle.externalBin in tauri.conf.json, the binary name suffix (-aarch64-apple-darwin) and the shell:allow-spawn capability.`, { type: 'transportError', cause: error });
38
+ }
39
+ const onPageHide = () => {
40
+ if (!exited)
41
+ void child.kill();
42
+ };
43
+ const removePageHide = () => {
44
+ if (typeof window !== 'undefined')
45
+ window.removeEventListener('pagehide', onPageHide);
46
+ };
47
+ if ((this.options.killOnPageHide ?? true) && typeof window !== 'undefined') {
48
+ window.addEventListener('pagehide', onPageHide);
49
+ }
50
+ const shutdownTimeoutMs = this.options.shutdownTimeoutMs ?? 2000;
51
+ return {
52
+ send(line) {
53
+ if (exited)
54
+ return;
55
+ child
56
+ .write(`${line}\n`)
57
+ .catch((error) => handlers.onLog?.(`[tauri shell] write failed: ${error}`));
58
+ },
59
+ async close() {
60
+ removePageHide();
61
+ if (exited)
62
+ return;
63
+ // The client sends `shutdown` first, so the sidecar is normally already exiting.
64
+ const timedOut = await Promise.race([
65
+ exit.then(() => false),
66
+ new Promise((resolve) => setTimeout(() => resolve(true), shutdownTimeoutMs)),
67
+ ]);
68
+ if (timedOut && !exited)
69
+ await child.kill();
70
+ },
71
+ };
72
+ }
73
+ }
74
+ function forEachLine(data, onLine) {
75
+ for (const line of data.split(/\r?\n/)) {
76
+ if (line.length > 0)
77
+ onLine(line);
78
+ }
79
+ }
80
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tauri/index.ts"],"names":[],"mappings":"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"}
package/dist/tool.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { type SchemaInput } from './schema.js';
2
+ export interface ToolContext {
3
+ /** Aborted when the generation is cancelled or the tool times out. */
4
+ signal: AbortSignal;
5
+ sessionId: string;
6
+ }
7
+ /**
8
+ * A function the model may call. Arguments are generated by the model to match
9
+ * `parameters`, validated, and passed to `execute`. The return value goes back to the
10
+ * model: strings as they are, anything else as JSON.
11
+ */
12
+ export interface Tool<Args = unknown> {
13
+ /** `^[a-zA-Z_][a-zA-Z0-9_]{0,63}$` */
14
+ name: string;
15
+ /** Tells the model when to use the tool. */
16
+ description: string;
17
+ /** Object schema of the arguments (JSON Schema or `zodSchema()`). */
18
+ parameters: SchemaInput<Args>;
19
+ includeSchemaInInstructions?: boolean;
20
+ /** Default 60 000 ms. */
21
+ timeoutMs?: number;
22
+ execute(args: Args, context: ToolContext): unknown;
23
+ }
24
+ /** Identity helper that infers the argument type from `parameters`. */
25
+ export declare function tool<Args>(definition: Tool<Args>): Tool<Args>;
26
+ /** Wire format for `session/create`. */
27
+ export declare function toolDefinition(t: Tool<unknown>): {
28
+ name: string;
29
+ description: string;
30
+ parameters: import("./schema.js").JSONSchema;
31
+ includeSchemaInInstructions?: boolean | undefined;
32
+ };
33
+ /** Runs a tool for a `tool/call` request. Errors become the error reply to the sidecar. */
34
+ export declare function runTool(t: Tool<unknown>, rawArguments: unknown, context: {
35
+ signal: AbortSignal;
36
+ sessionId: string;
37
+ }): Promise<{
38
+ output: string;
39
+ }>;
package/dist/tool.js ADDED
@@ -0,0 +1,48 @@
1
+ import { AfmError } from './errors.js';
2
+ import { toStructuredSchema } from './schema.js';
3
+ /** Identity helper that infers the argument type from `parameters`. */
4
+ export function tool(definition) {
5
+ return definition;
6
+ }
7
+ /** Wire format for `session/create`. */
8
+ export function toolDefinition(t) {
9
+ return {
10
+ name: t.name,
11
+ description: t.description,
12
+ parameters: toStructuredSchema(t.parameters).jsonSchema,
13
+ ...(t.includeSchemaInInstructions === undefined
14
+ ? {}
15
+ : { includeSchemaInInstructions: t.includeSchemaInInstructions }),
16
+ };
17
+ }
18
+ const DEFAULT_TOOL_TIMEOUT_MS = 60_000;
19
+ /** Runs a tool for a `tool/call` request. Errors become the error reply to the sidecar. */
20
+ export async function runTool(t, rawArguments, context) {
21
+ const args = toStructuredSchema(t.parameters).parse(rawArguments);
22
+ const timeoutMs = t.timeoutMs ?? DEFAULT_TOOL_TIMEOUT_MS;
23
+ const timeout = AbortSignal.timeout(timeoutMs);
24
+ const signal = AbortSignal.any([context.signal, timeout]);
25
+ // Settle as soon as the signal aborts, even if `execute` ignores it.
26
+ let onAbort = () => { };
27
+ const aborted = new Promise((_, reject) => {
28
+ onAbort = () => reject(timeout.aborted
29
+ ? new AfmError(`Tool '${t.name}' timed out after ${timeoutMs} ms`, { type: 'toolTimeout' })
30
+ : new AfmError(`Tool '${t.name}' was cancelled`, { type: 'cancelled' }));
31
+ if (signal.aborted)
32
+ onAbort();
33
+ else
34
+ signal.addEventListener('abort', onAbort, { once: true });
35
+ });
36
+ try {
37
+ const result = await Promise.race([
38
+ Promise.resolve().then(() => t.execute(args, { signal, sessionId: context.sessionId })),
39
+ aborted,
40
+ ]);
41
+ return { output: typeof result === 'string' ? result : JSON.stringify(result ?? null) };
42
+ }
43
+ finally {
44
+ signal.removeEventListener('abort', onAbort);
45
+ aborted.catch(() => { });
46
+ }
47
+ }
48
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAoB,kBAAkB,EAAE,MAAM,aAAa,CAAA;AA0BlE,uEAAuE;AACvE,MAAM,UAAU,IAAI,CAAO,UAAsB;IAC/C,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,cAAc,CAAC,CAAgB;IAC7C,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,UAAU;QACvD,GAAG,CAAC,CAAC,CAAC,2BAA2B,KAAK,SAAS;YAC7C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,2BAA2B,EAAE,CAAC,CAAC,2BAA2B,EAAE,CAAC;KACpE,CAAA;AACH,CAAC;AAED,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAEtC,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,CAAgB,EAChB,YAAqB,EACrB,OAAmD;IAEnD,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACjE,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,uBAAuB,CAAA;IACxD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAEzD,qEAAqE;IACrE,IAAI,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;IACtB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC/C,OAAO,GAAG,GAAG,EAAE,CACb,MAAM,CACJ,OAAO,CAAC,OAAO;YACb,CAAC,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,qBAAqB,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YAC3F,CAAC,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,iBAAiB,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAC1E,CAAA;QACH,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,CAAA;;YACxB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACvF,OAAO;SACR,CAAC,CAAA;QACF,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAA;IACzF,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC5C,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * A transport starts the sidecar and moves NDJSON lines in both directions.
3
+ * Implement it to run the sidecar somewhere else (for example behind Electron IPC).
4
+ */
5
+ export interface Transport {
6
+ /** Starts a new sidecar process. Called again after a crash to restart it. */
7
+ connect(handlers: TransportHandlers): Promise<Connection>;
8
+ }
9
+ export interface TransportHandlers {
10
+ /** One complete protocol line from the sidecar's stdout, without the trailing newline. */
11
+ onMessage(line: string): void;
12
+ /** The connection ended (process exited). Called exactly once. */
13
+ onClose(info: CloseInfo): void;
14
+ /** One line of the sidecar's stderr log. */
15
+ onLog?(line: string): void;
16
+ }
17
+ export interface CloseInfo {
18
+ code: number | null;
19
+ signal: string | null;
20
+ error?: Error;
21
+ }
22
+ export interface Connection {
23
+ /** Sends one protocol line. The transport appends the newline. */
24
+ send(line: string): void;
25
+ /** Ends the connection gracefully (close stdin, wait, then kill). Resolves when the process is gone. */
26
+ close(): Promise<void>;
27
+ /**
28
+ * Hint from the client: `true` while requests are in flight. Node transports use it to
29
+ * keep the event loop alive only while needed, so an idle sidecar never blocks process exit.
30
+ */
31
+ setActive?(active: boolean): void;
32
+ }
33
+ /** Splits a stream of text chunks into lines. Handles `\n` and `\r\n`. */
34
+ export declare function createLineSplitter(onLine: (line: string) => void): {
35
+ push(chunk: string): void;
36
+ flush(): void;
37
+ };
@@ -0,0 +1,24 @@
1
+ /** Splits a stream of text chunks into lines. Handles `\n` and `\r\n`. */
2
+ export function createLineSplitter(onLine) {
3
+ let buffer = '';
4
+ return {
5
+ push(chunk) {
6
+ buffer += chunk;
7
+ let index = buffer.indexOf('\n');
8
+ while (index !== -1) {
9
+ const line = buffer.slice(0, index).replace(/\r$/, '');
10
+ buffer = buffer.slice(index + 1);
11
+ if (line.length > 0)
12
+ onLine(line);
13
+ index = buffer.indexOf('\n');
14
+ }
15
+ },
16
+ flush() {
17
+ const rest = buffer.replace(/\r$/, '');
18
+ buffer = '';
19
+ if (rest.length > 0)
20
+ onLine(rest);
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAoCA,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,MAA8B;IAI/D,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,OAAO;QACL,IAAI,CAAC,KAAK;YACR,MAAM,IAAI,KAAK,CAAA;YACf,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YAChC,OAAO,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;gBACtD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;gBAChC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,MAAM,CAAC,IAAI,CAAC,CAAA;gBACjC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;QACD,KAAK;YACH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YACtC,MAAM,GAAG,EAAE,CAAA;YACX,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACnC,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,152 @@
1
+ import type { DeepPartial, SchemaInput } from './schema.js';
2
+ import type { Tool } from './tool.js';
3
+ /** Which model to use. `private-cloud` is reserved; see PROTOCOL.md section 10. */
4
+ export type ModelId = 'on-device' | 'private-cloud';
5
+ export type UnavailableReason =
6
+ /** The Mac cannot run Apple Intelligence (Apple silicon required). */
7
+ 'deviceNotEligible'
8
+ /** Apple Intelligence is switched off in System Settings. */
9
+ | 'appleIntelligenceNotEnabled'
10
+ /** Model assets are still downloading or being prepared. Try again later. */
11
+ | 'modelNotReady'
12
+ /** Private Cloud Compute: the system is not ready yet. */
13
+ | 'systemNotReady'
14
+ /** macOS is too old (afm-bridge needs macOS 26 or newer). */
15
+ | 'unsupportedOS'
16
+ /** Not macOS on Apple silicon (detected by the client, the sidecar never starts). */
17
+ | 'unsupportedPlatform'
18
+ /** The model needs an entitlement afm-bridge does not have. */
19
+ | 'requiresEntitlement' | 'unknown';
20
+ export type Capability = 'vision' | 'guidedGeneration' | 'reasoning' | 'toolCalling';
21
+ export type ModelStatus = {
22
+ available: true;
23
+ /** Context window in tokens (instructions + history + prompt + response). */
24
+ contextSize: number;
25
+ /** Model variant name, macOS 27+. */
26
+ variant?: string;
27
+ /** Empty on macOS 26, which does not report capabilities. */
28
+ capabilities: Capability[];
29
+ /** BCP 47 codes, for example `en`, `en-GB`, `de`. */
30
+ supportedLanguages: string[];
31
+ } | {
32
+ available: false;
33
+ reason: UnavailableReason;
34
+ message: string;
35
+ };
36
+ export type Sampling = {
37
+ mode: 'greedy';
38
+ } | {
39
+ mode: 'topK';
40
+ k: number;
41
+ seed?: number;
42
+ } | {
43
+ mode: 'topP';
44
+ threshold: number;
45
+ seed?: number;
46
+ };
47
+ export interface GenerationOptions {
48
+ temperature?: number;
49
+ maximumResponseTokens?: number;
50
+ sampling?: Sampling;
51
+ /** macOS 27+. */
52
+ toolCalling?: 'allowed' | 'required' | 'disallowed';
53
+ /** macOS 27+, only for models with the `reasoning` capability. */
54
+ reasoningLevel?: 'light' | 'moderate' | 'deep';
55
+ }
56
+ export type PromptPart = {
57
+ type: 'text';
58
+ text: string;
59
+ } | {
60
+ type: 'image';
61
+ path: string;
62
+ } | {
63
+ type: 'image';
64
+ data: string;
65
+ mimeType?: string;
66
+ };
67
+ export type Prompt = string | PromptPart[];
68
+ export interface Usage {
69
+ inputTokens: number;
70
+ cachedInputTokens: number;
71
+ outputTokens: number;
72
+ reasoningTokens: number;
73
+ }
74
+ export interface ServerInfo {
75
+ protocolVersion: number;
76
+ server: {
77
+ name: string;
78
+ version: string;
79
+ };
80
+ os: {
81
+ version: string;
82
+ };
83
+ models: Record<ModelId, ModelStatus>;
84
+ }
85
+ export interface SessionOptions {
86
+ model?: ModelId;
87
+ /** System instructions that apply to the whole conversation. */
88
+ instructions?: string;
89
+ guardrails?: 'default' | 'permissiveContentTransformations';
90
+ useCase?: 'general' | 'contentTagging';
91
+ /** Functions the model may call while responding. */
92
+ tools?: Array<Tool<any>>;
93
+ signal?: AbortSignal;
94
+ }
95
+ export interface CallOptions {
96
+ /** Cancels the request. The promise rejects with `AbortError`. */
97
+ signal?: AbortSignal;
98
+ /** Client-side timeout; rejects with `RequestTimeoutError` and cancels the request. */
99
+ timeoutMs?: number;
100
+ }
101
+ export type RespondOptions = GenerationOptions & CallOptions & {
102
+ /** Whether the schema is also described in the prompt (default true). Only with `schema`. */
103
+ includeSchemaInPrompt?: boolean;
104
+ };
105
+ /** Options that request structured output: the response is parsed and validated as `T`. */
106
+ export type StructuredOptions<T> = RespondOptions & {
107
+ schema: SchemaInput<T>;
108
+ };
109
+ export interface StructuredResult<T> {
110
+ /** Parsed and validated value. */
111
+ content: T;
112
+ /** The same value as JSON text. */
113
+ text: string;
114
+ usage?: Usage;
115
+ }
116
+ export type StructuredStreamChunk<T> = {
117
+ done: false;
118
+ partial: DeepPartial<T>;
119
+ } | {
120
+ done: true;
121
+ content: T;
122
+ text: string;
123
+ usage?: Usage;
124
+ };
125
+ export interface GenerateResult {
126
+ text: string;
127
+ /** Tokens used by this request (macOS 27+). */
128
+ usage?: Usage;
129
+ }
130
+ export type StreamChunk = {
131
+ done: false;
132
+ /** Text appended since the previous chunk. Empty when `reset` is true. */
133
+ delta: string;
134
+ /** Full text so far. */
135
+ text: string;
136
+ /** The model rewrote earlier output; replace what you showed with `text`. */
137
+ reset?: boolean;
138
+ } | {
139
+ done: true;
140
+ delta: '';
141
+ text: string;
142
+ usage?: Usage;
143
+ };
144
+ export interface SessionInfo {
145
+ model: ModelId;
146
+ contextSize: number;
147
+ isResponding: boolean;
148
+ /** Tokens currently occupied by the conversation history (macOS 26.4+). */
149
+ historyTokenCount?: number;
150
+ /** Cumulative usage of the session (macOS 27+). */
151
+ usage?: Usage;
152
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { type output, type ZodType } from 'zod';
2
+ import { type StructuredSchema } from '../schema.js';
3
+ export interface ZodSchemaOptions {
4
+ /**
5
+ * Keep `pattern` next to `format` (Zod adds a regex for `.email()`, `.uuid()` and similar).
6
+ * The on-device model rejects most of these patterns with `UnsupportedSchemaError`, so by
7
+ * default they are dropped and the format is checked by Zod after generation instead.
8
+ */
9
+ keepFormatPatterns?: boolean;
10
+ }
11
+ /**
12
+ * Uses a Zod 4 schema for structured output or tool arguments. The model generates the
13
+ * schema's input shape; the value is then run through `schema.parse`, so transforms and
14
+ * refinements apply and the result has the output type.
15
+ *
16
+ * ```ts
17
+ * const Person = z.object({ name: z.string(), age: z.number().int() })
18
+ * const person = await session.respond('Invent a person', { schema: zodSchema(Person) })
19
+ * ```
20
+ */
21
+ export declare function zodSchema<S extends ZodType>(schema: S, options?: ZodSchemaOptions): StructuredSchema<output<S>>;
@@ -0,0 +1,44 @@
1
+ import { toJSONSchema } from 'zod';
2
+ import { DecodingError } from '../errors.js';
3
+ import { jsonSchema } from '../schema.js';
4
+ /**
5
+ * Uses a Zod 4 schema for structured output or tool arguments. The model generates the
6
+ * schema's input shape; the value is then run through `schema.parse`, so transforms and
7
+ * refinements apply and the result has the output type.
8
+ *
9
+ * ```ts
10
+ * const Person = z.object({ name: z.string(), age: z.number().int() })
11
+ * const person = await session.respond('Invent a person', { schema: zodSchema(Person) })
12
+ * ```
13
+ */
14
+ export function zodSchema(schema, options = {}) {
15
+ const converted = toJSONSchema(schema, { target: 'draft-2020-12', io: 'input', unrepresentable: 'throw' });
16
+ const json = options.keepFormatPatterns ? converted : dropFormatPatterns(converted);
17
+ return jsonSchema(json, (value) => {
18
+ const result = schema.safeParse(value);
19
+ if (result.success)
20
+ return result.data;
21
+ const issue = result.error.issues[0];
22
+ const path = issue ? `#/${issue.path.join('/')}` : '#';
23
+ throw new DecodingError(`Generated value does not match the Zod schema at '${path}': ${issue?.message}`, {
24
+ type: 'decodingFailure',
25
+ data: { path, issues: result.error.issues, rawContent: JSON.stringify(value) },
26
+ cause: result.error,
27
+ });
28
+ });
29
+ }
30
+ function dropFormatPatterns(value) {
31
+ if (Array.isArray(value))
32
+ return value.map(dropFormatPatterns);
33
+ if (typeof value !== 'object' || value === null)
34
+ return value;
35
+ const record = value;
36
+ const out = {};
37
+ for (const [key, v] of Object.entries(record)) {
38
+ if (key === 'pattern' && 'format' in record)
39
+ continue;
40
+ out[key] = dropFormatPatterns(v);
41
+ }
42
+ return out;
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/zod/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,YAAY,EAAgB,MAAM,KAAK,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAmB,UAAU,EAAyB,MAAM,cAAc,CAAA;AAWjF;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CACvB,MAAS,EACT,OAAO,GAAqB,EAAE;IAE9B,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAA;IAC1G,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;IACnF,OAAO,UAAU,CAAC,IAAkB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACtC,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,MAAM,CAAC,IAAI,CAAA;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;QACtD,MAAM,IAAI,aAAa,CAAC,qDAAqD,IAAI,MAAM,KAAK,EAAE,OAAO,EAAE,EAAE;YACvG,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAC9E,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,MAAM,GAAG,KAAgC,CAAA;IAC/C,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,IAAI,GAAG,KAAK,SAAS,IAAI,QAAQ,IAAI,MAAM;YAAE,SAAQ;QACrD,GAAG,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAA;IAClC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "afm-bridge",
3
+ "version": "0.1.0",
4
+ "description": "Apple Foundation Models (on-device LLM) for Electron, Tauri and Node via a Swift sidecar",
5
+ "license": "MIT",
6
+ "author": "Miroslav Švarc",
7
+ "homepage": "https://github.com/mirasvarc/afm-bridge#readme",
8
+ "bugs": "https://github.com/mirasvarc/afm-bridge/issues",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/mirasvarc/afm-bridge.git",
12
+ "directory": "packages/client"
13
+ },
14
+ "type": "module",
15
+ "sideEffects": false,
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./node": {
22
+ "types": "./dist/node/index.d.ts",
23
+ "default": "./dist/node/index.js"
24
+ },
25
+ "./tauri": {
26
+ "types": "./dist/tauri/index.d.ts",
27
+ "default": "./dist/tauri/index.js"
28
+ },
29
+ "./zod": {
30
+ "types": "./dist/zod/index.d.ts",
31
+ "default": "./dist/zod/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "src",
38
+ "README.md",
39
+ "LICENSE"
40
+ ],
41
+ "keywords": [
42
+ "apple",
43
+ "foundation-models",
44
+ "apple-intelligence",
45
+ "llm",
46
+ "on-device",
47
+ "electron",
48
+ "tauri"
49
+ ],
50
+ "engines": {
51
+ "node": ">=20"
52
+ },
53
+ "optionalDependencies": {
54
+ "afm-bridge-darwin-arm64": "0.1.0"
55
+ },
56
+ "devDependencies": {
57
+ "@tauri-apps/plugin-shell": "^2.4.0",
58
+ "@types/node": "^26.6.3",
59
+ "typescript": "^7.0.2",
60
+ "vitest": "^5.0.2",
61
+ "zod": "^4.6.5"
62
+ },
63
+ "peerDependencies": {
64
+ "@tauri-apps/plugin-shell": "^2.0.0",
65
+ "zod": "^4.0.0"
66
+ },
67
+ "peerDependenciesMeta": {
68
+ "@tauri-apps/plugin-shell": {
69
+ "optional": true
70
+ },
71
+ "zod": {
72
+ "optional": true
73
+ }
74
+ },
75
+ "scripts": {
76
+ "build": "tsc -p tsconfig.json",
77
+ "test": "vitest run"
78
+ }
79
+ }