qtype 0.1.3__py3-none-any.whl → 0.1.7__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.
- qtype/dsl/model.py +2 -1
- qtype/dsl/parser.py +3 -3
- qtype/interpreter/conversions.py +25 -3
- qtype/interpreter/executors/document_embedder_executor.py +18 -2
- qtype/interpreter/executors/invoke_embedding_executor.py +36 -24
- qtype/interpreter/flow.py +1 -2
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/METADATA +2 -2
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/RECORD +12 -12
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/WHEEL +0 -0
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/entry_points.txt +0 -0
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/licenses/LICENSE +0 -0
- {qtype-0.1.3.dist-info → qtype-0.1.7.dist-info}/top_level.txt +0 -0
qtype/dsl/model.py
CHANGED
|
@@ -765,8 +765,9 @@ class AWSAuthProvider(AuthorizationProvider):
|
|
|
765
765
|
has_keys = self.access_key_id and self.secret_access_key
|
|
766
766
|
has_profile = self.profile_name
|
|
767
767
|
has_role = self.role_arn
|
|
768
|
+
has_region = self.region
|
|
768
769
|
|
|
769
|
-
if not (has_keys or has_profile or has_role):
|
|
770
|
+
if not (has_keys or has_profile or has_role or has_region):
|
|
770
771
|
raise ValueError(
|
|
771
772
|
"AWSAuthProvider must specify at least one authentication method: "
|
|
772
773
|
"access keys, profile name, or role ARN."
|
qtype/dsl/parser.py
CHANGED
|
@@ -153,12 +153,12 @@ def _format_validation_errors(
|
|
|
153
153
|
error_msg = "Validation failed (see details above)"
|
|
154
154
|
else:
|
|
155
155
|
error_msg = "Validation failed:\n"
|
|
156
|
-
for error in relevant_errors[:
|
|
156
|
+
for error in relevant_errors[:30]: # Show max 5 errors
|
|
157
157
|
loc_path = _simplify_field_path(error["loc"])
|
|
158
158
|
error_msg += f" {loc_path}: {error['msg']}\n"
|
|
159
159
|
|
|
160
|
-
if len(relevant_errors) >
|
|
161
|
-
error_msg += f" ... and {len(relevant_errors) -
|
|
160
|
+
if len(relevant_errors) > 30:
|
|
161
|
+
error_msg += f" ... and {len(relevant_errors) - 30} more errors\n"
|
|
162
162
|
|
|
163
163
|
if source_name:
|
|
164
164
|
error_msg = f"In {source_name}:\n{error_msg}"
|
qtype/interpreter/conversions.py
CHANGED
|
@@ -34,6 +34,7 @@ from qtype.interpreter.base.secrets import SecretManagerBase
|
|
|
34
34
|
from qtype.interpreter.types import InterpreterError
|
|
35
35
|
from qtype.semantic.model import (
|
|
36
36
|
APIKeyAuthProvider,
|
|
37
|
+
AWSAuthProvider,
|
|
37
38
|
DocumentIndex,
|
|
38
39
|
DocumentSplitter,
|
|
39
40
|
Model,
|
|
@@ -302,7 +303,9 @@ def to_vector_store(
|
|
|
302
303
|
|
|
303
304
|
|
|
304
305
|
@cached_resource
|
|
305
|
-
def to_embedding_model(
|
|
306
|
+
def to_embedding_model(
|
|
307
|
+
model: Model, secret_manager: SecretManagerBase
|
|
308
|
+
) -> BaseEmbedding:
|
|
306
309
|
"""Convert a qtype Model to a LlamaIndex embedding model."""
|
|
307
310
|
|
|
308
311
|
if model.provider == "aws-bedrock":
|
|
@@ -310,7 +313,14 @@ def to_embedding_model(model: Model) -> BaseEmbedding:
|
|
|
310
313
|
BedrockEmbedding,
|
|
311
314
|
)
|
|
312
315
|
|
|
316
|
+
session = None
|
|
317
|
+
if model.auth is not None:
|
|
318
|
+
assert isinstance(model.auth, AWSAuthProvider)
|
|
319
|
+
with aws(model.auth, secret_manager) as session:
|
|
320
|
+
session = session._session
|
|
321
|
+
|
|
313
322
|
bedrock_embedding: BaseEmbedding = BedrockEmbedding(
|
|
323
|
+
botocore_session=session,
|
|
314
324
|
model_name=model.model_id if model.model_id else model.id,
|
|
315
325
|
max_retries=100,
|
|
316
326
|
)
|
|
@@ -320,8 +330,20 @@ def to_embedding_model(model: Model) -> BaseEmbedding:
|
|
|
320
330
|
OpenAIEmbedding,
|
|
321
331
|
)
|
|
322
332
|
|
|
333
|
+
api_key = None
|
|
334
|
+
if model.auth:
|
|
335
|
+
with auth(model.auth, secret_manager) as provider:
|
|
336
|
+
if not isinstance(provider, APIKeyAuthProvider):
|
|
337
|
+
raise InterpreterError(
|
|
338
|
+
f"OpenAI provider requires APIKeyAuthProvider, "
|
|
339
|
+
f"got {type(provider).__name__}"
|
|
340
|
+
)
|
|
341
|
+
# api_key is guaranteed to be str after auth() resolves it
|
|
342
|
+
api_key = provider.api_key # type: ignore[assignment]
|
|
343
|
+
|
|
323
344
|
openai_embedding: BaseEmbedding = OpenAIEmbedding(
|
|
324
|
-
|
|
345
|
+
api_key=api_key,
|
|
346
|
+
model_name=model.model_id if model.model_id else model.id,
|
|
325
347
|
)
|
|
326
348
|
return openai_embedding
|
|
327
349
|
else:
|
|
@@ -566,7 +588,7 @@ def to_llama_vector_store_and_retriever(
|
|
|
566
588
|
vector_store = to_vector_store(index, secret_manager)
|
|
567
589
|
|
|
568
590
|
# Get the embedding model
|
|
569
|
-
embedding_model = to_embedding_model(index.embedding_model)
|
|
591
|
+
embedding_model = to_embedding_model(index.embedding_model, secret_manager)
|
|
570
592
|
|
|
571
593
|
# Create a VectorStoreIndex with the vector store and embedding model
|
|
572
594
|
vector_index = VectorStoreIndex.from_vector_store(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
1
3
|
from typing import AsyncIterator
|
|
2
4
|
|
|
3
5
|
from botocore.exceptions import ClientError
|
|
@@ -41,7 +43,7 @@ class DocumentEmbedderExecutor(StepExecutor):
|
|
|
41
43
|
self.step: DocumentEmbedder = step
|
|
42
44
|
# Initialize the embedding model once for the executor
|
|
43
45
|
self.embedding_model: BaseEmbedding = to_embedding_model(
|
|
44
|
-
self.step.model
|
|
46
|
+
self.step.model, context.secret_manager
|
|
45
47
|
)
|
|
46
48
|
|
|
47
49
|
# TODO: properly abstract this into a mixin
|
|
@@ -58,7 +60,17 @@ class DocumentEmbedderExecutor(StepExecutor):
|
|
|
58
60
|
Returns:
|
|
59
61
|
The embedding vector as a list of floats.
|
|
60
62
|
"""
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
# TODO: switch back to async once aws auth supports it.
|
|
65
|
+
# https://github.com/bazaarvoice/qtype/issues/108
|
|
66
|
+
def _call():
|
|
67
|
+
return self.embedding_model.get_text_embedding(text=text)
|
|
68
|
+
|
|
69
|
+
loop = asyncio.get_running_loop()
|
|
70
|
+
response = await loop.run_in_executor(self.context.thread_pool, _call)
|
|
71
|
+
|
|
72
|
+
return response
|
|
73
|
+
# return await self.embedding_model.aget_text_embedding(text=text)
|
|
62
74
|
|
|
63
75
|
async def process_message(
|
|
64
76
|
self,
|
|
@@ -103,5 +115,9 @@ class DocumentEmbedderExecutor(StepExecutor):
|
|
|
103
115
|
except Exception as e:
|
|
104
116
|
# Emit error event to stream so frontend can display it
|
|
105
117
|
await self.stream_emitter.error(str(e))
|
|
118
|
+
logging.error(
|
|
119
|
+
f"Error processing DocumentEmbedder step {self.step.id}",
|
|
120
|
+
exc_info=e,
|
|
121
|
+
)
|
|
106
122
|
message.set_error(self.step.id, e)
|
|
107
123
|
yield message
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
from typing import AsyncIterator
|
|
2
3
|
|
|
3
4
|
from openinference.semconv.trace import OpenInferenceSpanKindValues
|
|
@@ -30,7 +31,9 @@ class InvokeEmbeddingExecutor(StepExecutor):
|
|
|
30
31
|
)
|
|
31
32
|
self.step: InvokeEmbedding = step
|
|
32
33
|
# Initialize the embedding model once for the executor
|
|
33
|
-
self.embedding_model = to_embedding_model(
|
|
34
|
+
self.embedding_model = to_embedding_model(
|
|
35
|
+
self.step.model, context.secret_manager
|
|
36
|
+
)
|
|
34
37
|
|
|
35
38
|
async def process_message(
|
|
36
39
|
self,
|
|
@@ -54,32 +57,41 @@ class InvokeEmbeddingExecutor(StepExecutor):
|
|
|
54
57
|
if input_value is None:
|
|
55
58
|
raise ValueError(f"Input variable '{input_id}' is missing")
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
content = input_value
|
|
71
|
-
else:
|
|
72
|
-
raise ValueError(
|
|
73
|
-
(
|
|
74
|
-
f"Unsupported input type for embedding: "
|
|
75
|
-
f"{input_type}. Must be 'text' or 'image'."
|
|
60
|
+
def _call(input_value=input_value):
|
|
61
|
+
# Generate embedding based on input type
|
|
62
|
+
if input_type == PrimitiveTypeEnum.text:
|
|
63
|
+
if not isinstance(input_value, str):
|
|
64
|
+
input_value = str(input_value)
|
|
65
|
+
vector = self.embedding_model.get_text_embedding(
|
|
66
|
+
text=input_value
|
|
67
|
+
)
|
|
68
|
+
content = input_value
|
|
69
|
+
elif input_type == PrimitiveTypeEnum.image:
|
|
70
|
+
# For image embeddings
|
|
71
|
+
vector = self.embedding_model.get_image_embedding(
|
|
72
|
+
image_path=input_value
|
|
76
73
|
)
|
|
74
|
+
content = input_value
|
|
75
|
+
else:
|
|
76
|
+
raise ValueError(
|
|
77
|
+
(
|
|
78
|
+
f"Unsupported input type for embedding: "
|
|
79
|
+
f"{input_type}. Must be 'text' or 'image'."
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Create the Embedding object
|
|
84
|
+
embedding = Embedding(
|
|
85
|
+
vector=vector,
|
|
86
|
+
content=content,
|
|
77
87
|
)
|
|
88
|
+
return embedding
|
|
78
89
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
# TODO: switch back to async once aws auth supports it.
|
|
91
|
+
# https://github.com/bazaarvoice/qtype/issues/108
|
|
92
|
+
loop = asyncio.get_running_loop()
|
|
93
|
+
embedding = await loop.run_in_executor(
|
|
94
|
+
self.context.thread_pool, _call
|
|
83
95
|
)
|
|
84
96
|
|
|
85
97
|
# Yield the result
|
qtype/interpreter/flow.py
CHANGED
|
@@ -12,13 +12,12 @@ from opentelemetry import context as otel_context
|
|
|
12
12
|
from opentelemetry import trace
|
|
13
13
|
from opentelemetry.trace import Status, StatusCode
|
|
14
14
|
from rich.console import Console
|
|
15
|
-
from transformers import ProgressCallback
|
|
16
15
|
|
|
17
16
|
from qtype.interpreter.base import factory
|
|
18
17
|
from qtype.interpreter.base.executor_context import ExecutorContext
|
|
19
18
|
from qtype.interpreter.logging_progress import LoggingProgressCallback
|
|
20
19
|
from qtype.interpreter.rich_progress import RichProgressCallback
|
|
21
|
-
from qtype.interpreter.types import FlowMessage
|
|
20
|
+
from qtype.interpreter.types import FlowMessage, ProgressCallback
|
|
22
21
|
from qtype.semantic.model import Flow
|
|
23
22
|
|
|
24
23
|
logger = logging.getLogger(__name__)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qtype
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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
|
|
@@ -9,7 +9,7 @@ Requires-Python: >=3.10
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
Requires-Dist: jsonschema>=4.24.0
|
|
12
|
-
Requires-Dist: pydantic>=2.
|
|
12
|
+
Requires-Dist: pydantic>=2.12.4
|
|
13
13
|
Requires-Dist: pyyaml>=6.0.2
|
|
14
14
|
Requires-Dist: python-dotenv>=1.0.0
|
|
15
15
|
Requires-Dist: openai>=1.93.0
|
|
@@ -25,15 +25,15 @@ qtype/dsl/custom_types.py,sha256=N3qswimv0foH40YDubHaTZ3HYF9RUbZ2x5eQ4i798Ko,290
|
|
|
25
25
|
qtype/dsl/domain_types.py,sha256=-pX74DKwrRanoXBxYqAdN_f44ike6ssRV3tZ20R2PhQ,4319
|
|
26
26
|
qtype/dsl/linker.py,sha256=c7PPTULy7_z_9u_qeseIaomR_B8kBa9YzOhQpjeGaSM,12975
|
|
27
27
|
qtype/dsl/loader.py,sha256=mht0BqfmyTNHIEDaF3iTEmYQLJBP5GIZULwexxw9Dpg,9771
|
|
28
|
-
qtype/dsl/model.py,sha256=
|
|
29
|
-
qtype/dsl/parser.py,sha256=
|
|
28
|
+
qtype/dsl/model.py,sha256=g3cZ4-vh_WxrjJ1ev6kFfQcX2-NOZHb70ZT-7m-nHHY,40907
|
|
29
|
+
qtype/dsl/parser.py,sha256=Ww32bLQ2vGOObsA-vWjaMh4TOKRwEA7FAt9U6wjKZkw,5490
|
|
30
30
|
qtype/dsl/types.py,sha256=k6cgThA287bZ_pvTKQvxWhatcYCPNne8zpqOYOvLvOg,1687
|
|
31
31
|
qtype/interpreter/__init__.py,sha256=IaRF90JLFbsTLKz9LTOMI_Pz4xwVaEyXPNaXV7sLou8,43
|
|
32
32
|
qtype/interpreter/api.py,sha256=V7hjsmDhe1IwbcwdM5bnPGBiwH3TtlMLjUJdGJumCdA,4193
|
|
33
|
-
qtype/interpreter/conversions.py,sha256=
|
|
33
|
+
qtype/interpreter/conversions.py,sha256=VKRJm5ofM3tWzXKg_zLTvKzi7GNBDv6MiE4HnQ52eFY,21871
|
|
34
34
|
qtype/interpreter/converters.py,sha256=gWyfizl7d-DT6jJ2aOrneUcZcwB-LdMDEvl-VT0-mLQ,2348
|
|
35
35
|
qtype/interpreter/endpoints.py,sha256=un4iCYCk86lYKpTDFdzlByvebdctNwRF3n4oD4ZwpTw,11946
|
|
36
|
-
qtype/interpreter/flow.py,sha256=
|
|
36
|
+
qtype/interpreter/flow.py,sha256=rncholeAv7gn3Pr99N9mIA5oFY4OMHVQX6IJljtVO34,6566
|
|
37
37
|
qtype/interpreter/logging_progress.py,sha256=RmyNXdbpPZ7ye8cbSab0Tw10x3T38U3S8rj2bOTfbso,1848
|
|
38
38
|
qtype/interpreter/metadata_api.py,sha256=LfJjt9atsgiAra6aVBXLoJrPa06_CBUagYysT556nt8,3267
|
|
39
39
|
qtype/interpreter/resource_cache.py,sha256=K0kzpm223COWk7FN9qyOvNOEoOcABR4yLeADL9ekE_o,1188
|
|
@@ -59,7 +59,7 @@ qtype/interpreter/executors/aggregate_executor.py,sha256=Z3NJekpeo7aqqvOcXQqb6d6
|
|
|
59
59
|
qtype/interpreter/executors/bedrock_reranker_executor.py,sha256=p25BMmM1paAlK2vfpwJ9T5st_2B-bmZoDnVFp9ynZIY,7154
|
|
60
60
|
qtype/interpreter/executors/decoder_executor.py,sha256=KqLhnhiclMIcUNf3bu7H4vDAOXCQeVO0rc2hIXm1qZ4,5610
|
|
61
61
|
qtype/interpreter/executors/doc_to_text_executor.py,sha256=ZkTtKUL0BfNIiuj-OcYybn1f0By6ujRmd1U4VEAtJt4,3804
|
|
62
|
-
qtype/interpreter/executors/document_embedder_executor.py,sha256=
|
|
62
|
+
qtype/interpreter/executors/document_embedder_executor.py,sha256=dBx1yfjzGPAOAfCx0zr1uOkfs7JUWgHoKYanqnCFAQk,4089
|
|
63
63
|
qtype/interpreter/executors/document_search_executor.py,sha256=ZmKAt__jC5cxZY0gSm9AgpC6n7MFavTHE01tQED3zFk,4051
|
|
64
64
|
qtype/interpreter/executors/document_source_executor.py,sha256=ZpBrBaE16YeRk750TxvE08NnCIUzArjESZImESomaIo,4247
|
|
65
65
|
qtype/interpreter/executors/document_splitter_executor.py,sha256=00x32yo1wGUvW88_lUahfGU94prUPGaOTk5GBUJbBJA,3882
|
|
@@ -68,7 +68,7 @@ qtype/interpreter/executors/field_extractor_executor.py,sha256=geDmT6GyvbDDJvPX1
|
|
|
68
68
|
qtype/interpreter/executors/file_source_executor.py,sha256=OUT_zJrYN3iFMUgLECde93C4rv8PthcQsuJ--CJvEsI,3605
|
|
69
69
|
qtype/interpreter/executors/file_writer_executor.py,sha256=x4BpgdXM7Xhz1tJJ5MmBIjFO4y80VC1V1ow3tox_Xrw,4099
|
|
70
70
|
qtype/interpreter/executors/index_upsert_executor.py,sha256=5MxG3GX2bbjX6jhCpCdEZ0YFJOshn649cfaOT50PLCA,8518
|
|
71
|
-
qtype/interpreter/executors/invoke_embedding_executor.py,sha256=
|
|
71
|
+
qtype/interpreter/executors/invoke_embedding_executor.py,sha256=5iXh2elP51gdnuUvRDH_RuWugsm3KCJb8S15Oy4p8zg,3834
|
|
72
72
|
qtype/interpreter/executors/invoke_flow_executor.py,sha256=U30cYM3F_zy1_2CD1Dde59xyZD0rDa5W46lST1hxF6s,1682
|
|
73
73
|
qtype/interpreter/executors/invoke_tool_executor.py,sha256=hhbE8YTr0x5-kz_xsvdWGGzkLkVdvDoAVAF-3ZUK5as,12786
|
|
74
74
|
qtype/interpreter/executors/llm_inference_executor.py,sha256=A6b_Ns_734TCn_DMhdNSqWc5qX970FryhpsX_jtEu_4,9593
|
|
@@ -129,9 +129,9 @@ qtype/semantic/loader.py,sha256=QRhTc_AJfsWSMn8ThaW60GmIGjFMN-3bBUy4pktFjz4,3041
|
|
|
129
129
|
qtype/semantic/model.py,sha256=7yZ-Ufuo-gNJbhFXALuKZxILdhNB5zbL3a3oQQARI8g,28602
|
|
130
130
|
qtype/semantic/resolver.py,sha256=bWPCSB8KJpVqN_n41U_r-qzUiT8vAMBOD3pOGmxL6TY,4618
|
|
131
131
|
qtype/semantic/visualize.py,sha256=thjrZcfQuZJWrZ9EMAPhAa2kNikR5rLIJrfcD3hJ8XY,17426
|
|
132
|
-
qtype-0.1.
|
|
133
|
-
qtype-0.1.
|
|
134
|
-
qtype-0.1.
|
|
135
|
-
qtype-0.1.
|
|
136
|
-
qtype-0.1.
|
|
137
|
-
qtype-0.1.
|
|
132
|
+
qtype-0.1.7.dist-info/licenses/LICENSE,sha256=1KA5EgYBSR0O6nCH2HEvk6Di53YKJ9r_VCR7G8G8qAY,11341
|
|
133
|
+
qtype-0.1.7.dist-info/METADATA,sha256=N-2oIlfAJKDpgwT1XjZOKsH70kSUy6mSUSDR6j7ME0c,5657
|
|
134
|
+
qtype-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
135
|
+
qtype-0.1.7.dist-info/entry_points.txt,sha256=5y4vj8RLvgl2tXSj-Hm7v5-Tn3kP4-UonjNoN-mfaQE,41
|
|
136
|
+
qtype-0.1.7.dist-info/top_level.txt,sha256=ONroH5B0mZ51jr7NSWCK0weFwwCO7wBLmyVS1YqNU14,6
|
|
137
|
+
qtype-0.1.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|