react-native-nitro-mlx 0.2.2 → 0.3.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 (59) hide show
  1. package/MLXReactNative.podspec +1 -1
  2. package/ios/Sources/HybridLLM.swift +250 -15
  3. package/lib/module/index.js +1 -0
  4. package/lib/module/index.js.map +1 -1
  5. package/lib/module/llm.js +33 -3
  6. package/lib/module/llm.js.map +1 -1
  7. package/lib/module/tool-utils.js +56 -0
  8. package/lib/module/tool-utils.js.map +1 -0
  9. package/lib/typescript/src/index.d.ts +3 -2
  10. package/lib/typescript/src/index.d.ts.map +1 -1
  11. package/lib/typescript/src/llm.d.ts +14 -2
  12. package/lib/typescript/src/llm.d.ts.map +1 -1
  13. package/lib/typescript/src/specs/LLM.nitro.d.ts +30 -3
  14. package/lib/typescript/src/specs/LLM.nitro.d.ts.map +1 -1
  15. package/lib/typescript/src/tool-utils.d.ts +13 -0
  16. package/lib/typescript/src/tool-utils.d.ts.map +1 -0
  17. package/nitrogen/generated/ios/MLXReactNative+autolinking.rb +1 -1
  18. package/nitrogen/generated/ios/MLXReactNative-Swift-Cxx-Bridge.cpp +34 -1
  19. package/nitrogen/generated/ios/MLXReactNative-Swift-Cxx-Bridge.hpp +173 -1
  20. package/nitrogen/generated/ios/MLXReactNative-Swift-Cxx-Umbrella.hpp +8 -1
  21. package/nitrogen/generated/ios/MLXReactNativeAutolinking.mm +1 -1
  22. package/nitrogen/generated/ios/MLXReactNativeAutolinking.swift +1 -1
  23. package/nitrogen/generated/ios/c++/HybridLLMSpecSwift.cpp +1 -1
  24. package/nitrogen/generated/ios/c++/HybridLLMSpecSwift.hpp +10 -3
  25. package/nitrogen/generated/ios/c++/HybridModelManagerSpecSwift.cpp +1 -1
  26. package/nitrogen/generated/ios/c++/HybridModelManagerSpecSwift.hpp +1 -1
  27. package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_std__shared_ptr_AnyMap______std__shared_ptr_AnyMap_.swift +62 -0
  28. package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
  29. package/nitrogen/generated/ios/swift/Func_void_bool.swift +1 -1
  30. package/nitrogen/generated/ios/swift/Func_void_double.swift +1 -1
  31. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +1 -1
  32. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_AnyMap_.swift +47 -0
  33. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_std__shared_ptr_AnyMap___.swift +67 -0
  34. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +1 -1
  35. package/nitrogen/generated/ios/swift/Func_void_std__string_std__string.swift +47 -0
  36. package/nitrogen/generated/ios/swift/Func_void_std__vector_std__string_.swift +1 -1
  37. package/nitrogen/generated/ios/swift/GenerationStats.swift +1 -1
  38. package/nitrogen/generated/ios/swift/HybridLLMSpec.swift +2 -2
  39. package/nitrogen/generated/ios/swift/HybridLLMSpec_cxx.swift +14 -2
  40. package/nitrogen/generated/ios/swift/HybridModelManagerSpec.swift +1 -1
  41. package/nitrogen/generated/ios/swift/HybridModelManagerSpec_cxx.swift +1 -1
  42. package/nitrogen/generated/ios/swift/LLMLoadOptions.swift +44 -2
  43. package/nitrogen/generated/ios/swift/LLMMessage.swift +1 -1
  44. package/nitrogen/generated/ios/swift/ToolDefinition.swift +113 -0
  45. package/nitrogen/generated/ios/swift/ToolParameter.swift +69 -0
  46. package/nitrogen/generated/shared/c++/GenerationStats.hpp +1 -1
  47. package/nitrogen/generated/shared/c++/HybridLLMSpec.cpp +1 -1
  48. package/nitrogen/generated/shared/c++/HybridLLMSpec.hpp +2 -2
  49. package/nitrogen/generated/shared/c++/HybridModelManagerSpec.cpp +1 -1
  50. package/nitrogen/generated/shared/c++/HybridModelManagerSpec.hpp +1 -1
  51. package/nitrogen/generated/shared/c++/LLMLoadOptions.hpp +10 -3
  52. package/nitrogen/generated/shared/c++/LLMMessage.hpp +1 -1
  53. package/nitrogen/generated/shared/c++/ToolDefinition.hpp +93 -0
  54. package/nitrogen/generated/shared/c++/ToolParameter.hpp +87 -0
  55. package/package.json +8 -7
  56. package/src/index.ts +10 -3
  57. package/src/llm.ts +42 -3
  58. package/src/specs/LLM.nitro.ts +37 -3
  59. package/src/tool-utils.ts +74 -0
@@ -24,7 +24,7 @@ Pod::Spec.new do |s|
24
24
 
25
25
  spm_dependency(s,
26
26
  url: "https://github.com/ml-explore/mlx-swift-lm.git",
27
- requirement: {kind: "upToNextMinorVersion", minimumVersion: "2.29.2"},
27
+ requirement: {kind: "upToNextMinorVersion", minimumVersion: "2.29.3"},
28
28
  products: ["MLXLLM", "MLXLMCommon"]
29
29
  )
30
30
 
@@ -3,6 +3,7 @@ import NitroModules
3
3
  internal import MLX
4
4
  internal import MLXLLM
5
5
  internal import MLXLMCommon
6
+ internal import Tokenizers
6
7
 
7
8
  class HybridLLM: HybridLLMSpec {
8
9
  private var session: ChatSession?
@@ -19,6 +20,9 @@ class HybridLLM: HybridLLMSpec {
19
20
  private var messageHistory: [LLMMessage] = []
20
21
  private var loadTask: Task<Void, Error>?
21
22
 
23
+ private var tools: [ToolDefinition] = []
24
+ private var toolSchemas: [ToolSpec] = []
25
+
22
26
  var isLoaded: Bool { session != nil }
23
27
  var isGenerating: Bool { currentTask != nil }
24
28
  var modelId: String = ""
@@ -61,6 +65,34 @@ class HybridLLM: HybridLLMSpec {
61
65
  allocatedMB, cacheMB, peakMB)
62
66
  }
63
67
 
68
+ private func buildToolSchema(from tool: ToolDefinition) -> ToolSpec {
69
+ var properties: [String: [String: Any]] = [:]
70
+ var required: [String] = []
71
+
72
+ for param in tool.parameters {
73
+ properties[param.name] = [
74
+ "type": param.type,
75
+ "description": param.description
76
+ ]
77
+ if param.required {
78
+ required.append(param.name)
79
+ }
80
+ }
81
+
82
+ return [
83
+ "type": "function",
84
+ "function": [
85
+ "name": tool.name,
86
+ "description": tool.description,
87
+ "parameters": [
88
+ "type": "object",
89
+ "properties": properties,
90
+ "required": required
91
+ ]
92
+ ]
93
+ ] as ToolSpec
94
+ }
95
+
64
96
  func load(modelId: String, options: LLMLoadOptions?) throws -> Promise<Void> {
65
97
  self.loadTask?.cancel()
66
98
 
@@ -72,6 +104,8 @@ class HybridLLM: HybridLLMSpec {
72
104
  self.currentTask = nil
73
105
  self.session = nil
74
106
  self.container = nil
107
+ self.tools = []
108
+ self.toolSchemas = []
75
109
  MLX.GPU.clearCache()
76
110
 
77
111
  let memoryAfterCleanup = self.getMemoryUsage()
@@ -94,6 +128,12 @@ class HybridLLM: HybridLLMSpec {
94
128
  let gpuAfterContainer = self.getGPUMemoryUsage()
95
129
  log("Model loaded - Host: \(memoryAfterContainer), GPU: \(gpuAfterContainer)")
96
130
 
131
+ if let jsTools = options?.tools {
132
+ self.tools = jsTools
133
+ self.toolSchemas = jsTools.map { self.buildToolSchema(from: $0) }
134
+ log("Loaded \(self.tools.count) tools: \(self.tools.map { $0.name })")
135
+ }
136
+
97
137
  let additionalContextDict: [String: Any]? = if let messages = options?.additionalContext {
98
138
  ["messages": messages.map { ["role": $0.role, "content": $0.content] }]
99
139
  } else {
@@ -152,8 +192,14 @@ class HybridLLM: HybridLLMSpec {
152
192
  }
153
193
  }
154
194
 
155
- func stream(prompt: String, onToken: @escaping (String) -> Void) throws -> Promise<String> {
156
- guard let session = session else {
195
+ private let maxToolCallDepth = 10
196
+
197
+ func stream(
198
+ prompt: String,
199
+ onToken: @escaping (String) -> Void,
200
+ onToolCall: ((String, String) -> Void)?
201
+ ) throws -> Promise<String> {
202
+ guard let container = container as? ModelContainer else {
157
203
  throw LLMError.notLoaded
158
204
  }
159
205
 
@@ -163,22 +209,24 @@ class HybridLLM: HybridLLMSpec {
163
209
  }
164
210
 
165
211
  let task = Task<String, Error> {
166
- var result = ""
167
- var tokenCount = 0
168
212
  let startTime = Date()
169
213
  var firstTokenTime: Date?
214
+ var tokenCount = 0
170
215
 
171
- log("Streaming response for: \(prompt.prefix(50))...")
172
- for try await chunk in session.streamResponse(to: prompt) {
173
- if Task.isCancelled { break }
174
-
175
- if firstTokenTime == nil {
176
- firstTokenTime = Date()
177
- }
178
- tokenCount += 1
179
- result += chunk
180
- onToken(chunk)
181
- }
216
+ let result = try await self.performGeneration(
217
+ container: container,
218
+ prompt: prompt,
219
+ toolResults: nil,
220
+ depth: 0,
221
+ onToken: { token in
222
+ if firstTokenTime == nil {
223
+ firstTokenTime = Date()
224
+ }
225
+ tokenCount += 1
226
+ onToken(token)
227
+ },
228
+ onToolCall: onToolCall ?? { _, _ in }
229
+ )
182
230
 
183
231
  let endTime = Date()
184
232
  let totalTime = endTime.timeIntervalSince(startTime) * 1000
@@ -214,6 +262,191 @@ class HybridLLM: HybridLLMSpec {
214
262
  }
215
263
  }
216
264
 
265
+ private func performGeneration(
266
+ container: ModelContainer,
267
+ prompt: String,
268
+ toolResults: [String]?,
269
+ depth: Int,
270
+ onToken: @escaping (String) -> Void,
271
+ onToolCall: @escaping (String, String) -> Void
272
+ ) async throws -> String {
273
+ if depth >= maxToolCallDepth {
274
+ log("Max tool call depth reached (\(maxToolCallDepth))")
275
+ return ""
276
+ }
277
+
278
+ var output = ""
279
+ var pendingToolCalls: [(tool: ToolDefinition, args: [String: Any], argsJson: String)] = []
280
+
281
+ var chat: [Chat.Message] = []
282
+
283
+ if !self.systemPrompt.isEmpty {
284
+ chat.append(.system(self.systemPrompt))
285
+ }
286
+
287
+ for msg in self.messageHistory {
288
+ switch msg.role {
289
+ case "user": chat.append(.user(msg.content))
290
+ case "assistant": chat.append(.assistant(msg.content))
291
+ case "system": chat.append(.system(msg.content))
292
+ case "tool": chat.append(.tool(msg.content))
293
+ default: break
294
+ }
295
+ }
296
+
297
+ if depth == 0 {
298
+ chat.append(.user(prompt))
299
+ }
300
+
301
+ if let toolResults = toolResults {
302
+ for result in toolResults {
303
+ chat.append(.tool(result))
304
+ }
305
+ }
306
+
307
+ let userInput = UserInput(
308
+ chat: chat,
309
+ tools: !self.toolSchemas.isEmpty ? self.toolSchemas : nil
310
+ )
311
+
312
+ let lmInput = try await container.prepare(input: userInput)
313
+
314
+ let stream = try await container.perform { context in
315
+ let parameters = GenerateParameters(maxTokens: 2048, temperature: 0.7)
316
+ return try MLXLMCommon.generate(
317
+ input: lmInput,
318
+ parameters: parameters,
319
+ context: context
320
+ )
321
+ }
322
+
323
+ for await generation in stream {
324
+ if Task.isCancelled { break }
325
+
326
+ switch generation {
327
+ case .chunk(let text):
328
+ output += text
329
+ onToken(text)
330
+
331
+ case .toolCall(let toolCall):
332
+ log("Tool call detected: \(toolCall.function.name)")
333
+
334
+ guard let tool = self.tools.first(where: { $0.name == toolCall.function.name }) else {
335
+ log("Unknown tool: \(toolCall.function.name)")
336
+ continue
337
+ }
338
+
339
+ let argsDict = self.convertToolCallArguments(toolCall.function.arguments)
340
+ let argsJson = self.dictionaryToJson(argsDict)
341
+
342
+ pendingToolCalls.append((tool: tool, args: argsDict, argsJson: argsJson))
343
+ onToolCall(toolCall.function.name, argsJson)
344
+
345
+ case .info(let info):
346
+ log("Generation info: \(info.generationTokenCount) tokens, \(String(format: "%.1f", info.tokensPerSecond)) tokens/s")
347
+ }
348
+ }
349
+
350
+ if !pendingToolCalls.isEmpty {
351
+ log("Executing \(pendingToolCalls.count) tool call(s)")
352
+
353
+ var allToolResults: [String] = []
354
+
355
+ for (tool, argsDict, _) in pendingToolCalls {
356
+ do {
357
+ let argsAnyMap = self.dictionaryToAnyMap(argsDict)
358
+ let outerPromise = tool.handler(argsAnyMap)
359
+ let innerPromise = try await outerPromise.await()
360
+ let resultAnyMap = try await innerPromise.await()
361
+ let resultDict = self.anyMapToDictionary(resultAnyMap)
362
+ let resultJson = self.dictionaryToJson(resultDict)
363
+
364
+ log("Tool result for \(tool.name): \(resultJson.prefix(100))...")
365
+ allToolResults.append(resultJson)
366
+ } catch {
367
+ log("Tool execution error for \(tool.name): \(error)")
368
+ allToolResults.append("{\"error\": \"Tool execution failed\"}")
369
+ }
370
+ }
371
+
372
+ if !output.isEmpty {
373
+ self.messageHistory.append(LLMMessage(role: "assistant", content: output))
374
+ }
375
+
376
+ if depth == 0 {
377
+ self.messageHistory.append(LLMMessage(role: "user", content: prompt))
378
+ }
379
+
380
+ for result in allToolResults {
381
+ self.messageHistory.append(LLMMessage(role: "tool", content: result))
382
+ }
383
+
384
+ onToken("\u{200B}")
385
+
386
+ let continuation = try await self.performGeneration(
387
+ container: container,
388
+ prompt: prompt,
389
+ toolResults: allToolResults,
390
+ depth: depth + 1,
391
+ onToken: onToken,
392
+ onToolCall: onToolCall
393
+ )
394
+
395
+ return output + continuation
396
+ }
397
+
398
+ return output
399
+ }
400
+
401
+ private func convertToolCallArguments(_ arguments: [String: JSONValue]) -> [String: Any] {
402
+ var result: [String: Any] = [:]
403
+ for (key, value) in arguments {
404
+ result[key] = value.anyValue
405
+ }
406
+ return result
407
+ }
408
+
409
+ private func dictionaryToJson(_ dict: [String: Any]) -> String {
410
+ guard let data = try? JSONSerialization.data(withJSONObject: dict),
411
+ let json = String(data: data, encoding: .utf8) else {
412
+ return "{}"
413
+ }
414
+ return json
415
+ }
416
+
417
+ private func dictionaryToAnyMap(_ dict: [String: Any]) -> AnyMap {
418
+ let anyMap = AnyMap()
419
+ for (key, value) in dict {
420
+ switch value {
421
+ case let stringValue as String:
422
+ anyMap.setString(key: key, value: stringValue)
423
+ case let doubleValue as Double:
424
+ anyMap.setDouble(key: key, value: doubleValue)
425
+ case let intValue as Int:
426
+ anyMap.setDouble(key: key, value: Double(intValue))
427
+ case let boolValue as Bool:
428
+ anyMap.setBoolean(key: key, value: boolValue)
429
+ default:
430
+ anyMap.setString(key: key, value: String(describing: value))
431
+ }
432
+ }
433
+ return anyMap
434
+ }
435
+
436
+ private func anyMapToDictionary(_ anyMap: AnyMap) -> [String: Any] {
437
+ var dict: [String: Any] = [:]
438
+ for key in anyMap.getAllKeys() {
439
+ if anyMap.isString(key: key) {
440
+ dict[key] = anyMap.getString(key: key)
441
+ } else if anyMap.isDouble(key: key) {
442
+ dict[key] = anyMap.getDouble(key: key)
443
+ } else if anyMap.isBool(key: key) {
444
+ dict[key] = anyMap.getBoolean(key: key)
445
+ }
446
+ }
447
+ return dict
448
+ }
449
+
217
450
  func stop() throws {
218
451
  currentTask?.cancel()
219
452
  currentTask = nil
@@ -231,6 +464,8 @@ class HybridLLM: HybridLLMSpec {
231
464
  currentTask = nil
232
465
  session = nil
233
466
  container = nil
467
+ tools = []
468
+ toolSchemas = []
234
469
  messageHistory = []
235
470
  manageHistory = false
236
471
  modelId = ""
@@ -3,4 +3,5 @@
3
3
  export { LLM } from "./llm.js";
4
4
  export { ModelManager } from "./modelManager.js";
5
5
  export { MLXModel, MLXModels, ModelFamily, ModelProvider } from "./models.js";
6
+ export { createTool } from "./tool-utils.js";
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["LLM","ModelManager","MLXModel","MLXModels","ModelFamily","ModelProvider"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,GAAG,QAAsB,UAAO;AACzC,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SACEC,QAAQ,EACRC,SAAS,EACTC,WAAW,EAEXC,aAAa,QAER,aAAU","ignoreList":[]}
1
+ {"version":3,"names":["LLM","ModelManager","MLXModel","MLXModels","ModelFamily","ModelProvider","createTool"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,GAAG,QAA8D,UAAO;AACjF,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SACEC,QAAQ,EACRC,SAAS,EACTC,WAAW,EAEXC,aAAa,QAER,aAAU;AAUjB,SAASC,UAAU,QAAqC,iBAAc","ignoreList":[]}
package/lib/module/llm.js CHANGED
@@ -50,13 +50,43 @@ export const LLM = {
50
50
  return getInstance().generate(prompt);
51
51
  },
52
52
  /**
53
- * Stream a response token by token.
53
+ * Stream a response token by token with optional tool calling support.
54
+ * Tools must be provided when loading the model via `load()` options.
55
+ * Tools are automatically executed when the model calls them.
54
56
  * @param prompt - The input text to generate a response for
55
57
  * @param onToken - Callback invoked for each generated token
58
+ * @param onToolCall - Optional callback invoked when a tool is called.
59
+ * Receives the current tool call and an accumulated array of all tool calls so far.
56
60
  * @returns The complete generated text
57
61
  */
58
- stream(prompt, onToken) {
59
- return getInstance().stream(prompt, onToken);
62
+ stream(prompt, onToken, onToolCall) {
63
+ const accumulatedToolCalls = [];
64
+ return getInstance().stream(prompt, onToken, (name, argsJson) => {
65
+ if (onToolCall) {
66
+ try {
67
+ const args = JSON.parse(argsJson);
68
+ const toolCall = {
69
+ name,
70
+ arguments: args
71
+ };
72
+ accumulatedToolCalls.push(toolCall);
73
+ onToolCall({
74
+ toolCall,
75
+ allToolCalls: [...accumulatedToolCalls]
76
+ });
77
+ } catch {
78
+ const toolCall = {
79
+ name,
80
+ arguments: {}
81
+ };
82
+ accumulatedToolCalls.push(toolCall);
83
+ onToolCall({
84
+ toolCall,
85
+ allToolCalls: [...accumulatedToolCalls]
86
+ });
87
+ }
88
+ }
89
+ });
60
90
  },
61
91
  /**
62
92
  * Stop the current generation. Safe to call even if not generating.
@@ -1 +1 @@
1
- {"version":3,"names":["NitroModules","instance","getInstance","createHybridObject","LLM","load","modelId","options","generate","prompt","stream","onToken","stop","unload","getLastGenerationStats","getHistory","clearHistory","isLoaded","isGenerating","debug","value","systemPrompt"],"sourceRoot":"../../src","sources":["llm.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAGzD,IAAIC,QAAwB,GAAG,IAAI;AAOnC,SAASC,WAAWA,CAAA,EAAY;EAC9B,IAAI,CAACD,QAAQ,EAAE;IACbA,QAAQ,GAAGD,YAAY,CAACG,kBAAkB,CAAU,KAAK,CAAC;EAC5D;EACA,OAAOF,QAAQ;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,GAAG,GAAG;EACjB;AACF;AACA;AACA;AACA;EACEC,IAAIA,CAACC,OAAe,EAAEC,OAAuB,EAAiB;IAC5D,OAAOL,WAAW,CAAC,CAAC,CAACG,IAAI,CAACC,OAAO,EAAEC,OAAO,CAAC;EAC7C,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEC,QAAQA,CAACC,MAAc,EAAmB;IACxC,OAAOP,WAAW,CAAC,CAAC,CAACM,QAAQ,CAACC,MAAM,CAAC;EACvC,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;EACEC,MAAMA,CAACD,MAAc,EAAEE,OAAgC,EAAmB;IACxE,OAAOT,WAAW,CAAC,CAAC,CAACQ,MAAM,CAACD,MAAM,EAAEE,OAAO,CAAC;EAC9C,CAAC;EAED;AACF;AACA;EACEC,IAAIA,CAAA,EAAS;IACXV,WAAW,CAAC,CAAC,CAACU,IAAI,CAAC,CAAC;EACtB,CAAC;EAED;AACF;AACA;AACA;EACEC,MAAMA,CAAA,EAAS;IACbX,WAAW,CAAC,CAAC,CAACW,MAAM,CAAC,CAAC;EACxB,CAAC;EAED;AACF;AACA;AACA;EACEC,sBAAsBA,CAAA,EAAoB;IACxC,OAAOZ,WAAW,CAAC,CAAC,CAACY,sBAAsB,CAAC,CAAC;EAC/C,CAAC;EAED;AACF;AACA;AACA;EACEC,UAAUA,CAAA,EAAc;IACtB,OAAOb,WAAW,CAAC,CAAC,CAACa,UAAU,CAAC,CAAC;EACnC,CAAC;EAED;AACF;AACA;EACEC,YAAYA,CAAA,EAAS;IACnBd,WAAW,CAAC,CAAC,CAACc,YAAY,CAAC,CAAC;EAC9B,CAAC;EAED;EACA,IAAIC,QAAQA,CAAA,EAAY;IACtB,OAAOf,WAAW,CAAC,CAAC,CAACe,QAAQ;EAC/B,CAAC;EAED;EACA,IAAIC,YAAYA,CAAA,EAAY;IAC1B,OAAOhB,WAAW,CAAC,CAAC,CAACgB,YAAY;EACnC,CAAC;EAED;EACA,IAAIZ,OAAOA,CAAA,EAAW;IACpB,OAAOJ,WAAW,CAAC,CAAC,CAACI,OAAO;EAC9B,CAAC;EAED;EACA,IAAIa,KAAKA,CAAA,EAAY;IACnB,OAAOjB,WAAW,CAAC,CAAC,CAACiB,KAAK;EAC5B,CAAC;EAED,IAAIA,KAAKA,CAACC,KAAc,EAAE;IACxBlB,WAAW,CAAC,CAAC,CAACiB,KAAK,GAAGC,KAAK;EAC7B,CAAC;EAED;AACF;AACA;AACA;AACA;EACE,IAAIC,YAAYA,CAAA,EAAW;IACzB,OAAOnB,WAAW,CAAC,CAAC,CAACmB,YAAY;EACnC,CAAC;EAED,IAAIA,YAAYA,CAACD,KAAa,EAAE;IAC9BlB,WAAW,CAAC,CAAC,CAACmB,YAAY,GAAGD,KAAK;EACpC;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["NitroModules","instance","getInstance","createHybridObject","LLM","load","modelId","options","generate","prompt","stream","onToken","onToolCall","accumulatedToolCalls","name","argsJson","args","JSON","parse","toolCall","arguments","push","allToolCalls","stop","unload","getLastGenerationStats","getHistory","clearHistory","isLoaded","isGenerating","debug","value","systemPrompt"],"sourceRoot":"../../src","sources":["llm.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ function getZodTypeString(zodType) {
4
+ const typeName = zodType._zod.def.type;
5
+ switch (typeName) {
6
+ case 'string':
7
+ return 'string';
8
+ case 'number':
9
+ case 'int':
10
+ return 'number';
11
+ case 'boolean':
12
+ return 'boolean';
13
+ case 'array':
14
+ return 'array';
15
+ case 'object':
16
+ return 'object';
17
+ case 'optional':
18
+ return getZodTypeString(zodType._zod.def.innerType);
19
+ case 'default':
20
+ return getZodTypeString(zodType._zod.def.innerType);
21
+ default:
22
+ return 'string';
23
+ }
24
+ }
25
+ function isZodOptional(zodType) {
26
+ const typeName = zodType._zod.def.type;
27
+ return typeName === 'optional' || typeName === 'default';
28
+ }
29
+ function zodSchemaToParameters(schema) {
30
+ const shape = schema._zod.def.shape;
31
+ const parameters = [];
32
+ for (const [key, zodType] of Object.entries(shape)) {
33
+ const zType = zodType;
34
+ parameters.push({
35
+ name: key,
36
+ type: getZodTypeString(zType),
37
+ description: zType.description ?? '',
38
+ required: !isZodOptional(zType)
39
+ });
40
+ }
41
+ return parameters;
42
+ }
43
+ export function createTool(definition) {
44
+ return {
45
+ name: definition.name,
46
+ description: definition.description,
47
+ parameters: zodSchemaToParameters(definition.arguments),
48
+ handler: async args => {
49
+ const argsObj = args;
50
+ const parsedArgs = definition.arguments.parse(argsObj);
51
+ const result = await definition.handler(parsedArgs);
52
+ return result;
53
+ }
54
+ };
55
+ }
56
+ //# sourceMappingURL=tool-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getZodTypeString","zodType","typeName","_zod","def","type","innerType","isZodOptional","zodSchemaToParameters","schema","shape","parameters","key","Object","entries","zType","push","name","description","required","createTool","definition","arguments","handler","args","argsObj","parsedArgs","parse","result"],"sourceRoot":"../../src","sources":["tool-utils.ts"],"mappings":";;AAcA,SAASA,gBAAgBA,CAACC,OAAkB,EAAqB;EAC/D,MAAMC,QAAQ,GAAGD,OAAO,CAACE,IAAI,CAACC,GAAG,CAACC,IAAI;EACtC,QAAQH,QAAQ;IACd,KAAK,QAAQ;MACX,OAAO,QAAQ;IACjB,KAAK,QAAQ;IACb,KAAK,KAAK;MACR,OAAO,QAAQ;IACjB,KAAK,SAAS;MACZ,OAAO,SAAS;IAClB,KAAK,OAAO;MACV,OAAO,OAAO;IAChB,KAAK,QAAQ;MACX,OAAO,QAAQ;IACjB,KAAK,UAAU;MACb,OAAOF,gBAAgB,CAAEC,OAAO,CAA8BE,IAAI,CAACC,GAAG,CAACE,SAAS,CAAC;IACnF,KAAK,SAAS;MACZ,OAAON,gBAAgB,CAAEC,OAAO,CAA6BE,IAAI,CAACC,GAAG,CAACE,SAAS,CAAC;IAClF;MACE,OAAO,QAAQ;EACnB;AACF;AAEA,SAASC,aAAaA,CAACN,OAAkB,EAAW;EAClD,MAAMC,QAAQ,GAAGD,OAAO,CAACE,IAAI,CAACC,GAAG,CAACC,IAAI;EACtC,OAAOH,QAAQ,KAAK,UAAU,IAAIA,QAAQ,KAAK,SAAS;AAC1D;AAEA,SAASM,qBAAqBA,CAACC,MAAuB,EAAmB;EACvE,MAAMC,KAAK,GAAGD,MAAM,CAACN,IAAI,CAACC,GAAG,CAACM,KAAK;EACnC,MAAMC,UAA2B,GAAG,EAAE;EAEtC,KAAK,MAAM,CAACC,GAAG,EAAEX,OAAO,CAAC,IAAIY,MAAM,CAACC,OAAO,CAACJ,KAAK,CAAC,EAAE;IAClD,MAAMK,KAAK,GAAGd,OAAoB;IAClCU,UAAU,CAACK,IAAI,CAAC;MACdC,IAAI,EAAEL,GAAG;MACTP,IAAI,EAAEL,gBAAgB,CAACe,KAAK,CAAC;MAC7BG,WAAW,EAAEH,KAAK,CAACG,WAAW,IAAI,EAAE;MACpCC,QAAQ,EAAE,CAACZ,aAAa,CAACQ,KAAK;IAChC,CAAC,CAAC;EACJ;EAEA,OAAOJ,UAAU;AACnB;AAEA,OAAO,SAASS,UAAUA,CACxBC,UAAqC,EACrB;EAChB,OAAO;IACLJ,IAAI,EAAEI,UAAU,CAACJ,IAAI;IACrBC,WAAW,EAAEG,UAAU,CAACH,WAAW;IACnCP,UAAU,EAAEH,qBAAqB,CAACa,UAAU,CAACC,SAAS,CAAC;IACvDC,OAAO,EAAE,MAAOC,IAAY,IAAK;MAC/B,MAAMC,OAAO,GAAGD,IAA0C;MAC1D,MAAME,UAAU,GAAGL,UAAU,CAACC,SAAS,CAACK,KAAK,CAACF,OAAO,CAAC;MACtD,MAAMG,MAAM,GAAG,MAAMP,UAAU,CAACE,OAAO,CAACG,UAAU,CAAC;MACnD,OAAOE,MAAM;IACf;EACF,CAAC;AACH","ignoreList":[]}
@@ -1,6 +1,7 @@
1
- export { LLM, type Message } from './llm';
1
+ export { LLM, type Message, type ToolCallInfo, type ToolCallUpdate } from './llm';
2
2
  export { ModelManager } from './modelManager';
3
3
  export { MLXModel, MLXModels, ModelFamily, type ModelInfo, ModelProvider, type ModelQuantization, } from './models';
4
- export type { GenerationStats, LLM as LLMSpec, LLMLoadOptions } from './specs/LLM.nitro';
4
+ export type { GenerationStats, LLM as LLMSpec, LLMLoadOptions, ToolDefinition, ToolParameter, ToolParameterType, } from './specs/LLM.nitro';
5
5
  export type { ModelManager as ModelManagerSpec } from './specs/ModelManager.nitro';
6
+ export { createTool, type TypeSafeToolDefinition } from './tool-utils';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,SAAS,EACd,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAA;AAEjB,YAAY,EAAE,eAAe,EAAE,GAAG,IAAI,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACxF,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAA;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,SAAS,EACd,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,eAAe,EACf,GAAG,IAAI,OAAO,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,UAAU,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAA"}
@@ -3,6 +3,14 @@ export type Message = {
3
3
  role: 'user' | 'assistant' | 'system';
4
4
  content: string;
5
5
  };
6
+ export type ToolCallInfo = {
7
+ name: string;
8
+ arguments: Record<string, unknown>;
9
+ };
10
+ export type ToolCallUpdate = {
11
+ toolCall: ToolCallInfo;
12
+ allToolCalls: ToolCallInfo[];
13
+ };
6
14
  /**
7
15
  * LLM text generation using MLX on Apple Silicon.
8
16
  *
@@ -40,12 +48,16 @@ export declare const LLM: {
40
48
  */
41
49
  generate(prompt: string): Promise<string>;
42
50
  /**
43
- * Stream a response token by token.
51
+ * Stream a response token by token with optional tool calling support.
52
+ * Tools must be provided when loading the model via `load()` options.
53
+ * Tools are automatically executed when the model calls them.
44
54
  * @param prompt - The input text to generate a response for
45
55
  * @param onToken - Callback invoked for each generated token
56
+ * @param onToolCall - Optional callback invoked when a tool is called.
57
+ * Receives the current tool call and an accumulated array of all tool calls so far.
46
58
  * @returns The complete generated text
47
59
  */
48
- stream(prompt: string, onToken: (token: string) => void): Promise<string>;
60
+ stream(prompt: string, onToken: (token: string) => void, onToolCall?: (update: ToolCallUpdate) => void): Promise<string>;
49
61
  /**
50
62
  * Stop the current generation. Safe to call even if not generating.
51
63
  */
@@ -1 +1 @@
1
- {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/llm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAkB,MAAM,mBAAmB,CAAA;AAIxF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,GAAG;IACd;;;;OAIG;kBACW,MAAM,WAAW,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;;;;OAKG;qBACc,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzC;;;;;OAKG;mBACY,MAAM,WAAW,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE;;OAEG;YACK,IAAI;IAIZ;;;OAGG;cACO,IAAI;IAId;;;OAGG;8BACuB,eAAe;IAIzC;;;OAGG;kBACW,OAAO,EAAE;IAIvB;;OAEG;oBACa,IAAI;IAIpB,mEAAmE;uBACnD,OAAO;IAIvB,gDAAgD;2BAC5B,OAAO;IAI3B,oEAAoE;sBACrD,MAAM;IAIrB,sCAAsC;WACzB,OAAO;IAQpB;;;;OAIG;kBACiB,MAAM;CAO3B,CAAA"}
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/llm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAkB,MAAM,mBAAmB,CAAA;AAIxF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,YAAY,CAAA;IACtB,YAAY,EAAE,YAAY,EAAE,CAAA;CAC7B,CAAA;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,GAAG;IACd;;;;OAIG;kBACW,MAAM,WAAW,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;;;;OAKG;qBACc,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzC;;;;;;;;;OASG;mBAEO,MAAM,WACL,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,eACnB,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAC5C,OAAO,CAAC,MAAM,CAAC;IAyBlB;;OAEG;YACK,IAAI;IAIZ;;;OAGG;cACO,IAAI;IAId;;;OAGG;8BACuB,eAAe;IAIzC;;;OAGG;kBACW,OAAO,EAAE;IAIvB;;OAEG;oBACa,IAAI;IAIpB,mEAAmE;uBACnD,OAAO;IAIvB,gDAAgD;2BAC5B,OAAO;IAI3B,oEAAoE;sBACrD,MAAM;IAIrB,sCAAsC;WACzB,OAAO;IAQpB;;;;OAIG;kBACiB,MAAM;CAO3B,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { HybridObject } from 'react-native-nitro-modules';
1
+ import type { AnyMap, HybridObject } from 'react-native-nitro-modules';
2
2
  /**
3
3
  * Statistics from the last text generation.
4
4
  */
@@ -16,6 +16,24 @@ export interface LLMMessage {
16
16
  role: string;
17
17
  content: string;
18
18
  }
19
+ /**
20
+ * Parameter definition for a tool.
21
+ */
22
+ export interface ToolParameter {
23
+ name: string;
24
+ type: string;
25
+ description: string;
26
+ required: boolean;
27
+ }
28
+ /**
29
+ * Tool definition that can be called by the model.
30
+ */
31
+ export interface ToolDefinition {
32
+ name: string;
33
+ description: string;
34
+ parameters: ToolParameter[];
35
+ handler: (args: AnyMap) => Promise<AnyMap>;
36
+ }
19
37
  /** Options for loading a model.
20
38
  */
21
39
  export interface LLMLoadOptions {
@@ -25,6 +43,8 @@ export interface LLMLoadOptions {
25
43
  additionalContext?: LLMMessage[];
26
44
  /** Whether to automatically manage message history */
27
45
  manageHistory?: boolean;
46
+ /** Tools available for the model to call */
47
+ tools?: ToolDefinition[];
28
48
  }
29
49
  /**
30
50
  * Low-level LLM interface for text generation using MLX.
@@ -46,12 +66,14 @@ export interface LLM extends HybridObject<{
46
66
  */
47
67
  generate(prompt: string): Promise<string>;
48
68
  /**
49
- * Stream a response token by token.
69
+ * Stream a response token by token with optional tool calling support.
70
+ * Tools are automatically executed when the model calls them.
50
71
  * @param prompt - The input text to generate a response for
51
72
  * @param onToken - Callback invoked for each generated token
73
+ * @param onToolCall - Optional callback invoked when a tool is called (for UI feedback)
52
74
  * @returns The complete generated text
53
75
  */
54
- stream(prompt: string, onToken: (token: string) => void): Promise<string>;
76
+ stream(prompt: string, onToken: (token: string) => void, onToolCall?: (toolName: string, args: string) => void): Promise<string>;
55
77
  /**
56
78
  * Stop the current generation.
57
79
  */
@@ -85,4 +107,9 @@ export interface LLM extends HybridObject<{
85
107
  /** System prompt used when loading the model */
86
108
  systemPrompt: string;
87
109
  }
110
+ /**
111
+ * Supported parameter types for tool definitions.
112
+ * Used for type safety in createTool().
113
+ */
114
+ export type ToolParameterType = 'string' | 'number' | 'boolean' | 'array' | 'object';
88
115
  //# sourceMappingURL=LLM.nitro.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LLM.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/LLM.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAA;IACvB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;GACG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAA;IAChC,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,GAAI,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;IACzD;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE9D;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEzC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEzE;;OAEG;IACH,IAAI,IAAI,IAAI,CAAA;IAEZ;;OAEG;IACH,MAAM,IAAI,IAAI,CAAA;IAEd;;;OAGG;IACH,sBAAsB,IAAI,eAAe,CAAA;IAEzC;;;OAGG;IACH,UAAU,IAAI,UAAU,EAAE,CAAA;IAE1B;;OAEG;IACH,YAAY,IAAI,IAAI,CAAA;IAEpB,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAA;CACrB"}
1
+ {"version":3,"file":"LLM.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/LLM.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEtE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,4CAA4C;IAC5C,eAAe,EAAE,MAAM,CAAA;IACvB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3C;AAED;GACG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,UAAU,EAAE,CAAA;IAChC,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,cAAc,EAAE,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,GAAI,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;IACzD;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE9D;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEzC;;;;;;;OAOG;IACH,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAChC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC,MAAM,CAAC,CAAA;IAElB;;OAEG;IACH,IAAI,IAAI,IAAI,CAAA;IAEZ;;OAEG;IACH,MAAM,IAAI,IAAI,CAAA;IAEd;;;OAGG;IACH,sBAAsB,IAAI,eAAe,CAAA;IAEzC;;;OAGG;IACH,UAAU,IAAI,UAAU,EAAE,CAAA;IAE1B;;OAEG;IACH,YAAY,IAAI,IAAI,CAAA;IAEpB,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB,2BAA2B;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { z } from 'zod';
2
+ import type { ToolDefinition } from './specs/LLM.nitro';
3
+ type ZodObjectSchema = z.ZodObject<z.core.$ZodShape>;
4
+ type InferArgs<T extends ZodObjectSchema> = z.infer<T>;
5
+ export interface TypeSafeToolDefinition<T extends ZodObjectSchema> {
6
+ name: string;
7
+ description: string;
8
+ arguments: T;
9
+ handler: (args: InferArgs<T>) => Promise<Record<string, unknown>>;
10
+ }
11
+ export declare function createTool<T extends ZodObjectSchema>(definition: TypeSafeToolDefinition<T>): ToolDefinition;
12
+ export {};
13
+ //# sourceMappingURL=tool-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-utils.d.ts","sourceRoot":"","sources":["../../../src/tool-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAoC,MAAM,mBAAmB,CAAA;AAEzF,KAAK,eAAe,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;AACpD,KAAK,SAAS,CAAC,CAAC,SAAS,eAAe,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAEtD,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,eAAe;IAC/D,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,CAAC,CAAA;IACZ,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAClE;AA+CD,wBAAgB,UAAU,CAAC,CAAC,SAAS,eAAe,EAClD,UAAU,EAAE,sBAAsB,CAAC,CAAC,CAAC,GACpC,cAAc,CAYhB"}
@@ -2,7 +2,7 @@
2
2
  # MLXReactNative+autolinking.rb
3
3
  # This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
4
  # https://github.com/mrousavy/nitro
5
- # Copyright © 2025 Marc Rousavy @ Margelo
5
+ # Copyright © 2026 Marc Rousavy @ Margelo
6
6
  #
7
7
 
8
8
  # This is a Ruby script that adds all files generated by Nitrogen