mirror of https://github.com/kortix-ai/suna.git
fix agent installation
This commit is contained in:
parent
46aa1836d0
commit
5d56e08247
|
@ -139,6 +139,8 @@ def _extract_custom_agent_config(agent_data: Dict[str, Any], version_data: Optio
|
|||
return config
|
||||
|
||||
logger.warning(f"No version data found for custom agent {agent_id}, creating default configuration")
|
||||
logger.debug(f"Agent data keys: {list(agent_data.keys())}")
|
||||
logger.debug(f"Agent current_version_id: {agent_data.get('current_version_id')}")
|
||||
|
||||
fallback_config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
|
|
|
@ -312,19 +312,35 @@ class JsonImportService:
|
|||
agent_config: Dict[str, Any],
|
||||
system_prompt: str
|
||||
) -> None:
|
||||
|
||||
from ..handlers.versioning.version_service import VersionService
|
||||
version_service = VersionService()
|
||||
|
||||
await version_service.create_version(
|
||||
agent_id=agent_id,
|
||||
user_id=account_id,
|
||||
system_prompt=system_prompt,
|
||||
agentpress_tools=agent_config['tools']['agentpress'],
|
||||
configured_mcps=agent_config['tools']['mcp'],
|
||||
custom_mcps=agent_config['tools']['custom_mcp'],
|
||||
change_description="Initial version from JSON import"
|
||||
)
|
||||
try:
|
||||
logger.debug(f"Creating initial version for JSON imported agent {agent_id} with system_prompt: {system_prompt[:100]}...")
|
||||
|
||||
from .versioning.version_service import VersionService
|
||||
version_service = VersionService()
|
||||
|
||||
version = await version_service.create_version(
|
||||
agent_id=agent_id,
|
||||
user_id=account_id,
|
||||
system_prompt=system_prompt,
|
||||
agentpress_tools=agent_config['tools']['agentpress'],
|
||||
configured_mcps=agent_config['tools']['mcp'],
|
||||
custom_mcps=agent_config['tools']['custom_mcp'],
|
||||
change_description="Initial version from JSON import"
|
||||
)
|
||||
|
||||
logger.info(f"Successfully created initial version {version.version_id} for JSON imported agent {agent_id}")
|
||||
|
||||
# Verify the agent was updated with current_version_id
|
||||
client = await self._db.client
|
||||
agent_check = await client.table('agents').select('current_version_id').eq('agent_id', agent_id).execute()
|
||||
if agent_check.data and agent_check.data[0].get('current_version_id'):
|
||||
logger.debug(f"Agent {agent_id} current_version_id updated to: {agent_check.data[0]['current_version_id']}")
|
||||
else:
|
||||
logger.error(f"Agent {agent_id} current_version_id was not updated after version creation!")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create initial version for JSON imported agent {agent_id}: {e}", exc_info=True)
|
||||
raise # Re-raise the exception to ensure import fails if version creation fails
|
||||
|
||||
@router.get("/agents/{agent_id}/export")
|
||||
async def export_agent(agent_id: str, user_id: str = Depends(get_current_user_id_from_jwt)):
|
||||
|
|
|
@ -247,6 +247,7 @@ class AgentService:
|
|||
'version_number': row['version_number'],
|
||||
'version_name': row['version_name'],
|
||||
'system_prompt': config.get('system_prompt', ''),
|
||||
'model': config.get('model'),
|
||||
'configured_mcps': tools.get('mcp', []),
|
||||
'custom_mcps': tools.get('custom_mcp', []),
|
||||
'agentpress_tools': tools.get('agentpress', {}),
|
||||
|
@ -254,6 +255,7 @@ class AgentService:
|
|||
'created_at': row.get('created_at'),
|
||||
'updated_at': row.get('updated_at') or row.get('created_at'),
|
||||
'created_by': row.get('created_by'),
|
||||
'config': config # Include the full config for compatibility
|
||||
}
|
||||
version_map[row['agent_id']] = version_dict
|
||||
except Exception as e:
|
||||
|
|
|
@ -19,8 +19,9 @@ class ModelManager:
|
|||
logger.debug(f"Resolved model '{model_id}' to '{resolved}'")
|
||||
return resolved
|
||||
|
||||
all_aliases = list(self.registry._aliases.keys())
|
||||
logger.warning(f"Could not resolve model ID: '{model_id}'. Available aliases: {all_aliases[:10]}...")
|
||||
# Silently return the original model_id if we can't resolve it
|
||||
# This avoids spamming logs with warnings for unknown models
|
||||
logger.debug(f"Could not resolve model ID: '{model_id}', returning as-is")
|
||||
return model_id
|
||||
|
||||
def validate_model(self, model_id: str) -> Tuple[bool, str]:
|
||||
|
|
|
@ -129,7 +129,8 @@ def get_model_pricing(model: str) -> tuple[float, float] | None:
|
|||
else:
|
||||
logger.debug(f"No pricing for model_to_try='{model_to_try}' (model_obj: {model_obj is not None}, has_pricing: {model_obj.pricing is not None if model_obj else False})")
|
||||
|
||||
logger.warning(f"No pricing found for model '{model}' (resolved: '{resolved_model}')")
|
||||
# Silently return None for unknown models to avoid log spam
|
||||
logger.debug(f"No pricing found for model '{model}' (resolved: '{resolved_model}')")
|
||||
return None
|
||||
|
||||
|
||||
|
@ -788,11 +789,11 @@ def calculate_token_cost(prompt_tokens: int, completion_tokens: int, model: str)
|
|||
continue
|
||||
|
||||
if message_cost is None:
|
||||
logger.warning(f"Could not get pricing for model {model} (resolved: {resolved_model}), returning 0 cost")
|
||||
logger.debug(f"Could not get pricing for model {model} (resolved: {resolved_model}), returning 0 cost")
|
||||
return 0.0
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Could not get pricing for model {model} (resolved: {resolved_model}): {str(e)}, returning 0 cost")
|
||||
logger.debug(f"Could not get pricing for model {model} (resolved: {resolved_model}): {str(e)}, returning 0 cost")
|
||||
return 0.0
|
||||
|
||||
# Apply the TOKEN_PRICE_MULTIPLIER
|
||||
|
|
|
@ -390,9 +390,12 @@ class InstallationService:
|
|||
agentpress_tools = tools.get('agentpress', {})
|
||||
model = agent_config.get('model')
|
||||
|
||||
from agent.versioning.version_service import get_version_service
|
||||
logger.debug(f"Creating initial version for agent {agent_id} with system_prompt: {system_prompt[:100]}...")
|
||||
logger.debug(f"Agent config tools: agentpress={len(agentpress_tools)}, mcp={len(configured_mcps)}, custom_mcp={len(custom_mcps)}")
|
||||
|
||||
from agent.handlers.versioning.version_service import get_version_service
|
||||
version_service = await get_version_service()
|
||||
await version_service.create_version(
|
||||
version = await version_service.create_version(
|
||||
agent_id=agent_id,
|
||||
user_id=user_id,
|
||||
system_prompt=system_prompt,
|
||||
|
@ -404,10 +407,19 @@ class InstallationService:
|
|||
change_description="Initial version from template"
|
||||
)
|
||||
|
||||
logger.debug(f"Created initial version for agent {agent_id}")
|
||||
logger.info(f"Successfully created initial version {version.version_id} for agent {agent_id}")
|
||||
|
||||
# Verify the agent was updated with current_version_id
|
||||
client = await self._db.client
|
||||
agent_check = await client.table('agents').select('current_version_id').eq('agent_id', agent_id).execute()
|
||||
if agent_check.data and agent_check.data[0].get('current_version_id'):
|
||||
logger.debug(f"Agent {agent_id} current_version_id updated to: {agent_check.data[0]['current_version_id']}")
|
||||
else:
|
||||
logger.error(f"Agent {agent_id} current_version_id was not updated after version creation!")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to create initial version for agent {agent_id}: {e}")
|
||||
logger.error(f"Failed to create initial version for agent {agent_id}: {e}", exc_info=True)
|
||||
raise # Re-raise the exception to ensure installation fails if version creation fails
|
||||
|
||||
async def _restore_workflows(self, agent_id: str, template_config: Dict[str, Any]) -> None:
|
||||
workflows = template_config.get('workflows', [])
|
||||
|
|
|
@ -265,6 +265,13 @@ export function ThreadComponent({ projectId, threadId, compact = false, configur
|
|||
if (message.type === 'tool') {
|
||||
setAutoOpenedPanel(false);
|
||||
}
|
||||
|
||||
// Auto-scroll to bottom (top: 0 in flex-col-reverse) when new messages arrive
|
||||
setTimeout(() => {
|
||||
if (scrollContainerRef.current) {
|
||||
scrollContainerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
[setMessages, setAutoOpenedPanel],
|
||||
);
|
||||
|
@ -354,6 +361,13 @@ export function ThreadComponent({ projectId, threadId, compact = false, configur
|
|||
setMessages((prev) => [...prev, optimisticUserMessage]);
|
||||
setNewMessage('');
|
||||
|
||||
// Auto-scroll to bottom when user sends a message
|
||||
setTimeout(() => {
|
||||
if (scrollContainerRef.current) {
|
||||
scrollContainerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
}, 100);
|
||||
|
||||
try {
|
||||
const messagePromise = addUserMessageMutation.mutateAsync({
|
||||
threadId,
|
||||
|
@ -819,7 +833,7 @@ export function ThreadComponent({ projectId, threadId, compact = false, configur
|
|||
agentAvatar={undefined}
|
||||
agentMetadata={agent?.metadata}
|
||||
agentData={agent}
|
||||
scrollContainerRef={null}
|
||||
scrollContainerRef={scrollContainerRef}
|
||||
isPreviewMode={true}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -34,25 +34,27 @@ export const AgentLoader = () => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex py-2 items-center w-full">
|
||||
<div className="flex py-2 items-center w-full gap-3">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="h-1 w-1 rounded-full bg-primary/40 animate-pulse duration-1000" />
|
||||
<div className="h-1 w-1 rounded-full bg-primary/40 animate-pulse duration-1000 delay-150" />
|
||||
<div className="h-1 w-1 rounded-full bg-primary/40 animate-pulse duration-1000 delay-300" />
|
||||
</div>
|
||||
<AnimatePresence>
|
||||
<motion.div
|
||||
key={items[index].id}
|
||||
initial={{ y: 20, opacity: 0, filter: "blur(8px)" }}
|
||||
animate={{ y: 0, opacity: 1, filter: "blur(0px)" }}
|
||||
exit={{ y: -20, opacity: 0, filter: "blur(8px)" }}
|
||||
transition={{ ease: "easeInOut" }}
|
||||
style={{ position: "absolute" }}
|
||||
className='ml-7'
|
||||
>
|
||||
<AnimatedShinyText className='text-xs'>{items[index].content}</AnimatedShinyText>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
<div className="relative flex-1 h-7">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={items[index].id}
|
||||
initial={{ y: 10, opacity: 0, filter: "blur(4px)" }}
|
||||
animate={{ y: 0, opacity: 1, filter: "blur(0px)" }}
|
||||
exit={{ y: -10, opacity: 0, filter: "blur(4px)" }}
|
||||
transition={{ ease: "easeInOut", duration: 0.3 }}
|
||||
className="absolute left-0 top-0"
|
||||
>
|
||||
<AnimatedShinyText className='text-xs whitespace-nowrap'>{items[index].content}</AnimatedShinyText>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue