@getenki/ai 0.1.91
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 +201 -0
- package/README.md +170 -0
- package/client.d.ts +114 -0
- package/client.js +586 -0
- package/index.d.ts +6 -0
- package/index.js +579 -0
- package/package.json +120 -0
package/client.js
ADDED
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { NativeEnkiAgent, ...nativeBinding } = require('./index.js')
|
|
4
|
+
|
|
5
|
+
const DEFAULT_AGENT_NAME = 'Agent'
|
|
6
|
+
const DEFAULT_MAX_ITERATIONS = 20
|
|
7
|
+
|
|
8
|
+
class EnkiAgent {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
if (options == null || typeof options !== 'object' || Array.isArray(options)) {
|
|
11
|
+
throw new TypeError('EnkiAgent options must be an object')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
name,
|
|
16
|
+
systemPromptPreamble,
|
|
17
|
+
model,
|
|
18
|
+
maxIterations,
|
|
19
|
+
workspaceHome,
|
|
20
|
+
} = options
|
|
21
|
+
|
|
22
|
+
this._native = new NativeEnkiAgent(
|
|
23
|
+
optionalString(name, 'name'),
|
|
24
|
+
optionalString(systemPromptPreamble, 'systemPromptPreamble'),
|
|
25
|
+
optionalString(model, 'model'),
|
|
26
|
+
optionalPositiveInteger(maxIterations, 'maxIterations'),
|
|
27
|
+
optionalString(workspaceHome, 'workspaceHome'),
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
run(sessionId, userMessage) {
|
|
32
|
+
return this._native.run(
|
|
33
|
+
requiredString(sessionId, 'sessionId'),
|
|
34
|
+
requiredString(userMessage, 'userMessage'),
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class RunContext {
|
|
40
|
+
constructor(deps) {
|
|
41
|
+
this.deps = deps
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class AgentRunResult {
|
|
46
|
+
constructor(output) {
|
|
47
|
+
this.output = output
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class Tool {
|
|
52
|
+
constructor({ name, description = '', parametersJson, func, usesContext }) {
|
|
53
|
+
this.name = requiredString(name, 'name')
|
|
54
|
+
this.description = typeof description === 'string' ? description : ''
|
|
55
|
+
this.parametersJson = validateJsonSchema(parametersJson)
|
|
56
|
+
if (typeof func !== 'function') {
|
|
57
|
+
throw new TypeError('func must be a function')
|
|
58
|
+
}
|
|
59
|
+
this.func = func
|
|
60
|
+
this.usesContext = Boolean(usesContext)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static fromFunction(func, options = {}) {
|
|
64
|
+
if (typeof func !== 'function') {
|
|
65
|
+
throw new TypeError('func must be a function')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const {
|
|
69
|
+
usesContext,
|
|
70
|
+
name,
|
|
71
|
+
description,
|
|
72
|
+
parametersJson,
|
|
73
|
+
} = options
|
|
74
|
+
|
|
75
|
+
return new Tool({
|
|
76
|
+
name: name ?? func.name ?? 'tool',
|
|
77
|
+
description: description ?? getFunctionDescription(func),
|
|
78
|
+
parametersJson: parametersJson ?? JSON.stringify({
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {},
|
|
81
|
+
additionalProperties: false,
|
|
82
|
+
}),
|
|
83
|
+
func,
|
|
84
|
+
usesContext: Boolean(usesContext),
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
asLowLevelTool() {
|
|
89
|
+
return {
|
|
90
|
+
name: this.name,
|
|
91
|
+
description: this.description,
|
|
92
|
+
parametersJson: this.parametersJson,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class MemoryModule {
|
|
98
|
+
constructor({ name, record, recall, flush, consolidate }) {
|
|
99
|
+
this.name = requiredString(name, 'name')
|
|
100
|
+
if (typeof record !== 'function') {
|
|
101
|
+
throw new TypeError('record must be a function')
|
|
102
|
+
}
|
|
103
|
+
if (typeof recall !== 'function') {
|
|
104
|
+
throw new TypeError('recall must be a function')
|
|
105
|
+
}
|
|
106
|
+
if (flush != null && typeof flush !== 'function') {
|
|
107
|
+
throw new TypeError('flush must be a function')
|
|
108
|
+
}
|
|
109
|
+
if (consolidate != null && typeof consolidate !== 'function') {
|
|
110
|
+
throw new TypeError('consolidate must be a function')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.record = record
|
|
114
|
+
this.recall = recall
|
|
115
|
+
this.flush = flush
|
|
116
|
+
this.consolidate = consolidate
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
asLowLevelMemory() {
|
|
120
|
+
return { name: this.name }
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
class MemoryBackend {
|
|
125
|
+
asMemoryModule() {
|
|
126
|
+
return new MemoryModule({
|
|
127
|
+
name: this.name ?? 'memory',
|
|
128
|
+
record: this.record.bind(this),
|
|
129
|
+
recall: this.recall.bind(this),
|
|
130
|
+
flush: typeof this.flush === 'function' ? this.flush.bind(this) : undefined,
|
|
131
|
+
consolidate:
|
|
132
|
+
typeof this.consolidate === 'function' ? this.consolidate.bind(this) : undefined,
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class LlmProviderBackend {}
|
|
138
|
+
|
|
139
|
+
class ToolHandler {
|
|
140
|
+
constructor(tools) {
|
|
141
|
+
this._tools = tools
|
|
142
|
+
this._deps = undefined
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setDeps(deps) {
|
|
146
|
+
this._deps = deps
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
clearDeps() {
|
|
150
|
+
this._deps = undefined
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async execute(toolName, argsJson, agentDir, workspaceDir, sessionsDir) {
|
|
154
|
+
const tool = this._tools.get(toolName)
|
|
155
|
+
if (!tool) {
|
|
156
|
+
throw new Error(`Unknown tool '${toolName}'`)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const parsedArgs = parseObjectJson(argsJson, `Tool '${toolName}' expected JSON object args`)
|
|
160
|
+
const args = []
|
|
161
|
+
if (tool.usesContext) {
|
|
162
|
+
args.push(new RunContext(this._deps))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (const parameter of getFunctionParameters(tool.func, tool.usesContext)) {
|
|
166
|
+
if (Object.prototype.hasOwnProperty.call(parsedArgs, parameter.name)) {
|
|
167
|
+
args.push(parsedArgs[parameter.name])
|
|
168
|
+
} else if (parameter.hasDefault) {
|
|
169
|
+
args.push(parameter.defaultValue)
|
|
170
|
+
} else {
|
|
171
|
+
throw new TypeError(`Missing required argument '${parameter.name}' for tool '${toolName}'`)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
void agentDir
|
|
176
|
+
void workspaceDir
|
|
177
|
+
void sessionsDir
|
|
178
|
+
|
|
179
|
+
const result = await Promise.resolve(tool.func(...args))
|
|
180
|
+
return stringifyToolResult(result)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
class MemoryHandler {
|
|
185
|
+
constructor(memories) {
|
|
186
|
+
this._memories = memories
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async record(memoryName, sessionId, userMsg, assistantMsg) {
|
|
190
|
+
const memory = this._get(memoryName)
|
|
191
|
+
await Promise.resolve(memory.record(sessionId, userMsg, assistantMsg))
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async recall(memoryName, sessionId, query, maxEntries) {
|
|
195
|
+
const memory = this._get(memoryName)
|
|
196
|
+
return (await Promise.resolve(memory.recall(sessionId, query, maxEntries))) ?? []
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async flush(memoryName, sessionId) {
|
|
200
|
+
const memory = this._get(memoryName)
|
|
201
|
+
if (memory.flush) {
|
|
202
|
+
await Promise.resolve(memory.flush(sessionId))
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async consolidate(memoryName, sessionId) {
|
|
207
|
+
const memory = this._get(memoryName)
|
|
208
|
+
if (memory.consolidate) {
|
|
209
|
+
await Promise.resolve(memory.consolidate(sessionId))
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
_get(memoryName) {
|
|
214
|
+
const memory = this._memories.get(memoryName)
|
|
215
|
+
if (!memory) {
|
|
216
|
+
throw new Error(`Unknown memory '${memoryName}'`)
|
|
217
|
+
}
|
|
218
|
+
return memory
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
class LlmHandler {
|
|
223
|
+
constructor(provider) {
|
|
224
|
+
this._provider = provider
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async complete(model, messagesJson, toolsJson) {
|
|
228
|
+
const messages = parseArrayJson(messagesJson)
|
|
229
|
+
const tools = parseArrayJson(toolsJson)
|
|
230
|
+
const result =
|
|
231
|
+
this._provider instanceof LlmProviderBackend
|
|
232
|
+
? await Promise.resolve(this._provider.complete(model, messages, tools))
|
|
233
|
+
: await Promise.resolve(this._provider(model, messages, tools))
|
|
234
|
+
|
|
235
|
+
return typeof result === 'string' ? result : JSON.stringify(result)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
class Agent {
|
|
240
|
+
constructor(model, options = {}) {
|
|
241
|
+
this.model = requiredString(model, 'model')
|
|
242
|
+
|
|
243
|
+
if (options == null || typeof options !== 'object' || Array.isArray(options)) {
|
|
244
|
+
throw new TypeError('Agent options must be an object')
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const {
|
|
248
|
+
instructions = '',
|
|
249
|
+
name = DEFAULT_AGENT_NAME,
|
|
250
|
+
maxIterations = DEFAULT_MAX_ITERATIONS,
|
|
251
|
+
workspaceHome,
|
|
252
|
+
tools = [],
|
|
253
|
+
memories = [],
|
|
254
|
+
llm,
|
|
255
|
+
lowLevelAgent,
|
|
256
|
+
} = options
|
|
257
|
+
|
|
258
|
+
this.instructions = optionalString(instructions, 'instructions') ?? ''
|
|
259
|
+
this.name = optionalString(name, 'name') ?? DEFAULT_AGENT_NAME
|
|
260
|
+
this.maxIterations = optionalPositiveInteger(maxIterations, 'maxIterations') ?? DEFAULT_MAX_ITERATIONS
|
|
261
|
+
this.workspaceHome = optionalString(workspaceHome, 'workspaceHome')
|
|
262
|
+
this._lowLevelAgent = lowLevelAgent ?? Agent._LowLevelEnkiAgent
|
|
263
|
+
this._tools = new Map()
|
|
264
|
+
this._memories = new Map()
|
|
265
|
+
this._toolHandler = new ToolHandler(this._tools)
|
|
266
|
+
this._memoryHandler = new MemoryHandler(this._memories)
|
|
267
|
+
this._llmHandler = llm == null ? null : new LlmHandler(llm)
|
|
268
|
+
this._backend = null
|
|
269
|
+
this._dirty = true
|
|
270
|
+
|
|
271
|
+
for (const tool of tools) {
|
|
272
|
+
this.registerTool(tool)
|
|
273
|
+
}
|
|
274
|
+
for (const memory of memories) {
|
|
275
|
+
this.registerMemory(memory)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
toolPlain(func, options = {}) {
|
|
280
|
+
this.registerTool(Tool.fromFunction(func, { ...options, usesContext: false }))
|
|
281
|
+
return func
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
tool(func, options = {}) {
|
|
285
|
+
if (getFunctionParameters(func, false).length === 0) {
|
|
286
|
+
throw new TypeError(`Tool '${func.name || 'anonymous'}' must accept a RunContext argument`)
|
|
287
|
+
}
|
|
288
|
+
this.registerTool(Tool.fromFunction(func, { ...options, usesContext: true }))
|
|
289
|
+
return func
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
registerTool(tool) {
|
|
293
|
+
const normalized = tool instanceof Tool ? tool : new Tool(tool)
|
|
294
|
+
this._tools.set(normalized.name, normalized)
|
|
295
|
+
this._dirty = true
|
|
296
|
+
return normalized
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
registerMemory(memory) {
|
|
300
|
+
const normalized = memory instanceof MemoryModule ? memory : new MemoryModule(memory)
|
|
301
|
+
this._memories.set(normalized.name, normalized)
|
|
302
|
+
this._dirty = true
|
|
303
|
+
return normalized
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async run(userMessage, options = {}) {
|
|
307
|
+
const backend = this._ensureBackend()
|
|
308
|
+
const message = requiredString(userMessage, 'userMessage')
|
|
309
|
+
const sessionId = requiredString(options.sessionId ?? createSessionId(), 'sessionId')
|
|
310
|
+
|
|
311
|
+
this._toolHandler.setDeps(options.deps)
|
|
312
|
+
try {
|
|
313
|
+
const output = await backend.run(sessionId, message)
|
|
314
|
+
return new AgentRunResult(output)
|
|
315
|
+
} finally {
|
|
316
|
+
this._toolHandler.clearDeps()
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
_ensureBackend() {
|
|
321
|
+
if (this._backend != null && !this._dirty) {
|
|
322
|
+
return this._backend
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const toolSpecs = Array.from(this._tools.values(), (tool) => tool.asLowLevelTool())
|
|
326
|
+
const memorySpecs = Array.from(this._memories.values(), (memory) => memory.asLowLevelMemory())
|
|
327
|
+
const LowLevelAgent = this._lowLevelAgent
|
|
328
|
+
|
|
329
|
+
if (this._llmHandler && toolSpecs.length > 0 && memorySpecs.length > 0) {
|
|
330
|
+
this._backend = callFactory(
|
|
331
|
+
LowLevelAgent,
|
|
332
|
+
['withToolsMemoryAndLlm', 'with_tools_memory_and_llm'],
|
|
333
|
+
{
|
|
334
|
+
name: this.name,
|
|
335
|
+
systemPromptPreamble: this.instructions,
|
|
336
|
+
model: this.model,
|
|
337
|
+
maxIterations: this.maxIterations,
|
|
338
|
+
workspaceHome: this.workspaceHome,
|
|
339
|
+
tools: toolSpecs,
|
|
340
|
+
toolHandler: this._toolHandler,
|
|
341
|
+
memories: memorySpecs,
|
|
342
|
+
memoryHandler: this._memoryHandler,
|
|
343
|
+
llmHandler: this._llmHandler,
|
|
344
|
+
},
|
|
345
|
+
'custom tools, memory, and llm',
|
|
346
|
+
)
|
|
347
|
+
} else if (this._llmHandler && toolSpecs.length > 0) {
|
|
348
|
+
this._backend = callFactory(
|
|
349
|
+
LowLevelAgent,
|
|
350
|
+
['withToolsAndLlm', 'with_tools_and_llm'],
|
|
351
|
+
{
|
|
352
|
+
name: this.name,
|
|
353
|
+
systemPromptPreamble: this.instructions,
|
|
354
|
+
model: this.model,
|
|
355
|
+
maxIterations: this.maxIterations,
|
|
356
|
+
workspaceHome: this.workspaceHome,
|
|
357
|
+
tools: toolSpecs,
|
|
358
|
+
handler: this._toolHandler,
|
|
359
|
+
llmHandler: this._llmHandler,
|
|
360
|
+
},
|
|
361
|
+
'custom tools and llm',
|
|
362
|
+
)
|
|
363
|
+
} else if (this._llmHandler && memorySpecs.length > 0) {
|
|
364
|
+
this._backend = callFactory(
|
|
365
|
+
LowLevelAgent,
|
|
366
|
+
['withMemoryAndLlm', 'with_memory_and_llm'],
|
|
367
|
+
{
|
|
368
|
+
name: this.name,
|
|
369
|
+
systemPromptPreamble: this.instructions,
|
|
370
|
+
model: this.model,
|
|
371
|
+
maxIterations: this.maxIterations,
|
|
372
|
+
workspaceHome: this.workspaceHome,
|
|
373
|
+
memories: memorySpecs,
|
|
374
|
+
handler: this._memoryHandler,
|
|
375
|
+
llmHandler: this._llmHandler,
|
|
376
|
+
},
|
|
377
|
+
'custom memory and llm',
|
|
378
|
+
)
|
|
379
|
+
} else if (this._llmHandler) {
|
|
380
|
+
this._backend = callFactory(
|
|
381
|
+
LowLevelAgent,
|
|
382
|
+
['withLlm', 'with_llm'],
|
|
383
|
+
{
|
|
384
|
+
name: this.name,
|
|
385
|
+
systemPromptPreamble: this.instructions,
|
|
386
|
+
model: this.model,
|
|
387
|
+
maxIterations: this.maxIterations,
|
|
388
|
+
workspaceHome: this.workspaceHome,
|
|
389
|
+
llmHandler: this._llmHandler,
|
|
390
|
+
},
|
|
391
|
+
'custom llm',
|
|
392
|
+
)
|
|
393
|
+
} else if (toolSpecs.length > 0 && memorySpecs.length > 0) {
|
|
394
|
+
this._backend = callFactory(
|
|
395
|
+
LowLevelAgent,
|
|
396
|
+
['withToolsAndMemory', 'with_tools_and_memory'],
|
|
397
|
+
{
|
|
398
|
+
name: this.name,
|
|
399
|
+
systemPromptPreamble: this.instructions,
|
|
400
|
+
model: this.model,
|
|
401
|
+
maxIterations: this.maxIterations,
|
|
402
|
+
workspaceHome: this.workspaceHome,
|
|
403
|
+
tools: toolSpecs,
|
|
404
|
+
toolHandler: this._toolHandler,
|
|
405
|
+
memories: memorySpecs,
|
|
406
|
+
memoryHandler: this._memoryHandler,
|
|
407
|
+
},
|
|
408
|
+
'custom tools and memory',
|
|
409
|
+
)
|
|
410
|
+
} else if (toolSpecs.length > 0) {
|
|
411
|
+
this._backend = callFactory(
|
|
412
|
+
LowLevelAgent,
|
|
413
|
+
['withTools', 'with_tools'],
|
|
414
|
+
{
|
|
415
|
+
name: this.name,
|
|
416
|
+
systemPromptPreamble: this.instructions,
|
|
417
|
+
model: this.model,
|
|
418
|
+
maxIterations: this.maxIterations,
|
|
419
|
+
workspaceHome: this.workspaceHome,
|
|
420
|
+
tools: toolSpecs,
|
|
421
|
+
handler: this._toolHandler,
|
|
422
|
+
},
|
|
423
|
+
'custom tools',
|
|
424
|
+
)
|
|
425
|
+
} else if (memorySpecs.length > 0) {
|
|
426
|
+
this._backend = callFactory(
|
|
427
|
+
LowLevelAgent,
|
|
428
|
+
['withMemory', 'with_memory'],
|
|
429
|
+
{
|
|
430
|
+
name: this.name,
|
|
431
|
+
systemPromptPreamble: this.instructions,
|
|
432
|
+
model: this.model,
|
|
433
|
+
maxIterations: this.maxIterations,
|
|
434
|
+
workspaceHome: this.workspaceHome,
|
|
435
|
+
memories: memorySpecs,
|
|
436
|
+
handler: this._memoryHandler,
|
|
437
|
+
},
|
|
438
|
+
'custom memory',
|
|
439
|
+
)
|
|
440
|
+
} else {
|
|
441
|
+
this._backend = new LowLevelAgent(
|
|
442
|
+
this.name,
|
|
443
|
+
this.instructions,
|
|
444
|
+
this.model,
|
|
445
|
+
this.maxIterations,
|
|
446
|
+
this.workspaceHome,
|
|
447
|
+
)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
this._dirty = false
|
|
451
|
+
return this._backend
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
Agent._LowLevelEnkiAgent = NativeEnkiAgent
|
|
456
|
+
|
|
457
|
+
function requiredString(value, field) {
|
|
458
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
459
|
+
throw new TypeError(`${field} must be a non-empty string`)
|
|
460
|
+
}
|
|
461
|
+
return value
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function optionalString(value, field) {
|
|
465
|
+
if (value == null) {
|
|
466
|
+
return undefined
|
|
467
|
+
}
|
|
468
|
+
if (typeof value !== 'string') {
|
|
469
|
+
throw new TypeError(`${field} must be a string`)
|
|
470
|
+
}
|
|
471
|
+
return value
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function optionalPositiveInteger(value, field) {
|
|
475
|
+
if (value == null) {
|
|
476
|
+
return undefined
|
|
477
|
+
}
|
|
478
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
479
|
+
throw new TypeError(`${field} must be a positive integer`)
|
|
480
|
+
}
|
|
481
|
+
return value
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function validateJsonSchema(value) {
|
|
485
|
+
const json = requiredString(value, 'parametersJson')
|
|
486
|
+
JSON.parse(json)
|
|
487
|
+
return json
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function getFunctionDescription(func) {
|
|
491
|
+
return typeof func.description === 'string' ? func.description : ''
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function parseObjectJson(value, errorMessage) {
|
|
495
|
+
const parsed = value ? JSON.parse(value) : {}
|
|
496
|
+
if (parsed == null) {
|
|
497
|
+
return {}
|
|
498
|
+
}
|
|
499
|
+
if (typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
500
|
+
throw new TypeError(errorMessage)
|
|
501
|
+
}
|
|
502
|
+
return parsed
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function parseArrayJson(value) {
|
|
506
|
+
const parsed = value ? JSON.parse(value) : []
|
|
507
|
+
return Array.isArray(parsed) ? parsed : []
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function callFactory(LowLevelAgent, methodNames, args, featureName) {
|
|
511
|
+
for (const methodName of methodNames) {
|
|
512
|
+
if (typeof LowLevelAgent[methodName] === 'function') {
|
|
513
|
+
return LowLevelAgent[methodName](args)
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
throw new Error(`NativeEnkiAgent does not support ${featureName}`)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function createSessionId() {
|
|
521
|
+
return `session-${Date.now()}-${Math.random().toString(16).slice(2)}`
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
function getFunctionParameters(func, usesContext) {
|
|
525
|
+
const source = func.toString().replace(/\s+/g, ' ')
|
|
526
|
+
const match =
|
|
527
|
+
source.match(/^[^(]*\(([^)]*)\)/) ??
|
|
528
|
+
source.match(/^([^=()]+?)\s*=>/)
|
|
529
|
+
|
|
530
|
+
const rawParameters = match?.[1]
|
|
531
|
+
? match[1].split(',').map((part) => part.trim()).filter(Boolean)
|
|
532
|
+
: []
|
|
533
|
+
|
|
534
|
+
const parameters = rawParameters.map((parameter) => {
|
|
535
|
+
const [namePart, defaultPart] = parameter.split('=').map((part) => part.trim())
|
|
536
|
+
return {
|
|
537
|
+
name: namePart,
|
|
538
|
+
hasDefault: defaultPart != null,
|
|
539
|
+
defaultValue: defaultPart == null ? undefined : parseDefaultValue(defaultPart),
|
|
540
|
+
}
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
return usesContext ? parameters.slice(1) : parameters
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function parseDefaultValue(value) {
|
|
547
|
+
if (value === 'true') {
|
|
548
|
+
return true
|
|
549
|
+
}
|
|
550
|
+
if (value === 'false') {
|
|
551
|
+
return false
|
|
552
|
+
}
|
|
553
|
+
if (value === "''" || value === '""') {
|
|
554
|
+
return ''
|
|
555
|
+
}
|
|
556
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
557
|
+
return Number(value)
|
|
558
|
+
}
|
|
559
|
+
return undefined
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function stringifyToolResult(value) {
|
|
563
|
+
if (typeof value === 'string') {
|
|
564
|
+
return value
|
|
565
|
+
}
|
|
566
|
+
if (value == null) {
|
|
567
|
+
return ''
|
|
568
|
+
}
|
|
569
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
570
|
+
return String(value)
|
|
571
|
+
}
|
|
572
|
+
return JSON.stringify(value)
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
module.exports = {
|
|
576
|
+
...nativeBinding,
|
|
577
|
+
Agent,
|
|
578
|
+
AgentRunResult,
|
|
579
|
+
EnkiAgent,
|
|
580
|
+
LlmProviderBackend,
|
|
581
|
+
MemoryBackend,
|
|
582
|
+
MemoryModule,
|
|
583
|
+
NativeEnkiAgent,
|
|
584
|
+
RunContext,
|
|
585
|
+
Tool,
|
|
586
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export declare class NativeEnkiAgent {
|
|
4
|
+
constructor(name?: string | undefined | null, systemPromptPreamble?: string | undefined | null, model?: string | undefined | null, maxIterations?: number | undefined | null, workspaceHome?: string | undefined | null)
|
|
5
|
+
run(sessionId: string, userMessage: string): Promise<unknown>
|
|
6
|
+
}
|