edsl 0.1.47__py3-none-any.whl → 0.1.49__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 +44 -39
- edsl/__version__.py +1 -1
- edsl/agents/__init__.py +4 -2
- edsl/agents/{Agent.py → agent.py} +442 -152
- edsl/agents/{AgentList.py → agent_list.py} +220 -162
- edsl/agents/descriptors.py +46 -7
- edsl/{exceptions/agents.py → agents/exceptions.py} +3 -12
- edsl/base/__init__.py +75 -0
- edsl/base/base_class.py +1303 -0
- edsl/base/data_transfer_models.py +114 -0
- edsl/base/enums.py +215 -0
- edsl/base.py +8 -0
- edsl/buckets/__init__.py +25 -0
- edsl/buckets/bucket_collection.py +324 -0
- edsl/buckets/model_buckets.py +206 -0
- edsl/buckets/token_bucket.py +502 -0
- edsl/{jobs/buckets/TokenBucketAPI.py → buckets/token_bucket_api.py} +1 -1
- edsl/buckets/token_bucket_client.py +509 -0
- edsl/caching/__init__.py +20 -0
- edsl/caching/cache.py +814 -0
- edsl/caching/cache_entry.py +427 -0
- edsl/{data/CacheHandler.py → caching/cache_handler.py} +14 -15
- edsl/caching/exceptions.py +24 -0
- edsl/caching/orm.py +30 -0
- edsl/{data/RemoteCacheSync.py → caching/remote_cache_sync.py} +3 -3
- edsl/caching/sql_dict.py +441 -0
- edsl/config/__init__.py +8 -0
- edsl/config/config_class.py +177 -0
- edsl/config.py +4 -176
- edsl/conversation/Conversation.py +7 -7
- edsl/conversation/car_buying.py +4 -4
- edsl/conversation/chips.py +6 -6
- edsl/coop/__init__.py +25 -2
- edsl/coop/coop.py +311 -75
- edsl/coop/{ExpectedParrotKeyHandler.py → ep_key_handling.py} +86 -10
- edsl/coop/exceptions.py +62 -0
- edsl/coop/price_fetcher.py +126 -0
- edsl/coop/utils.py +89 -24
- edsl/data_transfer_models.py +5 -72
- edsl/dataset/__init__.py +10 -0
- edsl/{results/Dataset.py → dataset/dataset.py} +116 -36
- edsl/{results/DatasetExportMixin.py → dataset/dataset_operations_mixin.py} +606 -122
- edsl/{results/DatasetTree.py → dataset/dataset_tree.py} +156 -75
- edsl/{results/TableDisplay.py → dataset/display/table_display.py} +18 -7
- edsl/{results → dataset/display}/table_renderers.py +58 -2
- edsl/{results → dataset}/file_exports.py +4 -5
- edsl/{results → dataset}/smart_objects.py +2 -2
- edsl/enums.py +5 -205
- edsl/inference_services/__init__.py +5 -0
- edsl/inference_services/{AvailableModelCacheHandler.py → available_model_cache_handler.py} +2 -3
- edsl/inference_services/{AvailableModelFetcher.py → available_model_fetcher.py} +8 -14
- edsl/inference_services/data_structures.py +3 -2
- edsl/{exceptions/inference_services.py → inference_services/exceptions.py} +1 -1
- edsl/inference_services/{InferenceServiceABC.py → inference_service_abc.py} +1 -1
- edsl/inference_services/{InferenceServicesCollection.py → inference_services_collection.py} +8 -7
- edsl/inference_services/registry.py +4 -41
- edsl/inference_services/{ServiceAvailability.py → service_availability.py} +5 -25
- edsl/inference_services/services/__init__.py +31 -0
- edsl/inference_services/{AnthropicService.py → services/anthropic_service.py} +3 -3
- edsl/inference_services/{AwsBedrock.py → services/aws_bedrock.py} +2 -2
- edsl/inference_services/{AzureAI.py → services/azure_ai.py} +2 -2
- edsl/inference_services/{DeepInfraService.py → services/deep_infra_service.py} +1 -3
- edsl/inference_services/{DeepSeekService.py → services/deep_seek_service.py} +2 -4
- edsl/inference_services/{GoogleService.py → services/google_service.py} +5 -4
- edsl/inference_services/{GroqService.py → services/groq_service.py} +1 -1
- edsl/inference_services/{MistralAIService.py → services/mistral_ai_service.py} +3 -3
- edsl/inference_services/{OllamaService.py → services/ollama_service.py} +1 -7
- edsl/inference_services/{OpenAIService.py → services/open_ai_service.py} +5 -6
- edsl/inference_services/{PerplexityService.py → services/perplexity_service.py} +3 -7
- edsl/inference_services/{TestService.py → services/test_service.py} +7 -6
- edsl/inference_services/{TogetherAIService.py → services/together_ai_service.py} +2 -6
- edsl/inference_services/{XAIService.py → services/xai_service.py} +1 -1
- edsl/inference_services/write_available.py +1 -2
- edsl/instructions/__init__.py +6 -0
- edsl/{surveys/instructions/Instruction.py → instructions/instruction.py} +11 -6
- edsl/{surveys/instructions/InstructionCollection.py → instructions/instruction_collection.py} +10 -5
- edsl/{surveys/InstructionHandler.py → instructions/instruction_handler.py} +3 -3
- edsl/{jobs/interviews → interviews}/ReportErrors.py +2 -2
- edsl/interviews/__init__.py +4 -0
- edsl/{jobs/AnswerQuestionFunctionConstructor.py → interviews/answering_function.py} +45 -18
- edsl/{jobs/interviews/InterviewExceptionEntry.py → interviews/exception_tracking.py} +107 -22
- edsl/interviews/interview.py +638 -0
- edsl/{jobs/interviews/InterviewStatusDictionary.py → interviews/interview_status_dictionary.py} +21 -12
- edsl/{jobs/interviews/InterviewStatusLog.py → interviews/interview_status_log.py} +16 -7
- edsl/{jobs/InterviewTaskManager.py → interviews/interview_task_manager.py} +12 -7
- edsl/{jobs/RequestTokenEstimator.py → interviews/request_token_estimator.py} +8 -3
- edsl/{jobs/interviews/InterviewStatistic.py → interviews/statistics.py} +36 -10
- edsl/invigilators/__init__.py +38 -0
- edsl/invigilators/invigilator_base.py +477 -0
- edsl/{agents/Invigilator.py → invigilators/invigilators.py} +263 -10
- edsl/invigilators/prompt_constructor.py +476 -0
- edsl/{agents → invigilators}/prompt_helpers.py +2 -1
- edsl/{agents/QuestionInstructionPromptBuilder.py → invigilators/question_instructions_prompt_builder.py} +18 -13
- edsl/{agents → invigilators}/question_option_processor.py +96 -21
- edsl/{agents/QuestionTemplateReplacementsBuilder.py → invigilators/question_template_replacements_builder.py} +64 -12
- edsl/jobs/__init__.py +7 -1
- edsl/jobs/async_interview_runner.py +99 -35
- edsl/jobs/check_survey_scenario_compatibility.py +7 -5
- edsl/jobs/data_structures.py +153 -22
- edsl/{exceptions/jobs.py → jobs/exceptions.py} +2 -1
- edsl/jobs/{FetchInvigilator.py → fetch_invigilator.py} +4 -4
- edsl/jobs/{loggers/HTMLTableJobLogger.py → html_table_job_logger.py} +6 -2
- edsl/jobs/{Jobs.py → jobs.py} +313 -167
- edsl/jobs/{JobsChecks.py → jobs_checks.py} +15 -7
- edsl/jobs/{JobsComponentConstructor.py → jobs_component_constructor.py} +19 -17
- edsl/jobs/{InterviewsConstructor.py → jobs_interview_constructor.py} +10 -5
- edsl/jobs/jobs_pricing_estimation.py +347 -0
- edsl/jobs/{JobsRemoteInferenceLogger.py → jobs_remote_inference_logger.py} +4 -3
- edsl/jobs/jobs_runner_asyncio.py +282 -0
- edsl/jobs/{JobsRemoteInferenceHandler.py → remote_inference.py} +19 -22
- edsl/jobs/results_exceptions_handler.py +2 -2
- edsl/key_management/__init__.py +28 -0
- edsl/key_management/key_lookup.py +161 -0
- edsl/{language_models/key_management/KeyLookupBuilder.py → key_management/key_lookup_builder.py} +118 -47
- edsl/key_management/key_lookup_collection.py +82 -0
- edsl/key_management/models.py +218 -0
- edsl/language_models/__init__.py +7 -2
- edsl/language_models/{ComputeCost.py → compute_cost.py} +18 -3
- edsl/{exceptions/language_models.py → language_models/exceptions.py} +2 -1
- edsl/language_models/language_model.py +1080 -0
- edsl/language_models/model.py +10 -25
- edsl/language_models/{ModelList.py → model_list.py} +9 -14
- edsl/language_models/{RawResponseHandler.py → raw_response_handler.py} +1 -1
- edsl/language_models/{RegisterLanguageModelsMeta.py → registry.py} +1 -1
- edsl/language_models/repair.py +4 -4
- edsl/language_models/utilities.py +4 -4
- edsl/notebooks/__init__.py +3 -1
- edsl/notebooks/{Notebook.py → notebook.py} +7 -8
- edsl/prompts/__init__.py +1 -1
- edsl/{exceptions/prompts.py → prompts/exceptions.py} +3 -1
- edsl/prompts/{Prompt.py → prompt.py} +101 -95
- edsl/questions/HTMLQuestion.py +1 -1
- edsl/questions/__init__.py +154 -25
- edsl/questions/answer_validator_mixin.py +1 -1
- edsl/questions/compose_questions.py +4 -3
- edsl/questions/derived/question_likert_five.py +166 -0
- edsl/questions/derived/{QuestionLinearScale.py → question_linear_scale.py} +4 -4
- edsl/questions/derived/{QuestionTopK.py → question_top_k.py} +4 -4
- edsl/questions/derived/{QuestionYesNo.py → question_yes_no.py} +4 -5
- edsl/questions/descriptors.py +24 -30
- edsl/questions/loop_processor.py +65 -19
- edsl/questions/question_base.py +881 -0
- edsl/questions/question_base_gen_mixin.py +15 -16
- edsl/questions/{QuestionBasePromptsMixin.py → question_base_prompts_mixin.py} +2 -2
- edsl/questions/{QuestionBudget.py → question_budget.py} +3 -4
- edsl/questions/{QuestionCheckBox.py → question_check_box.py} +16 -16
- edsl/questions/{QuestionDict.py → question_dict.py} +39 -5
- edsl/questions/{QuestionExtract.py → question_extract.py} +9 -9
- edsl/questions/question_free_text.py +282 -0
- edsl/questions/{QuestionFunctional.py → question_functional.py} +6 -5
- edsl/questions/{QuestionList.py → question_list.py} +6 -7
- edsl/questions/{QuestionMatrix.py → question_matrix.py} +6 -5
- edsl/questions/{QuestionMultipleChoice.py → question_multiple_choice.py} +126 -21
- edsl/questions/{QuestionNumerical.py → question_numerical.py} +5 -5
- edsl/questions/{QuestionRank.py → question_rank.py} +6 -6
- edsl/questions/question_registry.py +4 -9
- edsl/questions/register_questions_meta.py +8 -4
- edsl/questions/response_validator_abc.py +17 -16
- edsl/results/__init__.py +4 -1
- edsl/{exceptions/results.py → results/exceptions.py} +1 -1
- edsl/results/report.py +197 -0
- edsl/results/{Result.py → result.py} +131 -45
- edsl/results/{Results.py → results.py} +365 -220
- edsl/results/results_selector.py +344 -25
- edsl/scenarios/__init__.py +30 -3
- edsl/scenarios/{ConstructDownloadLink.py → construct_download_link.py} +7 -0
- edsl/scenarios/directory_scanner.py +156 -13
- edsl/scenarios/document_chunker.py +186 -0
- edsl/scenarios/exceptions.py +101 -0
- edsl/scenarios/file_methods.py +2 -3
- edsl/scenarios/{FileStore.py → file_store.py} +275 -189
- edsl/scenarios/handlers/__init__.py +14 -14
- edsl/scenarios/handlers/{csv.py → csv_file_store.py} +1 -2
- edsl/scenarios/handlers/{docx.py → docx_file_store.py} +8 -7
- edsl/scenarios/handlers/{html.py → html_file_store.py} +1 -2
- edsl/scenarios/handlers/{jpeg.py → jpeg_file_store.py} +1 -1
- edsl/scenarios/handlers/{json.py → json_file_store.py} +1 -1
- edsl/scenarios/handlers/latex_file_store.py +5 -0
- edsl/scenarios/handlers/{md.py → md_file_store.py} +1 -1
- edsl/scenarios/handlers/{pdf.py → pdf_file_store.py} +2 -2
- edsl/scenarios/handlers/{png.py → png_file_store.py} +1 -1
- edsl/scenarios/handlers/{pptx.py → pptx_file_store.py} +8 -7
- edsl/scenarios/handlers/{py.py → py_file_store.py} +1 -3
- edsl/scenarios/handlers/{sql.py → sql_file_store.py} +2 -1
- edsl/scenarios/handlers/{sqlite.py → sqlite_file_store.py} +2 -3
- edsl/scenarios/handlers/{txt.py → txt_file_store.py} +1 -1
- edsl/scenarios/scenario.py +928 -0
- edsl/scenarios/scenario_join.py +18 -5
- edsl/scenarios/{ScenarioList.py → scenario_list.py} +294 -106
- edsl/scenarios/{ScenarioListPdfMixin.py → scenario_list_pdf_tools.py} +16 -15
- edsl/scenarios/scenario_selector.py +5 -1
- edsl/study/ObjectEntry.py +2 -2
- edsl/study/SnapShot.py +5 -5
- edsl/study/Study.py +18 -19
- edsl/study/__init__.py +6 -4
- edsl/surveys/__init__.py +7 -4
- edsl/surveys/dag/__init__.py +2 -0
- edsl/surveys/{ConstructDAG.py → dag/construct_dag.py} +3 -3
- edsl/surveys/{DAG.py → dag/dag.py} +13 -10
- edsl/surveys/descriptors.py +1 -1
- edsl/surveys/{EditSurvey.py → edit_survey.py} +9 -9
- edsl/{exceptions/surveys.py → surveys/exceptions.py} +1 -2
- edsl/surveys/memory/__init__.py +3 -0
- edsl/surveys/{MemoryPlan.py → memory/memory_plan.py} +10 -9
- edsl/surveys/rules/__init__.py +3 -0
- edsl/surveys/{Rule.py → rules/rule.py} +103 -43
- edsl/surveys/{RuleCollection.py → rules/rule_collection.py} +21 -30
- edsl/surveys/{RuleManager.py → rules/rule_manager.py} +19 -13
- edsl/surveys/survey.py +1743 -0
- edsl/surveys/{SurveyExportMixin.py → survey_export.py} +22 -27
- edsl/surveys/{SurveyFlowVisualization.py → survey_flow_visualization.py} +11 -2
- edsl/surveys/{Simulator.py → survey_simulator.py} +10 -3
- edsl/tasks/__init__.py +32 -0
- edsl/{jobs/tasks/QuestionTaskCreator.py → tasks/question_task_creator.py} +115 -57
- edsl/tasks/task_creators.py +135 -0
- edsl/{jobs/tasks/TaskHistory.py → tasks/task_history.py} +86 -47
- edsl/{jobs/tasks → tasks}/task_status_enum.py +91 -7
- edsl/tasks/task_status_log.py +85 -0
- edsl/tokens/__init__.py +2 -0
- edsl/tokens/interview_token_usage.py +53 -0
- edsl/utilities/PrettyList.py +1 -1
- edsl/utilities/SystemInfo.py +25 -22
- edsl/utilities/__init__.py +29 -21
- edsl/utilities/gcp_bucket/__init__.py +2 -0
- edsl/utilities/gcp_bucket/cloud_storage.py +99 -96
- edsl/utilities/interface.py +44 -536
- edsl/{results/MarkdownToPDF.py → utilities/markdown_to_pdf.py} +13 -5
- edsl/utilities/repair_functions.py +1 -1
- {edsl-0.1.47.dist-info → edsl-0.1.49.dist-info}/METADATA +1 -1
- edsl-0.1.49.dist-info/RECORD +347 -0
- edsl/Base.py +0 -493
- edsl/BaseDiff.py +0 -260
- edsl/agents/InvigilatorBase.py +0 -260
- edsl/agents/PromptConstructor.py +0 -318
- edsl/coop/PriceFetcher.py +0 -54
- edsl/data/Cache.py +0 -582
- edsl/data/CacheEntry.py +0 -238
- edsl/data/SQLiteDict.py +0 -292
- edsl/data/__init__.py +0 -5
- edsl/data/orm.py +0 -10
- edsl/exceptions/cache.py +0 -5
- edsl/exceptions/coop.py +0 -14
- edsl/exceptions/data.py +0 -14
- edsl/exceptions/scenarios.py +0 -29
- edsl/jobs/Answers.py +0 -43
- edsl/jobs/JobsPrompts.py +0 -354
- edsl/jobs/buckets/BucketCollection.py +0 -134
- edsl/jobs/buckets/ModelBuckets.py +0 -65
- edsl/jobs/buckets/TokenBucket.py +0 -283
- edsl/jobs/buckets/TokenBucketClient.py +0 -191
- edsl/jobs/interviews/Interview.py +0 -395
- edsl/jobs/interviews/InterviewExceptionCollection.py +0 -99
- edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -25
- edsl/jobs/runners/JobsRunnerAsyncio.py +0 -163
- edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
- edsl/jobs/tasks/TaskCreators.py +0 -64
- edsl/jobs/tasks/TaskStatusLog.py +0 -23
- edsl/jobs/tokens/InterviewTokenUsage.py +0 -27
- edsl/language_models/LanguageModel.py +0 -635
- edsl/language_models/ServiceDataSources.py +0 -0
- edsl/language_models/key_management/KeyLookup.py +0 -63
- edsl/language_models/key_management/KeyLookupCollection.py +0 -38
- edsl/language_models/key_management/models.py +0 -137
- edsl/questions/QuestionBase.py +0 -544
- edsl/questions/QuestionFreeText.py +0 -130
- edsl/questions/derived/QuestionLikertFive.py +0 -76
- edsl/results/ResultsExportMixin.py +0 -45
- edsl/results/TextEditor.py +0 -50
- edsl/results/results_fetch_mixin.py +0 -33
- edsl/results/results_tools_mixin.py +0 -98
- edsl/scenarios/DocumentChunker.py +0 -104
- edsl/scenarios/Scenario.py +0 -548
- edsl/scenarios/ScenarioHtmlMixin.py +0 -65
- edsl/scenarios/ScenarioListExportMixin.py +0 -45
- edsl/scenarios/handlers/latex.py +0 -5
- edsl/shared.py +0 -1
- edsl/surveys/Survey.py +0 -1301
- edsl/surveys/SurveyQualtricsImport.py +0 -284
- edsl/surveys/SurveyToApp.py +0 -141
- edsl/surveys/instructions/__init__.py +0 -0
- edsl/tools/__init__.py +0 -1
- edsl/tools/clusters.py +0 -192
- edsl/tools/embeddings.py +0 -27
- edsl/tools/embeddings_plotting.py +0 -118
- edsl/tools/plotting.py +0 -112
- edsl/tools/summarize.py +0 -18
- edsl/utilities/data/Registry.py +0 -6
- edsl/utilities/data/__init__.py +0 -1
- edsl/utilities/data/scooter_results.json +0 -1
- edsl-0.1.47.dist-info/RECORD +0 -354
- /edsl/coop/{CoopFunctionsMixin.py → coop_functions.py} +0 -0
- /edsl/{results → dataset/display}/CSSParameterizer.py +0 -0
- /edsl/{language_models/key_management → dataset/display}/__init__.py +0 -0
- /edsl/{results → dataset/display}/table_data_class.py +0 -0
- /edsl/{results → dataset/display}/table_display.css +0 -0
- /edsl/{results/ResultsGGMixin.py → dataset/r/ggplot.py} +0 -0
- /edsl/{results → dataset}/tree_explore.py +0 -0
- /edsl/{surveys/instructions/ChangeInstruction.py → instructions/change_instruction.py} +0 -0
- /edsl/{jobs/interviews → interviews}/interview_status_enum.py +0 -0
- /edsl/jobs/{runners/JobsRunnerStatus.py → jobs_runner_status.py} +0 -0
- /edsl/language_models/{PriceManager.py → price_manager.py} +0 -0
- /edsl/language_models/{fake_openai_call.py → unused/fake_openai_call.py} +0 -0
- /edsl/language_models/{fake_openai_service.py → unused/fake_openai_service.py} +0 -0
- /edsl/notebooks/{NotebookToLaTeX.py → notebook_to_latex.py} +0 -0
- /edsl/{exceptions/questions.py → questions/exceptions.py} +0 -0
- /edsl/questions/{SimpleAskMixin.py → simple_ask_mixin.py} +0 -0
- /edsl/surveys/{Memory.py → memory/memory.py} +0 -0
- /edsl/surveys/{MemoryManagement.py → memory/memory_management.py} +0 -0
- /edsl/surveys/{SurveyCSS.py → survey_css.py} +0 -0
- /edsl/{jobs/tokens/TokenUsage.py → tokens/token_usage.py} +0 -0
- /edsl/{results/MarkdownToDocx.py → utilities/markdown_to_docx.py} +0 -0
- /edsl/{TemplateLoader.py → utilities/template_loader.py} +0 -0
- {edsl-0.1.47.dist-info → edsl-0.1.49.dist-info}/LICENSE +0 -0
- {edsl-0.1.47.dist-info → edsl-0.1.49.dist-info}/WHEEL +0 -0
edsl/language_models/model.py
CHANGED
@@ -2,19 +2,16 @@ import textwrap
|
|
2
2
|
from random import random
|
3
3
|
from typing import Optional, TYPE_CHECKING, List, Callable
|
4
4
|
|
5
|
-
from
|
6
|
-
from
|
5
|
+
from ..utilities import PrettyList
|
6
|
+
from ..config import CONFIG
|
7
7
|
|
8
|
-
from
|
9
|
-
|
10
|
-
|
11
|
-
from
|
12
|
-
from edsl.inference_services.InferenceServiceABC import InferenceServiceABC
|
13
|
-
from edsl.enums import InferenceServiceLiteral
|
14
|
-
from edsl.exceptions.inference_services import InferenceServiceError
|
8
|
+
from ..inference_services import (InferenceServicesCollection,
|
9
|
+
AvailableModels, InferenceServiceABC, InferenceServiceError, default)
|
10
|
+
|
11
|
+
from ..enums import InferenceServiceLiteral
|
15
12
|
|
16
13
|
if TYPE_CHECKING:
|
17
|
-
from
|
14
|
+
from ..dataset import Dataset
|
18
15
|
|
19
16
|
|
20
17
|
def get_model_class(
|
@@ -22,8 +19,6 @@ def get_model_class(
|
|
22
19
|
registry: Optional[InferenceServicesCollection] = None,
|
23
20
|
service_name: Optional[InferenceServiceLiteral] = None,
|
24
21
|
):
|
25
|
-
from edsl.inference_services.registry import default
|
26
|
-
|
27
22
|
registry = registry or default
|
28
23
|
try:
|
29
24
|
factory = registry.create_model_factory(model_name, service_name=service_name)
|
@@ -31,7 +26,6 @@ def get_model_class(
|
|
31
26
|
except (InferenceServiceError, Exception) as e:
|
32
27
|
return Model._handle_model_error(model_name, e)
|
33
28
|
|
34
|
-
|
35
29
|
class Meta(type):
|
36
30
|
def __repr__(cls):
|
37
31
|
return textwrap.dedent(
|
@@ -59,8 +53,6 @@ class Model(metaclass=Meta):
|
|
59
53
|
def get_registry(cls) -> InferenceServicesCollection:
|
60
54
|
"""Get the current registry or initialize with default if None"""
|
61
55
|
if cls._registry is None:
|
62
|
-
from edsl.inference_services.registry import default
|
63
|
-
|
64
56
|
cls._registry = default
|
65
57
|
return cls._registry
|
66
58
|
|
@@ -165,10 +157,8 @@ class Model(metaclass=Meta):
|
|
165
157
|
@classmethod
|
166
158
|
def key_info(cls, obscure_api_key: bool = True) -> "Dataset":
|
167
159
|
"""Returns a dataset of local key information."""
|
168
|
-
from
|
169
|
-
|
170
|
-
)
|
171
|
-
from edsl.scenarios import Scenario, ScenarioList
|
160
|
+
from ..key_management import KeyLookupCollection
|
161
|
+
from ..scenarios import Scenario, ScenarioList
|
172
162
|
|
173
163
|
klc = KeyLookupCollection()
|
174
164
|
klc.add_key_lookup(fetch_order=None)
|
@@ -290,7 +280,7 @@ class Model(metaclass=Meta):
|
|
290
280
|
works_with_text: Optional[bool] = None,
|
291
281
|
works_with_images: Optional[bool] = None,
|
292
282
|
) -> list[dict]:
|
293
|
-
from
|
283
|
+
from ..coop import Coop
|
294
284
|
|
295
285
|
c = Coop()
|
296
286
|
working_models = c.fetch_working_models()
|
@@ -349,10 +339,5 @@ class Model(metaclass=Meta):
|
|
349
339
|
|
350
340
|
if __name__ == "__main__":
|
351
341
|
import doctest
|
352
|
-
|
353
342
|
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
354
343
|
|
355
|
-
# available = Model.available()
|
356
|
-
# m = Model("gpt-4-1106-preview")
|
357
|
-
# results = m.execute_model_call("Hello world")
|
358
|
-
# print(results)
|
@@ -1,17 +1,14 @@
|
|
1
1
|
from typing import Optional, List, TYPE_CHECKING
|
2
2
|
from collections import UserList
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
4
|
+
from ..base import Base
|
5
|
+
from ..language_models import Model
|
6
6
|
|
7
|
-
|
8
|
-
from edsl.utilities.remove_edsl_version import remove_edsl_version
|
9
|
-
from edsl.utilities.is_valid_variable_name import is_valid_variable_name
|
7
|
+
from ..utilities import remove_edsl_version, is_valid_variable_name, dict_hash
|
10
8
|
|
11
9
|
if TYPE_CHECKING:
|
12
|
-
from
|
13
|
-
from
|
14
|
-
|
10
|
+
from ..inference_services.data_structures import AvailableModels
|
11
|
+
from ..language_models import LanguageModel
|
15
12
|
|
16
13
|
class ModelList(Base, UserList):
|
17
14
|
__documentation__ = """https://docs.expectedparrot.com/en/latest/language_models.html#module-edsl.language_models.ModelList"""
|
@@ -50,13 +47,11 @@ class ModelList(Base, UserList):
|
|
50
47
|
True
|
51
48
|
|
52
49
|
"""
|
53
|
-
from edsl.utilities.utilities import dict_hash
|
54
|
-
|
55
50
|
return dict_hash(self.to_dict(sort=True, add_edsl_version=False))
|
56
51
|
|
57
52
|
def to_scenario_list(self):
|
58
|
-
from
|
59
|
-
from
|
53
|
+
from ..scenarios import ScenarioList
|
54
|
+
from ..scenarios import Scenario
|
60
55
|
|
61
56
|
sl = ScenarioList()
|
62
57
|
for model in self:
|
@@ -107,7 +102,7 @@ class ModelList(Base, UserList):
|
|
107
102
|
]
|
108
103
|
}
|
109
104
|
if add_edsl_version:
|
110
|
-
from
|
105
|
+
from .. import __version__
|
111
106
|
|
112
107
|
d["edsl_version"] = __version__
|
113
108
|
d["edsl_class_name"] = "ModelList"
|
@@ -140,7 +135,7 @@ class ModelList(Base, UserList):
|
|
140
135
|
>>> newm = ModelList.from_dict(ModelList.example().to_dict())
|
141
136
|
>>> assert ModelList.example() == newm
|
142
137
|
"""
|
143
|
-
from
|
138
|
+
from ..language_models import LanguageModel
|
144
139
|
|
145
140
|
return cls(data=[LanguageModel.from_dict(model) for model in data["models"]])
|
146
141
|
|
@@ -2,7 +2,7 @@ from abc import ABC, ABCMeta
|
|
2
2
|
from typing import Any, List, Callable
|
3
3
|
import inspect
|
4
4
|
from typing import get_type_hints
|
5
|
-
from
|
5
|
+
from .exceptions import LanguageModelAttributeTypeError
|
6
6
|
from edsl.enums import InferenceServiceType
|
7
7
|
|
8
8
|
|
edsl/language_models/repair.py
CHANGED
@@ -6,7 +6,7 @@ import warnings
|
|
6
6
|
async def async_repair(
|
7
7
|
bad_json, error_message="", user_prompt=None, system_prompt=None, cache=None
|
8
8
|
):
|
9
|
-
from
|
9
|
+
from ..utilities import clean_json
|
10
10
|
|
11
11
|
s = clean_json(bad_json)
|
12
12
|
|
@@ -22,7 +22,7 @@ async def async_repair(
|
|
22
22
|
return valid_dict, success
|
23
23
|
|
24
24
|
try:
|
25
|
-
from
|
25
|
+
from ..utilities.repair_functions import extract_json_from_string
|
26
26
|
|
27
27
|
valid_dict = extract_json_from_string(s)
|
28
28
|
success = True
|
@@ -32,11 +32,11 @@ async def async_repair(
|
|
32
32
|
else:
|
33
33
|
return valid_dict, success
|
34
34
|
|
35
|
-
from
|
35
|
+
from .model import Model
|
36
36
|
|
37
37
|
m = Model()
|
38
38
|
|
39
|
-
from
|
39
|
+
from ..questions.QuestionExtract import QuestionExtract
|
40
40
|
|
41
41
|
with warnings.catch_warnings():
|
42
42
|
warnings.simplefilter("ignore", UserWarning)
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Any, Optional, List
|
3
|
-
from
|
3
|
+
from ..enums import InferenceServiceType
|
4
|
+
from ..surveys import Survey
|
4
5
|
|
6
|
+
from .language_model import LanguageModel
|
5
7
|
|
6
8
|
def create_survey(num_questions: int, chained: bool = True, take_scenario=False):
|
7
|
-
from
|
8
|
-
from edsl.questions.QuestionFreeText import QuestionFreeText
|
9
|
+
from ..questions import QuestionFreeText
|
9
10
|
|
10
11
|
survey = Survey()
|
11
12
|
for i in range(num_questions):
|
@@ -27,7 +28,6 @@ def create_survey(num_questions: int, chained: bool = True, take_scenario=False)
|
|
27
28
|
def create_language_model(
|
28
29
|
exception: Exception, fail_at_number: int, never_ending=False
|
29
30
|
):
|
30
|
-
from edsl.language_models.LanguageModel import LanguageModel
|
31
31
|
|
32
32
|
class LanguageModelFromUtilities(LanguageModel):
|
33
33
|
_model_ = "test"
|
edsl/notebooks/__init__.py
CHANGED
@@ -4,9 +4,9 @@ from __future__ import annotations
|
|
4
4
|
import json
|
5
5
|
from typing import Dict, List, Optional, Union
|
6
6
|
from uuid import uuid4
|
7
|
-
from edsl.Base import Base
|
8
|
-
from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
|
9
7
|
|
8
|
+
from ..base import Base
|
9
|
+
from ..utilities.decorators import remove_edsl_version
|
10
10
|
|
11
11
|
class Notebook(Base):
|
12
12
|
"""
|
@@ -102,7 +102,7 @@ class Notebook(Base):
|
|
102
102
|
"""
|
103
103
|
Allow the model to be used as a key in a dictionary.
|
104
104
|
"""
|
105
|
-
from
|
105
|
+
from ..utilities.utilities import dict_hash
|
106
106
|
|
107
107
|
return dict_hash(self.data["cells"])
|
108
108
|
|
@@ -112,7 +112,7 @@ class Notebook(Base):
|
|
112
112
|
"""
|
113
113
|
d = {"name": self.name, "data": self.data}
|
114
114
|
if add_edsl_version:
|
115
|
-
from
|
115
|
+
from .. import __version__
|
116
116
|
|
117
117
|
d["edsl_version"] = __version__
|
118
118
|
d["edsl_class_name"] = self.__class__.__name__
|
@@ -241,7 +241,7 @@ class Notebook(Base):
|
|
241
241
|
Return the code that could be used to create this Notebook.
|
242
242
|
"""
|
243
243
|
lines = []
|
244
|
-
lines.append("from edsl import Notebook")
|
244
|
+
lines.append("from edsl import Notebook") # Keep as absolute for code generation
|
245
245
|
lines.append(f'nb = Notebook(data={self.data}, name="""{self.name}""")')
|
246
246
|
return lines
|
247
247
|
|
@@ -251,13 +251,12 @@ class Notebook(Base):
|
|
251
251
|
|
252
252
|
:param filename: Name of the output folder and main tex file (without extension)
|
253
253
|
"""
|
254
|
-
from
|
254
|
+
from .NotebookToLaTeX import NotebookToLaTeX
|
255
255
|
|
256
256
|
NotebookToLaTeX(self).convert(filename)
|
257
257
|
|
258
258
|
|
259
259
|
if __name__ == "__main__":
|
260
|
-
from
|
261
|
-
|
260
|
+
from .. import Notebook
|
262
261
|
notebook = Notebook.example()
|
263
262
|
assert notebook == notebook.from_dict(notebook.to_dict())
|
edsl/prompts/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# from edsl.prompts.registry import get_classes
|
2
|
-
from
|
2
|
+
from .prompt import Prompt
|
@@ -1,33 +1,50 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import Any, List, Union, Dict, Optional
|
3
3
|
from pathlib import Path
|
4
|
+
import time
|
5
|
+
from functools import lru_cache
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
from jinja2 import Environment, meta, Undefined
|
7
8
|
|
8
|
-
from
|
9
|
-
from
|
9
|
+
from .exceptions import TemplateRenderError
|
10
|
+
from ..base import PersistenceMixin, RepresentationMixin
|
10
11
|
|
11
12
|
MAX_NESTING = 100
|
12
13
|
|
13
|
-
from jinja2 import Environment, meta, TemplateSyntaxError, Undefined
|
14
|
-
from functools import lru_cache
|
15
|
-
|
16
14
|
class PreserveUndefined(Undefined):
|
17
15
|
def __str__(self):
|
18
16
|
return "{{ " + str(self._undefined_name) + " }}"
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
class TemplateVars:
|
19
|
+
"""Stores variables set during template rendering."""
|
20
|
+
def __init__(self):
|
21
|
+
self.data = {}
|
22
|
+
|
23
|
+
def set(self, name, value):
|
24
|
+
"""Store a variable with its name and value,
|
25
|
+
returning an empty string for direct use in the template.
|
26
|
+
"""
|
27
|
+
self.data[name] = value
|
28
|
+
return ""
|
29
|
+
|
30
|
+
def get(self, name, default=None):
|
31
|
+
"""Retrieve a stored variable."""
|
32
|
+
return self.data.get(name, default)
|
33
|
+
|
34
|
+
def get_all(self) -> Dict[str, Any]:
|
35
|
+
"""Return all captured variables."""
|
36
|
+
return self.data
|
22
37
|
|
23
|
-
|
24
|
-
|
25
|
-
|
38
|
+
def make_env() -> Environment:
|
39
|
+
"""Create a fresh Jinja environment each time,
|
40
|
+
so we don't mix captured variables across multiple renders.
|
41
|
+
"""
|
42
|
+
return Environment(undefined=PreserveUndefined)
|
26
43
|
|
27
44
|
@lru_cache(maxsize=1024)
|
28
|
-
def _find_template_variables(
|
29
|
-
|
30
|
-
ast =
|
45
|
+
def _find_template_variables(template_text: str) -> List[str]:
|
46
|
+
env = make_env()
|
47
|
+
ast = env.parse(template_text)
|
31
48
|
return list(meta.find_undeclared_variables(ast))
|
32
49
|
|
33
50
|
def _make_hashable(value):
|
@@ -81,9 +98,10 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
81
98
|
# make it idempotent w/ a prompt
|
82
99
|
text = text.text
|
83
100
|
self._text = text
|
101
|
+
self.captured_variables = {}
|
84
102
|
|
85
103
|
@classmethod
|
86
|
-
def from_txt(cls, filename: str) ->
|
104
|
+
def from_txt(cls, filename: str) -> 'Prompt':
|
87
105
|
"""Create a `Prompt` from text.
|
88
106
|
|
89
107
|
:param text: The text of the prompt.
|
@@ -98,7 +116,7 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
98
116
|
file_name: str,
|
99
117
|
path_to_folder: Optional[Union[str, Path]] = None,
|
100
118
|
**kwargs: Dict[str, Any],
|
101
|
-
) -> "
|
119
|
+
) -> "Prompt":
|
102
120
|
"""Create a `PromptBase` from a Jinja template.
|
103
121
|
|
104
122
|
Args:
|
@@ -131,11 +149,11 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
131
149
|
return cls(text=text)
|
132
150
|
|
133
151
|
@property
|
134
|
-
def text(self):
|
152
|
+
def text(self) -> str:
|
135
153
|
"""Return the `Prompt` text."""
|
136
154
|
return self._text
|
137
155
|
|
138
|
-
def __add__(self, other_prompt):
|
156
|
+
def __add__(self, other_prompt) -> 'Prompt':
|
139
157
|
"""Add two prompts together.
|
140
158
|
|
141
159
|
Example:
|
@@ -163,7 +181,7 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
163
181
|
"""
|
164
182
|
return self.text
|
165
183
|
|
166
|
-
def __contains__(self, text_to_check):
|
184
|
+
def __contains__(self, text_to_check) -> bool:
|
167
185
|
"""Check if the text_to_check is in the `Prompt` text.
|
168
186
|
|
169
187
|
Example:
|
@@ -190,7 +208,7 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
190
208
|
"""Return the variables in the template."""
|
191
209
|
return _find_template_variables(self.text)
|
192
210
|
|
193
|
-
def undefined_template_variables(self, replacement_dict: dict):
|
211
|
+
def undefined_template_variables(self, replacement_dict: dict) -> list[str]:
|
194
212
|
"""Return the variables in the template that are not in the replacement_dict.
|
195
213
|
|
196
214
|
:param replacement_dict: A dictionary of replacements to populate the template.
|
@@ -207,7 +225,7 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
207
225
|
"""
|
208
226
|
return [var for var in self.template_variables() if var not in replacement_dict]
|
209
227
|
|
210
|
-
def unused_traits(self, traits: dict):
|
228
|
+
def unused_traits(self, traits: dict) -> list[str]:
|
211
229
|
"""Return the traits that are not used in the template."""
|
212
230
|
return [trait for trait in traits if trait not in self.template_variables()]
|
213
231
|
|
@@ -227,8 +245,9 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
227
245
|
"""
|
228
246
|
return len(self.template_variables()) > 0
|
229
247
|
|
230
|
-
def render(self, primary_replacement: dict, **additional_replacements) ->
|
231
|
-
"""
|
248
|
+
def render(self, primary_replacement: dict, **additional_replacements) -> "Prompt":
|
249
|
+
"""
|
250
|
+
Render the prompt with the replacements.
|
232
251
|
|
233
252
|
:param primary_replacement: The primary replacement dictionary.
|
234
253
|
:param additional_replacements: Additional replacement dictionaries.
|
@@ -245,57 +264,65 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
245
264
|
|
246
265
|
>>> p.render({"person": "Mr. {{last_name}}"})
|
247
266
|
Prompt(text=\"""Hello, Mr. {{ last_name }}\""")
|
267
|
+
|
268
|
+
>>> p = Prompt("The sum is {% set x = 2 + 3 %}{{ vars.set('x', x) }}{{x}}")
|
269
|
+
>>> result = p.render({})
|
270
|
+
>>> print(result.captured_variables)
|
271
|
+
{'x': 5}
|
272
|
+
>>> result.captured_variables['x']
|
273
|
+
5
|
248
274
|
"""
|
249
275
|
try:
|
250
|
-
|
251
|
-
|
276
|
+
template_vars = TemplateVars()
|
277
|
+
new_text, captured_vars = self._render(
|
278
|
+
self.text, primary_replacement, template_vars, **additional_replacements
|
252
279
|
)
|
253
|
-
|
280
|
+
result = Prompt(text=new_text)
|
281
|
+
result.captured_variables = captured_vars
|
282
|
+
return result
|
254
283
|
except Exception as e:
|
255
284
|
print(f"Error rendering prompt: {e}")
|
256
285
|
return self
|
257
286
|
|
258
287
|
@staticmethod
|
259
|
-
def _render(
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
f"Template syntax error: {e}. Bad template: {text}"
|
298
|
-
)
|
288
|
+
def _render(
|
289
|
+
text: str,
|
290
|
+
primary_replacement: dict,
|
291
|
+
template_vars: TemplateVars,
|
292
|
+
**additional_replacements
|
293
|
+
) -> tuple[str, Dict[str, Any]]:
|
294
|
+
"""
|
295
|
+
Render the template text with variables replaced.
|
296
|
+
Returns (rendered_text, captured_variables).
|
297
|
+
"""
|
298
|
+
# Combine replacements.
|
299
|
+
all_replacements = {**primary_replacement, **additional_replacements}
|
300
|
+
|
301
|
+
# If no replacements and no Jinja variables, just return the text.
|
302
|
+
if not all_replacements and not _find_template_variables(text):
|
303
|
+
return text, template_vars.get_all()
|
304
|
+
|
305
|
+
env = make_env()
|
306
|
+
# Provide access to the 'vars' object inside the template.
|
307
|
+
env.globals['vars'] = template_vars
|
308
|
+
|
309
|
+
previous_text = None
|
310
|
+
current_text = text
|
311
|
+
|
312
|
+
for _ in range(MAX_NESTING):
|
313
|
+
template = env.from_string(current_text)
|
314
|
+
rendered_text = template.render(**all_replacements)
|
315
|
+
|
316
|
+
if rendered_text == current_text:
|
317
|
+
# No more changes, return final text with captured variables.
|
318
|
+
return rendered_text, template_vars.get_all()
|
319
|
+
|
320
|
+
previous_text = current_text
|
321
|
+
current_text = rendered_text
|
322
|
+
|
323
|
+
raise TemplateRenderError(
|
324
|
+
"Too much nesting - you created an infinite loop here, pal"
|
325
|
+
)
|
299
326
|
|
300
327
|
def to_dict(self, add_edsl_version=False) -> dict[str, Any]:
|
301
328
|
"""Return the `Prompt` as a dictionary.
|
@@ -310,7 +337,7 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
310
337
|
return {"text": self.text, "class_name": self.__class__.__name__}
|
311
338
|
|
312
339
|
@classmethod
|
313
|
-
def from_dict(cls, data) ->
|
340
|
+
def from_dict(cls, data) -> 'Prompt':
|
314
341
|
"""Create a `Prompt` from a dictionary.
|
315
342
|
|
316
343
|
Example:
|
@@ -324,18 +351,6 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
324
351
|
# class_name = data["class_name"]
|
325
352
|
return Prompt(text=data["text"])
|
326
353
|
|
327
|
-
# def rich_print(self):
|
328
|
-
# """Display an object as a table."""
|
329
|
-
# table = Table(title="Prompt")
|
330
|
-
# table.add_column("Attribute", style="bold")
|
331
|
-
# table.add_column("Value")
|
332
|
-
|
333
|
-
# to_display = self.__dict__.copy()
|
334
|
-
# for attr_name, attr_value in to_display.items():
|
335
|
-
# table.add_row(attr_name, repr(attr_value))
|
336
|
-
# table.add_row("Component type", str(self.component_type))
|
337
|
-
# table.add_row("Model", str(getattr(self, "model", "Not specified")))
|
338
|
-
# return table
|
339
354
|
|
340
355
|
@classmethod
|
341
356
|
def example(cls):
|
@@ -343,7 +358,12 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
343
358
|
return cls(cls.default_instructions)
|
344
359
|
|
345
360
|
def get_prompts(self) -> Dict[str, Any]:
|
346
|
-
"""Get the prompts for the question.
|
361
|
+
"""Get the prompts for the question.
|
362
|
+
|
363
|
+
>>> p = Prompt("Hello, {{person}}")
|
364
|
+
"""
|
365
|
+
|
366
|
+
raise NotImplementedError("This method should be implemented by the subclass.")
|
347
367
|
start = time.time()
|
348
368
|
|
349
369
|
# Build all the components
|
@@ -396,20 +416,6 @@ class Prompt(PersistenceMixin, RepresentationMixin):
|
|
396
416
|
return prompts
|
397
417
|
|
398
418
|
if __name__ == "__main__":
|
399
|
-
print("Running doctests...")
|
400
419
|
import doctest
|
401
|
-
|
402
420
|
doctest.testmod()
|
403
421
|
|
404
|
-
# from edsl.prompts.library.question_multiple_choice import *
|
405
|
-
# from edsl.prompts.library.agent_instructions import *
|
406
|
-
# from edsl.prompts.library.agent_persona import *
|
407
|
-
|
408
|
-
# from edsl.prompts.library.question_budget import *
|
409
|
-
# from edsl.prompts.library.question_checkbox import *
|
410
|
-
# from edsl.prompts.library.question_freetext import *
|
411
|
-
# from edsl.prompts.library.question_linear_scale import *
|
412
|
-
# from edsl.prompts.library.question_numerical import *
|
413
|
-
# from edsl.prompts.library.question_rank import *
|
414
|
-
# from edsl.prompts.library.question_extract import *
|
415
|
-
# from edsl.prompts.library.question_list import *
|
edsl/questions/HTMLQuestion.py
CHANGED