GeneralManager 0.79.0__tar.gz → 0.79.2__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.
- {generalmanager-0.79.0/src/GeneralManager.egg-info → generalmanager-0.79.2}/PKG-INFO +1 -1
- {generalmanager-0.79.0 → generalmanager-0.79.2}/pyproject.toml +1 -1
- {generalmanager-0.79.0 → generalmanager-0.79.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/GeneralManager.egg-info/SOURCES.txt +1 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_groups.py +15 -3
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/consumer.py +203 -49
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/context.py +49 -11
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/errors.py +19 -1
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/runner.py +29 -11
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/rate_limits.py +16 -25
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/settings.py +21 -0
- generalmanager-0.79.2/src/general_manager/chat/turns.py +84 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/views.py +203 -112
- {generalmanager-0.79.0 → generalmanager-0.79.2}/LICENSE +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/README.md +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/setup.cfg +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_as_of.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_ordering.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_output.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_type.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/apps.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/as_of.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/_materialized_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/_ordering.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/excel_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/projection.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/data_change_context.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/run_context_lru.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/budget.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/calculations.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/catalog.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/config.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/events.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/evidence.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/planner.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/provider_calls.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/resolver.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/routing.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/scheduler.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/synthesis.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/planned/validation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/conf.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/excel.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/calculation/input_resolution.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/excel.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/excel_store.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/excel_workbook.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/excel.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/logging.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/0012_chat_context_watermarks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/py.typed +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/invalidation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/m2m_invalidation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/finalization.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/_args_to_kwargs.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/_cache_key_encoder.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/_make_cache_key.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/_none_to_zero.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/tests/test_settings.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/tests/test_urls.py +0 -0
- {generalmanager-0.79.0 → generalmanager-0.79.2}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.79.
|
|
3
|
+
Version: 0.79.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.79.
|
|
7
|
+
version = "0.79.2"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.79.
|
|
3
|
+
Version: 0.79.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -96,6 +96,7 @@ src/general_manager/chat/signals.py
|
|
|
96
96
|
src/general_manager/chat/system_prompt.py
|
|
97
97
|
src/general_manager/chat/tool_metadata.py
|
|
98
98
|
src/general_manager/chat/tools.py
|
|
99
|
+
src/general_manager/chat/turns.py
|
|
99
100
|
src/general_manager/chat/views.py
|
|
100
101
|
src/general_manager/chat/evals/__init__.py
|
|
101
102
|
src/general_manager/chat/evals/__main__.py
|
|
@@ -94,7 +94,10 @@ def create_group_types(
|
|
|
94
94
|
)
|
|
95
95
|
else:
|
|
96
96
|
sum_fields[field_name] = map_field(sum_type, field_name, field_info)
|
|
97
|
-
sum_resolvers[f"resolve_{field_name}"] = _sum_resolver(
|
|
97
|
+
sum_resolvers[f"resolve_{field_name}"] = _sum_resolver(
|
|
98
|
+
field_name,
|
|
99
|
+
text_values=sum_type is not None and issubclass(sum_type, str),
|
|
100
|
+
)
|
|
98
101
|
|
|
99
102
|
key_type = type(
|
|
100
103
|
f"{manager_class.__name__}GroupKeys",
|
|
@@ -201,7 +204,7 @@ def _is_sum_type(field_type: object) -> bool:
|
|
|
201
204
|
return (
|
|
202
205
|
concrete_type is not None
|
|
203
206
|
and not issubclass(concrete_type, bool)
|
|
204
|
-
and issubclass(concrete_type, (int, float, Decimal, Measurement))
|
|
207
|
+
and issubclass(concrete_type, (int, float, Decimal, Measurement, str))
|
|
205
208
|
)
|
|
206
209
|
|
|
207
210
|
|
|
@@ -288,13 +291,22 @@ def _measurement_key_resolver(field_name: str) -> Callable[..., object]:
|
|
|
288
291
|
return resolver
|
|
289
292
|
|
|
290
293
|
|
|
291
|
-
def _sum_resolver(
|
|
294
|
+
def _sum_resolver(
|
|
295
|
+
field_name: str, *, text_values: bool = False
|
|
296
|
+
) -> Callable[..., object]:
|
|
292
297
|
def resolver(
|
|
293
298
|
group: GroupManager[GeneralManager],
|
|
294
299
|
info: GraphQLResolveInfo,
|
|
295
300
|
target_unit: str | None = None,
|
|
296
301
|
) -> object:
|
|
297
302
|
_validate_group_field_permission(group, info, field_name)
|
|
303
|
+
if text_values:
|
|
304
|
+
values = dict.fromkeys(
|
|
305
|
+
str(value)
|
|
306
|
+
for member in group.members
|
|
307
|
+
if (value := getattr(member, field_name)) is not None
|
|
308
|
+
)
|
|
309
|
+
return ", ".join(values) if values else None
|
|
298
310
|
value = group.sum(field_name)
|
|
299
311
|
if isinstance(value, Measurement):
|
|
300
312
|
return measurement_to_graphql_payload(value, target_unit)
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
from datetime import datetime, timedelta
|
|
7
|
+
import inspect
|
|
7
8
|
import json
|
|
8
9
|
from typing import TYPE_CHECKING, Any
|
|
9
10
|
|
|
@@ -54,6 +55,7 @@ from general_manager.chat.tools import (
|
|
|
54
55
|
execute_chat_tool,
|
|
55
56
|
get_tool_definitions,
|
|
56
57
|
)
|
|
58
|
+
from general_manager.chat.turns import TurnState
|
|
57
59
|
|
|
58
60
|
if TYPE_CHECKING:
|
|
59
61
|
from general_manager.chat.models import ChatConversation
|
|
@@ -99,14 +101,23 @@ async def _iter_provider_events(
|
|
|
99
101
|
stream_timeout = float(provider_config.get("stream_timeout_seconds", 30))
|
|
100
102
|
stream = provider.complete(messages, tools).__aiter__()
|
|
101
103
|
first_chunk = True
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
try:
|
|
105
|
+
while True:
|
|
106
|
+
timeout = request_timeout if first_chunk else stream_timeout
|
|
107
|
+
try:
|
|
108
|
+
event = await asyncio.wait_for(stream.__anext__(), timeout=timeout)
|
|
109
|
+
except StopAsyncIteration:
|
|
110
|
+
return
|
|
111
|
+
first_chunk = False
|
|
112
|
+
yield event
|
|
113
|
+
if isinstance(event, DoneEvent):
|
|
114
|
+
return
|
|
115
|
+
finally:
|
|
116
|
+
close = getattr(stream, "aclose", None)
|
|
117
|
+
if callable(close):
|
|
118
|
+
result = close()
|
|
119
|
+
if inspect.isawaitable(result):
|
|
120
|
+
await result
|
|
110
121
|
|
|
111
122
|
|
|
112
123
|
def _last_user_text(messages: list[Message]) -> str:
|
|
@@ -371,6 +382,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
371
382
|
{"message": text, "session_key": self.session_key},
|
|
372
383
|
)
|
|
373
384
|
messages = [Message(role="system", content=build_system_prompt())]
|
|
385
|
+
turn_state = TurnState.from_settings(get_chat_settings())
|
|
374
386
|
if self.conversation is not None:
|
|
375
387
|
from general_manager.chat.context import prepare_conversation_messages
|
|
376
388
|
|
|
@@ -379,6 +391,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
379
391
|
self.provider,
|
|
380
392
|
allow_summarization=not get_planned_chat_settings().enabled,
|
|
381
393
|
scope=self.scope,
|
|
394
|
+
turn_state=turn_state,
|
|
382
395
|
)
|
|
383
396
|
else:
|
|
384
397
|
messages.extend(
|
|
@@ -391,7 +404,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
391
404
|
conversation_id=getattr(self.conversation, "pk", None),
|
|
392
405
|
)
|
|
393
406
|
started_background_turn = await self._stream_message_turn(
|
|
394
|
-
text, messages, history
|
|
407
|
+
text, messages, history, turn_state=turn_state
|
|
395
408
|
)
|
|
396
409
|
except Exception as exc: # noqa: BLE001
|
|
397
410
|
emit_chat_error(
|
|
@@ -416,18 +429,47 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
416
429
|
tool_retries: int,
|
|
417
430
|
tool_calls: list[dict[str, Any]] | None = None,
|
|
418
431
|
recovered_missing_tools: bool = False,
|
|
432
|
+
turn_state: TurnState | None = None,
|
|
433
|
+
allow_tools: bool = True,
|
|
419
434
|
) -> None:
|
|
420
435
|
tool_calls = list(tool_calls or [])
|
|
421
436
|
assistant_chunks: list[str] = []
|
|
422
437
|
provider_tool_events: list[ToolCallEvent] = []
|
|
423
|
-
self._provider_task = asyncio.current_task()
|
|
424
438
|
recover_missing_tools = bool(
|
|
425
439
|
get_chat_settings().get("recover_missing_tool_calls", False)
|
|
426
440
|
)
|
|
441
|
+
turn_state = turn_state or TurnState.from_settings(get_chat_settings())
|
|
442
|
+
turn_state.tool_retries = tool_retries
|
|
443
|
+
if not turn_state.reserve_round():
|
|
444
|
+
await self.send_json(
|
|
445
|
+
{
|
|
446
|
+
"type": "error",
|
|
447
|
+
"message": "Chat turn limit exceeded.",
|
|
448
|
+
"code": "turn_limit",
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
return
|
|
452
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
453
|
+
self.scope, count_request=False
|
|
454
|
+
)
|
|
455
|
+
if isinstance(rate_limited, dict):
|
|
456
|
+
await self.send_json(
|
|
457
|
+
{
|
|
458
|
+
"type": "error",
|
|
459
|
+
"message": "Chat rate limit exceeded. Try again later.",
|
|
460
|
+
"code": "rate_limited",
|
|
461
|
+
"retry_after_seconds": rate_limited["retry_after_seconds"],
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
return
|
|
465
|
+
self._provider_task = asyncio.current_task()
|
|
466
|
+
provider_events = _iter_provider_events(
|
|
467
|
+
self.provider,
|
|
468
|
+
messages,
|
|
469
|
+
self._build_tool_definitions() if allow_tools else [],
|
|
470
|
+
)
|
|
427
471
|
try:
|
|
428
|
-
async for event in
|
|
429
|
-
self.provider, messages, self._build_tool_definitions()
|
|
430
|
-
):
|
|
472
|
+
async for event in provider_events:
|
|
431
473
|
if isinstance(event, TextChunkEvent):
|
|
432
474
|
assistant_chunks.append(event.content)
|
|
433
475
|
if not recover_missing_tools:
|
|
@@ -438,13 +480,37 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
438
480
|
provider_tool_events.append(event)
|
|
439
481
|
continue
|
|
440
482
|
elif isinstance(event, DoneEvent):
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
483
|
+
turn_state.record_usage(event.usage)
|
|
484
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
485
|
+
self.scope,
|
|
486
|
+
input_tokens=event.usage.input_tokens,
|
|
487
|
+
output_tokens=event.usage.output_tokens,
|
|
488
|
+
count_request=False,
|
|
489
|
+
)
|
|
490
|
+
# Account completion before cleanup, but do not continue or finish first.
|
|
491
|
+
await provider_events.aclose()
|
|
492
|
+
if isinstance(rate_limited, dict):
|
|
493
|
+
await self.send_json(
|
|
494
|
+
{
|
|
495
|
+
"type": "error",
|
|
496
|
+
"message": "Chat rate limit exceeded. Try again later.",
|
|
497
|
+
"code": "rate_limited",
|
|
498
|
+
"retry_after_seconds": rate_limited[
|
|
499
|
+
"retry_after_seconds"
|
|
500
|
+
],
|
|
501
|
+
}
|
|
447
502
|
)
|
|
503
|
+
return
|
|
504
|
+
if provider_tool_events:
|
|
505
|
+
if not allow_tools:
|
|
506
|
+
await self.send_json(
|
|
507
|
+
{
|
|
508
|
+
"type": "error",
|
|
509
|
+
"message": "Chat tool retry limit exceeded.",
|
|
510
|
+
"code": "tool_retry_limit",
|
|
511
|
+
}
|
|
512
|
+
)
|
|
513
|
+
return
|
|
448
514
|
await self._handle_tool_batch(
|
|
449
515
|
provider_tool_events,
|
|
450
516
|
messages,
|
|
@@ -452,6 +518,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
452
518
|
tool_retries=tool_retries,
|
|
453
519
|
tool_calls=tool_calls,
|
|
454
520
|
recovered_missing_tools=recovered_missing_tools,
|
|
521
|
+
turn_state=turn_state,
|
|
455
522
|
)
|
|
456
523
|
return
|
|
457
524
|
if assistant_chunks:
|
|
@@ -480,6 +547,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
480
547
|
tool_retries=tool_retries,
|
|
481
548
|
tool_calls=tool_calls,
|
|
482
549
|
recovered_missing_tools=True,
|
|
550
|
+
turn_state=turn_state,
|
|
483
551
|
)
|
|
484
552
|
return
|
|
485
553
|
if (
|
|
@@ -505,6 +573,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
505
573
|
tool_retries=tool_retries,
|
|
506
574
|
tool_calls=tool_calls,
|
|
507
575
|
recovered_missing_tools=True,
|
|
576
|
+
turn_state=turn_state,
|
|
508
577
|
)
|
|
509
578
|
return
|
|
510
579
|
if recover_missing_tools:
|
|
@@ -541,24 +610,28 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
541
610
|
tool_retries=tool_retries,
|
|
542
611
|
tool_calls=tool_calls,
|
|
543
612
|
recovered_missing_tools=True,
|
|
613
|
+
turn_state=turn_state,
|
|
544
614
|
)
|
|
545
615
|
return
|
|
546
|
-
await sync_to_async(enforce_chat_rate_limit)(
|
|
547
|
-
self.scope,
|
|
548
|
-
input_tokens=event.usage.input_tokens,
|
|
549
|
-
output_tokens=event.usage.output_tokens,
|
|
550
|
-
count_request=False,
|
|
551
|
-
)
|
|
552
616
|
await self.send_json(
|
|
553
617
|
{
|
|
554
618
|
"type": "done",
|
|
555
619
|
"usage": {
|
|
556
|
-
"input_tokens":
|
|
557
|
-
"output_tokens":
|
|
620
|
+
"input_tokens": turn_state.usage.input_tokens,
|
|
621
|
+
"output_tokens": turn_state.usage.output_tokens,
|
|
558
622
|
},
|
|
559
623
|
}
|
|
560
624
|
)
|
|
561
625
|
if provider_tool_events:
|
|
626
|
+
if not allow_tools:
|
|
627
|
+
await self.send_json(
|
|
628
|
+
{
|
|
629
|
+
"type": "error",
|
|
630
|
+
"message": "Chat tool retry limit exceeded.",
|
|
631
|
+
"code": "tool_retry_limit",
|
|
632
|
+
}
|
|
633
|
+
)
|
|
634
|
+
return
|
|
562
635
|
await self._handle_tool_batch(
|
|
563
636
|
provider_tool_events,
|
|
564
637
|
messages,
|
|
@@ -566,9 +639,13 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
566
639
|
tool_retries=tool_retries,
|
|
567
640
|
tool_calls=tool_calls,
|
|
568
641
|
recovered_missing_tools=recovered_missing_tools,
|
|
642
|
+
turn_state=turn_state,
|
|
569
643
|
)
|
|
570
644
|
finally:
|
|
571
|
-
|
|
645
|
+
try:
|
|
646
|
+
await provider_events.aclose()
|
|
647
|
+
finally:
|
|
648
|
+
self._provider_task = None
|
|
572
649
|
|
|
573
650
|
@staticmethod
|
|
574
651
|
def _planned_catalog_summary(settings: Any) -> dict[str, Any]:
|
|
@@ -595,11 +672,15 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
595
672
|
text: str,
|
|
596
673
|
messages: list[Message],
|
|
597
674
|
history: list[dict[str, str]],
|
|
675
|
+
*,
|
|
676
|
+
turn_state: TurnState | None = None,
|
|
598
677
|
) -> bool:
|
|
599
678
|
"""Plan after admission, retaining the unchanged legacy turn as fallback."""
|
|
600
679
|
planned_settings = get_planned_chat_settings()
|
|
601
680
|
if not planned_settings.enabled:
|
|
602
|
-
await self._stream_provider_turn(
|
|
681
|
+
await self._stream_provider_turn(
|
|
682
|
+
messages, history, tool_retries=0, turn_state=turn_state
|
|
683
|
+
)
|
|
603
684
|
return False
|
|
604
685
|
self._provider_task = asyncio.create_task(
|
|
605
686
|
self._stream_planned_turn(text, messages, history, planned_settings)
|
|
@@ -669,6 +750,8 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
669
750
|
tool_retries: int,
|
|
670
751
|
tool_calls: list[dict[str, Any]] | None = None,
|
|
671
752
|
recovered_missing_tools: bool = False,
|
|
753
|
+
turn_state: TurnState | None = None,
|
|
754
|
+
allow_tools: bool = True,
|
|
672
755
|
) -> bool:
|
|
673
756
|
"""Execute a completed non-mutation tool batch before continuing once."""
|
|
674
757
|
if len(events) > 1 and any(event.name == "mutate" for event in events):
|
|
@@ -688,6 +771,8 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
688
771
|
tool_retries=tool_retries,
|
|
689
772
|
tool_calls=tool_calls,
|
|
690
773
|
recovered_missing_tools=recovered_missing_tools,
|
|
774
|
+
turn_state=turn_state,
|
|
775
|
+
allow_tools=allow_tools,
|
|
691
776
|
)
|
|
692
777
|
|
|
693
778
|
max_retries = int(get_chat_settings().get("max_retries_per_message", 8))
|
|
@@ -704,6 +789,19 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
704
789
|
tool_calls = list(tool_calls or [])
|
|
705
790
|
results: list[tuple[ToolCallEvent, Any]] = []
|
|
706
791
|
for event in events:
|
|
792
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
793
|
+
self.scope, count_request=False
|
|
794
|
+
)
|
|
795
|
+
if isinstance(rate_limited, dict):
|
|
796
|
+
await self.send_json(
|
|
797
|
+
{
|
|
798
|
+
"type": "error",
|
|
799
|
+
"message": "Chat rate limit exceeded. Try again later.",
|
|
800
|
+
"code": "rate_limited",
|
|
801
|
+
"retry_after_seconds": rate_limited["retry_after_seconds"],
|
|
802
|
+
}
|
|
803
|
+
)
|
|
804
|
+
return False
|
|
707
805
|
emit_chat_audit_event(
|
|
708
806
|
"tool_call",
|
|
709
807
|
{
|
|
@@ -778,21 +876,14 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
778
876
|
tool_call_id=event.id,
|
|
779
877
|
)
|
|
780
878
|
|
|
781
|
-
if tool_retries + len(events) >= max_retries:
|
|
782
|
-
await self.send_json(
|
|
783
|
-
{
|
|
784
|
-
"type": "error",
|
|
785
|
-
"message": "Chat tool retry limit exceeded.",
|
|
786
|
-
"code": "tool_retry_limit",
|
|
787
|
-
}
|
|
788
|
-
)
|
|
789
|
-
return True
|
|
790
879
|
await self._stream_provider_turn(
|
|
791
880
|
messages,
|
|
792
881
|
history,
|
|
793
882
|
tool_retries=tool_retries + len(events),
|
|
794
883
|
tool_calls=tool_calls,
|
|
795
884
|
recovered_missing_tools=recovered_missing_tools,
|
|
885
|
+
turn_state=turn_state,
|
|
886
|
+
allow_tools=tool_retries + len(events) < max_retries,
|
|
796
887
|
)
|
|
797
888
|
return True
|
|
798
889
|
|
|
@@ -805,6 +896,8 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
805
896
|
tool_retries: int,
|
|
806
897
|
tool_calls: list[dict[str, Any]] | None = None,
|
|
807
898
|
recovered_missing_tools: bool = False,
|
|
899
|
+
turn_state: TurnState | None = None,
|
|
900
|
+
allow_tools: bool = True,
|
|
808
901
|
) -> bool:
|
|
809
902
|
"""Retain the single-call compatibility entry point."""
|
|
810
903
|
return await self._handle_tool_batch(
|
|
@@ -814,6 +907,8 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
814
907
|
tool_retries=tool_retries,
|
|
815
908
|
tool_calls=tool_calls,
|
|
816
909
|
recovered_missing_tools=recovered_missing_tools,
|
|
910
|
+
turn_state=turn_state,
|
|
911
|
+
allow_tools=allow_tools,
|
|
817
912
|
)
|
|
818
913
|
|
|
819
914
|
async def _handle_single_tool_call(
|
|
@@ -825,8 +920,43 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
825
920
|
tool_retries: int,
|
|
826
921
|
tool_calls: list[dict[str, Any]] | None = None,
|
|
827
922
|
recovered_missing_tools: bool = False,
|
|
923
|
+
turn_state: TurnState | None = None,
|
|
924
|
+
allow_tools: bool = True,
|
|
828
925
|
) -> bool:
|
|
829
926
|
tool_calls = list(tool_calls or [])
|
|
927
|
+
turn_state = turn_state or TurnState.from_settings(get_chat_settings())
|
|
928
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
929
|
+
self.scope, count_request=False
|
|
930
|
+
)
|
|
931
|
+
if isinstance(rate_limited, dict):
|
|
932
|
+
await self.send_json(
|
|
933
|
+
{
|
|
934
|
+
"type": "error",
|
|
935
|
+
"message": "Chat rate limit exceeded. Try again later.",
|
|
936
|
+
"code": "rate_limited",
|
|
937
|
+
"retry_after_seconds": rate_limited["retry_after_seconds"],
|
|
938
|
+
}
|
|
939
|
+
)
|
|
940
|
+
return False
|
|
941
|
+
max_retries = int(get_chat_settings().get("max_retries_per_message", 8))
|
|
942
|
+
if event.name != "mutate" and tool_retries >= max_retries:
|
|
943
|
+
await self.send_json(
|
|
944
|
+
{
|
|
945
|
+
"type": "error",
|
|
946
|
+
"message": "Chat tool retry limit exceeded.",
|
|
947
|
+
"code": "tool_retry_limit",
|
|
948
|
+
}
|
|
949
|
+
)
|
|
950
|
+
return False
|
|
951
|
+
if event.name == "mutate" and not turn_state.reserve_mutation():
|
|
952
|
+
await self.send_json(
|
|
953
|
+
{
|
|
954
|
+
"type": "error",
|
|
955
|
+
"message": "Chat mutation limit exceeded.",
|
|
956
|
+
"code": "mutation_limit",
|
|
957
|
+
}
|
|
958
|
+
)
|
|
959
|
+
return False
|
|
830
960
|
emit_chat_audit_event(
|
|
831
961
|
"tool_call",
|
|
832
962
|
{
|
|
@@ -887,7 +1017,10 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
887
1017
|
self.conversation,
|
|
888
1018
|
confirmation_id=event.id,
|
|
889
1019
|
mutation_name=str(result["mutation"]),
|
|
890
|
-
payload={
|
|
1020
|
+
payload={
|
|
1021
|
+
"input": result["input"],
|
|
1022
|
+
"_gm_turn_state": turn_state.as_payload(),
|
|
1023
|
+
},
|
|
891
1024
|
timeout_seconds=timeout_seconds,
|
|
892
1025
|
)
|
|
893
1026
|
except Exception as exc: # noqa: BLE001
|
|
@@ -922,6 +1055,7 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
922
1055
|
"history": history,
|
|
923
1056
|
"expires_at": timezone.now() + timedelta(seconds=timeout_seconds),
|
|
924
1057
|
"durable": durable,
|
|
1058
|
+
"turn_state": turn_state,
|
|
925
1059
|
}
|
|
926
1060
|
self._confirmation_waiter = asyncio.get_running_loop().create_future()
|
|
927
1061
|
self._confirmation_timeout_task = asyncio.create_task(
|
|
@@ -985,21 +1119,14 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
985
1119
|
)
|
|
986
1120
|
next_tool_retries = tool_retries + (0 if event.name == "mutate" else 1)
|
|
987
1121
|
max_retries = int(get_chat_settings().get("max_retries_per_message", 8))
|
|
988
|
-
if event.name != "mutate" and next_tool_retries >= max_retries:
|
|
989
|
-
await self.send_json(
|
|
990
|
-
{
|
|
991
|
-
"type": "error",
|
|
992
|
-
"message": "Chat tool retry limit exceeded.",
|
|
993
|
-
"code": "tool_retry_limit",
|
|
994
|
-
}
|
|
995
|
-
)
|
|
996
|
-
return True
|
|
997
1122
|
await self._stream_provider_turn(
|
|
998
1123
|
messages,
|
|
999
1124
|
history,
|
|
1000
1125
|
tool_retries=next_tool_retries,
|
|
1001
1126
|
tool_calls=tool_calls,
|
|
1002
1127
|
recovered_missing_tools=recovered_missing_tools,
|
|
1128
|
+
turn_state=turn_state,
|
|
1129
|
+
allow_tools=next_tool_retries < max_retries,
|
|
1003
1130
|
)
|
|
1004
1131
|
return True
|
|
1005
1132
|
|
|
@@ -1150,9 +1277,18 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
1150
1277
|
self.conversation,
|
|
1151
1278
|
self.provider,
|
|
1152
1279
|
scope=self.scope,
|
|
1280
|
+
turn_state=pending.get("turn_state"),
|
|
1153
1281
|
)
|
|
1154
1282
|
history = await self._load_history()
|
|
1155
|
-
await self._stream_provider_turn(
|
|
1283
|
+
await self._stream_provider_turn(
|
|
1284
|
+
messages,
|
|
1285
|
+
history,
|
|
1286
|
+
tool_retries=(
|
|
1287
|
+
pending.get("turn_state")
|
|
1288
|
+
or TurnState.from_settings(get_chat_settings())
|
|
1289
|
+
).tool_retries,
|
|
1290
|
+
turn_state=pending.get("turn_state"),
|
|
1291
|
+
)
|
|
1156
1292
|
finally:
|
|
1157
1293
|
if not followup_turn.done():
|
|
1158
1294
|
followup_turn.set_result(None)
|
|
@@ -1171,6 +1307,21 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
1171
1307
|
|
|
1172
1308
|
from general_manager.chat.models import ChatPendingConfirmation
|
|
1173
1309
|
|
|
1310
|
+
if confirmed:
|
|
1311
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
1312
|
+
self.scope, count_request=False
|
|
1313
|
+
)
|
|
1314
|
+
if isinstance(rate_limited, dict):
|
|
1315
|
+
await self.send_json(
|
|
1316
|
+
{
|
|
1317
|
+
"type": "error",
|
|
1318
|
+
"message": "Chat rate limit exceeded. Try again later.",
|
|
1319
|
+
"code": "rate_limited",
|
|
1320
|
+
"retry_after_seconds": rate_limited["retry_after_seconds"],
|
|
1321
|
+
}
|
|
1322
|
+
)
|
|
1323
|
+
return
|
|
1324
|
+
|
|
1174
1325
|
db_pending: Any | None = None
|
|
1175
1326
|
if pending is None and self.conversation is not None:
|
|
1176
1327
|
db_pending = await sync_to_async(
|
|
@@ -1196,6 +1347,9 @@ class ChatConsumer(_ChatConsumerBase):
|
|
|
1196
1347
|
"history": history,
|
|
1197
1348
|
"expires_at": db_pending.expires_at,
|
|
1198
1349
|
"durable": False,
|
|
1350
|
+
"turn_state": TurnState.from_payload(
|
|
1351
|
+
get_chat_settings(), db_pending.payload
|
|
1352
|
+
),
|
|
1199
1353
|
"rebuild_context_after_tool_result": True,
|
|
1200
1354
|
}
|
|
1201
1355
|
if pending is None or confirmation_id != pending.get("id"):
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
from collections.abc import Awaitable, Callable, Mapping
|
|
7
|
+
import inspect
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
9
10
|
from asgiref.sync import sync_to_async
|
|
@@ -19,6 +20,17 @@ from general_manager.chat.providers.base import DoneEvent, Message, TextChunkEve
|
|
|
19
20
|
from general_manager.chat.rate_limits import enforce_chat_rate_limit
|
|
20
21
|
from general_manager.chat.settings import get_chat_settings
|
|
21
22
|
from general_manager.chat.system_prompt import build_system_prompt
|
|
23
|
+
from general_manager.chat.turns import TurnState
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ChatSummaryRateLimitExceeded(RuntimeError):
|
|
27
|
+
"""Stop a request when history compression consumes its token allowance."""
|
|
28
|
+
|
|
29
|
+
public_reason = "rate_limited"
|
|
30
|
+
|
|
31
|
+
def __init__(self, retry_after_seconds: int) -> None:
|
|
32
|
+
super().__init__("Chat summary token budget exhausted.")
|
|
33
|
+
self.retry_after_seconds = retry_after_seconds
|
|
22
34
|
|
|
23
35
|
|
|
24
36
|
async def summarize_messages_with_provider(
|
|
@@ -26,6 +38,7 @@ async def summarize_messages_with_provider(
|
|
|
26
38
|
messages: list[Any],
|
|
27
39
|
*,
|
|
28
40
|
scope: dict[str, Any] | None = None,
|
|
41
|
+
turn_state: TurnState | None = None,
|
|
29
42
|
) -> str:
|
|
30
43
|
"""Summarize one history prefix within a whole-request provider deadline."""
|
|
31
44
|
prompt_messages = [
|
|
@@ -45,16 +58,40 @@ async def summarize_messages_with_provider(
|
|
|
45
58
|
chunks: list[str] = []
|
|
46
59
|
|
|
47
60
|
async def consume() -> None:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
if turn_state is not None and not turn_state.reserve_round():
|
|
62
|
+
return
|
|
63
|
+
if scope is not None:
|
|
64
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
65
|
+
scope, count_request=False
|
|
66
|
+
)
|
|
67
|
+
if isinstance(rate_limited, dict):
|
|
68
|
+
raise ChatSummaryRateLimitExceeded(rate_limited["retry_after_seconds"])
|
|
69
|
+
events = provider.complete(prompt_messages, [])
|
|
70
|
+
try:
|
|
71
|
+
async for event in events:
|
|
72
|
+
if isinstance(event, TextChunkEvent):
|
|
73
|
+
chunks.append(event.content)
|
|
74
|
+
elif isinstance(event, DoneEvent):
|
|
75
|
+
if turn_state is not None:
|
|
76
|
+
turn_state.record_usage(event.usage)
|
|
77
|
+
if scope is not None:
|
|
78
|
+
rate_limited = await sync_to_async(enforce_chat_rate_limit)(
|
|
79
|
+
scope,
|
|
80
|
+
input_tokens=event.usage.input_tokens,
|
|
81
|
+
output_tokens=event.usage.output_tokens,
|
|
82
|
+
count_request=False,
|
|
83
|
+
)
|
|
84
|
+
if isinstance(rate_limited, dict):
|
|
85
|
+
raise ChatSummaryRateLimitExceeded(
|
|
86
|
+
rate_limited["retry_after_seconds"]
|
|
87
|
+
)
|
|
88
|
+
return
|
|
89
|
+
finally:
|
|
90
|
+
close = getattr(events, "aclose", None)
|
|
91
|
+
if callable(close):
|
|
92
|
+
result = close()
|
|
93
|
+
if inspect.isawaitable(result):
|
|
94
|
+
await result
|
|
58
95
|
|
|
59
96
|
await asyncio.wait_for(consume(), timeout=timeout_seconds)
|
|
60
97
|
return "".join(chunks).strip()
|
|
@@ -67,6 +104,7 @@ async def prepare_conversation_messages(
|
|
|
67
104
|
allow_summarization: bool = True,
|
|
68
105
|
scope: dict[str, Any] | None = None,
|
|
69
106
|
summarize: Callable[[Any, list[Any]], Awaitable[str]] | None = None,
|
|
107
|
+
turn_state: TurnState | None = None,
|
|
70
108
|
) -> list[Message]:
|
|
71
109
|
"""Return system plus bounded durable history for a legacy provider turn."""
|
|
72
110
|
settings = get_chat_settings()
|
|
@@ -86,7 +124,7 @@ async def prepare_conversation_messages(
|
|
|
86
124
|
await summarize(provider, older_messages)
|
|
87
125
|
if summarize is not None
|
|
88
126
|
else await summarize_messages_with_provider(
|
|
89
|
-
provider, older_messages, scope=scope
|
|
127
|
+
provider, older_messages, scope=scope, turn_state=turn_state
|
|
90
128
|
)
|
|
91
129
|
)
|
|
92
130
|
if summary_text:
|