thinkwork-cli 0.13.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -14
- package/dist/{api-client-JYZXYQJR.js → api-client-4P4JZOBX.js} +1 -1
- package/dist/{chunk-Z2F6RJFR.js → chunk-4OMDWYZQ.js} +4 -5
- package/dist/{chunk-ILZKG5WV.js → chunk-AD2NIWB5.js} +434 -69
- package/dist/chunk-MWQ7RO76.js +137 -0
- package/dist/{chunk-DVPBI5HM.js → chunk-OLUQ4U2Z.js} +26 -26
- package/dist/{chunk-QOERT44A.js → chunk-YQCYD6NE.js} +57 -44
- package/dist/cli.js +4400 -16431
- package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +0 -1
- package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +0 -1
- package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +0 -14
- package/dist/{dist-es-CRV46D5B.js → dist-es-2OTNTL4N.js} +4 -4
- package/dist/{dist-es-ENBUC3JP.js → dist-es-2XVAH4BQ.js} +2 -2
- package/dist/{dist-es-DCY4IC3Y.js → dist-es-3DPDUJAH.js} +2 -2
- package/dist/{dist-es-G7PTG75M.js → dist-es-BNZTBBVC.js} +1 -1
- package/dist/{dist-es-GKDBE7E6.js → dist-es-CD2RBDAC.js} +1 -1
- package/dist/{dist-es-R7FGL2IB.js → dist-es-I4FW57PS.js} +1 -1
- package/dist/{dist-es-USORBXZ5.js → dist-es-KVFWJNDY.js} +4 -4
- package/dist/{dist-es-HY3535OI.js → dist-es-PS73DWNL.js} +2 -2
- package/dist/{dist-es-LDE437AM.js → dist-es-S3NZQFGT.js} +1 -1
- package/dist/{dist-es-G54LBMRN.js → dist-es-SGCA4P32.js} +1 -1
- package/dist/{dist-es-Q57SZXZ7.js → dist-es-WBM6J4RA.js} +2 -2
- package/dist/{dist-es-P26FWFLT.js → dist-es-ZGVADYIF.js} +8 -8
- package/dist/drizzle/0227_analyst_reader_role.sql +17 -26
- package/dist/drizzle/0230_analyst_rls.sql +28 -45
- package/dist/drizzle/0261_native_auth_control_plane.sql +7 -3
- package/dist/drizzle/0270_tool_execution_ledger.sql +115 -0
- package/dist/drizzle/0271_ontology_twin_declarations.sql +47 -0
- package/dist/drizzle/0272_identity_graph_projection_cursor.sql +23 -0
- package/dist/drizzle/0273_twin_materialization_suggestions.sql +29 -0
- package/dist/drizzle/0274_tenant_mcp_twin_keys.sql +59 -0
- package/dist/drizzle/0275_identity_bulk_rebuild_fence.sql +30 -0
- package/dist/drizzle/0276_tool_execution_ledger_allow_cascade_delete.sql +18 -0
- package/dist/drizzle/0277_knowledge_base_sources.sql +107 -0
- package/dist/drizzle/0278_kb_page_transcription.sql +55 -0
- package/dist/drizzle/0279_mcp_servers_off_plugin_provenance.sql +93 -0
- package/dist/drizzle/0280_work_item_external_refs_drop_plane_provider.sql +46 -0
- package/dist/drizzle/0281_tenant_mcp_twin_keys_expiry_suffix.sql +9 -0
- package/dist/drizzle/0282_tenant_mcp_twin_keys_grants.sql +24 -0
- package/dist/drizzle/0283_agents_agentcore_runtime_dispatch.sql +13 -0
- package/dist/drizzle/0284_user_brain_claims.sql +69 -0
- package/dist/drizzle/0285_tenant_mcp_twin_keys_trusted_subsystem.sql +30 -0
- package/dist/drizzle/0286_brain_analytics_key.sql +26 -0
- package/dist/drizzle/0287_brain_subject.sql +25 -0
- package/dist/drizzle/0288_multi_lane_identities.sql +25 -0
- package/dist/{loadSso-DJVB7BXE.js → loadSso-ETCXTR4I.js} +2 -2
- package/dist/{loadSso-JAMNA3WY.js → loadSso-UBD7KUHE.js} +2 -2
- package/dist/plugins/README.md +2 -2
- package/dist/plugins/catalog/package.json +0 -3
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +6 -3
- package/dist/plugins/catalog/src/__tests__/catalog.test.ts +21 -21
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +102 -25
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +7 -6
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -15
- package/dist/plugins/catalog/src/contracts.ts +15 -0
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -18
- package/dist/plugins/n8n/test/integrated-app-contract.test.ts +1 -1
- package/dist/plugins/twenty/package.json +2 -1
- package/dist/plugins/twenty/scripts/LAMBDA_DEPLOY.md +114 -0
- package/dist/plugins/twenty/scripts/build-lambda.sh +29 -0
- package/dist/plugins/twenty/scripts/configure-product-views.ts +195 -0
- package/dist/plugins/twenty/scripts/lambda-handler.ts +49 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/load-attachments.test.ts +38 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +145 -2
- package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +397 -151
- package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +28 -129
- package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +10 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +13 -8
- package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +222 -2
- package/dist/plugins/twenty/scripts/lib/load-attachments.ts +29 -0
- package/dist/plugins/twenty/scripts/lib/load-records.ts +160 -43
- package/dist/plugins/twenty/scripts/lib/mappers.ts +368 -152
- package/dist/plugins/twenty/scripts/lib/members-ensure.ts +43 -268
- package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +57 -0
- package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +136 -31
- package/dist/plugins/twenty/scripts/migrate-lastmile.ts +254 -152
- package/dist/plugins/twenty/scripts/provision-twenty-members.ts +44 -1
- package/dist/plugins/twenty/scripts/purge-lastmile-import.ts +178 -0
- package/dist/plugins/twenty/scripts/restructure-products.ts +312 -0
- package/dist/plugins/twenty/scripts/retag-stage-values.ts +362 -0
- package/dist/plugins/twenty/test/manifest.test.ts +2 -4
- package/dist/scripts/post-deploy.sh +79 -1
- package/dist/{signin-UGDWTGS4.js → signin-5QZNRSOO.js} +2 -2
- package/dist/{sso-oidc-Q4VXANXY.js → sso-oidc-XK673P54.js} +2 -2
- package/dist/{sts-CWLSE3GH.js → sts-OXI2UALF.js} +6 -134
- package/dist/{sts-DNZLNVOV.js → sts-SQW4NBK3.js} +6 -134
- package/dist/terraform/examples/greenfield/main.tf +233 -175
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +12 -8
- package/dist/terraform/modules/app/agentcore-admin/main.tf +47 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +39 -47
- package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +13 -66
- package/dist/terraform/modules/app/agentcore-identity/main.tf +106 -26
- package/dist/terraform/modules/app/agentcore-identity/outputs.tf +6 -6
- package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +216 -99
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +6 -9
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_workload_identity.sh +19 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/ensure_workload_identity.sh +29 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +22 -7
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +17 -46
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +65 -3
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/after.tf +15 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/before.tf +7 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-after.tf +8 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-before.tf +9 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-after.tf +3 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-before.tf +3 -0
- package/dist/terraform/modules/app/agentcore-identity/variables.tf +6 -0
- package/dist/terraform/modules/app/agentcore-memory/README.md +46 -9
- package/dist/terraform/modules/app/agentcore-memory/main.tf +27 -10
- package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +156 -24
- package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
- package/dist/terraform/modules/app/agentcore-pi/main.tf +42 -52
- package/dist/terraform/modules/app/agentcore-pi/outputs.tf +3 -3
- package/dist/terraform/modules/app/agentcore-pi/scripts/reconcile_pi_runtime.mjs +175 -0
- package/dist/terraform/modules/app/agentcore-pi/variables.tf +35 -28
- package/dist/terraform/modules/app/agentcore-platform/main.tf +68 -0
- package/dist/terraform/modules/app/agentcore-runtime/main.tf +4 -20
- package/dist/terraform/modules/app/capability-broker/main.tf +2 -2
- package/dist/terraform/modules/app/capability-broker/variables.tf +11 -0
- package/dist/terraform/modules/app/deployment-control-plane/README.md +264 -0
- package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +4 -1
- package/dist/terraform/modules/app/deployment-control-plane/main.tf +94 -0
- package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +5 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +2641 -124
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +2034 -154
- package/dist/terraform/modules/app/deployment-control-plane/variables.tf +33 -0
- package/dist/terraform/modules/app/lambda-api/auth-state.tf +72 -0
- package/dist/terraform/modules/app/lambda-api/chat-latency-observability.tf +466 -0
- package/dist/terraform/modules/app/lambda-api/dispatch-dlq.tf +55 -0
- package/dist/terraform/modules/app/lambda-api/handlers.tf +411 -723
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +262 -198
- package/dist/terraform/modules/app/lambda-api/main.tf +51 -13
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +4 -181
- package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +3 -28
- package/dist/terraform/modules/app/lambda-api/oauth-secrets.tf +1 -2
- package/dist/terraform/modules/app/lambda-api/outputs.tf +17 -45
- package/dist/terraform/modules/app/lambda-api/turn-assertion.tf +45 -0
- package/dist/terraform/modules/app/lambda-api/variables.tf +219 -126
- package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/README.md +1 -1
- package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/main.tf +18 -18
- package/dist/terraform/modules/app/sandbox-log-scrubber/README.md +11 -10
- package/dist/terraform/modules/app/sandbox-log-scrubber/main.tf +5 -5
- package/dist/terraform/modules/app/static-site/main.tf +1 -1
- package/dist/terraform/modules/app/www-dns/main.tf +9 -27
- package/dist/terraform/modules/app/www-dns/variables.tf +4 -10
- package/dist/terraform/modules/data/aurora-postgres/README.md +34 -0
- package/dist/terraform/modules/data/aurora-postgres/alarms.tf +82 -0
- package/dist/terraform/modules/data/aurora-postgres/main.tf +27 -57
- package/dist/terraform/modules/data/aurora-postgres/outputs.tf +0 -9
- package/dist/terraform/modules/data/aurora-postgres/variables.tf +41 -0
- package/dist/terraform/modules/data/s3-buckets/main.tf +5 -6
- package/dist/terraform/modules/foundation/cognito/main.tf +81 -8
- package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +24 -12
- package/dist/terraform/modules/thinkwork/README.md +5 -1
- package/dist/terraform/modules/thinkwork/main.tf +376 -374
- package/dist/terraform/modules/thinkwork/outputs.tf +12 -158
- package/dist/terraform/modules/thinkwork/variables.tf +246 -89
- package/dist/workspace-defaults/files/INSTRUCTIONS.md +9 -11
- package/dist/workspace-defaults/files/MEMORY_GUIDE.md +38 -35
- package/dist/workspace-defaults/files/ROUTER.md +1 -1
- package/dist/workspace-defaults/files/TOOLS.md +9 -39
- package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +6 -3
- package/dist/workspace-defaults/files/catalog-skills/brain-brief-builder/SKILL.md +165 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/SKILL.md +75 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/workflow-authoring.md +46 -0
- package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +1 -1
- package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +22 -3
- package/package.json +1 -1
- package/dist/drizzle/0261_managed_harness_multiplayer.sql +0 -313
- package/dist/drizzle/0262_parallel_harness_threads.sql +0 -9
- package/dist/drizzle/0264_harness_tool_execution_ledger.sql +0 -113
- package/dist/plugins/company-data/README.md +0 -49
- package/dist/plugins/company-data/package.json +0 -21
- package/dist/plugins/company-data/src/index.ts +0 -30
- package/dist/plugins/company-data/src/manifest.ts +0 -26
- package/dist/plugins/company-data/test/manifest.test.ts +0 -116
- package/dist/plugins/company-data/tsconfig.json +0 -8
- package/dist/plugins/company-etl/README.md +0 -46
- package/dist/plugins/company-etl/package.json +0 -21
- package/dist/plugins/company-etl/src/index.ts +0 -29
- package/dist/plugins/company-etl/src/manifest.ts +0 -26
- package/dist/plugins/company-etl/test/manifest.test.ts +0 -108
- package/dist/plugins/company-etl/tsconfig.json +0 -8
- package/dist/plugins/lastmile/README.md +0 -50
- package/dist/plugins/lastmile/package.json +0 -23
- package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +0 -661
- package/dist/plugins/lastmile/src/api/tasks-adapter.ts +0 -572
- package/dist/plugins/lastmile/src/discovery.fixture.ts +0 -64
- package/dist/plugins/lastmile/src/index.ts +0 -46
- package/dist/plugins/lastmile/src/manifest.ts +0 -139
- package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +0 -266
- package/dist/plugins/lastmile/test/discovery.test.ts +0 -88
- package/dist/plugins/lastmile/tsconfig.json +0 -8
- package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +0 -409
- package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +0 -359
- package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +0 -61
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +0 -227
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +0 -277
- package/dist/terraform/modules/app/agentcore-code-interpreter/scripts/build_and_push_sandbox_base.sh +0 -70
- package/dist/terraform/modules/app/agentcore-gateway/main.tf +0 -305
- package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +0 -44
- package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +0 -93
- package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +0 -33
- package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +0 -543
- package/dist/terraform/modules/app/agentcore-gateway/variables.tf +0 -70
- package/dist/terraform/modules/app/agentcore-harness/main.tf +0 -330
- package/dist/terraform/modules/app/agentcore-harness/outputs.tf +0 -72
- package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +0 -430
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +0 -180
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +0 -193
- package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/variables.tf +0 -96
- package/dist/terraform/modules/app/hindsight-memory/README.md +0 -89
- package/dist/terraform/modules/app/hindsight-memory/main.tf +0 -411
- package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +0 -88
- package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +0 -91
- package/dist/terraform/modules/data/bedrock-knowledge-base/main.tf +0 -102
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/outputs.tf +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/sync-database.py +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/test_sync_database.py +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/variables.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/README.md +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/main.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/outputs.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/variables.tf +0 -0
|
@@ -4,6 +4,12 @@ variable "enabled" {
|
|
|
4
4
|
default = false
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
variable "twenty_enabled" {
|
|
8
|
+
description = "THINK-324 — keep the Twenty CRM user-federation identity (shared workload identity, twenty-crm credential provider, DCR client secret) alive independent of the proof plane, so retiring the managed-harness proof (enabled = false) does not destroy the live Twenty connector."
|
|
9
|
+
type = bool
|
|
10
|
+
default = false
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
variable "stage" {
|
|
8
14
|
description = "Deployment stage."
|
|
9
15
|
type = string
|
|
@@ -10,12 +10,24 @@ the ThinkWork AgentCore runtime uses for automatic retention:
|
|
|
10
10
|
| summaries | `session_{sessionId}` | Per-thread rolling summaries |
|
|
11
11
|
| episodes | `episodes_{actorId}/{sessionId}` | Episodic memory of past interactions |
|
|
12
12
|
|
|
13
|
-
Automatic retention is wired
|
|
14
|
-
`CreateEvent`
|
|
15
|
-
|
|
16
|
-
back via the `recall()` tool
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
Automatic retention is wired through the API's normalized memory layer:
|
|
14
|
+
every turn emits a `CreateEvent` (`AgentCoreAdapter.retainTurn`, actor =
|
|
15
|
+
the user UUID), and AgentCore's background strategies extract facts into
|
|
16
|
+
the namespaces above. Agents read them back via the `recall()` tool, which
|
|
17
|
+
fans out over `assistant_{actorId}`, `preferences_{actorId}` and
|
|
18
|
+
`user_{actorId}`. There is no need for the model to call `remember()`
|
|
19
|
+
explicitly — it only exists for user-driven "please remember X" requests,
|
|
20
|
+
and writes direct records into `user_{actorId}`.
|
|
21
|
+
|
|
22
|
+
**The namespace templates above are a contract**, not an implementation
|
|
23
|
+
detail. Readers that must stay in sync:
|
|
24
|
+
|
|
25
|
+
- `packages/api/src/lib/memory/adapters/agentcore-adapter.ts` (`ACTOR_NAMESPACES`)
|
|
26
|
+
- `packages/agentcore-pi/agent-container/src/tools/memory.ts` (`recallNamespaces`)
|
|
27
|
+
|
|
28
|
+
Changing a template here without changing those makes extraction write
|
|
29
|
+
where nothing reads — silent, and invisible until someone notices the
|
|
30
|
+
agent has amnesia.
|
|
19
31
|
|
|
20
32
|
## Usage
|
|
21
33
|
|
|
@@ -42,12 +54,37 @@ The AWS Terraform provider does not (yet) expose a
|
|
|
42
54
|
`aws_bedrockagentcore_memory` resource. Until it does, this module drives
|
|
43
55
|
the lifecycle through the `aws bedrock-agentcore-control` CLI:
|
|
44
56
|
|
|
45
|
-
- **
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
- **Ensure**: `data "external"` runs `scripts/create_or_find_memory.sh` on
|
|
58
|
+
every plan and apply. It pages through `list-memories` for candidates
|
|
59
|
+
matching the logical name, probes each one with `get-memory`, and uses the
|
|
60
|
+
first that is ACTIVE (waiting out a `CREATING` one). Safe to re-run.
|
|
48
61
|
- **Destroy**: a paired `terraform_data` resource has a destroy-time
|
|
49
62
|
`local-exec` that calls `delete-memory` on the ID captured during create.
|
|
50
63
|
|
|
64
|
+
## Self-healing
|
|
65
|
+
|
|
66
|
+
The memory ID this module outputs comes from a **live lookup on every
|
|
67
|
+
plan**, never from stored state. If the memory resource is deleted
|
|
68
|
+
out-of-band — as happened to `dev` in THINK-404, where SSM still advertised
|
|
69
|
+
`AGENTCORE_MEMORY_ID` for a resource `GetMemory` returned
|
|
70
|
+
`ResourceNotFound` for — the next plan sees the ID no longer resolves and
|
|
71
|
+
the next apply creates a replacement with the same strategy set, waits for
|
|
72
|
+
it to reach `ACTIVE`, and rewires the runtime to it. No import, no state
|
|
73
|
+
surgery, no manual `create-memory`.
|
|
74
|
+
|
|
75
|
+
Two invariants keep that safe:
|
|
76
|
+
|
|
77
|
+
- **The ensure path never deletes.** Candidates in `DELETING` or `FAILED`
|
|
78
|
+
are skipped, not cleaned up. Deletion happens only through the
|
|
79
|
+
destroy-time provisioner.
|
|
80
|
+
- **Healing is not a replacement.** The destroy provisioner's
|
|
81
|
+
`triggers_replace` is keyed on the memory name and region, not the ID, so
|
|
82
|
+
recovering a new ID for the same logical memory can't fire a delete.
|
|
83
|
+
|
|
84
|
+
The cost of healing is the records: a recreated memory starts empty.
|
|
85
|
+
Extraction refills it from subsequent conversations; nothing recovers the
|
|
86
|
+
old records, because AgentCore has no export of a deleted memory.
|
|
87
|
+
|
|
51
88
|
When the AWS provider adds a native resource, migrate by importing the
|
|
52
89
|
existing memory ID into the new resource and removing this module's
|
|
53
90
|
external data source.
|
|
@@ -10,11 +10,18 @@
|
|
|
10
10
|
#
|
|
11
11
|
# **Why not a first-class resource?** The AWS provider does not (yet) expose a
|
|
12
12
|
# `aws_bedrockagentcore_memory` resource type. Until it does, we drive the
|
|
13
|
-
#
|
|
13
|
+
# ensure/destroy lifecycle through the `aws bedrock-agentcore-control`
|
|
14
14
|
# CLI via a small shell script, and read the resulting memory ID back into
|
|
15
|
-
# Terraform via `data "external"`.
|
|
16
|
-
#
|
|
17
|
-
#
|
|
15
|
+
# Terraform via `data "external"`.
|
|
16
|
+
#
|
|
17
|
+
# **Self-healing.** The script is an *ensure*, not a one-shot create: it
|
|
18
|
+
# probes the live resource on every plan and every apply, and recreates it
|
|
19
|
+
# when it has gone missing. That matters because Terraform state can hold a
|
|
20
|
+
# memory ID whose resource was deleted out-of-band (THINK-404 found dev in
|
|
21
|
+
# exactly that state — SSM advertised a memory ID that GetMemory 404'd on,
|
|
22
|
+
# and nothing in the module ever re-checked). The module output therefore
|
|
23
|
+
# reflects the memory that actually exists right now, not the one state
|
|
24
|
+
# remembers.
|
|
18
25
|
#
|
|
19
26
|
# **BYO override:** If you already have an AgentCore Memory resource, set
|
|
20
27
|
# `var.existing_memory_id` to skip provisioning. The module output will echo
|
|
@@ -97,12 +104,15 @@ resource "aws_iam_role_policy" "memory_execution" {
|
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
################################################################################
|
|
100
|
-
#
|
|
107
|
+
# Ensure via shell script (only when no existing_memory_id was given).
|
|
101
108
|
#
|
|
102
109
|
# The script produces JSON: `{"memory_id": "..."}`. Terraform re-runs it on
|
|
103
|
-
# every plan — if
|
|
104
|
-
#
|
|
105
|
-
#
|
|
110
|
+
# every plan — if an ACTIVE memory with this name already exists, the script
|
|
111
|
+
# returns that same ID and only drift-corrects its strategy list; if the
|
|
112
|
+
# memory is missing, unresolvable, or DELETING/FAILED, the script creates a
|
|
113
|
+
# replacement and waits for it to reach ACTIVE. It never deletes anything.
|
|
114
|
+
# Inputs are passed as JSON on stdin; outputs MUST be a single JSON object
|
|
115
|
+
# on stdout for `data "external"` to parse.
|
|
106
116
|
################################################################################
|
|
107
117
|
|
|
108
118
|
data "external" "memory" {
|
|
@@ -121,8 +131,15 @@ data "external" "memory" {
|
|
|
121
131
|
#
|
|
122
132
|
# Terraform's `data "external"` has no destroy hook, so we use a paired
|
|
123
133
|
# `terraform_data` resource with a destroy-time local-exec that deletes the
|
|
124
|
-
# memory by ID.
|
|
125
|
-
#
|
|
134
|
+
# memory by ID.
|
|
135
|
+
#
|
|
136
|
+
# `triggers_replace` is deliberately keyed on the memory *name* and region,
|
|
137
|
+
# NOT on the memory ID. Keying it on the ID would turn every self-heal (new
|
|
138
|
+
# ID for the same logical memory) into a replacement, firing the destroy
|
|
139
|
+
# provisioner against the ID the heal just recovered from — at best a no-op
|
|
140
|
+
# delete of an already-gone resource, at worst a delete of the freshly
|
|
141
|
+
# created one. Renaming or re-regioning the memory is a real replacement and
|
|
142
|
+
# still destroys the old resource; healing is an in-place `input` update.
|
|
126
143
|
################################################################################
|
|
127
144
|
|
|
128
145
|
resource "terraform_data" "memory_lifecycle" {
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
################################################################################
|
|
3
3
|
# create_or_find_memory.sh
|
|
4
4
|
#
|
|
5
|
-
# Idempotent
|
|
6
|
-
#
|
|
5
|
+
# Idempotent **ensure** for a Bedrock AgentCore Memory resource: guarantee
|
|
6
|
+
# that an ACTIVE memory with the desired strategy set exists, and return its
|
|
7
|
+
# live ID. Runs on every plan and every apply.
|
|
7
8
|
#
|
|
8
9
|
# Input (stdin, JSON):
|
|
9
10
|
# {"name": "<logical name>", "region": "<aws-region>",
|
|
@@ -11,18 +12,34 @@
|
|
|
11
12
|
# Output (stdout, JSON): {"memory_id": "<resource-id>"}
|
|
12
13
|
#
|
|
13
14
|
# Behavior:
|
|
14
|
-
# 1.
|
|
15
|
-
#
|
|
16
|
-
# uses `{name}-{randomSuffix}` for the resource ID,
|
|
17
|
-
# comes back null on existing resources).
|
|
18
|
-
# 2.
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# 3.
|
|
15
|
+
# 1. Pages through `aws bedrock-agentcore-control list-memories` and
|
|
16
|
+
# collects candidates matching by exact `name` OR by ID starting with
|
|
17
|
+
# `name-` (the API uses `{name}-{randomSuffix}` for the resource ID,
|
|
18
|
+
# and `name` sometimes comes back null on existing resources).
|
|
19
|
+
# 2. Probes each candidate with `get-memory`, which is the authoritative
|
|
20
|
+
# answer. A candidate is usable only if get-memory succeeds AND its
|
|
21
|
+
# status is ACTIVE (a CREATING memory is waited out). Candidates that
|
|
22
|
+
# 404, or that report DELETING / FAILED, are skipped.
|
|
23
|
+
# 3. Usable candidate: diff its current strategies against the desired set
|
|
24
|
+
# and `update-memory` with addMemoryStrategies for any that are missing.
|
|
25
|
+
# Adds new strategies without destructive recreation.
|
|
26
|
+
# 4. No usable candidate: `create-memory` with the full desired strategy
|
|
27
|
+
# list, then wait for ACTIVE.
|
|
23
28
|
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
29
|
+
# **Self-healing (THINK-404).** The dev memory was deleted out from under
|
|
30
|
+
# Terraform while state still held its ID, so every runtime read 404'd until
|
|
31
|
+
# a human noticed. Steps 1-2 are what make that unrecoverable-by-hand state
|
|
32
|
+
# impossible: the ID is re-derived from a live probe on every plan, so a
|
|
33
|
+
# missing or dying memory is simply recreated on the next apply and the
|
|
34
|
+
# module output tracks the resource that actually exists. The probe never
|
|
35
|
+
# deletes anything — teardown remains the exclusive job of the destroy-time
|
|
36
|
+
# provisioner in main.tf, whose `triggers_replace` deliberately does NOT
|
|
37
|
+
# include the memory ID so healing can't cascade into a delete.
|
|
38
|
+
#
|
|
39
|
+
# Strategy set must match the namespaces read by
|
|
40
|
+
# `packages/api/src/lib/memory/adapters/agentcore-adapter.ts` and
|
|
41
|
+
# `packages/agentcore-pi/agent-container/src/tools/memory.ts` so recall
|
|
42
|
+
# finds records written by the extractors:
|
|
26
43
|
# semantic -> assistant_{actorId}
|
|
27
44
|
# preferences -> preferences_{actorId}
|
|
28
45
|
# summaries -> session_{sessionId}
|
|
@@ -30,7 +47,8 @@
|
|
|
30
47
|
#
|
|
31
48
|
# Called from terraform/modules/app/agentcore-memory/main.tf via
|
|
32
49
|
# `data "external"`. Keep stdout strictly JSON — any stray echo will break
|
|
33
|
-
# Terraform's JSON parser. All diagnostics go to stderr.
|
|
50
|
+
# Terraform's JSON parser. All diagnostics go to stderr. Dependencies are
|
|
51
|
+
# bash, `aws`, and `jq` only, because this runs on the CI runner.
|
|
34
52
|
################################################################################
|
|
35
53
|
|
|
36
54
|
set -euo pipefail
|
|
@@ -103,18 +121,123 @@ strategies_json='[
|
|
|
103
121
|
desired_names=("semantic" "preferences" "summaries" "episodes")
|
|
104
122
|
|
|
105
123
|
# ---------------------------------------------------------------------------
|
|
106
|
-
#
|
|
124
|
+
# Helpers
|
|
107
125
|
# ---------------------------------------------------------------------------
|
|
108
126
|
|
|
109
|
-
|
|
110
|
-
|
|
127
|
+
# Echo the memory's status, or nothing at all when get-memory fails (the
|
|
128
|
+
# resource is gone). get-memory — not the list output — is the authority:
|
|
129
|
+
# list-memories has been observed returning IDs that no longer resolve.
|
|
130
|
+
memory_status() {
|
|
131
|
+
local id="$1" out
|
|
132
|
+
# `|| true` twice, deliberately: under `set -e -o pipefail` a failing
|
|
133
|
+
# get-memory (i.e. the memory is gone — the case this whole function
|
|
134
|
+
# exists to detect) would otherwise abort the script through the command
|
|
135
|
+
# substitution that calls it.
|
|
136
|
+
out="$(aws bedrock-agentcore-control get-memory \
|
|
111
137
|
--region "$region" \
|
|
112
|
-
--
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
--memory-id "$id" \
|
|
139
|
+
--output json 2>/dev/null || true)"
|
|
140
|
+
jq -r '.memory.status // empty' <<<"$out" 2>/dev/null || true
|
|
141
|
+
return 0
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# Block until the memory reports ACTIVE. Returns non-zero if it never gets
|
|
145
|
+
# there (deleted mid-wait, stuck in FAILED, or the wait budget expires).
|
|
146
|
+
# ~5 minutes: creation is normally well under a minute.
|
|
147
|
+
wait_for_active() {
|
|
148
|
+
local id="$1"
|
|
149
|
+
local status
|
|
150
|
+
for _ in $(seq 1 30); do
|
|
151
|
+
status="$(memory_status "$id")"
|
|
152
|
+
case "$status" in
|
|
153
|
+
ACTIVE) return 0 ;;
|
|
154
|
+
"" | FAILED | DELETING)
|
|
155
|
+
echo "[create_or_find_memory] $id is ${status:-gone}; not usable" >&2
|
|
156
|
+
return 1
|
|
157
|
+
;;
|
|
158
|
+
*)
|
|
159
|
+
echo "[create_or_find_memory] $id is $status; waiting for ACTIVE" >&2
|
|
160
|
+
sleep 10
|
|
161
|
+
;;
|
|
162
|
+
esac
|
|
163
|
+
done
|
|
164
|
+
echo "[create_or_find_memory] timed out waiting for $id to become ACTIVE" >&2
|
|
165
|
+
return 1
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
# ---------------------------------------------------------------------------
|
|
169
|
+
# Step 1: find a live memory with this name
|
|
170
|
+
#
|
|
171
|
+
# Paginated so a large account can't hide the existing resource behind a
|
|
172
|
+
# page boundary and trick us into creating a duplicate. Every candidate is
|
|
173
|
+
# probed with get-memory before it is trusted — that probe is what heals a
|
|
174
|
+
# memory that was deleted behind Terraform's back.
|
|
175
|
+
# ---------------------------------------------------------------------------
|
|
176
|
+
|
|
177
|
+
candidate_ids=()
|
|
178
|
+
next_token=""
|
|
179
|
+
list_err="$(mktemp)"
|
|
180
|
+
trap 'rm -f "$list_err"' EXIT
|
|
181
|
+
while :; do
|
|
182
|
+
set +e
|
|
183
|
+
if [[ -n "$next_token" ]]; then
|
|
184
|
+
page="$(aws bedrock-agentcore-control list-memories \
|
|
185
|
+
--region "$region" --max-results 100 --next-token "$next_token" \
|
|
186
|
+
--output json 2>"$list_err")"
|
|
187
|
+
else
|
|
188
|
+
page="$(aws bedrock-agentcore-control list-memories \
|
|
189
|
+
--region "$region" --max-results 100 \
|
|
190
|
+
--output json 2>"$list_err")"
|
|
191
|
+
fi
|
|
192
|
+
list_status=$?
|
|
193
|
+
set -e
|
|
194
|
+
# Fail loudly rather than treating an API error as "no memories exist" —
|
|
195
|
+
# that misreading would create a duplicate memory alongside the healthy
|
|
196
|
+
# one and silently split the tenant's records across two resources.
|
|
197
|
+
if [[ $list_status -ne 0 ]]; then
|
|
198
|
+
echo '{"error": "list-memories failed"}' >&2
|
|
199
|
+
cat "$list_err" >&2
|
|
200
|
+
exit "$list_status"
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
while IFS= read -r id; do
|
|
204
|
+
[[ -n "$id" ]] && candidate_ids+=("$id")
|
|
205
|
+
done < <(
|
|
206
|
+
jq -r --arg n "$name" \
|
|
207
|
+
'.memories[]? | select(.name == $n or ((.id // "") | startswith($n + "-"))) | .id' \
|
|
208
|
+
<<<"$page"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
next_token="$(jq -r '.nextToken // empty' <<<"$page")"
|
|
212
|
+
[[ -z "$next_token" ]] && break
|
|
213
|
+
done
|
|
116
214
|
|
|
117
|
-
|
|
215
|
+
existing_id=""
|
|
216
|
+
for candidate in ${candidate_ids[@]+"${candidate_ids[@]}"}; do
|
|
217
|
+
status="$(memory_status "$candidate")"
|
|
218
|
+
case "$status" in
|
|
219
|
+
ACTIVE)
|
|
220
|
+
existing_id="$candidate"
|
|
221
|
+
break
|
|
222
|
+
;;
|
|
223
|
+
CREATING)
|
|
224
|
+
if wait_for_active "$candidate"; then
|
|
225
|
+
existing_id="$candidate"
|
|
226
|
+
break
|
|
227
|
+
fi
|
|
228
|
+
;;
|
|
229
|
+
"")
|
|
230
|
+
# Listed but unresolvable: the resource was deleted out from under us
|
|
231
|
+
# (exactly the state THINK-404 found dev in). Fall through to create.
|
|
232
|
+
echo "[create_or_find_memory] listed memory $candidate no longer exists; will recreate" >&2
|
|
233
|
+
;;
|
|
234
|
+
*)
|
|
235
|
+
echo "[create_or_find_memory] skipping $candidate in status $status" >&2
|
|
236
|
+
;;
|
|
237
|
+
esac
|
|
238
|
+
done
|
|
239
|
+
|
|
240
|
+
if [[ -n "$existing_id" ]]; then
|
|
118
241
|
# ---------------------------------------------------------------------------
|
|
119
242
|
# Step 2a: memory exists — drift-correct its strategy list
|
|
120
243
|
#
|
|
@@ -128,7 +251,7 @@ if [[ -n "$existing_id" && "$existing_id" != "null" ]]; then
|
|
|
128
251
|
--region "$region" \
|
|
129
252
|
--memory-id "$existing_id" \
|
|
130
253
|
--output json 2>/dev/null \
|
|
131
|
-
| jq -r '.memory.strategies[]? | .name'
|
|
254
|
+
| jq -r '.memory.strategies[]? | .name' || true
|
|
132
255
|
)"
|
|
133
256
|
|
|
134
257
|
missing=()
|
|
@@ -200,7 +323,7 @@ fi
|
|
|
200
323
|
create_output=""
|
|
201
324
|
create_status=1
|
|
202
325
|
err_file="$(mktemp)"
|
|
203
|
-
trap 'rm -f "$err_file"' EXIT
|
|
326
|
+
trap 'rm -f "$err_file" "$list_err"' EXIT
|
|
204
327
|
for attempt in $(seq 1 12); do
|
|
205
328
|
set +e
|
|
206
329
|
create_output="$(
|
|
@@ -240,4 +363,13 @@ if [[ -z "$new_id" || "$new_id" == "null" ]]; then
|
|
|
240
363
|
exit 1
|
|
241
364
|
fi
|
|
242
365
|
|
|
366
|
+
# Don't hand Terraform an ID the runtime can't use yet: a memory in CREATING
|
|
367
|
+
# rejects CreateEvent, and downstream SSM/runtime wiring is written in the
|
|
368
|
+
# same apply.
|
|
369
|
+
if ! wait_for_active "$new_id"; then
|
|
370
|
+
echo '{"error": "created memory never became ACTIVE"}' >&2
|
|
371
|
+
exit 1
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
echo "[create_or_find_memory] created memory $new_id" >&2
|
|
243
375
|
jq -nc --arg id "$new_id" '{memory_id: $id}'
|
|
@@ -8,7 +8,7 @@ This module owns the dedicated Pi Lambda + log group + IAM role + event-invoke c
|
|
|
8
8
|
|
|
9
9
|
- `aws_iam_role.agentcore_pi` (`thinkwork-${stage}-agentcore-pi-role`) — assumed by Lambda + Bedrock AgentCore Runtime principals.
|
|
10
10
|
- `aws_iam_role_policy.agentcore_pi` — baseline permissions (S3 skill catalog, Bedrock model invoke, AgentCore Memory + Code Interpreter, CloudWatch Logs, X-Ray ingestion, ECR pull, SSM parameter access, memory-retain Lambda invoke). Forward-compat additions for U4-U8: Aurora Data API + Secrets Manager scoped to `thinkwork-${stage}-*`.
|
|
11
|
-
- `aws_iam_role_policy_attachment.agentcore_pi_vpc_access` —
|
|
11
|
+
- `aws_iam_role_policy_attachment.agentcore_pi_vpc_access` — retired (THINK-589): the OKF wiki EFS mount is removed, Pi is not VPC-attached, and the attachment is conditioned off pending deletion in the follow-up PR.
|
|
12
12
|
- `aws_iam_role_policy.agentcore_pi_dlq_send` — `sqs:SendMessage` against the shared async DLQ (injected via `var.async_dlq_arn`).
|
|
13
13
|
- `aws_cloudwatch_log_group.agentcore_pi` (`/thinkwork/${stage}/agentcore-pi`).
|
|
14
14
|
- `aws_lambda_function.agentcore_pi` (`thinkwork-${stage}-agentcore-pi`) — `package_type = "Image"`, pulls `${ecr_repository_url}:pi-latest`.
|
|
@@ -43,11 +43,9 @@ The Lambda function name changes from `thinkwork-${stage}-agentcore-flue` to `th
|
|
|
43
43
|
| `bucket_name` | yes | Primary S3 bucket for skills + workspace files. |
|
|
44
44
|
| `ecr_repository_url` | yes | Shared ECR repo URL from `module.agentcore_platform.ecr_repository_url`. |
|
|
45
45
|
| `async_dlq_arn` | yes | Shared async DLQ ARN from `module.agentcore_platform.agentcore_async_dlq_arn`. |
|
|
46
|
-
| `hindsight_endpoint` | no | Hindsight API endpoint when enabled; empty disables Hindsight tools. |
|
|
47
46
|
| `agentcore_memory_id` | no | AgentCore Memory resource ID for auto-retention. |
|
|
48
47
|
| `api_endpoint` | no | API Gateway base URL for the `/api/skills/complete` callback. |
|
|
49
48
|
| `api_auth_secret` | no | Service-auth bearer for the same callback. |
|
|
50
|
-
| `memory_engine` | no | `hindsight` or `agentcore`; surfaced as `MEMORY_ENGINE` env var. |
|
|
51
49
|
|
|
52
50
|
## Outputs
|
|
53
51
|
|
|
@@ -26,34 +26,19 @@ locals {
|
|
|
26
26
|
chat_agent_activity_fn_arn = "arn:aws:lambda:${var.region}:${var.account_id}:function:${local.chat_agent_activity_fn_name}"
|
|
27
27
|
manifest_log_fn_name = "thinkwork-${var.stage}-api-manifest-log"
|
|
28
28
|
manifest_log_fn_arn = "arn:aws:lambda:${var.region}:${var.account_id}:function:${local.manifest_log_fn_name}"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# no HTTP route exists for this Lambda.
|
|
32
|
-
capability_control_fn_name = "thinkwork-${var.stage}-api-capability-control-service"
|
|
33
|
-
capability_control_fn_arn = "arn:aws:lambda:${var.region}:${var.account_id}:function:${local.capability_control_fn_name}"
|
|
29
|
+
tool_executions_fn_name = "thinkwork-${var.stage}-api-tool-executions"
|
|
30
|
+
tool_executions_fn_arn = "arn:aws:lambda:${var.region}:${var.account_id}:function:${local.tool_executions_fn_name}"
|
|
34
31
|
# Release-backed deployments use an immutable, source-derived target tag so
|
|
35
32
|
# changing the release image also changes aws_lambda_function.image_uri.
|
|
36
33
|
# Reusing pi-latest lets Terraform miss the update even after ECR is retagged.
|
|
37
|
-
pi_image_tag
|
|
38
|
-
pi_image_uri
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
Sid = "OkfWikiEfsReadOnlyMount"
|
|
47
|
-
Effect = "Allow"
|
|
48
|
-
Action = ["elasticfilesystem:ClientMount"]
|
|
49
|
-
Resource = var.okf_efs_file_system_arn
|
|
50
|
-
Condition = {
|
|
51
|
-
StringEquals = {
|
|
52
|
-
"elasticfilesystem:AccessPointArn" = var.okf_efs_read_access_point_arn
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
] : []
|
|
34
|
+
pi_image_tag = var.source_image_uri != "" ? "pi-${substr(sha256(var.source_image_uri), 0, 16)}" : "pi-latest"
|
|
35
|
+
pi_image_uri = "${var.ecr_repository_url}:${local.pi_image_tag}"
|
|
36
|
+
# THINK-589 PR 1 (deprecate-to-no-op): the OKF wiki EFS feature is dead. The
|
|
37
|
+
# okf_efs_* inputs remain declared as deprecated no-ops so customer-stage
|
|
38
|
+
# passthroughs keep working, but nothing is wired regardless of their
|
|
39
|
+
# values: no VPC attach, no EFS mount, no OKF env, no EFS IAM grant.
|
|
40
|
+
# PR 2 deletes the variables outright.
|
|
41
|
+
okf_efs_mount_enabled = false
|
|
57
42
|
}
|
|
58
43
|
|
|
59
44
|
################################################################################
|
|
@@ -83,7 +68,7 @@ resource "aws_iam_role_policy" "agentcore_pi" {
|
|
|
83
68
|
|
|
84
69
|
policy = jsonencode({
|
|
85
70
|
Version = "2012-10-17"
|
|
86
|
-
Statement =
|
|
71
|
+
Statement = [
|
|
87
72
|
{
|
|
88
73
|
Sid = "S3Access"
|
|
89
74
|
Effect = "Allow"
|
|
@@ -264,13 +249,12 @@ resource "aws_iam_role_policy" "agentcore_pi" {
|
|
|
264
249
|
local.chat_agent_finalize_fn_arn,
|
|
265
250
|
local.chat_agent_activity_fn_arn,
|
|
266
251
|
local.manifest_log_fn_arn,
|
|
267
|
-
local.
|
|
252
|
+
local.tool_executions_fn_arn,
|
|
268
253
|
]
|
|
269
254
|
},
|
|
270
255
|
{
|
|
271
|
-
# Aurora Data API — U4 SessionStore
|
|
272
|
-
#
|
|
273
|
-
# connections. Cover both the canonical cluster name and suffixed
|
|
256
|
+
# Aurora Data API — U4 SessionStore reads/writes via the RDS Data
|
|
257
|
+
# API rather than long-lived Postgres connections. Cover both the canonical cluster name and suffixed
|
|
274
258
|
# replacement names.
|
|
275
259
|
Sid = "AuroraDataAPI"
|
|
276
260
|
Effect = "Allow"
|
|
@@ -299,12 +283,16 @@ resource "aws_iam_role_policy" "agentcore_pi" {
|
|
|
299
283
|
]
|
|
300
284
|
Resource = "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:thinkwork-${var.stage}-*"
|
|
301
285
|
},
|
|
302
|
-
]
|
|
286
|
+
]
|
|
303
287
|
})
|
|
304
288
|
}
|
|
305
289
|
|
|
290
|
+
# THINK-589 retired this with the OKF wiki EFS mount (Pi's only VPC
|
|
291
|
+
# attachment at the time). THINK-1082 brings it back for the network-only
|
|
292
|
+
# in_vpc lane: a VPC-attached function needs the ENI grant. Still never
|
|
293
|
+
# created when in_vpc is off.
|
|
306
294
|
resource "aws_iam_role_policy_attachment" "agentcore_pi_vpc_access" {
|
|
307
|
-
count =
|
|
295
|
+
count = var.in_vpc ? 1 : 0
|
|
308
296
|
|
|
309
297
|
role = aws_iam_role.agentcore_pi.name
|
|
310
298
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
|
|
@@ -384,51 +372,53 @@ resource "aws_lambda_function" "agentcore_pi" {
|
|
|
384
372
|
AWS_LWA_PORT = "8080"
|
|
385
373
|
AGENTCORE_MEMORY_ID = var.agentcore_memory_id
|
|
386
374
|
AGENTCORE_FILES_BUCKET = var.bucket_name
|
|
387
|
-
MEMORY_ENGINE =
|
|
375
|
+
MEMORY_ENGINE = "agentcore"
|
|
388
376
|
REQUESTER_IDLE_MEMORY_LEARNING_ENABLED = tostring(var.requester_idle_memory_learning_enabled)
|
|
389
377
|
MEMORY_RETAIN_FN_NAME = local.memory_retain_fn_name
|
|
390
378
|
CHAT_AGENT_FINALIZE_FN_NAME = local.chat_agent_finalize_fn_name
|
|
391
379
|
CHAT_AGENT_ACTIVITY_FN_NAME = local.chat_agent_activity_fn_name
|
|
392
380
|
MANIFEST_LOG_FUNCTION_NAME = local.manifest_log_fn_name
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
HINDSIGHT_DATABASE_NAME = var.hindsight_database_name
|
|
397
|
-
THINKWORK_API_URL = var.api_endpoint
|
|
398
|
-
API_AUTH_SECRET = var.api_auth_secret
|
|
381
|
+
TOOL_EXECUTIONS_FUNCTION_NAME = local.tool_executions_fn_name
|
|
382
|
+
THINKWORK_API_URL = var.api_endpoint
|
|
383
|
+
API_AUTH_SECRET = var.api_auth_secret
|
|
399
384
|
# Plan §005 U4 — AuroraSessionStore uses the RDS Data API to persist
|
|
400
385
|
# Pi's SessionData blobs against threads.session_data. Empty during
|
|
401
386
|
# the first greenfield apply (DB cluster doesn't exist yet); the
|
|
402
387
|
# constructor fail-closes if either is missing at runtime.
|
|
403
|
-
DB_CLUSTER_ARN
|
|
404
|
-
DB_SECRET_ARN
|
|
405
|
-
OKF_WIKI_NAVIGATOR_ENABLED = tostring(local.okf_efs_mount_enabled)
|
|
388
|
+
DB_CLUSTER_ARN = var.db_cluster_arn
|
|
389
|
+
DB_SECRET_ARN = var.db_secret_arn
|
|
406
390
|
# THINK-173 U6: PUBLIC key only — the container verifies capability
|
|
407
391
|
# manifests and must never hold signing material (KTD-3).
|
|
408
392
|
CAPABILITY_SIGNING_PUBLIC_KEY = var.capability_signing_public_key
|
|
409
|
-
OKF_WIKI_ROOT = var.okf_efs_mount_path
|
|
410
393
|
# Per-model Bedrock region overrides, honored by the patched pi-ai
|
|
411
394
|
# provider (patches/@earendil-works__pi-ai). SigV4 signing and endpoint
|
|
412
395
|
# selection both follow the override.
|
|
413
396
|
PI_BEDROCK_MODEL_REGIONS = jsonencode(var.pi_bedrock_model_regions)
|
|
397
|
+
# THINK-324: 1-hour Bedrock prompt-cache TTL (pi-ai resolveCacheRetention).
|
|
398
|
+
# The default 5-minute TTL made any thread idle >5 min pay full uncached
|
|
399
|
+
# input on its next turn.
|
|
400
|
+
PI_CACHE_RETENTION = "long"
|
|
414
401
|
}
|
|
415
402
|
}
|
|
416
403
|
|
|
404
|
+
# THINK-589: the OKF wiki EFS mount (and the VPC attachment that existed
|
|
405
|
+
# solely to reach it) is removed — no file_system_config, ever.
|
|
406
|
+
# THINK-1082: the VPC attachment returns as a NETWORK-ONLY lane so Pi can sit
|
|
407
|
+
# behind the api-lambda security group with the rest of the agent's database
|
|
408
|
+
# clients. Absent entirely when in_vpc is off.
|
|
417
409
|
dynamic "vpc_config" {
|
|
418
|
-
for_each =
|
|
410
|
+
for_each = var.in_vpc ? [1] : []
|
|
419
411
|
|
|
420
412
|
content {
|
|
421
|
-
subnet_ids =
|
|
422
|
-
security_group_ids =
|
|
413
|
+
subnet_ids = var.vpc_subnet_ids
|
|
414
|
+
security_group_ids = var.vpc_security_group_ids
|
|
423
415
|
}
|
|
424
416
|
}
|
|
425
417
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
arn = var.okf_efs_read_access_point_arn
|
|
431
|
-
local_mount_path = var.okf_efs_mount_path
|
|
418
|
+
lifecycle {
|
|
419
|
+
precondition {
|
|
420
|
+
condition = !var.in_vpc || (length(var.vpc_subnet_ids) > 0 && length(var.vpc_security_group_ids) > 0)
|
|
421
|
+
error_message = "in_vpc requires non-empty vpc_subnet_ids and vpc_security_group_ids."
|
|
432
422
|
}
|
|
433
423
|
}
|
|
434
424
|
|
|
@@ -23,16 +23,16 @@ output "agentcore_pi_log_group_name" {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
output "okf_wiki_mount_enabled" {
|
|
26
|
-
description = "
|
|
26
|
+
description = "DEPRECATED (THINK-589): always false — the OKF wiki EFS view is never mounted into the Pi Lambda. Removal pending (PR 2)."
|
|
27
27
|
value = local.okf_efs_mount_enabled
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
output "okf_wiki_mount_path" {
|
|
31
|
-
description = "
|
|
31
|
+
description = "DEPRECATED (THINK-589): inert echo of the deprecated okf_efs_mount_path input; nothing is mounted. Removal pending (PR 2)."
|
|
32
32
|
value = var.okf_efs_mount_path
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
output "okf_wiki_read_access_point_arn" {
|
|
36
|
-
description = "
|
|
36
|
+
description = "DEPRECATED (THINK-589): inert echo of the deprecated okf_efs_read_access_point_arn input; nothing is mounted. Removal pending (PR 2)."
|
|
37
37
|
value = var.okf_efs_read_access_point_arn
|
|
38
38
|
}
|