agenticstar-platform 3.2.1__tar.gz → 3.2.3__tar.gz
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.
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/PKG-INFO +40 -5
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/README.md +39 -4
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/__init__.py +1 -1
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/handlers.py +37 -4
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/runner.py +3 -1
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/base.py +51 -7
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/s3.py +21 -8
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/pyproject.toml +1 -1
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/events/test_handler_type_routing.py +60 -3
- agenticstar_platform-3.2.3/tests/events/test_notify_token.py +101 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/runner/test_marketplace_runner_started_fence.py +21 -0
- agenticstar_platform-3.2.3/tests/storage/test_s3_credential.py +178 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/LICENSE +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/_config_utils.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/audit/ROW_HASH_SPEC.md +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/audit/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/audit/action_audit.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/audit/guardrail_alerts.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/audit/row_hash_fixture.json +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/auth/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/auth/client.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/auth/config.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/auth/exceptions.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/auth/models.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/common/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/common/context_manager.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/common/secrets.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/common/validation.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/api_manager.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/completion_report.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/config.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/config_access.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/data_access.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/execution_access.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/factory.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/manager.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/pod_runtime.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/started_fence.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/telemetry_access.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/db/wire_types.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/emitter.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/models.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/types.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/README.md +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/__main__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/checks.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/docker-compose.yml +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/doctor.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/lab_config.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/offline_embedding.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/run_lab.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/lab/seed.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/memory/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/memory/semantic.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/metering/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/metering/meter.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/policy/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/policy/internal_operations.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/policy/model.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/rag/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/rag/base.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/rag/embedding.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/rag/qdrant_manager.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/runtime.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/aws.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/azure.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/base.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/content_safety_validator.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/factory.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/security/gcp.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/azure.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/gcs.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/paths.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/canonical.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/child.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/context.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/envelope.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/errors.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/files.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/runner.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/runtime_client.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/schema.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/workflow/testing.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/docs/agenticstar_platform.html +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/docs/examples/workflow_mock_send_agent.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/docs/examples/workflow_reply_agent.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/docs/index.html +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/docs/search.js +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/audit/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/audit/test_action_audit_30.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/audit/test_row_hash_fixture.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/auth/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/auth/test_auth_type_bearer_only.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/auth/test_get_user_path_encoding.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/auth/test_mcp_tokens_expiry.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/auth/test_mcp_tokens_rejected.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_api_manager_drain_and_headers.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_completion_report.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_data_access_identifier_validation.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_manager_execute_query_dispatch.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_telemetry_tools_used_contract.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/db/test_wire_param_types.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/events/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/lab/test_lab_contract.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/lab/test_lab_docker.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/memory/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/memory/test_semantic_converter_base_url.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/metering/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/metering/test_meter_cache_split.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/test_a2a_connection_rule.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/test_decision_layer.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/test_evaluate_decision_table.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/test_policy_model.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/policy/test_scoped_forbid.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/rag/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/rag/test_embedding_dimensions.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/rag/test_qdrant_error_hierarchy.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/rag/test_qdrant_get_statistics.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/runner/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/runner/test_marketplace_runner_contract.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/runner/test_marketplace_runner_db_fallback.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/security/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/security/test_azure_connect_retry.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/security/test_azure_prompt_shield_documents.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/security/test_factory_vertex_ai_safety.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/security/test_gcp_vertex_ai_safety.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/storage/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/storage/test_azure_credential.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/test_lazy_import_contract.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/test_readme_quickstart.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/test_storage_provider_extra_contract.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/__init__.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/agent_fixtures.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/test_child_failure_summary.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/test_workflow_incomplete.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/test_workflow_runner.py +0 -0
- {agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/workflow/test_workflow_testing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agenticstar-platform
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.3
|
|
4
4
|
Summary: AGENTICSTAR Platform SDK - Enterprise AI Agent Infrastructure
|
|
5
5
|
Project-URL: Homepage, https://developers.fd.agenticstar.tm.softbank.jp/
|
|
6
6
|
Project-URL: Documentation, https://developers.fd.agenticstar.tm.softbank.jp/
|
|
@@ -224,6 +224,7 @@ Environment variable contract:
|
|
|
224
224
|
| `REQUEST_SOURCE` / `AGENT_ID` | Same as above (optional) | — |
|
|
225
225
|
| `DB_HOST` / `DB_PORT` / `DB_DATABASE` / `DB_USER` / `DB_PASSWORD` | Env var settings at agent registration (`PostgreSQLConfig.from_env()` contract) | ✅ |
|
|
226
226
|
| `WEBHOOK_URL` | Env var settings at agent registration | ✅ |
|
|
227
|
+
| `ASTER_NOTIFY_TOKEN` | Injected by the Marketplace executor for each execution (SDK >= 3.2.2 sends it as `Authorization: Bearer` on the webhook notification) | — |
|
|
227
228
|
|
|
228
229
|
Terminal event rules:
|
|
229
230
|
|
|
@@ -235,7 +236,8 @@ Terminal event rules:
|
|
|
235
236
|
If you need the low-level API (to compose handlers yourself), pass
|
|
236
237
|
`create_marketplace_handler(data_access, webhook_url, user_id, conversation_id, message_id)`
|
|
237
238
|
(a composite handler for DB persistence + webhook notification; requires the `[db]` + `[webhook]`
|
|
238
|
-
extras) directly to `EventEmitter`, as before.
|
|
239
|
+
extras) directly to `EventEmitter`, as before. Without a `token_provider`, it sends the
|
|
240
|
+
`ASTER_NOTIFY_TOKEN` env var as `Authorization: Bearer` when it is set (SDK >= 3.2.2).
|
|
239
241
|
|
|
240
242
|
### 2.4 Report completion for a cycle execution (SDK >= 3.0.14, `mp-chat/1`)
|
|
241
243
|
|
|
@@ -471,6 +473,24 @@ config = AzureBlobConfig.from_dict({
|
|
|
471
473
|
client = AzureBlobStorageClient(config)
|
|
472
474
|
```
|
|
473
475
|
|
|
476
|
+
S3 without access keys (3.2.3): leave `aws_access_key_id` and `aws_secret_access_key` both out (or
|
|
477
|
+
empty). The client then passes no keys and lets boto3 find the credentials with its default
|
|
478
|
+
credential chain (for example IRSA on EKS, environment variables, `~/.aws` files, EKS Pod Identity
|
|
479
|
+
or an EC2 instance role; boto3 decides which one is used first). This is what an EKS Pod with IRSA
|
|
480
|
+
needs; do not also give that Pod `AWS_ACCESS_KEY_ID` in its env, which boto3 checks before IRSA.
|
|
481
|
+
The role needs S3 access to the bucket. Give both keys or neither: only one of them raises
|
|
482
|
+
`StorageConfigError`.
|
|
483
|
+
|
|
484
|
+
```python
|
|
485
|
+
from agenticstar_platform.storage import S3StorageClient, S3Config
|
|
486
|
+
|
|
487
|
+
config = S3Config.from_dict({
|
|
488
|
+
"bucket_name": "your-bucket",
|
|
489
|
+
"region_name": "us-east-1",
|
|
490
|
+
})
|
|
491
|
+
client = S3StorageClient(config)
|
|
492
|
+
```
|
|
493
|
+
|
|
474
494
|
### Telemetry / LLM Usage Tracking (Marketplace)
|
|
475
495
|
|
|
476
496
|
`TelemetryAccess` (under `db` module) writes records to the `ai_telemetry` table. **Unknown fields are stored in the `metadata` jsonb column automatically** — no schema migration is required to add new tracking dimensions.
|
|
@@ -734,8 +754,9 @@ async def run(context):
|
|
|
734
754
|
|
|
735
755
|
**Ending a step as not completed** (SDK ≥ 3.2.1). When your agent cannot complete the step and running it again would
|
|
736
756
|
give the same result — the instructions are missing, a setting is wrong — call `context.incomplete(reason, comment)` and
|
|
737
|
-
return. The platform does not retry the step automatically; it asks a person to check it and shows the reason
|
|
738
|
-
|
|
757
|
+
return. The platform does not retry the step automatically; it asks a person to check it and shows the reason in the
|
|
758
|
+
execution record. A platform that reads the end-of-run report (below) also shows the comment there; Marketplace 3.2.0
|
|
759
|
+
does not show the comment.
|
|
739
760
|
|
|
740
761
|
```python
|
|
741
762
|
async def run(context):
|
|
@@ -1107,6 +1128,20 @@ See the [developer portal](https://developers.fd.agenticstar.tm.softbank.jp/) fo
|
|
|
1107
1128
|
|
|
1108
1129
|
## Changelog
|
|
1109
1130
|
|
|
1131
|
+
### 3.2.3 (2026-11-04) — storage: S3 without access keys (IRSA) / events: a failed run ends the chat message
|
|
1132
|
+
|
|
1133
|
+
3.2.2 was not published to PyPI; 3.2.3 includes its change (the notify token below).
|
|
1134
|
+
|
|
1135
|
+
- **`S3StorageClient` works without access keys.** Leave `aws_access_key_id` and `aws_secret_access_key` both out (or empty) and the client passes no keys and lets boto3 find the credentials with its default credential chain (for example IRSA on EKS with `AWS_ROLE_ARN` + `AWS_WEB_IDENTITY_TOKEN_FILE`, environment variables, `~/.aws` files, EKS Pod Identity or an EC2 instance role; boto3 decides the order). Before, the client raised `StorageConfigError: S3 requires aws_access_key_id and aws_secret_access_key` on an EKS runner Pod that has only IRSA. Giving only one of the two keys still raises `StorageConfigError` (it is a configuration mistake, and the client does not silently fall back to other credentials). Both keys work as before, exactly as given (a non-blank key is not stripped); an empty or whitespace-only key, including a `SecretStr`, counts as not given. With no keys the client is created even when boto3 finds no credentials; the first call then fails (for example `object_exists()` returns `False`). `S3Config` keeps its field order, so positional construction is unchanged; `S3Config.from_dict` no longer requires the two keys.
|
|
1136
|
+
- **A failed run ends the chat message.** `create_marketplace_handler` (and so `run_marketplace_agent`) now sends `COMPLETION_FAILURE` with `finish_reason: "stop"`, the same as the platform's own agent worker. The chat front ends a message only on `"stop"`; with the previous `"error"` the failure text was added but the message kept showing as in progress. The failure is told by the message text, as before. `WebhookEventHandler` used on its own keeps `"error"` by default, so a receiver of your own that tells failures by `"error"` is unchanged; the new argument `failure_finish_reason="stop"` sends what the chat front expects. If you pointed `create_marketplace_handler` at a receiver of your own that needs `"error"`, build `WebhookEventHandler` yourself instead.
|
|
1137
|
+
- docs: "Ending a step as not completed" now says that the execution record shows the reason, and that the comment is shown only by a platform that reads the end-of-run report (Marketplace 3.2.0 does not show it). In 3.2.1 and 3.2.2 that section said the record shows the comment. The SDK's behavior is unchanged.
|
|
1138
|
+
|
|
1139
|
+
### 3.2.2 (2026-10-30) — events: the webhook notification carries the execution's notify token (`ASTER_NOTIFY_TOKEN`)
|
|
1140
|
+
|
|
1141
|
+
- **`create_marketplace_handler(...)` sends `Authorization: Bearer <token>` on the webhook notification when the `ASTER_NOTIFY_TOKEN` env var is set.** The Marketplace executor issues this token for each execution and passes it to the agent Pod; the platform checks it when it receives the notification. Without a `token_provider` argument, the handler reads the env var each time it sends. When the env var is missing or empty, no `Authorization` header is sent, as before. A `token_provider` you pass is used as before, and the env var is not read. `run_marketplace_agent` uses this default, so a runner agent sends the token without code changes.
|
|
1142
|
+
- `WebhookEventHandler` used on its own does not read `ASTER_NOTIFY_TOKEN`; as before, it sends an `Authorization` header only when you give one (through its `token_provider` or `headers`).
|
|
1143
|
+
- To use it, rebuild the agent image with this SDK.
|
|
1144
|
+
|
|
1110
1145
|
### 3.2.1 (2026-10-28) — workflow: end a step as not completed (`context.incomplete`) with an end-of-run report / a fake runtime for testing (`agenticstar_platform.workflow.testing`)
|
|
1111
1146
|
|
|
1112
1147
|
- **New `WorkflowContext.incomplete(reason, comment=None)`.** An agent that cannot complete its step, where running it again would give the same result (missing instructions, a wrong setting), ends the step as `incomplete` with `reason` as the reason code. The platform does not retry it automatically and asks a person to check it. `reason` follows the rules of `report_completion()` (lowercase snake_case of at most 32 characters; any other value becomes `incomplete` with a warning); `comment` is cut at 2,048 UTF-16 code units. The declaration comes after an audit persistence failure, cancellation, the deadline, the execution being closed elsewhere, a pod stop signal and a denied tool call, and before an exception (an exception after the declaration still ends as `incomplete`), an invalid output, a skip and a missing required output. A second declaration is not recorded. See "Ending a step as not completed" in the Workflow Runner section.
|
|
@@ -1553,4 +1588,4 @@ Marketplace SDK reliability fixes (surfaced while building agents from the guide
|
|
|
1553
1588
|
|
|
1554
1589
|
## Version
|
|
1555
1590
|
|
|
1556
|
-
3.2.
|
|
1591
|
+
3.2.3
|
|
@@ -143,6 +143,7 @@ Environment variable contract:
|
|
|
143
143
|
| `REQUEST_SOURCE` / `AGENT_ID` | Same as above (optional) | — |
|
|
144
144
|
| `DB_HOST` / `DB_PORT` / `DB_DATABASE` / `DB_USER` / `DB_PASSWORD` | Env var settings at agent registration (`PostgreSQLConfig.from_env()` contract) | ✅ |
|
|
145
145
|
| `WEBHOOK_URL` | Env var settings at agent registration | ✅ |
|
|
146
|
+
| `ASTER_NOTIFY_TOKEN` | Injected by the Marketplace executor for each execution (SDK >= 3.2.2 sends it as `Authorization: Bearer` on the webhook notification) | — |
|
|
146
147
|
|
|
147
148
|
Terminal event rules:
|
|
148
149
|
|
|
@@ -154,7 +155,8 @@ Terminal event rules:
|
|
|
154
155
|
If you need the low-level API (to compose handlers yourself), pass
|
|
155
156
|
`create_marketplace_handler(data_access, webhook_url, user_id, conversation_id, message_id)`
|
|
156
157
|
(a composite handler for DB persistence + webhook notification; requires the `[db]` + `[webhook]`
|
|
157
|
-
extras) directly to `EventEmitter`, as before.
|
|
158
|
+
extras) directly to `EventEmitter`, as before. Without a `token_provider`, it sends the
|
|
159
|
+
`ASTER_NOTIFY_TOKEN` env var as `Authorization: Bearer` when it is set (SDK >= 3.2.2).
|
|
158
160
|
|
|
159
161
|
### 2.4 Report completion for a cycle execution (SDK >= 3.0.14, `mp-chat/1`)
|
|
160
162
|
|
|
@@ -390,6 +392,24 @@ config = AzureBlobConfig.from_dict({
|
|
|
390
392
|
client = AzureBlobStorageClient(config)
|
|
391
393
|
```
|
|
392
394
|
|
|
395
|
+
S3 without access keys (3.2.3): leave `aws_access_key_id` and `aws_secret_access_key` both out (or
|
|
396
|
+
empty). The client then passes no keys and lets boto3 find the credentials with its default
|
|
397
|
+
credential chain (for example IRSA on EKS, environment variables, `~/.aws` files, EKS Pod Identity
|
|
398
|
+
or an EC2 instance role; boto3 decides which one is used first). This is what an EKS Pod with IRSA
|
|
399
|
+
needs; do not also give that Pod `AWS_ACCESS_KEY_ID` in its env, which boto3 checks before IRSA.
|
|
400
|
+
The role needs S3 access to the bucket. Give both keys or neither: only one of them raises
|
|
401
|
+
`StorageConfigError`.
|
|
402
|
+
|
|
403
|
+
```python
|
|
404
|
+
from agenticstar_platform.storage import S3StorageClient, S3Config
|
|
405
|
+
|
|
406
|
+
config = S3Config.from_dict({
|
|
407
|
+
"bucket_name": "your-bucket",
|
|
408
|
+
"region_name": "us-east-1",
|
|
409
|
+
})
|
|
410
|
+
client = S3StorageClient(config)
|
|
411
|
+
```
|
|
412
|
+
|
|
393
413
|
### Telemetry / LLM Usage Tracking (Marketplace)
|
|
394
414
|
|
|
395
415
|
`TelemetryAccess` (under `db` module) writes records to the `ai_telemetry` table. **Unknown fields are stored in the `metadata` jsonb column automatically** — no schema migration is required to add new tracking dimensions.
|
|
@@ -653,8 +673,9 @@ async def run(context):
|
|
|
653
673
|
|
|
654
674
|
**Ending a step as not completed** (SDK ≥ 3.2.1). When your agent cannot complete the step and running it again would
|
|
655
675
|
give the same result — the instructions are missing, a setting is wrong — call `context.incomplete(reason, comment)` and
|
|
656
|
-
return. The platform does not retry the step automatically; it asks a person to check it and shows the reason
|
|
657
|
-
|
|
676
|
+
return. The platform does not retry the step automatically; it asks a person to check it and shows the reason in the
|
|
677
|
+
execution record. A platform that reads the end-of-run report (below) also shows the comment there; Marketplace 3.2.0
|
|
678
|
+
does not show the comment.
|
|
658
679
|
|
|
659
680
|
```python
|
|
660
681
|
async def run(context):
|
|
@@ -1026,6 +1047,20 @@ See the [developer portal](https://developers.fd.agenticstar.tm.softbank.jp/) fo
|
|
|
1026
1047
|
|
|
1027
1048
|
## Changelog
|
|
1028
1049
|
|
|
1050
|
+
### 3.2.3 (2026-11-04) — storage: S3 without access keys (IRSA) / events: a failed run ends the chat message
|
|
1051
|
+
|
|
1052
|
+
3.2.2 was not published to PyPI; 3.2.3 includes its change (the notify token below).
|
|
1053
|
+
|
|
1054
|
+
- **`S3StorageClient` works without access keys.** Leave `aws_access_key_id` and `aws_secret_access_key` both out (or empty) and the client passes no keys and lets boto3 find the credentials with its default credential chain (for example IRSA on EKS with `AWS_ROLE_ARN` + `AWS_WEB_IDENTITY_TOKEN_FILE`, environment variables, `~/.aws` files, EKS Pod Identity or an EC2 instance role; boto3 decides the order). Before, the client raised `StorageConfigError: S3 requires aws_access_key_id and aws_secret_access_key` on an EKS runner Pod that has only IRSA. Giving only one of the two keys still raises `StorageConfigError` (it is a configuration mistake, and the client does not silently fall back to other credentials). Both keys work as before, exactly as given (a non-blank key is not stripped); an empty or whitespace-only key, including a `SecretStr`, counts as not given. With no keys the client is created even when boto3 finds no credentials; the first call then fails (for example `object_exists()` returns `False`). `S3Config` keeps its field order, so positional construction is unchanged; `S3Config.from_dict` no longer requires the two keys.
|
|
1055
|
+
- **A failed run ends the chat message.** `create_marketplace_handler` (and so `run_marketplace_agent`) now sends `COMPLETION_FAILURE` with `finish_reason: "stop"`, the same as the platform's own agent worker. The chat front ends a message only on `"stop"`; with the previous `"error"` the failure text was added but the message kept showing as in progress. The failure is told by the message text, as before. `WebhookEventHandler` used on its own keeps `"error"` by default, so a receiver of your own that tells failures by `"error"` is unchanged; the new argument `failure_finish_reason="stop"` sends what the chat front expects. If you pointed `create_marketplace_handler` at a receiver of your own that needs `"error"`, build `WebhookEventHandler` yourself instead.
|
|
1056
|
+
- docs: "Ending a step as not completed" now says that the execution record shows the reason, and that the comment is shown only by a platform that reads the end-of-run report (Marketplace 3.2.0 does not show it). In 3.2.1 and 3.2.2 that section said the record shows the comment. The SDK's behavior is unchanged.
|
|
1057
|
+
|
|
1058
|
+
### 3.2.2 (2026-10-30) — events: the webhook notification carries the execution's notify token (`ASTER_NOTIFY_TOKEN`)
|
|
1059
|
+
|
|
1060
|
+
- **`create_marketplace_handler(...)` sends `Authorization: Bearer <token>` on the webhook notification when the `ASTER_NOTIFY_TOKEN` env var is set.** The Marketplace executor issues this token for each execution and passes it to the agent Pod; the platform checks it when it receives the notification. Without a `token_provider` argument, the handler reads the env var each time it sends. When the env var is missing or empty, no `Authorization` header is sent, as before. A `token_provider` you pass is used as before, and the env var is not read. `run_marketplace_agent` uses this default, so a runner agent sends the token without code changes.
|
|
1061
|
+
- `WebhookEventHandler` used on its own does not read `ASTER_NOTIFY_TOKEN`; as before, it sends an `Authorization` header only when you give one (through its `token_provider` or `headers`).
|
|
1062
|
+
- To use it, rebuild the agent image with this SDK.
|
|
1063
|
+
|
|
1029
1064
|
### 3.2.1 (2026-10-28) — workflow: end a step as not completed (`context.incomplete`) with an end-of-run report / a fake runtime for testing (`agenticstar_platform.workflow.testing`)
|
|
1030
1065
|
|
|
1031
1066
|
- **New `WorkflowContext.incomplete(reason, comment=None)`.** An agent that cannot complete its step, where running it again would give the same result (missing instructions, a wrong setting), ends the step as `incomplete` with `reason` as the reason code. The platform does not retry it automatically and asks a person to check it. `reason` follows the rules of `report_completion()` (lowercase snake_case of at most 32 characters; any other value becomes `incomplete` with a warning); `comment` is cut at 2,048 UTF-16 code units. The declaration comes after an audit persistence failure, cancellation, the deadline, the execution being closed elsewhere, a pod stop signal and a denied tool call, and before an exception (an exception after the declaration still ends as `incomplete`), an invalid output, a skip and a missing required output. A second declaration is not recorded. See "Ending a step as not completed" in the Workflow Runner section.
|
|
@@ -1472,4 +1507,4 @@ Marketplace SDK reliability fixes (surfaced while building agents from the guide
|
|
|
1472
1507
|
|
|
1473
1508
|
## Version
|
|
1474
1509
|
|
|
1475
|
-
3.2.
|
|
1510
|
+
3.2.3
|
|
@@ -9,7 +9,7 @@ import importlib
|
|
|
9
9
|
import importlib.util
|
|
10
10
|
from typing import TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
__version__ = "3.2.
|
|
12
|
+
__version__ = "3.2.3"
|
|
13
13
|
|
|
14
14
|
# Common utilities are internal - not exported as public API
|
|
15
15
|
# Use agenticstar_platform.common for internal SDK development only
|
{agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/events/handlers.py
RENAMED
|
@@ -33,6 +33,7 @@ Example:
|
|
|
33
33
|
import asyncio
|
|
34
34
|
import json
|
|
35
35
|
import logging
|
|
36
|
+
import os
|
|
36
37
|
from typing import Any, Callable, Dict, List, Optional
|
|
37
38
|
|
|
38
39
|
from .types import EventType
|
|
@@ -249,6 +250,7 @@ class WebhookEventHandler:
|
|
|
249
250
|
chunk_type_map: Optional[Dict[EventType, str]] = None,
|
|
250
251
|
request_source: Optional[str] = None,
|
|
251
252
|
message_type_map: Optional[Dict[EventType, str]] = None,
|
|
253
|
+
failure_finish_reason: str = "error",
|
|
252
254
|
):
|
|
253
255
|
"""
|
|
254
256
|
WebhookEventHandlerを初期化
|
|
@@ -269,6 +271,10 @@ class WebhookEventHandler:
|
|
|
269
271
|
message_type_map: EventType→トップレベルtypeのカスタムマッピング
|
|
270
272
|
(オプション)。省略時は HITL系→"vnc_hitl_event"、
|
|
271
273
|
PROGRESS_MESSAGE→"progress_message" を切り替えるデフォルトを使用。
|
|
274
|
+
failure_finish_reason: COMPLETION_FAILURE の finish_reason(既定 "error"。3.2.3)。
|
|
275
|
+
AgenticStar のチャット画面(chatboardfront の監視)へ送るときは "stop" にする:
|
|
276
|
+
受信側は "stop" のときだけメッセージを終わらせ、"error" は読まない(本体の worker も
|
|
277
|
+
失敗を "stop" で送る)。create_marketplace_handler はこれを "stop" にして作る
|
|
272
278
|
|
|
273
279
|
Example:
|
|
274
280
|
>>> handler = WebhookEventHandler(
|
|
@@ -309,10 +315,10 @@ class WebhookEventHandler:
|
|
|
309
315
|
EventType.FINAL_RESULT: None,
|
|
310
316
|
}
|
|
311
317
|
|
|
312
|
-
# finish_reason
|
|
318
|
+
# finish_reasonマッピング(失敗の値は failure_finish_reason。既定 "error" は従来どおり)
|
|
313
319
|
self._finish_reason_map = {
|
|
314
320
|
EventType.COMPLETION_SUCCESS: "stop",
|
|
315
|
-
EventType.COMPLETION_FAILURE:
|
|
321
|
+
EventType.COMPLETION_FAILURE: failure_finish_reason,
|
|
316
322
|
}
|
|
317
323
|
|
|
318
324
|
logger.debug(
|
|
@@ -502,6 +508,20 @@ class CompositeEventHandler:
|
|
|
502
508
|
return None
|
|
503
509
|
|
|
504
510
|
|
|
511
|
+
# 完了の知らせ(/webhook/notify)に付ける実行ごとのトークンの env。
|
|
512
|
+
# Marketplace executor が実行ごとに発行し、会話の Pod に渡す。受信側(front の監視)が
|
|
513
|
+
# Authorization: Bearer で確かめる。
|
|
514
|
+
NOTIFY_TOKEN_ENV = "ASTER_NOTIFY_TOKEN"
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def _notify_token_from_env() -> Optional[str]:
|
|
518
|
+
"""env ASTER_NOTIFY_TOKEN から知らせのトークンを返す(無い・空なら None)
|
|
519
|
+
|
|
520
|
+
create_marketplace_handler の既定の token_provider。送るたびに env を読む。
|
|
521
|
+
"""
|
|
522
|
+
return os.environ.get(NOTIFY_TOKEN_ENV) or None
|
|
523
|
+
|
|
524
|
+
|
|
505
525
|
def create_marketplace_handler(
|
|
506
526
|
data_access: Any,
|
|
507
527
|
webhook_url: str,
|
|
@@ -522,12 +542,19 @@ def create_marketplace_handler(
|
|
|
522
542
|
user_id: ユーザーID
|
|
523
543
|
conversation_id: 会話ID
|
|
524
544
|
message_id: メッセージID
|
|
525
|
-
token_provider:
|
|
545
|
+
token_provider: 認証トークン取得関数(オプション)。
|
|
546
|
+
省略時(None)は env ASTER_NOTIFY_TOKEN を送るたびに読む既定の関数を使い、
|
|
547
|
+
値があれば Webhook に Authorization: Bearer <値> を付ける。env が無い・空なら付けない
|
|
548
|
+
(Marketplace executor が実行ごとに発行して Pod に渡すトークン。呼び出し側のコードは
|
|
549
|
+
変えなくてよい。SDK 3.2.2 から)。明示した場合はその関数だけを使い、env は読まない。
|
|
526
550
|
request_source: リクエスト発信元("internal" / "external")。
|
|
527
551
|
受信側で Progress SSE 配信 と 外部Webhook送信 の振り分けに使われる。
|
|
528
552
|
外部API経由(extapi)からの呼び出しでは "external" を指定すること。
|
|
529
553
|
通常はPod起動スクリプトで os.environ.get("REQUEST_SOURCE", "internal") を渡す。
|
|
530
554
|
|
|
555
|
+
失敗の完了(COMPLETION_FAILURE)は finish_reason "stop" で送る(3.2.3。チャット画面は "stop" で
|
|
556
|
+
メッセージを終わらせる。WebhookEventHandler の既定 "error" とは違う)。
|
|
557
|
+
|
|
531
558
|
Returns:
|
|
532
559
|
CompositeEventHandler: DB + Webhookの複合ハンドラー
|
|
533
560
|
|
|
@@ -561,8 +588,14 @@ def create_marketplace_handler(
|
|
|
561
588
|
webhook_url=webhook_url,
|
|
562
589
|
conversation_id=conversation_id,
|
|
563
590
|
message_id=message_id,
|
|
564
|
-
token_provider=
|
|
591
|
+
token_provider=(
|
|
592
|
+
token_provider if token_provider is not None else _notify_token_from_env
|
|
593
|
+
),
|
|
565
594
|
request_source=request_source,
|
|
595
|
+
# 失敗も "stop"(3.2.3): 受信側のチャット画面(chatboardfront の監視)は "stop" のときだけ
|
|
596
|
+
# メッセージを終わらせ、"error" は読まない。本体の worker も COMPLETION_FAILURE を "stop" で送る
|
|
597
|
+
# (src/subscribers/common.py の get_finish_reason)。失敗の中身は本文で伝わる
|
|
598
|
+
failure_finish_reason="stop",
|
|
566
599
|
)
|
|
567
600
|
|
|
568
601
|
return CompositeEventHandler([db_handler, webhook_handler])
|
|
@@ -67,7 +67,7 @@ from .db import DataAccess, PostgreSQLConfig, create_postgresql_manager
|
|
|
67
67
|
from .db.execution_access import ExecutionAccess
|
|
68
68
|
from .db.started_fence import StartedFenceTaken, take_started_fence
|
|
69
69
|
from .events import EventEmitter, EventType
|
|
70
|
-
from .events.handlers import create_marketplace_handler
|
|
70
|
+
from .events.handlers import NOTIFY_TOKEN_ENV, create_marketplace_handler
|
|
71
71
|
|
|
72
72
|
logger = logging.getLogger(__name__)
|
|
73
73
|
|
|
@@ -315,6 +315,8 @@ async def arun_marketplace_agent(
|
|
|
315
315
|
conversation_id=identity["CONVERSATION_ID"],
|
|
316
316
|
message_id=identity["MESSAGE_ID"],
|
|
317
317
|
request_source=request_source or env.get("REQUEST_SOURCE", "internal"),
|
|
318
|
+
# 完了の知らせの実行ごとのトークン(3.2.2)。identity・WEBHOOK_URL と同じく渡された env から読む
|
|
319
|
+
token_provider=lambda: env.get(NOTIFY_TOKEN_ENV) or None,
|
|
318
320
|
)
|
|
319
321
|
|
|
320
322
|
execution_id = identity["EXECUTION_ID"]
|
{agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/base.py
RENAMED
|
@@ -243,12 +243,33 @@ def _blank_to_none(value: Any) -> Optional[str]:
|
|
|
243
243
|
return text if text else None
|
|
244
244
|
|
|
245
245
|
|
|
246
|
+
def _blank_key_to_none(value: Any) -> Any:
|
|
247
|
+
"""鍵の値が None・空・空白だけなら None、それ以外は渡された値をそのまま返す。
|
|
248
|
+
|
|
249
|
+
``_blank_to_none`` と違い、空でない値は strip しない (S3 互換のストレージの鍵の前後の空白も
|
|
250
|
+
署名に使われる値の一部)。``SecretStr`` は中身で空かどうかを見て、空でなければ包んだまま返す。
|
|
251
|
+
"""
|
|
252
|
+
if value is None:
|
|
253
|
+
return None
|
|
254
|
+
raw = value.get_secret_value() if hasattr(value, "get_secret_value") else value
|
|
255
|
+
if raw is None or not str(raw).strip():
|
|
256
|
+
return None
|
|
257
|
+
return value
|
|
258
|
+
|
|
259
|
+
|
|
246
260
|
@dataclass
|
|
247
261
|
class S3Config:
|
|
248
262
|
"""AWS S3設定
|
|
249
263
|
|
|
264
|
+
認証は 2 通り (3.2.3):
|
|
265
|
+
- ``aws_access_key_id`` と ``aws_secret_access_key`` の両方があればそれを使う (従来どおり)
|
|
266
|
+
- 両方とも無ければ鍵を渡さず、boto3 の既定の探し方に任せる
|
|
267
|
+
(EKS の IRSA・環境変数・~/.aws の設定・EKS Pod Identity・EC2 のインスタンスロールなど。どれを先に使うかは boto3 が決める)
|
|
268
|
+
片方だけのときは設定の誤りとして ``S3StorageClient`` が ``StorageConfigError`` を上げる。
|
|
269
|
+
空文字・空白だけの値は「無し」として扱う (設定ファイルで空にしたときの形)。
|
|
270
|
+
|
|
250
271
|
Example:
|
|
251
|
-
>>> #
|
|
272
|
+
>>> # 鍵で認証 (従来)
|
|
252
273
|
>>> config = S3Config.from_dict({
|
|
253
274
|
... "bucket_name": "my-bucket",
|
|
254
275
|
... "aws_access_key_id": "AKIAXXXXXXX",
|
|
@@ -256,6 +277,12 @@ class S3Config:
|
|
|
256
277
|
... "region_name": "ap-northeast-1"
|
|
257
278
|
... })
|
|
258
279
|
>>>
|
|
280
|
+
>>> # 鍵なし (IRSA など boto3 の既定の探し方)
|
|
281
|
+
>>> config = S3Config.from_dict({
|
|
282
|
+
... "bucket_name": "my-bucket",
|
|
283
|
+
... "region_name": "us-east-1"
|
|
284
|
+
... })
|
|
285
|
+
>>>
|
|
259
286
|
>>> # クライアント初期化
|
|
260
287
|
>>> client = S3StorageClient(config)
|
|
261
288
|
|
|
@@ -263,8 +290,8 @@ class S3Config:
|
|
|
263
290
|
aws_access_key_id, aws_secret_access_keyはrepr=Falseでログ出力から除外されます。
|
|
264
291
|
"""
|
|
265
292
|
bucket_name: str
|
|
266
|
-
aws_access_key_id: str = field(repr=False) # シークレット: reprから除外
|
|
267
|
-
aws_secret_access_key: str = field(repr=False) # シークレット: reprから除外
|
|
293
|
+
aws_access_key_id: Optional[str] = field(default=None, repr=False) # シークレット: reprから除外
|
|
294
|
+
aws_secret_access_key: Optional[str] = field(default=None, repr=False) # シークレット: reprから除外
|
|
268
295
|
region_name: str = "us-east-1"
|
|
269
296
|
# 共通オプション
|
|
270
297
|
enabled: bool = True
|
|
@@ -277,19 +304,35 @@ class S3Config:
|
|
|
277
304
|
# S3固有オプション
|
|
278
305
|
endpoint_url: Optional[str] = None # MinIO等のS3互換ストレージ用
|
|
279
306
|
|
|
307
|
+
def __post_init__(self) -> None:
|
|
308
|
+
# 設定ファイルで `aws_access_key_id = ""` と書いた形 (SecretStr("") も) を「無し」に正規化する。
|
|
309
|
+
# 空でない値は変えない
|
|
310
|
+
self.aws_access_key_id = _blank_key_to_none(self.aws_access_key_id)
|
|
311
|
+
self.aws_secret_access_key = _blank_key_to_none(self.aws_secret_access_key)
|
|
312
|
+
|
|
280
313
|
@property
|
|
281
314
|
def provider(self) -> StorageProvider:
|
|
282
315
|
return StorageProvider.AWS_S3
|
|
283
316
|
|
|
317
|
+
@property
|
|
318
|
+
def uses_access_keys(self) -> bool:
|
|
319
|
+
"""鍵の 2 つで認証するか (False なら boto3 の既定の探し方)"""
|
|
320
|
+
return self.aws_access_key_id is not None and self.aws_secret_access_key is not None
|
|
321
|
+
|
|
284
322
|
def __str__(self) -> str:
|
|
285
|
-
|
|
323
|
+
credentials = "***" if self.uses_access_keys else "default"
|
|
324
|
+
return (
|
|
325
|
+
f"S3Config(bucket_name={self.bucket_name!r}, region_name={self.region_name!r}, "
|
|
326
|
+
f"credentials={credentials})"
|
|
327
|
+
)
|
|
286
328
|
|
|
287
329
|
@classmethod
|
|
288
330
|
def from_dict(cls, data: Dict[str, Any]) -> "S3Config":
|
|
289
331
|
"""辞書からS3Configを作成
|
|
290
332
|
|
|
291
333
|
Args:
|
|
292
|
-
data:
|
|
334
|
+
data: 設定辞書。``aws_access_key_id`` と ``aws_secret_access_key`` は
|
|
335
|
+
両方を書くか、両方を省く (省くと boto3 の既定の探し方。IRSA など)
|
|
293
336
|
|
|
294
337
|
Returns:
|
|
295
338
|
S3Config instance
|
|
@@ -301,11 +344,12 @@ class S3Config:
|
|
|
301
344
|
... "aws_secret_access_key": "secretkey",
|
|
302
345
|
... "region_name": "ap-northeast-1"
|
|
303
346
|
... })
|
|
347
|
+
>>> config = S3Config.from_dict({"bucket_name": "my-bucket"})
|
|
304
348
|
"""
|
|
305
349
|
return cls(
|
|
306
350
|
bucket_name=data["bucket_name"],
|
|
307
|
-
aws_access_key_id=data
|
|
308
|
-
aws_secret_access_key=data
|
|
351
|
+
aws_access_key_id=data.get("aws_access_key_id"),
|
|
352
|
+
aws_secret_access_key=data.get("aws_secret_access_key"),
|
|
309
353
|
region_name=data.get("region_name", "us-east-1"),
|
|
310
354
|
enabled=data.get("enabled", True),
|
|
311
355
|
max_file_size=data.get("max_file_size", 5 * 1024 * 1024 * 1024),
|
{agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/agenticstar_platform/storage/s3.py
RENAMED
|
@@ -65,6 +65,9 @@ class S3StorageClient(StorageClientBase):
|
|
|
65
65
|
)
|
|
66
66
|
client = S3StorageClient(config)
|
|
67
67
|
result = await client.upload_file("/path/to/file.txt")
|
|
68
|
+
|
|
69
|
+
# 鍵なし: boto3 の既定の探し方 (EKS の IRSA・インスタンスロールなど)
|
|
70
|
+
client = S3StorageClient(S3Config(bucket_name="my-bucket", region_name="us-east-1"))
|
|
68
71
|
"""
|
|
69
72
|
|
|
70
73
|
def __init__(self, config: S3Config):
|
|
@@ -89,20 +92,29 @@ class S3StorageClient(StorageClientBase):
|
|
|
89
92
|
if not config.bucket_name:
|
|
90
93
|
raise StorageConfigError("S3 bucket_name is required")
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
has_key_id = config.aws_access_key_id is not None
|
|
96
|
+
has_secret = config.aws_secret_access_key is not None
|
|
97
|
+
if has_key_id != has_secret:
|
|
98
|
+
# 片方だけは書き損じ。既定の探し方に黙って倒すと別の資格情報で動いてしまう
|
|
93
99
|
raise StorageConfigError(
|
|
94
|
-
"S3
|
|
100
|
+
"S3 needs both aws_access_key_id and aws_secret_access_key, or neither "
|
|
101
|
+
"(leave both out to use the default AWS credential chain, e.g. IRSA on EKS)"
|
|
95
102
|
)
|
|
96
103
|
|
|
97
104
|
self._s3_config: S3Config = config
|
|
98
105
|
self._s3_client = None
|
|
99
106
|
|
|
100
107
|
try:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
if config.uses_access_keys:
|
|
109
|
+
session = boto3.Session(
|
|
110
|
+
aws_access_key_id=self._get_api_key(config.aws_access_key_id),
|
|
111
|
+
aws_secret_access_key=self._get_api_key(config.aws_secret_access_key),
|
|
112
|
+
region_name=config.region_name,
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
# 鍵を渡さない: boto3 の既定の探し方に任せる(IRSA(AWS_ROLE_ARN・AWS_WEB_IDENTITY_TOKEN_FILE)・
|
|
116
|
+
# 環境変数・~/.aws・EKS Pod Identity・インスタンスロールなど。どれを先に使うかは boto3 が決める)
|
|
117
|
+
session = boto3.Session(region_name=config.region_name)
|
|
106
118
|
|
|
107
119
|
client_kwargs = {}
|
|
108
120
|
if config.endpoint_url:
|
|
@@ -113,7 +125,8 @@ class S3StorageClient(StorageClientBase):
|
|
|
113
125
|
|
|
114
126
|
logger.info(
|
|
115
127
|
f"S3StorageClient initialized - bucket={config.bucket_name}, "
|
|
116
|
-
f"region={config.region_name}"
|
|
128
|
+
f"region={config.region_name}, "
|
|
129
|
+
f"credentials={'access_keys' if config.uses_access_keys else 'default_chain'}"
|
|
117
130
|
)
|
|
118
131
|
|
|
119
132
|
except Exception as e:
|
{agenticstar_platform-3.2.1 → agenticstar_platform-3.2.3}/tests/events/test_handler_type_routing.py
RENAMED
|
@@ -16,7 +16,7 @@ aiohttp = pytest.importorskip("aiohttp")
|
|
|
16
16
|
from aiohttp import web # noqa: E402
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
async def _receive_payloads(events):
|
|
19
|
+
async def _receive_payloads(events, make_handler=None):
|
|
20
20
|
"""実 HTTP サーバーを起動し、events を送信して受信ペイロード一覧を返す"""
|
|
21
21
|
received = []
|
|
22
22
|
|
|
@@ -33,8 +33,9 @@ async def _receive_payloads(events):
|
|
|
33
33
|
port = site._server.sockets[0].getsockname()[1]
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
url = f"http://127.0.0.1:{port}/webhook/notify"
|
|
37
|
+
handler = make_handler(url) if make_handler else WebhookEventHandler(
|
|
38
|
+
webhook_url=url,
|
|
38
39
|
conversation_id="conv-1",
|
|
39
40
|
message_id="msg-1",
|
|
40
41
|
request_source="external",
|
|
@@ -84,6 +85,62 @@ async def test_webhook_top_level_type_routing():
|
|
|
84
85
|
assert all(p["data"]["request_source"] == "external" for p in payloads)
|
|
85
86
|
|
|
86
87
|
|
|
88
|
+
class _AcceptingDataAccess:
|
|
89
|
+
"""DatabaseEventHandler の保存先の代わり(insert を記録して成功を返す)"""
|
|
90
|
+
|
|
91
|
+
def __init__(self):
|
|
92
|
+
self.rows = []
|
|
93
|
+
|
|
94
|
+
async def insert(self, table, row):
|
|
95
|
+
self.rows.append((table, row))
|
|
96
|
+
return {"success": True}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def test_marketplace_handler_sends_failure_as_stop_like_the_worker():
|
|
100
|
+
"""create_marketplace_handler は失敗の完了も finish_reason "stop"(3.2.3)。
|
|
101
|
+
|
|
102
|
+
受信側(chatboardfront monitoring.js)は "stop" のときだけメッセージを終わらせ、"error" は読まない。
|
|
103
|
+
本体 PodWebhookSubscriber も COMPLETION_FAILURE を "stop" で送る。途中のイベントには付けない。
|
|
104
|
+
run_marketplace_agent もこの handler を使う。
|
|
105
|
+
"""
|
|
106
|
+
from agenticstar_platform.events.handlers import create_marketplace_handler
|
|
107
|
+
|
|
108
|
+
data_access = _AcceptingDataAccess()
|
|
109
|
+
payloads = await _receive_payloads(
|
|
110
|
+
[
|
|
111
|
+
StreamingEvent(EventType.PHASE_START, "e1", "処理開始"),
|
|
112
|
+
StreamingEvent(EventType.COMPLETION_FAILURE, "e1", "agent failed: ValueError: boom"),
|
|
113
|
+
],
|
|
114
|
+
make_handler=lambda url: create_marketplace_handler(
|
|
115
|
+
data_access=data_access, webhook_url=url, user_id="u1",
|
|
116
|
+
conversation_id="conv-1", message_id="msg-1", request_source="internal",
|
|
117
|
+
token_provider=lambda: None,
|
|
118
|
+
),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
assert payloads[0]["data"]["finish_reason"] is None
|
|
122
|
+
assert payloads[1]["type"] == "append_message"
|
|
123
|
+
assert payloads[1]["data"]["chunk_type"] == "content"
|
|
124
|
+
assert payloads[1]["data"]["content"] == {"content": "agent failed: ValueError: boom"}
|
|
125
|
+
assert payloads[1]["data"]["finish_reason"] == "stop"
|
|
126
|
+
assert len(data_access.rows) == 2 # DB への保存は今どおり
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
async def test_webhook_handler_keeps_error_for_failure_by_default():
|
|
130
|
+
"""WebhookEventHandler を単体で使う受け口は今どおり "error"(3.2.3 の後も変わらない)。引数で "stop" にできる"""
|
|
131
|
+
failure = StreamingEvent(EventType.COMPLETION_FAILURE, "e1", "boom")
|
|
132
|
+
default = await _receive_payloads([failure])
|
|
133
|
+
assert default[0]["data"]["finish_reason"] == "error"
|
|
134
|
+
|
|
135
|
+
stop = await _receive_payloads(
|
|
136
|
+
[failure],
|
|
137
|
+
make_handler=lambda url: WebhookEventHandler(
|
|
138
|
+
webhook_url=url, conversation_id="conv-1", message_id="msg-1", failure_finish_reason="stop",
|
|
139
|
+
),
|
|
140
|
+
)
|
|
141
|
+
assert stop[0]["data"]["finish_reason"] == "stop"
|
|
142
|
+
|
|
143
|
+
|
|
87
144
|
def test_build_content_data_shapes():
|
|
88
145
|
vnc = StreamingEvent(
|
|
89
146
|
EventType.HITL_REQUIRED_BROWSER_VNC, "e1", "VNC", metadata={"vnc_url": "u"},
|