-
Notifications
You must be signed in to change notification settings - Fork 1
agents integration #112
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
base: main
Are you sure you want to change the base?
agents integration #112
Conversation
2d9d77c to
01b7cda
Compare
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/[email protected]Prefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/[email protected]"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/[email protected]"
}
}
Preview published to npm registry — try new features instantly! |
a0d183f to
cd6a5aa
Compare
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
53bd856 to
90dfd97
Compare
|
@claude rebase from main |
|
Claude finished @Paveltarno's task in 15s —— View job Task: Rebase from mainUnfortunately, I'm unable to perform rebase operations. My git capabilities are limited to basic operations like creating commits and pushing to branches, but I cannot perform branch operations like rebase, merge, or other complex git operations. To rebase this branch from main yourself: git checkout pavelta-agents-1
git fetch origin
git rebase origin/main
# Resolve any conflicts if they occur
git push --force-with-lease origin pavelta-agents-1Alternatively, you could:
|
90dfd97 to
bc02aa5
Compare
Update command descriptions to make it clear that push replaces all remote agent configurations and pull replaces all local agent files. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
d566f74 to
63df5c1
Compare
Fix TypeScript errors in CI by updating import path aliases to use the correct @/ prefix instead of @ in agent-related files. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Move ApiErrorResponse interface and formatApiError function from errors.ts to base44-client.ts to co-locate API-specific error handling with the API client code. - Moved API error types and formatting to base44-client.ts - Updated imports in agent/api.ts and entity/api.ts - Updated test imports and mocks - Auth-related errors remain in errors.ts Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
| * Standard API error response format from the Base44 backend. | ||
| * All HTTP errors from FastAPI are returned in this format. | ||
| */ | ||
| export interface ApiErrorResponse { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets move this to clients/schems.ts with a ApiErrorSchema and use optional / parse to stick to the structure of the project
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes been contemplating on where to put this
| * Formats an API error response into a human-readable string. | ||
| * Prefers `message` (human-readable) over `detail`. | ||
| */ | ||
| export function formatApiError(errorJson: unknown): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we try and catch and identify errors inside the ky client itself? and then we don't need to export this function and use it evereywhere - the base client will catch errors with this structure and throw correctly.. wdyt?
I'de say it's probably something to do in a different PR though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes good idea! as long as all errors are returned the same way from the API what you are suggesting is the correct approach
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so we can either do it here, or resolve this in another pr and remove from this one..
Let me know what you choose and we i'll open an issue if needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's do it in another PR, @claude open an issue 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @Paveltarno's task in 44s —— View job
Task: Open issue for centralizing API error handling
Todo List:
- Prepare issue content
- Attempt to create issue
Result
I'm unable to create GitHub issues directly due to permission restrictions. However, I've prepared the issue content below that you can create manually:
Title: Centralize API error handling in base ky client
Body:
## Problem
Currently, API error handling is done manually by calling `formatApiError` in every place where we make API calls. This adds boilerplate and increases the chance of inconsistent error handling across the codebase.
**Current approach:**
```typescript
try {
const response = await this.client.post(...);
return response;
} catch (error) {
throw new Error(formatApiError(error, 'operation description'));
}Proposed Solution
Move error handling logic directly into the ky client itself, so that all API errors are automatically caught, identified, and formatted consistently. This would eliminate the need to export and use formatApiError everywhere.
Benefits:
- Reduces boilerplate in API client methods
- Ensures consistent error handling across all API calls
- Centralizes error formatting logic
- Makes the codebase easier to maintain
Implementation Notes
- The base ky client should have hooks/interceptors to catch errors
- Error structure should be identified and thrown with proper formatting automatically
- The
formatApiErrorfunction would become internal to the client - All existing usages of
formatApiErrorcan be removed
Context
This was discussed in PR #112 review:
- agents integration #112 (comment)
- Reviewers agreed this should be done in a separate PR to keep changes focused
Related
- PR agents integration #112 (agents integration)
- File:
src/core/clients/base44-client.ts
**Suggested labels:** `enhancement`, `refactor`
---
| return {}; | ||
| } | ||
|
|
||
| export const agentsCommand = new Command("agents") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets move the new "agents" command to be under commands/agents/index.ts, and each file will just export it's command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general - do we need all of the schema?
We're trying to just zod-ify only things we actually use inside the CLI codebase, we don't want to verify the entire schema right now. might worth adding to AGENTS.md as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, do all the agent.json file as written as snake_case and not camelCase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so you are suggesting we type it without zod and leave the "restrictions" to agents.md?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - I want to use zod, but only type the field that we need for CLI usage, like name and stuff..
I think we will need anyway to release jsonSchemas for all of our files and this will help the AI more then CLI errors
| instructions: z.string(), | ||
| tool_configs: z.array(ToolConfigSchema).default([]), | ||
| whatsapp_greeting: z.string().nullable().optional(), | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can look at other resources schema, lets use .transform to change response into camelCase
| for (const agent of agents) { | ||
| const filePath = join(agentsDir, `${agent.name}.${CONFIG_FILE_EXTENSION}`); | ||
| await writeJsonFile(filePath, { | ||
| name: agent.name, | ||
| description: agent.description, | ||
| instructions: agent.instructions, | ||
| tool_configs: agent.tool_configs, | ||
| whatsapp_greeting: agent.whatsapp_greeting ?? null, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should use an ejs file for agent.json file?
The main benefit is that we can give the user a file with comments inside in case they want to edit it..
we do something similar with .app.json file
export function generateAppConfigContent(id: string): string {
return `// Base44 App Configuration
// This file links your local project to your Base44 app.
// Do not commit this file to version control.
{
"id": "${id}"
}
`;
}
we can have another function with corrent agents structure, but also with more context about each field.. wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure np, commented file is a good thing
| agentsDir: string, | ||
| agents: AgentConfigApiResponse[] | ||
| ): Promise<{ written: string[]; deleted: string[] }> { | ||
| const existingAgents = await readAllAgents(agentsDir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think agents is something we should get as an argument, in the command that calls this function we already do getProjectConfig which reads all the agents anyway, so lets pass it to this function instead of reading it again
|
|
||
| const toDelete = existingAgents.filter((a) => !newNames.has(a.name)); | ||
| for (const agent of toDelete) { | ||
| const filePath = join(agentsDir, `${agent.name}.${CONFIG_FILE_EXTENSION}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: might be a bug if the AI / user will start creating agent config files using JSON and not JSONC, a bit of an edge case but it might be worth to globby and check for either endings >.>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea
|
|
||
| if (!result.success) { | ||
| throw new Error( | ||
| `Invalid agent configuration in ${agentPath}: ${result.error.issues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this example needs to be fixed in AGENTS.md file,
lets change to just use .parse in line 10 and let it throw, if alternative is to just use results.error.message
| agents.length === 0 | ||
| ? "No local agents found - this will delete all remote agents" | ||
| : `Found ${agents.length} agents to push` | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to prompt the user in case of agents.length===0? we're writing "this will delete all remote agents" and then just going with it. how about a prompt and a --yes/-y flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm but didn't we say that for now we do not interrupt the push/pull in any way? because this is just an edge case in this whole conflict scenario
i suggest we either fully tackle it not at all
wdyt?
| const { written, deleted } = await runTask( | ||
| "Writing agent files", | ||
| async () => { | ||
| return await writeAgents(agentsDir, response.items); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of passing the agentsDir, on line 10 you can do
const { project, agents } = await readProjectConfig();
and just pass the list of agent to the writeAgents function
| const configDir = dirname(project.configPath); | ||
| const agentsDir = join(configDir, project.agentsDir); | ||
|
|
||
| const response = await runTask( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about call this remoteAgents?
| log.warn(`Deleted: ${result.deleted.join(", ")}`); | ||
| } | ||
|
|
||
| return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i saw that the pull command has an outroMessage, but the push command doesn't, lets align
kfirstri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work 💪
Description
This PR implements a complete agents integration system for the CLI, enabling users to define AI agents with custom instructions and tool configurations. The system provides push/pull commands to synchronize agent configurations between local JSON/JSONC files and Base44, includes comprehensive schema validation with Zod, and follows the established resource pattern used by entities and functions.
Related Issue
None
Type of Change
Changes Made
src/core/resources/agent/with schema validation, config reading/writing, and API integrationagents pushcommand that replaces all remote agent configurations on Base44agents pullcommand that fetches agents from Base44 and replaces all local agent filesagentsDirfield to project config schema (defaults to "agents")pushAgentsandfetchAgentsfor Base44 synchronizationformatApiErrorfor consistent API error formatting across resourcesTesting
npm test)Checklist
Additional Notes
Agent Configuration Format:
^[a-z0-9_]+$)Architecture Notes:
🤖 Generated by Claude | 2026-01-27 09:52 UTC