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.
- package/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.js +216 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +111 -0
- package/dist/errors.js +152 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/node/index.d.ts +28 -0
- package/dist/node/index.js +177 -0
- package/dist/node/index.js.map +1 -0
- package/dist/rpc.d.ts +37 -0
- package/dist/rpc.js +172 -0
- package/dist/rpc.js.map +1 -0
- package/dist/schema.d.ts +53 -0
- package/dist/schema.js +149 -0
- package/dist/schema.js.map +1 -0
- package/dist/session.d.ts +63 -0
- package/dist/session.js +202 -0
- package/dist/session.js.map +1 -0
- package/dist/tauri/index.d.ts +29 -0
- package/dist/tauri/index.js +80 -0
- package/dist/tauri/index.js.map +1 -0
- package/dist/tool.d.ts +39 -0
- package/dist/tool.js +48 -0
- package/dist/tool.js.map +1 -0
- package/dist/transport.d.ts +37 -0
- package/dist/transport.js +24 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/zod/index.d.ts +21 -0
- package/dist/zod/index.js +44 -0
- package/dist/zod/index.js.map +1 -0
- package/package.json +79 -0
- package/src/client.ts +312 -0
- package/src/errors.ts +170 -0
- package/src/index.ts +22 -0
- package/src/node/index.ts +203 -0
- package/src/rpc.ts +204 -0
- package/src/schema.ts +206 -0
- package/src/session.ts +290 -0
- package/src/tauri/index.ts +100 -0
- package/src/tool.ts +80 -0
- package/src/transport.ts +60 -0
- package/src/types.ts +142 -0
- package/src/zod/index.ts +53 -0
package/src/zod/index.ts
ADDED
|
@@ -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
|
+
}
|