agentengine-sdk-python 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl
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.
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
- agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
- ksadk/a2a/__init__.py +2 -0
- ksadk/a2a/_space_client_events.py +381 -0
- ksadk/a2a/bootstrap.py +0 -2
- ksadk/a2a/card.py +6 -111
- ksadk/a2a/control_plane.py +239 -1
- ksadk/a2a/event_adapter.py +156 -64
- ksadk/a2a/executor.py +195 -172
- ksadk/a2a/routes.py +12 -5
- ksadk/a2a/server.py +1 -8
- ksadk/a2a/service_env.py +33 -0
- ksadk/a2a/space_client.py +43 -349
- ksadk/a2a_card.py +101 -0
- ksadk/a2ui/core.py +222 -53
- ksadk/agui/_agent_helpers.py +243 -0
- ksadk/agui/a2ui_projection.py +12 -5
- ksadk/agui/agent.py +474 -275
- ksadk/agui/config.py +11 -5
- ksadk/agui/routes.py +7 -15
- ksadk/api/client.py +530 -40
- ksadk/api/environment.py +27 -0
- ksadk/builders/code_builder.py +352 -53
- ksadk/builders/container_builder.py +71 -44
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +2 -2
- ksadk/builders/managed_runtime_builder.py +60 -28
- ksadk/cli/__init__.py +25 -0
- ksadk/cli/cmd_a2a.py +18 -31
- ksadk/cli/cmd_create.py +13 -26
- ksadk/cli/cmd_dashboard.py +15 -1
- ksadk/cli/cmd_deploy.py +28 -3
- ksadk/cli/cmd_eval.py +443 -0
- ksadk/cli/cmd_evalset.py +284 -0
- ksadk/cli/cmd_files.py +5 -1
- ksadk/cli/cmd_hermes.py +137 -163
- ksadk/cli/cmd_invoke.py +28 -38
- ksadk/cli/cmd_launch.py +12 -0
- ksadk/cli/cmd_managed_runtime.py +95 -0
- ksadk/cli/cmd_observe.py +85 -0
- ksadk/cli/cmd_openclaw.py +85 -479
- ksadk/cli/cmd_replay.py +28 -4
- ksadk/cli/cmd_run.py +29 -67
- ksadk/cli/cmd_studio.py +201 -0
- ksadk/cli/cmd_web.py +15 -6
- ksadk/cli/dry_run.py +2 -1
- ksadk/cli/env_options.py +83 -0
- ksadk/cli/global_options.py +3 -1
- ksadk/cli/hermes_env.py +151 -0
- ksadk/cli/invoke_payload.py +49 -0
- ksadk/cli/network_options.py +7 -5
- ksadk/cli/openclaw_env.py +458 -0
- ksadk/cli/runtime_bootstrap.py +51 -0
- ksadk/cli/ui.py +6 -0
- ksadk/cli/workflow_common.py +5 -5
- ksadk/codex/__init__.py +3 -3
- ksadk/codex/client.py +833 -49
- ksadk/codex/phase.py +1 -1
- ksadk/codex/runtime.py +720 -127
- ksadk/common/kop_client.py +232 -0
- ksadk/configs/__init__.py +1 -3
- ksadk/configs/env_registry.py +244 -45
- ksadk/configs/env_registry_pcm.py +181 -0
- ksadk/configs/env_var_spec.py +18 -0
- ksadk/configs/global_config.py +6 -1
- ksadk/configs/settings.py +5 -108
- ksadk/context_engine/__init__.py +98 -0
- ksadk/context_engine/assembler.py +176 -0
- ksadk/context_engine/baseline.py +419 -0
- ksadk/context_engine/cache_observability.py +228 -0
- ksadk/context_engine/capabilities.py +443 -0
- ksadk/context_engine/contributors.py +344 -0
- ksadk/context_engine/hosted_pipeline.py +417 -0
- ksadk/context_engine/models.py +117 -0
- ksadk/context_engine/planner.py +698 -0
- ksadk/context_engine/policies.py +319 -0
- ksadk/context_engine/projection.py +31 -0
- ksadk/context_engine/shadow_plan.py +266 -0
- ksadk/context_engine/tokenizer.py +164 -0
- ksadk/conversations/__init__.py +85 -94
- ksadk/conversations/context.py +126 -6
- ksadk/conversations/message_projection.py +292 -28
- ksadk/conversations/model_context.py +49 -3
- ksadk/conversations/runtime_compaction.py +207 -5
- ksadk/conversations/runtime_input.py +193 -3
- ksadk/conversations/runtime_invocation.py +81 -3
- ksadk/conversations/runtime_observability.py +157 -4
- ksadk/conversations/runtime_payloads.py +42 -0
- ksadk/conversations/runtime_preparation.py +280 -2
- ksadk/conversations/runtime_resume.py +71 -32
- ksadk/conversations/runtime_stream_events.py +94 -9
- ksadk/conversations/runtime_streaming.py +175 -22
- ksadk/conversations/semantic_summary.py +311 -1
- ksadk/conversations/session_lock.py +51 -0
- ksadk/deployment/env_forward.py +72 -0
- ksadk/deployment/managed_runtime.py +38 -0
- ksadk/deployment/manager.py +24 -8
- ksadk/deployment/providers/serverless.py +228 -92
- ksadk/evaluation/__init__.py +116 -0
- ksadk/evaluation/a2a_adapter.py +452 -0
- ksadk/evaluation/adapters.py +67 -0
- ksadk/evaluation/agent_eval_client.py +395 -0
- ksadk/evaluation/cloud_binding.py +80 -0
- ksadk/evaluation/cloud_converter.py +194 -0
- ksadk/evaluation/cloud_service.py +199 -0
- ksadk/evaluation/contracts.py +478 -0
- ksadk/evaluation/evalset.py +351 -0
- ksadk/evaluation/evaluators.py +627 -0
- ksadk/evaluation/evidence.py +258 -0
- ksadk/evaluation/executor.py +143 -0
- ksadk/evaluation/local_adapter.py +550 -0
- ksadk/evaluation/service_env.py +27 -0
- ksadk/evaluation/storage.py +68 -0
- ksadk/evaluation/studio_build_adapter.py +253 -0
- ksadk/evaluation/target.py +82 -0
- ksadk/events/__init__.py +13 -13
- ksadk/events/_v1_compat/__init__.py +1 -0
- ksadk/events/_v1_compat/models.py +299 -0
- ksadk/events/_v1_compat/parser.py +247 -0
- ksadk/events/_v1_compat/projection.py +753 -0
- ksadk/events/adapters/__init__.py +34 -0
- ksadk/events/adapters/_a2a_snapshot.py +622 -0
- ksadk/events/adapters/_a2a_support.py +275 -0
- ksadk/events/adapters/_codex_interactions.py +375 -0
- ksadk/events/adapters/_codex_items.py +801 -0
- ksadk/events/adapters/_codex_validators.py +311 -0
- ksadk/events/adapters/_langgraph_support.py +785 -0
- ksadk/events/adapters/a2a.py +841 -0
- ksadk/events/adapters/adk.py +503 -0
- ksadk/events/adapters/codex.py +717 -0
- ksadk/events/adapters/langgraph.py +745 -0
- ksadk/events/canonical.py +440 -0
- ksadk/events/canonical_replay.py +497 -0
- ksadk/events/canonical_store.py +468 -0
- ksadk/events/cold_recovery.py +257 -0
- ksadk/events/content.py +89 -0
- ksadk/events/identity.py +86 -0
- ksadk/events/pipeline.py +455 -0
- ksadk/events/projections.py +66 -0
- ksadk/events/reducer.py +661 -0
- ksadk/events/replay.py +3 -36
- ksadk/events/runtime_event.py +20 -256
- ksadk/events/session_event.py +324 -0
- ksadk/events/store.py +3 -316
- ksadk/events/v1_compat.py +41 -0
- ksadk/harness/__init__.py +3 -2
- ksadk/harness/app.py +114 -123
- ksadk/harness/config.py +1 -1
- ksadk/harness/runtime.py +467 -0
- ksadk/hermes_terminal.py +5 -0
- ksadk/identity/resolver.py +4 -3
- ksadk/interaction/__init__.py +28 -0
- ksadk/interaction/contracts.py +136 -0
- ksadk/interaction/ledger.py +189 -0
- ksadk/interaction/provider.py +122 -0
- ksadk/interaction/providers/__init__.py +52 -0
- ksadk/interaction/providers/adk.py +40 -0
- ksadk/interaction/providers/codex.py +94 -0
- ksadk/interaction/providers/langgraph.py +58 -0
- ksadk/kernel/__init__.py +117 -0
- ksadk/kernel/authorization.py +258 -0
- ksadk/kernel/bootstrap.py +1074 -0
- ksadk/kernel/contract_fingerprints.py +61 -0
- ksadk/kernel/contracts.py +362 -0
- ksadk/kernel/control.py +219 -0
- ksadk/kernel/errors.py +79 -0
- ksadk/kernel/ingress.py +1102 -0
- ksadk/kernel/mapping.py +111 -0
- ksadk/kernel/memory_store.py +1133 -0
- ksadk/kernel/postgres_store.py +1756 -0
- ksadk/kernel/recovery.py +452 -0
- ksadk/kernel/runtime_identity.py +103 -0
- ksadk/kernel/sql/001_agent_kernel.sql +120 -0
- ksadk/kernel/sqlite_store.py +1410 -0
- ksadk/kernel/state.py +145 -0
- ksadk/kernel/store.py +232 -0
- ksadk/kernel/worker.py +953 -0
- ksadk/knowledge_base/client.py +22 -4
- ksadk/knowledge_base/service.py +32 -5
- ksadk/managed_a2a_card.py +160 -0
- ksadk/managed_runtime.py +16 -9
- ksadk/memory/__init__.py +61 -0
- ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
- ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
- ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
- ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
- ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
- ksadk/memory/adk/long_term_memory.py +3 -2
- ksadk/memory/coordinator.py +461 -0
- ksadk/memory/events.py +202 -0
- ksadk/memory/extraction.py +228 -0
- ksadk/memory/ltm_backend_factory.py +16 -3
- ksadk/memory/models.py +316 -0
- ksadk/memory/policy.py +215 -0
- ksadk/memory/provider.py +47 -0
- ksadk/memory/provider_adapter.py +159 -0
- ksadk/memory/provider_resolver.py +71 -0
- ksadk/memory/providers/__init__.py +5 -0
- ksadk/memory/providers/local_sqlite.py +490 -0
- ksadk/memory/resolved_policy.py +145 -0
- ksadk/memory/service.py +198 -8
- ksadk/memory/tool.py +4 -0
- ksadk/model_proxy/bootstrap.py +16 -9
- ksadk/model_proxy/config.py +22 -1
- ksadk/model_proxy/detect.py +202 -9
- ksadk/model_proxy/namespace.py +67 -15
- ksadk/model_proxy/server.py +168 -6
- ksadk/model_proxy/transform.py +105 -3
- ksadk/observability/__init__.py +25 -0
- ksadk/observability/session_log.py +420 -0
- ksadk/observability/trajectory.py +105 -0
- ksadk/prompts/__init__.py +71 -0
- ksadk/prompts/compiler.py +215 -0
- ksadk/prompts/models.py +82 -0
- ksadk/prompts/projection.py +89 -0
- ksadk/prompts/resolved.py +137 -0
- ksadk/prompts/sources.py +233 -0
- ksadk/runners/_langgraph_runner_streams.py +822 -0
- ksadk/runners/adk_runner.py +14 -31
- ksadk/runners/base_runner.py +44 -3
- ksadk/runners/factory.py +3 -3
- ksadk/runners/langgraph_runner.py +252 -433
- ksadk/runners/utils/__init__.py +0 -10
- ksadk/runners/utils/loader.py +16 -0
- ksadk/runtime/__init__.py +67 -41
- ksadk/runtime/_runner_adapter/__init__.py +1 -0
- ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
- ksadk/runtime/adapter.py +199 -16
- ksadk/runtime/conversation_execution.py +687 -0
- ksadk/runtime/executor.py +392 -0
- ksadk/runtime/factory.py +342 -0
- ksadk/runtime/framework_adapters.py +6 -12
- ksadk/runtime/hosted_finalizer.py +268 -0
- ksadk/runtime/launch.py +61 -0
- ksadk/runtime/preprocessing.py +49 -14
- ksadk/runtime/runner_adapter.py +330 -391
- ksadk/runtime/runner_loading.py +36 -0
- ksadk/runtime/usage.py +33 -0
- ksadk/sandbox/backends/e2b.py +36 -3
- ksadk/server/__init__.py +39 -4
- ksadk/server/app.py +18 -492
- ksadk/server/composition.py +36 -2
- ksadk/server/factory.py +210 -149
- ksadk/server/routes/common.py +15 -46
- ksadk/server/routes/control.py +13 -9
- ksadk/server/routes/kernel_ingress.py +258 -0
- ksadk/server/routes/misc.py +10 -33
- ksadk/server/routes/models.py +14 -6
- ksadk/server/routes/openai_compat.py +129 -27
- ksadk/server/routes/projection.py +84 -16
- ksadk/server/routes/run.py +347 -460
- ksadk/server/routes/sessions.py +37 -40
- ksadk/server/routes/streaming.py +52 -7
- ksadk/server/routes/workspace.py +54 -21
- ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
- ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
- ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
- ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
- ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
- ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
- ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
- ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
- ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
- ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
- ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
- ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
- ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
- ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
- ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
- ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
- ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
- ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
- ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
- ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
- ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
- ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
- ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
- ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
- ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
- ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
- ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
- ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
- ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
- ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
- ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
- ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
- ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
- ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
- ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
- ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
- ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
- ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
- ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
- ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
- ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
- ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
- ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
- ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
- ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
- ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
- ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
- ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
- ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
- ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
- ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
- ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
- ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
- ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
- ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
- ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
- ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
- ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
- ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
- ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
- ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
- ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
- ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
- ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
- ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
- ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
- ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
- ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
- ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
- ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
- ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
- ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
- ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
- ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
- ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
- ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
- ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
- ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
- ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
- ksadk/server/static/index.html +2 -2
- ksadk/sessions/__init__.py +26 -9
- ksadk/sessions/_local_service_sync.py +688 -0
- ksadk/sessions/_local_tables.py +21 -0
- ksadk/sessions/_postgres_schema.py +305 -0
- ksadk/sessions/_postgres_tables.py +15 -0
- ksadk/sessions/base.py +80 -1
- ksadk/sessions/in_memory.py +53 -2
- ksadk/sessions/local_service.py +63 -604
- ksadk/sessions/postgres_service.py +58 -148
- ksadk/sessions/resilient.py +35 -1
- ksadk/skills/runtime/backends/e2b.py +1 -1
- ksadk/skills/service_client.py +13 -3
- ksadk/studio/__init__.py +5 -0
- ksadk/studio/agent_avatar_assets.py +120 -0
- ksadk/studio/agent_lifecycle.py +51 -0
- ksadk/studio/api.py +1598 -0
- ksadk/studio/api_catalog_routes.py +324 -0
- ksadk/studio/api_contracts.py +286 -0
- ksadk/studio/api_helpers.py +132 -0
- ksadk/studio/api_memory_routes.py +82 -0
- ksadk/studio/authoring.py +749 -0
- ksadk/studio/authoring_coordinator.py +1017 -0
- ksadk/studio/builder.py +397 -0
- ksadk/studio/capabilities.py +368 -0
- ksadk/studio/cloud.py +2099 -0
- ksadk/studio/codex_agent_service.py +694 -0
- ksadk/studio/codex_authoring.py +469 -0
- ksadk/studio/codex_builder.py +437 -0
- ksadk/studio/codex_manifest.py +307 -0
- ksadk/studio/codex_run.py +395 -0
- ksadk/studio/compiler.py +190 -0
- ksadk/studio/contracts.py +755 -0
- ksadk/studio/errors.py +47 -0
- ksadk/studio/event_store.py +214 -0
- ksadk/studio/framework_run.py +342 -0
- ksadk/studio/hosted_kernel.py +317 -0
- ksadk/studio/identifiers.py +33 -0
- ksadk/studio/manifest_resolver.py +131 -0
- ksadk/studio/mcp_runtime.py +229 -0
- ksadk/studio/model_client.py +629 -0
- ksadk/studio/model_profile_service.py +214 -0
- ksadk/studio/operations.py +275 -0
- ksadk/studio/otel_trace.py +1060 -0
- ksadk/studio/pagination.py +182 -0
- ksadk/studio/pcm_memory.py +85 -0
- ksadk/studio/python_tool_inspection.py +183 -0
- ksadk/studio/repository.py +327 -0
- ksadk/studio/resource_catalog.py +1260 -0
- ksadk/studio/run_service.py +1133 -0
- ksadk/studio/runtime_catalog.py +74 -0
- ksadk/studio/runtime_source.py +365 -0
- ksadk/studio/service.py +2249 -0
- ksadk/studio/shared_web.py +1004 -0
- ksadk/studio/skill_discovery.py +628 -0
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
- ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
- ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
- ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
- ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
- ksadk/studio/static/index.html +15 -0
- ksadk/studio/templates.py +722 -0
- ksadk/studio/validator.py +265 -0
- ksadk/studio/workspace.py +135 -0
- ksadk/tools/gateway.py +9 -0
- ksadk/toolsets/__init__.py +27 -1
- ksadk/toolsets/a2a.py +426 -0
- ksadk/tracing/__init__.py +19 -21
- ksadk/tracing/setup.py +317 -403
- ksadk/tracing/span_utils.py +0 -44
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/registry.py +56 -56
- ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
- ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
- ksadk_runtime_common/workspace_files/router.py +8 -2
- agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
- ksadk/a2a/card_builder.py +0 -64
- ksadk/a2a/client.py +0 -309
- ksadk/events/parser.py +0 -191
- ksadk/harness/runner.py +0 -211
- ksadk/runners/codex_runner.py +0 -132
- ksadk/runners/utils/langfuse.py +0 -230
- ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
- ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
- ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
- ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
- ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
- ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
- ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
- ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
- ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
- ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
- ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
- ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
- ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
- ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
- ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
- ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
- ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
- ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
- ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
- ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
- ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
- ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
- ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
- ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
- ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
- ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
- ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
- ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
- ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
- ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
- ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
- ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
- ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
- ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
- ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
- ksadk/server/static/assets/katex-DATssjp1.js +0 -265
- ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
- ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
- ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
- ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
- ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
- ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
- ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
- ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
- ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
- ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
- ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
- ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
- ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
- ksadk/tracing/exporters/langfuse_exporter.py +0 -460
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
3
5
|
import uuid
|
|
4
6
|
from typing import Any, Callable, Dict, Mapping, Optional, Sequence
|
|
5
7
|
|
|
@@ -13,6 +15,8 @@ from ksadk.conversations.context import (
|
|
|
13
15
|
)
|
|
14
16
|
from ksadk.conversations.model_context import (
|
|
15
17
|
estimate_text_tokens,
|
|
18
|
+
get_auto_compact_hard_limit_tokens,
|
|
19
|
+
get_auto_compact_soft_limit_tokens,
|
|
16
20
|
get_auto_compact_threshold_percentage,
|
|
17
21
|
get_auto_compact_threshold_tokens,
|
|
18
22
|
)
|
|
@@ -33,11 +37,14 @@ from ksadk.conversations.runtime_payloads import CompactionPlan
|
|
|
33
37
|
from ksadk.conversations.runtime_persistence import append_context_checkpoint_event
|
|
34
38
|
from ksadk.conversations.semantic_summary import (
|
|
35
39
|
extract_pinned_state,
|
|
40
|
+
extract_working_state,
|
|
36
41
|
find_pinned_group_indexes,
|
|
37
42
|
summarize_compaction,
|
|
38
43
|
)
|
|
39
44
|
from ksadk.sessions import SessionEvent, resolve_session_service
|
|
40
45
|
|
|
46
|
+
logger = logging.getLogger(__name__)
|
|
47
|
+
|
|
41
48
|
|
|
42
49
|
def _plan_compaction(
|
|
43
50
|
events: Sequence[SessionEvent],
|
|
@@ -47,8 +54,19 @@ def _plan_compaction(
|
|
|
47
54
|
pending_events: Sequence[SessionEvent] | None = None,
|
|
48
55
|
force: bool = False,
|
|
49
56
|
keep_tail_groups: int | None = None,
|
|
57
|
+
prompt_integration_mode: str = "",
|
|
58
|
+
compaction_owner: str = "",
|
|
50
59
|
) -> CompactionPlan:
|
|
51
|
-
"""根据当前 transcript 计算是否需要做 checkpoint compaction。
|
|
60
|
+
"""根据当前 transcript 计算是否需要做 checkpoint compaction。
|
|
61
|
+
|
|
62
|
+
``compaction_owner=="ksadk"`` 时走双阈值(soft 50% / hard ~84%),命中且
|
|
63
|
+
``len(groups) > tail_groups`` 时触发 proactive compact(soft=整理,hard=强制止血)。
|
|
64
|
+
未显式提供 owner 的旧调用继续以 ``ksadk_hosted`` 作为兼容判据。
|
|
65
|
+
``force=True``(PTL)始终绕过阈值,``trigger_band="emergency"``。
|
|
66
|
+
|
|
67
|
+
compaction_owner 硬门控(方案 §6.2):native/framework owner 不运行 KsADK 第二套
|
|
68
|
+
压缩;framework-assisted Runner 可显式声明 owner=ksadk 使用平台压缩。
|
|
69
|
+
"""
|
|
52
70
|
|
|
53
71
|
compacted_until = compacted_until_seq_id(list(events))
|
|
54
72
|
transcript_events = [
|
|
@@ -82,9 +100,46 @@ def _plan_compaction(
|
|
|
82
100
|
total_estimated_tokens = sum(
|
|
83
101
|
estimate_text_tokens(extract_event_text(event)) for event in combined_events
|
|
84
102
|
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
# 是否启用双阈值由 compaction ownership 决定,而不是由 Prompt 接管模式决定。
|
|
104
|
+
# framework-assisted LangGraph 也可以把压缩明确交给 KsADK;native/framework
|
|
105
|
+
# owner 则继续使用各自原生机制,避免双重压缩。
|
|
106
|
+
is_ksadk_hosted = compaction_owner == "ksadk" or (
|
|
107
|
+
not compaction_owner and prompt_integration_mode == "ksadk_hosted"
|
|
108
|
+
)
|
|
109
|
+
soft_limit_tokens = (
|
|
110
|
+
get_auto_compact_soft_limit_tokens(resolved_model_metadata) if is_ksadk_hosted else None
|
|
111
|
+
)
|
|
112
|
+
hard_limit_tokens = (
|
|
113
|
+
get_auto_compact_hard_limit_tokens(resolved_model_metadata) if is_ksadk_hosted else None
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# 触发带判定。force(PTL)优先 → emergency,绕过阈值。
|
|
117
|
+
groups_enough = len(groups) > tail_groups
|
|
118
|
+
if force:
|
|
119
|
+
trigger_band = "emergency"
|
|
120
|
+
should_by_threshold = True
|
|
121
|
+
elif is_ksadk_hosted and soft_limit_tokens is not None and hard_limit_tokens is not None:
|
|
122
|
+
# 双阈值:hard 优先于 soft。二者都需 groups 充足,否则 none(避免每轮压缩)。
|
|
123
|
+
if not groups_enough:
|
|
124
|
+
trigger_band = "none"
|
|
125
|
+
should_by_threshold = False
|
|
126
|
+
elif total_estimated_tokens > hard_limit_tokens:
|
|
127
|
+
trigger_band = "hard"
|
|
128
|
+
should_by_threshold = True
|
|
129
|
+
elif total_estimated_tokens > soft_limit_tokens:
|
|
130
|
+
trigger_band = "soft"
|
|
131
|
+
should_by_threshold = True
|
|
132
|
+
else:
|
|
133
|
+
trigger_band = "none"
|
|
134
|
+
should_by_threshold = False
|
|
135
|
+
else:
|
|
136
|
+
# 非 ksadk_hosted → 旧单阈值。trigger_band="" 表示门控未启用(旧路径)。
|
|
137
|
+
trigger_band = ""
|
|
138
|
+
should_by_threshold = total_estimated_tokens > auto_compact_threshold_tokens
|
|
139
|
+
|
|
140
|
+
# early-return:groups 不足或(非 force 且未超阈值)。保留 len(groups)<=tail_groups 早退,
|
|
141
|
+
# 避免每轮压缩。force 仍绕过此早退的阈值部分,但 groups 不足时 force 也无可压缩(下方)。
|
|
142
|
+
if not force and (len(groups) <= tail_groups or not should_by_threshold):
|
|
88
143
|
return CompactionPlan(
|
|
89
144
|
should_compact=False,
|
|
90
145
|
groups_to_compact=[],
|
|
@@ -96,6 +151,9 @@ def _plan_compaction(
|
|
|
96
151
|
auto_compact_threshold_percentage=auto_compact_threshold_percentage,
|
|
97
152
|
pinned_group_indexes=pinned_group_indexes,
|
|
98
153
|
pinned_state=pinned_state,
|
|
154
|
+
soft_limit_tokens=soft_limit_tokens,
|
|
155
|
+
hard_limit_tokens=hard_limit_tokens,
|
|
156
|
+
trigger_band=trigger_band,
|
|
99
157
|
)
|
|
100
158
|
|
|
101
159
|
compactable_indexes = [
|
|
@@ -121,6 +179,9 @@ def _plan_compaction(
|
|
|
121
179
|
auto_compact_threshold_percentage=auto_compact_threshold_percentage,
|
|
122
180
|
pinned_group_indexes=pinned_group_indexes,
|
|
123
181
|
pinned_state=pinned_state,
|
|
182
|
+
soft_limit_tokens=soft_limit_tokens,
|
|
183
|
+
hard_limit_tokens=hard_limit_tokens,
|
|
184
|
+
trigger_band=trigger_band,
|
|
124
185
|
)
|
|
125
186
|
|
|
126
187
|
compacted_until_seq_id_value = groups_to_compact[-1][-1].seq_id or None
|
|
@@ -136,6 +197,9 @@ def _plan_compaction(
|
|
|
136
197
|
compacted_until_seq_id=compacted_until_seq_id_value,
|
|
137
198
|
pinned_group_indexes=pinned_group_indexes,
|
|
138
199
|
pinned_state=pinned_state,
|
|
200
|
+
soft_limit_tokens=soft_limit_tokens,
|
|
201
|
+
hard_limit_tokens=hard_limit_tokens,
|
|
202
|
+
trigger_band=trigger_band,
|
|
139
203
|
)
|
|
140
204
|
|
|
141
205
|
|
|
@@ -148,6 +212,7 @@ async def preview_auto_compaction(
|
|
|
148
212
|
model: Optional[str] = None,
|
|
149
213
|
model_metadata: Mapping[str, Any] | None = None,
|
|
150
214
|
session_service_provider: Callable[[], Any] | None = None,
|
|
215
|
+
prompt_integration_mode: str = "",
|
|
151
216
|
) -> CompactionPlan:
|
|
152
217
|
"""在真正写入 turn 之前预估是否会触发自动压缩。
|
|
153
218
|
|
|
@@ -214,9 +279,81 @@ async def preview_auto_compaction(
|
|
|
214
279
|
model=model,
|
|
215
280
|
model_metadata=resolved_model_metadata,
|
|
216
281
|
pending_events=[pending_event],
|
|
282
|
+
prompt_integration_mode=prompt_integration_mode,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _working_state_from_checkpoint(checkpoint: Any) -> Any:
|
|
287
|
+
"""§8.1:从上一个 context_checkpoint 事件解析 WorkingState(用于缺失字段合并)。
|
|
288
|
+
|
|
289
|
+
checkpoint metadata 由 compact_conversation_history 写入(仅 ksadk_hosted)。无 checkpoint
|
|
290
|
+
或无 working_state 键时返回 None。重建的 WorkingState 仅用于回填 current_goal/constraints
|
|
291
|
+
等关键字段,不恢复 pending_tools/approvals(那些以事实事件为准)。
|
|
292
|
+
"""
|
|
293
|
+
if checkpoint is None:
|
|
294
|
+
return None
|
|
295
|
+
meta = getattr(checkpoint, "metadata", None) or {}
|
|
296
|
+
ws_audit = meta.get("working_state")
|
|
297
|
+
if not isinstance(ws_audit, dict):
|
|
298
|
+
return None
|
|
299
|
+
from ksadk.conversations.semantic_summary import WorkingState
|
|
300
|
+
|
|
301
|
+
return WorkingState(
|
|
302
|
+
current_goal=str(ws_audit.get("current_goal") or ""),
|
|
303
|
+
next_action=ws_audit.get("next_action"),
|
|
304
|
+
completed_steps=list(ws_audit.get("completed_steps") or []),
|
|
305
|
+
constraints=list(ws_audit.get("constraints") or []),
|
|
306
|
+
source_seq_range=tuple(ws_audit.get("source_seq_range") or (0, 0)), # type: ignore[arg-type]
|
|
217
307
|
)
|
|
218
308
|
|
|
219
309
|
|
|
310
|
+
async def _maybe_memory_flush(
|
|
311
|
+
events: Sequence[SessionEvent],
|
|
312
|
+
*,
|
|
313
|
+
user_id: str = "",
|
|
314
|
+
agent_id: str = "",
|
|
315
|
+
) -> dict[str, Any] | None:
|
|
316
|
+
"""压缩前 best-effort Memory Flush(方案 §9.2)。
|
|
317
|
+
|
|
318
|
+
门控:``KSADK_MEMORY_FLUSH_ENABLED``(默认关,避免在无 Memory Provider 时改变行为)+
|
|
319
|
+
``KSADK_MEMORY_FLUSH_BEFORE_COMPACTION``(默认开,但需前者总开关)。提取候选交
|
|
320
|
+
``MemoryCoordinator.flush_candidates``,Policy 决定 commit/reject。失败返回 ``failed``,不抛。
|
|
321
|
+
"""
|
|
322
|
+
import os as _os
|
|
323
|
+
|
|
324
|
+
if _os.environ.get("KSADK_MEMORY_FLUSH_ENABLED", "").strip().lower() not in (
|
|
325
|
+
"1",
|
|
326
|
+
"true",
|
|
327
|
+
"yes",
|
|
328
|
+
"on",
|
|
329
|
+
):
|
|
330
|
+
return None
|
|
331
|
+
try:
|
|
332
|
+
from ksadk.context_engine.policies import ContextPolicy
|
|
333
|
+
from ksadk.memory.coordinator import MemoryCoordinator
|
|
334
|
+
from ksadk.memory.extraction import propose_memory_candidates
|
|
335
|
+
from ksadk.memory.providers.local_sqlite import resolve_default_memory_provider
|
|
336
|
+
|
|
337
|
+
policy = ContextPolicy.from_env()
|
|
338
|
+
if not policy.compaction.flush_memory_before_compaction:
|
|
339
|
+
return None
|
|
340
|
+
# 持久化 Memory Provider(替换临时 :memory:,方案 §10/§12)。云端应经
|
|
341
|
+
# LongTermMemoryService/HTTP/SDK Provider;本地默认 SQLite 文件库。
|
|
342
|
+
provider = resolve_default_memory_provider()
|
|
343
|
+
coordinator = MemoryCoordinator(provider)
|
|
344
|
+
from ksadk.memory.coordinator import agent_user_scope_id
|
|
345
|
+
|
|
346
|
+
_scope_id = agent_user_scope_id(agent_id=agent_id, user_id=str(user_id or ""))
|
|
347
|
+
candidates = propose_memory_candidates(list(events), scope="user", scope_id=_scope_id)
|
|
348
|
+
if not candidates:
|
|
349
|
+
return {"status": "skipped", "proposed": 0, "committed": 0, "rejected": 0}
|
|
350
|
+
result = coordinator.flush_candidates(candidates)
|
|
351
|
+
return result.to_audit_dict()
|
|
352
|
+
except Exception as exc: # noqa: BLE001
|
|
353
|
+
logger.warning("memory flush failed: %s", exc)
|
|
354
|
+
return {"status": "failed", "error": str(exc), "proposed": 0, "committed": 0, "rejected": 0}
|
|
355
|
+
|
|
356
|
+
|
|
220
357
|
async def compact_conversation_history(
|
|
221
358
|
*,
|
|
222
359
|
session_id: str,
|
|
@@ -228,21 +365,29 @@ async def compact_conversation_history(
|
|
|
228
365
|
trigger: str = "auto",
|
|
229
366
|
keep_tail_groups: Optional[int] = None,
|
|
230
367
|
session_service_provider: Callable[[], Any] | None = None,
|
|
368
|
+
prompt_integration_mode: str = "",
|
|
369
|
+
compaction_owner: str = "",
|
|
231
370
|
) -> SessionEvent | None:
|
|
232
371
|
"""把旧轮次折叠为 checkpoint。
|
|
233
372
|
|
|
234
373
|
这是本地版的 compaction:先按 API round 分组,再保留尾部若干轮,把更早
|
|
235
374
|
的部分压成 append-only summary 事件。force=True 时用于 PTL 恢复。
|
|
375
|
+
|
|
376
|
+
compaction_owner 硬门控(方案 §6.2):非 ksadk 时不走 KsADK 双阈值压缩。
|
|
236
377
|
"""
|
|
237
378
|
provider = session_service_provider or resolve_session_service
|
|
238
379
|
service = provider()
|
|
239
380
|
events = await service.get_events(session_id)
|
|
381
|
+
session = await service.get_session(session_id)
|
|
382
|
+
memory_user_id = str(getattr(session, "user_id", "") or "")
|
|
240
383
|
plan = _plan_compaction(
|
|
241
384
|
events,
|
|
242
385
|
model=model,
|
|
243
386
|
model_metadata=model_metadata,
|
|
244
387
|
force=force,
|
|
245
388
|
keep_tail_groups=keep_tail_groups,
|
|
389
|
+
prompt_integration_mode=prompt_integration_mode,
|
|
390
|
+
compaction_owner=compaction_owner,
|
|
246
391
|
)
|
|
247
392
|
if not plan.should_compact:
|
|
248
393
|
return None
|
|
@@ -285,7 +430,38 @@ async def compact_conversation_history(
|
|
|
285
430
|
# L5 working set 恢复(保守版):只记 metadata,不读文件内容。
|
|
286
431
|
working_set = build_working_set_metadata(pinned_state=plan.pinned_state)
|
|
287
432
|
|
|
288
|
-
|
|
433
|
+
# PR D2:Session Working State(仅 ksadk_hosted)。从事实事件确定性提取,
|
|
434
|
+
# 写进 checkpoint metadata 供下一轮门控重注入。非门控不写(向后兼容)。
|
|
435
|
+
working_state_audit: dict[str, Any] | None = None
|
|
436
|
+
# PR D2.5:Memory Flush(方案 §9.2)。仅 ksadk_hosted + policy 开启时,压缩前 best-effort
|
|
437
|
+
# 提取候选并提交;失败不阻止 compaction(§9.2 失败语义)。非门控不执行(向后兼容)。
|
|
438
|
+
memory_flush_audit: dict[str, Any] | None = None
|
|
439
|
+
if (
|
|
440
|
+
compaction_owner == "ksadk"
|
|
441
|
+
or (not compaction_owner and prompt_integration_mode == "ksadk_hosted")
|
|
442
|
+
) and plan.groups_to_compact:
|
|
443
|
+
compacted_events = [event for group in plan.groups_to_compact for event in group]
|
|
444
|
+
seq_range = (
|
|
445
|
+
int(plan.groups_to_compact[0][0].seq_id or 0),
|
|
446
|
+
int(plan.groups_to_compact[-1][-1].seq_id or 0),
|
|
447
|
+
)
|
|
448
|
+
working_state = extract_working_state(
|
|
449
|
+
compacted_events,
|
|
450
|
+
pinned_state=plan.pinned_state,
|
|
451
|
+
summary_text=summary_result.summary_text,
|
|
452
|
+
source_seq_range=seq_range,
|
|
453
|
+
)
|
|
454
|
+
# §8.1:关键字段缺失时用压缩前 checkpoint 的 WorkingState 合并,不接受空值覆盖。
|
|
455
|
+
previous_ws = _working_state_from_checkpoint(latest_checkpoint)
|
|
456
|
+
working_state.merge_missing_from(previous_ws)
|
|
457
|
+
working_state_audit = working_state.to_audit_dict()
|
|
458
|
+
memory_flush_audit = await _maybe_memory_flush(
|
|
459
|
+
compacted_events, user_id=memory_user_id, agent_id=author
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
# PR D2.6:per-session compaction lock + stale guard(方案 §9.6)。同一 session 同时只
|
|
463
|
+
# 允许一个 checkpoint/WorkingState 提交;拿不到锁则放弃本次提交避免并发覆盖。
|
|
464
|
+
_checkpoint_kwargs = dict(
|
|
289
465
|
session_id=session_id,
|
|
290
466
|
author=author,
|
|
291
467
|
compacted_until_seq_id=compacted_until_seq_id_value,
|
|
@@ -328,6 +504,32 @@ async def compact_conversation_history(
|
|
|
328
504
|
else None
|
|
329
505
|
),
|
|
330
506
|
"working_set": working_set,
|
|
507
|
+
# PR D1:双阈值带标记(""=非门控旧路径 / "soft" / "hard" / "emergency"=PTL)。
|
|
508
|
+
# 仅审计用,不改变既有 trigger 字段;trigger 仍为调用方值。
|
|
509
|
+
"trigger_band": plan.trigger_band,
|
|
510
|
+
# PR D2:Session Working State(仅 ksadk_hosted)。结构化工作面,供下一轮门控重注入。
|
|
511
|
+
# 含 content_hash/source_seq_range/status,无 prompt 明文。非门控不写该键(向后兼容)。
|
|
512
|
+
**({"working_state": working_state_audit} if working_state_audit is not None else {}),
|
|
513
|
+
# PR D2.5:Memory Flush 审计(方案 §9.2)。失败不阻止 compaction。
|
|
514
|
+
**({"memory_flush": memory_flush_audit} if memory_flush_audit is not None else {}),
|
|
515
|
+
# PR D2:tokens_by_kind before/after(从 pipeline stats 取,审计用)。
|
|
516
|
+
"tokens_by_kind_before": {"transcript": pipeline_result["tokens_before"]},
|
|
517
|
+
"tokens_by_kind_after": {"transcript": pipeline_result["tokens_after"]},
|
|
331
518
|
},
|
|
332
519
|
session_service_provider=provider,
|
|
333
520
|
)
|
|
521
|
+
try:
|
|
522
|
+
from ksadk.conversations.session_lock import session_compaction_lock
|
|
523
|
+
except Exception: # noqa: BLE001
|
|
524
|
+
session_compaction_lock = None # type: ignore[assignment]
|
|
525
|
+
if session_compaction_lock is None:
|
|
526
|
+
return await append_context_checkpoint_event(**_checkpoint_kwargs)
|
|
527
|
+
try:
|
|
528
|
+
async with session_compaction_lock(session_id):
|
|
529
|
+
return await append_context_checkpoint_event(**_checkpoint_kwargs)
|
|
530
|
+
except asyncio.TimeoutError:
|
|
531
|
+
logger.warning(
|
|
532
|
+
"session compaction lock timeout for %s; skipping checkpoint commit",
|
|
533
|
+
session_id,
|
|
534
|
+
)
|
|
535
|
+
return None
|
|
@@ -48,6 +48,74 @@ def _env_flag(name: str, default: bool = True) -> bool:
|
|
|
48
48
|
return normalized not in {"0", "false", "no", "off"}
|
|
49
49
|
|
|
50
50
|
|
|
51
|
+
def _prompt_compiler_enabled() -> bool:
|
|
52
|
+
"""PR B:全局 kill switch。默认关——关闭时 Runner 输入与旧逻辑字节级一致。
|
|
53
|
+
|
|
54
|
+
接管由三重门控共同决定:本 flag × per-Agent ``prompt_integration_mode``
|
|
55
|
+
(由 ``prompt_ownership=ksadk`` 标记的 per-Build)× runner 类型限定 LangGraph。
|
|
56
|
+
任一不满足 → ``_should_project_compiled_prompt`` 返回 False → 走旧 ``instructions`` 分支。
|
|
57
|
+
"""
|
|
58
|
+
return _env_flag("KSADK_PROMPT_COMPILER_ENABLED", False)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _should_project_compiled_prompt(
|
|
62
|
+
*, prepared: PreparedConversationTurn, runner: Any | None
|
|
63
|
+
) -> bool:
|
|
64
|
+
"""PR B:判断本 turn 是否用 ``compiled_prompt`` 接管 ``payload["instructions"]``。
|
|
65
|
+
|
|
66
|
+
满足全部条件才接管:
|
|
67
|
+
1. 全局 flag 开(``KSADK_PROMPT_COMPILER_ENABLED``);
|
|
68
|
+
2. per-Build 接管标记 ``prompt_integration_mode=="ksadk_hosted"``
|
|
69
|
+
(仅 ``prompt_ownership=ksadk``);
|
|
70
|
+
3. 已编译出真实 CompiledPrompt 且含非空 ``prompt_content``(agent_system/agent_task 非空,
|
|
71
|
+
非 resume 旁路);
|
|
72
|
+
4. runner 类型为 langgraph(ADK/Codex 接管错位,排除)。
|
|
73
|
+
|
|
74
|
+
任一不满足 → 返回 False → 调用方走 ``elif`` 分支 == 旧 ``if``,字节级一致。
|
|
75
|
+
"""
|
|
76
|
+
if not _prompt_compiler_enabled():
|
|
77
|
+
return False
|
|
78
|
+
if prepared.prompt_integration_mode != "ksadk_hosted":
|
|
79
|
+
return False
|
|
80
|
+
compiled = prepared.compiled_prompt
|
|
81
|
+
if not isinstance(compiled, Mapping):
|
|
82
|
+
return False
|
|
83
|
+
content = compiled.get("prompt_content")
|
|
84
|
+
if not isinstance(content, str) or not content.strip():
|
|
85
|
+
return False
|
|
86
|
+
return _runner_type_name(runner) == "langgraph"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _should_use_hosted_assembly(*, prepared: PreparedConversationTurn, runner: Any | None) -> bool:
|
|
90
|
+
"""PR E:判断本 turn 是否用 hosted pipeline 的 assembled_input 接管 payload。
|
|
91
|
+
|
|
92
|
+
条件:``assembled_input`` 已生成(build_run_input 在 V2 门控下产出)且 runner 为
|
|
93
|
+
langgraph 系(prompt_owner=ksadk)。该分支优先于 PR B/D2;满足时直接 return,不双重注入。
|
|
94
|
+
native_runtime(codex)的 ``assembled_input`` 恒为 None(build_run_input 不为它生成),
|
|
95
|
+
故 Managed Codex 不受影响(方案 §6.2 / PCM-RUNNER-003)。
|
|
96
|
+
"""
|
|
97
|
+
if not isinstance(prepared.assembled_input, Mapping):
|
|
98
|
+
return False
|
|
99
|
+
if not str(prepared.assembled_input.get("system") or "").strip():
|
|
100
|
+
return False
|
|
101
|
+
return _runner_type_name(runner) == "langgraph"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _assembled_input(prepared: PreparedConversationTurn) -> Any:
|
|
105
|
+
"""把 prepared.assembled_input 的 plain dict 还原成 assembler 能消费的形式。"""
|
|
106
|
+
from ksadk.context_engine.assembler import AssembledInput
|
|
107
|
+
|
|
108
|
+
d = prepared.assembled_input
|
|
109
|
+
return AssembledInput(
|
|
110
|
+
format=d.get("format", "chat"),
|
|
111
|
+
system=str(d.get("system") or ""),
|
|
112
|
+
messages=list(d.get("messages") or []),
|
|
113
|
+
responses_items=[],
|
|
114
|
+
estimated_tokens=int(d.get("estimated_tokens") or 0),
|
|
115
|
+
warnings=tuple(d.get("warnings") or ()),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
51
119
|
def _ltm_auto_save_enabled() -> bool:
|
|
52
120
|
backend = str(os.getenv("KSADK_LTM_BACKEND") or "").strip().lower()
|
|
53
121
|
namespace = str(os.getenv("KSADK_LTM_NAMESPACE") or "").strip()
|
|
@@ -83,10 +151,19 @@ def _ambient_context_has_error(context: Any) -> bool:
|
|
|
83
151
|
if not isinstance(context, dict):
|
|
84
152
|
return True
|
|
85
153
|
|
|
154
|
+
# 显式 error 字段(PR:Memory Recall 失败语义):build_context 失败时把原因放
|
|
155
|
+
# 独立 ``error`` 字段、``formatted_text`` 置空,错误不进模型上下文。
|
|
156
|
+
if str(context.get("error") or "").strip():
|
|
157
|
+
return True
|
|
158
|
+
|
|
86
159
|
formatted_text = str(context.get("formatted_text") or "").strip()
|
|
160
|
+
# 真无记忆不是可注入的上下文。它不是 provider failure,但对投影层而言
|
|
161
|
+
# 同样应被丢弃,避免 UI 和审计把空召回误报成“已使用长期记忆”。
|
|
87
162
|
if not formatted_text:
|
|
88
163
|
return True
|
|
89
164
|
|
|
165
|
+
# 纵深防御:``search_text``(工具路径)仍会把错误塞进正文,这里按前缀兜底,
|
|
166
|
+
# 防止任何直接调 ``search_text`` 拼上下文的路径把错误字符串注入。
|
|
90
167
|
failure_prefixes = (
|
|
91
168
|
"知识库检索失败",
|
|
92
169
|
"长期记忆检索失败",
|
|
@@ -350,6 +427,7 @@ def _build_runner_ambient_contexts(
|
|
|
350
427
|
contexts: dict[str, Any] = {
|
|
351
428
|
"kb_context": None,
|
|
352
429
|
"memory_context": None,
|
|
430
|
+
"memory_recall_events": [],
|
|
353
431
|
}
|
|
354
432
|
normalized_input = str(user_input or "").strip()
|
|
355
433
|
if not normalized_input or not _should_use_platform_ambient_context(runner):
|
|
@@ -379,8 +457,18 @@ def _build_runner_ambient_contexts(
|
|
|
379
457
|
)
|
|
380
458
|
if not _ambient_context_has_error(memory_context):
|
|
381
459
|
contexts["memory_context"] = memory_context
|
|
460
|
+
contexts.setdefault("memory_recall_events", []).append(
|
|
461
|
+
{"type": "memory.recall.completed", "count": 1}
|
|
462
|
+
)
|
|
463
|
+
else:
|
|
464
|
+
contexts.setdefault("memory_recall_events", []).append(
|
|
465
|
+
{"type": "memory.recall.empty"}
|
|
466
|
+
)
|
|
382
467
|
except Exception as exc:
|
|
383
468
|
logger.warning("Failed to build ambient memory context: %s", exc)
|
|
469
|
+
contexts.setdefault("memory_recall_events", []).append(
|
|
470
|
+
{"type": "memory.recall.failed", "error": str(exc)[:200]}
|
|
471
|
+
)
|
|
384
472
|
|
|
385
473
|
return contexts
|
|
386
474
|
|
|
@@ -417,7 +505,31 @@ def _build_runner_request_payload(
|
|
|
417
505
|
# (for example, its conversation approval profile) without leaking
|
|
418
506
|
# caller public metadata into the agent payload.
|
|
419
507
|
payload["request_metadata"] = dict(prepared.request_metadata)
|
|
420
|
-
|
|
508
|
+
# PR E:hosted pipeline 接管(最高优先级)。当 build_run_input 产出 assembled_input 时,
|
|
509
|
+
# 用组装好的 system/input/history 直接覆盖 payload——它已含 compiled_prompt + working_state
|
|
510
|
+
# + planner 决策后的有序 messages。此分支满足后不再走 PR B/D2(避免双重注入)。
|
|
511
|
+
if _should_use_hosted_assembly(prepared=prepared, runner=runner):
|
|
512
|
+
from ksadk.context_engine.hosted_pipeline import assembled_to_payload
|
|
513
|
+
|
|
514
|
+
override = assembled_to_payload(_assembled_input(prepared))
|
|
515
|
+
if override["instructions"]:
|
|
516
|
+
payload["instructions"] = override["instructions"]
|
|
517
|
+
if override["input"]:
|
|
518
|
+
payload["input"] = override["input"]
|
|
519
|
+
# An empty assembled history is authoritative: on the first turn the
|
|
520
|
+
# just-persisted user event must not survive from ``prepared.history``
|
|
521
|
+
# and be injected alongside the canonical current input.
|
|
522
|
+
payload["history"] = override["history"]
|
|
523
|
+
payload["context_plan_id"] = (
|
|
524
|
+
prepared.context_plan.get("plan_id") if prepared.context_plan else None
|
|
525
|
+
)
|
|
526
|
+
return payload
|
|
527
|
+
# PR B:LangGraph CompiledPrompt→instructions 接管。三重门控满足时,把
|
|
528
|
+
# payload["instructions"] 替换为 CompiledPrompt.content(XML),使 agent_system/
|
|
529
|
+
# agent_task 首次进模型输入。任一门控不满足 → elif == 旧逻辑(字节级一致)。
|
|
530
|
+
if _should_project_compiled_prompt(prepared=prepared, runner=runner):
|
|
531
|
+
payload["instructions"] = prepared.compiled_prompt["prompt_content"]
|
|
532
|
+
elif prepared.instructions:
|
|
421
533
|
payload["instructions"] = prepared.instructions
|
|
422
534
|
if prepared.resume_input is not None:
|
|
423
535
|
if _is_checkpoint_resume_input(prepared.resume_input):
|
|
@@ -431,7 +543,15 @@ def _build_runner_request_payload(
|
|
|
431
543
|
prepared.resume_input.get("checkpoint_metadata") or {}
|
|
432
544
|
)
|
|
433
545
|
else:
|
|
434
|
-
|
|
546
|
+
resume_input = dict(prepared.resume_input)
|
|
547
|
+
gateway_approval_resume = bool(
|
|
548
|
+
resume_input.pop("_ksadk_gateway_approval_resume", False)
|
|
549
|
+
)
|
|
550
|
+
if gateway_approval_resume and bool(
|
|
551
|
+
getattr(runner, "supports_gateway_approval_semantic_resume", False)
|
|
552
|
+
):
|
|
553
|
+
resume_input["_ksadk_gateway_approval_resume"] = True
|
|
554
|
+
payload["input"] = resume_input
|
|
435
555
|
payload["resume"] = True
|
|
436
556
|
previous_response_id = prepared.request_metadata.get("previous_response_id")
|
|
437
557
|
if previous_response_id:
|
|
@@ -446,9 +566,74 @@ def _build_runner_request_payload(
|
|
|
446
566
|
deferred_tool_names = _extract_deferred_tool_names(prepared.request_metadata)
|
|
447
567
|
if deferred_tool_names:
|
|
448
568
|
payload["deferred_tool_names"] = deferred_tool_names
|
|
569
|
+
# PR D2:WorkingState 门控重注入。仅 ksadk_hosted + 有 working_state 时,把结构化工作面
|
|
570
|
+
# 渲染成 XML 段追加进 instructions(与 CompiledPrompt.content 风格一致,LangGraph _to_state
|
|
571
|
+
# 能消费 instructions 字符串)。非门控或有 CompiledPrompt 接管时仍由前者决定 instructions。
|
|
572
|
+
_maybe_inject_working_state(payload, prepared)
|
|
449
573
|
return payload
|
|
450
574
|
|
|
451
575
|
|
|
576
|
+
def _maybe_inject_working_state(
|
|
577
|
+
payload: dict[str, Any], prepared: PreparedConversationTurn
|
|
578
|
+
) -> None:
|
|
579
|
+
"""PR D2:把 working_state 渲染成 <working_state> XML 段追加进 payload instructions。
|
|
580
|
+
|
|
581
|
+
门控:仅 ``prompt_integration_mode=="ksadk_hosted"`` 且 ``working_state`` 非空时注入。
|
|
582
|
+
与 PR B 的 CompiledPrompt 接管叠加:若 instructions 已被 CompiledPrompt 接管(XML),
|
|
583
|
+
WorkingState 段追加在其后;否则追加在 request instructions 后。非门控零注入。
|
|
584
|
+
Prompt 明文不进 Trace(working_state 不进 shadow plan/trace)。
|
|
585
|
+
"""
|
|
586
|
+
if prepared.prompt_integration_mode != "ksadk_hosted":
|
|
587
|
+
return
|
|
588
|
+
ws = prepared.working_state
|
|
589
|
+
if not isinstance(ws, Mapping) or not ws:
|
|
590
|
+
return
|
|
591
|
+
xml = _render_working_state_xml(ws)
|
|
592
|
+
if not xml:
|
|
593
|
+
return
|
|
594
|
+
existing = str(payload.get("instructions") or "").strip()
|
|
595
|
+
if existing:
|
|
596
|
+
payload["instructions"] = f"{existing}\n\n{xml}"
|
|
597
|
+
else:
|
|
598
|
+
payload["instructions"] = xml
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
def _render_working_state_xml(ws: Mapping[str, Any]) -> str:
|
|
602
|
+
"""把 working_state 审计 dict 渲染成 <working_state> XML 段(供模型理解当前工作面)。"""
|
|
603
|
+
current_goal = str(ws.get("current_goal") or "").strip()
|
|
604
|
+
next_action = str(ws.get("next_action") or "").strip()
|
|
605
|
+
active_files = ws.get("active_files") or []
|
|
606
|
+
pending_tools = ws.get("pending_tools") or []
|
|
607
|
+
pending_approvals = ws.get("pending_approvals") or []
|
|
608
|
+
lines: list[str] = []
|
|
609
|
+
if current_goal:
|
|
610
|
+
lines.append(f"当前目标:{current_goal}")
|
|
611
|
+
if next_action:
|
|
612
|
+
lines.append(f"下一步:{next_action}")
|
|
613
|
+
if isinstance(active_files, list) and active_files:
|
|
614
|
+
files = ", ".join(
|
|
615
|
+
str((f.get("path") if isinstance(f, Mapping) else "") or "") for f in active_files
|
|
616
|
+
).strip(", ")
|
|
617
|
+
if files:
|
|
618
|
+
lines.append(f"活跃文件:{files}")
|
|
619
|
+
if isinstance(pending_tools, list) and pending_tools:
|
|
620
|
+
tools = "; ".join(
|
|
621
|
+
str((t.get("text") if isinstance(t, Mapping) else "") or "") for t in pending_tools
|
|
622
|
+
).strip("; ")
|
|
623
|
+
if tools:
|
|
624
|
+
lines.append(f"未完成工具:{tools}")
|
|
625
|
+
if isinstance(pending_approvals, list) and pending_approvals:
|
|
626
|
+
approvals = "; ".join(
|
|
627
|
+
str((a.get("text") if isinstance(a, Mapping) else "") or "") for a in pending_approvals
|
|
628
|
+
).strip("; ")
|
|
629
|
+
if approvals:
|
|
630
|
+
lines.append(f"待审批:{approvals}")
|
|
631
|
+
if not lines:
|
|
632
|
+
return ""
|
|
633
|
+
body = "\n".join(lines)
|
|
634
|
+
return f"<working_state>\n{body}\n</working_state>"
|
|
635
|
+
|
|
636
|
+
|
|
452
637
|
def _inject_runner_deferred_tools_for_request(
|
|
453
638
|
runner: Any, prepared: PreparedConversationTurn
|
|
454
639
|
) -> None:
|
|
@@ -563,7 +748,12 @@ async def _auto_save_ltm_turn(
|
|
|
563
748
|
runner_type: str,
|
|
564
749
|
model: str | None,
|
|
565
750
|
) -> None:
|
|
566
|
-
if prepared.resume_input is not None
|
|
751
|
+
if prepared.resume_input is not None:
|
|
752
|
+
return
|
|
753
|
+
memory_rollout = str(prepared.memory_write_rollout or "").strip().lower()
|
|
754
|
+
if memory_rollout in {"off", "shadow"}:
|
|
755
|
+
return
|
|
756
|
+
if not memory_rollout and not _ltm_auto_save_enabled():
|
|
567
757
|
return
|
|
568
758
|
|
|
569
759
|
metadata: dict[str, Any] = {
|