Refactor: Clean up obsolete files and organize codebase structure

This commit removes deprecated modules and reorganizes code into logical directories:

Deleted files (superseded by newer systems):
- claude_code_server.py (replaced by agent-sdk direct integration)
- heartbeat.py (superseded by scheduled_tasks.py)
- pulse_brain.py (unused in production)
- config/pulse_brain_config.py (obsolete config)

Created directory structure:
- examples/ (7 example files: example_*.py, demo_*.py)
- tests/ (5 test files: test_*.py)

Updated imports:
- agent.py: Removed heartbeat module and all enable_heartbeat logic
- bot_runner.py: Removed heartbeat parameter from Agent initialization
- llm_interface.py: Updated deprecated claude_code_server message

Preserved essential files:
- hooks.py (for future use)
- adapters/skill_integration.py (for future use)
- All Google integration tools (Gmail, Calendar, Contacts)
- GLM provider code (backward compatibility)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 09:57:39 -07:00
parent f018800d94
commit a8665d8c72
26 changed files with 1068 additions and 1067 deletions

View File

@@ -0,0 +1,174 @@
"""
Example: Bot runner with local skills support.
This demonstrates how to use local skills from .claude/skills/
in your bot, allowing users to invoke them from Slack/Telegram.
"""
import asyncio
from adapters.base import AdapterConfig, InboundMessage
from adapters.runtime import AdapterRuntime
from adapters.skill_integration import SkillInvoker
from adapters.slack.adapter import SlackAdapter
from adapters.telegram.adapter import TelegramAdapter
from agent import Agent
def create_skill_preprocessor(
skill_invoker: SkillInvoker, agent: Agent
) -> callable:
"""
Preprocessor that allows invoking skills via /skill-name syntax.
Example messages:
"/adapter-dev create Discord adapter"
"/help"
"/status check health of all adapters"
"""
def preprocessor(
message: InboundMessage,
) -> InboundMessage:
text = message.text.strip()
if not text.startswith("/"):
return message
parts = text.split(maxsplit=1)
skill_name = parts[0][1:]
args = parts[1] if len(parts) > 1 else ""
available_skills = skill_invoker.list_available_skills()
if skill_name in available_skills:
print(
f"[Skills] Invoking /{skill_name} "
f"with args: {args}"
)
skill_info = skill_invoker.get_skill_info(skill_name)
if skill_info:
skill_body = skill_info.get("body", "")
skill_context = skill_body.replace(
"$ARGUMENTS", args,
)
arg_parts = args.split() if args else []
for i, arg in enumerate(arg_parts):
skill_context = skill_context.replace(
f"${i}", arg,
)
message.text = skill_context
message.metadata["skill_invoked"] = skill_name
print(f"[Skills] Skill /{skill_name} loaded")
else:
message.text = (
f"Error: Could not load skill '{skill_name}'"
)
elif skill_name in ["help", "skills"]:
skills_list = "\n".join(
f" - /{s}" for s in available_skills
)
message.text = (
f"Available skills:\n{skills_list}\n\n"
f"Use /skill-name to invoke."
)
message.metadata["builtin_command"] = True
return message
return preprocessor
def create_skill_postprocessor() -> callable:
"""Postprocessor that adds skill metadata to responses."""
def postprocessor(
response: str, original: InboundMessage,
) -> str:
if original.metadata.get("skill_invoked"):
skill_name = original.metadata["skill_invoked"]
response += f"\n\n_[Powered by /{skill_name}]_"
return response
return postprocessor
async def main() -> None:
print("=" * 60)
print("Ajarbot with Local Skills")
print("=" * 60)
# 1. Create agent
agent = Agent(
provider="claude",
workspace_dir="./memory_workspace",
enable_heartbeat=False,
)
# 2. Initialize skill system
skill_invoker = SkillInvoker()
print("\n[Skills] Available local skills:")
for skill in skill_invoker.list_available_skills():
info = skill_invoker.get_skill_info(skill)
desc = (
info.get("description", "No description")
if info
else "Unknown"
)
print(f" - /{skill} - {desc}")
# 3. Create runtime with skill support
runtime = AdapterRuntime(agent)
runtime.add_preprocessor(
create_skill_preprocessor(skill_invoker, agent),
)
runtime.add_postprocessor(create_skill_postprocessor())
# 4. Add adapters
slack_adapter = SlackAdapter(AdapterConfig(
platform="slack",
enabled=True,
credentials={
"bot_token": "xoxb-YOUR-TOKEN",
"app_token": "xapp-YOUR-TOKEN",
},
))
runtime.add_adapter(slack_adapter)
telegram_adapter = TelegramAdapter(AdapterConfig(
platform="telegram",
enabled=True,
credentials={"bot_token": "YOUR-TELEGRAM-TOKEN"},
))
runtime.add_adapter(telegram_adapter)
print("\n[Setup] Bot configured with skill support")
print("\nUsers can now invoke skills from Slack/Telegram:")
print(" Example: '/adapter-dev create Discord adapter'")
print(" Example: '/skills' (list available skills)")
# 5. Start runtime
await runtime.start()
print("\n" + "=" * 60)
print("Bot is running! Press Ctrl+C to stop.")
print("=" * 60 + "\n")
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("\n[Shutdown] Stopping...")
finally:
await runtime.stop()
if __name__ == "__main__":
asyncio.run(main())