@kigathi/ai-agents 0.1.1 → 0.1.3

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 (2) hide show
  1. package/README.md +415 -37
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @kigathi/ai-agents
2
2
 
3
- Unified Agents/Bots SDK for Responses API.
3
+ Unified Agents/Bots SDK for the OpenAI Responses API.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,84 +8,462 @@ Unified Agents/Bots SDK for Responses API.
8
8
  npm install @kigathi/ai-agents
9
9
  ```
10
10
 
11
- ## Direct OpenAI mode
11
+ For direct mode, also install:
12
+
13
+ ```bash
14
+ npm install openai
15
+ ```
16
+
17
+ ## Quick API shape
18
+
19
+ ```js
20
+ import { createClient } from "@kigathi/ai-agents";
21
+
22
+ const sdk = createClient(config);
23
+ sdk.registerTool(tool);
24
+ sdk.createAgent(agent);
25
+ const result = await sdk.run(params);
26
+ ```
27
+
28
+ ## Modes
29
+
30
+ The SDK supports three setup patterns, and in normal usage you do not need to pass `mode` manually. The client infers it from the config you provide.
31
+
32
+ ### 1. Direct mode
33
+
34
+ Use this when your app should call OpenAI directly and you do not need backend persistence.
35
+
36
+ ```js
37
+ import { createClient } from "@kigathi/ai-agents";
38
+
39
+ const sdk = createClient({
40
+ apiKey: process.env.OPENAI_API_KEY,
41
+ });
42
+ ```
43
+
44
+ Required:
45
+
46
+ - `apiKey`
47
+
48
+ ### 2. Proxy mode
49
+
50
+ Use this when your app should call your backend, and your backend should perform the agent run.
51
+
52
+ ```js
53
+ import { createClient } from "@kigathi/ai-agents";
54
+
55
+ const sdk = createClient({
56
+ backendUrl: "https://api.example.com",
57
+ });
58
+ ```
59
+
60
+ Required:
61
+
62
+ - `backendUrl`
63
+
64
+ ### 3. Direct mode with backend persistence
65
+
66
+ Use this when your app should call OpenAI directly, but you still want your backend to persist messages, receive tool events, or trigger downstream workflows.
67
+
68
+ ```js
69
+ import { createClient } from "@kigathi/ai-agents";
70
+
71
+ const sdk = createClient({
72
+ apiKey: process.env.OPENAI_API_KEY,
73
+ backendUrl: "https://api.example.com",
74
+ });
75
+ ```
76
+
77
+ Required:
78
+
79
+ - `apiKey`
80
+ - `backendUrl`
81
+
82
+ Behavior summary:
83
+
84
+ - `apiKey` only: direct OpenAI execution
85
+ - `backendUrl` only: proxy mode, where your backend performs the run
86
+ - `apiKey` and `backendUrl` together: direct OpenAI execution plus backend persistence and event sync
87
+
88
+ ## Minimal vs full examples
89
+
90
+ The sections below show the smallest valid call for each API, followed by a more realistic production-style example.
91
+
92
+ ### 1. Create a client
93
+
94
+ Minimal direct mode:
12
95
 
13
96
  ```js
14
- import { createClient } from '@kigathi/ai-agents';
97
+ import { createClient } from "@kigathi/ai-agents";
98
+
99
+ const sdk = createClient({
100
+ apiKey: process.env.OPENAI_API_KEY,
101
+ });
102
+ ```
103
+
104
+ Minimal proxy mode:
105
+
106
+ ```js
107
+ import { createClient } from "@kigathi/ai-agents";
108
+
109
+ const sdk = createClient({
110
+ backendUrl: "https://api.example.com",
111
+ });
112
+ ```
113
+
114
+ Full example:
115
+
116
+ ```js
117
+ import { createClient } from "@kigathi/ai-agents";
15
118
 
16
119
  const sdk = createClient({
17
120
  apiKey: process.env.OPENAI_API_KEY,
18
121
  orgId: process.env.OPENAI_ORG_ID,
19
122
  projectId: process.env.OPENAI_PROJECT_ID,
123
+ backendUrl: "https://api.example.com",
124
+ pricing: {
125
+ "gpt-4.1-mini": {
126
+ prompt_per_million: 0.4,
127
+ completion_per_million: 1.6,
128
+ },
129
+ },
20
130
  });
131
+ ```
132
+
133
+ Required parameters:
134
+
135
+ - Direct mode: `apiKey`
136
+ - Proxy mode: `backendUrl`
137
+
138
+ Optional parameters:
139
+
140
+ - `mode`
141
+ - `orgId`
142
+ - `projectId`
143
+ - `pricing`
144
+
145
+ ### Direct OpenAI + backend persistence mode
146
+
147
+ You can also run the model directly with OpenAI while still sending conversation events to your backend for persistence, analytics, or post-processing.
148
+
149
+ Use `apiKey` and `backendUrl` together:
21
150
 
151
+ ```js
152
+ import { createClient } from "@kigathi/ai-agents";
153
+
154
+ const sdk = createClient({
155
+ apiKey: process.env.OPENAI_API_KEY,
156
+ backendUrl: "https://api.example.com",
157
+ });
158
+ ```
159
+
160
+ What this mode does:
161
+
162
+ - Runs the actual model request against OpenAI directly
163
+ - Persists user and assistant messages to your backend
164
+ - Syncs tool-call events to your backend on a best-effort basis
165
+
166
+ Useful request fields in this mode:
167
+
168
+ - `conversation_id`
169
+ - `user_id`
170
+ - `metadata`
171
+ - `client_message_id`
172
+ - `idempotency_key`
173
+ - `idempotency_key_response`
174
+
175
+ ### 2. Register a tool
176
+
177
+ Minimal example:
178
+
179
+ ```js
22
180
  sdk.registerTool({
23
- name: 'lookup_order',
24
- type: 'function',
25
- description: 'Find order by order number',
181
+ name: "lookup_order",
182
+ });
183
+ ```
184
+
185
+ Full example:
186
+
187
+ ```js
188
+ sdk.registerTool({
189
+ name: "lookup_order",
190
+ type: "function",
191
+ description: "Find order details by order number.",
26
192
  parameters_schema: {
27
- type: 'object',
28
- properties: { order_number: { type: 'string' } },
29
- required: ['order_number'],
193
+ type: "object",
194
+ properties: {
195
+ order_number: { type: "string" },
196
+ },
197
+ required: ["order_number"],
198
+ },
199
+ handler: async ({ order_number }, context) => {
200
+ return {
201
+ order_number,
202
+ status: "processing",
203
+ requested_by: context.userId ?? null,
204
+ };
30
205
  },
31
- handler: async ({ order_number }) => ({ order_number, status: 'processing' }),
32
206
  });
207
+ ```
208
+
209
+ Required parameters:
210
+
211
+ - `name`
212
+
213
+ Useful optional parameters:
214
+
215
+ - `description`
216
+ - `parameters_schema`
217
+ - `handler`
218
+
219
+ Notes:
220
+
221
+ - If you omit `handler`, tool calls will fail gracefully with `Tool not registered: <name>`.
222
+ - If an agent does not list specific tools, it can use all registered tools.
223
+
224
+ ### 3. Register an agent
225
+
226
+ Minimal example:
227
+
228
+ ```js
229
+ sdk.createAgent({
230
+ name: "support-bot",
231
+ model: "gpt-4.1-mini",
232
+ });
233
+ ```
33
234
 
235
+ Full example:
236
+
237
+ ```js
34
238
  sdk.createAgent({
35
- name: 'support-bot',
36
- model: 'gpt-4.1-mini',
37
- instructions: 'You are a concise support assistant.',
38
- tools: ['lookup_order'],
239
+ id: "support-bot-v1",
240
+ name: "support-bot",
241
+ model: "gpt-4.1-mini",
242
+ instructions: "You are a concise support assistant. Use tools when needed.",
243
+ temperature: 0.3,
244
+ max_output_tokens: 400,
245
+ tools: ["lookup_order"],
246
+ metadata: {
247
+ team: "support",
248
+ channel: "web",
249
+ },
250
+ });
251
+ ```
252
+
253
+ Required parameters:
254
+
255
+ - `name`
256
+ - `model`
257
+
258
+ Useful optional parameters:
259
+
260
+ - `id`
261
+ - `instructions`
262
+ - `temperature`
263
+ - `max_output_tokens`
264
+ - `tools`
265
+ - `metadata`
266
+
267
+ ### 4. Run an agent
268
+
269
+ Minimal example:
270
+
271
+ ```js
272
+ const result = await sdk.run({
273
+ agent: "support-bot",
274
+ message: "Where is order AX-4420?",
275
+ });
276
+
277
+ console.log(result.output_text);
278
+ ```
279
+
280
+ Full example:
281
+
282
+ ```js
283
+ const result = await sdk.run({
284
+ agent: "support-bot",
285
+ message: "Check order AX-4420 and summarize the current status.",
286
+ conversation_id: 1234,
287
+ conversation_key: "support:customer-42",
288
+ user_id: 42,
289
+ context: {
290
+ userId: 42,
291
+ accountId: "acc_123",
292
+ },
293
+ messages: [
294
+ { role: "user", content: "Hi" },
295
+ { role: "assistant", content: "How can I help?" },
296
+ ],
297
+ max_history_messages: 20,
298
+ maxToolIterations: 8,
39
299
  });
40
300
 
41
- const result = await sdk.run({ agent: 'support-bot', message: 'Check order AX-4420' });
42
301
  console.log(result.output_text);
302
+ console.log(result.usage);
303
+ console.log(result.cost_usd);
43
304
  ```
44
305
 
45
- ## Streaming
306
+ Required parameters:
307
+
308
+ - `agent`
309
+ - `message`
310
+
311
+ Useful optional parameters:
312
+
313
+ - `conversation_id`
314
+ - `conversation_key`
315
+ - `user_id`
316
+ - `context`
317
+ - `messages`
318
+ - `max_history_messages`
319
+ - `maxToolIterations`
320
+ - `previous_response_id`
321
+ - `replying_to`
322
+
323
+ ### 5. Stream an agent response
324
+
325
+ Minimal example:
46
326
 
47
327
  ```js
48
328
  for await (const delta of sdk.runStream({
49
- agent: 'support-bot',
50
- message: 'Give me a short summary of today\'s ticket updates',
329
+ agent: "support-bot",
330
+ message: "Give me a short update on order AX-4420.",
51
331
  })) {
52
332
  process.stdout.write(delta);
53
333
  }
54
334
  ```
55
335
 
56
- ## Backend proxy mode (frontend-safe)
336
+ Full example:
57
337
 
58
338
  ```js
339
+ for await (const delta of sdk.runStream({
340
+ agent: "support-bot",
341
+ message: "Summarize the latest ticket updates.",
342
+ conversation_key: "support:customer-42",
343
+ user_id: 42,
344
+ })) {
345
+ process.stdout.write(delta);
346
+ }
347
+ ```
348
+
349
+ ## Complete minimal working example
350
+
351
+ ```js
352
+ import { createClient } from "@kigathi/ai-agents";
353
+
354
+ const sdk = createClient({
355
+ apiKey: process.env.OPENAI_API_KEY,
356
+ });
357
+
358
+ sdk.registerTool({
359
+ name: "lookup_order",
360
+ description: "Return a fake order status.",
361
+ parameters_schema: {
362
+ type: "object",
363
+ properties: {
364
+ order_number: { type: "string" },
365
+ },
366
+ required: ["order_number"],
367
+ },
368
+ handler: async ({ order_number }) => ({
369
+ order_number,
370
+ status: "processing",
371
+ }),
372
+ });
373
+
374
+ sdk.createAgent({
375
+ name: "support-bot",
376
+ model: "gpt-4.1-mini",
377
+ instructions: "You are a concise support assistant.",
378
+ tools: ["lookup_order"],
379
+ });
380
+
381
+ const result = await sdk.run({
382
+ agent: "support-bot",
383
+ message: "Check order AX-4420",
384
+ });
385
+
386
+ console.log(result.output_text);
387
+ ```
388
+
389
+ ## Complete proxy example
390
+
391
+ ```js
392
+ import { createClient } from "@kigathi/ai-agents";
393
+
59
394
  const sdk = createClient({
60
- backendUrl: 'https://api.example.com',
61
- mode: 'proxy',
395
+ backendUrl: "https://api.example.com",
62
396
  });
63
397
 
64
398
  const result = await sdk.run({
65
- agent: 'support-bot',
66
- message: 'Start claim #99',
399
+ agent: "support-bot",
400
+ message: "Start claim #99",
67
401
  conversation_id: 1234,
68
402
  });
403
+
404
+ console.log(result.output_text);
69
405
  ```
70
406
 
71
- ## Full sample apps
407
+ ## Complete direct + backend persistence example
408
+
409
+ ```js
410
+ import { createClient } from "@kigathi/ai-agents";
72
411
 
73
- - `../examples/lyre-ai-agents-node/express-chat` - Express server + Tailwind widget UI
74
- - `../examples/lyre-ai-agents-node/nuxt-chat` - Nuxt 3 app + server API route + Tailwind
75
- - `../examples/lyre-ai-agents-node/sveltekit-chat` - SvelteKit app + server endpoint + Tailwind
412
+ const sdk = createClient({
413
+ apiKey: process.env.OPENAI_API_KEY,
414
+ backendUrl: "https://api.example.com",
415
+ });
76
416
 
77
- All three use `@kigathi/ai-agents` in `proxy` mode against Axis backend so conversation/message/cost metadata stays in Axis.
417
+ sdk.registerTool({
418
+ name: "lookup_order",
419
+ description: "Find order by order number.",
420
+ parameters_schema: {
421
+ type: "object",
422
+ properties: {
423
+ order_number: { type: "string" },
424
+ },
425
+ required: ["order_number"],
426
+ },
427
+ handler: async ({ order_number }) => ({
428
+ order_number,
429
+ status: "processing",
430
+ }),
431
+ });
78
432
 
79
- ## Publishing to npm
433
+ sdk.createAgent({
434
+ name: "support-bot",
435
+ model: "gpt-4.1-mini",
436
+ instructions: "You are a concise support assistant.",
437
+ tools: ["lookup_order"],
438
+ });
439
+
440
+ const result = await sdk.run({
441
+ agent: "support-bot",
442
+ message: "Check order AX-4420",
443
+ conversation_id: 1234,
444
+ user_id: 42,
445
+ client_message_id: "msg_123",
446
+ metadata: {
447
+ source: "dashboard",
448
+ account_id: "acc_123",
449
+ },
450
+ });
451
+
452
+ console.log(result.output_text);
453
+ ```
454
+
455
+ ## Full sample apps
80
456
 
81
- This package is configured for public publishing as a scoped package via:
457
+ - [express-chat](https://github.com/kigathi-chege/lyre-ai-agents-examples/tree/main/express-chat) - Express server + Tailwind widget UI
458
+ - [nuxt-chat](https://github.com/kigathi-chege/lyre-ai-agents-examples/tree/main/nuxt-chat) - Nuxt 3 app + server API route + Tailwind
459
+ - [sveltekit-chat](https://github.com/kigathi-chege/lyre-ai-agents-examples/tree/main/sveltekit-chat) - SvelteKit app + server endpoint + Tailwind
82
460
 
83
- - `name: @kigathi/ai-agents`
84
- - `publishConfig.access: public`
461
+ All three use `@kigathi/ai-agents` in direct mode with backend persistence so OpenAI handles model execution while Axis stores conversation, message, and related event metadata.
85
462
 
86
- Before the first publish, make sure you:
463
+ ## Notes
87
464
 
88
- 1. Pick and add a license file.
89
- 2. Log in with `npm login`.
90
- 3. Run `npm pack --dry-run` to inspect the publish artifact.
91
- 4. Publish with `npm publish`.
465
+ - `createClient()` auto-selects proxy mode when `backendUrl` is provided without `apiKey`. Otherwise it uses direct mode.
466
+ - In direct mode, the consuming app must have the `openai` package installed.
467
+ - In direct mode with `backendUrl`, the SDK still calls OpenAI directly, then asynchronously persists messages and tool events to your backend.
468
+ - You can pass either an agent name/id or a full agent object to `run()`.
469
+ - If proxy mode cannot find a local agent, it will try to resolve the agent from the backend.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kigathi/ai-agents",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Forward-only Agents/Bots SDK on top of OpenAI Responses API.",
5
5
  "type": "module",
6
6
  "sideEffects": false,