@pikku/core 0.12.1 → 0.12.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.
- package/CHANGELOG.md +34 -0
- package/dist/crypto-utils.d.ts +10 -0
- package/dist/crypto-utils.js +62 -0
- package/dist/function/function-runner.js +4 -4
- package/dist/function/functions.types.d.ts +26 -1
- package/dist/function/functions.types.js +16 -0
- package/dist/handle-error.d.ts +1 -1
- package/dist/handle-error.js +7 -3
- package/dist/index.d.ts +14 -2
- package/dist/index.js +1 -1
- package/dist/middleware-runner.js +1 -0
- package/dist/permissions.js +1 -0
- package/dist/pikku-state.js +7 -1
- package/dist/schema.js +1 -1
- package/dist/services/gateway-service.d.ts +19 -0
- package/dist/services/gateway-service.js +1 -0
- package/dist/services/in-memory-workflow-service.d.ts +8 -2
- package/dist/services/in-memory-workflow-service.js +28 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +1 -0
- package/dist/services/local-gateway-service.d.ts +22 -0
- package/dist/services/local-gateway-service.js +51 -0
- package/dist/services/workflow-service.d.ts +8 -2
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/service-tests.d.ts +31 -0
- package/dist/testing/service-tests.js +598 -0
- package/dist/types/core.types.d.ts +12 -2
- package/dist/types/state.types.d.ts +9 -2
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils.js +1 -1
- package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +6 -0
- package/dist/wirings/ai-agent/agent-dynamic-workflow.js +348 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +1 -1
- package/dist/wirings/ai-agent/ai-agent-memory.js +19 -7
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -7
- package/dist/wirings/ai-agent/ai-agent-prepare.js +141 -48
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +4 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +381 -27
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +7 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +126 -48
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +57 -3
- package/dist/wirings/ai-agent/index.d.ts +2 -3
- package/dist/wirings/ai-agent/index.js +1 -2
- package/dist/wirings/channel/channel-handler.d.ts +5 -2
- package/dist/wirings/channel/channel-handler.js +16 -2
- package/dist/wirings/channel/channel-middleware-runner.js +1 -0
- package/dist/wirings/channel/channel.types.d.ts +7 -7
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +8 -1
- package/dist/wirings/channel/local/local-channel-handler.js +22 -3
- package/dist/wirings/channel/local/local-channel-runner.js +28 -5
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +2 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +5 -2
- package/dist/wirings/cli/cli-runner.js +13 -2
- package/dist/wirings/cli/cli.types.d.ts +1 -0
- package/dist/wirings/gateway/gateway-runner.d.ts +24 -0
- package/dist/wirings/gateway/gateway-runner.js +325 -0
- package/dist/wirings/gateway/gateway.types.d.ts +127 -0
- package/dist/wirings/gateway/gateway.types.js +1 -0
- package/dist/wirings/gateway/index.d.ts +2 -0
- package/dist/wirings/gateway/index.js +1 -0
- package/dist/wirings/http/http-routes.js +0 -1
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +28 -3
- package/dist/wirings/http/http.types.d.ts +3 -11
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +3 -0
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +4 -4
- package/dist/wirings/http/web-request.d.ts +12 -0
- package/dist/wirings/http/web-request.js +85 -0
- package/dist/wirings/mcp/mcp-endpoint-registry.js +1 -1
- package/dist/wirings/mcp/mcp-runner.js +13 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +30 -6
- package/dist/wirings/rpc/rpc-runner.js +36 -14
- package/dist/wirings/rpc/rpc-types.d.ts +6 -1
- package/dist/wirings/rpc/wire-addon.d.ts +1 -0
- package/dist/wirings/rpc/wire-addon.js +1 -1
- package/dist/wirings/scheduler/scheduler-runner.js +1 -0
- package/dist/wirings/workflow/graph/graph-validation.d.ts +3 -0
- package/dist/wirings/workflow/graph/graph-validation.js +175 -0
- package/dist/wirings/workflow/graph/index.d.ts +1 -0
- package/dist/wirings/workflow/graph/index.js +1 -0
- package/dist/wirings/workflow/index.d.ts +1 -1
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +8 -2
- package/dist/wirings/workflow/pikku-workflow-service.js +1 -2
- package/dist/wirings/workflow/workflow.types.d.ts +10 -1
- package/package.json +6 -3
- package/src/crypto-utils.test.ts +99 -1
- package/src/crypto-utils.ts +114 -0
- package/src/function/function-runner.ts +5 -5
- package/src/function/functions.types.ts +38 -1
- package/src/handle-error.test.ts +65 -2
- package/src/handle-error.ts +8 -4
- package/src/index.ts +14 -0
- package/src/middleware-runner.ts +1 -0
- package/src/permissions.ts +1 -0
- package/src/pikku-state.ts +8 -1
- package/src/schema.ts +1 -1
- package/src/services/gateway-service.ts +20 -0
- package/src/services/in-memory-workflow-service.ts +45 -2
- package/src/services/index.ts +2 -0
- package/src/services/local-gateway-service.ts +62 -0
- package/src/services/workflow-service.ts +12 -1
- package/src/testing/index.ts +2 -0
- package/src/testing/service-tests.ts +873 -0
- package/src/types/core.types.ts +12 -1
- package/src/types/state.types.ts +12 -2
- package/src/utils/hash.test.ts +68 -0
- package/src/utils/hash.ts +26 -0
- package/src/utils.ts +1 -1
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +469 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +17 -7
- package/src/wirings/ai-agent/ai-agent-prepare.ts +194 -62
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +3 -1
- package/src/wirings/ai-agent/ai-agent-runner.ts +553 -31
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +209 -2
- package/src/wirings/ai-agent/ai-agent-stream.ts +195 -91
- package/src/wirings/ai-agent/ai-agent.types.ts +57 -3
- package/src/wirings/ai-agent/index.ts +3 -5
- package/src/wirings/channel/channel-handler.ts +41 -4
- package/src/wirings/channel/channel-middleware-runner.ts +1 -0
- package/src/wirings/channel/channel.types.ts +12 -7
- package/src/wirings/channel/index.ts +1 -0
- package/src/wirings/channel/local/local-channel-handler.ts +31 -3
- package/src/wirings/channel/local/local-channel-runner.ts +32 -8
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +2 -0
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +8 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +5 -2
- package/src/wirings/cli/cli-runner.ts +15 -2
- package/src/wirings/cli/cli.types.ts +1 -0
- package/src/wirings/gateway/gateway-runner.test.ts +474 -0
- package/src/wirings/gateway/gateway-runner.ts +411 -0
- package/src/wirings/gateway/gateway.types.ts +149 -0
- package/src/wirings/gateway/index.ts +13 -0
- package/src/wirings/http/http-routes.ts +0 -1
- package/src/wirings/http/http-runner.ts +38 -10
- package/src/wirings/http/http.types.ts +3 -12
- package/src/wirings/http/index.ts +3 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +4 -0
- package/src/wirings/http/pikku-fetch-http-response.ts +4 -4
- package/src/wirings/http/web-request.test.ts +236 -0
- package/src/wirings/http/web-request.ts +104 -0
- package/src/wirings/mcp/mcp-endpoint-registry.ts +1 -1
- package/src/wirings/mcp/mcp-runner.ts +30 -12
- package/src/wirings/rpc/rpc-runner.ts +45 -24
- package/src/wirings/rpc/rpc-types.ts +6 -1
- package/src/wirings/rpc/wire-addon.ts +2 -1
- package/src/wirings/scheduler/scheduler-runner.ts +1 -0
- package/src/wirings/workflow/graph/graph-validation.test.ts +170 -0
- package/src/wirings/workflow/graph/graph-validation.ts +237 -0
- package/src/wirings/workflow/graph/index.ts +5 -0
- package/src/wirings/workflow/index.ts +1 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +14 -3
- package/src/wirings/workflow/workflow.types.ts +9 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +0 -146
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +0 -363
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +0 -214
|
@@ -94,7 +94,12 @@ describe('streamAIAgent', () => {
|
|
|
94
94
|
{}
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
assert.deepEqual(updates, [
|
|
97
|
+
assert.deepEqual(updates, [
|
|
98
|
+
{
|
|
99
|
+
runId: 'run-1',
|
|
100
|
+
patch: { status: 'failed', errorMessage: 'stream failed' },
|
|
101
|
+
},
|
|
102
|
+
])
|
|
98
103
|
assert.deepEqual(
|
|
99
104
|
events.map((event) => event.type),
|
|
100
105
|
['step-start', 'error', 'done']
|
|
@@ -198,7 +203,7 @@ describe('streamAIAgent', () => {
|
|
|
198
203
|
pikkuState(null, 'rpc', 'meta')['tool-x'] = 'tool-x'
|
|
199
204
|
pikkuState(null, 'function', 'meta')['tool-x'] = {
|
|
200
205
|
description: 'test tool',
|
|
201
|
-
|
|
206
|
+
approvalRequired: true,
|
|
202
207
|
}
|
|
203
208
|
pikkuState(null, 'misc', 'schemas').set('ToolXInput', {
|
|
204
209
|
type: 'object',
|
|
@@ -260,6 +265,208 @@ describe('streamAIAgent', () => {
|
|
|
260
265
|
)
|
|
261
266
|
})
|
|
262
267
|
|
|
268
|
+
test('suspends run when multiple tool calls need approval (explicit policy)', async () => {
|
|
269
|
+
addTestAgent('multi-approval-agent')
|
|
270
|
+
|
|
271
|
+
const updates: Array<{ runId: string; patch: unknown }> = []
|
|
272
|
+
const events: AIStreamEvent[] = []
|
|
273
|
+
|
|
274
|
+
const mockServices = {
|
|
275
|
+
logger: {
|
|
276
|
+
info: () => {},
|
|
277
|
+
warn: () => {},
|
|
278
|
+
error: () => {},
|
|
279
|
+
debug: () => {},
|
|
280
|
+
},
|
|
281
|
+
aiAgentRunner: {
|
|
282
|
+
stream: async (): Promise<AIAgentStepResult> => {
|
|
283
|
+
// Simulate LLM returning 3 addTodo calls in one step
|
|
284
|
+
return makeStepResult({
|
|
285
|
+
toolCalls: [
|
|
286
|
+
{
|
|
287
|
+
toolCallId: 'tc-1',
|
|
288
|
+
toolName: 'todos__addTodo',
|
|
289
|
+
args: { title: 'todo 1' },
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
toolCallId: 'tc-2',
|
|
293
|
+
toolName: 'todos__addTodo',
|
|
294
|
+
args: { title: 'todo 2' },
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
toolCallId: 'tc-3',
|
|
298
|
+
toolName: 'todos__addTodo',
|
|
299
|
+
args: { title: 'todo 3' },
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
// No toolResults since tools have no execute (needsApproval)
|
|
303
|
+
})
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
aiRunState: {
|
|
307
|
+
createRun: async () => 'run-multi-approval',
|
|
308
|
+
updateRun: async (runId: string, patch: unknown) => {
|
|
309
|
+
updates.push({ runId, patch })
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
} as any
|
|
313
|
+
|
|
314
|
+
pikkuState(null, 'package', 'singletonServices', mockServices)
|
|
315
|
+
|
|
316
|
+
const agentName = 'multi-approval-agent'
|
|
317
|
+
pikkuState(null, 'agent', 'agentsMeta')[agentName].tools = [
|
|
318
|
+
'todos__addTodo',
|
|
319
|
+
]
|
|
320
|
+
pikkuState(null, 'rpc', 'meta')['todos__addTodo'] = 'addTodo'
|
|
321
|
+
pikkuState(null, 'function', 'meta')['addTodo'] = {
|
|
322
|
+
description: 'Add a todo',
|
|
323
|
+
approvalRequired: true,
|
|
324
|
+
inputSchemaName: 'AddTodoInput',
|
|
325
|
+
}
|
|
326
|
+
pikkuState(null, 'misc', 'schemas').set('AddTodoInput', {
|
|
327
|
+
type: 'object',
|
|
328
|
+
properties: { title: { type: 'string' } },
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
await streamAIAgent(
|
|
332
|
+
agentName,
|
|
333
|
+
{
|
|
334
|
+
message: 'create 3 todos',
|
|
335
|
+
threadId: 'thread-multi-approval',
|
|
336
|
+
resourceId: 'resource-multi-approval',
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
channelId: 'channel-multi-approval',
|
|
340
|
+
openingData: undefined,
|
|
341
|
+
state: 'open',
|
|
342
|
+
send: (event: AIStreamEvent) => {
|
|
343
|
+
events.push(event)
|
|
344
|
+
},
|
|
345
|
+
close: () => {},
|
|
346
|
+
},
|
|
347
|
+
{}
|
|
348
|
+
// No options → defaults to requiresToolApproval: 'explicit'
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
// Should suspend on first tool call
|
|
352
|
+
const approvalEvent = events.find(
|
|
353
|
+
(e) => e.type === 'approval-request'
|
|
354
|
+
) as any
|
|
355
|
+
assert.ok(approvalEvent, 'Should have an approval-request event')
|
|
356
|
+
assert.equal(approvalEvent.toolCallId, 'tc-1')
|
|
357
|
+
assert.equal(approvalEvent.toolName, 'todos__addTodo')
|
|
358
|
+
|
|
359
|
+
// Run should be suspended
|
|
360
|
+
assert.ok(
|
|
361
|
+
updates.some((u) => (u.patch as any).status === 'suspended'),
|
|
362
|
+
'Run should be suspended for approval'
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
assert.ok(events.some((e) => e.type === 'done'))
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
test('suspends run for addon tools using namespaced resolution (explicit policy)', async () => {
|
|
369
|
+
addTestAgent('addon-approval-agent')
|
|
370
|
+
|
|
371
|
+
const updates: Array<{ runId: string; patch: unknown }> = []
|
|
372
|
+
const events: AIStreamEvent[] = []
|
|
373
|
+
|
|
374
|
+
const mockServices = {
|
|
375
|
+
logger: {
|
|
376
|
+
info: () => {},
|
|
377
|
+
warn: () => {},
|
|
378
|
+
error: () => {},
|
|
379
|
+
debug: () => {},
|
|
380
|
+
},
|
|
381
|
+
aiAgentRunner: {
|
|
382
|
+
stream: async (params: any): Promise<AIAgentStepResult> => {
|
|
383
|
+
// Verify the tool was built with needsApproval
|
|
384
|
+
const addTodoTool = params.tools.find(
|
|
385
|
+
(t: any) => t.name === 'todos__addTodo'
|
|
386
|
+
)
|
|
387
|
+
assert.ok(addTodoTool, 'Tool todos__addTodo should exist')
|
|
388
|
+
assert.equal(
|
|
389
|
+
addTodoTool.needsApproval,
|
|
390
|
+
true,
|
|
391
|
+
'Tool should have needsApproval=true'
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
// Simulate LLM calling the tool
|
|
395
|
+
return makeStepResult({
|
|
396
|
+
toolCalls: [
|
|
397
|
+
{
|
|
398
|
+
toolCallId: 'tc-1',
|
|
399
|
+
toolName: 'todos__addTodo',
|
|
400
|
+
args: { title: 'new todo' },
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
})
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
aiRunState: {
|
|
407
|
+
createRun: async () => 'run-addon-approval',
|
|
408
|
+
updateRun: async (runId: string, patch: unknown) => {
|
|
409
|
+
updates.push({ runId, patch })
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
} as any
|
|
413
|
+
|
|
414
|
+
pikkuState(null, 'package', 'singletonServices', mockServices)
|
|
415
|
+
|
|
416
|
+
// Register addon package
|
|
417
|
+
pikkuState(null, 'addons', 'packages').set('todos', {
|
|
418
|
+
package: '@test/addon-todos',
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
// Set up addon package's function metadata
|
|
422
|
+
pikkuState('@test/addon-todos', 'function', 'meta')['addTodo'] = {
|
|
423
|
+
description: 'Add a todo',
|
|
424
|
+
approvalRequired: true,
|
|
425
|
+
inputSchemaName: 'AddTodoInput',
|
|
426
|
+
}
|
|
427
|
+
pikkuState('@test/addon-todos', 'misc', 'schemas').set('AddTodoInput', {
|
|
428
|
+
type: 'object',
|
|
429
|
+
properties: { title: { type: 'string' } },
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
// Set up agent with namespaced tool
|
|
433
|
+
const agentName = 'addon-approval-agent'
|
|
434
|
+
pikkuState(null, 'agent', 'agentsMeta')[agentName].tools = ['todos:addTodo']
|
|
435
|
+
|
|
436
|
+
await streamAIAgent(
|
|
437
|
+
agentName,
|
|
438
|
+
{
|
|
439
|
+
message: 'add a todo',
|
|
440
|
+
threadId: 'thread-addon-approval',
|
|
441
|
+
resourceId: 'resource-addon-approval',
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
channelId: 'channel-addon-approval',
|
|
445
|
+
openingData: undefined,
|
|
446
|
+
state: 'open',
|
|
447
|
+
send: (event: AIStreamEvent) => {
|
|
448
|
+
events.push(event)
|
|
449
|
+
},
|
|
450
|
+
close: () => {},
|
|
451
|
+
},
|
|
452
|
+
{}
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
// Should suspend on the tool call
|
|
456
|
+
const approvalEvent = events.find(
|
|
457
|
+
(e) => e.type === 'approval-request'
|
|
458
|
+
) as any
|
|
459
|
+
assert.ok(approvalEvent, 'Should have an approval-request event')
|
|
460
|
+
assert.equal(approvalEvent.toolCallId, 'tc-1')
|
|
461
|
+
assert.equal(approvalEvent.toolName, 'todos__addTodo')
|
|
462
|
+
|
|
463
|
+
// Run should be suspended
|
|
464
|
+
assert.ok(
|
|
465
|
+
updates.some((u) => (u.patch as any).status === 'suspended'),
|
|
466
|
+
'Run should be suspended for approval'
|
|
467
|
+
)
|
|
468
|
+
})
|
|
469
|
+
|
|
263
470
|
test('suspends with agent-call type when sub-agent returns approval sentinel', async () => {
|
|
264
471
|
addTestAgent('parent-agent')
|
|
265
472
|
|