@pikku/core 0.12.0 → 0.12.2
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 +40 -0
- package/dist/errors/errors.d.ts +6 -0
- package/dist/errors/errors.js +10 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/function/function-runner.d.ts +3 -3
- package/dist/function/function-runner.js +66 -44
- package/dist/function/functions.types.d.ts +1 -0
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +2 -2
- package/dist/index.d.ts +5 -3
- package/dist/index.js +2 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.js +2 -0
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-bearer.js +1 -1
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +1 -1
- package/dist/middleware/cors.d.ts +2 -2
- package/dist/middleware/cors.js +45 -37
- package/dist/middleware-runner.d.ts +1 -1
- package/dist/middleware-runner.js +1 -0
- package/dist/permissions.d.ts +2 -2
- package/dist/permissions.js +1 -0
- package/dist/pikku-state.d.ts +9 -8
- package/dist/pikku-state.js +34 -17
- package/dist/schema.d.ts +4 -4
- package/dist/schema.js +9 -5
- package/dist/services/ai-agent-runner-service.d.ts +22 -3
- package/dist/services/ai-run-state-service.d.ts +1 -1
- package/dist/services/ai-storage-service.d.ts +1 -1
- package/dist/services/content-service.d.ts +6 -0
- package/dist/services/gateway-service.d.ts +19 -0
- package/dist/services/gopass-secrets.d.ts +1 -1
- package/dist/services/gopass-secrets.js +3 -0
- package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
- package/dist/services/in-memory-ai-run-state-service.js +44 -0
- package/dist/services/in-memory-trigger-service.d.ts +0 -1
- package/dist/services/in-memory-trigger-service.js +6 -8
- package/dist/services/index.d.ts +5 -2
- package/dist/services/index.js +2 -0
- package/dist/services/local-content.d.ts +2 -1
- package/dist/services/local-content.js +6 -1
- package/dist/services/local-gateway-service.d.ts +22 -0
- package/dist/services/local-gateway-service.js +51 -0
- package/dist/services/local-secrets.d.ts +2 -2
- package/dist/services/local-variables.d.ts +1 -1
- package/dist/services/logger-console.d.ts +2 -1
- package/dist/services/scheduler-service.d.ts +0 -12
- package/dist/services/scheduler-service.js +0 -6
- package/dist/services/scoped-secret-service.d.ts +1 -1
- package/dist/services/trigger-service.d.ts +0 -7
- package/dist/services/user-session-service.d.ts +3 -3
- package/dist/services/workflow-service.d.ts +2 -3
- package/dist/types/core.types.d.ts +27 -19
- package/dist/types/state.types.d.ts +22 -15
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +12 -9
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +168 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +13 -2
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
- package/dist/wirings/ai-agent/ai-agent-prepare.js +80 -31
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +263 -89
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +96 -4
- package/dist/wirings/ai-agent/index.d.ts +3 -1
- package/dist/wirings/ai-agent/index.js +2 -0
- package/dist/wirings/channel/channel-common.d.ts +2 -2
- package/dist/wirings/channel/channel-handler.d.ts +7 -4
- package/dist/wirings/channel/channel-handler.js +15 -5
- package/dist/wirings/channel/channel-middleware-runner.js +1 -0
- package/dist/wirings/channel/channel-runner.d.ts +5 -5
- package/dist/wirings/channel/channel-runner.js +3 -2
- package/dist/wirings/channel/channel-store.d.ts +1 -1
- package/dist/wirings/channel/channel.types.d.ts +10 -6
- package/dist/wirings/channel/index.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-handler.d.ts +7 -0
- package/dist/wirings/channel/local/local-channel-handler.js +17 -0
- package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
- package/dist/wirings/channel/local/local-channel-runner.js +18 -4
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
- package/dist/wirings/channel/log-channels.d.ts +1 -1
- 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.d.ts +4 -4
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +26 -20
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +2 -2
- package/dist/wirings/cli/cli-runner.js +3 -0
- package/dist/wirings/cli/cli.types.d.ts +3 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -1
- 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/index.d.ts +2 -0
- package/dist/wirings/gateway/index.js +1 -0
- package/dist/wirings/http/http-runner.d.ts +9 -9
- package/dist/wirings/http/http-runner.js +36 -14
- package/dist/wirings/http/http.types.d.ts +2 -6
- package/dist/wirings/http/log-http-routes.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
- package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
- package/dist/wirings/http/routers/http-router.d.ts +1 -1
- package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
- package/dist/wirings/mcp/mcp-runner.js +4 -2
- package/dist/wirings/mcp/mcp.types.d.ts +2 -2
- package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
- package/dist/wirings/queue/index.d.ts +1 -1
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +1 -12
- package/dist/wirings/queue/queue-runner.js +4 -12
- package/dist/wirings/queue/queue.types.d.ts +3 -9
- package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
- package/dist/wirings/queue/register-queue-helper.js +1 -1
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +2 -0
- package/dist/wirings/rpc/index.js +1 -0
- package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
- package/dist/wirings/rpc/rpc-runner.js +56 -28
- package/dist/wirings/rpc/rpc-types.d.ts +14 -2
- package/dist/wirings/rpc/wire-addon.d.ts +10 -0
- package/dist/wirings/rpc/wire-addon.js +9 -0
- package/dist/wirings/scheduler/index.d.ts +1 -1
- package/dist/wirings/scheduler/index.js +1 -1
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
- package/dist/wirings/scheduler/scheduler-runner.js +4 -25
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
- package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
- package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
- package/dist/wirings/trigger/trigger-runner.js +4 -3
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
- package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
- package/dist/wirings/workflow/workflow.types.d.ts +2 -2
- package/package.json +4 -2
- package/src/crypto-utils.test.ts +116 -0
- package/src/errors/error.test.ts +143 -2
- package/src/errors/errors.ts +10 -0
- package/src/errors/index.ts +1 -0
- package/src/function/function-runner.test.ts +2 -2
- package/src/function/function-runner.ts +72 -49
- package/src/function/functions.types.ts +1 -0
- package/src/handle-error.test.ts +361 -0
- package/src/handle-error.ts +4 -4
- package/src/index.ts +3 -10
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +1 -1
- package/src/middleware/auth-bearer.test.ts +1 -1
- package/src/middleware/auth-bearer.ts +2 -5
- package/src/middleware/auth-cookie.test.ts +1 -1
- package/src/middleware/auth-cookie.ts +3 -5
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +14 -6
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware-runner.test.ts +1 -1
- package/src/middleware-runner.ts +2 -1
- package/src/permissions.test.ts +2 -2
- package/src/permissions.ts +3 -2
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +45 -28
- package/src/schema.test.ts +198 -6
- package/src/schema.ts +11 -7
- package/src/services/ai-agent-runner-service.ts +15 -3
- package/src/services/ai-run-state-service.ts +1 -1
- package/src/services/ai-storage-service.ts +1 -1
- package/src/services/content-service.ts +7 -0
- package/src/services/gateway-service.ts +20 -0
- package/src/services/gopass-secrets.ts +4 -1
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +6 -10
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/index.ts +4 -1
- package/src/services/local-content.ts +9 -3
- package/src/services/local-gateway-service.ts +62 -0
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +2 -2
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +1 -1
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +2 -1
- package/src/services/scheduler-service.ts +0 -18
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +1 -1
- package/src/services/trigger-service.ts +0 -21
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +3 -3
- package/src/services/workflow-service.ts +2 -12
- package/src/time-utils.test.ts +1 -1
- package/src/types/core.types.ts +28 -19
- package/src/types/state.types.ts +32 -15
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +14 -13
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +238 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +10 -1
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +98 -46
- package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
- package/src/wirings/ai-agent/ai-agent-stream.ts +390 -104
- package/src/wirings/ai-agent/ai-agent.types.ts +91 -4
- package/src/wirings/ai-agent/index.ts +13 -0
- package/src/wirings/channel/channel-common.ts +2 -2
- package/src/wirings/channel/channel-handler.ts +43 -11
- package/src/wirings/channel/channel-middleware-runner.ts +1 -0
- package/src/wirings/channel/channel-runner.ts +6 -6
- package/src/wirings/channel/channel-store.ts +1 -1
- package/src/wirings/channel/channel.types.ts +15 -8
- package/src/wirings/channel/index.ts +1 -0
- package/src/wirings/channel/local/local-channel-handler.ts +26 -0
- package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
- package/src/wirings/channel/local/local-channel-runner.ts +33 -14
- package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
- package/src/wirings/channel/log-channels.ts +1 -1
- 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 +38 -33
- package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +1 -1
- package/src/wirings/cli/cli-runner.ts +14 -4
- package/src/wirings/cli/cli.types.ts +3 -3
- package/src/wirings/cli/command-parser.test.ts +1 -1
- package/src/wirings/cli/command-parser.ts +1 -1
- 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.test.ts +1 -1
- package/src/wirings/http/http-runner.test.ts +9 -17
- package/src/wirings/http/http-runner.ts +46 -27
- package/src/wirings/http/http.types.ts +1 -14
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
- package/src/wirings/http/routers/http-router.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.ts +4 -3
- package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +2 -2
- package/src/wirings/oauth2/oauth2-client.ts +3 -3
- package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
- package/src/wirings/queue/index.ts +0 -1
- package/src/wirings/queue/queue-runner.test.ts +52 -25
- package/src/wirings/queue/queue-runner.ts +8 -30
- package/src/wirings/queue/queue.types.ts +3 -13
- package/src/wirings/queue/register-queue-helper.ts +3 -5
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +4 -1
- package/src/wirings/rpc/index.ts +2 -0
- package/src/wirings/rpc/rpc-runner.ts +92 -49
- package/src/wirings/rpc/rpc-types.ts +17 -2
- package/src/wirings/rpc/wire-addon.ts +20 -0
- package/src/wirings/scheduler/index.ts +0 -1
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
- package/src/wirings/scheduler/scheduler-runner.ts +9 -56
- package/src/wirings/scheduler/scheduler.types.ts +2 -2
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +8 -11
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
- package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow.types.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/src/wirings/workflow/workflow-utils.ts +0 -0
- /package/dist/{wirings/workflow/workflow-utils.d.ts → services/gateway-service.js} +0 -0
- /package/dist/wirings/{workflow/workflow-utils.js → gateway/gateway.types.js} +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import {
|
|
4
|
+
agent,
|
|
5
|
+
agentStream,
|
|
6
|
+
agentResume,
|
|
7
|
+
agentApprove,
|
|
8
|
+
} from './ai-agent-helpers.js'
|
|
9
|
+
|
|
10
|
+
describe('agent helpers', () => {
|
|
11
|
+
describe('agent', () => {
|
|
12
|
+
test('should return an object with func', () => {
|
|
13
|
+
const a = agent('myAgent')
|
|
14
|
+
assert.strictEqual(typeof a.func, 'function')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('func should call rpc.agent.run', async () => {
|
|
18
|
+
const a = agent('myAgent')
|
|
19
|
+
let calledWith: any
|
|
20
|
+
const rpc = {
|
|
21
|
+
agent: {
|
|
22
|
+
run: async (...args: any[]) => {
|
|
23
|
+
calledWith = args
|
|
24
|
+
return {
|
|
25
|
+
runId: 'run-1',
|
|
26
|
+
result: 'done',
|
|
27
|
+
usage: { inputTokens: 10, outputTokens: 20 },
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
const input = { message: 'hello', threadId: 't1', resourceId: 'r1' }
|
|
33
|
+
const result = await a.func({}, input, { rpc })
|
|
34
|
+
assert.strictEqual(calledWith[0], 'myAgent')
|
|
35
|
+
assert.deepStrictEqual(calledWith[1], input)
|
|
36
|
+
assert.strictEqual(result.runId, 'run-1')
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('agentStream', () => {
|
|
41
|
+
test('should return an object with func', () => {
|
|
42
|
+
const a = agentStream('myAgent')
|
|
43
|
+
assert.strictEqual(typeof a.func, 'function')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('func should call rpc.agent.stream with bound name', async () => {
|
|
47
|
+
const a = agentStream('myAgent')
|
|
48
|
+
let calledWith: any
|
|
49
|
+
const rpc = {
|
|
50
|
+
agent: {
|
|
51
|
+
stream: async (...args: any[]) => {
|
|
52
|
+
calledWith = args
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
const input = { message: 'hello', threadId: 't1', resourceId: 'r1' }
|
|
57
|
+
await a.func({}, input, { rpc })
|
|
58
|
+
assert.strictEqual(calledWith[0], 'myAgent')
|
|
59
|
+
assert.deepStrictEqual(calledWith[1], input)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('func should extract agentName from data when no name bound', async () => {
|
|
63
|
+
const a = agentStream()
|
|
64
|
+
let calledWith: any
|
|
65
|
+
const rpc = {
|
|
66
|
+
agent: {
|
|
67
|
+
stream: async (...args: any[]) => {
|
|
68
|
+
calledWith = args
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
const input = {
|
|
73
|
+
agentName: 'dynamicAgent',
|
|
74
|
+
message: 'hello',
|
|
75
|
+
threadId: 't1',
|
|
76
|
+
resourceId: 'r1',
|
|
77
|
+
}
|
|
78
|
+
await a.func({}, input, { rpc })
|
|
79
|
+
assert.strictEqual(calledWith[0], 'dynamicAgent')
|
|
80
|
+
assert.deepStrictEqual(calledWith[1], {
|
|
81
|
+
message: 'hello',
|
|
82
|
+
threadId: 't1',
|
|
83
|
+
resourceId: 'r1',
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('func should throw when no name bound and no agentName in data', async () => {
|
|
88
|
+
const a = agentStream()
|
|
89
|
+
const rpc = { agent: { stream: async () => {} } }
|
|
90
|
+
await assert.rejects(() => a.func({}, { message: 'hello' }, { rpc }), {
|
|
91
|
+
message:
|
|
92
|
+
'agentStream requires an agentName either as a parameter or in the input data',
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('agentResume', () => {
|
|
98
|
+
test('should return an object with func', () => {
|
|
99
|
+
const a = agentResume()
|
|
100
|
+
assert.strictEqual(typeof a.func, 'function')
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
test('func should call rpc.agent.resume', async () => {
|
|
104
|
+
const a = agentResume()
|
|
105
|
+
let calledWith: any
|
|
106
|
+
const rpc = {
|
|
107
|
+
agent: {
|
|
108
|
+
resume: async (...args: any[]) => {
|
|
109
|
+
calledWith = args
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
const data = { runId: 'run-1', toolCallId: 'tc1', approved: true }
|
|
114
|
+
await a.func({}, data, { rpc })
|
|
115
|
+
assert.strictEqual(calledWith[0], 'run-1')
|
|
116
|
+
assert.deepStrictEqual(calledWith[1], {
|
|
117
|
+
toolCallId: 'tc1',
|
|
118
|
+
approved: true,
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
describe('agentApprove', () => {
|
|
124
|
+
test('should return an object with func', () => {
|
|
125
|
+
const a = agentApprove('myAgent')
|
|
126
|
+
assert.strictEqual(typeof a.func, 'function')
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
test('func should call rpc.agent.approve', async () => {
|
|
130
|
+
const a = agentApprove('myAgent')
|
|
131
|
+
let calledWith: any
|
|
132
|
+
const rpc = {
|
|
133
|
+
agent: {
|
|
134
|
+
approve: async (...args: any[]) => {
|
|
135
|
+
calledWith = args
|
|
136
|
+
return { approved: true }
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
const data = {
|
|
141
|
+
runId: 'run-1',
|
|
142
|
+
approvals: [{ toolCallId: 'tc1', approved: true }],
|
|
143
|
+
}
|
|
144
|
+
const result = await a.func({}, data, { rpc })
|
|
145
|
+
assert.strictEqual(calledWith[0], 'run-1')
|
|
146
|
+
assert.deepStrictEqual(calledWith[1], [
|
|
147
|
+
{ toolCallId: 'tc1', approved: true },
|
|
148
|
+
])
|
|
149
|
+
assert.deepStrictEqual(result, { approved: true })
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function agent<TAgentMap extends Record<string, { output: any }>>(
|
|
2
|
+
agentName: string & keyof TAgentMap
|
|
3
|
+
): { func: (services: any, data: any, wire: any) => Promise<any> } {
|
|
4
|
+
return {
|
|
5
|
+
func: async (_services: any, data: any, { rpc }: any) => {
|
|
6
|
+
return rpc.agent.run(agentName, data)
|
|
7
|
+
},
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function agentStream<TAgentMap extends Record<string, { output: any }>>(
|
|
12
|
+
agentName?: string & keyof TAgentMap
|
|
13
|
+
): { func: (services: any, data: any, wire: any) => Promise<void> } {
|
|
14
|
+
return {
|
|
15
|
+
func: async (_services: any, data: any, { rpc }: any) => {
|
|
16
|
+
if (agentName) {
|
|
17
|
+
await rpc.agent.stream(agentName, data)
|
|
18
|
+
} else {
|
|
19
|
+
const { agentName: name, ...rest } = data
|
|
20
|
+
if (!name) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
'agentStream requires an agentName either as a parameter or in the input data'
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
await rpc.agent.stream(name, rest)
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function agentResume(): {
|
|
32
|
+
func: (
|
|
33
|
+
services: any,
|
|
34
|
+
data: { runId: string; toolCallId: string; approved: boolean },
|
|
35
|
+
wire: any
|
|
36
|
+
) => Promise<void>
|
|
37
|
+
} {
|
|
38
|
+
return {
|
|
39
|
+
func: async (
|
|
40
|
+
_services: any,
|
|
41
|
+
data: { runId: string; toolCallId: string; approved: boolean },
|
|
42
|
+
{ rpc }: any
|
|
43
|
+
) => {
|
|
44
|
+
await rpc.agent.resume(data.runId, {
|
|
45
|
+
toolCallId: data.toolCallId,
|
|
46
|
+
approved: data.approved,
|
|
47
|
+
})
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function agentApprove<TAgentMap extends Record<string, { output: any }>>(
|
|
53
|
+
_agentName: string & keyof TAgentMap
|
|
54
|
+
): {
|
|
55
|
+
func: (
|
|
56
|
+
services: any,
|
|
57
|
+
data: {
|
|
58
|
+
runId: string
|
|
59
|
+
approvals: { toolCallId: string; approved: boolean }[]
|
|
60
|
+
},
|
|
61
|
+
wire: any
|
|
62
|
+
) => Promise<any>
|
|
63
|
+
} {
|
|
64
|
+
return {
|
|
65
|
+
func: async (
|
|
66
|
+
_services: any,
|
|
67
|
+
data: {
|
|
68
|
+
runId: string
|
|
69
|
+
approvals: { toolCallId: string; approved: boolean }[]
|
|
70
|
+
},
|
|
71
|
+
{ rpc }: any
|
|
72
|
+
) => {
|
|
73
|
+
return rpc.agent.approve(data.runId, data.approvals)
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -277,7 +277,16 @@ function sanitizeToolMessages(messages: AIMessage[]): AIMessage[] {
|
|
|
277
277
|
|
|
278
278
|
function estimateTokens(msg: AIMessage): number {
|
|
279
279
|
let chars = 0
|
|
280
|
-
if (msg.content)
|
|
280
|
+
if (msg.content) {
|
|
281
|
+
if (typeof msg.content === 'string') {
|
|
282
|
+
chars += msg.content.length
|
|
283
|
+
} else {
|
|
284
|
+
for (const part of msg.content) {
|
|
285
|
+
if (part.type === 'text') chars += part.text.length
|
|
286
|
+
else chars += 1000
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
281
290
|
if (msg.toolCalls) chars += JSON.stringify(msg.toolCalls).length
|
|
282
291
|
if (msg.toolResults) chars += JSON.stringify(msg.toolResults).length
|
|
283
292
|
return Math.ceil(chars / 4)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, test, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { resolveModelConfig } from './ai-agent-model-config.js'
|
|
4
|
+
import { resetPikkuState, pikkuState } from '../../pikku-state.js'
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
resetPikkuState()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
describe('resolveModelConfig', () => {
|
|
11
|
+
test('should return agent model when no config', () => {
|
|
12
|
+
const result = resolveModelConfig('testAgent', {
|
|
13
|
+
model: 'anthropic/claude-3',
|
|
14
|
+
temperature: 0.7,
|
|
15
|
+
})
|
|
16
|
+
assert.strictEqual(result.model, 'anthropic/claude-3')
|
|
17
|
+
assert.strictEqual(result.temperature, 0.7)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('should resolve model alias to string', () => {
|
|
21
|
+
pikkuState(null, 'models', 'config', {
|
|
22
|
+
models: { fast: 'anthropic/claude-haiku' },
|
|
23
|
+
} as any)
|
|
24
|
+
|
|
25
|
+
const result = resolveModelConfig('testAgent', { model: 'fast' })
|
|
26
|
+
assert.strictEqual(result.model, 'anthropic/claude-haiku')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('should resolve model alias with temperature and maxSteps', () => {
|
|
30
|
+
pikkuState(null, 'models', 'config', {
|
|
31
|
+
models: {
|
|
32
|
+
smart: {
|
|
33
|
+
model: 'anthropic/claude-opus',
|
|
34
|
+
temperature: 0.3,
|
|
35
|
+
maxSteps: 10,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
} as any)
|
|
39
|
+
|
|
40
|
+
const result = resolveModelConfig('testAgent', { model: 'smart' })
|
|
41
|
+
assert.strictEqual(result.model, 'anthropic/claude-opus')
|
|
42
|
+
assert.strictEqual(result.temperature, 0.3)
|
|
43
|
+
assert.strictEqual(result.maxSteps, 10)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('should throw for unknown model alias', () => {
|
|
47
|
+
pikkuState(null, 'models', 'config', {
|
|
48
|
+
models: {},
|
|
49
|
+
} as any)
|
|
50
|
+
|
|
51
|
+
assert.throws(() => resolveModelConfig('testAgent', { model: 'unknown' }), {
|
|
52
|
+
message: "Unknown model alias 'unknown'.",
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('should pass through model with slash (not an alias)', () => {
|
|
57
|
+
pikkuState(null, 'models', 'config', {
|
|
58
|
+
models: {},
|
|
59
|
+
} as any)
|
|
60
|
+
|
|
61
|
+
const result = resolveModelConfig('testAgent', { model: 'openai/gpt-4' })
|
|
62
|
+
assert.strictEqual(result.model, 'openai/gpt-4')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('should use agent override model', () => {
|
|
66
|
+
pikkuState(null, 'models', 'config', {
|
|
67
|
+
models: { fast: 'anthropic/haiku' },
|
|
68
|
+
agentOverrides: { testAgent: { model: 'fast' } },
|
|
69
|
+
} as any)
|
|
70
|
+
|
|
71
|
+
const result = resolveModelConfig('testAgent', {
|
|
72
|
+
model: 'anthropic/default',
|
|
73
|
+
})
|
|
74
|
+
assert.strictEqual(result.model, 'anthropic/haiku')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('should use agent override temperature over alias', () => {
|
|
78
|
+
pikkuState(null, 'models', 'config', {
|
|
79
|
+
models: { smart: { model: 'anthropic/opus', temperature: 0.5 } },
|
|
80
|
+
agentOverrides: { testAgent: { model: 'smart', temperature: 0.1 } },
|
|
81
|
+
} as any)
|
|
82
|
+
|
|
83
|
+
const result = resolveModelConfig('testAgent', {
|
|
84
|
+
model: 'anthropic/default',
|
|
85
|
+
})
|
|
86
|
+
assert.strictEqual(result.temperature, 0.1)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('should use agentDefaults as fallback', () => {
|
|
90
|
+
pikkuState(null, 'models', 'config', {
|
|
91
|
+
models: {},
|
|
92
|
+
agentDefaults: { temperature: 0.5, maxSteps: 20 },
|
|
93
|
+
} as any)
|
|
94
|
+
|
|
95
|
+
const result = resolveModelConfig('testAgent', {
|
|
96
|
+
model: 'anthropic/claude-3',
|
|
97
|
+
})
|
|
98
|
+
assert.strictEqual(result.temperature, 0.5)
|
|
99
|
+
assert.strictEqual(result.maxSteps, 20)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('should prioritize: override > alias > defaults > agent', () => {
|
|
103
|
+
pikkuState(null, 'models', 'config', {
|
|
104
|
+
models: { fast: { model: 'anthropic/haiku', temperature: 0.3 } },
|
|
105
|
+
agentDefaults: { temperature: 0.5 },
|
|
106
|
+
agentOverrides: { testAgent: { temperature: 0.1 } },
|
|
107
|
+
} as any)
|
|
108
|
+
|
|
109
|
+
const result = resolveModelConfig('testAgent', {
|
|
110
|
+
model: 'fast',
|
|
111
|
+
temperature: 0.9,
|
|
112
|
+
})
|
|
113
|
+
assert.strictEqual(result.temperature, 0.1)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type CoreSingletonServices,
|
|
3
|
-
type CoreServices,
|
|
4
|
-
type CoreUserSession,
|
|
5
|
-
type CreateWireServices,
|
|
6
|
-
PikkuWire,
|
|
7
|
-
} from '../../types/core.types.js'
|
|
1
|
+
import type { PikkuWire, CoreUserSession } from '../../types/core.types.js'
|
|
8
2
|
import type {
|
|
9
3
|
CoreAIAgent,
|
|
10
4
|
AIAgentInput,
|
|
11
5
|
AIAgentToolDef,
|
|
6
|
+
AIContentPart,
|
|
12
7
|
AIMessage,
|
|
13
8
|
AIStreamChannel,
|
|
14
9
|
AIStreamEvent,
|
|
10
|
+
PikkuAIMiddlewareHooks,
|
|
15
11
|
} from './ai-agent.types.js'
|
|
16
12
|
import type { AIAgentRunnerParams } from '../../services/ai-agent-runner-service.js'
|
|
17
13
|
import { PikkuError } from '../../errors/error-handler.js'
|
|
18
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
pikkuState,
|
|
16
|
+
getSingletonServices,
|
|
17
|
+
getCreateWireServices,
|
|
18
|
+
} from '../../pikku-state.js'
|
|
19
19
|
import { runPikkuFunc } from '../../function/function-runner.js'
|
|
20
20
|
import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js'
|
|
21
21
|
import type { SessionService } from '../../services/user-session-service.js'
|
|
@@ -29,13 +29,7 @@ import {
|
|
|
29
29
|
import { resolveModelConfig } from './ai-agent-model-config.js'
|
|
30
30
|
|
|
31
31
|
export type RunAIAgentParams = {
|
|
32
|
-
singletonServices: CoreSingletonServices
|
|
33
32
|
sessionService?: SessionService<CoreUserSession>
|
|
34
|
-
createWireServices?: CreateWireServices<
|
|
35
|
-
CoreSingletonServices,
|
|
36
|
-
CoreServices<CoreSingletonServices>,
|
|
37
|
-
CoreUserSession
|
|
38
|
-
>
|
|
39
33
|
}
|
|
40
34
|
|
|
41
35
|
export type StreamAIAgentOptions = {
|
|
@@ -88,8 +82,8 @@ export const resolveAgent = (
|
|
|
88
82
|
if (colonIndex !== -1) {
|
|
89
83
|
const namespace = agentName.substring(0, colonIndex)
|
|
90
84
|
const localName = agentName.substring(colonIndex + 1)
|
|
91
|
-
const
|
|
92
|
-
const pkgConfig =
|
|
85
|
+
const addons = pikkuState(null, 'rpc', 'addons')
|
|
86
|
+
const pkgConfig = addons.get(namespace)
|
|
93
87
|
if (pkgConfig) {
|
|
94
88
|
const extAgent = pikkuState(pkgConfig.package, 'agent', 'agents').get(
|
|
95
89
|
localName
|
|
@@ -151,6 +145,7 @@ export function createScopedChannel(
|
|
|
151
145
|
return capturedApproval
|
|
152
146
|
},
|
|
153
147
|
close: () => {},
|
|
148
|
+
sendBinary: (data) => parent.sendBinary(data),
|
|
154
149
|
send: (event: AIStreamEvent) => {
|
|
155
150
|
if (event.type === 'done') return
|
|
156
151
|
if (event.type === 'approval-request') {
|
|
@@ -163,6 +158,7 @@ export function createScopedChannel(
|
|
|
163
158
|
return
|
|
164
159
|
}
|
|
165
160
|
if (
|
|
161
|
+
event.type === 'step-start' ||
|
|
166
162
|
event.type === 'text-delta' ||
|
|
167
163
|
event.type === 'reasoning-delta' ||
|
|
168
164
|
event.type === 'tool-call' ||
|
|
@@ -179,14 +175,15 @@ export function createScopedChannel(
|
|
|
179
175
|
}
|
|
180
176
|
|
|
181
177
|
export function buildToolDefs(
|
|
182
|
-
singletonServices: CoreSingletonServices,
|
|
183
178
|
params: RunAIAgentParams,
|
|
184
179
|
agentSessionMap: Map<string, string>,
|
|
185
180
|
resourceId: string,
|
|
186
181
|
agentName: string,
|
|
187
182
|
packageName: string | null,
|
|
188
|
-
streamContext?: StreamContext
|
|
183
|
+
streamContext?: StreamContext,
|
|
184
|
+
aiMiddlewares?: PikkuAIMiddlewareHooks[]
|
|
189
185
|
): { tools: AIAgentToolDef[]; missingRpcs: string[] } {
|
|
186
|
+
const singletonServices = getSingletonServices()
|
|
190
187
|
const tools: AIAgentToolDef[] = []
|
|
191
188
|
const missingRpcs: string[] = []
|
|
192
189
|
const approvalPolicy =
|
|
@@ -228,39 +225,18 @@ export function buildToolDefs(
|
|
|
228
225
|
approvalPolicy === 'all' ||
|
|
229
226
|
(approvalPolicy === 'explicit' && fnMeta?.requiresApproval)
|
|
230
227
|
|
|
231
|
-
if (needsApproval) {
|
|
232
|
-
inputSchema = {
|
|
233
|
-
...inputSchema,
|
|
234
|
-
properties: {
|
|
235
|
-
...((inputSchema.properties as Record<string, unknown>) || {}),
|
|
236
|
-
toolApprovalReason: {
|
|
237
|
-
type: 'string',
|
|
238
|
-
description: 'Brief explanation of why this action is needed',
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
228
|
tools.push({
|
|
245
229
|
name: pikkuFuncId,
|
|
246
230
|
description: fnMeta?.description || fnMeta?.title || toolName,
|
|
247
231
|
inputSchema,
|
|
232
|
+
needsApproval: needsApproval || undefined,
|
|
248
233
|
execute: async (toolInput: unknown) => {
|
|
249
|
-
if (needsApproval) {
|
|
250
|
-
const { toolApprovalReason, ...cleanArgs } = toolInput as any
|
|
251
|
-
return {
|
|
252
|
-
__approvalRequired: true,
|
|
253
|
-
toolName: pikkuFuncId,
|
|
254
|
-
args: cleanArgs,
|
|
255
|
-
reason: toolApprovalReason,
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
234
|
const wire: PikkuWire = params.sessionService
|
|
259
235
|
? { ...createMiddlewareSessionWireProps(params.sessionService) }
|
|
260
236
|
: {}
|
|
261
237
|
return runPikkuFunc('agent', `tool:${pikkuFuncId}`, pikkuFuncId, {
|
|
262
238
|
singletonServices,
|
|
263
|
-
createWireServices:
|
|
239
|
+
createWireServices: getCreateWireServices(),
|
|
264
240
|
data: () => toolInput,
|
|
265
241
|
wire,
|
|
266
242
|
sessionService: params.sessionService,
|
|
@@ -362,6 +338,62 @@ export function buildToolDefs(
|
|
|
362
338
|
}
|
|
363
339
|
}
|
|
364
340
|
|
|
341
|
+
const hasToolHooks = aiMiddlewares?.some(
|
|
342
|
+
(mw) => mw.beforeToolCall || mw.afterToolCall
|
|
343
|
+
)
|
|
344
|
+
if (hasToolHooks) {
|
|
345
|
+
for (const tool of tools) {
|
|
346
|
+
const originalExecute = tool.execute
|
|
347
|
+
tool.execute = async (toolInput: unknown) => {
|
|
348
|
+
const toolCallId = randomUUID()
|
|
349
|
+
let args = (toolInput ?? {}) as Record<string, unknown>
|
|
350
|
+
|
|
351
|
+
for (const mw of aiMiddlewares!) {
|
|
352
|
+
if (mw.beforeToolCall) {
|
|
353
|
+
const beforeResult = await mw.beforeToolCall(singletonServices, {
|
|
354
|
+
toolName: tool.name,
|
|
355
|
+
toolCallId,
|
|
356
|
+
args,
|
|
357
|
+
})
|
|
358
|
+
if (beforeResult && 'args' in beforeResult) {
|
|
359
|
+
args = beforeResult.args
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const startTime = Date.now()
|
|
365
|
+
let result: unknown
|
|
366
|
+
let execError: unknown
|
|
367
|
+
try {
|
|
368
|
+
result = await originalExecute(args)
|
|
369
|
+
} catch (err) {
|
|
370
|
+
execError = err
|
|
371
|
+
result = err instanceof Error ? err.message : String(err)
|
|
372
|
+
}
|
|
373
|
+
const durationMs = Date.now() - startTime
|
|
374
|
+
|
|
375
|
+
for (let i = aiMiddlewares!.length - 1; i >= 0; i--) {
|
|
376
|
+
const mw = aiMiddlewares![i]
|
|
377
|
+
if (mw.afterToolCall) {
|
|
378
|
+
const afterResult = await mw.afterToolCall(singletonServices, {
|
|
379
|
+
toolName: tool.name,
|
|
380
|
+
toolCallId,
|
|
381
|
+
args,
|
|
382
|
+
result,
|
|
383
|
+
durationMs,
|
|
384
|
+
})
|
|
385
|
+
if (afterResult && 'result' in afterResult) {
|
|
386
|
+
result = afterResult.result
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (execError) throw execError
|
|
392
|
+
return result
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
365
397
|
return { tools, missingRpcs }
|
|
366
398
|
}
|
|
367
399
|
|
|
@@ -372,7 +404,7 @@ export async function prepareAgentRun(
|
|
|
372
404
|
agentSessionMap: Map<string, string>,
|
|
373
405
|
streamContext?: StreamContext
|
|
374
406
|
) {
|
|
375
|
-
const
|
|
407
|
+
const singletonServices = getSingletonServices()
|
|
376
408
|
const { agent, packageName, resolvedName } = resolveAgent(agentName)
|
|
377
409
|
|
|
378
410
|
const agentRunner = singletonServices.aiAgentRunner
|
|
@@ -418,29 +450,48 @@ export async function prepareAgentRun(
|
|
|
418
450
|
workingMemoryJsonSchema
|
|
419
451
|
)
|
|
420
452
|
|
|
453
|
+
const userContent: AIMessage['content'] = input.attachments?.length
|
|
454
|
+
? [
|
|
455
|
+
{ type: 'text' as const, text: input.message },
|
|
456
|
+
...input.attachments.map(
|
|
457
|
+
(a) =>
|
|
458
|
+
({
|
|
459
|
+
type: a.type,
|
|
460
|
+
data: a.data,
|
|
461
|
+
url: a.url,
|
|
462
|
+
mediaType: a.mediaType,
|
|
463
|
+
...(a.filename ? { filename: a.filename } : {}),
|
|
464
|
+
}) as AIContentPart
|
|
465
|
+
),
|
|
466
|
+
]
|
|
467
|
+
: input.message
|
|
468
|
+
|
|
421
469
|
const userMessage: AIMessage = {
|
|
422
470
|
id: randomUUID(),
|
|
423
471
|
role: 'user',
|
|
424
|
-
content:
|
|
472
|
+
content: userContent,
|
|
425
473
|
createdAt: new Date(),
|
|
426
474
|
}
|
|
427
475
|
|
|
428
476
|
const allMessages = [...contextMessages, ...messages, userMessage]
|
|
429
477
|
const trimmedMessages = trimMessages(allMessages)
|
|
430
478
|
|
|
479
|
+
const aiMiddlewares: PikkuAIMiddlewareHooks[] = agent.aiMiddleware ?? []
|
|
480
|
+
|
|
431
481
|
const { tools, missingRpcs } = buildToolDefs(
|
|
432
|
-
singletonServices,
|
|
433
482
|
params,
|
|
434
483
|
agentSessionMap,
|
|
435
484
|
input.resourceId,
|
|
436
485
|
resolvedName,
|
|
437
486
|
packageName,
|
|
438
|
-
streamContext
|
|
487
|
+
streamContext,
|
|
488
|
+
aiMiddlewares
|
|
439
489
|
)
|
|
440
490
|
|
|
441
491
|
const instructions = buildInstructions(resolvedName, packageName)
|
|
442
492
|
|
|
443
493
|
const resolved = resolveModelConfig(resolvedName, agent)
|
|
494
|
+
const maxSteps = resolved.maxSteps ?? 10
|
|
444
495
|
|
|
445
496
|
const runnerParams: AIAgentRunnerParams = {
|
|
446
497
|
model: resolved.model,
|
|
@@ -448,7 +499,7 @@ export async function prepareAgentRun(
|
|
|
448
499
|
instructions,
|
|
449
500
|
messages: trimmedMessages,
|
|
450
501
|
tools,
|
|
451
|
-
maxSteps:
|
|
502
|
+
maxSteps: 1,
|
|
452
503
|
toolChoice: agent.toolChoice ?? 'auto',
|
|
453
504
|
outputSchema,
|
|
454
505
|
}
|
|
@@ -463,6 +514,7 @@ export async function prepareAgentRun(
|
|
|
463
514
|
threadId,
|
|
464
515
|
userMessage,
|
|
465
516
|
runnerParams,
|
|
517
|
+
maxSteps,
|
|
466
518
|
missingRpcs,
|
|
467
519
|
workingMemoryJsonSchema,
|
|
468
520
|
workingMemorySchemaName,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CoreAIAgent, AgentRunState } from './ai-agent.types.js'
|
|
2
2
|
import { pikkuState } from '../../pikku-state.js'
|
|
3
|
-
import { AIRunStateService } from '../../services/ai-run-state-service.js'
|
|
3
|
+
import type { AIRunStateService } from '../../services/ai-run-state-service.js'
|
|
4
4
|
import { PikkuMissingMetaError } from '../../errors/errors.js'
|
|
5
5
|
|
|
6
6
|
export const addAIAgent = (
|