Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utils.ai.AIAgent,CallTool,CallToolOutput (minor) new components for d… #305

Draft
wants to merge 9 commits into
base: dev
Choose a base branch
from
31 changes: 31 additions & 0 deletions src/appmixer/ai/agenttools/ToolOutput/ToolOutput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';

module.exports = {

receive: async function(context) {

// Find the toolCallId in the message scope, looking into the first
// component with type 'appmixer.utils.ai.ToolStart' and taking
// toolCallId from the output message that is stored in the flow state.
const flowDescriptor = context.flowDescriptor;
const scope = context.messages.in.scope;
let toolCallId;
for (const componentId of Object.keys(scope)) {
const component = flowDescriptor[componentId];
if (component && component.type === 'appmixer.ai.agenttools.ToolStart') {
const key = componentId + ':' + context.messages.in.correlationId;
toolCallId = await context.flow.stateGet(key);
await context.flow.stateUnset(key);
}
}

if (!toolCallId) {
await context.log({ step: 'no-tool-call-id', scope, flowDescriptor });
throw new context.CancelError('No toolCallId found in the scope. Are you sure you used ai.ToolStart to start your tool chain?');
}

await context.log({ step: 'tool-output', toolCallId, output: context.messages.in.content.output });
// The AI agent expects to see the output in the flow state under the toolCallId key.
return context.flow.stateSet(toolCallId, { output: context.messages.in.content.output });
}
};
24 changes: 24 additions & 0 deletions src/appmixer/ai/agenttools/ToolOutput/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "appmixer.ai.agenttools.ToolOutput",
"author": "Appmixer <[email protected]>",
"description": "Determines the end of tool chain for AI Agent. Set the output of the tool chain. This output will be sent back to the AI Agent to serve as context.",
"inPorts": [{
"name": "in",
"schema": {
"type": "object",
"properties": {
"output": { "type": "string" }
}
},
"inspector": {
"inputs": {
"output": {
"type": "textarea",
"label": "Output",
"index": 1
}
}
}
}],
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzUyMjFfMzI1MzcpIj4KPHBhdGggZD0iTTEyLjY2NjcgNi42NjY2N1YySDgiIHN0cm9rZT0iIzE4MTgxOCIgc3Ryb2tlLXdpZHRoPSIyLjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTguNjY4MyA2LjY2NjVINS42NjgyOUM0LjM3OTYzIDYuNjY2NSAzLjMzNDk2IDcuNzExMTcgMy4zMzQ5NiA4Ljk5OTg0VjE4LjMzMzJDMy4zMzQ5NiAxOS42MjE4IDQuMzc5NjMgMjAuNjY2NSA1LjY2ODI5IDIwLjY2NjVIMTguNjY4M0MxOS45NTcgMjAuNjY2NSAyMS4wMDE2IDE5LjYyMTggMjEuMDAxNiAxOC4zMzMyVjguOTk5ODRDMjEuMDAxNiA3LjcxMTE3IDE5Ljk1NyA2LjY2NjUgMTguNjY4MyA2LjY2NjVaIiBzdHJva2U9IiMxODE4MTgiIHN0cm9rZS13aWR0aD0iMi4xIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEuMDAwOTggMTMuNjY2M0gzLjMzNDMxIiBzdHJva2U9IiMxODE4MTgiIHN0cm9rZS13aWR0aD0iMi4xIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTIxLjAwMSAxMy42NjYzSDIzLjAzNDUiIHN0cm9rZT0iIzE4MTgxOCIgc3Ryb2tlLXdpZHRoPSIyLjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZyBmaWx0ZXI9InVybCgjZmlsdGVyMF9kXzUyMjFfMzI1MzcpIj4KPHBhdGggZD0iTTcuMDAwOTggMTMuNDU5NUw5LjYwNzE4IDE2LjA2NTdDMTAuMzA2OCAxNi43NjUzIDExLjQ0OTUgMTYuNzM2NyAxMi4xMTMyIDE2LjAwM0wxNy4wMDEgMTAuNTk5OSIgc3Ryb2tlPSIjMjBCNzVBIiBzdHJva2Utd2lkdGg9IjIuODU1MTIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L2c+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZF81MjIxXzMyNTM3IiB4PSIzLjQ3MjY5IiB5PSI3LjA3MTgxIiB3aWR0aD0iMTcuMDU2NiIgaGVpZ2h0PSIxMy4wMjg3IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIxLjA1MDI3Ii8+CjxmZUNvbXBvc2l0ZSBpbjI9ImhhcmRBbHBoYSIgb3BlcmF0b3I9Im91dCIvPgo8ZmVDb2xvck1hdHJpeCB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4yNSAwIi8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0iZWZmZWN0MV9kcm9wU2hhZG93XzUyMjFfMzI1MzciLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJlZmZlY3QxX2Ryb3BTaGFkb3dfNTIyMV8zMjUzNyIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPGNsaXBQYXRoIGlkPSJjbGlwMF81MjIxXzMyNTM3Ij4KPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
}
26 changes: 26 additions & 0 deletions src/appmixer/ai/agenttools/ToolOutput/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/appmixer/ai/agenttools/ToolStart/ToolStart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

module.exports = {

receive: async function(context) {

if (context.properties.generateOutputPortOptions) {
return this.getOutputPortOptions(context);
}
const { toolCalls } = context.messages.in.originalContent;
for (const toolCall of toolCalls) {
// Process only those tool calls that are for this component.
// This is because the AI Agent fans out all tool calls by using sendJson(..., 'tools').
if (toolCall.componentId === context.componentId) {
const out = { args: toolCall.args, toolCallId: toolCall.id };
await context.flow.stateSet(context.componentId + ':' + context.messages.in.correlationId, toolCall.id);
await context.sendJson(out, 'out');
}
}
},

getOutputPortOptions(context) {

const options = [];
const parameters = context.properties.parameters?.ADD || [];
parameters.forEach(parameter => {
options.push({ label: parameter.name, value: 'args.' + parameter.name, schema: { type: parameter.type } });
});
options.push({ label: 'Tool Call ID', value: 'toolCallId', schema: { type: 'string' } });
return context.sendJson(options, 'out');
}
};
65 changes: 65 additions & 0 deletions src/appmixer/ai/agenttools/ToolStart/component.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"name": "appmixer.ai.agenttools.ToolStart",
"author": "Appmixer <[email protected]>",
"description": "Define a tool chain (i.e. a set of actions that might be selected by the AI model to run based on the user prompt). The tool can provide additional context to the AI agent to be able to reply to the user or call actions. This has to be the first component connected to the AI Agent tools output port. The tool chain must be ended with 'Tool Output'.",
"properties": {
"schema": {
"type": "object",
"properties": {
"generateOutputPortOptions": { "type": "boolean" },
"description": { "type": "string" },
"parameters": { "type": "object" }
}
},
"inspector": {
"inputs": {
"description": {
"type": "textarea",
"label": "Description",
"index": 1
},
"parameters": {
"type": "expression",
"levels": ["ADD"],
"label": "Parameters",
"index": 2,
"fields": {
"name": {
"type": "text",
"label": "Name"
},
"description": {
"type": "textarea",
"label": "Description"
},
"type": {
"type": "select",
"label": "Type",
"options": [
{ "value": "string", "label": "String" },
{ "value": "number", "label": "Number" },
{ "value": "boolean", "label": "Boolean" }
]
}
}
}
}
}
},
"inPorts": [{
"name": "in"
}],
"outPorts": [{
"name": "out",
"source": {
"url": "/component/appmixer/ai/agenttools/ToolStart?outPort=out",
"data": {
"properties": {
"generateOutputPortOptions": true,
"parameters": "properties/parameters"
}
}
}
}],
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzUyMjFfMzI0OTcpIj4KPHBhdGggZD0iTTExLjk5OTggNS4yVjFINy43OTk4IiBzdHJva2U9IiMxODE4MTgiIHN0cm9rZS13aWR0aD0iMi4xIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTcuNzk5NjEgMTcuOEwzLjU5OTYxIDIyVjcuMjk5OTVDMy41OTk2MSA2Ljc0MyAzLjgyMDg2IDYuMjA4ODUgNC4yMTQ2OSA1LjgxNTAzQzQuNjA4NTEgNS40MjEyIDUuMTQyNjUgNS4xOTk5NSA1LjY5OTYxIDUuMTk5OTVIMTguMjk5NkMxOC44NTY2IDUuMTk5OTUgMTkuMzkwNyA1LjQyMTIgMTkuNzg0NSA1LjgxNTAzQzIwLjE3ODQgNi4yMDg4NSAyMC4zOTk2IDYuNzQzIDIwLjM5OTYgNy4yOTk5NVYxNS43QzIwLjM5OTYgMTYuMjU2OSAyMC4xNzg0IDE2Ljc5MSAxOS43ODQ1IDE3LjE4NDlDMTkuMzkwNyAxNy41Nzg3IDE4Ljg1NjYgMTcuOCAxOC4yOTk2IDE3LjhINy43OTk2MVoiIHN0cm9rZT0iIzE4MTgxOCIgc3Ryb2tlLXdpZHRoPSIyLjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMS41IDExLjQ5OThIMy42IiBzdHJva2U9IiMxODE4MTgiIHN0cm9rZS13aWR0aD0iMi4xIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTguODQ5NjEgMTAuNDVWMTIuNTUiIHN0cm9rZT0iIzE4MTgxOCIgc3Ryb2tlLXdpZHRoPSIyLjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTUuMTUwNCAxMC40NVYxMi41NSIgc3Ryb2tlPSIjMTgxODE4IiBzdHJva2Utd2lkdGg9IjIuMSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0yMC40MDA0IDExLjQ5OThIMjIuNTAwNCIgc3Ryb2tlPSIjMTgxODE4IiBzdHJva2Utd2lkdGg9IjIuMSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjwvZz4KPGRlZnM+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNTIyMV8zMjQ5NyI+CjxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K"
}
15 changes: 15 additions & 0 deletions src/appmixer/ai/agenttools/ToolStart/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/appmixer/ai/agenttools/bundle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "appmixer.ai.agenttools",
"version": "1.0.0",
"changelog": {
"1.0.0": [
"First version."
]
}
}
10 changes: 10 additions & 0 deletions src/appmixer/ai/agenttools/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "appmixer.ai.agenttools",
"label": "Agent Tools",
"category": "ai",
"categoryIndex": 0,
"index": 2,
"categoryLabel": "AI",
"description": "Generic tool components for building AI agents.",
"icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzUyMjFfMzI0OTApIj4KPHBhdGggZD0iTTEyLjE1OTcgNi44Nzk5VjIuMzk5OUg3LjY3OTY5IiBzdHJva2U9IiMzMDMyMzYiIHN0cm9rZS13aWR0aD0iMi4wMTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMTcuOTIxMiA2Ljg3OTY0SDUuNDQxMTdDNC4yMDQwNSA2Ljg3OTY0IDMuMjAxMTcgNy44ODI1MiAzLjIwMTE3IDkuMTE5NjRWMTguMDc5NkMzLjIwMTE3IDE5LjMxNjggNC4yMDQwNSAyMC4zMTk2IDUuNDQxMTcgMjAuMzE5NkgxNy45MjEyQzE5LjE1ODMgMjAuMzE5NiAyMC4xNjEyIDE5LjMxNjggMjAuMTYxMiAxOC4wNzk2VjkuMTE5NjRDMjAuMTYxMiA3Ljg4MjUyIDE5LjE1ODMgNi44Nzk2NCAxNy45MjEyIDYuODc5NjRaIiBzdHJva2U9IiMzMDMyMzYiIHN0cm9rZS13aWR0aD0iMi4wMTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMC45NTk5NjEgMTMuNTk5NkgzLjE5OTk2IiBzdHJva2U9IiMzMDMyMzYiIHN0cm9rZS13aWR0aD0iMi4wMTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjEuMTIwMSAxMy41OTk2SDIyLjQwMDEiIHN0cm9rZT0iIzMwMzIzNiIgc3Ryb2tlLXdpZHRoPSIyLjAxNiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xNC43ODQyIDEyLjQ3OTdWMTQuNzE5NyIgc3Ryb2tlPSIjMzAzMjM2IiBzdHJva2Utd2lkdGg9IjIuMDE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTguNjM5NjUgMTIuNDc5N1YxNC43MTk3IiBzdHJva2U9IiMzMDMyMzYiIHN0cm9rZS13aWR0aD0iMi4wMTYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzUyMjFfMzI0OTAiPgo8cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjMuMDQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDAuNDc5OTgpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg=="
}
Loading