- 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.
36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
import os
|
|
from tools.workspace import load_persona_files
|
|
|
|
# Cache: built once per warm session
|
|
_system_prompt: str | None = None
|
|
|
|
|
|
def build_system_prompt() -> str:
|
|
"""Build system prompt from S3 workspace files (cached for warm session)."""
|
|
global _system_prompt
|
|
if _system_prompt is not None:
|
|
return _system_prompt
|
|
|
|
files = load_persona_files()
|
|
parts = []
|
|
|
|
# Inject persona files in order
|
|
for fname in ['SOUL.md', 'AGENTS.md', 'IDENTITY.md', 'USER.md']:
|
|
content = files.get(fname, '')
|
|
if content:
|
|
parts.append(f"## {fname}\n{content}")
|
|
|
|
# Runtime metadata block
|
|
parts.append(f"""## Runtime
|
|
Runtime: agent-claw | host=AgentCore | model=bedrock-claude-sonnet | channel=telegram
|
|
Current date/time is provided by the system. Timezone: America/Chicago.""")
|
|
|
|
_system_prompt = '\n\n---\n\n'.join(parts)
|
|
return _system_prompt
|
|
|
|
|
|
def invalidate_prompt() -> None:
|
|
"""Force rebuild of system prompt on next invocation (call after workspace write)."""
|
|
global _system_prompt
|
|
_system_prompt = None
|