edsl 0.1.48__py3-none-any.whl → 0.1.50__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edsl/__init__.py +124 -53
- edsl/__version__.py +1 -1
- edsl/agents/agent.py +21 -21
- edsl/agents/agent_list.py +2 -5
- edsl/agents/exceptions.py +119 -5
- edsl/base/__init__.py +10 -35
- edsl/base/base_class.py +71 -36
- edsl/base/base_exception.py +204 -0
- edsl/base/data_transfer_models.py +1 -1
- edsl/base/exceptions.py +94 -0
- edsl/buckets/__init__.py +15 -1
- edsl/buckets/bucket_collection.py +3 -4
- edsl/buckets/exceptions.py +75 -0
- edsl/buckets/model_buckets.py +1 -2
- edsl/buckets/token_bucket.py +11 -6
- edsl/buckets/token_bucket_api.py +1 -2
- edsl/buckets/token_bucket_client.py +9 -7
- edsl/caching/cache.py +7 -2
- edsl/caching/cache_entry.py +10 -9
- edsl/caching/exceptions.py +113 -7
- edsl/caching/remote_cache_sync.py +1 -2
- edsl/caching/sql_dict.py +17 -12
- edsl/cli.py +43 -0
- edsl/config/config_class.py +30 -6
- edsl/conversation/Conversation.py +3 -2
- edsl/conversation/exceptions.py +58 -0
- edsl/conversation/mug_negotiation.py +0 -2
- edsl/coop/__init__.py +20 -1
- edsl/coop/coop.py +129 -38
- edsl/coop/exceptions.py +188 -9
- edsl/coop/price_fetcher.py +3 -6
- edsl/coop/utils.py +4 -6
- edsl/dataset/__init__.py +5 -4
- edsl/dataset/dataset.py +53 -43
- edsl/dataset/dataset_operations_mixin.py +86 -72
- edsl/dataset/dataset_tree.py +9 -5
- edsl/dataset/display/table_display.py +0 -2
- edsl/dataset/display/table_renderers.py +0 -1
- edsl/dataset/exceptions.py +125 -0
- edsl/dataset/file_exports.py +18 -11
- edsl/dataset/r/ggplot.py +13 -6
- edsl/display/__init__.py +27 -0
- edsl/display/core.py +147 -0
- edsl/display/plugin.py +189 -0
- edsl/display/utils.py +52 -0
- edsl/inference_services/__init__.py +9 -1
- edsl/inference_services/available_model_cache_handler.py +1 -1
- edsl/inference_services/available_model_fetcher.py +4 -5
- edsl/inference_services/data_structures.py +9 -6
- edsl/inference_services/exceptions.py +132 -1
- edsl/inference_services/inference_service_abc.py +2 -2
- edsl/inference_services/inference_services_collection.py +2 -6
- edsl/inference_services/registry.py +4 -3
- edsl/inference_services/service_availability.py +2 -1
- edsl/inference_services/services/anthropic_service.py +4 -1
- edsl/inference_services/services/aws_bedrock.py +13 -12
- edsl/inference_services/services/azure_ai.py +12 -10
- edsl/inference_services/services/deep_infra_service.py +1 -4
- edsl/inference_services/services/deep_seek_service.py +1 -5
- edsl/inference_services/services/google_service.py +6 -2
- edsl/inference_services/services/groq_service.py +1 -1
- edsl/inference_services/services/mistral_ai_service.py +4 -2
- edsl/inference_services/services/ollama_service.py +1 -1
- edsl/inference_services/services/open_ai_service.py +7 -5
- edsl/inference_services/services/perplexity_service.py +6 -2
- edsl/inference_services/services/test_service.py +8 -7
- edsl/inference_services/services/together_ai_service.py +2 -3
- edsl/inference_services/services/xai_service.py +1 -1
- edsl/instructions/__init__.py +1 -1
- edsl/instructions/change_instruction.py +3 -2
- edsl/instructions/exceptions.py +61 -0
- edsl/instructions/instruction.py +5 -2
- edsl/instructions/instruction_collection.py +2 -1
- edsl/instructions/instruction_handler.py +4 -9
- edsl/interviews/ReportErrors.py +0 -3
- edsl/interviews/__init__.py +9 -2
- edsl/interviews/answering_function.py +11 -13
- edsl/interviews/exception_tracking.py +14 -7
- edsl/interviews/exceptions.py +79 -0
- edsl/interviews/interview.py +32 -29
- edsl/interviews/interview_status_dictionary.py +4 -2
- edsl/interviews/interview_status_log.py +2 -1
- edsl/interviews/interview_task_manager.py +3 -3
- edsl/interviews/request_token_estimator.py +3 -1
- edsl/interviews/statistics.py +2 -3
- edsl/invigilators/__init__.py +7 -1
- edsl/invigilators/exceptions.py +79 -0
- edsl/invigilators/invigilator_base.py +0 -1
- edsl/invigilators/invigilators.py +8 -12
- edsl/invigilators/prompt_constructor.py +1 -5
- edsl/invigilators/prompt_helpers.py +8 -4
- edsl/invigilators/question_instructions_prompt_builder.py +1 -1
- edsl/invigilators/question_option_processor.py +9 -5
- edsl/invigilators/question_template_replacements_builder.py +3 -2
- edsl/jobs/__init__.py +3 -3
- edsl/jobs/async_interview_runner.py +24 -22
- edsl/jobs/check_survey_scenario_compatibility.py +7 -6
- edsl/jobs/data_structures.py +7 -4
- edsl/jobs/exceptions.py +177 -8
- edsl/jobs/fetch_invigilator.py +1 -1
- edsl/jobs/jobs.py +72 -67
- edsl/jobs/jobs_checks.py +2 -3
- edsl/jobs/jobs_component_constructor.py +2 -2
- edsl/jobs/jobs_pricing_estimation.py +3 -2
- edsl/jobs/jobs_remote_inference_logger.py +5 -4
- edsl/jobs/jobs_runner_asyncio.py +1 -2
- edsl/jobs/jobs_runner_status.py +8 -9
- edsl/jobs/remote_inference.py +26 -23
- edsl/jobs/results_exceptions_handler.py +8 -5
- edsl/key_management/__init__.py +3 -1
- edsl/key_management/exceptions.py +62 -0
- edsl/key_management/key_lookup.py +1 -1
- edsl/key_management/key_lookup_builder.py +37 -14
- edsl/key_management/key_lookup_collection.py +2 -0
- edsl/language_models/__init__.py +1 -1
- edsl/language_models/exceptions.py +302 -14
- edsl/language_models/language_model.py +4 -7
- edsl/language_models/model.py +4 -4
- edsl/language_models/model_list.py +1 -1
- edsl/language_models/price_manager.py +1 -1
- edsl/language_models/raw_response_handler.py +14 -9
- edsl/language_models/registry.py +17 -21
- edsl/language_models/repair.py +0 -6
- edsl/language_models/unused/fake_openai_service.py +0 -1
- edsl/load_plugins.py +69 -0
- edsl/logger.py +146 -0
- edsl/notebooks/notebook.py +1 -1
- edsl/notebooks/notebook_to_latex.py +0 -1
- edsl/plugins/__init__.py +63 -0
- edsl/plugins/built_in/export_example.py +50 -0
- edsl/plugins/built_in/pig_latin.py +67 -0
- edsl/plugins/cli.py +372 -0
- edsl/plugins/cli_typer.py +283 -0
- edsl/plugins/exceptions.py +31 -0
- edsl/plugins/hookspec.py +51 -0
- edsl/plugins/plugin_host.py +128 -0
- edsl/plugins/plugin_manager.py +633 -0
- edsl/plugins/plugins_registry.py +168 -0
- edsl/prompts/__init__.py +2 -0
- edsl/prompts/exceptions.py +107 -5
- edsl/prompts/prompt.py +14 -6
- edsl/questions/HTMLQuestion.py +5 -11
- edsl/questions/Quick.py +0 -1
- edsl/questions/__init__.py +2 -0
- edsl/questions/answer_validator_mixin.py +318 -318
- edsl/questions/compose_questions.py +2 -2
- edsl/questions/descriptors.py +10 -49
- edsl/questions/exceptions.py +278 -22
- edsl/questions/loop_processor.py +7 -5
- edsl/questions/prompt_templates/question_list.jinja +3 -0
- edsl/questions/question_base.py +14 -16
- edsl/questions/question_base_gen_mixin.py +2 -2
- edsl/questions/question_base_prompts_mixin.py +9 -3
- edsl/questions/question_budget.py +9 -5
- edsl/questions/question_check_box.py +3 -5
- edsl/questions/question_dict.py +171 -194
- edsl/questions/question_extract.py +1 -1
- edsl/questions/question_free_text.py +4 -6
- edsl/questions/question_functional.py +4 -3
- edsl/questions/question_list.py +36 -9
- edsl/questions/question_matrix.py +95 -61
- edsl/questions/question_multiple_choice.py +6 -4
- edsl/questions/question_numerical.py +2 -4
- edsl/questions/question_registry.py +4 -2
- edsl/questions/register_questions_meta.py +0 -1
- edsl/questions/response_validator_abc.py +7 -13
- edsl/questions/templates/dict/answering_instructions.jinja +1 -0
- edsl/questions/templates/rank/question_presentation.jinja +1 -1
- edsl/results/__init__.py +1 -1
- edsl/results/exceptions.py +141 -7
- edsl/results/report.py +0 -1
- edsl/results/result.py +4 -5
- edsl/results/results.py +10 -51
- edsl/results/results_selector.py +8 -4
- edsl/scenarios/PdfExtractor.py +2 -2
- edsl/scenarios/construct_download_link.py +69 -35
- edsl/scenarios/directory_scanner.py +33 -14
- edsl/scenarios/document_chunker.py +1 -1
- edsl/scenarios/exceptions.py +238 -14
- edsl/scenarios/file_methods.py +1 -1
- edsl/scenarios/file_store.py +7 -3
- edsl/scenarios/handlers/__init__.py +17 -0
- edsl/scenarios/handlers/docx_file_store.py +0 -5
- edsl/scenarios/handlers/pdf_file_store.py +0 -1
- edsl/scenarios/handlers/pptx_file_store.py +0 -5
- edsl/scenarios/handlers/py_file_store.py +0 -1
- edsl/scenarios/handlers/sql_file_store.py +1 -4
- edsl/scenarios/handlers/sqlite_file_store.py +0 -1
- edsl/scenarios/handlers/txt_file_store.py +1 -1
- edsl/scenarios/scenario.py +0 -1
- edsl/scenarios/scenario_list.py +152 -18
- edsl/scenarios/scenario_list_pdf_tools.py +1 -0
- edsl/scenarios/scenario_selector.py +0 -1
- edsl/surveys/__init__.py +3 -4
- edsl/surveys/dag/__init__.py +4 -2
- edsl/surveys/descriptors.py +1 -1
- edsl/surveys/edit_survey.py +1 -0
- edsl/surveys/exceptions.py +165 -9
- edsl/surveys/memory/__init__.py +5 -3
- edsl/surveys/memory/memory_management.py +1 -0
- edsl/surveys/memory/memory_plan.py +6 -15
- edsl/surveys/rules/__init__.py +5 -3
- edsl/surveys/rules/rule.py +1 -2
- edsl/surveys/rules/rule_collection.py +1 -1
- edsl/surveys/survey.py +12 -24
- edsl/surveys/survey_export.py +6 -3
- edsl/surveys/survey_flow_visualization.py +10 -1
- edsl/tasks/__init__.py +2 -0
- edsl/tasks/question_task_creator.py +3 -3
- edsl/tasks/task_creators.py +1 -3
- edsl/tasks/task_history.py +5 -7
- edsl/tasks/task_status_log.py +1 -2
- edsl/tokens/__init__.py +3 -1
- edsl/tokens/token_usage.py +1 -1
- edsl/utilities/__init__.py +21 -1
- edsl/utilities/decorators.py +1 -2
- edsl/utilities/markdown_to_docx.py +2 -2
- edsl/utilities/markdown_to_pdf.py +1 -1
- edsl/utilities/repair_functions.py +0 -1
- edsl/utilities/restricted_python.py +0 -1
- edsl/utilities/template_loader.py +2 -3
- edsl/utilities/utilities.py +8 -29
- {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/METADATA +32 -2
- edsl-0.1.50.dist-info/RECORD +363 -0
- edsl-0.1.50.dist-info/entry_points.txt +3 -0
- edsl/dataset/smart_objects.py +0 -96
- edsl/exceptions/BaseException.py +0 -21
- edsl/exceptions/__init__.py +0 -54
- edsl/exceptions/configuration.py +0 -16
- edsl/exceptions/general.py +0 -34
- edsl/study/ObjectEntry.py +0 -173
- edsl/study/ProofOfWork.py +0 -113
- edsl/study/SnapShot.py +0 -80
- edsl/study/Study.py +0 -520
- edsl/study/__init__.py +0 -6
- edsl/utilities/interface.py +0 -135
- edsl-0.1.48.dist-info/RECORD +0 -347
- {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/LICENSE +0 -0
- {edsl-0.1.48.dist-info → edsl-0.1.50.dist-info}/WHEEL +0 -0
edsl/__init__.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import os
|
2
2
|
import time
|
3
|
+
import importlib
|
4
|
+
import pkgutil
|
3
5
|
|
4
6
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
5
7
|
ROOT_DIR = os.path.dirname(BASE_DIR)
|
@@ -7,57 +9,126 @@ ROOT_DIR = os.path.dirname(BASE_DIR)
|
|
7
9
|
from edsl.__version__ import __version__
|
8
10
|
from edsl.config import Config, CONFIG
|
9
11
|
|
10
|
-
|
12
|
+
# Initialize and expose logger
|
13
|
+
from edsl import logger
|
14
|
+
|
15
|
+
# Set up logger with configuration from environment/config
|
16
|
+
# (We'll configure the logger after CONFIG is initialized below)
|
17
|
+
|
18
|
+
__all__ = ['logger']
|
19
|
+
|
20
|
+
# Define modules to import
|
21
|
+
modules_to_import = [
|
22
|
+
'dataset',
|
23
|
+
'agents',
|
24
|
+
'surveys',
|
25
|
+
'questions',
|
26
|
+
'scenarios',
|
27
|
+
'language_models',
|
28
|
+
'results',
|
29
|
+
'caching',
|
30
|
+
'notebooks',
|
31
|
+
'coop',
|
32
|
+
'instructions',
|
33
|
+
'jobs'
|
34
|
+
]
|
35
|
+
|
36
|
+
# Dynamically import modules and extend __all__
|
37
|
+
for module_name in modules_to_import:
|
38
|
+
try:
|
39
|
+
# Import the module
|
40
|
+
module = importlib.import_module(f'.{module_name}', package='edsl')
|
41
|
+
|
42
|
+
# Get the module's __all__ attribute
|
43
|
+
module_all = getattr(module, '__all__', [])
|
44
|
+
|
45
|
+
# Import all names from the module
|
46
|
+
exec(f"from .{module_name} import *")
|
47
|
+
|
48
|
+
# Extend __all__ with the module's __all__
|
49
|
+
if module_all:
|
50
|
+
logger.debug(f"Adding {len(module_all)} items from {module_name} to __all__")
|
51
|
+
__all__.extend(module_all)
|
52
|
+
else:
|
53
|
+
logger.warning(f"Module {module_name} does not have __all__ defined")
|
54
|
+
except ImportError as e:
|
55
|
+
logger.warning(f"Failed to import module {module_name}: {e}")
|
56
|
+
except Exception as e:
|
57
|
+
logger.warning(f"Error importing from module {module_name}: {e}")
|
58
|
+
|
59
|
+
|
60
|
+
# Load plugins
|
61
|
+
try:
|
62
|
+
from edsl.load_plugins import load_plugins
|
63
|
+
from edsl.plugins import get_plugin_manager, get_exports
|
64
|
+
|
65
|
+
# Load all plugins
|
66
|
+
plugins = load_plugins()
|
67
|
+
logger.info(f"Loaded {len(plugins)} plugins")
|
68
|
+
|
69
|
+
# Add plugins to globals and __all__
|
70
|
+
for plugin_name, plugin in plugins.items():
|
71
|
+
globals()[plugin_name] = plugin
|
72
|
+
__all__.append(plugin_name)
|
73
|
+
logger.info(f"Registered plugin {plugin_name} in global namespace")
|
74
|
+
|
75
|
+
# Get exports from plugins and add them to globals
|
76
|
+
exports = get_exports()
|
77
|
+
logger.info(f"Found {len(exports)} exported objects from plugins")
|
78
|
+
|
79
|
+
for name, obj in exports.items():
|
80
|
+
globals()[name] = obj
|
81
|
+
__all__.append(name)
|
82
|
+
logger.info(f"Added plugin export: {name}")
|
83
|
+
|
84
|
+
# Add placeholders for expected exports that are missing
|
85
|
+
# This maintains backward compatibility for common plugins
|
86
|
+
PLUGIN_PLACEHOLDERS = {
|
87
|
+
# No placeholders - removed Conjure for cleaner namespace
|
88
|
+
}
|
89
|
+
|
90
|
+
for placeholder_name, github_url in PLUGIN_PLACEHOLDERS.items():
|
91
|
+
if placeholder_name not in globals():
|
92
|
+
# Create a placeholder class
|
93
|
+
placeholder_class = type(placeholder_name, (), {
|
94
|
+
"__getattr__": lambda self, name: self._not_installed(name),
|
95
|
+
"_not_installed": lambda self, name: self._raise_import_error(),
|
96
|
+
"_raise_import_error": lambda self: exec(f"""
|
97
|
+
msg = (
|
98
|
+
"The {placeholder_name} plugin is not installed. "
|
99
|
+
"To use {placeholder_name} with EDSL, install it using:\\n"
|
100
|
+
" from edsl.plugins import install_from_github\\n"
|
101
|
+
" install_from_github('{github_url}')\\n"
|
102
|
+
"\\nOr from the command line:\\n"
|
103
|
+
" edsl plugins install {github_url}"
|
104
|
+
)
|
105
|
+
logger.warning(msg)
|
106
|
+
raise ImportError(msg)
|
107
|
+
""")
|
108
|
+
})
|
109
|
+
|
110
|
+
# Register the placeholder
|
111
|
+
globals()[placeholder_name] = placeholder_class()
|
112
|
+
__all__.append(placeholder_name)
|
113
|
+
logger.info(f"Added placeholder for {placeholder_name} with installation instructions")
|
114
|
+
|
115
|
+
except ImportError as e:
|
116
|
+
# Modules not available
|
117
|
+
logger.info("Plugin system not available, skipping plugin loading: %s", e)
|
118
|
+
logger.debug("Plugin system not available, skipping plugin loading: %s", e)
|
119
|
+
except Exception as e:
|
120
|
+
# Error loading plugins
|
121
|
+
logger.error("Error loading plugins: %s", e)
|
122
|
+
logger.debug("Error loading plugins: %s", e)
|
123
|
+
|
124
|
+
# Now that all modules are loaded, configure logging from the config
|
125
|
+
logger.configure_from_config()
|
126
|
+
|
127
|
+
|
128
|
+
# Installs a custom exception handling routine for edsl exceptions
|
129
|
+
from .base.base_exception import BaseException
|
130
|
+
BaseException.install_exception_hook()
|
131
|
+
|
132
|
+
# Log the total number of items in __all__ for debugging
|
133
|
+
logger.debug(f"EDSL initialization complete with {len(__all__)} items in __all__")
|
11
134
|
|
12
|
-
from .dataset import __all__ as dataset_all
|
13
|
-
from .dataset import *
|
14
|
-
__all__.extend(dataset_all)
|
15
|
-
|
16
|
-
from .agents import __all__ as agents_all
|
17
|
-
from .agents import *
|
18
|
-
__all__.extend(agents_all)
|
19
|
-
|
20
|
-
from .surveys import __all__ as surveys_all
|
21
|
-
from .surveys import *
|
22
|
-
__all__.extend(surveys_all)
|
23
|
-
|
24
|
-
# Questions
|
25
|
-
from .questions import __all__ as questions_all
|
26
|
-
from .questions import *
|
27
|
-
__all__.extend(questions_all)
|
28
|
-
|
29
|
-
from .scenarios import __all__ as scenarios_all
|
30
|
-
from .scenarios import *
|
31
|
-
__all__.extend(scenarios_all)
|
32
|
-
|
33
|
-
from .language_models import __all__ as language_models_all
|
34
|
-
from .language_models import *
|
35
|
-
__all__.extend(language_models_all)
|
36
|
-
|
37
|
-
from .results import __all__ as results_all
|
38
|
-
from .results import *
|
39
|
-
__all__.extend(results_all)
|
40
|
-
|
41
|
-
from .caching import __all__ as caching_all
|
42
|
-
from .caching import *
|
43
|
-
__all__.extend(caching_all)
|
44
|
-
|
45
|
-
from .notebooks import __all__ as notebooks_all
|
46
|
-
from .notebooks import *
|
47
|
-
__all__.extend(notebooks_all)
|
48
|
-
|
49
|
-
from .coop import __all__ as coop_all
|
50
|
-
from .coop import *
|
51
|
-
__all__.extend(coop_all)
|
52
|
-
|
53
|
-
from .instructions import __all__ as instructions_all
|
54
|
-
from .instructions import *
|
55
|
-
__all__.extend(instructions_all)
|
56
|
-
|
57
|
-
from .jobs import __all__ as jobs_all
|
58
|
-
from .jobs import *
|
59
|
-
__all__.extend(jobs_all)
|
60
|
-
|
61
|
-
from .study import __all__ as study_all
|
62
|
-
from .study import *
|
63
|
-
__all__.extend(study_all)
|
edsl/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.1.
|
1
|
+
__version__ = "0.1.50"
|
edsl/agents/agent.py
CHANGED
@@ -47,7 +47,6 @@ import types
|
|
47
47
|
import warnings
|
48
48
|
from uuid import uuid4
|
49
49
|
from contextlib import contextmanager
|
50
|
-
|
51
50
|
from typing import (
|
52
51
|
Callable,
|
53
52
|
Optional,
|
@@ -57,11 +56,9 @@ from typing import (
|
|
57
56
|
Protocol,
|
58
57
|
runtime_checkable,
|
59
58
|
TypeVar,
|
59
|
+
Type,
|
60
60
|
)
|
61
61
|
|
62
|
-
# Type variable for the Agent class
|
63
|
-
A = TypeVar("A", bound="Agent")
|
64
|
-
|
65
62
|
if TYPE_CHECKING:
|
66
63
|
from ..caching import Cache
|
67
64
|
from ..surveys import Survey
|
@@ -71,17 +68,8 @@ if TYPE_CHECKING:
|
|
71
68
|
from ..questions import QuestionBase
|
72
69
|
from ..invigilators import InvigilatorBase
|
73
70
|
from ..prompts import Prompt
|
74
|
-
from ..questions import QuestionBase
|
75
71
|
from ..key_management import KeyLookup
|
76
72
|
|
77
|
-
|
78
|
-
@runtime_checkable
|
79
|
-
class DirectAnswerMethod(Protocol):
|
80
|
-
"""Protocol defining the required signature for direct answer methods."""
|
81
|
-
|
82
|
-
def __call__(self, self_: A, question: QuestionBase, scenario: Scenario) -> Any: ...
|
83
|
-
|
84
|
-
|
85
73
|
from ..base import Base
|
86
74
|
from ..scenarios import Scenario
|
87
75
|
from ..questions import QuestionScenarioRenderError
|
@@ -93,7 +81,6 @@ from ..utilities import (
|
|
93
81
|
remove_edsl_version,
|
94
82
|
)
|
95
83
|
|
96
|
-
|
97
84
|
from .exceptions import (
|
98
85
|
AgentErrors,
|
99
86
|
AgentCombinationError,
|
@@ -108,6 +95,16 @@ from .descriptors import (
|
|
108
95
|
NameDescriptor,
|
109
96
|
)
|
110
97
|
|
98
|
+
# Type variable for the Agent class
|
99
|
+
A = TypeVar("A", bound="Agent")
|
100
|
+
|
101
|
+
|
102
|
+
@runtime_checkable
|
103
|
+
class DirectAnswerMethod(Protocol):
|
104
|
+
"""Protocol defining the required signature for direct answer methods."""
|
105
|
+
|
106
|
+
def __call__(self, self_: A, question: QuestionBase, scenario: Scenario) -> Any: ...
|
107
|
+
|
111
108
|
|
112
109
|
class AgentTraits(Scenario):
|
113
110
|
"""A class representing the traits of an agent.
|
@@ -472,9 +469,10 @@ class Agent(Base):
|
|
472
469
|
# Transfer direct answering method if present
|
473
470
|
if hasattr(self, "answer_question_directly"):
|
474
471
|
answer_question_directly = self.answer_question_directly
|
475
|
-
newf
|
476
|
-
|
477
|
-
|
472
|
+
def newf(self, question, scenario):
|
473
|
+
return answer_question_directly(
|
474
|
+
question, scenario
|
475
|
+
)
|
478
476
|
new_agent.add_direct_question_answering_method(newf)
|
479
477
|
|
480
478
|
# Transfer dynamic traits function if present
|
@@ -940,7 +938,7 @@ class Agent(Base):
|
|
940
938
|
|
941
939
|
answer_question = sync_wrapper(async_answer_question)
|
942
940
|
|
943
|
-
def _get_invigilator_class(self, question: QuestionBase) -> Type[InvigilatorBase]:
|
941
|
+
def _get_invigilator_class(self, question: "QuestionBase") -> Type["InvigilatorBase"]:
|
944
942
|
"""Get the invigilator class for a question.
|
945
943
|
|
946
944
|
This method returns the invigilator class that should be used to answer a question.
|
@@ -1098,6 +1096,8 @@ class Agent(Base):
|
|
1098
1096
|
if name in self._traits:
|
1099
1097
|
return self._traits[name]
|
1100
1098
|
|
1099
|
+
# Keep using AttributeError instead of our custom exception to maintain compatibility
|
1100
|
+
# with Python's attribute access mechanism
|
1101
1101
|
raise AttributeError(
|
1102
1102
|
f"'{type(self).__name__}' object has no attribute '{name}'"
|
1103
1103
|
)
|
@@ -1142,7 +1142,7 @@ class Agent(Base):
|
|
1142
1142
|
raw_data.pop("instruction")
|
1143
1143
|
if self.codebook == {}:
|
1144
1144
|
raw_data.pop("codebook")
|
1145
|
-
if self.name
|
1145
|
+
if self.name is None:
|
1146
1146
|
raw_data.pop("name")
|
1147
1147
|
|
1148
1148
|
if hasattr(self, "dynamic_traits_function"):
|
@@ -1164,7 +1164,7 @@ class Agent(Base):
|
|
1164
1164
|
|
1165
1165
|
if (
|
1166
1166
|
answer_question_directly_func
|
1167
|
-
and raw_data.get("answer_question_directly_source_code", None)
|
1167
|
+
and raw_data.get("answer_question_directly_source_code", None) is not None
|
1168
1168
|
):
|
1169
1169
|
raw_data["answer_question_directly_source_code"] = inspect.getsource(
|
1170
1170
|
answer_question_directly_func
|
@@ -1352,7 +1352,7 @@ def main():
|
|
1352
1352
|
question_name="food_preference",
|
1353
1353
|
)
|
1354
1354
|
job = question.by(agent)
|
1355
|
-
|
1355
|
+
job.run() # results not used
|
1356
1356
|
|
1357
1357
|
|
1358
1358
|
if __name__ == "__main__":
|
edsl/agents/agent_list.py
CHANGED
@@ -27,10 +27,7 @@ from .exceptions import AgentListError
|
|
27
27
|
logger = logging.getLogger(__name__)
|
28
28
|
|
29
29
|
if TYPE_CHECKING:
|
30
|
-
from ..scenarios import ScenarioList
|
31
30
|
from ..agents import Agent
|
32
|
-
from pandas import DataFrame
|
33
|
-
from ..dataset import Dataset
|
34
31
|
|
35
32
|
|
36
33
|
def is_iterable(obj):
|
@@ -212,7 +209,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
|
|
212
209
|
new_data = [
|
213
210
|
agent for agent in self.data if create_evaluator(agent).eval(expression)
|
214
211
|
]
|
215
|
-
except NameNotDefined
|
212
|
+
except NameNotDefined:
|
216
213
|
e = AgentListError(f"'{expression}' is not a valid expression.")
|
217
214
|
if is_notebook():
|
218
215
|
print(e, file=sys.stderr)
|
@@ -451,7 +448,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
|
|
451
448
|
*fields,
|
452
449
|
tablefmt: Optional[str] = None,
|
453
450
|
pretty_labels: Optional[dict] = None,
|
454
|
-
) ->
|
451
|
+
) -> Any:
|
455
452
|
if len(self) == 0:
|
456
453
|
e = AgentListError("Cannot create a table from an empty AgentList.")
|
457
454
|
if is_notebook():
|
edsl/agents/exceptions.py
CHANGED
@@ -1,18 +1,52 @@
|
|
1
|
-
import sys
|
2
1
|
|
3
|
-
from ..
|
4
|
-
from ..utilities.is_notebook import is_notebook
|
2
|
+
from ..base.base_exception import BaseException
|
5
3
|
|
6
4
|
|
7
5
|
class AgentListError(BaseException):
|
6
|
+
"""
|
7
|
+
Exception raised when an AgentList operation fails.
|
8
|
+
|
9
|
+
This exception is raised in the following cases:
|
10
|
+
- When an invalid expression is provided in the filter() method
|
11
|
+
- When trying to add traits with mismatched lengths
|
12
|
+
- When attempting to create a table from an empty AgentList
|
13
|
+
|
14
|
+
Examples:
|
15
|
+
```python
|
16
|
+
agents.filter("invalid expression") # Raises AgentListError
|
17
|
+
agents.add_trait(name="scores", values=[1, 2]) # Raises AgentListError if agents list has different length
|
18
|
+
```
|
19
|
+
"""
|
8
20
|
relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-lists"
|
9
21
|
|
10
22
|
|
11
23
|
class AgentErrors(BaseException):
|
24
|
+
"""
|
25
|
+
Base exception class for all agent-related errors.
|
26
|
+
|
27
|
+
This class is the parent of all agent-specific exceptions and may also be raised directly
|
28
|
+
when modifying agent traits or during operations like renaming or adding traits.
|
29
|
+
"""
|
12
30
|
relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html"
|
13
31
|
|
14
32
|
|
15
33
|
class AgentDynamicTraitsFunctionError(AgentErrors):
|
34
|
+
"""
|
35
|
+
Exception raised when there's an issue with the dynamic traits function.
|
36
|
+
|
37
|
+
This exception occurs when:
|
38
|
+
- The dynamic traits function has too many parameters
|
39
|
+
- The dynamic traits function has parameters other than 'question'
|
40
|
+
|
41
|
+
This error typically indicates that your dynamic traits function has an incorrect signature.
|
42
|
+
The function should accept only one parameter named 'question'.
|
43
|
+
|
44
|
+
Examples:
|
45
|
+
```python
|
46
|
+
def wrong_func(question, extra_param): # Will raise AgentDynamicTraitsFunctionError
|
47
|
+
return {"trait": "value"}
|
48
|
+
```
|
49
|
+
"""
|
16
50
|
relevant_doc = (
|
17
51
|
"https://docs.expectedparrot.com/en/latest/agents.html#dynamic-traits-function"
|
18
52
|
)
|
@@ -20,26 +54,106 @@ class AgentDynamicTraitsFunctionError(AgentErrors):
|
|
20
54
|
|
21
55
|
|
22
56
|
class AgentDirectAnswerFunctionError(AgentErrors):
|
57
|
+
"""
|
58
|
+
Exception raised when there's an issue with the direct answer method.
|
59
|
+
|
60
|
+
This exception occurs when the direct answer method doesn't have the required parameters.
|
61
|
+
The method must include 'question', 'scenario', and/or 'self' parameters.
|
62
|
+
|
63
|
+
Examples:
|
64
|
+
```python
|
65
|
+
def wrong_answer_func(wrong_param): # Will raise AgentDirectAnswerFunctionError
|
66
|
+
return "Answer"
|
67
|
+
```
|
68
|
+
"""
|
23
69
|
relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-direct-answering-methods"
|
24
70
|
|
25
71
|
|
26
72
|
class AgentCombinationError(AgentErrors):
|
73
|
+
"""
|
74
|
+
Exception raised when attempting to combine agents with overlapping traits.
|
75
|
+
|
76
|
+
This exception occurs when you try to combine agents that have the same trait names,
|
77
|
+
which would result in ambiguous trait values in the combined agent.
|
78
|
+
|
79
|
+
To fix this, ensure that the agents being combined have unique trait names,
|
80
|
+
or rename the conflicting traits before combination.
|
81
|
+
|
82
|
+
Examples:
|
83
|
+
```python
|
84
|
+
agent1 = Agent(name="A1", age=30)
|
85
|
+
agent2 = Agent(name="A2", age=40)
|
86
|
+
agent1 + agent2 # Raises AgentCombinationError due to duplicate 'age' trait
|
87
|
+
```
|
88
|
+
"""
|
27
89
|
relevant_doc = (
|
28
90
|
"https://docs.expectedparrot.com/en/latest/agents.html#combining-agents"
|
29
91
|
)
|
30
92
|
|
31
93
|
|
32
94
|
class AgentNameError(AgentErrors):
|
95
|
+
"""
|
96
|
+
Exception raised when there's an issue with an agent's name.
|
97
|
+
|
98
|
+
This exception occurs when a trait key conflicts with the 'name' parameter,
|
99
|
+
as 'name' is a special attribute for agents and cannot be used as a trait name.
|
100
|
+
|
101
|
+
Examples:
|
102
|
+
```python
|
103
|
+
Agent(name="John", name="John") # Raises AgentNameError
|
104
|
+
agent.add_trait(name="name", value="NewName") # Raises AgentNameError
|
105
|
+
```
|
106
|
+
"""
|
33
107
|
relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-names"
|
34
108
|
|
35
109
|
|
36
110
|
class AgentTraitKeyError(AgentErrors):
|
111
|
+
"""
|
112
|
+
Exception raised when an invalid trait key is used.
|
113
|
+
|
114
|
+
This exception occurs when a trait key is not a valid Python identifier.
|
115
|
+
Trait keys must follow Python variable naming rules (no spaces, no special characters
|
116
|
+
except underscore, cannot start with a number).
|
117
|
+
|
118
|
+
Examples:
|
119
|
+
```python
|
120
|
+
Agent(name="John", "invalid-key"=30) # Raises AgentTraitKeyError
|
121
|
+
agent.add_trait(name="2invalid", value="value") # Raises AgentTraitKeyError
|
122
|
+
```
|
123
|
+
"""
|
37
124
|
relevant_doc = (
|
38
125
|
"https://docs.expectedparrot.com/en/latest/agents.html#constructing-an-agent"
|
39
126
|
)
|
40
127
|
|
41
128
|
|
42
|
-
class
|
43
|
-
|
129
|
+
class AgentAttributeError(AgentErrors):
|
130
|
+
"""
|
131
|
+
Exception raised when accessing a non-existent attribute of an agent.
|
132
|
+
|
133
|
+
This exception occurs when trying to access a trait or attribute that
|
134
|
+
doesn't exist on the agent.
|
135
|
+
|
136
|
+
Examples:
|
137
|
+
```python
|
138
|
+
agent = Agent(name="John", age=30)
|
139
|
+
agent.height # Raises AgentAttributeError as 'height' doesn't exist
|
140
|
+
```
|
141
|
+
"""
|
142
|
+
relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-traits"
|
143
|
+
|
144
|
+
def __init__(self, message):
|
44
145
|
super().__init__(message)
|
146
|
+
|
147
|
+
|
148
|
+
class FailedTaskException(BaseException):
|
149
|
+
"""
|
150
|
+
Exception raised when an agent task execution fails.
|
151
|
+
|
152
|
+
This exception is used to track agent execution failures and retain information
|
153
|
+
about the agent's response when the failure occurred.
|
154
|
+
|
155
|
+
Note: This exception class is currently not used in the codebase.
|
156
|
+
"""
|
157
|
+
def __init__(self, message, agent_response_dict):
|
158
|
+
super().__init__(f"Agent task failed: {message}")
|
45
159
|
self.agent_response_dict = agent_response_dict
|
edsl/base/__init__.py
CHANGED
@@ -7,7 +7,6 @@ from edsl.base.base_class import (
|
|
7
7
|
Base,
|
8
8
|
BaseDiff,
|
9
9
|
BaseDiffCollection,
|
10
|
-
BaseException,
|
11
10
|
DiffMethodsMixin,
|
12
11
|
DisplayJSON,
|
13
12
|
DisplayYAML,
|
@@ -18,6 +17,15 @@ from edsl.base.base_class import (
|
|
18
17
|
RepresentationMixin,
|
19
18
|
is_iterable,
|
20
19
|
)
|
20
|
+
from edsl.base.base_exception import BaseException
|
21
|
+
from edsl.base.exceptions import (
|
22
|
+
BaseValueError,
|
23
|
+
BaseNotImplementedError,
|
24
|
+
BaseKeyError,
|
25
|
+
BaseFileError,
|
26
|
+
BaseTypeError
|
27
|
+
)
|
28
|
+
|
21
29
|
from edsl.base.enums import (
|
22
30
|
EnumWithChecks,
|
23
31
|
InferenceServiceLiteral,
|
@@ -39,37 +47,4 @@ from edsl.base.data_transfer_models import (
|
|
39
47
|
ModelResponse,
|
40
48
|
)
|
41
49
|
|
42
|
-
__all__ = [
|
43
|
-
# From base_class
|
44
|
-
"Base",
|
45
|
-
"BaseDiff",
|
46
|
-
"BaseDiffCollection",
|
47
|
-
"BaseException",
|
48
|
-
"DiffMethodsMixin",
|
49
|
-
"DisplayJSON",
|
50
|
-
"DisplayYAML",
|
51
|
-
"DummyObject",
|
52
|
-
"HashingMixin",
|
53
|
-
"PersistenceMixin",
|
54
|
-
"RegisterSubclassesMeta",
|
55
|
-
"RepresentationMixin",
|
56
|
-
"is_iterable",
|
57
|
-
# From enums
|
58
|
-
"EnumWithChecks",
|
59
|
-
"InferenceServiceLiteral",
|
60
|
-
"InferenceServiceType",
|
61
|
-
"QuestionType",
|
62
|
-
"TokenPricing",
|
63
|
-
"available_models_urls",
|
64
|
-
"get_token_pricing",
|
65
|
-
"pricing",
|
66
|
-
"service_to_api_keyname",
|
67
|
-
# From data_transfer_models
|
68
|
-
"AgentResponseDict",
|
69
|
-
"Answers",
|
70
|
-
"EDSLOutput",
|
71
|
-
"EDSLResultObjectInput",
|
72
|
-
"ImageInfo",
|
73
|
-
"ModelInputs",
|
74
|
-
"ModelResponse",
|
75
|
-
]
|
50
|
+
__all__ = []
|