agenta 0.19.8a0__tar.gz → 0.20.0a0__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.
Potentially problematic release.
This version of agenta might be problematic. Click here for more details.
- {agenta-0.19.8a0 → agenta-0.20.0a0}/PKG-INFO +1 -1
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/__init__.py +1 -1
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/create_span.py +4 -1
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/llm_tokens.py +3 -3
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/__init__.py +1 -1
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/decorators/llm_entrypoint.py +197 -78
- agenta-0.20.0a0/agenta/sdk/decorators/tracing.py +91 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/llm_tracing.py +172 -58
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/tasks_manager.py +3 -2
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/tracing_context.py +9 -6
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/types.py +5 -6
- {agenta-0.19.8a0 → agenta-0.20.0a0}/pyproject.toml +1 -1
- agenta-0.19.8a0/agenta/sdk/decorators/tracing.py +0 -186
- {agenta-0.19.8a0 → agenta-0.20.0a0}/README.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/evaluation_commands.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/helper.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/main.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/telemetry.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/variant_commands.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/cli/variant_configs.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/Readme.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/api.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/api_models.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/api_error.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/client_wrapper.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/datetime_utils.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/jsonable_encoder.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/core/remove_none_from_dict.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/errors/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/errors/unprocessable_entity_error.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/apps/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/apps/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/bases/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/bases/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/configs/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/configs/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/containers/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/containers/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/containers/types/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/containers/types/container_templates_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/environments/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/environments/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/evaluations/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/evaluations/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/evaluators/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/evaluators/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/observability/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/observability/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/testsets/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/testsets/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/variants/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/variants/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/variants/types/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/resources/variants/types/add_variant_from_base_and_config_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/aggregated_result.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/aggregated_result_evaluator_config.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/app.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/app_variant_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/app_variant_revision.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/base_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/body_import_testset.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/config_db.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/create_app_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/create_trace_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/docker_env_vars.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/environment_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/environment_output_extended.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/environment_revision.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/error.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_scenario.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_scenario_input.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_scenario_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_scenario_result.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_scenario_score_update.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_status_enum.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_type.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluation_webhook.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluator.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/evaluator_config.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/feedback.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/get_config_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/http_validation_error.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation_scenario.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation_scenario_input.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation_scenario_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation_scenario_update.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/human_evaluation_update.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/image.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/invite_request.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/list_api_keys_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/llm_run_rate_limit.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/new_human_evaluation.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/new_testset.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/organization.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/organization_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/permission.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/result.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/score.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/simple_evaluation_output.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/span.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/span_detail.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/span_kind.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/span_status_code.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/span_variant.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/template.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/template_image_info.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/test_set_output_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/test_set_simple_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/trace_detail.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/uri.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/validation_error.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/validation_error_loc_item.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/variant_action.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/variant_action_enum.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/with_pagination.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/workspace_member_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/workspace_permission.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/workspace_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/workspace_role.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/backend/types/workspace_role_response.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/client/exceptions.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/config.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/config.toml +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/Dockerfile.cloud.template +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/Dockerfile.template +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/README.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/entrypoint.sh +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/lambda_function.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker-assets/main.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/docker/docker_utils.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/agenta_init.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/client.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/context.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/decorators/base.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/router.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/__init__.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/callbacks.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/context_manager.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/tracing/logger.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/utils/debug.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/utils/globals.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/utils/helper/openai_cost.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/sdk/utils/preinit.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/compose_email/README.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/compose_email/app.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/compose_email/env.example +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/compose_email/requirements.txt +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/compose_email/template.toml +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/extract_data_to_json/README.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/extract_data_to_json/app.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/extract_data_to_json/env.example +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/extract_data_to_json/requirements.txt +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/extract_data_to_json/template.toml +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/simple_prompt/README.md +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/simple_prompt/app.py +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/simple_prompt/env.example +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/simple_prompt/requirements.txt +0 -0
- {agenta-0.19.8a0 → agenta-0.20.0a0}/agenta/templates/simple_prompt/template.toml +0 -0
|
@@ -17,7 +17,7 @@ from .sdk.types import (
|
|
|
17
17
|
from .sdk.tracing.logger import llm_logger as logging
|
|
18
18
|
from .sdk.tracing.llm_tracing import Tracing
|
|
19
19
|
from .sdk.decorators.tracing import instrument
|
|
20
|
-
from .sdk.decorators.llm_entrypoint import entrypoint, app
|
|
20
|
+
from .sdk.decorators.llm_entrypoint import entrypoint, app, route
|
|
21
21
|
from .sdk.agenta_init import Config, AgentaSingleton, init
|
|
22
22
|
from .sdk.utils.helper.openai_cost import calculate_token_usage
|
|
23
23
|
from .sdk.client import Agenta
|
|
@@ -20,7 +20,10 @@ class CreateSpan(pydantic.BaseModel):
|
|
|
20
20
|
variant_id: typing.Optional[str]
|
|
21
21
|
variant_name: typing.Optional[str]
|
|
22
22
|
inputs: typing.Optional[typing.Dict[str, typing.Any]]
|
|
23
|
-
|
|
23
|
+
internals: typing.Optional[typing.Dict[str, typing.Any]]
|
|
24
|
+
outputs: typing.Optional[
|
|
25
|
+
typing.Union[typing.Dict[str, typing.Any], typing.List[str]]
|
|
26
|
+
]
|
|
24
27
|
config: typing.Optional[typing.Dict[str, typing.Any]]
|
|
25
28
|
environment: typing.Optional[str]
|
|
26
29
|
tags: typing.Optional[typing.List[str]]
|
|
@@ -12,9 +12,9 @@ except ImportError:
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class LlmTokens(pydantic.BaseModel):
|
|
15
|
-
prompt_tokens: typing.Optional[int]
|
|
16
|
-
completion_tokens: typing.Optional[int]
|
|
17
|
-
total_tokens: typing.Optional[int]
|
|
15
|
+
prompt_tokens: typing.Optional[int] = 0
|
|
16
|
+
completion_tokens: typing.Optional[int] = 0
|
|
17
|
+
total_tokens: typing.Optional[int] = 0
|
|
18
18
|
|
|
19
19
|
def json(self, **kwargs: typing.Any) -> str:
|
|
20
20
|
kwargs_with_defaults: typing.Any = {
|
|
@@ -16,7 +16,7 @@ from .types import (
|
|
|
16
16
|
|
|
17
17
|
from .tracing.llm_tracing import Tracing
|
|
18
18
|
from .decorators.tracing import instrument
|
|
19
|
-
from .decorators.llm_entrypoint import entrypoint, app
|
|
19
|
+
from .decorators.llm_entrypoint import entrypoint, app, route
|
|
20
20
|
from .agenta_init import Config, AgentaSingleton, init
|
|
21
21
|
from .utils.helper.openai_cost import calculate_token_usage
|
|
22
22
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
5
|
import time
|
|
6
|
+
import json
|
|
6
7
|
import inspect
|
|
7
8
|
import argparse
|
|
8
9
|
import asyncio
|
|
@@ -15,11 +16,11 @@ from typing import Any, Callable, Dict, Optional, Tuple, List
|
|
|
15
16
|
from fastapi.middleware.cors import CORSMiddleware
|
|
16
17
|
from fastapi import Body, FastAPI, UploadFile, HTTPException
|
|
17
18
|
|
|
18
|
-
import agenta
|
|
19
|
+
import agenta as ag
|
|
19
20
|
from agenta.sdk.context import save_context
|
|
20
21
|
from agenta.sdk.router import router as router
|
|
21
22
|
from agenta.sdk.tracing.logger import llm_logger as logging
|
|
22
|
-
from agenta.sdk.tracing.
|
|
23
|
+
from agenta.sdk.tracing.tracing_context import tracing_context, TracingContext
|
|
23
24
|
from agenta.sdk.decorators.base import BaseDecorator
|
|
24
25
|
from agenta.sdk.types import (
|
|
25
26
|
Context,
|
|
@@ -32,10 +33,12 @@ from agenta.sdk.types import (
|
|
|
32
33
|
TextParam,
|
|
33
34
|
MessagesInput,
|
|
34
35
|
FileInputURL,
|
|
35
|
-
|
|
36
|
+
BaseResponse,
|
|
36
37
|
BinaryParam,
|
|
37
38
|
)
|
|
38
39
|
|
|
40
|
+
from pydantic import BaseModel, HttpUrl
|
|
41
|
+
|
|
39
42
|
app = FastAPI()
|
|
40
43
|
|
|
41
44
|
origins = [
|
|
@@ -52,16 +55,56 @@ app.add_middleware(
|
|
|
52
55
|
|
|
53
56
|
app.include_router(router, prefix="")
|
|
54
57
|
|
|
55
|
-
|
|
56
58
|
from agenta.sdk.utils.debug import debug, DEBUG, SHIFT
|
|
57
59
|
|
|
58
60
|
|
|
59
61
|
logging.setLevel("DEBUG")
|
|
60
62
|
|
|
61
63
|
|
|
64
|
+
class PathValidator(BaseModel):
|
|
65
|
+
url: HttpUrl
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class route(BaseDecorator):
|
|
69
|
+
# This decorator is used to expose specific stages of a workflow (embedding, retrieval, summarization, etc.)
|
|
70
|
+
# as independent endpoints. It is designed for backward compatibility with existing code that uses
|
|
71
|
+
# the @entrypoint decorator, which has certain limitations. By using @route(), we can create new
|
|
72
|
+
# routes without altering the main workflow entrypoint. This helps in modularizing the services
|
|
73
|
+
# and provides flexibility in how we expose different functionalities as APIs.
|
|
74
|
+
def __init__(self, path):
|
|
75
|
+
path = "/" + path.strip("/").strip()
|
|
76
|
+
path = "" if path == "/" else path
|
|
77
|
+
|
|
78
|
+
PathValidator(url=f"http://example.com{path}")
|
|
79
|
+
|
|
80
|
+
self.route_path = path
|
|
81
|
+
|
|
82
|
+
def __call__(self, f):
|
|
83
|
+
self.e = entrypoint(f, route_path=self.route_path)
|
|
84
|
+
|
|
85
|
+
return f
|
|
86
|
+
|
|
87
|
+
|
|
62
88
|
class entrypoint(BaseDecorator):
|
|
63
|
-
"""
|
|
89
|
+
"""
|
|
90
|
+
Decorator class to wrap a function for HTTP POST, terminal exposure and enable tracing.
|
|
91
|
+
|
|
92
|
+
This decorator generates the following endpoints:
|
|
93
|
+
|
|
94
|
+
Playground Endpoints
|
|
95
|
+
- /generate with @entrypoint, @route("/"), @route(path="") # LEGACY
|
|
96
|
+
- /playground/run with @entrypoint, @route("/"), @route(path="")
|
|
97
|
+
- /playground/run/{route} with @route({route}), @route(path={route})
|
|
64
98
|
|
|
99
|
+
Deployed Endpoints:
|
|
100
|
+
- /generate_deployed with @entrypoint, @route("/"), @route(path="") # LEGACY
|
|
101
|
+
- /run with @entrypoint, @route("/"), @route(path="")
|
|
102
|
+
- /run/{route} with @route({route}), @route(path={route})
|
|
103
|
+
|
|
104
|
+
The rationale is:
|
|
105
|
+
- There may be multiple endpoints, based on the different routes.
|
|
106
|
+
- It's better to make it explicit that an endpoint is for the playground.
|
|
107
|
+
- Prefixing the routes with /run is more futureproof in case we add more endpoints.
|
|
65
108
|
|
|
66
109
|
Example:
|
|
67
110
|
```python
|
|
@@ -73,31 +116,64 @@ class entrypoint(BaseDecorator):
|
|
|
73
116
|
```
|
|
74
117
|
"""
|
|
75
118
|
|
|
76
|
-
|
|
77
|
-
|
|
119
|
+
routes = list()
|
|
120
|
+
|
|
121
|
+
def __init__(self, func: Callable[..., Any], route_path=""):
|
|
122
|
+
DEFAULT_PATH = "generate"
|
|
123
|
+
PLAYGROUND_PATH = "/playground"
|
|
124
|
+
RUN_PATH = "/run"
|
|
125
|
+
|
|
78
126
|
func_signature = inspect.signature(func)
|
|
79
|
-
config_params =
|
|
127
|
+
config_params = ag.config.all()
|
|
80
128
|
ingestible_files = self.extract_ingestible_files(func_signature)
|
|
81
129
|
|
|
130
|
+
### --- Playground --- #
|
|
82
131
|
@debug()
|
|
83
132
|
@functools.wraps(func)
|
|
84
133
|
async def wrapper(*args, **kwargs) -> Any:
|
|
85
134
|
func_params, api_config_params = self.split_kwargs(kwargs, config_params)
|
|
86
135
|
self.ingest_files(func_params, ingestible_files)
|
|
87
|
-
|
|
136
|
+
ag.config.set(**api_config_params)
|
|
88
137
|
|
|
89
138
|
# Set the configuration and environment of the LLM app parent span at run-time
|
|
90
|
-
|
|
139
|
+
ag.tracing.update_baggage(
|
|
91
140
|
{"config": config_params, "environment": "playground"}
|
|
92
141
|
)
|
|
93
142
|
|
|
94
|
-
|
|
95
|
-
llm_result = await self.execute_function(
|
|
143
|
+
entrypoint_result = await self.execute_function(
|
|
96
144
|
func, *args, params=func_params, config_params=config_params
|
|
97
145
|
)
|
|
98
146
|
|
|
99
|
-
return
|
|
147
|
+
return entrypoint_result
|
|
148
|
+
|
|
149
|
+
self.update_function_signature(
|
|
150
|
+
wrapper, func_signature, config_params, ingestible_files
|
|
151
|
+
)
|
|
100
152
|
|
|
153
|
+
#
|
|
154
|
+
if route_path == "":
|
|
155
|
+
route = f"/{DEFAULT_PATH}"
|
|
156
|
+
app.post(route, response_model=BaseResponse)(wrapper)
|
|
157
|
+
entrypoint.routes.append(
|
|
158
|
+
{
|
|
159
|
+
"func": func.__name__,
|
|
160
|
+
"endpoint": DEFAULT_PATH,
|
|
161
|
+
"params": {**config_params, **func_signature.parameters},
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
route = f"{PLAYGROUND_PATH}{RUN_PATH}{route_path}"
|
|
166
|
+
app.post(route, response_model=BaseResponse)(wrapper)
|
|
167
|
+
entrypoint.routes.append(
|
|
168
|
+
{
|
|
169
|
+
"func": func.__name__,
|
|
170
|
+
"endpoint": route[1:].replace("/", "_"),
|
|
171
|
+
"params": {**config_params, **func_signature.parameters},
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
### ---------------------------- #
|
|
175
|
+
|
|
176
|
+
### --- Deployed / Published --- #
|
|
101
177
|
@debug()
|
|
102
178
|
@functools.wraps(func)
|
|
103
179
|
async def wrapper_deployed(*args, **kwargs) -> Any:
|
|
@@ -106,44 +182,51 @@ class entrypoint(BaseDecorator):
|
|
|
106
182
|
}
|
|
107
183
|
|
|
108
184
|
if "environment" in kwargs and kwargs["environment"] is not None:
|
|
109
|
-
|
|
185
|
+
ag.config.pull(environment_name=kwargs["environment"])
|
|
110
186
|
elif "config" in kwargs and kwargs["config"] is not None:
|
|
111
|
-
|
|
187
|
+
ag.config.pull(config_name=kwargs["config"])
|
|
112
188
|
else:
|
|
113
|
-
|
|
189
|
+
ag.config.pull(config_name="default")
|
|
114
190
|
|
|
115
191
|
# Set the configuration and environment of the LLM app parent span at run-time
|
|
116
|
-
|
|
192
|
+
ag.tracing.update_baggage(
|
|
117
193
|
{"config": config_params, "environment": kwargs["environment"]}
|
|
118
194
|
)
|
|
119
195
|
|
|
120
|
-
|
|
196
|
+
entrypoint_result = await self.execute_function(
|
|
121
197
|
func, *args, params=func_params, config_params=config_params
|
|
122
198
|
)
|
|
123
199
|
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
self.update_function_signature(
|
|
127
|
-
wrapper, func_signature, config_params, ingestible_files
|
|
128
|
-
)
|
|
129
|
-
route = f"/{endpoint_name}"
|
|
130
|
-
app.post(route, response_model=FuncResponse)(wrapper)
|
|
200
|
+
return entrypoint_result
|
|
131
201
|
|
|
132
202
|
self.update_deployed_function_signature(
|
|
133
203
|
wrapper_deployed,
|
|
134
204
|
func_signature,
|
|
135
205
|
ingestible_files,
|
|
136
206
|
)
|
|
137
|
-
route_deployed = f"/{endpoint_name}_deployed"
|
|
138
|
-
app.post(route_deployed, response_model=FuncResponse)(wrapper_deployed)
|
|
139
|
-
self.override_schema(
|
|
140
|
-
openapi_schema=app.openapi(),
|
|
141
|
-
func_name=func.__name__,
|
|
142
|
-
endpoint=endpoint_name,
|
|
143
|
-
params={**config_params, **func_signature.parameters},
|
|
144
|
-
)
|
|
145
207
|
|
|
146
|
-
if
|
|
208
|
+
if route_path == "/":
|
|
209
|
+
route_deployed = f"/{DEFAULT_PATH}_deployed"
|
|
210
|
+
app.post(route_deployed, response_model=BaseResponse)(wrapper_deployed)
|
|
211
|
+
|
|
212
|
+
route_deployed = f"{RUN_PATH}{route_path}"
|
|
213
|
+
app.post(route_deployed, response_model=BaseResponse)(wrapper_deployed)
|
|
214
|
+
### ---------------------------- #
|
|
215
|
+
|
|
216
|
+
### --- Update OpenAPI --- #
|
|
217
|
+
app.openapi_schema = None # Forces FastAPI to re-generate the schema
|
|
218
|
+
openapi_schema = app.openapi()
|
|
219
|
+
|
|
220
|
+
for route in entrypoint.routes:
|
|
221
|
+
self.override_schema(
|
|
222
|
+
openapi_schema=openapi_schema,
|
|
223
|
+
func=route["func"],
|
|
224
|
+
endpoint=route["endpoint"],
|
|
225
|
+
params=route["params"],
|
|
226
|
+
)
|
|
227
|
+
### ---------------------- #
|
|
228
|
+
|
|
229
|
+
if self.is_main_script(func) and route_path == "":
|
|
147
230
|
self.handle_terminal_run(
|
|
148
231
|
func,
|
|
149
232
|
func_signature.parameters, # type: ignore
|
|
@@ -198,51 +281,55 @@ class entrypoint(BaseDecorator):
|
|
|
198
281
|
For synchronous functions, it calls them directly, while for asynchronous functions,
|
|
199
282
|
it awaits their execution.
|
|
200
283
|
"""
|
|
284
|
+
data = None
|
|
285
|
+
trace = None
|
|
286
|
+
|
|
287
|
+
token = None
|
|
288
|
+
if tracing_context.get() is None:
|
|
289
|
+
token = tracing_context.set(TracingContext())
|
|
290
|
+
|
|
201
291
|
is_coroutine_function = inspect.iscoroutinefunction(func)
|
|
202
|
-
start_time = time.perf_counter()
|
|
203
292
|
|
|
204
293
|
if is_coroutine_function:
|
|
205
294
|
result = await func(*args, **func_params["params"])
|
|
206
295
|
else:
|
|
207
296
|
result = func(*args, **func_params["params"])
|
|
208
297
|
|
|
209
|
-
|
|
210
|
-
|
|
298
|
+
if token is not None:
|
|
299
|
+
trace = ag.tracing.dump_trace()
|
|
300
|
+
tracing_context.reset(token)
|
|
211
301
|
|
|
212
302
|
if isinstance(result, Context):
|
|
213
303
|
save_context(result)
|
|
304
|
+
|
|
214
305
|
if isinstance(result, Dict):
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
cost=None,
|
|
225
|
-
latency=round(latency, 4),
|
|
226
|
-
)
|
|
227
|
-
if result is None:
|
|
228
|
-
return FuncResponse(
|
|
229
|
-
message="Function executed successfully, but did return None. \n Are you sure you did not forget to return a value?",
|
|
230
|
-
usage=None,
|
|
231
|
-
cost=None,
|
|
232
|
-
latency=round(latency, 4),
|
|
306
|
+
data = result
|
|
307
|
+
elif isinstance(result, str):
|
|
308
|
+
data = {"message": result}
|
|
309
|
+
elif isinstance(result, int) or isinstance(result, float):
|
|
310
|
+
data = {"message": str(result)}
|
|
311
|
+
|
|
312
|
+
if data is None:
|
|
313
|
+
warning = (
|
|
314
|
+
"Function executed successfully, but did return None. \n Are you sure you did not forget to return a value?",
|
|
233
315
|
)
|
|
316
|
+
|
|
317
|
+
data = {"message": warning}
|
|
318
|
+
|
|
319
|
+
return BaseResponse(data=data, trace=trace)
|
|
320
|
+
|
|
234
321
|
except Exception as e:
|
|
235
322
|
self.handle_exception(e)
|
|
236
|
-
return FuncResponse(message="Unexpected error occurred when calling the @entrypoint decorated function", latency=0) # type: ignore
|
|
237
323
|
|
|
238
324
|
def handle_exception(self, e: Exception):
|
|
239
|
-
|
|
325
|
+
status_code = e.status_code if hasattr(e, "status_code") else 500
|
|
326
|
+
message = str(e)
|
|
327
|
+
stacktrace = traceback.format_exception(e, value=e, tb=e.__traceback__) # type: ignore
|
|
328
|
+
detail = {"message": message, "stacktrace": stacktrace}
|
|
240
329
|
|
|
241
|
-
status_code: int = e.status_code if hasattr(e, "status_code") else 500
|
|
242
|
-
traceback_str = traceback.format_exception(e, value=e, tb=e.__traceback__) # type: ignore
|
|
243
330
|
raise HTTPException(
|
|
244
331
|
status_code=status_code,
|
|
245
|
-
detail=
|
|
332
|
+
detail=detail,
|
|
246
333
|
)
|
|
247
334
|
|
|
248
335
|
def update_wrapper_signature(
|
|
@@ -418,26 +505,29 @@ class entrypoint(BaseDecorator):
|
|
|
418
505
|
file_path=args_func_params[name],
|
|
419
506
|
)
|
|
420
507
|
|
|
421
|
-
|
|
508
|
+
ag.config.set(**args_config_params)
|
|
422
509
|
|
|
423
510
|
# Set the configuration and environment of the LLM app parent span at run-time
|
|
424
|
-
|
|
425
|
-
{"config": agenta.config.all(), "environment": "bash"}
|
|
426
|
-
)
|
|
511
|
+
ag.tracing.update_baggage({"config": ag.config.all(), "environment": "bash"})
|
|
427
512
|
|
|
428
513
|
loop = asyncio.get_event_loop()
|
|
514
|
+
|
|
429
515
|
result = loop.run_until_complete(
|
|
430
516
|
self.execute_function(
|
|
431
517
|
func,
|
|
432
518
|
**{"params": args_func_params, "config_params": args_config_params},
|
|
433
519
|
)
|
|
434
520
|
)
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
521
|
+
|
|
522
|
+
print(f"\n========== Result ==========\n")
|
|
523
|
+
|
|
524
|
+
print("-> data")
|
|
525
|
+
print(json.dumps(result.data, indent=2))
|
|
526
|
+
print("-> trace")
|
|
527
|
+
print(json.dumps(result.trace, indent=2))
|
|
438
528
|
|
|
439
529
|
def override_schema(
|
|
440
|
-
self, openapi_schema: dict,
|
|
530
|
+
self, openapi_schema: dict, func: str, endpoint: str, params: dict
|
|
441
531
|
):
|
|
442
532
|
"""
|
|
443
533
|
Overrides the default openai schema generated by fastapi with additional information about:
|
|
@@ -452,7 +542,7 @@ class entrypoint(BaseDecorator):
|
|
|
452
542
|
|
|
453
543
|
Args:
|
|
454
544
|
openapi_schema (dict): The openapi schema generated by fastapi
|
|
455
|
-
|
|
545
|
+
func (str): The name of the function to override
|
|
456
546
|
endpoint (str): The name of the endpoint to override
|
|
457
547
|
params (dict(param_name, param_val)): The dictionary of the parameters for the function
|
|
458
548
|
"""
|
|
@@ -484,8 +574,29 @@ class entrypoint(BaseDecorator):
|
|
|
484
574
|
# value = {'temperature': { "type": "number", "title": "Temperature", "x-parameter": "float" }}
|
|
485
575
|
return value
|
|
486
576
|
|
|
577
|
+
def get_type_from_param(param_val):
|
|
578
|
+
param_type = "string"
|
|
579
|
+
annotation = param_val.annotation
|
|
580
|
+
|
|
581
|
+
if annotation == int:
|
|
582
|
+
param_type = "integer"
|
|
583
|
+
elif annotation == float:
|
|
584
|
+
param_type = "number"
|
|
585
|
+
elif annotation == dict:
|
|
586
|
+
param_type = "object"
|
|
587
|
+
elif annotation == bool:
|
|
588
|
+
param_type = "boolean"
|
|
589
|
+
elif annotation == list:
|
|
590
|
+
param_type = "list"
|
|
591
|
+
elif annotation == str:
|
|
592
|
+
param_type = "string"
|
|
593
|
+
else:
|
|
594
|
+
print("ERROR, unhandled annotation:", annotation)
|
|
595
|
+
|
|
596
|
+
return param_type
|
|
597
|
+
|
|
487
598
|
schema_to_override = openapi_schema["components"]["schemas"][
|
|
488
|
-
f"Body_{
|
|
599
|
+
f"Body_{func}_{endpoint}_post"
|
|
489
600
|
]["properties"]
|
|
490
601
|
for param_name, param_val in params.items():
|
|
491
602
|
if isinstance(param_val, GroupedMultipleChoiceParam):
|
|
@@ -501,7 +612,7 @@ class entrypoint(BaseDecorator):
|
|
|
501
612
|
subschema["choices"] = param_val.choices # type: ignore
|
|
502
613
|
subschema["default"] = param_val.default # type: ignore
|
|
503
614
|
|
|
504
|
-
|
|
615
|
+
elif isinstance(param_val, MultipleChoiceParam):
|
|
505
616
|
subschema = find_in_schema(
|
|
506
617
|
param_val.__schema_type_properties__(),
|
|
507
618
|
schema_to_override,
|
|
@@ -520,7 +631,7 @@ class entrypoint(BaseDecorator):
|
|
|
520
631
|
default if default in param_choices else choices[0]
|
|
521
632
|
)
|
|
522
633
|
|
|
523
|
-
|
|
634
|
+
elif isinstance(param_val, FloatParam):
|
|
524
635
|
subschema = find_in_schema(
|
|
525
636
|
param_val.__schema_type_properties__(),
|
|
526
637
|
schema_to_override,
|
|
@@ -531,7 +642,7 @@ class entrypoint(BaseDecorator):
|
|
|
531
642
|
subschema["maximum"] = param_val.maxval # type: ignore
|
|
532
643
|
subschema["default"] = param_val
|
|
533
644
|
|
|
534
|
-
|
|
645
|
+
elif isinstance(param_val, IntParam):
|
|
535
646
|
subschema = find_in_schema(
|
|
536
647
|
param_val.__schema_type_properties__(),
|
|
537
648
|
schema_to_override,
|
|
@@ -542,7 +653,7 @@ class entrypoint(BaseDecorator):
|
|
|
542
653
|
subschema["maximum"] = param_val.maxval # type: ignore
|
|
543
654
|
subschema["default"] = param_val
|
|
544
655
|
|
|
545
|
-
|
|
656
|
+
elif (
|
|
546
657
|
isinstance(param_val, inspect.Parameter)
|
|
547
658
|
and param_val.annotation is DictInput
|
|
548
659
|
):
|
|
@@ -554,7 +665,7 @@ class entrypoint(BaseDecorator):
|
|
|
554
665
|
)
|
|
555
666
|
subschema["default"] = param_val.default["default_keys"]
|
|
556
667
|
|
|
557
|
-
|
|
668
|
+
elif isinstance(param_val, TextParam):
|
|
558
669
|
subschema = find_in_schema(
|
|
559
670
|
param_val.__schema_type_properties__(),
|
|
560
671
|
schema_to_override,
|
|
@@ -563,7 +674,7 @@ class entrypoint(BaseDecorator):
|
|
|
563
674
|
)
|
|
564
675
|
subschema["default"] = param_val
|
|
565
676
|
|
|
566
|
-
|
|
677
|
+
elif (
|
|
567
678
|
isinstance(param_val, inspect.Parameter)
|
|
568
679
|
and param_val.annotation is MessagesInput
|
|
569
680
|
):
|
|
@@ -575,7 +686,7 @@ class entrypoint(BaseDecorator):
|
|
|
575
686
|
)
|
|
576
687
|
subschema["default"] = param_val.default
|
|
577
688
|
|
|
578
|
-
|
|
689
|
+
elif (
|
|
579
690
|
isinstance(param_val, inspect.Parameter)
|
|
580
691
|
and param_val.annotation is FileInputURL
|
|
581
692
|
):
|
|
@@ -587,7 +698,7 @@ class entrypoint(BaseDecorator):
|
|
|
587
698
|
)
|
|
588
699
|
subschema["default"] = "https://example.com"
|
|
589
700
|
|
|
590
|
-
|
|
701
|
+
elif isinstance(param_val, BinaryParam):
|
|
591
702
|
subschema = find_in_schema(
|
|
592
703
|
param_val.__schema_type_properties__(),
|
|
593
704
|
schema_to_override,
|
|
@@ -595,3 +706,11 @@ class entrypoint(BaseDecorator):
|
|
|
595
706
|
"bool",
|
|
596
707
|
)
|
|
597
708
|
subschema["default"] = param_val.default # type: ignore
|
|
709
|
+
else:
|
|
710
|
+
subschema = {
|
|
711
|
+
"title": str(param_name).capitalize(),
|
|
712
|
+
"type": get_type_from_param(param_val),
|
|
713
|
+
}
|
|
714
|
+
if param_val.default != inspect._empty:
|
|
715
|
+
subschema["default"] = param_val.default # type: ignore
|
|
716
|
+
schema_to_override[param_name] = subschema
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Stdlib Imports
|
|
2
|
+
import inspect
|
|
3
|
+
import traceback
|
|
4
|
+
from functools import wraps
|
|
5
|
+
from typing import Any, Callable, Optional
|
|
6
|
+
|
|
7
|
+
# Own Imports
|
|
8
|
+
import agenta as ag
|
|
9
|
+
from agenta.sdk.decorators.base import BaseDecorator
|
|
10
|
+
from agenta.sdk.tracing.logger import llm_logger as logging
|
|
11
|
+
from agenta.sdk.utils.debug import debug, DEBUG, SHIFT
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logging.setLevel("DEBUG")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class instrument(BaseDecorator):
|
|
18
|
+
"""Decorator class for monitoring llm apps functions.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
BaseDecorator (object): base decorator class
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
```python
|
|
25
|
+
import agenta as ag
|
|
26
|
+
|
|
27
|
+
prompt_config = {"system_prompt": ..., "temperature": 0.5, "max_tokens": ...}
|
|
28
|
+
|
|
29
|
+
@ag.instrument(spankind="llm")
|
|
30
|
+
async def litellm_openai_call(prompt:str) -> str:
|
|
31
|
+
return "do something"
|
|
32
|
+
|
|
33
|
+
@ag.instrument(config=prompt_config) # spankind for parent span defaults to workflow
|
|
34
|
+
async def generate(prompt: str):
|
|
35
|
+
return ...
|
|
36
|
+
```
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
config: Optional[dict] = None,
|
|
42
|
+
spankind: str = "workflow",
|
|
43
|
+
) -> None:
|
|
44
|
+
self.config = config
|
|
45
|
+
self.spankind = spankind
|
|
46
|
+
|
|
47
|
+
def __call__(self, func: Callable[..., Any]):
|
|
48
|
+
is_coroutine_function = inspect.iscoroutinefunction(func)
|
|
49
|
+
|
|
50
|
+
def get_inputs(*args, **kwargs):
|
|
51
|
+
func_args = inspect.getfullargspec(func).args
|
|
52
|
+
input_dict = {name: value for name, value in zip(func_args, args)}
|
|
53
|
+
input_dict.update(kwargs)
|
|
54
|
+
|
|
55
|
+
return input_dict
|
|
56
|
+
|
|
57
|
+
@wraps(func)
|
|
58
|
+
async def async_wrapper(*args, **kwargs):
|
|
59
|
+
async def wrapped_func(*args, **kwargs):
|
|
60
|
+
with ag.tracing.Context(
|
|
61
|
+
name=func.__name__,
|
|
62
|
+
input=get_inputs(*args, **kwargs),
|
|
63
|
+
spankind=self.spankind,
|
|
64
|
+
config=self.config,
|
|
65
|
+
):
|
|
66
|
+
result = await func(*args, **kwargs)
|
|
67
|
+
|
|
68
|
+
ag.tracing.store_outputs(result)
|
|
69
|
+
|
|
70
|
+
return result
|
|
71
|
+
|
|
72
|
+
return await wrapped_func(*args, **kwargs)
|
|
73
|
+
|
|
74
|
+
@wraps(func)
|
|
75
|
+
def sync_wrapper(*args, **kwargs):
|
|
76
|
+
def wrapped_func(*args, **kwargs):
|
|
77
|
+
with ag.tracing.Context(
|
|
78
|
+
name=func.__name__,
|
|
79
|
+
input=get_inputs(*args, **kwargs),
|
|
80
|
+
spankind=self.spankind,
|
|
81
|
+
config=self.config,
|
|
82
|
+
):
|
|
83
|
+
result = func(*args, **kwargs)
|
|
84
|
+
|
|
85
|
+
ag.tracing.store_outputs(result)
|
|
86
|
+
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
return wrapped_func(*args, **kwargs)
|
|
90
|
+
|
|
91
|
+
return async_wrapper if is_coroutine_function else sync_wrapper
|