Skip to content

Commit 6eafeda

Browse files
authored
Merge pull request #26 from MikePfunk28/012-visual-builder-update
feat: Enhance model registry and agent execution with new skills and …
2 parents c359068 + 384e1aa commit 6eafeda

80 files changed

Lines changed: 4073 additions & 1966 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/setup-github-projects_Version3.yml

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,68 +19,11 @@ jobs:
1919
- name: Checkout
2020
uses: actions/checkout@v4
2121

22-
- name: Set up GitHub CLI
23-
run: |
24-
sudo apt-get update
25-
sudo apt-get install -y gh
26-
# Verify gh CLI version is compatible (>=2.21.0) for native 'gh project' commands
27-
version=$(gh --version | head -n1 | awk '{print $3}' 2>/dev/null || echo "0.0.0")
28-
major=$(echo "$version" | cut -d. -f1)
29-
minor=$(echo "$version" | cut -d. -f2)
30-
if [ "$major" -lt 2 ] || { [ "$major" -eq 2 ] && [ "$minor" -lt 21 ]; }; then
31-
echo "gh CLI >= 2.21.0 required. Current: $version" >&2
32-
exit 1
33-
fi
34-
35-
- name: Create Project with description
36-
env:
37-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38-
run: |
39-
PROJECT_NAME="Agent Builder Application"
40-
PROJECT_DESC="Agent Builder Application - AI agent creation, testing, and deployment platform"
41-
42-
# Check if project exists
43-
proj_list=$(gh project list --owner ${{ github.repository_owner }} --format json 2>&1)
44-
rc=$?
45-
if [ $rc -ne 0 ]; then
46-
echo "gh project list failed: $proj_list" >&2
47-
exit $rc
48-
fi
49-
PROJECT_ID=$(echo "$proj_list" | jq -r "[.[] | select(.title == \"$PROJECT_NAME\") | .number] | first // empty")
50-
51-
if [ -z "$PROJECT_ID" ]; then
52-
echo "Creating new project..."
53-
gh project create "$PROJECT_NAME" --owner ${{ github.repository_owner }} --body "$PROJECT_DESC"
54-
55-
# Re-check to ensure we obtained an ID, fail explicitly if not found
56-
proj_list=$(gh project list --owner ${{ github.repository_owner }} --format json 2>&1)
57-
rc=$?
58-
if [ $rc -ne 0 ]; then
59-
echo "gh project list failed after create: $proj_list" >&2
60-
exit $rc
61-
fi
62-
PROJECT_ID=$(echo "$proj_list" | jq -r "[.[] | select(.title == \"$PROJECT_NAME\") | .number] | first // empty")
63-
if [ -z "$PROJECT_ID" ]; then
64-
echo "Failed to obtain PROJECT_ID for $PROJECT_NAME" >&2
65-
exit 1
66-
fi
67-
fi
68-
69-
echo "PROJECT_ID=$PROJECT_ID" >> $GITHUB_ENV
70-
71-
- name: Reminder - Create views manually
72-
run: |
73-
echo "NOTE: GitHub Projects v2 views cannot be created via the gh CLI."
74-
echo "Please create the following views manually in the GitHub web UI:"
75-
echo " 1. 'Tasks Table' (Table view)"
76-
echo " 2. 'Kanban Board' (Board view)"
77-
echo " 3. 'Schedule Timeline' (Timeline view)"
78-
7922
- name: Backfill existing open issues
8023
env:
8124
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
PROJECT_ID: "4"
8226
run: |
83-
PROJECT_ID=${{ env.PROJECT_ID }}
8427
REPO="${{ github.repository }}"
8528
8629
# Fetch all open issues via paginated API
@@ -109,8 +52,8 @@ jobs:
10952
if: github.event_name == 'issues' || github.event_name == 'pull_request'
11053
env:
11154
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
55+
PROJECT_ID: "4"
11256
run: |
113-
PROJECT_ID=${{ env.PROJECT_ID }}
11457
REPO="${{ github.repository }}"
11558
11659
if [ "${{ github.event_name }}" = "issues" ]; then

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,14 @@ ARCHITECTURE_DIAGRAM.txt
134134
OLLAMA_QUICK_SUMMARY.txt
135135
mcp.json
136136
tmp_write_check.txt
137+
agent_builder_complete_infrastructure_updated.png
138+
agent_builder_complete_infrastructure.png
139+
agent_builder_comprehensive_features.png
140+
agent_builder_deployment_flow.png
141+
agent_builder_infrastructure
142+
agent_builder_mcp_servers.png
143+
agent_builder_memory_architecture.png
144+
agent_builder_security.png
145+
agent_builder_registries.png
146+
agent_builder_three_chat_system.png
147+
agent_builder_tier_comparison.png

README.md

Lines changed: 137 additions & 96 deletions
Large diffs are not rendered by default.

convex/_generated/api.d.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import type * as cloudFormationGenerator from "../cloudFormationGenerator.js";
3939
import type * as codeGenerator from "../codeGenerator.js";
4040
import type * as cognitoAuth from "../cognitoAuth.js";
4141
import type * as constants from "../constants.js";
42-
import type * as containerOrchestrator from "../containerOrchestrator.js";
4342
import type * as conversationAnalysis from "../conversationAnalysis.js";
4443
import type * as conversations from "../conversations.js";
4544
import type * as crons from "../crons.js";
@@ -56,18 +55,21 @@ import type * as http from "../http.js";
5655
import type * as interleavedReasoning from "../interleavedReasoning.js";
5756
import type * as lambdaTesting from "../lambdaTesting.js";
5857
import type * as lib_aws_cloudwatchClient from "../lib/aws/cloudwatchClient.js";
59-
import type * as lib_aws_ecsClient from "../lib/aws/ecsClient.js";
58+
import type * as lib_aws_credentials from "../lib/aws/credentials.js";
6059
import type * as lib_aws_s3Client from "../lib/aws/s3Client.js";
6160
import type * as lib_bedrockGate from "../lib/bedrockGate.js";
6261
import type * as lib_cloudFormationGenerator from "../lib/cloudFormationGenerator.js";
6362
import type * as lib_dynamicModelSwitching from "../lib/dynamicModelSwitching.js";
6463
import type * as lib_fileGenerators from "../lib/fileGenerators.js";
64+
import type * as lib_iterativeLoop from "../lib/iterativeLoop.js";
65+
import type * as lib_jsonUtils from "../lib/jsonUtils.js";
6566
import type * as lib_memoryStore from "../lib/memoryStore.js";
6667
import type * as lib_messageExecutor from "../lib/messageExecutor.js";
6768
import type * as lib_roles from "../lib/roles.js";
6869
import type * as lib_strandsTools from "../lib/strandsTools.js";
6970
import type * as lib_tierConfig from "../lib/tierConfig.js";
7071
import type * as lib_tokenBilling from "../lib/tokenBilling.js";
72+
import type * as lib_toolDispatch from "../lib/toolDispatch.js";
7173
import type * as lib_unifiedModalitySwitching from "../lib/unifiedModalitySwitching.js";
7274
import type * as localModelDetector from "../localModelDetector.js";
7375
import type * as maintenance from "../maintenance.js";
@@ -150,7 +152,6 @@ declare const fullApi: ApiFromModules<{
150152
codeGenerator: typeof codeGenerator;
151153
cognitoAuth: typeof cognitoAuth;
152154
constants: typeof constants;
153-
containerOrchestrator: typeof containerOrchestrator;
154155
conversationAnalysis: typeof conversationAnalysis;
155156
conversations: typeof conversations;
156157
crons: typeof crons;
@@ -167,18 +168,21 @@ declare const fullApi: ApiFromModules<{
167168
interleavedReasoning: typeof interleavedReasoning;
168169
lambdaTesting: typeof lambdaTesting;
169170
"lib/aws/cloudwatchClient": typeof lib_aws_cloudwatchClient;
170-
"lib/aws/ecsClient": typeof lib_aws_ecsClient;
171+
"lib/aws/credentials": typeof lib_aws_credentials;
171172
"lib/aws/s3Client": typeof lib_aws_s3Client;
172173
"lib/bedrockGate": typeof lib_bedrockGate;
173174
"lib/cloudFormationGenerator": typeof lib_cloudFormationGenerator;
174175
"lib/dynamicModelSwitching": typeof lib_dynamicModelSwitching;
175176
"lib/fileGenerators": typeof lib_fileGenerators;
177+
"lib/iterativeLoop": typeof lib_iterativeLoop;
178+
"lib/jsonUtils": typeof lib_jsonUtils;
176179
"lib/memoryStore": typeof lib_memoryStore;
177180
"lib/messageExecutor": typeof lib_messageExecutor;
178181
"lib/roles": typeof lib_roles;
179182
"lib/strandsTools": typeof lib_strandsTools;
180183
"lib/tierConfig": typeof lib_tierConfig;
181184
"lib/tokenBilling": typeof lib_tokenBilling;
185+
"lib/toolDispatch": typeof lib_toolDispatch;
182186
"lib/unifiedModalitySwitching": typeof lib_unifiedModalitySwitching;
183187
localModelDetector: typeof localModelDetector;
184188
maintenance: typeof maintenance;

convex/agentAsToolGenerator.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { action } from "./_generated/server";
99
import { v } from "convex/values";
1010
import { api } from "./_generated/api";
1111
import type { Id } from "./_generated/dataModel";
12+
import { escapePythonString, escapePythonTripleQuote } from "./constants";
1213

1314
/**
1415
* Generate agent-as-tool wrapper code
@@ -21,7 +22,7 @@ export const generateAgentAsTool = action( {
2122
const agent: any = await ctx.runQuery( api.agents.get, { id: args.agentId } );
2223
if ( !agent ) throw new Error( "Agent not found" );
2324

24-
const toolName: string = agent.name.replaceAll( /[^a-zA-Z0-9_]/g, '_' ).toLowerCase();
25+
const toolName: string = agent.name.replaceAll( /\W/g, '_' ).toLowerCase();
2526
const toolCode = generateToolCode( agent.name, toolName, agent.description || "", args.agentId );
2627

2728
return {
@@ -42,8 +43,9 @@ function generateToolCode(
4243
agentId: string
4344
): string {
4445
// Sanitize inputs to prevent template injection in generated Python code
45-
const sanitize = ( s: string ) => s.replaceAll( '\\', "\\\\" ).replaceAll( '"""', String.raw`\"\"\"` );
46-
const safeAgentName = sanitize( agentName );
46+
const safeAgentName = escapePythonTripleQuote(agentName);
47+
const safeDescription = escapePythonString(description || `Invoke ${agentName} agent to handle specialized tasks`);
48+
const safeAgentNameDQ = escapePythonString(agentName);
4749
return `"""
4850
Agent-as-Tool: ${safeAgentName}
4951
Auto-generated wrapper to use ${safeAgentName} as a tool in other agents.
@@ -56,11 +58,11 @@ from typing import Optional
5658
5759
@tool(
5860
name="${toolName}",
59-
description="${description || `Invoke ${agentName} agent to handle specialized tasks`}",
61+
description="${safeDescription}",
6062
parameters={
6163
"task": {
6264
"type": "string",
63-
"description": "The task or question to send to ${agentName}",
65+
"description": "The task or question to send to ${safeAgentNameDQ}",
6466
"required": True
6567
},
6668
"context": {
@@ -72,17 +74,17 @@ from typing import Optional
7274
)
7375
async def ${toolName}(task: str, context: Optional[dict] = None) -> str:
7476
"""
75-
Invoke ${agentName} agent as a tool.
77+
Invoke ${safeAgentName} agent as a tool.
7678
7779
This allows hierarchical agent architectures where one agent
7880
can delegate tasks to specialized agents.
7981
8082
Args:
81-
task: The task or question for ${agentName}
83+
task: The task or question for ${safeAgentName}
8284
context: Optional context dictionary
8385
8486
Returns:
85-
str: Response from ${agentName}
87+
str: Response from ${safeAgentName}
8688
"""
8789
try:
8890
# Get platform API endpoint from environment
@@ -139,7 +141,7 @@ export const generateCoordinatorAgent = action( {
139141
// Generate tool wrappers for each agent
140142
const agentTools: Array<{ name: string; agentId: string; agentName: string; description: string }> = agents.map( ( agent: any ) => {
141143
if ( !agent ) return null;
142-
const toolName: string = agent.name.replaceAll( /[\W]/g, '_' ).toLowerCase();
144+
const toolName: string = agent.name.replaceAll( /\W/g, '_' ).toLowerCase();
143145
return {
144146
name: toolName,
145147
agentId: agent._id,
@@ -277,7 +279,7 @@ export const linkAgentsForCoordination = action( {
277279
const child: any = await ctx.runQuery( api.agents.get, { id: childId } );
278280
if ( !child ) return null;
279281

280-
const toolName: string = child.name.replaceAll( /[\W]/g, '_' ).toLowerCase();
282+
const toolName: string = child.name.replaceAll( /\W/g, '_' ).toLowerCase();
281283
return {
282284
name: toolName,
283285
type: "agent_tool",

0 commit comments

Comments
 (0)