@antfly/embedded-linux-x64 0.0.0-stage → 0.3.0-rc.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.
Files changed (71) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/LICENSES/source-map/apache_engine_files.txt +4 -0
  4. package/LICENSES/source-map/embedded_asset_licenses.json +36 -0
  5. package/LICENSES/source-map/source_license_roots.json +37 -0
  6. package/LICENSES/third-party/HTTPX-MIT.txt +21 -0
  7. package/LICENSES/third-party/LMDB-lmdb-h-notice.txt +26 -0
  8. package/LICENSES/third-party/LMDB-mdb-c-notice.txt +26 -0
  9. package/LICENSES/third-party/LMDB-midl-c-notice.txt +11 -0
  10. package/LICENSES/third-party/LMDB-midl-h-notice.txt +11 -0
  11. package/LICENSES/third-party/OpenLDAP-2.8.txt +47 -0
  12. package/LICENSES/third-party/PacketVideo-AAC-notice.txt +2 -0
  13. package/LICENSES/third-party/PyTorch-BSD-3-Clause.txt +84 -0
  14. package/LICENSES/third-party/Roboto-Apache-2.0.txt +201 -0
  15. package/LICENSES/third-party/Roboto-COPYRIGHT.txt +1 -0
  16. package/LICENSES/third-party/SciPy-rectangular-lsap-BSD-3-Clause.txt +29 -0
  17. package/LICENSES/third-party/Unicode-V3.txt +39 -0
  18. package/LICENSES/third-party/Zig-SHA256-MIT.txt +19 -0
  19. package/LICENSES/third-party/Zig-TLS-MIT.txt +19 -0
  20. package/LICENSES/third-party/dav1d-BSD-2-Clause.txt +23 -0
  21. package/LICENSES/third-party/libvpx-BSD-3-Clause.txt +30 -0
  22. package/README.md +2 -2
  23. package/THIRD_PARTY_NOTICES.md +909 -0
  24. package/include/antfly.h +816 -0
  25. package/lib/libantfly.so +4 -0
  26. package/lib/pkgconfig/libantfly.pc +11 -0
  27. package/package.json +27 -4
  28. package/share/licenses/antfly-inference/LICENSE +202 -0
  29. package/share/licenses/antfly-inference/LICENSES/Apache-2.0.txt +202 -0
  30. package/share/licenses/antfly-inference/LICENSES/third-party/HTTPX-MIT.txt +21 -0
  31. package/share/licenses/antfly-inference/LICENSES/third-party/LMDB-lmdb-h-notice.txt +26 -0
  32. package/share/licenses/antfly-inference/LICENSES/third-party/LMDB-mdb-c-notice.txt +26 -0
  33. package/share/licenses/antfly-inference/LICENSES/third-party/LMDB-midl-c-notice.txt +11 -0
  34. package/share/licenses/antfly-inference/LICENSES/third-party/LMDB-midl-h-notice.txt +11 -0
  35. package/share/licenses/antfly-inference/LICENSES/third-party/OpenLDAP-2.8.txt +47 -0
  36. package/share/licenses/antfly-inference/LICENSES/third-party/PacketVideo-AAC-notice.txt +2 -0
  37. package/share/licenses/antfly-inference/LICENSES/third-party/PyTorch-BSD-3-Clause.txt +84 -0
  38. package/share/licenses/antfly-inference/LICENSES/third-party/Roboto-Apache-2.0.txt +201 -0
  39. package/share/licenses/antfly-inference/LICENSES/third-party/Roboto-COPYRIGHT.txt +1 -0
  40. package/share/licenses/antfly-inference/LICENSES/third-party/SciPy-rectangular-lsap-BSD-3-Clause.txt +29 -0
  41. package/share/licenses/antfly-inference/LICENSES/third-party/Unicode-V3.txt +39 -0
  42. package/share/licenses/antfly-inference/LICENSES/third-party/Zig-SHA256-MIT.txt +19 -0
  43. package/share/licenses/antfly-inference/LICENSES/third-party/Zig-TLS-MIT.txt +19 -0
  44. package/share/licenses/antfly-inference/LICENSES/third-party/dav1d-BSD-2-Clause.txt +23 -0
  45. package/share/licenses/antfly-inference/LICENSES/third-party/libvpx-BSD-3-Clause.txt +30 -0
  46. package/share/licenses/antfly-inference/THIRD_PARTY_NOTICES.md +909 -0
  47. package/share/licenses/antfly-inference/scripts/apache_engine_files.txt +4 -0
  48. package/share/licenses/antfly-inference/scripts/embedded_asset_licenses.json +36 -0
  49. package/share/licenses/antfly-inference/scripts/source_license_roots.json +37 -0
  50. package/share/licenses/antfly-lite/LICENSE +202 -0
  51. package/share/licenses/antfly-lite/LICENSES/Apache-2.0.txt +202 -0
  52. package/share/licenses/antfly-lite/LICENSES/third-party/HTTPX-MIT.txt +21 -0
  53. package/share/licenses/antfly-lite/LICENSES/third-party/LMDB-lmdb-h-notice.txt +26 -0
  54. package/share/licenses/antfly-lite/LICENSES/third-party/LMDB-mdb-c-notice.txt +26 -0
  55. package/share/licenses/antfly-lite/LICENSES/third-party/LMDB-midl-c-notice.txt +11 -0
  56. package/share/licenses/antfly-lite/LICENSES/third-party/LMDB-midl-h-notice.txt +11 -0
  57. package/share/licenses/antfly-lite/LICENSES/third-party/OpenLDAP-2.8.txt +47 -0
  58. package/share/licenses/antfly-lite/LICENSES/third-party/PacketVideo-AAC-notice.txt +2 -0
  59. package/share/licenses/antfly-lite/LICENSES/third-party/PyTorch-BSD-3-Clause.txt +84 -0
  60. package/share/licenses/antfly-lite/LICENSES/third-party/Roboto-Apache-2.0.txt +201 -0
  61. package/share/licenses/antfly-lite/LICENSES/third-party/Roboto-COPYRIGHT.txt +1 -0
  62. package/share/licenses/antfly-lite/LICENSES/third-party/SciPy-rectangular-lsap-BSD-3-Clause.txt +29 -0
  63. package/share/licenses/antfly-lite/LICENSES/third-party/Unicode-V3.txt +39 -0
  64. package/share/licenses/antfly-lite/LICENSES/third-party/Zig-SHA256-MIT.txt +19 -0
  65. package/share/licenses/antfly-lite/LICENSES/third-party/Zig-TLS-MIT.txt +19 -0
  66. package/share/licenses/antfly-lite/LICENSES/third-party/dav1d-BSD-2-Clause.txt +23 -0
  67. package/share/licenses/antfly-lite/LICENSES/third-party/libvpx-BSD-3-Clause.txt +30 -0
  68. package/share/licenses/antfly-lite/THIRD_PARTY_NOTICES.md +909 -0
  69. package/share/licenses/antfly-lite/scripts/apache_engine_files.txt +4 -0
  70. package/share/licenses/antfly-lite/scripts/embedded_asset_licenses.json +36 -0
  71. package/share/licenses/antfly-lite/scripts/source_license_roots.json +37 -0
@@ -0,0 +1,816 @@
1
+ // Copyright 2026 Antfly, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+
16
+ #ifndef ANTFLY_H
17
+ #define ANTFLY_H
18
+
19
+ /* ABI implemented by this header; compare with antfly_abi_version() at runtime. */
20
+ #define ANTFLY_ABI_VERSION 3
21
+
22
+ #include <stdbool.h>
23
+ #include <stddef.h>
24
+ #include <stdint.h>
25
+
26
+ #ifdef __cplusplus
27
+ extern "C" {
28
+ #endif
29
+
30
+ typedef enum antfly_error_code {
31
+ ANTFLY_OK = 0,
32
+ ANTFLY_INVALID_ARGUMENT = 1,
33
+ ANTFLY_NOT_FOUND = 2,
34
+ ANTFLY_VERSION_CONFLICT = 3,
35
+ ANTFLY_INTENT_CONFLICT = 4,
36
+ ANTFLY_TXN_NOT_FOUND = 5,
37
+ ANTFLY_BUSY = 6,
38
+ /* The operation crossed its publication point, but crash durability could
39
+ * not be confirmed. Inspect the destination; do not retry automatically. */
40
+ ANTFLY_OUTCOME_UNKNOWN = 7,
41
+ /* The operation requires a capability unavailable on this platform or
42
+ * filesystem. Retrying unchanged will not succeed. */
43
+ ANTFLY_UNSUPPORTED = 8,
44
+ /* Derived work stalled or a worker failed. Inspect pending-work diagnostics
45
+ * and repair or reopen the database; primary-only writes may still succeed. */
46
+ ANTFLY_STALLED = 9,
47
+ /* The operation was cancelled, including a pending replacement or a
48
+ * progress/stream callback returning false. */
49
+ ANTFLY_CANCELLED = 10,
50
+ /* Stable replacement precondition failures, distinct from malformed input. */
51
+ ANTFLY_REPLACEMENT_FAILED = 11,
52
+ ANTFLY_REPLACEMENT_PENDING = 12,
53
+ ANTFLY_REPLACEMENT_CONFIGURATION_MISMATCH = 13,
54
+ ANTFLY_INTERNAL = 255,
55
+ } antfly_error_code;
56
+
57
+ /*
58
+ * C ABI conventions:
59
+ *
60
+ * - Functions return ANTFLY_OK on success. Any other antfly_error_code is an
61
+ * error and should be handled with the stable strings returned by
62
+ * antfly_error_code_name and antfly_error_code_description.
63
+ * - ANTFLY_OUTCOME_UNKNOWN is not safe to retry automatically: publication
64
+ * completed in the running process, but crash durability was not confirmed.
65
+ * Inspect the caller-supplied destination before deciding how to proceed.
66
+ * - ANTFLY_UNSUPPORTED is not transient. For file restore operations it can
67
+ * mean the source filesystem lacks required advisory locking; copy the
68
+ * archive to a supported local filesystem before retrying.
69
+ * - antfly_slice is borrowed input. The caller owns the memory and must keep it
70
+ * valid for the duration of the call.
71
+ * - antfly_buffer is owned output. On success, the caller owns the returned
72
+ * memory and must release it with antfly_buffer_free, or
73
+ * antfly_buffer_free_zero when the bytes may contain sensitive data.
74
+ * - Status, maintenance, backup, restore, check, and snapshot calls reset
75
+ * antfly_buffer outputs to {NULL, 0} before validating arguments. Other
76
+ * buffer-returning calls require a valid output pointer and only transfer
77
+ * ownership after ANTFLY_OK.
78
+ * - antfly_db handles are owned by the caller after a successful open and
79
+ * must be closed with antfly_db_close. Closing NULL, an already closed
80
+ * handle, or a handle closed concurrently is allowed.
81
+ * - Search result structs own nested allocations only after ANTFLY_OK and must
82
+ * be released with their matching *_free function.
83
+ *
84
+ * Naming: antfly_* functions are library-level and take no database handle;
85
+ * antfly_db_* functions take an antfly_db handle of any storage kind;
86
+ * antfly_lite_* functions operate on the .aflite single-file format itself,
87
+ * plus shortcuts for opening one; antfly_inference_* functions take an
88
+ * antfly_inference handle and run inference without a database.
89
+ */
90
+
91
+ /* An open database. Opaque; see antfly_db_open_with_options. */
92
+ typedef struct antfly_db antfly_db;
93
+
94
+ typedef enum antfly_txn_status {
95
+ ANTFLY_TXN_PENDING = 0,
96
+ ANTFLY_TXN_COMMITTED = 1,
97
+ ANTFLY_TXN_ABORTED = 2,
98
+ } antfly_txn_status;
99
+
100
+ typedef struct antfly_slice {
101
+ const uint8_t *ptr;
102
+ size_t len;
103
+ } antfly_slice;
104
+
105
+ typedef struct antfly_buffer {
106
+ uint8_t *ptr;
107
+ size_t len;
108
+ } antfly_buffer;
109
+
110
+ #define ANTFLY_OPEN_MODE_WRITER 0u
111
+ #define ANTFLY_OPEN_MODE_READONLY 1u
112
+ #define ANTFLY_OPEN_MODE_STATUS_ONLY 2u
113
+
114
+ #define ANTFLY_STORAGE_KIND_DIRECTORY 0u
115
+ #define ANTFLY_STORAGE_KIND_LITE 1u
116
+
117
+ #define ANTFLY_PROFILE_NATIVE 0u
118
+ #define ANTFLY_PROFILE_HOSTED 1u
119
+
120
+ #define ANTFLY_OPEN_FLAG_NO_SYNC (1u << 0)
121
+ #define ANTFLY_OPEN_FLAG_TTL_CLEANUP (1u << 1)
122
+ #define ANTFLY_OPEN_FLAG_REMOTE_PROVIDER_CONFIGURED (1u << 2)
123
+ #define ANTFLY_OPEN_FLAG_LOCAL_RUNTIME_CONFIGURED (1u << 3)
124
+ #define ANTFLY_OPEN_FLAG_GENERATED_ENRICHMENT_REPLAY (1u << 4)
125
+
126
+ /* `inference.mode` values reported by antfly_db_status_json. */
127
+ #define ANTFLY_INFERENCE_MODE_CALLER_SUPPLIED_OR_DISABLED "caller_supplied_or_disabled"
128
+ #define ANTFLY_INFERENCE_MODE_CALLER_SUPPLIED_ARTIFACTS "caller_supplied_artifacts"
129
+ #define ANTFLY_INFERENCE_MODE_REMOTE_PROVIDER "remote_provider"
130
+ #define ANTFLY_INFERENCE_MODE_LOCAL_EMBEDDED "local_embedded"
131
+ #define ANTFLY_INFERENCE_MODE_MANUAL_MAINTENANCE "manual_maintenance"
132
+ #define ANTFLY_INFERENCE_MODE_DISABLED_DEFERRED "disabled_deferred"
133
+
134
+ typedef struct antfly_open_options {
135
+ uint32_t abi_size;
136
+ uint32_t storage_kind;
137
+ uint32_t open_mode;
138
+ uint32_t profile;
139
+ uint32_t flags;
140
+ uint32_t reserved0;
141
+ uint64_t map_size;
142
+ bool ttl_cleanup_enabled;
143
+ bool ttl_cleanup_lease_owned;
144
+ uint32_t ttl_cleanup_batch_size;
145
+ antfly_slice ttl_cleanup_owner_id;
146
+ uint64_t ttl_cleanup_lease_ttl_ms;
147
+ uint64_t ttl_cleanup_interval_ms;
148
+ uint64_t ttl_cleanup_grace_period_ns;
149
+ /* Explicit embedded-inference resource-budget overrides in MiB, 0
150
+ * meaning automatic/host-detected sizing. Only consulted when `flags`
151
+ * carries ANTFLY_OPEN_FLAG_LOCAL_RUNTIME_CONFIGURED; mirror the antfly
152
+ * CLI's --inference-host-budget-mb/--inference-backend-budget-mb/
153
+ * --process-memory-budget-mb. */
154
+ uint32_t inference_host_budget_mb;
155
+ uint32_t inference_backend_budget_mb;
156
+ uint32_t inference_process_memory_budget_mb;
157
+ uint32_t inference_combined_budget_mb;
158
+ uint32_t inference_kv_budget_mb;
159
+ uint32_t inference_scratch_budget_mb;
160
+ /* Milliseconds to retry a Lite operation while another process holds the
161
+ * writer lease (ANTFLY_BUSY), like sqlite3_busy_timeout. 0 fails immediately. */
162
+ uint64_t busy_timeout_ms;
163
+ uint64_t reserved[6];
164
+ /* Optional model directory for database enrichments; empty uses default. */
165
+ antfly_slice models_dir;
166
+ } antfly_open_options;
167
+
168
+ /*
169
+ * Call antfly_open_options_init before setting fields manually. The abi_size
170
+ * field must remain the value returned by antfly_open_options_size so future
171
+ * library versions can detect the caller's struct layout.
172
+ */
173
+
174
+
175
+ typedef struct antfly_write_intent {
176
+ antfly_slice key;
177
+ antfly_slice value;
178
+ bool is_delete;
179
+ } antfly_write_intent;
180
+
181
+ typedef struct antfly_version_predicate {
182
+ antfly_slice key;
183
+ uint64_t expected_version;
184
+ } antfly_version_predicate;
185
+
186
+ typedef struct antfly_dense_search_hit {
187
+ uint8_t *id_ptr;
188
+ size_t id_len;
189
+ float score;
190
+ } antfly_dense_search_hit;
191
+
192
+ typedef struct antfly_dense_search_result {
193
+ antfly_dense_search_hit *hits_ptr;
194
+ size_t hit_count;
195
+ uint32_t total_hits;
196
+ uint64_t identity_read_generation;
197
+ } antfly_dense_search_result;
198
+
199
+ typedef struct antfly_packed_dense_search_hit {
200
+ size_t id_offset;
201
+ size_t id_len;
202
+ float score;
203
+ } antfly_packed_dense_search_hit;
204
+
205
+ typedef struct antfly_packed_dense_search_result {
206
+ antfly_packed_dense_search_hit *hits_ptr;
207
+ size_t hit_count;
208
+ uint32_t total_hits;
209
+ uint8_t *ids_ptr;
210
+ size_t ids_len;
211
+ uint64_t identity_read_generation;
212
+ } antfly_packed_dense_search_result;
213
+
214
+ typedef struct antfly_dense_search_profile {
215
+ uint64_t total_ns;
216
+ uint64_t index_lookup_ns;
217
+ uint64_t search_ns;
218
+ uint64_t hits_ns;
219
+ uint64_t fallback_ns;
220
+ uint64_t hbc_total_ns;
221
+ uint64_t hbc_setup_ns;
222
+ uint64_t hbc_root_load_ns;
223
+ uint64_t hbc_node_cache_miss_ns;
224
+ uint64_t hbc_node_cache_misses;
225
+ uint64_t hbc_quantized_cache_miss_ns;
226
+ uint64_t hbc_quantized_cache_misses;
227
+ uint64_t hbc_child_expand_ns;
228
+ uint64_t hbc_leaf_score_ns;
229
+ uint64_t hbc_rerank_ns;
230
+ uint64_t hbc_rerank_vector_load_ns;
231
+ uint64_t hbc_rerank_distance_ns;
232
+ uint64_t hbc_nodes_visited;
233
+ uint64_t hbc_leaves_explored;
234
+ uint64_t hbc_reranked_vectors;
235
+ uint32_t hit_count;
236
+ uint32_t total_hits;
237
+ bool used_fast_path;
238
+ } antfly_dense_search_profile;
239
+
240
+ typedef struct antfly_dense_wire_search_profile {
241
+ uint64_t total_ns;
242
+ uint64_t decode_ns;
243
+ uint64_t search_ns;
244
+ uint64_t resolve_ns;
245
+ uint64_t encode_ns;
246
+ uint64_t fallback_ns;
247
+ uint64_t hbc_total_ns;
248
+ uint64_t hbc_setup_ns;
249
+ uint64_t hbc_root_load_ns;
250
+ uint64_t hbc_node_cache_miss_ns;
251
+ uint64_t hbc_node_cache_misses;
252
+ uint64_t hbc_quantized_cache_miss_ns;
253
+ uint64_t hbc_quantized_cache_misses;
254
+ uint64_t hbc_child_expand_ns;
255
+ uint64_t hbc_leaf_score_ns;
256
+ uint64_t hbc_rerank_ns;
257
+ uint64_t hbc_rerank_vector_load_ns;
258
+ uint64_t hbc_rerank_distance_ns;
259
+ uint64_t hbc_nodes_visited;
260
+ uint64_t hbc_leaves_explored;
261
+ uint64_t hbc_reranked_vectors;
262
+ uint32_t hit_count;
263
+ uint32_t total_hits;
264
+ bool used_fast_path;
265
+ } antfly_dense_wire_search_profile;
266
+
267
+ typedef struct antfly_scan_hash_entry {
268
+ uint8_t *id_ptr;
269
+ size_t id_len;
270
+ uint64_t hash;
271
+ } antfly_scan_hash_entry;
272
+
273
+ typedef struct antfly_scan_hash_result {
274
+ antfly_scan_hash_entry *entries_ptr;
275
+ size_t entry_count;
276
+ } antfly_scan_hash_result;
277
+
278
+ uint32_t antfly_abi_version(void);
279
+ uint32_t antfly_open_options_size(void);
280
+ /* Borrowed thread-local detail for the last error-code-returning call. Empty
281
+ * on success or when no concrete validation detail is available. Copy before
282
+ * another call on this thread; this accessor never changes the detail. */
283
+ const char *antfly_last_error_detail(void);
284
+ /* Code associated with the retained detail; ANTFLY_OK after success. */
285
+ antfly_error_code antfly_last_error_code(void);
286
+ const char *antfly_error_code_name(antfly_error_code code);
287
+ const char *antfly_error_code_description(antfly_error_code code);
288
+ antfly_error_code antfly_open_options_init(antfly_open_options *options);
289
+
290
+ /*
291
+ * Threading contract, like sqlite3_threadsafe(). ANTFLY_THREADING_SERIALIZED
292
+ * means any thread may call any function on any handle concurrently: reads
293
+ * run in parallel, writes on one handle queue behind each other, and schema
294
+ * or admin changes wait for in-flight calls. See zig/CAPI.md "Thread Safety".
295
+ */
296
+ #define ANTFLY_THREADING_SERIALIZED 1u
297
+ /*
298
+ * Minimum native stack, in bytes, for any thread that calls into libantfly.
299
+ * The storage engine keeps sizable buffers on the stack; release builds use
300
+ * about 2 MiB at peak and debug builds more. 8 MiB is the Linux and macOS
301
+ * main-thread default, but secondary threads are often smaller (512 KiB for
302
+ * macOS pthreads, 2 MiB for Rust std threads): size them explicitly.
303
+ */
304
+ #define ANTFLY_MIN_THREAD_STACK_SIZE (8u * 1024u * 1024u)
305
+ uint32_t antfly_threading_mode(void);
306
+
307
+ /*
308
+ * Storage-neutral opens. ANTFLY_STORAGE_KIND_DIRECTORY opens a normal
309
+ * single-node Antfly directory; ANTFLY_STORAGE_KIND_LITE opens a .aflite
310
+ * single-file database. antfly_db_create_with_options has exclusive-create
311
+ * semantics for ANTFLY_STORAGE_KIND_LITE; directory storage is opened (and
312
+ * created if missing) with antfly_db_open_with_options. NULL options open
313
+ * directory storage with defaults.
314
+ */
315
+ antfly_error_code antfly_db_open(const char *path, antfly_db **out_db);
316
+ antfly_error_code antfly_db_open_with_options(
317
+ const char *path,
318
+ const antfly_open_options *options,
319
+ antfly_db **out_db
320
+ );
321
+ antfly_error_code antfly_db_create_with_options(
322
+ const char *path,
323
+ const antfly_open_options *options,
324
+ antfly_db **out_db
325
+ );
326
+ void antfly_db_close(antfly_db *db);
327
+
328
+ /*
329
+ * Shortcuts for ANTFLY_STORAGE_KIND_LITE with default options.
330
+ * antfly_lite_create* creates a new .aflite database; antfly_lite_open*
331
+ * opens an existing one and never creates a missing file or migrates a
332
+ * pre-release layout.
333
+ */
334
+ antfly_error_code antfly_lite_open(const char *path, antfly_db **out_db);
335
+ antfly_error_code antfly_lite_create(const char *path, antfly_db **out_db);
336
+ antfly_error_code antfly_lite_open_hosted(const char *path, antfly_db **out_db);
337
+ antfly_error_code antfly_lite_create_hosted(const char *path, antfly_db **out_db);
338
+ antfly_error_code antfly_lite_open_readonly(const char *path, antfly_db **out_db);
339
+ antfly_error_code antfly_lite_open_status_only(const char *path, antfly_db **out_db);
340
+
341
+ /* Storage identity, stats, pending work, inference state, and capabilities. */
342
+ antfly_error_code antfly_db_status_json(antfly_db *db, antfly_buffer *out);
343
+ antfly_error_code antfly_db_capabilities_json(antfly_db *db, antfly_buffer *out);
344
+
345
+ /*
346
+ * Portable .afb backups work across storage kinds: a backup of either kind
347
+ * restores or imports into either kind. antfly_db_import_backup requires an
348
+ * empty database with no open table handles, SQL sessions, or cursors.
349
+ * Archives contain the complete catalog and every live table namespace.
350
+ * Backup/import require the database handle. antfly_restore_backup_json and
351
+ * antfly_restore_backup_file_json create a new database at dest_path whose
352
+ * storage kind comes from `options` (NULL means directory storage); other
353
+ * option fields apply when the restored database is opened. `replace`
354
+ * atomically replaces an existing destination.
355
+ */
356
+ antfly_error_code antfly_db_backup(antfly_db *db, antfly_buffer *out);
357
+ /** Portable backup with optional {"tables":["default","healthy"]} scope.
358
+ * Explicit scope includes default and exactly the named tables. Full backup
359
+ * fails closed if any table is unavailable; it never silently omits data. */
360
+ antfly_error_code antfly_db_backup_json(antfly_db *db, antfly_slice options_json, antfly_buffer *out);
361
+ antfly_error_code antfly_db_import_backup(antfly_db *db, antfly_slice backup);
362
+ antfly_error_code antfly_restore_backup_json(
363
+ const char *dest_path,
364
+ const antfly_open_options *options,
365
+ antfly_slice backup,
366
+ bool replace,
367
+ antfly_buffer *out
368
+ );
369
+ antfly_error_code antfly_restore_backup_file_json(
370
+ const char *dest_path,
371
+ const antfly_open_options *options,
372
+ const char *backup_path,
373
+ bool replace,
374
+ antfly_buffer *out
375
+ );
376
+
377
+ /* Operations on the .aflite file format. */
378
+ antfly_error_code antfly_lite_check_json(antfly_db *db, antfly_buffer *out);
379
+ antfly_error_code antfly_lite_check_file_json(const char *path, antfly_buffer *out);
380
+ antfly_error_code antfly_lite_copy_stable_snapshot_json(
381
+ antfly_db *db,
382
+ const char *dest_path,
383
+ bool replace,
384
+ antfly_buffer *out
385
+ );
386
+ antfly_error_code antfly_lite_copy_stable_snapshot_file_json(
387
+ const char *src_path,
388
+ const char *dest_path,
389
+ bool replace,
390
+ antfly_buffer *out
391
+ );
392
+ antfly_error_code antfly_lite_compact_json(antfly_db *db, antfly_buffer *out);
393
+ antfly_error_code antfly_lite_vacuum_json(antfly_db *db, antfly_buffer *out);
394
+
395
+ void antfly_buffer_free(antfly_buffer *buffer);
396
+ void antfly_buffer_free_zero(antfly_buffer *buffer);
397
+ void antfly_dense_search_result_free(antfly_dense_search_result *result);
398
+ void antfly_packed_dense_search_result_free(antfly_packed_dense_search_result *result);
399
+ void antfly_scan_hash_result_free(antfly_scan_hash_result *result);
400
+
401
+ antfly_error_code antfly_db_batch(
402
+ antfly_db *db,
403
+ const antfly_write_intent *writes,
404
+ size_t write_count,
405
+ const antfly_version_predicate *predicates,
406
+ size_t predicate_count,
407
+ uint64_t timestamp_ns,
408
+ uint8_t sync_level
409
+ );
410
+ antfly_error_code antfly_db_batch_json(
411
+ antfly_db *db,
412
+ antfly_slice request_json,
413
+ antfly_buffer *out
414
+ );
415
+ antfly_error_code antfly_db_begin_transaction_with_id(
416
+ antfly_db *db,
417
+ const uint8_t (*txn_id)[16],
418
+ uint64_t timestamp_ns,
419
+ const antfly_slice *participants,
420
+ size_t participant_count
421
+ );
422
+ antfly_error_code antfly_db_write_transaction(
423
+ antfly_db *db,
424
+ const uint8_t (*txn_id)[16],
425
+ const antfly_write_intent *writes,
426
+ size_t write_count,
427
+ const antfly_version_predicate *predicates,
428
+ size_t predicate_count
429
+ );
430
+ antfly_error_code antfly_db_resolve_intents(
431
+ antfly_db *db,
432
+ const uint8_t (*txn_id)[16],
433
+ uint8_t status,
434
+ uint64_t commit_version
435
+ );
436
+ antfly_error_code antfly_db_get_transaction_status(
437
+ antfly_db *db,
438
+ const uint8_t (*txn_id)[16],
439
+ uint8_t *out_status
440
+ );
441
+ antfly_error_code antfly_db_get_commit_version(
442
+ antfly_db *db,
443
+ const uint8_t (*txn_id)[16],
444
+ uint64_t *out_commit_version
445
+ );
446
+ antfly_error_code antfly_db_get_timestamp(antfly_db *db, antfly_slice key, uint64_t *out_timestamp);
447
+ antfly_error_code antfly_db_lookup_json(antfly_db *db, antfly_slice key, antfly_buffer *out);
448
+ antfly_error_code antfly_db_get_raw(antfly_db *db, antfly_slice key, antfly_buffer *out);
449
+ antfly_error_code antfly_db_get_schema_json(antfly_db *db, antfly_buffer *out);
450
+ antfly_error_code antfly_db_set_schema_json(antfly_db *db, antfly_slice schema_json);
451
+ antfly_error_code antfly_db_run_until_idle(antfly_db *db);
452
+ antfly_error_code antfly_db_run_until_idle_json(antfly_db *db, antfly_buffer *out);
453
+ antfly_error_code antfly_db_pending_work_stats_json(antfly_db *db, antfly_buffer *out);
454
+ antfly_error_code antfly_db_replay_generated_enrichments_json(antfly_db *db, antfly_buffer *out);
455
+ antfly_error_code antfly_db_list_indexes_json(antfly_db *db, antfly_buffer *out);
456
+ /** Render a durable resolver's key without writes. Mention JSON: {"text","label"}.
457
+ * Returns {"minted_key","key","table","config_generation"}; key follows configured aliases.
458
+ * Free output with antfly_buffer_free. ANN matching is not performed. */
459
+ antfly_error_code antfly_db_render_resolver_key_json(antfly_db *db, antfly_slice resolver_name, antfly_slice mention_json, antfly_buffer *out_json);
460
+
461
+ /* Resolve {"text":"..."} through the resolver's configured asset extractor, or
462
+ * {"extraction":{"entities":[...]}} through the same resolver. Includes aliases,
463
+ * mention embeddings, ANN candidates and scoring. Returns {extraction,resolution}
464
+ * with canonical doc_refs and decisions. Does not write documents or artifacts.
465
+ * Requires an asset-scoped resolver; text requires an extractor producer. */
466
+ antfly_error_code antfly_db_resolve_query_json(antfly_db *db, antfly_slice resolver_name, antfly_slice request_json, antfly_buffer *out_json);
467
+ /** Merge fully rendered keys: {"key":"concept/old","target":"concept/new"}.
468
+ * Durable and idempotent. Cycles/redirect replacement are rejected. Drain with
469
+ * antfly_db_run_until_idle to re-resolve existing artifacts and replace mention edges.
470
+ * Promotion-enabled resolvers also reconcile entity documents. Arbitrary application
471
+ * references and manually supplied graph edges are not rewritten.
472
+ * May return ANTFLY_BUSY during replay/promotion; retry with bounded backoff. */
473
+ antfly_error_code antfly_db_merge_resolver_keys_json(antfly_db *db, antfly_slice resolver_name, antfly_slice merge_json);
474
+
475
+ /* Lists active and retired identities, including durable merges. */
476
+ antfly_error_code antfly_db_list_resolver_identities_json(antfly_db *db, antfly_buffer *out);
477
+ /* Drops a retired identity and its merges; rejects an active identity.
478
+ * Existing resolution artifacts and promoted documents remain. Delete source
479
+ * documents to remove their artifacts; delete canonical rows explicitly only
480
+ * after checking other resolvers/application references.
481
+ * May return ANTFLY_BUSY during replay/promotion; retry with bounded backoff. */
482
+ antfly_error_code antfly_db_drop_resolver_identity(antfly_db *db, antfly_slice resolver_name, bool *out_deleted);
483
+ /** Set {table,key_template} and choose reset_merges:true (clears inline aliases too,
484
+ * unless an explicit replacement aliases array is supplied) or
485
+ * key_map:[{key,target},...] mapping every inline/durable alias endpoint.
486
+ * A durable fence rejects stale inline namespaces/aliases even after reset.
487
+ * Validates atomically; drain to reconcile resolver-owned artifacts and edges.
488
+ * Application-owned documents/references are not renamed.
489
+ * May return ANTFLY_BUSY during replay/promotion; retry with bounded backoff. */
490
+ antfly_error_code antfly_db_set_resolver_namespace_json(antfly_db *db, antfly_slice resolver_name, antfly_slice request_json);
491
+
492
+ /* Schema admission (add, replaces, delete, namespace changes and identity drop)
493
+ * may return ANTFLY_BUSY before mutation when replay/promotion is active for
494
+ * approximately 100 ms. Retry the identical request with bounded backoff.
495
+ * replaces registers a hidden resumable shadow and returns; the old graph
496
+ * serves until background activation. Identical requests are idempotent.
497
+ * Acts as add when the old index is absent. Optional wait:{timeout_ms:N}
498
+ * waits for activation; deadline BUSY leaves the accepted shadow running.
499
+ * Waiting releases admission between work quanta and remains bound to the
500
+ * admitted generation. Cancellation or target-name reuse returns ANTFLY_CANCELLED;
501
+ * a different generation under the same name never completes the original wait.
502
+ * Precondition failures are ANTFLY_REPLACEMENT_FAILED,
503
+ * ANTFLY_REPLACEMENT_PENDING or ANTFLY_REPLACEMENT_CONFIGURATION_MISMATCH.
504
+ * pending_work_stats_json reports progress, retry_count, retry_after_ns and
505
+ * last_error. Consecutive transient failures retry four times with persisted
506
+ * backoff; durable forward progress resets the consecutive budget. A separate
507
+ * lifetime ceiling permits at most 64 retries (total_retry_count/max_total_retries
508
+ * in status). Backward-clock deadlines are clamped to at most 3.2 seconds.
509
+ * ANTFLY_CANCELLED also covers interrupted IO/mutex admission; interruption of
510
+ * a call does not cancel accepted work. Inspect state if completion raced it. */
511
+ antfly_error_code antfly_db_add_index_json(antfly_db *db, antfly_slice config_json);
512
+ /* May return ANTFLY_BUSY during replay/promotion; retry with bounded backoff. */
513
+ antfly_error_code antfly_db_delete_index(antfly_db *db, antfly_slice name, bool *out_deleted);
514
+ /** Cancel a running or failed shadow by its new name; idempotent. Leaves the
515
+ * serving index intact and schedules bounded shadow-artifact cleanup. Failed
516
+ * jobs do not retry or pin replay; cancel before registering a fresh attempt.
517
+ * delete_index on either name also cancels dependent replacements. */
518
+ antfly_error_code antfly_db_cancel_replacement(antfly_db *db, antfly_slice name, bool *out_cancelled);
519
+ antfly_error_code antfly_db_list_enrichments_json(antfly_db *db, antfly_buffer *out);
520
+ antfly_error_code antfly_db_add_enrichment_json(antfly_db *db, antfly_slice config_json);
521
+ antfly_error_code antfly_db_delete_enrichment(
522
+ antfly_db *db,
523
+ antfly_slice kind,
524
+ antfly_slice name,
525
+ bool *out_deleted
526
+ );
527
+ antfly_error_code antfly_db_scan_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
528
+ antfly_error_code antfly_db_scan_hashes(
529
+ antfly_db *db,
530
+ antfly_slice request_json,
531
+ antfly_scan_hash_result *out_result
532
+ );
533
+ antfly_error_code antfly_db_stats_json(antfly_db *db, antfly_buffer *out);
534
+ antfly_error_code antfly_db_search_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
535
+ /* Database SQL; uses statement/parameters/limit and optional session_id.
536
+ * Logical tables are resolved from the durable database catalog.
537
+ * Always free a nonempty out buffer, including SQL diagnostics on error. */
538
+ antfly_error_code antfly_db_sql_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
539
+
540
+ /* Logical tables have independent schemas, indexes, and document identities.
541
+ * Dropped table IDs are never reused. The root document table is "default". */
542
+ antfly_error_code antfly_db_create_table_json(antfly_db *db, antfly_slice table_name, antfly_slice schema_json);
543
+ /* A table handle supports the document/schema/index/enrichment APIs. Close it
544
+ * with antfly_db_close. Database close invalidates all its table handles. DROP
545
+ * requires its table handles and SQL cursors to be closed first. */
546
+ antfly_error_code antfly_db_open_table(antfly_db *db, antfly_slice table_name, antfly_db **out_table);
547
+ antfly_error_code antfly_db_drop_table(antfly_db *db, antfly_slice table_name);
548
+ antfly_error_code antfly_db_list_tables_json(antfly_db *db, antfly_buffer *out);
549
+
550
+ /* Describe binds without executing; returns columns and parameter_types. */
551
+ antfly_error_code antfly_db_sql_describe_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
552
+
553
+ /* Sessions are connection-local; close abandons staged writes and cursors.
554
+ * BEGIN ISOLATION LEVEL READ COMMITTED is supported, with savepoints.
555
+ * Stronger isolation is rejected. COMMIT uses a durable native decision. */
556
+ antfly_error_code antfly_db_sql_session_open(antfly_db *db, uint64_t *out_session);
557
+ antfly_error_code antfly_db_sql_session_close(antfly_db *db, uint64_t session);
558
+
559
+ /* Cursors belong to db. Requests contain statement and parameters. Fetch
560
+ * returns {"result": <SQL result>, "exhausted": bool}. Fetch sizes are 1..4096.
561
+ * Explicit close releases snapshots; database close releases every cursor.
562
+ * Error buffers contain SQLSTATE diagnostics and must also be freed. */
563
+ antfly_error_code antfly_db_sql_open_cursor_json(antfly_db *db, antfly_slice request_json, uint64_t *out_cursor, antfly_buffer *out_error);
564
+ antfly_error_code antfly_db_sql_fetch_cursor_json(antfly_db *db, uint64_t cursor, uint32_t rows, antfly_buffer *out);
565
+ antfly_error_code antfly_db_sql_close_cursor(antfly_db *db, uint64_t cursor);
566
+ antfly_error_code antfly_db_search_dense(
567
+ antfly_db *db,
568
+ antfly_slice index_name,
569
+ const float *vector_ptr,
570
+ size_t vector_len,
571
+ uint32_t k,
572
+ uint32_t limit,
573
+ uint32_t offset,
574
+ antfly_packed_dense_search_result *out_result
575
+ );
576
+ antfly_error_code antfly_db_search_dense_profile(
577
+ antfly_db *db,
578
+ antfly_slice index_name,
579
+ const float *vector_ptr,
580
+ size_t vector_len,
581
+ uint32_t k,
582
+ uint32_t limit,
583
+ uint32_t offset,
584
+ antfly_dense_search_profile *out_profile
585
+ );
586
+ antfly_error_code antfly_db_search_dense_wire(
587
+ antfly_db *db,
588
+ antfly_slice request_buf,
589
+ antfly_buffer *out
590
+ );
591
+ antfly_error_code antfly_db_search_dense_wire_profile(
592
+ antfly_db *db,
593
+ antfly_slice request_buf,
594
+ antfly_buffer *out,
595
+ antfly_dense_wire_search_profile *out_profile
596
+ );
597
+ antfly_error_code antfly_db_search_text_match(
598
+ antfly_db *db,
599
+ antfly_slice index_name,
600
+ antfly_slice field,
601
+ antfly_slice text,
602
+ uint32_t limit,
603
+ uint32_t offset,
604
+ antfly_dense_search_result *out_result
605
+ );
606
+ antfly_error_code antfly_db_search_text_match_wire(antfly_db *db, antfly_slice request_buf, antfly_buffer *out);
607
+ antfly_error_code antfly_db_search_text_term_wire(antfly_db *db, antfly_slice request_buf, antfly_buffer *out);
608
+ antfly_error_code antfly_db_search_text_match_phrase_wire(antfly_db *db, antfly_slice request_buf, antfly_buffer *out);
609
+ antfly_error_code antfly_db_search_hits_json(
610
+ antfly_db *db,
611
+ antfly_slice request_json,
612
+ antfly_dense_search_result *out_result
613
+ );
614
+ antfly_error_code antfly_db_aggregate_hits_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
615
+ antfly_error_code antfly_db_lookup_artifact_json(antfly_db *db, antfly_slice artifact_id_b64, antfly_buffer *out);
616
+ antfly_error_code antfly_decode_artifact_id_json(antfly_slice artifact_id_b64, antfly_buffer *out);
617
+ antfly_error_code antfly_db_extract_enrichments_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
618
+ antfly_error_code antfly_db_compute_enrichments_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
619
+
620
+ /* `direction` values for antfly_db_get_edges_json and
621
+ * antfly_db_get_neighbors_json. */
622
+ #define ANTFLY_GRAPH_DIRECTION_OUT 0u
623
+ #define ANTFLY_GRAPH_DIRECTION_IN 1u
624
+ #define ANTFLY_GRAPH_DIRECTION_BOTH 2u
625
+ antfly_error_code antfly_db_get_edges_json(
626
+ antfly_db *db,
627
+ antfly_slice index_name,
628
+ antfly_slice key,
629
+ antfly_slice edge_type,
630
+ uint8_t direction,
631
+ antfly_buffer *out
632
+ );
633
+ antfly_error_code antfly_db_traverse_edges_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
634
+ antfly_error_code antfly_db_execute_graph_queries_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
635
+ antfly_error_code antfly_db_get_neighbors_json(
636
+ antfly_db *db,
637
+ antfly_slice index_name,
638
+ antfly_slice key,
639
+ antfly_slice edge_type,
640
+ uint8_t direction,
641
+ antfly_buffer *out
642
+ );
643
+ antfly_error_code antfly_db_find_shortest_path_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
644
+ antfly_error_code antfly_db_find_k_shortest_paths_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
645
+ antfly_error_code antfly_db_match_pattern_json(antfly_db *db, antfly_slice request_json, antfly_buffer *out);
646
+
647
+ /*
648
+ * Embedded inference without a database.
649
+ *
650
+ * An antfly_inference handle owns an inference runtime: models load on first
651
+ * use and stay cached until the handle closes. Each call takes the request
652
+ * JSON and returns the response JSON of the matching /ai/v1 route of the
653
+ * Antfly inference HTTP API (see specs/openapi/inference/api.yaml): embed,
654
+ * rerank, chunk, generate, generate/batch, rewrite, decide, extract, read (OCR),
655
+ * transcribe, and models. Binary inputs such as images and audio are passed inline, as base64
656
+ * or data: URIs. The _json calls return complete responses: a generate
657
+ * request with "stream": true fails with ANTFLY_INVALID_ARGUMENT; use
658
+ * antfly_inference_generate_stream_json to stream.
659
+ *
660
+ * Every call resets *out, then fills it with the response body whether or
661
+ * not the call succeeds, so a failure carries the runtime's JSON error
662
+ * ({"error": ..., "message": ...}); release it with antfly_buffer_free
663
+ * either way. An HTTP 4xx maps to ANTFLY_INVALID_ARGUMENT, 404 (such as a
664
+ * model that is not installed) to ANTFLY_NOT_FOUND, 429/503/504 and an
665
+ * elapsed call_timeout_ms to ANTFLY_BUSY, and 501 or 507 (the model does not
666
+ * fit the memory budgets) to ANTFLY_UNSUPPORTED.
667
+ *
668
+ * Models are not downloaded automatically; install them with
669
+ * `antfly inference pull <owner/name>` or antfly_inference_pull_json.
670
+ * antfly_inference_open returns ANTFLY_UNSUPPORTED when this build does not
671
+ * link the inference runtime or the runtime cannot start.
672
+ *
673
+ * Models run in the calling process on every backend, including Metal, CUDA,
674
+ * and ONNX. Those backends cannot interrupt a call once it reaches the device
675
+ * or driver: call_timeout_ms and closing the handle take effect only when the
676
+ * call returns, and a driver fault terminates the process. (The antfly server
677
+ * instead runs them in a worker process it can kill and restart.)
678
+ *
679
+ * Handles have the same safety as antfly_db handles: any thread may call
680
+ * concurrently, close waits for in-flight calls, and a closed or foreign
681
+ * handle is rejected with ANTFLY_INVALID_ARGUMENT.
682
+ */
683
+ typedef struct antfly_inference antfly_inference;
684
+
685
+ typedef struct antfly_inference_options {
686
+ uint32_t abi_size;
687
+ /* No flags are defined yet; must be zero. */
688
+ uint32_t flags;
689
+ /* Models directory. Empty uses $ANTFLY_INFERENCE_MODELS_DIR, else
690
+ * ~/.antfly/inference/models. */
691
+ antfly_slice models_dir;
692
+ /* Resource budgets in MiB, 0 meaning automatic; the same knobs as the
693
+ * inference_*_budget_mb fields of antfly_open_options. */
694
+ uint32_t host_budget_mb;
695
+ uint32_t backend_budget_mb;
696
+ uint32_t process_memory_budget_mb;
697
+ uint32_t combined_budget_mb;
698
+ uint32_t kv_budget_mb;
699
+ uint32_t scratch_budget_mb;
700
+ /* Deadline for each call in milliseconds; 0 means none. */
701
+ uint64_t call_timeout_ms;
702
+ uint64_t reserved[8];
703
+ } antfly_inference_options;
704
+
705
+ uint32_t antfly_inference_options_size(void);
706
+ antfly_error_code antfly_inference_options_init(antfly_inference_options *options);
707
+ /* options may be NULL for defaults. */
708
+ antfly_error_code antfly_inference_open(
709
+ const antfly_inference_options *options,
710
+ antfly_inference **out_inference
711
+ );
712
+ void antfly_inference_close(antfly_inference *inference);
713
+
714
+ antfly_error_code antfly_inference_embed_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
715
+ antfly_error_code antfly_inference_rerank_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
716
+ antfly_error_code antfly_inference_chunk_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
717
+ antfly_error_code antfly_inference_generate_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
718
+ /* Receives one streamed chunk: the JSON of a "chat.completion.chunk", valid
719
+ * only during the call. Return true to continue, false to stop generating. */
720
+ typedef bool (*antfly_inference_stream_fn)(void *context, antfly_slice chunk_json);
721
+
722
+ /*
723
+ * Streams a generate request (the same body as antfly_inference_generate_json;
724
+ * "stream" is set for you). on_chunk is called on the calling thread for each
725
+ * chunk, as the model produces tokens; generation waits for each call to
726
+ * return. Returns ANTFLY_OK once generation
727
+ * finishes, or ANTFLY_CANCELLED when on_chunk returned false. A request
728
+ * rejected before generation starts (such as a missing model) fails as
729
+ * antfly_inference_generate_json does, with the JSON error in *out; a failure
730
+ * mid-stream returns ANTFLY_INTERNAL with {"error": "STREAM_FAILED", ...}.
731
+ */
732
+ antfly_error_code antfly_inference_generate_stream_json(
733
+ antfly_inference *inference,
734
+ antfly_slice request_json,
735
+ antfly_inference_stream_fn on_chunk,
736
+ void *chunk_context,
737
+ antfly_buffer *out
738
+ );
739
+
740
+ /* Up to 128 non-streaming generate requests in one call; per-item failures
741
+ * are reported in the response. */
742
+ antfly_error_code antfly_inference_generate_batch_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
743
+ antfly_error_code antfly_inference_rewrite_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
744
+ /* Named choice, ordinal score, and Boolean questions. Uses DecideRequest and
745
+ * DecideResponse from specs/openapi/inference/api.yaml; no database required. */
746
+ antfly_error_code antfly_inference_decide_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
747
+ antfly_error_code antfly_inference_extract_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
748
+ antfly_error_code antfly_inference_read_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
749
+ antfly_error_code antfly_inference_transcribe_json(antfly_inference *inference, antfly_slice request_json, antfly_buffer *out);
750
+ /* The installed models, as returned by GET /ai/v1/models. */
751
+ antfly_error_code antfly_inference_list_models_json(antfly_inference *inference, antfly_buffer *out);
752
+
753
+ /* One report to an antfly_inference_pull_json progress callback. The slices
754
+ * are valid only during the callback. Check abi_size before reading fields
755
+ * added in later versions. */
756
+ typedef struct antfly_inference_pull_progress {
757
+ uint32_t abi_size;
758
+ uint32_t reserved0;
759
+ /* The model reference this report is for: one per requested variant, or
760
+ * a companion model the requested one needs (such as the speculative
761
+ * decoding assistant of a Gemma 4 QAT checkpoint), whose files are
762
+ * counted separately. */
763
+ antfly_slice model;
764
+ antfly_slice file;
765
+ uint64_t bytes_downloaded;
766
+ /* 0 when unknown. */
767
+ uint64_t total_bytes;
768
+ uint64_t files_done;
769
+ uint64_t files_total;
770
+ /* The file was already present and verified; nothing was downloaded. */
771
+ bool cached;
772
+ } antfly_inference_pull_progress;
773
+
774
+ /* Return true to continue, false to cancel the pull. */
775
+ typedef bool (*antfly_inference_pull_progress_fn)(
776
+ void *context,
777
+ const antfly_inference_pull_progress *progress
778
+ );
779
+
780
+ /*
781
+ * Downloads a model from the Hugging Face Hub into the handle's models
782
+ * directory, like `antfly inference pull`. request_json:
783
+ *
784
+ * {"model": "owner/name[:variant]", required
785
+ * "variants": ["q8_0", ...], pull model:variant for each
786
+ * "token": "...", private or gated models; default $HF_TOKEN
787
+ * "tasks": [...], "capabilities": [...], override the model manifest
788
+ * "projector": "auto" | "none" | "match",
789
+ * "max_artifact_bytes": N, "max_model_bytes": N}
790
+ *
791
+ * progress (may be NULL) is called on the calling thread as each file
792
+ * starts, every 16 MiB, and as it completes; the download waits for each
793
+ * call to return. Returning false cancels: the call returns ANTFLY_CANCELLED
794
+ * and the model is not installed, even if that was the last report.
795
+ * Completed files stay staged, so pulling the same model again resumes
796
+ * rather than restarts.
797
+ *
798
+ * On success *out is {"models": [...], "models_dir": "..."}; on failure it is
799
+ * {"error": ..., "message": ...}. A model missing from the hub returns
800
+ * ANTFLY_NOT_FOUND, a bad request or a model over the size limits
801
+ * ANTFLY_INVALID_ARGUMENT, and a network or hub failure ANTFLY_BUSY.
802
+ * antfly_inference_close waits for a pull in progress.
803
+ */
804
+ antfly_error_code antfly_inference_pull_json(
805
+ antfly_inference *inference,
806
+ antfly_slice request_json,
807
+ antfly_inference_pull_progress_fn progress,
808
+ void *progress_context,
809
+ antfly_buffer *out
810
+ );
811
+
812
+ #ifdef __cplusplus
813
+ }
814
+ #endif
815
+
816
+ #endif