daniel
42dbdcde9e
feat: factbase-cloud integration — knowledge_agent subagent with M2M auth
2026-05-15 23:32:23 -05:00
daniel
ed6577ccf9
feat: billing tags on CDK stack + inference profile creation script
2026-05-15 20:35:02 -05:00
daniel
4f17bbd2c3
fix: intercept [HEARTBEAT] prompt, suppress chatty non-urgent responses
2026-05-15 18:34:14 -05:00
daniel
e00702164d
refactor: slim system prompt — SOUL.md+STATUS.md only, fix duplicate time injection
2026-05-15 16:42:27 -05:00
daniel
05fee423f2
feat: dynamic subagent loading from SSM
2026-05-15 15:19:08 -05:00
daniel
85efb082f7
fix: unconditional system prompt for call_aws availability
2026-05-15 11:49:03 -05:00
daniel
40f9712c54
fix: remove explicit MCPClient.start() - Strands calls it internally
2026-05-15 11:26:01 -05:00
daniel
ebd5a57ece
fix: pass aws_service=aws-mcp to aws_iam_streamablehttp_client
2026-05-15 10:32:32 -05:00
daniel
9c09dce519
deps: add mcp-proxy-for-aws to runtime dependencies
2026-05-15 10:28:51 -05:00
daniel
0eff46126f
Wire AWS MCP Server via mcp-proxy-for-aws
2026-05-15 10:19:44 -05:00
daniel
266231d070
Add native boto3 AWS tools, remove broken AWS MCP client
2026-05-15 10:03:56 -05:00
daniel
17b1536dae
fix: move MCPClient imports inside try block, add TOOLS.md placeholder
2026-05-15 09:29:07 -05:00
daniel
add8c6c988
fix: add missing MCPClient/streamablehttp_client imports; fix EXECUTION_ROLE_ARN to actual AgentCore role
2026-05-15 09:14:33 -05:00
daniel
88ed337938
Add AWS MCP Server integration + IAM self-modify with approval gate
...
- CDK: add compute/build, broad read-only, IAM self-modify (scoped to own role),
IAM policy management, and SSM read permissions to runtime1Role
- config.py: load /agent-claw/aws-mcp-url from SSM at cold start
- main.py: connect to AWS MCP Server with SigV4 auth (_AwsMcpSigV4Auth);
add request_iam_permission and apply_iam_permission tools
- agentcore.json: add EXECUTION_ROLE_ARN env var
2026-05-15 08:56:06 -05:00
daniel
68aad4fb71
Read model-id from /agent-claw/model-id SSM param and pass to BedrockModel
2026-05-15 07:00:23 -05:00
daniel
f31d732cb9
Read model-id from SSM and pass to BedrockModel in main.py
2026-05-15 06:58:54 -05:00
daniel
62862f00f0
Make agent and compaction model IDs configurable via SSM
2026-05-14 18:27:35 -05:00
daniel
bdd334b6fb
feat: add user-configurable MCP connections
...
- manage_mcp_connection tool: add/remove/enable/disable/list MCP servers
- mcp_loader: dynamic connection with OAuth/bearer/none auth, token caching
- Secrets stored in SSM, never in DynamoDB
- MCP clients loaded per-session and cleaned up in finally block
2026-05-13 21:55:01 -05:00
daniel
74f74ef877
refactor: migrate Secrets Manager secrets to SSM Parameter Store (free tier)
2026-05-13 12:55:16 -05:00
daniel
3a34e61479
feat: add windowed session history + LTM extraction/retrieval
...
- New memory_manager.py with:
- check_and_compact: runs compaction on flagged sessions (extracts LTM via
Claude Haiku, stores as AgentCore Memory event, deletes old events)
- check_window_and_flag: sets DynamoDB flag when session > 100 events
- load_ltm: retrieves LTM extractions and formats as system prompt block
- Wired into main.py:
- Compaction runs before session_manager creation (trims old events)
- LTM block injected into system prompt
- Window check runs after session close
- SESSION_WINDOW_SIZE = 100 (named constant)
- Compaction is idempotent (uses event timestamps as cursor)
- LTM retrieval failure is non-fatal (logs and continues)
2026-05-13 11:57:50 -05:00
daniel
d217842917
refactor: remove MEMORY.md from prompt, add AgentCore memory instructions
2026-05-13 11:48:53 -05:00
daniel
3cc90550b5
feat: add Telegram file attachment support (inbound + outbound)
...
Inbound:
- tg-ingest detects document/photo/audio/video/voice attachments
- Downloads files via Telegram Bot API (getFile + download)
- Inlines small text files (<50KB) directly in the prompt
- Stores binary/large files to S3 (attachments/{chat_id}/{update_id}/{filename})
- agent-runner appends file context to the AgentCore prompt
Outbound:
- New send_file tool for the agent to send documents back to users
- TelegramAdapter.send_document uses multipart/form-data POST
- CDK grants tg-ingest S3 write access and passes bucket name env var
2026-05-13 05:34:33 -05:00
daniel
eba4f7db25
fix: align run_code with AWS docs pattern (invoke+executeCode, not execute_code wrapper)
2026-05-12 15:26:01 -05:00
daniel
9253d5046f
feat: re-enable code interpreter tool (lazy code_session, no module-level init)
2026-05-12 15:05:26 -05:00
daniel
138f9224c3
fix: use sender from_id as actor_id in groups, not group chat_id
2026-05-12 14:17:02 -05:00
daniel
9d3a93a998
feat: capture message_thread_id for Telegram topic routing
2026-05-12 14:05:00 -05:00
daniel
3a49dadb69
Inject live datetime into system prompt per invocation with relative-time instruction
2026-05-09 14:56:25 -05:00
daniel
c317d948b1
Migrate primary to labeled path, remove all flat-path fallback logic
2026-05-09 14:20:24 -05:00
daniel
aaecbcfa02
Fix: list_google_accounts also shows flat primary secret
2026-05-09 14:17:53 -05:00
daniel
bf89f7255a
Fix: always load flat secret as primary regardless of labeled secrets
2026-05-09 14:14:38 -05:00
daniel
ac260e4314
Add remove_google_account tool
2026-05-09 13:49:01 -05:00
daniel
6e04d8511c
fix: two-step DynamoDB update for google_accounts; live SM lookup in list_google_accounts
2026-05-09 13:32:36 -05:00
daniel
38d828ef74
Multi-account Google support with user labels
2026-05-09 11:21:37 -05:00
daniel
01b258579b
Phase 3: proactive heartbeat — EventBridge 30min rule, heartbeat-runner Lambda, HEARTBEAT_OK suppression
2026-05-08 20:14:16 -05:00
daniel
eddbd98153
Fix: use build(credentials=creds) instead of creds.authorize() for google-auth compatibility; add traceback logging
2026-05-08 19:57:35 -05:00
daniel
9b56aa83df
Fix Google OAuth: explicit IAM policy + strip OIDC scopes from credentials
2026-05-08 16:57:40 -05:00
daniel
d68ddab8a2
OAuth callback: send Telegram confirmation message after Google auth
2026-05-08 16:29:05 -05:00
daniel
633ad03db0
Fix naive/aware datetime comparison: strip tz from expiry for google-auth
2026-05-08 16:05:45 -05:00
daniel
8a25eb2d5a
Fix: pass expiry to Credentials so auto-refresh fires when token expired
2026-05-08 16:03:09 -05:00
daniel
9d21d5d2e5
Fix: import main in _actor_id() causes app.run() hang — use module-level var instead
2026-05-08 11:32:21 -05:00
daniel
54902cca8d
Remove AgentCoreCodeInterpreter import+init: port 8080 conflict blocks event loop
2026-05-08 11:27:32 -05:00
daniel
2f15dd2af3
Remove code_interpreter from base_tools: port 8080 conflict hangs warm containers
2026-05-08 11:23:02 -05:00
daniel
f4444cbd22
Fix: pass only authorized http to build(), not credentials, so timeout applies to API calls
2026-05-08 11:17:38 -05:00
daniel
350ce231a4
embed workspace-mcp as direct dependency, simplify google credential loading
...
- Add workspace-mcp >= 1.20.0 to pyproject.toml (pulls google-api-python-client etc. transitively)
- Remove redundant google-api-python-client/google-auth/google-auth-httplib2 direct deps
- Rewrite google_workspace.py: single Secrets Manager call per tool (client_id/client_secret
are already in the credentials secret stored by oauth-handler, no separate oauth-client secret needed)
- Mirror workspace-mcp output format for list_calendars and get_calendar_events
- Add body_format param to get_gmail_message (text/html/raw) matching workspace-mcp API
- Update uv.lock
2026-05-08 11:12:06 -05:00
daniel
245c2d64f5
Add debug logging to google_workspace tools
2026-05-08 10:56:29 -05:00
daniel
6d0464ea07
Add httplib2 15s timeout + cache_discovery=False to prevent hangs
2026-05-08 10:53:19 -05:00
daniel
25cba295b0
Update uv.lock to include google-api-python-client and deps
2026-05-08 10:49:11 -05:00
daniel
ad594f6797
Add direct Google Calendar/Gmail tools, remove workspace_mcp
2026-05-08 10:37:31 -05:00
daniel
943cf26d77
workspace-mcp: strip /workspace prefix for API GW proxy route
2026-05-08 10:27:46 -05:00
daniel
647cb516db
Route workspace-mcp through API Gateway to bypass SCP Lambda URL block
2026-05-08 10:24:37 -05:00
daniel
eaf19fa9c5
Add debug logging for google_email and workspace_mcp URL
2026-05-08 10:17:08 -05:00
daniel
700e9af2b8
Fix OAUTH_START_URL: use 'or' fallback in case env var is empty string
2026-05-08 09:52:01 -05:00
daniel
9bf6461e1b
Disable extended thinking: causes blank responses via streaming retry
2026-05-08 09:44:42 -05:00
daniel
f90171cb43
test-bot: use env vars for credentials when available
2026-05-08 09:38:20 -05:00
daniel
c3432649c0
Add deploy-agentcore.sh: SSO creds + staging sync before agentcore deploy
2026-05-08 09:31:02 -05:00
daniel
b728356fe4
Hardcode OAUTH_START_URL fallback (env var not propagating to runtime)
2026-05-08 09:23:23 -05:00
daniel
4e90440011
Hardcode scheduler Lambda ARN fallback (env var not propagating)
2026-05-07 23:31:11 -05:00
daniel
58ed60f7b7
Add EventBridge scheduling: schedule_reminder, list_reminders, cancel_reminder
2026-05-07 23:24:48 -05:00
daniel
825294d433
Inject current datetime into system prompt on every request
2026-05-07 23:21:05 -05:00
daniel
0a0e26ccd2
Enable extended thinking: budget_tokens=2000
2026-05-07 23:18:48 -05:00
daniel
b919a13c76
Fix enrolled_services key mapping in agent-runner payload
2026-05-07 19:29:50 -05:00
daniel
ce95cf4c12
Remove send_message @tool def: was causing session-history duplicates
2026-05-07 19:26:23 -05:00
daniel
08ad66a732
Log Telegram API response message_id to find duplicate source
2026-05-07 19:22:40 -05:00
daniel
fa74ea784f
Remove mid-stream flush on newlines: prevents split multi-turn responses
2026-05-07 19:13:02 -05:00
daniel
fd479b8c00
Suppress exceptions in generator to prevent AgentCore retry duplicates
2026-05-07 19:09:46 -05:00
daniel
60573c360f
Switch to sync entrypoint + callback delivery: eliminates AgentCore retry duplicates
2026-05-07 19:07:30 -05:00
daniel
bbd9a99645
Fix duplicate: remove event.data fallback, only use contentBlockDelta.delta.text
2026-05-07 19:01:36 -05:00
daniel
d44fd788f9
Fix broken send_telegram_direct: restore missing data= line
2026-05-07 18:47:16 -05:00
daniel
e35599b522
Add stack trace logging to track duplicate send source
2026-05-07 18:43:56 -05:00
daniel
b0b641b4c8
Add in-process dedup to prevent AgentCore retry duplicates
2026-05-07 18:38:55 -05:00
daniel
6098f4766a
Fix Bedrock read timeout causing retry → duplicate messages
2026-05-07 18:31:44 -05:00
daniel
83b937c20e
Remove fallback adapter.send() — streaming consumer handles delivery
2026-05-07 18:17:48 -05:00
daniel
89d0819189
Add logging to streaming path in agent-runner
2026-05-07 18:12:31 -05:00
daniel
ae5e0df884
Remove send_message tool: let harness stream text deltas to Telegram
2026-05-07 17:03:34 -05:00
daniel
04c0aeeb8a
test-bot: capture send_message tool calls in output
2026-05-07 16:53:15 -05:00
daniel
d773985191
Restore send_message in base_tools (tool-based delivery works, streaming is fallback)
2026-05-07 16:52:12 -05:00
daniel
7b7ad578c0
Guard isinstance(event, dict) in SSE parser
2026-05-07 16:47:24 -05:00
daniel
beb8dfc969
Fix SSE parsing: read data: prefix + contentBlockDelta.delta.text
2026-05-07 16:45:58 -05:00
daniel
cc3b448291
Fix agent-runner: 600s read timeout on bedrock-agentcore streaming
2026-05-07 16:42:49 -05:00
daniel
6adec991da
Wire streaming: agent-runner processes chunks, remove send_message tool
2026-05-07 16:32:02 -05:00
daniel
40a942b506
streaming: switch to stream_async + iter_chunks response drain
2026-05-07 16:27:26 -05:00
daniel
7f7f555983
Fix send_message docstring: remove unicode dashes that broke tool spec
2026-05-07 15:15:41 -05:00
daniel
b69fdd479a
Prompt send_message to fire incrementally instead of buffering
2026-05-07 14:54:21 -05:00
daniel
0951d2be31
Fix workspace bucket fallback + typing error logging
2026-05-07 09:35:09 -05:00
daniel
116d79ead5
Add WORKSPACE_BUCKET_NAME, TELEGRAM_BOT_TOKEN_SECRET_ARN, BRAVE_API_KEY_SECRET_ARN to agentcore env
2026-05-07 09:27:28 -05:00
daniel
92c87222e8
multi-tenant phase 3: per-user Home Assistant + enrolled services
...
- tools/home_assistant.py: remove hardcoded URL/token; read from per-user
config injected via set_ha_config() at invocation time; return helpful
enrollment prompt when HA not configured
- main.py: inject HA config from user_profile.services at startup; add
manage_service tool (enroll/remove/list) that persists to DynamoDB;
show enrolled services in user context; add USERS_TABLE_NAME env var
- agent-runner/handler.py: pass services dict from DDB user record in
user_profile payload; initialize services={} for new users
- cdk/lib/agent-claw-stack.ts: grant usersTable read/write to runtime1Role
so manage_service tool can update user records
- agentclaw/agentcore/agentcore.json: add USERS_TABLE_NAME env var
2026-05-07 09:10:39 -05:00
daniel
4f551ce069
Fix kiro mcp.json: remove invalid factbase server ref
2026-05-07 09:01:43 -05:00
daniel
c54e9b1b22
Add kiro config (.kiro steering + settings)
2026-05-07 03:33:02 -05:00
daniel
b1056beaa9
Phase 2: wire X-Actor-Id credential loading into workspace-mcp handler.py
...
Replace cold-start single-user credential loading with per-request
multi-tenant loading via ASGI middleware:
- _setup_shared_environment(): loads OAuth client creds once at cold start
- _ActorCredentialsMiddleware: reads x-actor-id header per request,
fetches per-user Google credentials from Secrets Manager
(agent-claw/google-credentials/{actor_id}), writes to /tmp,
sets USER_GOOGLE_EMAIL env var
- 5-minute in-memory cache to avoid redundant Secrets Manager calls
2026-05-06 21:48:05 -05:00
daniel
ac5bd78d5a
multi-tenant Phase 2: per-user Google OAuth
...
- workspace-mcp: add proxy.py (port 8080) that reads X-Actor-Id header,
fetches per-user Google credentials from Secrets Manager, writes creds
file, sets USER_GOOGLE_EMAIL, proxies to workspace-mcp on port 8081
- workspace-mcp: update bootstrap to start workspace-mcp on 8081 + proxy on 8080
- workspace-mcp: update Dockerfile to include proxy.py
- oauth-handler Lambda: new Lambda with /oauth/start + /oauth/callback
routes; exchanges Google auth code, stores tokens in Secrets Manager
at agent-claw/google-credentials/{actor_id_safe}, updates DynamoDB
- CDK: add OAuthHandler Lambda + GET /oauth/start + /oauth/callback routes
- CDK: remove shared google-workspace-credentials secret; add per-user
secret IAM grants (agent-claw/google-credentials/*) for workspace-mcp
role, runtime1 role, and oauth-handler role
- CDK: output OAuthStartUrl + OAuthRedirectUri
- agent-runner: pass google_email in user_profile payload
- main.py: pass actor_id as X-Actor-Id header in workspace-mcp MCP calls;
skip workspace-mcp if user has no google_email; add connect_google_account
tool that generates OAuth URL for the current user
- main.py: include google_email in user_context for system prompt
- agentcore.json: add OAUTH_START_URL env var for agent runtime
2026-05-06 21:42:33 -05:00
daniel
841e729b18
Phase 1 cleanup: onboarding flow, per-user S3 MEMORY.md, seed script
2026-05-06 21:11:07 -05:00
daniel
893c110729
multi-tenant Phase 1: user registry + per-user memory
...
- CDK: add agent-claw-users DynamoDB table (actor_id PK, RETAIN policy)
- CDK: grant agent-runner read/write on users table; add USERS_TABLE_NAME env
- CDK: fix cdk.json app field (was object, must be command string)
- CDK: add UsersTableName output
- agent-runner: get_or_create_user() auto-registers users on first contact
(stores display_name, telegram_username, created_at, allowed)
- agent-runner: pass user_profile in AgentCore payload
- prompt_builder: split base prompt (cached) from per-user context (injected per-call)
removes USER.md/MEMORY.md from shared load; user name/username injected dynamically
- main.py: extract user_profile from payload, build user_context string for prompt
2026-05-06 20:36:22 -05:00
daniel
732b00fb66
agent-claw: automated task changes
2026-05-06 18:55:16 -05:00
daniel
38905bb1e9
Phase 0: CDK stack + Lambdas + AgentCore Runtime 1 scaffold
...
- 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.
2026-05-04 09:00:23 -05:00
daniel
6ee2890831
Add final architecture design doc
2026-05-04 08:43:08 -05:00
daniel
0369a74ac1
Initial research: OpenClaw on AgentCore architecture
...
- Architecture comparison (OpenClaw daemon vs AgentCore serverless)
- Component compatibility analysis
- Fargate analysis
- AgentCore rebuild plan (Telegram, zero always-on compute)
- Memory strategy: AgentCore Memory + factbase as structured KB
- Serverless relay patterns per channel
- All open questions resolved
- OpenClaw feature delta March→May 2026
- Build phases and cost estimates
2026-05-04 08:28:52 -05:00