@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
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { PikkuError } from '../../errors/error-handler.js';
|
|
2
|
-
import { pikkuState, getSingletonServices
|
|
3
|
-
import { runPikkuFunc } from '../../function/function-runner.js';
|
|
2
|
+
import { pikkuState, getSingletonServices } from '../../pikku-state.js';
|
|
4
3
|
import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js';
|
|
5
4
|
import { randomUUID } from 'crypto';
|
|
5
|
+
import { streamAIAgent } from './ai-agent-stream.js';
|
|
6
|
+
import { runAIAgent } from './ai-agent-runner.js';
|
|
7
|
+
import { resolveNamespace, ContextAwareRPCService, } from '../../wirings/rpc/rpc-runner.js';
|
|
8
|
+
import { buildDynamicWorkflowInstructions, buildWorkflowTools } from './agent-dynamic-workflow.js';
|
|
6
9
|
import { resolveMemoryServices, loadContextMessages, trimMessages, } from './ai-agent-memory.js';
|
|
7
10
|
import { resolveModelConfig } from './ai-agent-model-config.js';
|
|
8
11
|
export class ToolApprovalRequired extends PikkuError {
|
|
@@ -33,7 +36,7 @@ export const resolveAgent = (agentName) => {
|
|
|
33
36
|
if (colonIndex !== -1) {
|
|
34
37
|
const namespace = agentName.substring(0, colonIndex);
|
|
35
38
|
const localName = agentName.substring(colonIndex + 1);
|
|
36
|
-
const addons = pikkuState(null, '
|
|
39
|
+
const addons = pikkuState(null, 'addons', 'packages');
|
|
37
40
|
const pkgConfig = addons.get(namespace);
|
|
38
41
|
if (pkgConfig) {
|
|
39
42
|
const extAgent = pikkuState(pkgConfig.package, 'agent', 'agents').get(localName);
|
|
@@ -48,41 +51,47 @@ export const resolveAgent = (agentName) => {
|
|
|
48
51
|
}
|
|
49
52
|
throw new Error(`AI agent not found: ${agentName}`);
|
|
50
53
|
};
|
|
51
|
-
export function buildInstructions(agentName, packageName) {
|
|
54
|
+
export async function buildInstructions(agentName, packageName) {
|
|
52
55
|
const meta = pikkuState(packageName, 'agent', 'agentsMeta')[agentName];
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
?
|
|
56
|
-
:
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const rawInstructions = meta?.instructions ?? '';
|
|
57
|
+
let instructions = Array.isArray(rawInstructions)
|
|
58
|
+
? rawInstructions.join('\n')
|
|
59
|
+
: rawInstructions;
|
|
60
|
+
if (meta?.agents?.length) {
|
|
61
|
+
instructions +=
|
|
59
62
|
'\n\nWhen calling a sub-agent, provide a short session name that describes the task. ' +
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
'Use the same session name to continue a previous conversation with that agent. ' +
|
|
64
|
+
'Use a new session name for a new independent task. ' +
|
|
65
|
+
'When a request involves multiple actions for the same domain, combine them into a single sub-agent call rather than making separate calls.';
|
|
66
|
+
}
|
|
67
|
+
if (meta?.dynamicWorkflows && meta.tools?.length) {
|
|
68
|
+
instructions += buildDynamicWorkflowInstructions(meta.tools, meta.dynamicWorkflows);
|
|
69
|
+
}
|
|
70
|
+
return instructions;
|
|
63
71
|
}
|
|
64
72
|
export function createScopedChannel(parent, agentName, session) {
|
|
65
|
-
|
|
73
|
+
const capturedApprovals = [];
|
|
66
74
|
return {
|
|
67
75
|
channelId: `${parent.channelId}:${agentName}:${session}`,
|
|
68
76
|
openingData: parent.openingData,
|
|
69
77
|
get state() {
|
|
70
78
|
return parent.state;
|
|
71
79
|
},
|
|
72
|
-
get
|
|
73
|
-
return
|
|
80
|
+
get approvals() {
|
|
81
|
+
return capturedApprovals;
|
|
74
82
|
},
|
|
75
83
|
close: () => { },
|
|
84
|
+
sendBinary: (data) => parent.sendBinary(data),
|
|
76
85
|
send: (event) => {
|
|
77
86
|
if (event.type === 'done')
|
|
78
87
|
return;
|
|
79
88
|
if (event.type === 'approval-request') {
|
|
80
|
-
|
|
89
|
+
capturedApprovals.push({
|
|
81
90
|
toolCallId: event.toolCallId,
|
|
82
91
|
toolName: event.toolName,
|
|
83
92
|
args: event.args,
|
|
84
93
|
runId: event.runId,
|
|
85
|
-
};
|
|
94
|
+
});
|
|
86
95
|
return;
|
|
87
96
|
}
|
|
88
97
|
if (event.type === 'step-start' ||
|
|
@@ -91,7 +100,8 @@ export function createScopedChannel(parent, agentName, session) {
|
|
|
91
100
|
event.type === 'tool-call' ||
|
|
92
101
|
event.type === 'tool-result' ||
|
|
93
102
|
event.type === 'usage' ||
|
|
94
|
-
event.type === 'error'
|
|
103
|
+
event.type === 'error' ||
|
|
104
|
+
event.type === 'workflow-created') {
|
|
95
105
|
parent.send({ ...event, agent: agentName, session });
|
|
96
106
|
}
|
|
97
107
|
else {
|
|
@@ -100,7 +110,7 @@ export function createScopedChannel(parent, agentName, session) {
|
|
|
100
110
|
},
|
|
101
111
|
};
|
|
102
112
|
}
|
|
103
|
-
export function buildToolDefs(params, agentSessionMap, resourceId, agentName, packageName, streamContext, aiMiddlewares) {
|
|
113
|
+
export async function buildToolDefs(params, agentSessionMap, resourceId, agentName, packageName, streamContext, aiMiddlewares, agentMode) {
|
|
104
114
|
const singletonServices = getSingletonServices();
|
|
105
115
|
const tools = [];
|
|
106
116
|
const missingRpcs = [];
|
|
@@ -111,16 +121,34 @@ export function buildToolDefs(params, agentSessionMap, resourceId, agentName, pa
|
|
|
111
121
|
const metaTools = meta.tools;
|
|
112
122
|
const metaAgents = meta.agents;
|
|
113
123
|
if (metaTools?.length) {
|
|
114
|
-
const functionMeta = pikkuState(null, 'function', 'meta');
|
|
115
|
-
const schemas = pikkuState(null, 'misc', 'schemas');
|
|
116
124
|
for (const toolName of metaTools) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
let fnMeta;
|
|
126
|
+
let resolvedPkg = null;
|
|
127
|
+
let schemas;
|
|
128
|
+
const resolved = toolName.includes(':')
|
|
129
|
+
? resolveNamespace(toolName)
|
|
130
|
+
: null;
|
|
131
|
+
let pikkuFuncId;
|
|
132
|
+
if (resolved) {
|
|
133
|
+
resolvedPkg = resolved.package;
|
|
134
|
+
pikkuFuncId = resolved.function;
|
|
135
|
+
fnMeta = pikkuState(resolvedPkg, 'function', 'meta')[pikkuFuncId];
|
|
136
|
+
schemas = pikkuState(resolvedPkg, 'misc', 'schemas');
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const rpcMeta = pikkuState(null, 'rpc', 'meta');
|
|
140
|
+
pikkuFuncId = rpcMeta[toolName];
|
|
141
|
+
if (!pikkuFuncId) {
|
|
142
|
+
missingRpcs.push(toolName);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
fnMeta = pikkuState(null, 'function', 'meta')[pikkuFuncId];
|
|
146
|
+
schemas = pikkuState(null, 'misc', 'schemas');
|
|
147
|
+
}
|
|
148
|
+
if (!fnMeta) {
|
|
120
149
|
missingRpcs.push(toolName);
|
|
121
150
|
continue;
|
|
122
151
|
}
|
|
123
|
-
const fnMeta = functionMeta[pikkuFuncId];
|
|
124
152
|
const inputSchemaName = fnMeta?.inputSchemaName;
|
|
125
153
|
let inputSchema = inputSchemaName
|
|
126
154
|
? schemas.get(inputSchemaName)
|
|
@@ -132,23 +160,38 @@ export function buildToolDefs(params, agentSessionMap, resourceId, agentName, pa
|
|
|
132
160
|
inputSchema = { type: 'object', properties: {} };
|
|
133
161
|
}
|
|
134
162
|
const needsApproval = approvalPolicy === 'all' ||
|
|
135
|
-
(approvalPolicy === 'explicit' && fnMeta?.
|
|
163
|
+
(approvalPolicy === 'explicit' && fnMeta?.approvalRequired);
|
|
164
|
+
// Build approvalDescriptionFn if the function has an approvalDescription configured
|
|
165
|
+
let approvalDescriptionFn;
|
|
166
|
+
if (needsApproval && pikkuFuncId) {
|
|
167
|
+
const funcConfig = pikkuState(resolvedPkg, 'function', 'functions').get(pikkuFuncId);
|
|
168
|
+
if (funcConfig?.approvalDescription) {
|
|
169
|
+
const descFn = funcConfig.approvalDescription;
|
|
170
|
+
const capturedPkg = resolvedPkg;
|
|
171
|
+
approvalDescriptionFn = async (input) => {
|
|
172
|
+
let services = singletonServices;
|
|
173
|
+
if (capturedPkg) {
|
|
174
|
+
const pkgServices = pikkuState(capturedPkg, 'package', 'singletonServices');
|
|
175
|
+
if (pkgServices) {
|
|
176
|
+
services = pkgServices;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return descFn(services, input);
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
136
183
|
tools.push({
|
|
137
|
-
name:
|
|
184
|
+
name: toolName.replaceAll(':', '__'),
|
|
138
185
|
description: fnMeta?.description || fnMeta?.title || toolName,
|
|
139
186
|
inputSchema,
|
|
140
187
|
needsApproval: needsApproval || undefined,
|
|
188
|
+
approvalDescriptionFn,
|
|
141
189
|
execute: async (toolInput) => {
|
|
142
190
|
const wire = params.sessionService
|
|
143
191
|
? { ...createMiddlewareSessionWireProps(params.sessionService) }
|
|
144
192
|
: {};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
createWireServices: getCreateWireServices(),
|
|
148
|
-
data: () => toolInput,
|
|
149
|
-
wire,
|
|
150
|
-
sessionService: params.sessionService,
|
|
151
|
-
});
|
|
193
|
+
const rpcService = new ContextAwareRPCService(singletonServices, wire, { sessionService: params.sessionService });
|
|
194
|
+
return rpcService.rpc(toolName, toolInput);
|
|
152
195
|
},
|
|
153
196
|
});
|
|
154
197
|
}
|
|
@@ -180,11 +223,14 @@ export function buildToolDefs(params, agentSessionMap, resourceId, agentName, pa
|
|
|
180
223
|
const sessionKey = `${subAgentName}::${session}`;
|
|
181
224
|
let threadId = agentSessionMap.get(sessionKey);
|
|
182
225
|
if (!threadId) {
|
|
183
|
-
threadId =
|
|
226
|
+
threadId = randomUUID();
|
|
184
227
|
agentSessionMap.set(sessionKey, threadId);
|
|
185
228
|
}
|
|
186
229
|
if (streamContext) {
|
|
187
|
-
const
|
|
230
|
+
const isDelegate = agentMode !== 'supervise';
|
|
231
|
+
if (isDelegate && streamContext.delegateState) {
|
|
232
|
+
streamContext.delegateState.delegated = true;
|
|
233
|
+
}
|
|
188
234
|
const { channel } = streamContext;
|
|
189
235
|
channel.send({
|
|
190
236
|
type: 'agent-call',
|
|
@@ -193,32 +239,48 @@ export function buildToolDefs(params, agentSessionMap, resourceId, agentName, pa
|
|
|
193
239
|
input: message,
|
|
194
240
|
});
|
|
195
241
|
const subChannel = createScopedChannel(channel, subAgentName, session);
|
|
196
|
-
|
|
197
|
-
|
|
242
|
+
// In supervise mode, suppress sub-agent text from reaching the client.
|
|
243
|
+
// Approvals still flow through normally.
|
|
244
|
+
const effectiveChannel = isDelegate
|
|
245
|
+
? subChannel
|
|
246
|
+
: {
|
|
247
|
+
...subChannel,
|
|
248
|
+
send: (event) => {
|
|
249
|
+
if (event.type === 'text-delta' ||
|
|
250
|
+
event.type === 'reasoning-delta')
|
|
251
|
+
return;
|
|
252
|
+
subChannel.send(event);
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
const resultText = await streamAIAgent(subAgentName, { message, threadId, resourceId }, effectiveChannel, params, agentSessionMap, streamContext.options);
|
|
256
|
+
if (subChannel.approvals.length > 0) {
|
|
198
257
|
return {
|
|
199
258
|
__approvalRequired: true,
|
|
200
259
|
toolName: subAgentName,
|
|
201
260
|
args: toolInput,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
agentRunId: subChannel.approval.runId,
|
|
261
|
+
agentRunId: subChannel.approvals[0].runId,
|
|
262
|
+
subApprovals: subChannel.approvals,
|
|
205
263
|
};
|
|
206
264
|
}
|
|
207
265
|
channel.send({
|
|
208
266
|
type: 'agent-result',
|
|
209
267
|
agentName: subAgentName,
|
|
210
268
|
session,
|
|
211
|
-
result:
|
|
269
|
+
result: resultText,
|
|
212
270
|
});
|
|
213
|
-
return
|
|
271
|
+
return resultText;
|
|
214
272
|
}
|
|
215
|
-
|
|
273
|
+
// No stream context: sub-agent runs non-streaming
|
|
216
274
|
const result = await runAIAgent(subAgentName, { message, threadId, resourceId }, params, agentSessionMap);
|
|
217
275
|
return result.object ?? result.text;
|
|
218
276
|
},
|
|
219
277
|
});
|
|
220
278
|
}
|
|
221
279
|
}
|
|
280
|
+
if (meta.dynamicWorkflows) {
|
|
281
|
+
const workflowTools = buildWorkflowTools(agentName, packageName, meta.tools ?? [], meta.dynamicWorkflows, streamContext, params.sessionService);
|
|
282
|
+
tools.push(...workflowTools);
|
|
283
|
+
}
|
|
222
284
|
const hasToolHooks = aiMiddlewares?.some((mw) => mw.beforeToolCall || mw.afterToolCall);
|
|
223
285
|
if (hasToolHooks) {
|
|
224
286
|
for (const tool of tools) {
|
|
@@ -279,6 +341,15 @@ export async function prepareAgentRun(agentName, input, params, agentSessionMap,
|
|
|
279
341
|
if (!agentRunner) {
|
|
280
342
|
throw new Error('AIAgentRunnerService not available in singletonServices');
|
|
281
343
|
}
|
|
344
|
+
if (agent.dynamicWorkflows && singletonServices.workflowService) {
|
|
345
|
+
const persisted = await singletonServices.workflowService.getAIGeneratedWorkflows(resolvedName);
|
|
346
|
+
const allMeta = pikkuState(null, 'workflows', 'meta');
|
|
347
|
+
for (const wf of persisted) {
|
|
348
|
+
if (!allMeta[wf.workflowName]) {
|
|
349
|
+
allMeta[wf.workflowName] = wf.graph;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
282
353
|
const { storage } = resolveMemoryServices(agent, singletonServices);
|
|
283
354
|
const memoryConfig = agent.memory;
|
|
284
355
|
const threadId = input.threadId;
|
|
@@ -307,18 +378,40 @@ export async function prepareAgentRun(agentName, input, params, agentSessionMap,
|
|
|
307
378
|
});
|
|
308
379
|
}
|
|
309
380
|
const contextMessages = await loadContextMessages(memoryConfig, storage, input, workingMemoryJsonSchema);
|
|
381
|
+
const userContent = input.attachments?.length
|
|
382
|
+
? [
|
|
383
|
+
{ type: 'text', text: input.message },
|
|
384
|
+
...input.attachments.map((a) => ({
|
|
385
|
+
type: a.type,
|
|
386
|
+
data: a.data,
|
|
387
|
+
url: a.url,
|
|
388
|
+
mediaType: a.mediaType,
|
|
389
|
+
...(a.filename ? { filename: a.filename } : {}),
|
|
390
|
+
})),
|
|
391
|
+
]
|
|
392
|
+
: input.message;
|
|
310
393
|
const userMessage = {
|
|
311
394
|
id: randomUUID(),
|
|
312
395
|
role: 'user',
|
|
313
|
-
content:
|
|
396
|
+
content: userContent,
|
|
314
397
|
createdAt: new Date(),
|
|
315
398
|
};
|
|
316
399
|
const allMessages = [...contextMessages, ...messages, userMessage];
|
|
317
400
|
const trimmedMessages = trimMessages(allMessages);
|
|
318
401
|
const aiMiddlewares = agent.aiMiddleware ?? [];
|
|
319
|
-
const { tools, missingRpcs } = buildToolDefs(params, agentSessionMap, input.resourceId, resolvedName, packageName, streamContext, aiMiddlewares);
|
|
320
|
-
const instructions = buildInstructions(resolvedName, packageName);
|
|
402
|
+
const { tools, missingRpcs } = await buildToolDefs(params, agentSessionMap, input.resourceId, resolvedName, packageName, streamContext, aiMiddlewares, agent.agentMode);
|
|
403
|
+
const instructions = await buildInstructions(resolvedName, packageName);
|
|
321
404
|
const resolved = resolveModelConfig(resolvedName, agent);
|
|
405
|
+
// Per-request overrides
|
|
406
|
+
if (input.model) {
|
|
407
|
+
resolved.model = resolveModelConfig(resolvedName, {
|
|
408
|
+
...agent,
|
|
409
|
+
model: input.model,
|
|
410
|
+
}).model;
|
|
411
|
+
}
|
|
412
|
+
if (input.temperature !== undefined) {
|
|
413
|
+
resolved.temperature = input.temperature;
|
|
414
|
+
}
|
|
322
415
|
const maxSteps = resolved.maxSteps ?? 10;
|
|
323
416
|
const runnerParams = {
|
|
324
417
|
model: resolved.model,
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { AIAgentInput, AIAgentOutput } from './ai-agent.types.js';
|
|
2
2
|
import { type RunAIAgentParams } from './ai-agent-prepare.js';
|
|
3
3
|
export declare function runAIAgent(agentName: string, input: AIAgentInput, params: RunAIAgentParams, agentSessionMap?: Map<string, string>): Promise<AIAgentOutput>;
|
|
4
|
+
export declare function resumeAIAgentSync(runId: string, approvals: {
|
|
5
|
+
toolCallId: string;
|
|
6
|
+
approved: boolean;
|
|
7
|
+
}[], params: RunAIAgentParams, expectedAgentName?: string): Promise<AIAgentOutput>;
|