qtype 0.1.1__tar.gz → 0.1.3__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.
- {qtype-0.1.1/qtype.egg-info → qtype-0.1.3}/PKG-INFO +12 -11
- {qtype-0.1.1 → qtype-0.1.3}/pyproject.toml +12 -11
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/facade.py +14 -15
- {qtype-0.1.1 → qtype-0.1.3}/qtype/cli.py +1 -1
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/generate.py +1 -1
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/run.py +7 -3
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/domain_types.py +24 -3
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/model.py +56 -3
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/base_step_executor.py +1 -1
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/executor_context.py +18 -1
- qtype-0.1.3/qtype/interpreter/base/factory.py +84 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/conversions.py +15 -6
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/converters.py +14 -12
- qtype-0.1.3/qtype/interpreter/executors/bedrock_reranker_executor.py +195 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/document_search_executor.py +37 -46
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/document_splitter_executor.py +1 -1
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/field_extractor_executor.py +10 -5
- qtype-0.1.3/qtype/interpreter/executors/index_upsert_executor.py +232 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/flow.py +47 -33
- qtype-0.1.3/qtype/interpreter/logging_progress.py +61 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/checker.py +79 -19
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/model.py +43 -3
- {qtype-0.1.1 → qtype-0.1.3/qtype.egg-info}/PKG-INFO +12 -11
- {qtype-0.1.1 → qtype-0.1.3}/qtype.egg-info/SOURCES.txt +2 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype.egg-info/requires.txt +11 -10
- qtype-0.1.1/qtype/interpreter/base/factory.py +0 -117
- qtype-0.1.1/qtype/interpreter/executors/index_upsert_executor.py +0 -228
- {qtype-0.1.1 → qtype-0.1.3}/LICENSE +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/README.md +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/commons/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/commons/tools.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/converters/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/converters/tools_from_api.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/converters/tools_from_module.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/converters/types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/application/documentation.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/base/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/base/exceptions.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/base/logging.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/base/types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/convert.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/serve.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/validate.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/commands/visualize.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/custom_types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/linker.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/loader.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/parser.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/dsl/types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/api.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/auth/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/auth/aws.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/auth/cache.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/auth/generic.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/batch_step_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/exceptions.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/progress_tracker.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/secrets.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/step_cache.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/base/stream_emitter.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/endpoints.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/agent_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/aggregate_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/decoder_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/doc_to_text_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/document_embedder_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/document_source_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/echo_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/file_source_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/file_writer_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/invoke_embedding_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/invoke_flow_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/invoke_tool_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/llm_inference_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/prompt_template_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/sql_source_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/executors/vector_search_executor.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/metadata_api.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/resource_cache.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/rich_progress.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/chat/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/chat/converter.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/chat/file_conversions.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/chat/ui_request_to_domain_type.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/chat/vercel.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/build_vercel_ai_formatter.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/callback_to_stream.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/create_streaming_response.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/default_chat_extract_text.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/stream/utils/error_streaming_response.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/telemetry.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/tools/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/tools/function_tool_helper.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/typing.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/404/index.html +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/404.html +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/20HoJN6otZ_LyHLHpCPE6/_buildManifest.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/20HoJN6otZ_LyHLHpCPE6/_ssgManifest.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/434-b2112d19f25c44ff.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/964-2b041321a01cbf56.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/app/_not-found/page-e110d2a9d0a83d82.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/app/layout-a05273ead5de2c41.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/app/page-8c67d16ac90d23cb.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/ba12c10f-546f2714ff8abc66.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/framework-7c95b8e5103c9e90.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/main-app-6fc6346bc8f7f163.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/main-e26b9cb206da2cac.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/pages/_app-0a0020ddd67f79cf.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/pages/_error-03529f2c21436739.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/chunks/webpack-08642e441b39b6c2.js +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/css/8a8d1269e362fef7.css +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/747892c23ea88013-s.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/8d697b304b401681-s.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/9610d9e46709d722-s.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/_next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/file.svg +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/globe.svg +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/icon.png +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/index.html +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/index.txt +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/next.svg +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/vercel.svg +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/interpreter/ui/window.svg +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/__init__.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/base_types.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/generate.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/loader.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/resolver.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype/semantic/visualize.py +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype.egg-info/dependency_links.txt +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype.egg-info/entry_points.txt +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/qtype.egg-info/top_level.txt +0 -0
- {qtype-0.1.1 → qtype-0.1.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qtype
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: DSL for Generative AI Prototyping
|
|
5
5
|
Author-email: Lou Kratz <lou.kratz+qtype@bazaarvoice.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -23,16 +23,26 @@ Provides-Extra: interpreter
|
|
|
23
23
|
Requires-Dist: aiostream>=0.7.1; extra == "interpreter"
|
|
24
24
|
Requires-Dist: arize-phoenix-otel>=0.12.1; extra == "interpreter"
|
|
25
25
|
Requires-Dist: boto3>=1.34.0; extra == "interpreter"
|
|
26
|
+
Requires-Dist: datasets>=4.4.1; extra == "interpreter"
|
|
27
|
+
Requires-Dist: diskcache>=5.6.3; extra == "interpreter"
|
|
26
28
|
Requires-Dist: docling>=2.55.1; extra == "interpreter"
|
|
27
|
-
Requires-Dist:
|
|
29
|
+
Requires-Dist: docx2txt>=0.9; extra == "interpreter"
|
|
28
30
|
Requires-Dist: fastapi>=0.116.1; extra == "interpreter"
|
|
31
|
+
Requires-Dist: jsonpath-ng>=1.7.0; extra == "interpreter"
|
|
32
|
+
Requires-Dist: langfuse>=3.9.0; extra == "interpreter"
|
|
29
33
|
Requires-Dist: llama-index-embeddings-bedrock>=0.5.2; extra == "interpreter"
|
|
30
34
|
Requires-Dist: llama-index-embeddings-openai>=0.3.1; extra == "interpreter"
|
|
31
35
|
Requires-Dist: llama-index-llms-bedrock-converse>=0.10.5; extra == "interpreter"
|
|
32
36
|
Requires-Dist: llama-index-llms-bedrock>=0.3.8; extra == "interpreter"
|
|
37
|
+
Requires-Dist: llama-index-llms-vertex>=0.6.1; extra == "interpreter"
|
|
38
|
+
Requires-Dist: llama-index-postprocessor-bedrock-rerank>=0.5.1; extra == "interpreter"
|
|
39
|
+
Requires-Dist: llama-index-readers-huggingface-fs>=0.4.1; extra == "interpreter"
|
|
40
|
+
Requires-Dist: llama-index-vector-stores-qdrant>=0.8.6; extra == "interpreter"
|
|
33
41
|
Requires-Dist: llama-index>=0.12.45; extra == "interpreter"
|
|
34
42
|
Requires-Dist: openinference-instrumentation-llama-index>=4.3.4; extra == "interpreter"
|
|
35
43
|
Requires-Dist: opensearch-py>=2.7.0; extra == "interpreter"
|
|
44
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.35.0; extra == "interpreter"
|
|
45
|
+
Requires-Dist: opentelemetry-sdk>=1.35.0; extra == "interpreter"
|
|
36
46
|
Requires-Dist: pandas>=2.2.3; extra == "interpreter"
|
|
37
47
|
Requires-Dist: psycopg2-binary>=2.9.10; extra == "interpreter"
|
|
38
48
|
Requires-Dist: pyarrow>=21.0.0; extra == "interpreter"
|
|
@@ -41,15 +51,6 @@ Requires-Dist: python-magic>=0.4.27; extra == "interpreter"
|
|
|
41
51
|
Requires-Dist: s3fs>=2025.7.0; extra == "interpreter"
|
|
42
52
|
Requires-Dist: sqlalchemy>=2.0.42; extra == "interpreter"
|
|
43
53
|
Requires-Dist: uvicorn[standard]>=0.35.0; extra == "interpreter"
|
|
44
|
-
Requires-Dist: llama-index-llms-vertex>=0.6.1; extra == "interpreter"
|
|
45
|
-
Requires-Dist: langfuse>=3.9.0; extra == "interpreter"
|
|
46
|
-
Requires-Dist: opentelemetry-exporter-otlp>=1.35.0; extra == "interpreter"
|
|
47
|
-
Requires-Dist: opentelemetry-sdk>=1.35.0; extra == "interpreter"
|
|
48
|
-
Requires-Dist: docx2txt>=0.9; extra == "interpreter"
|
|
49
|
-
Requires-Dist: llama-index-vector-stores-qdrant>=0.8.6; extra == "interpreter"
|
|
50
|
-
Requires-Dist: jsonpath-ng>=1.7.0; extra == "interpreter"
|
|
51
|
-
Requires-Dist: llama-index-readers-huggingface-fs>=0.4.1; extra == "interpreter"
|
|
52
|
-
Requires-Dist: datasets>=4.4.1; extra == "interpreter"
|
|
53
54
|
Dynamic: license-file
|
|
54
55
|
|
|
55
56
|
# QType
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "qtype"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.3"
|
|
4
4
|
description = "DSL for Generative AI Prototyping"
|
|
5
5
|
authors = [{ name="Lou Kratz", email="lou.kratz+qtype@bazaarvoice.com" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -29,16 +29,26 @@ interpreter = [
|
|
|
29
29
|
"aiostream>=0.7.1",
|
|
30
30
|
"arize-phoenix-otel>=0.12.1",
|
|
31
31
|
"boto3>=1.34.0",
|
|
32
|
+
"datasets>=4.4.1",
|
|
33
|
+
"diskcache>=5.6.3",
|
|
32
34
|
"docling>=2.55.1",
|
|
33
|
-
"
|
|
35
|
+
"docx2txt>=0.9",
|
|
34
36
|
"fastapi>=0.116.1",
|
|
37
|
+
"jsonpath-ng>=1.7.0",
|
|
38
|
+
"langfuse>=3.9.0",
|
|
35
39
|
"llama-index-embeddings-bedrock>=0.5.2",
|
|
36
40
|
"llama-index-embeddings-openai>=0.3.1",
|
|
37
41
|
"llama-index-llms-bedrock-converse>=0.10.5",
|
|
38
42
|
"llama-index-llms-bedrock>=0.3.8",
|
|
43
|
+
"llama-index-llms-vertex>=0.6.1",
|
|
44
|
+
"llama-index-postprocessor-bedrock-rerank>=0.5.1",
|
|
45
|
+
"llama-index-readers-huggingface-fs>=0.4.1",
|
|
46
|
+
"llama-index-vector-stores-qdrant>=0.8.6",
|
|
39
47
|
"llama-index>=0.12.45",
|
|
40
48
|
"openinference-instrumentation-llama-index>=4.3.4",
|
|
41
49
|
"opensearch-py>=2.7.0",
|
|
50
|
+
"opentelemetry-exporter-otlp>=1.35.0",
|
|
51
|
+
"opentelemetry-sdk>=1.35.0",
|
|
42
52
|
"pandas>=2.2.3",
|
|
43
53
|
"psycopg2-binary>=2.9.10",
|
|
44
54
|
"pyarrow>=21.0.0",
|
|
@@ -47,15 +57,6 @@ interpreter = [
|
|
|
47
57
|
"s3fs>=2025.7.0",
|
|
48
58
|
"sqlalchemy>=2.0.42",
|
|
49
59
|
"uvicorn[standard]>=0.35.0",
|
|
50
|
-
"llama-index-llms-vertex>=0.6.1",
|
|
51
|
-
"langfuse>=3.9.0",
|
|
52
|
-
"opentelemetry-exporter-otlp>=1.35.0",
|
|
53
|
-
"opentelemetry-sdk>=1.35.0",
|
|
54
|
-
"docx2txt>=0.9",
|
|
55
|
-
"llama-index-vector-stores-qdrant>=0.8.6",
|
|
56
|
-
"jsonpath-ng>=1.7.0",
|
|
57
|
-
"llama-index-readers-huggingface-fs>=0.4.1",
|
|
58
|
-
"datasets>=4.4.1",
|
|
59
60
|
]
|
|
60
61
|
|
|
61
62
|
[dependency-groups]
|
|
@@ -27,13 +27,13 @@ class QTypeFacade:
|
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
def telemetry(self, spec: SemanticDocumentType) -> None:
|
|
30
|
+
from qtype.interpreter.telemetry import register
|
|
31
|
+
|
|
30
32
|
if isinstance(spec, SemanticApplication) and spec.telemetry:
|
|
31
33
|
logger.info(
|
|
32
34
|
f"Telemetry enabled with endpoint: {spec.telemetry.endpoint}"
|
|
33
35
|
)
|
|
34
36
|
# Register telemetry if needed
|
|
35
|
-
from qtype.interpreter.telemetry import register
|
|
36
|
-
|
|
37
37
|
register(spec.telemetry, self.secret_manager(spec), spec.id)
|
|
38
38
|
|
|
39
39
|
def secret_manager(self, spec: SemanticDocumentType):
|
|
@@ -75,11 +75,17 @@ class QTypeFacade:
|
|
|
75
75
|
DataFrame with results (one row per input)
|
|
76
76
|
"""
|
|
77
77
|
import pandas as pd
|
|
78
|
+
from opentelemetry import trace
|
|
78
79
|
|
|
80
|
+
from qtype.interpreter.base.executor_context import ExecutorContext
|
|
81
|
+
from qtype.interpreter.converters import (
|
|
82
|
+
dataframe_to_flow_messages,
|
|
83
|
+
flow_messages_to_dataframe,
|
|
84
|
+
)
|
|
85
|
+
from qtype.interpreter.flow import run_flow
|
|
86
|
+
from qtype.interpreter.types import Session
|
|
79
87
|
from qtype.semantic.loader import load
|
|
80
88
|
|
|
81
|
-
logger.info(f"Executing workflow from {path}")
|
|
82
|
-
|
|
83
89
|
# Load the semantic application
|
|
84
90
|
semantic_model, type_registry = load(Path(path))
|
|
85
91
|
assert isinstance(semantic_model, SemanticApplication)
|
|
@@ -100,7 +106,10 @@ class QTypeFacade:
|
|
|
100
106
|
else:
|
|
101
107
|
raise ValueError("No flows found in application")
|
|
102
108
|
|
|
109
|
+
logger.info(f"Executing flow {target_flow.id} from {path}")
|
|
110
|
+
|
|
103
111
|
# Convert inputs to DataFrame (normalize single dict to 1-row DataFrame)
|
|
112
|
+
|
|
104
113
|
if isinstance(inputs, dict):
|
|
105
114
|
input_df = pd.DataFrame([inputs])
|
|
106
115
|
elif isinstance(inputs, pd.DataFrame):
|
|
@@ -111,12 +120,6 @@ class QTypeFacade:
|
|
|
111
120
|
)
|
|
112
121
|
|
|
113
122
|
# Create session
|
|
114
|
-
from qtype.interpreter.converters import (
|
|
115
|
-
dataframe_to_flow_messages,
|
|
116
|
-
flow_messages_to_dataframe,
|
|
117
|
-
)
|
|
118
|
-
from qtype.interpreter.types import Session
|
|
119
|
-
|
|
120
123
|
session = Session(
|
|
121
124
|
session_id=kwargs.pop("session_id", "default"),
|
|
122
125
|
conversation_history=kwargs.pop("conversation_history", []),
|
|
@@ -126,12 +129,8 @@ class QTypeFacade:
|
|
|
126
129
|
initial_messages = dataframe_to_flow_messages(input_df, session)
|
|
127
130
|
|
|
128
131
|
# Execute the flow
|
|
129
|
-
from opentelemetry import trace
|
|
130
|
-
|
|
131
|
-
from qtype.interpreter.base.executor_context import ExecutorContext
|
|
132
|
-
from qtype.interpreter.flow import run_flow
|
|
133
|
-
|
|
134
132
|
secret_manager = self.secret_manager(semantic_model)
|
|
133
|
+
|
|
135
134
|
context = ExecutorContext(
|
|
136
135
|
secret_manager=secret_manager,
|
|
137
136
|
tracer=trace.get_tracer(__name__),
|
|
@@ -135,7 +135,7 @@ def main() -> None:
|
|
|
135
135
|
# Set logging level based on user input
|
|
136
136
|
logging.basicConfig(
|
|
137
137
|
level=getattr(logging, args.log_level),
|
|
138
|
-
format="%(levelname)s: %(message)s",
|
|
138
|
+
format="%(asctime)s - %(levelname)s: %(message)s",
|
|
139
139
|
)
|
|
140
140
|
|
|
141
141
|
# Dispatch to the selected subcommand
|
|
@@ -188,7 +188,7 @@ def parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
188
188
|
|
|
189
189
|
has_semantic_deps = True
|
|
190
190
|
except ImportError:
|
|
191
|
-
logger.
|
|
191
|
+
logger.debug(
|
|
192
192
|
"NetworkX or Ruff is not installed. Skipping semantic model generation."
|
|
193
193
|
)
|
|
194
194
|
has_semantic_deps = False
|
|
@@ -25,7 +25,7 @@ warnings.filterwarnings("ignore", category=UnsupportedFieldAttributeWarning)
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
# supress qdrant logging
|
|
28
|
-
for name in ["httpx", "urllib3", "qdrant_client"]:
|
|
28
|
+
for name in ["httpx", "urllib3", "qdrant_client", "opensearch"]:
|
|
29
29
|
logging.getLogger(name).setLevel(logging.WARNING)
|
|
30
30
|
|
|
31
31
|
|
|
@@ -40,12 +40,16 @@ def read_data_from_file(file_path: str) -> pd.DataFrame:
|
|
|
40
40
|
mime_type = magic.Magic(mime=True).from_file(file_path)
|
|
41
41
|
|
|
42
42
|
if mime_type == "text/csv":
|
|
43
|
-
|
|
43
|
+
# TODO: Restore na values and convert to optional once we support them https://github.com/bazaarvoice/qtype/issues/101
|
|
44
|
+
df = pd.read_csv(file_path)
|
|
45
|
+
return df.fillna("")
|
|
44
46
|
elif mime_type == "text/plain":
|
|
45
47
|
# For text/plain, use file extension to determine format
|
|
46
48
|
file_ext = Path(file_path).suffix.lower()
|
|
47
49
|
if file_ext == ".csv":
|
|
48
|
-
|
|
50
|
+
# TODO: Restore na values and convert to optional once we support them https://github.com/bazaarvoice/qtype/issues/101
|
|
51
|
+
df = pd.read_csv(file_path)
|
|
52
|
+
return df.fillna("")
|
|
49
53
|
elif file_ext == ".json":
|
|
50
54
|
return pd.read_json(file_path)
|
|
51
55
|
else:
|
|
@@ -93,12 +93,33 @@ class RAGChunk(Embedding):
|
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
class
|
|
97
|
-
"""A standard, built-in representation of a search result
|
|
96
|
+
class SearchResult(StrictBaseModel):
|
|
97
|
+
"""A standard, built-in representation of a search result."""
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
content: Any = Field(..., description="The content of the search result.")
|
|
100
|
+
doc_id: str = Field(
|
|
101
|
+
...,
|
|
102
|
+
description="The identifier of the document from which the result was retrieved.",
|
|
103
|
+
)
|
|
104
|
+
score: float = Field(
|
|
105
|
+
...,
|
|
106
|
+
description="The relevance score of the search result with respect to the query.",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class RAGSearchResult(SearchResult):
|
|
111
|
+
"""A standard, built-in representation of a search result from a RAG vector search.
|
|
112
|
+
|
|
113
|
+
Note: doc_id is duplicated from content.document_id for convenience.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
content: RAGChunk = Field(
|
|
100
117
|
..., description="The RAG chunk returned as a search result."
|
|
101
118
|
)
|
|
119
|
+
doc_id: str = Field(
|
|
120
|
+
...,
|
|
121
|
+
description="The document ID (duplicated from content.document_id).",
|
|
122
|
+
)
|
|
102
123
|
score: float = Field(
|
|
103
124
|
...,
|
|
104
125
|
description="The similarity score of the chunk with respect to the query.",
|
|
@@ -573,6 +573,10 @@ class FieldExtractor(Step):
|
|
|
573
573
|
...,
|
|
574
574
|
description="JSONPath expression to extract data from the input. Uses jsonpath-ng syntax.",
|
|
575
575
|
)
|
|
576
|
+
fail_on_missing: bool = Field(
|
|
577
|
+
default=True,
|
|
578
|
+
description="Whether to raise an error if the JSONPath matches no data. If False, returns None.",
|
|
579
|
+
)
|
|
576
580
|
|
|
577
581
|
|
|
578
582
|
class InvokeTool(Step, ConcurrentStepMixin):
|
|
@@ -1077,6 +1081,14 @@ class DocumentIndex(Index):
|
|
|
1077
1081
|
...,
|
|
1078
1082
|
description="URL endpoint for the search cluster (e.g., https://my-cluster.es.amazonaws.com).",
|
|
1079
1083
|
)
|
|
1084
|
+
id_field: str | None = Field(
|
|
1085
|
+
default=None,
|
|
1086
|
+
description=(
|
|
1087
|
+
"Field name to use as document ID. "
|
|
1088
|
+
"If not specified, auto-detects from: _id, id, doc_id, document_id, or uuid. "
|
|
1089
|
+
"If all are missing, a UUID is generated."
|
|
1090
|
+
),
|
|
1091
|
+
)
|
|
1080
1092
|
|
|
1081
1093
|
|
|
1082
1094
|
class Search(Step, ABC):
|
|
@@ -1089,15 +1101,18 @@ class Search(Step, ABC):
|
|
|
1089
1101
|
index: Reference[IndexType] | str = Field(
|
|
1090
1102
|
..., description="Index to search against (object or ID reference)."
|
|
1091
1103
|
)
|
|
1104
|
+
default_top_k: int | None = Field(
|
|
1105
|
+
default=10,
|
|
1106
|
+
description="Number of top results to retrieve if not provided in the inputs.",
|
|
1107
|
+
)
|
|
1092
1108
|
|
|
1093
1109
|
|
|
1094
1110
|
class VectorSearch(Search, BatchableStepMixin):
|
|
1095
1111
|
"""Performs vector similarity search against a vector index."""
|
|
1096
1112
|
|
|
1097
1113
|
type: Literal["VectorSearch"] = "VectorSearch"
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
description="Number of top results to retrieve if not provided in the inputs.",
|
|
1114
|
+
index: Reference[VectorIndex] | str = Field(
|
|
1115
|
+
..., description="Index to search against (object or ID reference)."
|
|
1101
1116
|
)
|
|
1102
1117
|
|
|
1103
1118
|
|
|
@@ -1105,6 +1120,43 @@ class DocumentSearch(Search, ConcurrentStepMixin):
|
|
|
1105
1120
|
"""Performs document search against a document index."""
|
|
1106
1121
|
|
|
1107
1122
|
type: Literal["DocumentSearch"] = "DocumentSearch"
|
|
1123
|
+
index: Reference[DocumentIndex] | str = Field(
|
|
1124
|
+
..., description="Index to search against (object or ID reference)."
|
|
1125
|
+
)
|
|
1126
|
+
query_args: dict[str, Any] = Field(
|
|
1127
|
+
default={
|
|
1128
|
+
"type": "best_fields",
|
|
1129
|
+
"fields": ["*"],
|
|
1130
|
+
},
|
|
1131
|
+
description="The arguments (other than 'query') to specify to the query shape (see https://docs.opensearch.org/latest/query-dsl/full-text/multi-match/).",
|
|
1132
|
+
)
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
class Reranker(Step):
|
|
1136
|
+
"""Reranks a list of documents based on relevance to a query using an LLM."""
|
|
1137
|
+
|
|
1138
|
+
type: Literal["Reranker"] = "Reranker"
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
# TODO: create a reranker that supports llamaindex rerankers...
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
class BedrockReranker(Reranker, ConcurrentStepMixin):
|
|
1145
|
+
"""Reranks documents using an AWS Bedrock model."""
|
|
1146
|
+
|
|
1147
|
+
type: Literal["BedrockReranker"] = "BedrockReranker"
|
|
1148
|
+
auth: Reference[AWSAuthProvider] | str | None = Field(
|
|
1149
|
+
default=None,
|
|
1150
|
+
description="AWS authorization provider for Bedrock access.",
|
|
1151
|
+
)
|
|
1152
|
+
model_id: str = Field(
|
|
1153
|
+
...,
|
|
1154
|
+
description="Bedrock model ID to use for reranking. See https://docs.aws.amazon.com/bedrock/latest/userguide/rerank-supported.html",
|
|
1155
|
+
)
|
|
1156
|
+
num_results: int | None = Field(
|
|
1157
|
+
default=None,
|
|
1158
|
+
description="Return this many results.",
|
|
1159
|
+
)
|
|
1108
1160
|
|
|
1109
1161
|
|
|
1110
1162
|
# Create a union type for all tool types
|
|
@@ -1146,6 +1198,7 @@ StepType = Annotated[
|
|
|
1146
1198
|
Union[
|
|
1147
1199
|
Agent,
|
|
1148
1200
|
Aggregate,
|
|
1201
|
+
BedrockReranker,
|
|
1149
1202
|
Decoder,
|
|
1150
1203
|
DocToTextConverter,
|
|
1151
1204
|
DocumentEmbedder,
|
|
@@ -7,7 +7,8 @@ concerns threaded through the execution pipeline.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
11
|
+
from dataclasses import dataclass, field
|
|
11
12
|
|
|
12
13
|
from opentelemetry.trace import Tracer
|
|
13
14
|
|
|
@@ -51,6 +52,9 @@ class ExecutorContext:
|
|
|
51
52
|
on_progress: Optional callback for progress updates during execution.
|
|
52
53
|
tracer: OpenTelemetry tracer for distributed tracing and observability.
|
|
53
54
|
Defaults to a no-op tracer if telemetry is not configured.
|
|
55
|
+
thread_pool: Shared thread pool for running synchronous operations
|
|
56
|
+
in async contexts. Defaults to a pool with 100 threads to support
|
|
57
|
+
high concurrency workloads without thread exhaustion.
|
|
54
58
|
|
|
55
59
|
Example:
|
|
56
60
|
```python
|
|
@@ -72,3 +76,16 @@ class ExecutorContext:
|
|
|
72
76
|
on_stream_event: StreamingCallback | None = None
|
|
73
77
|
on_progress: ProgressCallback | None = None
|
|
74
78
|
tracer: Tracer | None = None
|
|
79
|
+
thread_pool: ThreadPoolExecutor = field(
|
|
80
|
+
default_factory=lambda: ThreadPoolExecutor(max_workers=100)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def cleanup(self) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Clean up resources held by the context.
|
|
86
|
+
|
|
87
|
+
This should be called when the context is no longer needed to ensure
|
|
88
|
+
proper cleanup of the thread pool and any other resources.
|
|
89
|
+
"""
|
|
90
|
+
if self.thread_pool:
|
|
91
|
+
self.thread_pool.shutdown(wait=True)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from qtype.semantic.model import (
|
|
2
|
+
Agent,
|
|
3
|
+
Aggregate,
|
|
4
|
+
BedrockReranker,
|
|
5
|
+
Decoder,
|
|
6
|
+
DocToTextConverter,
|
|
7
|
+
DocumentEmbedder,
|
|
8
|
+
DocumentSearch,
|
|
9
|
+
DocumentSource,
|
|
10
|
+
DocumentSplitter,
|
|
11
|
+
Echo,
|
|
12
|
+
FieldExtractor,
|
|
13
|
+
FileSource,
|
|
14
|
+
FileWriter,
|
|
15
|
+
IndexUpsert,
|
|
16
|
+
InvokeEmbedding,
|
|
17
|
+
InvokeFlow,
|
|
18
|
+
InvokeTool,
|
|
19
|
+
LLMInference,
|
|
20
|
+
PromptTemplate,
|
|
21
|
+
SQLSource,
|
|
22
|
+
Step,
|
|
23
|
+
VectorSearch,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from .batch_step_executor import StepExecutor
|
|
27
|
+
from .executor_context import ExecutorContext
|
|
28
|
+
|
|
29
|
+
# Lazy-load executor classes only when needed
|
|
30
|
+
# This avoids importing heavy dependencies until actually required
|
|
31
|
+
EXECUTOR_REGISTRY = {
|
|
32
|
+
Agent: "qtype.interpreter.executors.agent_executor.AgentExecutor",
|
|
33
|
+
Aggregate: "qtype.interpreter.executors.aggregate_executor.AggregateExecutor",
|
|
34
|
+
BedrockReranker: "qtype.interpreter.executors.bedrock_reranker_executor.BedrockRerankerExecutor",
|
|
35
|
+
Decoder: "qtype.interpreter.executors.decoder_executor.DecoderExecutor",
|
|
36
|
+
DocToTextConverter: "qtype.interpreter.executors.doc_to_text_executor.DocToTextConverterExecutor",
|
|
37
|
+
DocumentEmbedder: "qtype.interpreter.executors.document_embedder_executor.DocumentEmbedderExecutor",
|
|
38
|
+
DocumentSearch: "qtype.interpreter.executors.document_search_executor.DocumentSearchExecutor",
|
|
39
|
+
DocumentSource: "qtype.interpreter.executors.document_source_executor.DocumentSourceExecutor",
|
|
40
|
+
DocumentSplitter: "qtype.interpreter.executors.document_splitter_executor.DocumentSplitterExecutor",
|
|
41
|
+
Echo: "qtype.interpreter.executors.echo_executor.EchoExecutor",
|
|
42
|
+
FieldExtractor: "qtype.interpreter.executors.field_extractor_executor.FieldExtractorExecutor",
|
|
43
|
+
FileSource: "qtype.interpreter.executors.file_source_executor.FileSourceExecutor",
|
|
44
|
+
FileWriter: "qtype.interpreter.executors.file_writer_executor.FileWriterExecutor",
|
|
45
|
+
IndexUpsert: "qtype.interpreter.executors.index_upsert_executor.IndexUpsertExecutor",
|
|
46
|
+
InvokeEmbedding: "qtype.interpreter.executors.invoke_embedding_executor.InvokeEmbeddingExecutor",
|
|
47
|
+
InvokeFlow: "qtype.interpreter.executors.invoke_flow_executor.InvokeFlowExecutor",
|
|
48
|
+
InvokeTool: "qtype.interpreter.executors.invoke_tool_executor.InvokeToolExecutor",
|
|
49
|
+
LLMInference: "qtype.interpreter.executors.llm_inference_executor.LLMInferenceExecutor",
|
|
50
|
+
PromptTemplate: "qtype.interpreter.executors.prompt_template_executor.PromptTemplateExecutor",
|
|
51
|
+
SQLSource: "qtype.interpreter.executors.sql_source_executor.SQLSourceExecutor",
|
|
52
|
+
VectorSearch: "qtype.interpreter.executors.vector_search_executor.VectorSearchExecutor",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def create_executor(
|
|
57
|
+
step: Step, context: ExecutorContext, **dependencies
|
|
58
|
+
) -> StepExecutor:
|
|
59
|
+
"""
|
|
60
|
+
Factory to create the appropriate executor for a given step.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
step: The step to create an executor for
|
|
64
|
+
context: ExecutorContext containing cross-cutting concerns
|
|
65
|
+
**dependencies: Executor-specific dependencies
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
StepExecutor: Configured executor instance
|
|
69
|
+
"""
|
|
70
|
+
executor_path = EXECUTOR_REGISTRY.get(type(step))
|
|
71
|
+
if not executor_path:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
f"No executor found for step type: {type(step).__name__}"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Lazy-load the executor class
|
|
77
|
+
module_path, class_name = executor_path.rsplit(".", 1)
|
|
78
|
+
import importlib
|
|
79
|
+
|
|
80
|
+
module = importlib.import_module(module_path)
|
|
81
|
+
executor_class = getattr(module, class_name)
|
|
82
|
+
|
|
83
|
+
# This assumes the constructor takes the step, context, then dependencies
|
|
84
|
+
return executor_class(step, context, **dependencies)
|
|
@@ -18,10 +18,15 @@ from llama_index.core.base.llms.types import (
|
|
|
18
18
|
from llama_index.core.memory import Memory as LlamaMemory
|
|
19
19
|
from llama_index.core.schema import Document as LlamaDocument
|
|
20
20
|
from llama_index.core.vector_stores.types import BasePydanticVectorStore
|
|
21
|
-
from opensearchpy import
|
|
21
|
+
from opensearchpy import AsyncOpenSearch, AWSV4SignerAuth
|
|
22
22
|
|
|
23
23
|
from qtype.base.types import PrimitiveTypeEnum
|
|
24
|
-
from qtype.dsl.domain_types import
|
|
24
|
+
from qtype.dsl.domain_types import (
|
|
25
|
+
ChatContent,
|
|
26
|
+
ChatMessage,
|
|
27
|
+
RAGDocument,
|
|
28
|
+
RAGSearchResult,
|
|
29
|
+
)
|
|
25
30
|
from qtype.dsl.model import Memory
|
|
26
31
|
from qtype.interpreter.auth.aws import aws
|
|
27
32
|
from qtype.interpreter.auth.generic import auth
|
|
@@ -328,7 +333,7 @@ def to_embedding_model(model: Model) -> BaseEmbedding:
|
|
|
328
333
|
@cached_resource
|
|
329
334
|
def to_opensearch_client(
|
|
330
335
|
index: DocumentIndex, secret_manager: SecretManagerBase
|
|
331
|
-
) ->
|
|
336
|
+
) -> AsyncOpenSearch:
|
|
332
337
|
"""
|
|
333
338
|
Convert a DocumentIndex to an OpenSearch/Elasticsearch client.
|
|
334
339
|
|
|
@@ -377,7 +382,7 @@ def to_opensearch_client(
|
|
|
377
382
|
f"Unsupported authentication type for DocumentIndex: {type(index.auth)}"
|
|
378
383
|
)
|
|
379
384
|
|
|
380
|
-
return
|
|
385
|
+
return AsyncOpenSearch(**client_kwargs)
|
|
381
386
|
|
|
382
387
|
|
|
383
388
|
def to_content_block(content: ChatContent) -> ContentBlock:
|
|
@@ -575,7 +580,7 @@ def to_llama_vector_store_and_retriever(
|
|
|
575
580
|
return vector_store, retriever
|
|
576
581
|
|
|
577
582
|
|
|
578
|
-
def from_node_with_score(node_with_score) ->
|
|
583
|
+
def from_node_with_score(node_with_score) -> RAGSearchResult:
|
|
579
584
|
"""Convert a LlamaIndex NodeWithScore to a RAGSearchResult.
|
|
580
585
|
|
|
581
586
|
Args:
|
|
@@ -603,4 +608,8 @@ def from_node_with_score(node_with_score) -> Any:
|
|
|
603
608
|
)
|
|
604
609
|
|
|
605
610
|
# Wrap in RAGSearchResult with score
|
|
606
|
-
return RAGSearchResult(
|
|
611
|
+
return RAGSearchResult(
|
|
612
|
+
content=chunk,
|
|
613
|
+
doc_id=chunk.document_id,
|
|
614
|
+
score=node_with_score.score or 0.0,
|
|
615
|
+
)
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from collections.abc import AsyncIterator
|
|
6
|
+
from typing import Any, cast
|
|
7
|
+
|
|
5
8
|
import pandas as pd
|
|
6
9
|
from pydantic import BaseModel
|
|
7
10
|
|
|
@@ -9,11 +12,11 @@ from qtype.interpreter.types import FlowMessage, Session
|
|
|
9
12
|
from qtype.semantic.model import Flow
|
|
10
13
|
|
|
11
14
|
|
|
12
|
-
def dataframe_to_flow_messages(
|
|
15
|
+
async def dataframe_to_flow_messages(
|
|
13
16
|
df: pd.DataFrame, session: Session
|
|
14
|
-
) ->
|
|
17
|
+
) -> AsyncIterator[FlowMessage]:
|
|
15
18
|
"""
|
|
16
|
-
Convert a DataFrame to
|
|
19
|
+
Convert a DataFrame to an async generator of FlowMessages.
|
|
17
20
|
|
|
18
21
|
Each row in the DataFrame becomes a FlowMessage with the same session.
|
|
19
22
|
|
|
@@ -21,14 +24,15 @@ def dataframe_to_flow_messages(
|
|
|
21
24
|
df: DataFrame where each row represents one set of inputs
|
|
22
25
|
session: Session object to use for all messages
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
Yields:
|
|
28
|
+
FlowMessages, one per DataFrame row
|
|
26
29
|
"""
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
# Use to_dict with orient='records' - much faster than iterrows
|
|
31
|
+
# This returns a list of dicts directly without Series overhead
|
|
32
|
+
records = cast(list[dict[str, Any]], df.to_dict(orient="records"))
|
|
33
|
+
|
|
34
|
+
for record in records:
|
|
35
|
+
yield FlowMessage(session=session, variables=record)
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
def flow_messages_to_dataframe(
|
|
@@ -46,8 +50,6 @@ def flow_messages_to_dataframe(
|
|
|
46
50
|
Returns:
|
|
47
51
|
DataFrame with one row per message, columns for each output variable
|
|
48
52
|
"""
|
|
49
|
-
from typing import Any
|
|
50
|
-
|
|
51
53
|
results = []
|
|
52
54
|
for idx, message in enumerate(messages):
|
|
53
55
|
row_data: dict[str, Any] = {"row": idx}
|