Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
gpt-maa-ts
Advanced tools
A TypeScript client for submitting AgentDefinitions and user prompt to a gpt-multi-atomic-agents REST API, to generate supported mutations.
A TypeScript client for submitting AgentDefinitions and user prompts to a gpt-multi-atomic-agents REST API, to generate supported mutations (function calls).
This client provides a mini framework for defining the Agents and handling the response.
This provides a clean approach to LLM based Agent calling, so the client can focus on the 'domain' or business logic:
As an Example, consider the domain of household maintenance agents which operate a Lawn Mower robot and a Waste Disposer robot.
There is one agent for mowing the lawn (the 'Lawn Mower' agent), and another agent for disposing of waste (the 'Waster Disposer' agent).
By collaborating together, the agents can complete the greater task of clearing and mowing the lawn, and then cleaning up afterwards.
Agents are declared in terms of input and output functions.
First, we define the functions which the Lawn Mower agent will use:
const areaParameter: ParameterSpec = {
name: "area",
type: "string",
allowedValues: ["front", "back"],
}
const mowLawnFunction: FunctionSpecSchema = {
functionName: "MowLawn",
description: "Mow the lawn and tidy it up",
parameters: [areaParameter]
}
const produceCutGrassFunction: FunctionSpecSchema = {
functionName: "ProduceCutGrass",
description: "Produce cut grass waster",
parameters: [areaParameter]
}
Next, we can define the Lawn Mower Agent in terms of Functions (as inputs and outputs):
const lawnMowerAgent: FunctionAgentDefinitionMinimal = {
agentName: "Lawn Mower",
description: "Knows how to mow lawns",
acceptedFunctions: [mowLawnFunction, produceCutGrassFunction],
functionsAllowedToGenerate: [mowLawnFunction, produceCutGrassFunction],
topics: ["garden", "lawn", "grass"],
}
NOTE: Notice than an agent is basically a JSON document, so it can be imported, exported and even edited between REST API calls.
Next we define Functions that are specific to the Waste Disposer agent:
const wasteDisposerOutputFunctions: FunctionSpecSchema[] = [
{
functionName: "CollectWaste",
description: "Collect waste from an area",
parameters: [areaParameter]
},
{
functionName: "TakeWasteToCollectionSite",
description: "Take previously collected waste from an area, to a collection site",
parameters: [areaParameter, {
name: "site_name",
type: "string"
}]
}
]
Now that we have the waster disposer functions, and the waste output function of the Lawn Mower, we can define the Waste Disposer agent.
const wasteDisposerAgent: FunctionAgentDefinitionMinimal = {
agentName: "Waste Disposer",
description: "Knows how to collect and dispose of waste",
acceptedFunctions: [...wasteDisposerOutputFunctions, produceCutGrassFunction], // The waste disposer can observe when the lawn-mower has generated waste
functionsAllowedToGenerate: wasteDisposerOutputFunctions,
topics: ["waste", "dispose"],
}
Notice that the Waste Disposer agent takes the produceCutGrassFunction
function as in an input. This allows the Waste Disposer agent to see and understand that part of the output from the Lawn Mower agent.
NOTE: By sharing a subset of Function Calls, agents are able to understand each other's output, and collaborate indirectly via the REST API (internally, the REST API uses a Blackboard).
Finally, we also need to provide Handlers, to be able to execute the generated function calls.
NOTE: Handlers are the main point of integration with the greater application. Handlers are 'fixed' since they are necessarily hard-coded against the greater application, whereas Agents are more dynamic.
const functionRegistry = new FunctionRegistry();
class LawnHandler extends AreaHandlerBase
{
constructor(registry: FunctionRegistry) {
super(registry);
this.registerFunction(mowLawnFunction.functionName!, this.handleMowLawn)
this.registerFunction(produceCutGrassFunction.functionName!, this.handleProduceCutGrass)
}
private handleMowLawn(functionCall: FunctionCallSchema): void {
console.log("<mowing the lawn>")
console.log(` params:`, functionCall.parameters)
}
private handleProduceCutGrass(functionCall: FunctionCallSchema): void {
console.log("<producing cut grass>")
console.log(` params:`, functionCall.parameters)
}
protected nameImplementation(): string
{
return "Lawn Handler";
}
}
// Create the handlers (they register themselves)
const defaultHandler = new DefaultAreaHandler(functionRegistry, (functionCall: FunctionCallSchema) => {
console.log(`[default handler] for function call: ${functionCall.functionName}`, functionCall.parameters);
});
const lawnHandler = new LawnHandler(functionRegistry);
const wasteHandler = defaultHandler; // We can later add specific handling for Waste functions.
Now, we can use the agents to generate function calls, and execute them:
const agentDefinitions: FunctionAgentDefinitionMinimal[] = [
lawnMowerAgent, wasteDisposerAgent
]
// =================================================
// Chat with the Agents
const chatAgentDescription = "Handles questions about household chores such as garden, garden furniture and waste maintenance.";
const blackboardAccessor = await handleUserPrompt("Mow the lawn, dealing with any lawn furniture and waste. After mowing make sure waste is disposed of.", agentDefinitions, chatAgentDescription)
// =================================================
// Display the messages from the Agents
console.log(blackboardAccessor.get_new_messages());
// =================================================
// Execute the Function Calls using our Handlers
blackboardAccessor.get_new_functions()
const onExecuteStart = (): Promise<ExecuteStartResult> => {
console.log("(execution started)");
return {
isOkToContinue: true,
alsoExecutePreviousFunctions: false
}
}
const onExecuteEnd = (errors: ExecutionError[], blackboardAccessor: FunctionCallBlackboardAccessor): Promise<void> => {
console.log("(execution ended)");
if (errors.length) {
console.error(errors);
}
// Assuming that client has applied all functions, and wants to continue from that state:
const new_user_data = blackboardAccessor.get_new_functions();
blackboardAccessor.set_user_data(new_user_data);
}
execute(blackboardAccessor, functionRegistry, onExecuteStart, onExecuteEnd);
NOTE: The Blackboard is serialized back to the client, in order to avoid making the server statefull. If that produces heavy network traffic, then future versions of the server may allow for state-full operation (however this comes with tradeoffs).
For more details, see TypeScript Example Agents.
Depdencencies:
NOTE: You need a copy of the config.gpt-maa-ts.json file in your folder.
NOTE: You need to ensure that any directories referred to by
config.gpt-maa-ts.json
have been created.
NOTE: You need to have the gpt-multi-atomic-agents REST API running.
To run a REPL loop:
./go.sh
NOTE: 'Dynamic' Custom Agents are stored locally in the data-agents folder. Even while running the REPL, you can edit the agent files or add new ones. If you edit or add a custom agent, then use the REPL command to reload agents. There is also a command to list the active agents.
For examples, see the TypeScript Example Agents.
./test.sh
FAQs
A TypeScript client for submitting AgentDefinitions and user prompt to a gpt-multi-atomic-agents REST API, to generate supported mutations.
The npm package gpt-maa-ts receives a total of 0 weekly downloads. As such, gpt-maa-ts popularity was classified as not popular.
We found that gpt-maa-ts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.