@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
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { pikkuState } from '../../pikku-state.js';
|
|
1
|
+
import { pikkuState, getSingletonServices } from '../../pikku-state.js';
|
|
2
2
|
import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../channel/channel-middleware-runner.js';
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
4
|
import { parseWorkingMemory, deepMergeWorkingMemory, resolveMemoryServices, loadContextMessages, trimMessages, } from './ai-agent-memory.js';
|
|
5
5
|
import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, createScopedChannel, ToolApprovalRequired, } from './ai-agent-prepare.js';
|
|
6
|
+
import { createAssistantUIChannel, parseAssistantUIInput, } from './ai-agent-assistant-ui.js';
|
|
6
7
|
import { resolveModelConfig } from './ai-agent-model-config.js';
|
|
7
8
|
function createPersistingChannel(parent, storage, threadId) {
|
|
8
9
|
let fullText = '';
|
|
9
10
|
let stepText = '';
|
|
10
11
|
let stepToolCalls = [];
|
|
11
12
|
let stepToolResults = [];
|
|
13
|
+
const totalUsage = {
|
|
14
|
+
inputTokens: 0,
|
|
15
|
+
outputTokens: 0,
|
|
16
|
+
};
|
|
12
17
|
const flushStep = async () => {
|
|
13
18
|
if (!storage)
|
|
14
19
|
return;
|
|
@@ -47,8 +52,12 @@ function createPersistingChannel(parent, storage, threadId) {
|
|
|
47
52
|
get fullText() {
|
|
48
53
|
return fullText;
|
|
49
54
|
},
|
|
55
|
+
get totalUsage() {
|
|
56
|
+
return totalUsage;
|
|
57
|
+
},
|
|
50
58
|
flush: flushStep,
|
|
51
59
|
close: () => parent.close(),
|
|
60
|
+
sendBinary: (data) => parent.sendBinary(data),
|
|
52
61
|
send: (event) => {
|
|
53
62
|
if (storage) {
|
|
54
63
|
switch (event.type) {
|
|
@@ -73,6 +82,10 @@ function createPersistingChannel(parent, storage, threadId) {
|
|
|
73
82
|
});
|
|
74
83
|
break;
|
|
75
84
|
case 'usage':
|
|
85
|
+
totalUsage.inputTokens += event.tokens.input;
|
|
86
|
+
totalUsage.outputTokens += event.tokens.output;
|
|
87
|
+
if (event.model)
|
|
88
|
+
totalUsage.model = event.model;
|
|
76
89
|
flushStep();
|
|
77
90
|
break;
|
|
78
91
|
case 'done':
|
|
@@ -86,6 +99,7 @@ function createPersistingChannel(parent, storage, threadId) {
|
|
|
86
99
|
return channel;
|
|
87
100
|
}
|
|
88
101
|
async function postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, storage, memoryConfig, threadId, workingMemorySchemaName, messages, aiRunState, runId) {
|
|
102
|
+
const usage = persistingChannel.totalUsage;
|
|
89
103
|
let outputText = persistingChannel.fullText;
|
|
90
104
|
let outputMessages = messages;
|
|
91
105
|
for (let i = aiMiddlewares.length - 1; i >= 0; i--) {
|
|
@@ -94,7 +108,10 @@ async function postStreamCleanup(persistingChannel, aiMiddlewares, singletonServ
|
|
|
94
108
|
const result = await mw.modifyOutput(singletonServices, {
|
|
95
109
|
text: outputText,
|
|
96
110
|
messages: outputMessages,
|
|
97
|
-
usage: {
|
|
111
|
+
usage: {
|
|
112
|
+
inputTokens: usage.inputTokens,
|
|
113
|
+
outputTokens: usage.outputTokens,
|
|
114
|
+
},
|
|
98
115
|
});
|
|
99
116
|
outputText = result.text;
|
|
100
117
|
outputMessages = result.messages;
|
|
@@ -116,13 +133,160 @@ async function postStreamCleanup(persistingChannel, aiMiddlewares, singletonServ
|
|
|
116
133
|
await storage.saveWorkingMemory(threadId, 'thread', merged);
|
|
117
134
|
}
|
|
118
135
|
}
|
|
119
|
-
await aiRunState.updateRun(runId, {
|
|
136
|
+
await aiRunState.updateRun(runId, {
|
|
137
|
+
status: 'completed',
|
|
138
|
+
...(usage.model
|
|
139
|
+
? {
|
|
140
|
+
usage: {
|
|
141
|
+
inputTokens: usage.inputTokens,
|
|
142
|
+
outputTokens: usage.outputTokens,
|
|
143
|
+
model: usage.model,
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
: {}),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
async function runStreamStepLoop(params) {
|
|
150
|
+
const { agent, runnerParams, maxSteps, agentRunner, persistingChannel, channel, runId, aiMiddlewares, } = params;
|
|
151
|
+
const singletonServices = getSingletonServices();
|
|
152
|
+
for (let step = 0; step < maxSteps; step++) {
|
|
153
|
+
if (agent.prepareStep) {
|
|
154
|
+
let stopped = false;
|
|
155
|
+
await agent.prepareStep({
|
|
156
|
+
stepNumber: step,
|
|
157
|
+
messages: runnerParams.messages,
|
|
158
|
+
tools: runnerParams.tools,
|
|
159
|
+
toolChoice: runnerParams.toolChoice,
|
|
160
|
+
model: runnerParams.model,
|
|
161
|
+
stop: () => {
|
|
162
|
+
stopped = true;
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
if (stopped)
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
channel.send({ type: 'step-start', stepNumber: step });
|
|
169
|
+
const stepResult = await agentRunner.stream(runnerParams, persistingChannel);
|
|
170
|
+
for (const mw of aiMiddlewares) {
|
|
171
|
+
if (mw.afterStep) {
|
|
172
|
+
await mw.afterStep(singletonServices, {
|
|
173
|
+
stepNumber: step,
|
|
174
|
+
text: stepResult.text,
|
|
175
|
+
toolCalls: stepResult.toolCalls,
|
|
176
|
+
toolResults: stepResult.toolResults,
|
|
177
|
+
usage: stepResult.usage,
|
|
178
|
+
finishReason: stepResult.finishReason,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (stepResult.toolCalls.length === 0)
|
|
183
|
+
break;
|
|
184
|
+
const approvalNeeded = checkForApproval(stepResult, runnerParams.tools, runId);
|
|
185
|
+
if (approvalNeeded) {
|
|
186
|
+
return { outcome: 'approval', approval: approvalNeeded };
|
|
187
|
+
}
|
|
188
|
+
appendStepMessages(runnerParams, stepResult);
|
|
189
|
+
}
|
|
190
|
+
return { outcome: 'done' };
|
|
191
|
+
}
|
|
192
|
+
function checkForApproval(stepResult, tools, runId) {
|
|
193
|
+
for (const tc of stepResult.toolCalls) {
|
|
194
|
+
const toolDef = tools.find((t) => t.name === tc.toolName);
|
|
195
|
+
if (toolDef?.needsApproval) {
|
|
196
|
+
return new ToolApprovalRequired(tc.toolCallId, tc.toolName, tc.args);
|
|
197
|
+
}
|
|
198
|
+
const tr = stepResult.toolResults.find((r) => r.toolCallId === tc.toolCallId);
|
|
199
|
+
if (tr?.result &&
|
|
200
|
+
typeof tr.result === 'object' &&
|
|
201
|
+
'__approvalRequired' in tr.result) {
|
|
202
|
+
const r = tr.result;
|
|
203
|
+
return new ToolApprovalRequired(tc.toolCallId, r.toolName, r.args, r.reason, r.displayToolName, r.displayArgs, r.agentRunId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function appendStepMessages(runnerParams, stepResult) {
|
|
209
|
+
const assistantMsg = {
|
|
210
|
+
id: randomUUID(),
|
|
211
|
+
role: 'assistant',
|
|
212
|
+
content: stepResult.text || undefined,
|
|
213
|
+
toolCalls: stepResult.toolCalls.length > 0
|
|
214
|
+
? stepResult.toolCalls.map((tc) => ({
|
|
215
|
+
id: tc.toolCallId,
|
|
216
|
+
name: tc.toolName,
|
|
217
|
+
args: tc.args,
|
|
218
|
+
}))
|
|
219
|
+
: undefined,
|
|
220
|
+
createdAt: new Date(),
|
|
221
|
+
};
|
|
222
|
+
runnerParams.messages.push(assistantMsg);
|
|
223
|
+
if (stepResult.toolResults.length > 0) {
|
|
224
|
+
const toolMsg = {
|
|
225
|
+
id: randomUUID(),
|
|
226
|
+
role: 'tool',
|
|
227
|
+
toolResults: stepResult.toolResults.map((tr) => ({
|
|
228
|
+
id: tr.toolCallId,
|
|
229
|
+
name: tr.toolName,
|
|
230
|
+
result: typeof tr.result === 'string' ? tr.result : JSON.stringify(tr.result),
|
|
231
|
+
})),
|
|
232
|
+
createdAt: new Date(),
|
|
233
|
+
};
|
|
234
|
+
runnerParams.messages.push(toolMsg);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function handleApproval(err, runId, channel, aiRunState, persistingChannel) {
|
|
238
|
+
return (async () => {
|
|
239
|
+
await persistingChannel.flush();
|
|
240
|
+
const pendingApproval = err.agentRunId
|
|
241
|
+
? {
|
|
242
|
+
type: 'agent-call',
|
|
243
|
+
toolCallId: err.toolCallId,
|
|
244
|
+
agentName: err.toolName,
|
|
245
|
+
agentRunId: err.agentRunId,
|
|
246
|
+
displayToolName: err.displayToolName ?? err.toolName,
|
|
247
|
+
displayArgs: err.displayArgs ?? err.args,
|
|
248
|
+
}
|
|
249
|
+
: {
|
|
250
|
+
type: 'tool-call',
|
|
251
|
+
toolCallId: err.toolCallId,
|
|
252
|
+
toolName: err.toolName,
|
|
253
|
+
args: err.args,
|
|
254
|
+
};
|
|
255
|
+
await aiRunState.updateRun(runId, {
|
|
256
|
+
status: 'suspended',
|
|
257
|
+
suspendReason: 'approval',
|
|
258
|
+
pendingApprovals: [pendingApproval],
|
|
259
|
+
});
|
|
260
|
+
const approvalEvent = {
|
|
261
|
+
type: 'approval-request',
|
|
262
|
+
toolCallId: err.toolCallId,
|
|
263
|
+
toolName: err.displayToolName ?? err.toolName,
|
|
264
|
+
args: err.displayArgs ?? err.args,
|
|
265
|
+
reason: err.reason,
|
|
266
|
+
runId,
|
|
267
|
+
};
|
|
268
|
+
channel.send(approvalEvent);
|
|
269
|
+
channel.send({ type: 'done' });
|
|
270
|
+
channel.close();
|
|
271
|
+
})();
|
|
120
272
|
}
|
|
121
273
|
export async function streamAIAgent(agentName, input, channel, params, agentSessionMap, options) {
|
|
122
274
|
const sessionMap = agentSessionMap ?? new Map();
|
|
275
|
+
const { agent: resolvedAgentForProtocol } = resolveAgent(agentName);
|
|
276
|
+
const inputRecord = input;
|
|
277
|
+
const useUIMessageStream = resolvedAgentForProtocol.protocol === 'ui-message-stream' ||
|
|
278
|
+
Array.isArray(inputRecord.messages);
|
|
279
|
+
let normalizedInput;
|
|
280
|
+
if (useUIMessageStream) {
|
|
281
|
+
normalizedInput = parseAssistantUIInput(inputRecord);
|
|
282
|
+
channel = createAssistantUIChannel(channel);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
normalizedInput = input;
|
|
286
|
+
}
|
|
123
287
|
const streamContext = { channel, options };
|
|
124
|
-
const { agent, packageName, resolvedName, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName,
|
|
125
|
-
const
|
|
288
|
+
const { agent, packageName, resolvedName, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, maxSteps, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName, normalizedInput, params, sessionMap, streamContext);
|
|
289
|
+
const singletonServices = getSingletonServices();
|
|
126
290
|
const { aiRunState } = singletonServices;
|
|
127
291
|
if (!aiRunState) {
|
|
128
292
|
throw new Error('AIRunStateService not available in singletonServices');
|
|
@@ -131,7 +295,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
131
295
|
await aiRunState.createRun({
|
|
132
296
|
agentName,
|
|
133
297
|
threadId,
|
|
134
|
-
resourceId:
|
|
298
|
+
resourceId: normalizedInput.resourceId,
|
|
135
299
|
status: 'suspended',
|
|
136
300
|
suspendReason: 'rpc-missing',
|
|
137
301
|
missingRpcs,
|
|
@@ -161,7 +325,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
161
325
|
const runId = await aiRunState.createRun({
|
|
162
326
|
agentName,
|
|
163
327
|
threadId,
|
|
164
|
-
resourceId:
|
|
328
|
+
resourceId: normalizedInput.resourceId,
|
|
165
329
|
status: 'running',
|
|
166
330
|
usage: { inputTokens: 0, outputTokens: 0, model: agent.model },
|
|
167
331
|
createdAt: new Date(),
|
|
@@ -182,8 +346,15 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
182
346
|
allEvents,
|
|
183
347
|
state,
|
|
184
348
|
});
|
|
185
|
-
if (result
|
|
349
|
+
if (result == null)
|
|
350
|
+
return;
|
|
351
|
+
if (Array.isArray(result)) {
|
|
352
|
+
for (const r of result)
|
|
353
|
+
await next(r);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
186
356
|
await next(result);
|
|
357
|
+
}
|
|
187
358
|
};
|
|
188
359
|
});
|
|
189
360
|
const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta');
|
|
@@ -200,44 +371,38 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
200
371
|
: channel;
|
|
201
372
|
const persistingChannel = createPersistingChannel(wrappedChannel, storage, threadId);
|
|
202
373
|
try {
|
|
203
|
-
await
|
|
374
|
+
const loopResult = await runStreamStepLoop({
|
|
375
|
+
agent,
|
|
376
|
+
runnerParams,
|
|
377
|
+
maxSteps,
|
|
378
|
+
agentRunner,
|
|
379
|
+
persistingChannel,
|
|
380
|
+
channel,
|
|
381
|
+
runId,
|
|
382
|
+
aiMiddlewares,
|
|
383
|
+
});
|
|
384
|
+
if (loopResult.outcome === 'approval') {
|
|
385
|
+
await handleApproval(loopResult.approval, runId, channel, aiRunState, persistingChannel);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
204
388
|
await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, storage, memoryConfig, threadId, workingMemorySchemaName, runnerParams.messages, aiRunState, runId);
|
|
389
|
+
channel.send({ type: 'done' });
|
|
390
|
+
channel.close();
|
|
205
391
|
}
|
|
206
392
|
catch (err) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
displayToolName: err.displayToolName ?? err.toolName,
|
|
216
|
-
displayArgs: err.displayArgs ?? err.args,
|
|
393
|
+
for (const mw of aiMiddlewares) {
|
|
394
|
+
if (mw.onError) {
|
|
395
|
+
try {
|
|
396
|
+
await mw.onError(singletonServices, {
|
|
397
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
398
|
+
stepNumber: -1,
|
|
399
|
+
messages: runnerParams.messages,
|
|
400
|
+
});
|
|
217
401
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
args: err.args,
|
|
223
|
-
};
|
|
224
|
-
await aiRunState.updateRun(runId, {
|
|
225
|
-
status: 'suspended',
|
|
226
|
-
suspendReason: 'approval',
|
|
227
|
-
pendingApprovals: [pendingApproval],
|
|
228
|
-
});
|
|
229
|
-
const approvalEvent = {
|
|
230
|
-
type: 'approval-request',
|
|
231
|
-
toolCallId: err.toolCallId,
|
|
232
|
-
toolName: err.displayToolName ?? err.toolName,
|
|
233
|
-
args: err.displayArgs ?? err.args,
|
|
234
|
-
reason: err.reason,
|
|
235
|
-
runId,
|
|
236
|
-
};
|
|
237
|
-
channel.send(approvalEvent);
|
|
238
|
-
channel.send({ type: 'done' });
|
|
239
|
-
channel.close();
|
|
240
|
-
return;
|
|
402
|
+
catch {
|
|
403
|
+
// onError hooks must not affect error flow
|
|
404
|
+
}
|
|
405
|
+
}
|
|
241
406
|
}
|
|
242
407
|
await aiRunState.updateRun(runId, { status: 'failed' });
|
|
243
408
|
channel.send({
|
|
@@ -249,16 +414,19 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
|
|
|
249
414
|
}
|
|
250
415
|
}
|
|
251
416
|
export async function resumeAIAgent(input, channel, params, options) {
|
|
252
|
-
const
|
|
417
|
+
const singletonServices = getSingletonServices();
|
|
253
418
|
const { aiRunState } = singletonServices;
|
|
254
419
|
if (!aiRunState) {
|
|
255
420
|
throw new Error('AIRunStateService not available in singletonServices');
|
|
256
421
|
}
|
|
257
|
-
const
|
|
258
|
-
if (!
|
|
259
|
-
throw new Error(`No
|
|
422
|
+
const run = await aiRunState.getRun(input.runId);
|
|
423
|
+
if (!run) {
|
|
424
|
+
throw new Error(`No run found for runId ${input.runId}`);
|
|
425
|
+
}
|
|
426
|
+
const pending = run.pendingApprovals?.find((p) => p.toolCallId === input.toolCallId);
|
|
427
|
+
if (!pending) {
|
|
428
|
+
throw new Error(`No pending approval for toolCallId ${input.toolCallId} on run ${input.runId}`);
|
|
260
429
|
}
|
|
261
|
-
const { run, approval: pending } = found;
|
|
262
430
|
await aiRunState.resolveApproval(input.toolCallId, input.approved ? 'approved' : 'denied');
|
|
263
431
|
const { agent, packageName, resolvedName } = resolveAgent(run.agentName);
|
|
264
432
|
const { storage } = resolveMemoryServices(agent, singletonServices);
|
|
@@ -310,7 +478,11 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
310
478
|
session: 'resume',
|
|
311
479
|
input: null,
|
|
312
480
|
});
|
|
313
|
-
await resumeAIAgent({
|
|
481
|
+
await resumeAIAgent({
|
|
482
|
+
runId: pending.agentRunId,
|
|
483
|
+
toolCallId: subPending.toolCallId,
|
|
484
|
+
approved: true,
|
|
485
|
+
}, subChannel, params, options);
|
|
314
486
|
channel.send({
|
|
315
487
|
type: 'agent-result',
|
|
316
488
|
agentName: subRun.agentName,
|
|
@@ -339,16 +511,16 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
339
511
|
channel,
|
|
340
512
|
options: { ...options, requiresToolApproval: false },
|
|
341
513
|
};
|
|
342
|
-
const
|
|
514
|
+
const aiMiddlewaresForResume = agent.aiMiddleware ?? [];
|
|
515
|
+
const { tools } = buildToolDefs(params, new Map(), run.resourceId, resolvedName, packageName, streamContext, aiMiddlewaresForResume);
|
|
343
516
|
const matchingTool = tools.find((t) => t.name === pending.toolName);
|
|
344
517
|
if (!matchingTool) {
|
|
345
518
|
throw new Error(`Tool "${pending.toolName}" not found in agent definition`);
|
|
346
519
|
}
|
|
347
520
|
const toolArgs = typeof pending.args === 'string' ? JSON.parse(pending.args) : pending.args;
|
|
348
|
-
const { toolApprovalReason: _ignored, ...cleanArgs } = toolArgs;
|
|
349
521
|
let toolResult;
|
|
350
522
|
try {
|
|
351
|
-
toolResult = await matchingTool.execute(
|
|
523
|
+
toolResult = await matchingTool.execute(toolArgs);
|
|
352
524
|
}
|
|
353
525
|
catch (execErr) {
|
|
354
526
|
toolResult = `Error: ${execErr instanceof Error ? execErr.message : String(execErr)}`;
|
|
@@ -381,7 +553,7 @@ export async function resumeAIAgent(input, channel, params, options) {
|
|
|
381
553
|
await continueAfterToolResult(run, agent, packageName, resolvedName, storage, memoryConfig, agentRunner, channel, params, aiRunState, options);
|
|
382
554
|
}
|
|
383
555
|
async function continueAfterToolResult(run, agent, packageName, resolvedName, storage, memoryConfig, agentRunner, channel, params, aiRunState, options) {
|
|
384
|
-
const
|
|
556
|
+
const singletonServices = getSingletonServices();
|
|
385
557
|
const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta');
|
|
386
558
|
const meta = agentsMeta[resolvedName];
|
|
387
559
|
const workingMemorySchemaName = meta?.workingMemorySchema ?? null;
|
|
@@ -422,8 +594,15 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
422
594
|
allEvents,
|
|
423
595
|
state,
|
|
424
596
|
});
|
|
425
|
-
if (result
|
|
597
|
+
if (result == null)
|
|
598
|
+
return;
|
|
599
|
+
if (Array.isArray(result)) {
|
|
600
|
+
for (const r of result)
|
|
601
|
+
await next(r);
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
426
604
|
await next(result);
|
|
605
|
+
}
|
|
427
606
|
};
|
|
428
607
|
});
|
|
429
608
|
const allChannelMiddleware = combineChannelMiddleware('agent', `stream:${run.agentName}`, {
|
|
@@ -438,59 +617,54 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
|
|
|
438
617
|
: channel;
|
|
439
618
|
const persistingChannel = createPersistingChannel(wrappedChannel, storage, run.threadId);
|
|
440
619
|
const streamContext = { channel, options };
|
|
441
|
-
const resumeTools = buildToolDefs(
|
|
620
|
+
const resumeTools = buildToolDefs(params, new Map(), run.resourceId, resolvedName, packageName, streamContext, aiMiddlewares).tools;
|
|
442
621
|
const resolved = resolveModelConfig(resolvedName, agent);
|
|
622
|
+
const maxSteps = resolved.maxSteps ?? 10;
|
|
443
623
|
const runnerParams = {
|
|
444
624
|
model: resolved.model,
|
|
445
625
|
temperature: resolved.temperature,
|
|
446
626
|
instructions: modifiedInstructions,
|
|
447
627
|
messages: modifiedMessages,
|
|
448
628
|
tools: resumeTools,
|
|
449
|
-
maxSteps:
|
|
629
|
+
maxSteps: 1,
|
|
450
630
|
toolChoice: (agent.toolChoice ?? 'auto'),
|
|
451
631
|
outputSchema: meta?.outputSchema
|
|
452
632
|
? pikkuState(packageName, 'misc', 'schemas').get(meta.outputSchema)
|
|
453
633
|
: undefined,
|
|
454
634
|
};
|
|
455
635
|
try {
|
|
456
|
-
await
|
|
636
|
+
const loopResult = await runStreamStepLoop({
|
|
637
|
+
agent,
|
|
638
|
+
runnerParams,
|
|
639
|
+
maxSteps,
|
|
640
|
+
agentRunner,
|
|
641
|
+
persistingChannel,
|
|
642
|
+
channel,
|
|
643
|
+
runId: run.runId,
|
|
644
|
+
aiMiddlewares,
|
|
645
|
+
});
|
|
646
|
+
if (loopResult.outcome === 'approval') {
|
|
647
|
+
await handleApproval(loopResult.approval, run.runId, channel, aiRunState, persistingChannel);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
457
650
|
await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, storage, memoryConfig, run.threadId, workingMemorySchemaName, runnerParams.messages, aiRunState, run.runId);
|
|
651
|
+
channel.send({ type: 'done' });
|
|
652
|
+
channel.close();
|
|
458
653
|
}
|
|
459
654
|
catch (err) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
displayToolName: err.displayToolName ?? err.toolName,
|
|
469
|
-
displayArgs: err.displayArgs ?? err.args,
|
|
655
|
+
for (const mw of aiMiddlewares) {
|
|
656
|
+
if (mw.onError) {
|
|
657
|
+
try {
|
|
658
|
+
await mw.onError(singletonServices, {
|
|
659
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
660
|
+
stepNumber: -1,
|
|
661
|
+
messages: runnerParams.messages,
|
|
662
|
+
});
|
|
470
663
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
args: err.args,
|
|
476
|
-
};
|
|
477
|
-
await aiRunState.updateRun(run.runId, {
|
|
478
|
-
status: 'suspended',
|
|
479
|
-
suspendReason: 'approval',
|
|
480
|
-
pendingApprovals: [pendingApproval],
|
|
481
|
-
});
|
|
482
|
-
const approvalEvent = {
|
|
483
|
-
type: 'approval-request',
|
|
484
|
-
toolCallId: err.toolCallId,
|
|
485
|
-
toolName: err.displayToolName ?? err.toolName,
|
|
486
|
-
args: err.displayArgs ?? err.args,
|
|
487
|
-
reason: err.reason,
|
|
488
|
-
runId: run.runId,
|
|
489
|
-
};
|
|
490
|
-
channel.send(approvalEvent);
|
|
491
|
-
channel.send({ type: 'done' });
|
|
492
|
-
channel.close();
|
|
493
|
-
return;
|
|
664
|
+
catch {
|
|
665
|
+
// onError hooks must not affect error flow
|
|
666
|
+
}
|
|
667
|
+
}
|
|
494
668
|
}
|
|
495
669
|
await aiRunState.updateRun(run.runId, { status: 'failed' });
|
|
496
670
|
channel.send({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CorePermissionGroup, CorePikkuPermission } from '../../function/functions.types.js';
|
|
2
|
-
import { CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
|
|
1
|
+
import type { CorePermissionGroup, CorePikkuPermission } from '../../function/functions.types.js';
|
|
2
|
+
import type { CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
|
|
3
3
|
import type { PikkuChannel } from '../channel/channel.types.js';
|
|
4
4
|
import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js';
|
|
5
5
|
export interface AIThread {
|
|
@@ -10,6 +10,21 @@ export interface AIThread {
|
|
|
10
10
|
createdAt: Date;
|
|
11
11
|
updatedAt: Date;
|
|
12
12
|
}
|
|
13
|
+
export type AIContentPart = {
|
|
14
|
+
type: 'text';
|
|
15
|
+
text: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'image';
|
|
18
|
+
data?: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
mediaType?: string;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'file';
|
|
23
|
+
data?: string;
|
|
24
|
+
url?: string;
|
|
25
|
+
mediaType: string;
|
|
26
|
+
filename?: string;
|
|
27
|
+
};
|
|
13
28
|
export interface AIToolCall {
|
|
14
29
|
id: string;
|
|
15
30
|
name: string;
|
|
@@ -23,7 +38,7 @@ export interface AIToolResult {
|
|
|
23
38
|
export interface AIMessage {
|
|
24
39
|
id: string;
|
|
25
40
|
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
26
|
-
content?: string;
|
|
41
|
+
content?: string | AIContentPart[];
|
|
27
42
|
toolCalls?: AIToolCall[];
|
|
28
43
|
toolResults?: AIToolResult[];
|
|
29
44
|
createdAt: Date;
|
|
@@ -39,10 +54,18 @@ export interface AIAgentStep {
|
|
|
39
54
|
result: string;
|
|
40
55
|
}[];
|
|
41
56
|
}
|
|
57
|
+
export interface AIAgentInputAttachment {
|
|
58
|
+
type: 'image' | 'file';
|
|
59
|
+
data?: string;
|
|
60
|
+
url?: string;
|
|
61
|
+
mediaType?: string;
|
|
62
|
+
filename?: string;
|
|
63
|
+
}
|
|
42
64
|
export interface AIAgentInput {
|
|
43
65
|
message: string;
|
|
44
66
|
threadId: string;
|
|
45
67
|
resourceId: string;
|
|
68
|
+
attachments?: AIAgentInputAttachment[];
|
|
46
69
|
}
|
|
47
70
|
export interface AIAgentOutput {
|
|
48
71
|
runId: string;
|
|
@@ -60,6 +83,7 @@ export interface AIAgentToolDef {
|
|
|
60
83
|
description: string;
|
|
61
84
|
inputSchema: Record<string, unknown>;
|
|
62
85
|
execute: (input: unknown) => Promise<unknown>;
|
|
86
|
+
needsApproval?: boolean;
|
|
63
87
|
}
|
|
64
88
|
export interface PikkuAIMiddlewareHooks<State extends Record<string, unknown> = Record<string, unknown>, Services = any> {
|
|
65
89
|
modifyInput?: (services: Services, ctx: {
|
|
@@ -76,7 +100,7 @@ export interface PikkuAIMiddlewareHooks<State extends Record<string, unknown> =
|
|
|
76
100
|
event: AIStreamEvent;
|
|
77
101
|
allEvents: readonly AIStreamEvent[];
|
|
78
102
|
state: State;
|
|
79
|
-
}) => Promise<AIStreamEvent | null> | AIStreamEvent | null;
|
|
103
|
+
}) => Promise<AIStreamEvent | AIStreamEvent[] | null> | AIStreamEvent | AIStreamEvent[] | null;
|
|
80
104
|
modifyOutput?: (services: Services, ctx: {
|
|
81
105
|
text: string;
|
|
82
106
|
messages: AIMessage[];
|
|
@@ -91,6 +115,50 @@ export interface PikkuAIMiddlewareHooks<State extends Record<string, unknown> =
|
|
|
91
115
|
text: string;
|
|
92
116
|
messages: AIMessage[];
|
|
93
117
|
};
|
|
118
|
+
beforeToolCall?: (services: Services, ctx: {
|
|
119
|
+
toolName: string;
|
|
120
|
+
toolCallId: string;
|
|
121
|
+
args: Record<string, unknown>;
|
|
122
|
+
}) => Promise<{
|
|
123
|
+
args: Record<string, unknown>;
|
|
124
|
+
} | void> | {
|
|
125
|
+
args: Record<string, unknown>;
|
|
126
|
+
} | void;
|
|
127
|
+
afterToolCall?: (services: Services, ctx: {
|
|
128
|
+
toolName: string;
|
|
129
|
+
toolCallId: string;
|
|
130
|
+
args: Record<string, unknown>;
|
|
131
|
+
result: unknown;
|
|
132
|
+
durationMs: number;
|
|
133
|
+
}) => Promise<{
|
|
134
|
+
result: unknown;
|
|
135
|
+
} | void> | {
|
|
136
|
+
result: unknown;
|
|
137
|
+
} | void;
|
|
138
|
+
afterStep?: (services: Services, ctx: {
|
|
139
|
+
stepNumber: number;
|
|
140
|
+
text: string;
|
|
141
|
+
toolCalls: {
|
|
142
|
+
toolCallId: string;
|
|
143
|
+
toolName: string;
|
|
144
|
+
args: unknown;
|
|
145
|
+
}[];
|
|
146
|
+
toolResults: {
|
|
147
|
+
toolCallId: string;
|
|
148
|
+
toolName: string;
|
|
149
|
+
result: unknown;
|
|
150
|
+
}[];
|
|
151
|
+
usage: {
|
|
152
|
+
inputTokens: number;
|
|
153
|
+
outputTokens: number;
|
|
154
|
+
};
|
|
155
|
+
finishReason: string;
|
|
156
|
+
}) => Promise<void> | void;
|
|
157
|
+
onError?: (services: Services, ctx: {
|
|
158
|
+
error: Error;
|
|
159
|
+
stepNumber: number;
|
|
160
|
+
messages: AIMessage[];
|
|
161
|
+
}) => Promise<void> | void;
|
|
94
162
|
}
|
|
95
163
|
export type AIAgentMemoryConfig = {
|
|
96
164
|
storage?: string;
|
|
@@ -115,12 +183,26 @@ export type CoreAIAgent<PikkuPermission = CorePikkuPermission<any, any>, PikkuMi
|
|
|
115
183
|
input?: unknown;
|
|
116
184
|
output?: unknown;
|
|
117
185
|
tags?: string[];
|
|
186
|
+
protocol?: 'ui-message-stream';
|
|
187
|
+
prepareStep?: (ctx: {
|
|
188
|
+
stepNumber: number;
|
|
189
|
+
messages: AIMessage[];
|
|
190
|
+
tools: AIAgentToolDef[];
|
|
191
|
+
toolChoice: 'auto' | 'required' | 'none';
|
|
192
|
+
model: string;
|
|
193
|
+
stop: () => void;
|
|
194
|
+
}) => void | Promise<void>;
|
|
118
195
|
middleware?: PikkuMiddleware[];
|
|
119
196
|
channelMiddleware?: CorePikkuChannelMiddleware<any, any>[];
|
|
120
197
|
aiMiddleware?: PikkuAIMiddlewareHooks<any, any>[];
|
|
121
198
|
permissions?: CorePermissionGroup<PikkuPermission>;
|
|
122
199
|
};
|
|
123
200
|
export type AIStreamEvent = {
|
|
201
|
+
type: 'step-start';
|
|
202
|
+
stepNumber: number;
|
|
203
|
+
agent?: string;
|
|
204
|
+
session?: string;
|
|
205
|
+
} | {
|
|
124
206
|
type: 'text-delta';
|
|
125
207
|
text: string;
|
|
126
208
|
agent?: string;
|
|
@@ -176,6 +258,16 @@ export type AIStreamEvent = {
|
|
|
176
258
|
message: string;
|
|
177
259
|
agent?: string;
|
|
178
260
|
session?: string;
|
|
261
|
+
} | {
|
|
262
|
+
type: 'audio-delta';
|
|
263
|
+
data: string;
|
|
264
|
+
format: string;
|
|
265
|
+
agent?: string;
|
|
266
|
+
session?: string;
|
|
267
|
+
} | {
|
|
268
|
+
type: 'audio-done';
|
|
269
|
+
agent?: string;
|
|
270
|
+
session?: string;
|
|
179
271
|
} | {
|
|
180
272
|
type: 'suspended';
|
|
181
273
|
reason: 'rpc-missing';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export { agent, agentStream, agentResume, agentApprove, } from './ai-agent-helpers.js';
|
|
1
2
|
export { runAIAgent } from './ai-agent-runner.js';
|
|
2
3
|
export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js';
|
|
4
|
+
export { createAssistantUIChannel, parseAssistantUIInput, } from './ai-agent-assistant-ui.js';
|
|
3
5
|
export { type RunAIAgentParams, type StreamAIAgentOptions, ToolApprovalRequired, } from './ai-agent-prepare.js';
|
|
4
6
|
export { addAIAgent, approveAIAgent, getAIAgents, getAIAgentsMeta, } from './ai-agent-registry.js';
|
|
5
|
-
export type { AIAgentMeta, AIAgentMemoryConfig, AIAgentStep, AgentRunRow, AgentRunService, AgentRunState, AIMessage, AIStreamChannel, AIStreamEvent, AIThread, CoreAIAgent, PendingApproval, PikkuAIMiddlewareHooks, } from './ai-agent.types.js';
|
|
7
|
+
export type { AIAgentInput, AIAgentInputAttachment, AIAgentMeta, AIAgentMemoryConfig, AIAgentStep, AIContentPart, AgentRunRow, AgentRunService, AgentRunState, AIMessage, AIStreamChannel, AIStreamEvent, AIThread, CoreAIAgent, PendingApproval, PikkuAIMiddlewareHooks, } from './ai-agent.types.js';
|