- CDK TypeScript stack (AgentClawStack): - S3 workspace bucket with BucketDeployment seed - DynamoDB session-store (actor_id → session_id, TTL) - SQS FIFO message queue (serialized per actor) - Lambda: tg-ingest (webhook validation, typing action, SQS enqueue) - Lambda: agent-runner (SQS → InvokeAgentRuntime, session management) - API Gateway HTTP: POST /telegram → tg-ingest - AgentCore Runtime 1 IAM execution role - CDK outputs: WebhookUrl, WorkspaceBucketName, Runtime1RoleArn - Runtime 1 (Python + Strands + BedrockAgentCoreApp): - main.py: entrypoint, Strands agent, tool wiring - channels/: ChannelAdapter Protocol + TelegramAdapter (decoupled) - tools/: web_search (Brave), web_fetch, read/write_workspace_file, send_message - prompt_builder.py: loads SOUL.md/AGENTS.md/USER.md from S3 (cached) - Lambdas: - tg-ingest: validate X-Telegram-Bot-Api-Secret-Token, send typing, enqueue FIFO - agent-runner: session lookup/create in DDB, bundle batched messages, InvokeAgentRuntime - workspace/: seed files (SOUL.md, AGENTS.md, USER.md, IDENTITY.md, HEARTBEAT.md) NOTE: AgentCore Runtime 1 creation via CfnResource deferred — deploy CDK first, create runtime manually with the output Role ARN, then redeploy with runtime1Arn context param.
22 lines
620 B
Python
22 lines
620 B
Python
"""Messaging tool — channel-adapter-backed send_message for the agent."""
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from channels.adapter import ChannelAdapter
|
|
|
|
# Injected by main.py before each invocation
|
|
_adapter: 'ChannelAdapter | None' = None
|
|
|
|
|
|
def set_adapter(adapter: 'ChannelAdapter') -> None:
|
|
global _adapter
|
|
_adapter = adapter
|
|
|
|
|
|
def send(text: str) -> str:
|
|
"""Send a message to the user via the active channel adapter."""
|
|
if _adapter is None:
|
|
return 'No channel adapter configured.'
|
|
msg_id = _adapter.send(text)
|
|
return f"Sent (id={msg_id})" if msg_id else 'Sent'
|