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,53 @@
1
+ import { type output, toJSONSchema, type ZodType } from 'zod'
2
+ import { DecodingError } from '../errors.js'
3
+ import { type JSONSchema, jsonSchema, type StructuredSchema } from '../schema.js'
4
+
5
+ export interface ZodSchemaOptions {
6
+ /**
7
+ * Keep `pattern` next to `format` (Zod adds a regex for `.email()`, `.uuid()` and similar).
8
+ * The on-device model rejects most of these patterns with `UnsupportedSchemaError`, so by
9
+ * default they are dropped and the format is checked by Zod after generation instead.
10
+ */
11
+ keepFormatPatterns?: boolean
12
+ }
13
+
14
+ /**
15
+ * Uses a Zod 4 schema for structured output or tool arguments. The model generates the
16
+ * schema's input shape; the value is then run through `schema.parse`, so transforms and
17
+ * refinements apply and the result has the output type.
18
+ *
19
+ * ```ts
20
+ * const Person = z.object({ name: z.string(), age: z.number().int() })
21
+ * const person = await session.respond('Invent a person', { schema: zodSchema(Person) })
22
+ * ```
23
+ */
24
+ export function zodSchema<S extends ZodType>(
25
+ schema: S,
26
+ options: ZodSchemaOptions = {},
27
+ ): StructuredSchema<output<S>> {
28
+ const converted = toJSONSchema(schema, { target: 'draft-2020-12', io: 'input', unrepresentable: 'throw' })
29
+ const json = options.keepFormatPatterns ? converted : dropFormatPatterns(converted)
30
+ return jsonSchema(json as JSONSchema, (value) => {
31
+ const result = schema.safeParse(value)
32
+ if (result.success) return result.data
33
+ const issue = result.error.issues[0]
34
+ const path = issue ? `#/${issue.path.join('/')}` : '#'
35
+ throw new DecodingError(`Generated value does not match the Zod schema at '${path}': ${issue?.message}`, {
36
+ type: 'decodingFailure',
37
+ data: { path, issues: result.error.issues, rawContent: JSON.stringify(value) },
38
+ cause: result.error,
39
+ })
40
+ })
41
+ }
42
+
43
+ function dropFormatPatterns(value: unknown): unknown {
44
+ if (Array.isArray(value)) return value.map(dropFormatPatterns)
45
+ if (typeof value !== 'object' || value === null) return value
46
+ const record = value as Record<string, unknown>
47
+ const out: Record<string, unknown> = {}
48
+ for (const [key, v] of Object.entries(record)) {
49
+ if (key === 'pattern' && 'format' in record) continue
50
+ out[key] = dropFormatPatterns(v)
51
+ }
52
+ return out
53
+ }