qtype 0.1.11__py3-none-any.whl → 0.1.13__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/` +0 -0
- qtype/application/__init__.py +0 -2
- qtype/application/converters/tools_from_api.py +67 -57
- qtype/application/converters/tools_from_module.py +66 -32
- qtype/base/types.py +6 -1
- qtype/commands/convert.py +3 -6
- qtype/commands/generate.py +97 -10
- qtype/commands/mcp.py +68 -0
- qtype/commands/run.py +116 -44
- qtype/commands/validate.py +4 -4
- qtype/docs/.pages +8 -0
- qtype/docs/Concepts/mental-model-and-philosophy.md +363 -0
- qtype/docs/Contributing/.pages +4 -0
- qtype/docs/Contributing/index.md +283 -0
- qtype/docs/Contributing/roadmap.md +81 -0
- qtype/docs/Decisions/ADR-001-Chat-vs-Completion-Endpoint-Features.md +56 -0
- qtype/docs/Gallery/dataflow_pipelines.md +81 -0
- qtype/docs/Gallery/dataflow_pipelines.mermaid +45 -0
- qtype/docs/Gallery/research_assistant.md +97 -0
- qtype/docs/Gallery/research_assistant.mermaid +42 -0
- qtype/docs/Gallery/simple_chatbot.md +38 -0
- qtype/docs/Gallery/simple_chatbot.mermaid +35 -0
- qtype/docs/How To/Authentication/configure_aws_authentication.md +60 -0
- qtype/docs/How To/Authentication/use_api_key_authentication.md +40 -0
- qtype/docs/How To/Command Line Usage/load_multiple_inputs_from_files.md +77 -0
- qtype/docs/How To/Command Line Usage/pass_inputs_on_the_cli.md +52 -0
- qtype/docs/How To/Command Line Usage/serve_with_auto_reload.md +27 -0
- qtype/docs/How To/Data Processing/adjust_concurrency.md +40 -0
- qtype/docs/How To/Data Processing/cache_step_results.md +71 -0
- qtype/docs/How To/Data Processing/decode_json_xml.md +24 -0
- qtype/docs/How To/Data Processing/explode_collections.md +40 -0
- qtype/docs/How To/Data Processing/gather_results.md +68 -0
- qtype/docs/How To/Data Processing/invoke_other_flows.md +71 -0
- qtype/docs/How To/Data Processing/load_data_from_athena.md +49 -0
- qtype/docs/How To/Data Processing/read_data_from_files.md +61 -0
- qtype/docs/How To/Data Processing/read_sql_databases.md +46 -0
- qtype/docs/How To/Data Processing/write_data_to_file.md +39 -0
- qtype/docs/How To/Invoke Models/call_large_language_models.md +51 -0
- qtype/docs/How To/Invoke Models/create_embeddings.md +49 -0
- qtype/docs/How To/Invoke Models/reuse_prompts_with_templates.md +38 -0
- qtype/docs/How To/Language Features/include_qtype_yaml.md +45 -0
- qtype/docs/How To/Language Features/include_raw_text_from_other_files.md +48 -0
- qtype/docs/How To/Language Features/reference_entities_by_id.md +51 -0
- qtype/docs/How To/Language Features/use_agent_skills.md +29 -0
- qtype/docs/How To/Language Features/use_environment_variables.md +48 -0
- qtype/docs/How To/Language Features/use_optional_variables.md +42 -0
- qtype/docs/How To/Language Features/use_qtype_mcp.md +59 -0
- qtype/docs/How To/Observability & Debugging/trace_calls_with_open_telemetry.md +49 -0
- qtype/docs/How To/Observability & Debugging/validate_qtype_yaml.md +36 -0
- qtype/docs/How To/Observability & Debugging/visualize_application_architecture.md +61 -0
- qtype/docs/How To/Observability & Debugging/visualize_example.mermaid +35 -0
- qtype/docs/How To/Qtype Server/flow_as_ui.png +0 -0
- qtype/docs/How To/Qtype Server/serve_flows_as_apis.md +40 -0
- qtype/docs/How To/Qtype Server/serve_flows_as_ui.md +41 -0
- qtype/docs/How To/Qtype Server/use_conversational_interfaces.md +56 -0
- qtype/docs/How To/Qtype Server/use_variables_with_ui_hints.md +48 -0
- qtype/docs/How To/Tools & Integration/bind_tool_inputs_and_outputs.md +47 -0
- qtype/docs/How To/Tools & Integration/create_tools_from_openapi_specifications.md +85 -0
- qtype/docs/How To/Tools & Integration/create_tools_from_python_modules.md +87 -0
- qtype/docs/Reference/cli.md +336 -0
- qtype/docs/Reference/plugins.md +99 -0
- qtype/docs/Reference/semantic-validation-rules.md +184 -0
- qtype/docs/Tutorials/.pages +1 -0
- qtype/docs/Tutorials/01-first-qtype-application.md +249 -0
- qtype/docs/Tutorials/02-conversational-chatbot.md +327 -0
- qtype/docs/Tutorials/03-structured-data.md +480 -0
- qtype/docs/Tutorials/04-tools-and-function-calling.md +476 -0
- qtype/docs/Tutorials/example_chat.png +0 -0
- qtype/docs/Tutorials/index.md +92 -0
- qtype/docs/components/APIKeyAuthProvider.md +7 -0
- qtype/docs/components/APITool.md +10 -0
- qtype/docs/components/AWSAuthProvider.md +13 -0
- qtype/docs/components/AWSSecretManager.md +5 -0
- qtype/docs/components/Agent.md +6 -0
- qtype/docs/components/Aggregate.md +7 -0
- qtype/docs/components/AggregateStats.md +7 -0
- qtype/docs/components/Application.md +22 -0
- qtype/docs/components/AuthorizationProvider.md +6 -0
- qtype/docs/components/AuthorizationProviderList.md +5 -0
- qtype/docs/components/BearerTokenAuthProvider.md +6 -0
- qtype/docs/components/BedrockReranker.md +8 -0
- qtype/docs/components/ChatContent.md +7 -0
- qtype/docs/components/ChatMessage.md +6 -0
- qtype/docs/components/Collect.md +6 -0
- qtype/docs/components/ConstantPath.md +5 -0
- qtype/docs/components/Construct.md +6 -0
- qtype/docs/components/CustomType.md +7 -0
- qtype/docs/components/Decoder.md +8 -0
- qtype/docs/components/DecoderFormat.md +8 -0
- qtype/docs/components/DocToTextConverter.md +7 -0
- qtype/docs/components/Document.md +7 -0
- qtype/docs/components/DocumentEmbedder.md +6 -0
- qtype/docs/components/DocumentIndex.md +7 -0
- qtype/docs/components/DocumentSearch.md +7 -0
- qtype/docs/components/DocumentSource.md +12 -0
- qtype/docs/components/DocumentSplitter.md +9 -0
- qtype/docs/components/Echo.md +8 -0
- qtype/docs/components/Embedding.md +7 -0
- qtype/docs/components/EmbeddingModel.md +6 -0
- qtype/docs/components/Explode.md +5 -0
- qtype/docs/components/FieldExtractor.md +21 -0
- qtype/docs/components/FileSource.md +6 -0
- qtype/docs/components/FileWriter.md +7 -0
- qtype/docs/components/Flow.md +14 -0
- qtype/docs/components/FlowInterface.md +7 -0
- qtype/docs/components/Index.md +8 -0
- qtype/docs/components/IndexUpsert.md +6 -0
- qtype/docs/components/InvokeEmbedding.md +7 -0
- qtype/docs/components/InvokeFlow.md +8 -0
- qtype/docs/components/InvokeTool.md +8 -0
- qtype/docs/components/LLMInference.md +9 -0
- qtype/docs/components/ListType.md +5 -0
- qtype/docs/components/Memory.md +8 -0
- qtype/docs/components/MessageRole.md +14 -0
- qtype/docs/components/Model.md +10 -0
- qtype/docs/components/ModelList.md +5 -0
- qtype/docs/components/OAuth2AuthProvider.md +9 -0
- qtype/docs/components/PrimitiveTypeEnum.md +20 -0
- qtype/docs/components/PromptTemplate.md +7 -0
- qtype/docs/components/PythonFunctionTool.md +7 -0
- qtype/docs/components/RAGChunk.md +7 -0
- qtype/docs/components/RAGDocument.md +10 -0
- qtype/docs/components/RAGSearchResult.md +8 -0
- qtype/docs/components/Reranker.md +5 -0
- qtype/docs/components/SQLSource.md +8 -0
- qtype/docs/components/Search.md +7 -0
- qtype/docs/components/SearchResult.md +7 -0
- qtype/docs/components/SecretManager.md +7 -0
- qtype/docs/components/SecretReference.md +7 -0
- qtype/docs/components/Source.md +5 -0
- qtype/docs/components/Step.md +8 -0
- qtype/docs/components/TelemetrySink.md +9 -0
- qtype/docs/components/Tool.md +9 -0
- qtype/docs/components/ToolList.md +5 -0
- qtype/docs/components/TypeList.md +5 -0
- qtype/docs/components/Variable.md +8 -0
- qtype/docs/components/VariableList.md +5 -0
- qtype/docs/components/VectorIndex.md +7 -0
- qtype/docs/components/VectorSearch.md +6 -0
- qtype/docs/components/VertexAuthProvider.md +9 -0
- qtype/docs/components/Writer.md +5 -0
- qtype/docs/example_ui.png +0 -0
- qtype/docs/index.md +81 -0
- qtype/docs/legacy_how_tos/.pages +6 -0
- qtype/docs/legacy_how_tos/Configuration/modular-yaml.md +366 -0
- qtype/docs/legacy_how_tos/Configuration/phoenix_projects.png +0 -0
- qtype/docs/legacy_how_tos/Configuration/phoenix_traces.png +0 -0
- qtype/docs/legacy_how_tos/Configuration/reference-by-id.md +251 -0
- qtype/docs/legacy_how_tos/Configuration/telemetry-setup.md +259 -0
- qtype/docs/legacy_how_tos/Data Types/custom-types.md +52 -0
- qtype/docs/legacy_how_tos/Data Types/domain-types.md +113 -0
- qtype/docs/legacy_how_tos/Debugging/visualize-apps.md +147 -0
- qtype/docs/legacy_how_tos/Tools/api-tools.md +29 -0
- qtype/docs/legacy_how_tos/Tools/python-tools.md +299 -0
- qtype/docs/skills/architect/SKILL.md +188 -0
- qtype/docs/skills/architect/references/cheatsheet.md +198 -0
- qtype/docs/skills/architect/references/patterns.md +29 -0
- qtype/docs/stylesheets/extra.css +27 -0
- qtype/dsl/custom_types.py +2 -1
- qtype/dsl/linker.py +23 -7
- qtype/dsl/loader.py +3 -3
- qtype/dsl/model.py +181 -67
- qtype/examples/authentication/aws_authentication.qtype.yaml +63 -0
- qtype/examples/conversational_ai/hello_world_chat.qtype.yaml +43 -0
- qtype/examples/conversational_ai/simple_chatbot.qtype.yaml +40 -0
- qtype/examples/data_processing/athena_query.qtype.yaml +56 -0
- qtype/examples/data_processing/batch_inputs.csv +5 -0
- qtype/examples/data_processing/batch_processing.qtype.yaml +54 -0
- qtype/examples/data_processing/cache_step_results.qtype.yaml +78 -0
- qtype/examples/data_processing/collect_results.qtype.yaml +55 -0
- qtype/examples/data_processing/create_sample_db.py +129 -0
- qtype/examples/data_processing/dataflow_pipelines.qtype.yaml +108 -0
- qtype/examples/data_processing/decode_json.qtype.yaml +23 -0
- qtype/examples/data_processing/explode_items.qtype.yaml +25 -0
- qtype/examples/data_processing/invoke_other_flows.qtype.yaml +98 -0
- qtype/examples/data_processing/read_file.qtype.yaml +60 -0
- qtype/examples/data_processing/reviews.db +0 -0
- qtype/examples/data_processing/sample_article.txt +1 -0
- qtype/examples/data_processing/sample_documents.jsonl +5 -0
- qtype/examples/invoke_models/create_embeddings.qtype.yaml +28 -0
- qtype/examples/invoke_models/simple_llm_call.qtype.yaml +32 -0
- qtype/examples/language_features/include_raw.qtype.yaml +27 -0
- qtype/examples/language_features/optional_variables.qtype.yaml +32 -0
- qtype/examples/language_features/story_prompt.txt +6 -0
- qtype/examples/language_features/ui_hints.qtype.yaml +52 -0
- qtype/examples/legacy/bedrock/data_analysis_with_telemetry.qtype.yaml +169 -0
- qtype/examples/legacy/bedrock/hello_world.qtype.yaml +39 -0
- qtype/examples/legacy/bedrock/hello_world_chat.qtype.yaml +37 -0
- qtype/examples/legacy/bedrock/hello_world_chat_with_telemetry.qtype.yaml +40 -0
- qtype/examples/legacy/bedrock/hello_world_chat_with_thinking.qtype.yaml +40 -0
- qtype/examples/legacy/bedrock/hello_world_completion.qtype.yaml +41 -0
- qtype/examples/legacy/bedrock/hello_world_completion_with_auth.qtype.yaml +44 -0
- qtype/examples/legacy/bedrock/simple_agent_chat.qtype.yaml +46 -0
- qtype/examples/legacy/chat_with_langfuse.qtype.yaml +50 -0
- qtype/examples/legacy/data/customers.csv +6 -0
- qtype/examples/legacy/data_processor.qtype.yaml +48 -0
- qtype/examples/legacy/echo/debug_example.qtype.yaml +59 -0
- qtype/examples/legacy/echo/prompt.qtype.yaml +22 -0
- qtype/examples/legacy/echo/readme.md +29 -0
- qtype/examples/legacy/echo/test.qtype.yaml +26 -0
- qtype/examples/legacy/echo/video.qtype.yaml +20 -0
- qtype/examples/legacy/field_extractor_example.qtype.yaml +137 -0
- qtype/examples/legacy/multi_flow_example.qtype.yaml +125 -0
- qtype/examples/legacy/openai/hello_world_chat.qtype.yaml +43 -0
- qtype/examples/legacy/openai/hello_world_chat_with_telemetry.qtype.yaml +46 -0
- qtype/examples/legacy/qtype_plugin_example.py +51 -0
- qtype/examples/legacy/rag.qtype.yaml +207 -0
- qtype/examples/legacy/sample_data.txt +43 -0
- qtype/examples/legacy/time_utilities.qtype.yaml +64 -0
- qtype/examples/legacy/vertex/README.md +11 -0
- qtype/examples/legacy/vertex/hello_world_chat.qtype.yaml +36 -0
- qtype/examples/legacy/vertex/hello_world_completion.qtype.yaml +40 -0
- qtype/examples/legacy/vertex/hello_world_completion_with_auth.qtype.yaml +45 -0
- qtype/examples/observability_debugging/trace_with_opentelemetry.qtype.yaml +40 -0
- qtype/examples/research_assistant/research_assistant.qtype.yaml +94 -0
- qtype/examples/research_assistant/tavily.oas.yaml +722 -0
- qtype/examples/research_assistant/tavily.qtype.yaml +216 -0
- qtype/examples/tutorials/01_hello_world.qtype.yaml +48 -0
- qtype/examples/tutorials/02_conversational_chat.qtype.yaml +37 -0
- qtype/examples/tutorials/03_structured_data.qtype.yaml +130 -0
- qtype/examples/tutorials/04_tools_and_function_calling.qtype.yaml +89 -0
- qtype/interpreter/api.py +4 -1
- qtype/interpreter/base/base_step_executor.py +3 -1
- qtype/interpreter/base/stream_emitter.py +19 -13
- qtype/interpreter/conversions.py +7 -3
- qtype/interpreter/converters.py +142 -26
- qtype/interpreter/executors/agent_executor.py +2 -3
- qtype/interpreter/executors/aggregate_executor.py +3 -4
- qtype/interpreter/executors/construct_executor.py +15 -15
- qtype/interpreter/executors/doc_to_text_executor.py +1 -3
- qtype/interpreter/executors/field_extractor_executor.py +13 -12
- qtype/interpreter/executors/file_source_executor.py +21 -34
- qtype/interpreter/executors/file_writer_executor.py +4 -4
- qtype/interpreter/executors/index_upsert_executor.py +1 -1
- qtype/interpreter/executors/invoke_embedding_executor.py +1 -4
- qtype/interpreter/executors/invoke_flow_executor.py +2 -2
- qtype/interpreter/executors/invoke_tool_executor.py +19 -18
- qtype/interpreter/executors/llm_inference_executor.py +16 -18
- qtype/interpreter/executors/prompt_template_executor.py +1 -3
- qtype/interpreter/executors/sql_source_executor.py +1 -1
- qtype/interpreter/resource_cache.py +3 -1
- qtype/interpreter/rich_progress.py +6 -3
- qtype/interpreter/stream/chat/converter.py +25 -17
- qtype/interpreter/stream/chat/ui_request_to_domain_type.py +2 -2
- qtype/interpreter/tools/function_tool_helper.py +11 -10
- qtype/interpreter/types.py +89 -4
- qtype/interpreter/typing.py +35 -38
- qtype/mcp/__init__.py +0 -0
- qtype/mcp/server.py +722 -0
- qtype/schema/qtype.schema.json +4016 -0
- qtype/semantic/checker.py +20 -1
- qtype/semantic/generate.py +6 -9
- qtype/semantic/model.py +26 -33
- qtype/semantic/resolver.py +7 -0
- qtype/semantic/visualize.py +45 -53
- {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/METADATA +65 -44
- qtype-0.1.13.dist-info/RECORD +352 -0
- {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/WHEEL +1 -2
- qtype/application/facade.py +0 -177
- qtype-0.1.11.dist-info/RECORD +0 -142
- qtype-0.1.11.dist-info/top_level.txt +0 -1
- {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/entry_points.txt +0 -0
- {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/licenses/LICENSE +0 -0
qtype/semantic/checker.py
CHANGED
|
@@ -50,6 +50,10 @@ class FlowHasNoStepsError(QTypeValidationError):
|
|
|
50
50
|
# Alias for backward compatibility and semantic clarity
|
|
51
51
|
QTypeSemanticError = SemanticError
|
|
52
52
|
|
|
53
|
+
# Step types that support text streaming
|
|
54
|
+
# These are the only step types that can produce streaming text output
|
|
55
|
+
STREAMING_STEP_TYPES = (LLMInference, Agent)
|
|
56
|
+
|
|
53
57
|
|
|
54
58
|
# ---- Helper Functions for Common Validation Patterns ----
|
|
55
59
|
|
|
@@ -543,6 +547,21 @@ def _validate_flow(flow: Flow) -> None:
|
|
|
543
547
|
f"Flow {flow.id} has a Complete interface but {len(text_outputs)} text outputs -- there should be 1."
|
|
544
548
|
)
|
|
545
549
|
|
|
550
|
+
# Ensure the final step supports streaming for Complete interface
|
|
551
|
+
if flow.steps:
|
|
552
|
+
final_step = flow.steps[-1]
|
|
553
|
+
if not isinstance(final_step, STREAMING_STEP_TYPES):
|
|
554
|
+
streaming_type_names = ", ".join(
|
|
555
|
+
t.__name__ for t in STREAMING_STEP_TYPES
|
|
556
|
+
)
|
|
557
|
+
raise QTypeSemanticError(
|
|
558
|
+
(
|
|
559
|
+
f"Flow {flow.id} has a Complete interface which requires streaming output, "
|
|
560
|
+
f"but the final step '{final_step.id}' is of type '{final_step.type}' which does not support streaming. "
|
|
561
|
+
f"The final step must be one of: {streaming_type_names}."
|
|
562
|
+
)
|
|
563
|
+
)
|
|
564
|
+
|
|
546
565
|
|
|
547
566
|
def _has_secret_reference(obj: Any) -> bool:
|
|
548
567
|
"""
|
|
@@ -704,7 +723,7 @@ def check(model: BaseModel) -> None:
|
|
|
704
723
|
# Check if this model type has a validator
|
|
705
724
|
model_type = type(model)
|
|
706
725
|
if model_type in _VALIDATORS:
|
|
707
|
-
_VALIDATORS[model_type](model)
|
|
726
|
+
_VALIDATORS[model_type](model) # type: ignore[arg-type]
|
|
708
727
|
|
|
709
728
|
# Recursively validate all fields
|
|
710
729
|
for field_name, field_value in model:
|
qtype/semantic/generate.py
CHANGED
|
@@ -73,7 +73,7 @@ def sort_classes_by_inheritance(
|
|
|
73
73
|
):
|
|
74
74
|
graph.add_edge(base.__name__, class_name)
|
|
75
75
|
|
|
76
|
-
sorted_names = list(nx.topological_sort(graph))
|
|
76
|
+
sorted_names = list(nx.topological_sort(graph)) # type: ignore[arg-type]
|
|
77
77
|
|
|
78
78
|
# sorted_names = sorted(graph.nodes, key=lambda node: depths[node])
|
|
79
79
|
return [(name, class_dict[name]) for name in sorted_names]
|
|
@@ -144,8 +144,7 @@ def generate_semantic_model(args: argparse.Namespace) -> None:
|
|
|
144
144
|
CustomType,
|
|
145
145
|
DecoderFormat,
|
|
146
146
|
ListType,
|
|
147
|
-
PrimitiveTypeEnum
|
|
148
|
-
ToolParameter
|
|
147
|
+
PrimitiveTypeEnum
|
|
149
148
|
)
|
|
150
149
|
from qtype.dsl.model import Variable as DSLVariable # noqa: F401
|
|
151
150
|
from qtype.dsl.model import VariableType # noqa: F401
|
|
@@ -158,10 +157,8 @@ def generate_semantic_model(args: argparse.Namespace) -> None:
|
|
|
158
157
|
f.write(
|
|
159
158
|
dedent('''
|
|
160
159
|
class Variable(DSLVariable, BaseModel):
|
|
161
|
-
"""Semantic version of DSL Variable
|
|
162
|
-
|
|
163
|
-
def is_set(self) -> bool:
|
|
164
|
-
return self.value is not None
|
|
160
|
+
"""Semantic version of DSL Variable."""
|
|
161
|
+
pass
|
|
165
162
|
|
|
166
163
|
''').lstrip()
|
|
167
164
|
)
|
|
@@ -490,10 +487,10 @@ def generate_semantic_class(class_name: str, cls: type) -> str:
|
|
|
490
487
|
# Only process fields that are actually defined on this class
|
|
491
488
|
for field_name in cls.__annotations__:
|
|
492
489
|
if (
|
|
493
|
-
field_name in cls.model_fields
|
|
490
|
+
field_name in cls.model_fields # type: ignore[operator]
|
|
494
491
|
and f"{class_name}.{field_name}" not in FIELDS_TO_IGNORE
|
|
495
492
|
):
|
|
496
|
-
field_info = cls.model_fields[field_name]
|
|
493
|
+
field_info = cls.model_fields[field_name] # type: ignore[index]
|
|
497
494
|
field_type = field_info.annotation
|
|
498
495
|
field_default = field_info.default
|
|
499
496
|
field_default_factory = field_info.default_factory
|
qtype/semantic/model.py
CHANGED
|
@@ -32,19 +32,15 @@ from qtype.dsl.model import ( # noqa: F401
|
|
|
32
32
|
DecoderFormat,
|
|
33
33
|
ListType,
|
|
34
34
|
PrimitiveTypeEnum,
|
|
35
|
-
ToolParameter,
|
|
36
35
|
)
|
|
37
36
|
from qtype.dsl.model import Variable as DSLVariable # noqa: F401
|
|
38
37
|
from qtype.semantic.base_types import ImmutableModel
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
class Variable(DSLVariable, BaseModel):
|
|
42
|
-
"""Semantic version of DSL Variable
|
|
41
|
+
"""Semantic version of DSL Variable."""
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def is_set(self) -> bool:
|
|
47
|
-
return self.value is not None
|
|
43
|
+
pass
|
|
48
44
|
|
|
49
45
|
|
|
50
46
|
class AuthorizationProvider(ImmutableModel):
|
|
@@ -66,12 +62,12 @@ class Tool(ImmutableModel):
|
|
|
66
62
|
description: str = Field(
|
|
67
63
|
..., description="Description of what the tool does."
|
|
68
64
|
)
|
|
69
|
-
inputs:
|
|
70
|
-
default_factory=
|
|
65
|
+
inputs: list[Variable] = Field(
|
|
66
|
+
default_factory=list,
|
|
71
67
|
description="Input parameters required by this tool.",
|
|
72
68
|
)
|
|
73
|
-
outputs:
|
|
74
|
-
default_factory=
|
|
69
|
+
outputs: list[Variable] = Field(
|
|
70
|
+
default_factory=list,
|
|
75
71
|
description="Output parameters produced by this tool.",
|
|
76
72
|
)
|
|
77
73
|
|
|
@@ -421,9 +417,9 @@ class APITool(Tool):
|
|
|
421
417
|
default_factory=dict,
|
|
422
418
|
description="Optional HTTP headers to include in the request.",
|
|
423
419
|
)
|
|
424
|
-
parameters:
|
|
425
|
-
default_factory=
|
|
426
|
-
description="
|
|
420
|
+
parameters: list[Variable] = Field(
|
|
421
|
+
default_factory=list,
|
|
422
|
+
description="Path and query parameters for the API call.",
|
|
427
423
|
)
|
|
428
424
|
|
|
429
425
|
|
|
@@ -447,15 +443,12 @@ class AWSSecretManager(SecretManager):
|
|
|
447
443
|
|
|
448
444
|
class Aggregate(Step):
|
|
449
445
|
"""
|
|
450
|
-
A
|
|
451
|
-
|
|
446
|
+
A step that, after all messages have been processed,
|
|
447
|
+
returns a single message containing the counts of successful and failed
|
|
448
|
+
messages. Other messages are passed through unchanged.
|
|
452
449
|
"""
|
|
453
450
|
|
|
454
451
|
type: Literal["Aggregate"] = Field("Aggregate")
|
|
455
|
-
outputs: list[Variable] = Field(
|
|
456
|
-
default_factory=list,
|
|
457
|
-
description="References to the variables for the output. There should be one and only one output with type AggregateStats",
|
|
458
|
-
)
|
|
459
452
|
|
|
460
453
|
|
|
461
454
|
class Collect(Step, BatchableStepMixin):
|
|
@@ -472,8 +465,9 @@ class Construct(Step):
|
|
|
472
465
|
"""A step that converts variables into an instance of a Custom or Domain Type"""
|
|
473
466
|
|
|
474
467
|
type: Literal["Construct"] = Field("Construct")
|
|
475
|
-
|
|
476
|
-
...,
|
|
468
|
+
field_bindings: dict[str, Variable] = Field(
|
|
469
|
+
...,
|
|
470
|
+
description="Mapping from type field names to flow variable names.",
|
|
477
471
|
)
|
|
478
472
|
|
|
479
473
|
|
|
@@ -558,6 +552,9 @@ class FieldExtractor(Step):
|
|
|
558
552
|
The extracted data is used to construct the output variable by passing it
|
|
559
553
|
as keyword arguments to the output type's constructor.
|
|
560
554
|
|
|
555
|
+
If there is no match and the output variable is optional, it is set to None.
|
|
556
|
+
If there is no match and the output variable is required, an error is raised.
|
|
557
|
+
|
|
561
558
|
Example JSONPath expressions:
|
|
562
559
|
- `$.field_name` - Extract a single field
|
|
563
560
|
- `$.items[*]` - Extract all items from a list
|
|
@@ -569,10 +566,6 @@ class FieldExtractor(Step):
|
|
|
569
566
|
...,
|
|
570
567
|
description="JSONPath expression to extract data from the input. Uses jsonpath-ng syntax.",
|
|
571
568
|
)
|
|
572
|
-
fail_on_missing: bool = Field(
|
|
573
|
-
True,
|
|
574
|
-
description="Whether to raise an error if the JSONPath matches no data. If False, returns None.",
|
|
575
|
-
)
|
|
576
569
|
|
|
577
570
|
|
|
578
571
|
class InvokeEmbedding(Step, ConcurrentStepMixin):
|
|
@@ -590,13 +583,13 @@ class InvokeFlow(Step):
|
|
|
590
583
|
|
|
591
584
|
type: Literal["InvokeFlow"] = Field("InvokeFlow")
|
|
592
585
|
flow: Flow = Field(..., description="Flow to invoke.")
|
|
593
|
-
input_bindings: dict[
|
|
586
|
+
input_bindings: dict[str, Variable] = Field(
|
|
594
587
|
...,
|
|
595
|
-
description="Mapping from variable
|
|
588
|
+
description="Mapping from flow input variable IDs to step variable names.",
|
|
596
589
|
)
|
|
597
|
-
output_bindings: dict[
|
|
590
|
+
output_bindings: dict[str, Variable] = Field(
|
|
598
591
|
...,
|
|
599
|
-
description="Mapping from variable
|
|
592
|
+
description="Mapping from flow output variable IDs to step variable names.",
|
|
600
593
|
)
|
|
601
594
|
|
|
602
595
|
|
|
@@ -605,13 +598,13 @@ class InvokeTool(Step, ConcurrentStepMixin):
|
|
|
605
598
|
|
|
606
599
|
type: Literal["InvokeTool"] = Field("InvokeTool")
|
|
607
600
|
tool: Tool = Field(..., description="Tool to invoke.")
|
|
608
|
-
input_bindings: dict[str,
|
|
601
|
+
input_bindings: dict[str, Variable] = Field(
|
|
609
602
|
...,
|
|
610
|
-
description="Mapping from
|
|
603
|
+
description="Mapping from tool parameter names to flow variable names.",
|
|
611
604
|
)
|
|
612
|
-
output_bindings: dict[str,
|
|
605
|
+
output_bindings: dict[str, Variable] = Field(
|
|
613
606
|
...,
|
|
614
|
-
description="Mapping from
|
|
607
|
+
description="Mapping from tool output names to flow variable names.",
|
|
615
608
|
)
|
|
616
609
|
|
|
617
610
|
|
qtype/semantic/resolver.py
CHANGED
|
@@ -71,6 +71,13 @@ def to_semantic_ir(
|
|
|
71
71
|
# If the object is already in the symbol table, return it.
|
|
72
72
|
return symbol_table[obj_id]
|
|
73
73
|
|
|
74
|
+
if isinstance(dslobj, dict):
|
|
75
|
+
# If the object is a dict, recursively resolve each value
|
|
76
|
+
return {
|
|
77
|
+
key: to_semantic_ir(value, symbol_table)
|
|
78
|
+
for key, value in dslobj.items()
|
|
79
|
+
}
|
|
80
|
+
|
|
74
81
|
if isinstance(dslobj, list):
|
|
75
82
|
# If the object is a list, we will resolve each item in the list.
|
|
76
83
|
return [to_semantic_ir(item, symbol_table) for item in dslobj] # type: ignore
|
qtype/semantic/visualize.py
CHANGED
|
@@ -21,6 +21,8 @@ from qtype.semantic.model import (
|
|
|
21
21
|
DocumentIndex,
|
|
22
22
|
DocumentSearch,
|
|
23
23
|
Flow,
|
|
24
|
+
InvokeFlow,
|
|
25
|
+
InvokeTool,
|
|
24
26
|
LLMInference,
|
|
25
27
|
Memory,
|
|
26
28
|
Model,
|
|
@@ -47,7 +49,7 @@ def visualize_application(app: Application) -> str:
|
|
|
47
49
|
"""
|
|
48
50
|
lines = [
|
|
49
51
|
"flowchart TD",
|
|
50
|
-
f' subgraph APP ["📱
|
|
52
|
+
f' subgraph APP ["📱 {app.id}"]',
|
|
51
53
|
" direction TB",
|
|
52
54
|
"",
|
|
53
55
|
]
|
|
@@ -117,8 +119,8 @@ def _generate_flow_subgraph(
|
|
|
117
119
|
flow: Flow, flow_id: str
|
|
118
120
|
) -> tuple[list[str], list[str]]:
|
|
119
121
|
"""Generate a flow subgraph with internal nodes and return external connections."""
|
|
120
|
-
#
|
|
121
|
-
|
|
122
|
+
# Keep labels concise - no multi-line descriptions in labels
|
|
123
|
+
flow_label = f"🔄 {flow.id}"
|
|
122
124
|
|
|
123
125
|
# Choose direction based on flow characteristics:
|
|
124
126
|
# - Flows with interface (e.g., Conversational) use LR (left-right)
|
|
@@ -126,7 +128,7 @@ def _generate_flow_subgraph(
|
|
|
126
128
|
direction = "LR" if flow.interface else "TB"
|
|
127
129
|
|
|
128
130
|
lines = [
|
|
129
|
-
f' subgraph {flow_id} ["
|
|
131
|
+
f' subgraph {flow_id} ["{flow_label}"]',
|
|
130
132
|
f" direction {direction}",
|
|
131
133
|
]
|
|
132
134
|
|
|
@@ -167,20 +169,31 @@ def _generate_step_node(
|
|
|
167
169
|
lines = []
|
|
168
170
|
external_connections = []
|
|
169
171
|
|
|
170
|
-
if isinstance(step,
|
|
171
|
-
# Nested flow
|
|
172
|
+
if isinstance(step, InvokeFlow):
|
|
172
173
|
lines.append(
|
|
173
|
-
f' {node_id}@{{shape:
|
|
174
|
+
f' {node_id}@{{shape: sub-r, label: "🔄 {step.id}"}}'
|
|
175
|
+
)
|
|
176
|
+
# Connect to the invoked flow
|
|
177
|
+
invoked_flow_id = f"FLOW_{_sanitize_id(step.flow.id)}"
|
|
178
|
+
external_connections.append(
|
|
179
|
+
f" {node_id} -.->|invokes| {invoked_flow_id}"
|
|
174
180
|
)
|
|
175
181
|
elif isinstance(step, Agent):
|
|
176
182
|
# Agent with tools
|
|
177
183
|
lines.append(
|
|
178
|
-
f' {node_id}@{{shape: hex, label: "🤖
|
|
184
|
+
f' {node_id}@{{shape: hex, label: "🤖 {step.id}"}}'
|
|
179
185
|
)
|
|
180
186
|
# Connect to tools
|
|
181
187
|
for tool in step.tools:
|
|
182
188
|
tool_id = f"TOOL_{_sanitize_id(tool.id)}"
|
|
183
|
-
external_connections.append(f" {node_id}
|
|
189
|
+
external_connections.append(f" {node_id} -.->|uses| {tool_id}")
|
|
190
|
+
elif isinstance(step, InvokeTool):
|
|
191
|
+
lines.append(
|
|
192
|
+
f' {node_id}@{{shape: rect, label: "⚙️ {step.id}"}}'
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
tool_id = f"TOOL_{_sanitize_id(step.tool.id)}"
|
|
196
|
+
external_connections.append(f" {node_id} -.->|uses| {tool_id}")
|
|
184
197
|
elif isinstance(step, LLMInference):
|
|
185
198
|
lines.append(
|
|
186
199
|
f' {node_id}@{{shape: rounded, label: "✨ {step.id}"}}'
|
|
@@ -196,7 +209,7 @@ def _generate_step_node(
|
|
|
196
209
|
)
|
|
197
210
|
elif isinstance(step, PromptTemplate):
|
|
198
211
|
lines.append(
|
|
199
|
-
f' {node_id}@{{shape: doc, label: "📄
|
|
212
|
+
f' {node_id}@{{shape: doc, label: "📄 {step.id}"}}'
|
|
200
213
|
)
|
|
201
214
|
elif isinstance(step, Decoder):
|
|
202
215
|
format_label = (
|
|
@@ -205,46 +218,30 @@ def _generate_step_node(
|
|
|
205
218
|
else str(step.format)
|
|
206
219
|
)
|
|
207
220
|
lines.append(
|
|
208
|
-
f' {node_id}@{{shape: lean-r, label: "🔍
|
|
221
|
+
f' {node_id}@{{shape: lean-r, label: "🔍 {step.id} ({format_label})"}}'
|
|
209
222
|
)
|
|
210
223
|
elif isinstance(step, VectorSearch):
|
|
211
224
|
lines.append(
|
|
212
|
-
f' {node_id}@{{shape: cyl, label: "🔎
|
|
225
|
+
f' {node_id}@{{shape: cyl, label: "🔎 {step.id}"}}'
|
|
213
226
|
)
|
|
214
227
|
index_id = f"INDEX_{_sanitize_id(step.index.id)}"
|
|
215
228
|
external_connections.append(f" {node_id} -.-> {index_id}")
|
|
216
229
|
elif isinstance(step, DocumentSearch):
|
|
217
230
|
lines.append(
|
|
218
|
-
f' {node_id}@{{shape: cyl, label: "📚
|
|
231
|
+
f' {node_id}@{{shape: cyl, label: "📚 {step.id}"}}'
|
|
219
232
|
)
|
|
220
233
|
index_id = f"INDEX_{_sanitize_id(step.index.id)}"
|
|
221
234
|
external_connections.append(f" {node_id} -.-> {index_id}")
|
|
222
235
|
elif isinstance(step, Search):
|
|
223
236
|
lines.append(
|
|
224
|
-
f' {node_id}@{{shape: cyl, label: "🔍
|
|
237
|
+
f' {node_id}@{{shape: cyl, label: "🔍 {step.id}"}}'
|
|
225
238
|
)
|
|
226
239
|
index_id = f"INDEX_{_sanitize_id(step.index.id)}"
|
|
227
240
|
external_connections.append(f" {node_id} -.-> {index_id}")
|
|
228
|
-
elif isinstance(step, APITool):
|
|
229
|
-
method_label = step.method.upper()
|
|
230
|
-
lines.append(
|
|
231
|
-
f' {node_id}["⚡ API: {step.id} ({method_label})"]'
|
|
232
|
-
)
|
|
233
|
-
if step.auth:
|
|
234
|
-
auth_id = f"AUTH_{_sanitize_id(step.auth.id)}"
|
|
235
|
-
external_connections.append(f" {node_id} -.-> {auth_id}")
|
|
236
|
-
elif isinstance(step, PythonFunctionTool):
|
|
237
|
-
lines.append(
|
|
238
|
-
f' {node_id}@{{shape: rect, label: "🐍 Python: {step.id} {step.function_name}"}}'
|
|
239
|
-
)
|
|
240
|
-
elif isinstance(step, Tool):
|
|
241
|
-
lines.append(
|
|
242
|
-
f' {node_id}@{{shape: rect, label: "🔧 Tool: {step.id}"}}'
|
|
243
|
-
)
|
|
244
241
|
else:
|
|
245
242
|
# Generic step
|
|
246
243
|
lines.append(
|
|
247
|
-
f' {node_id}@{{shape: rect, label: "⚙️
|
|
244
|
+
f' {node_id}@{{shape: rect, label: "⚙️ {step.id}"}}'
|
|
248
245
|
)
|
|
249
246
|
|
|
250
247
|
return lines, external_connections
|
|
@@ -276,20 +273,11 @@ def _generate_step_connections(
|
|
|
276
273
|
# consumes and produces the same variable)
|
|
277
274
|
if producer_id == node_id:
|
|
278
275
|
continue
|
|
279
|
-
#
|
|
280
|
-
|
|
281
|
-
-1
|
|
282
|
-
] # Get the last part after dots
|
|
283
|
-
var_id_and_type = f"{input_var.id}: {var_type}"
|
|
284
|
-
|
|
285
|
-
is_list = str(var_type).startswith("list[") and str(
|
|
286
|
-
var_type
|
|
287
|
-
).endswith("]")
|
|
288
|
-
if is_list:
|
|
289
|
-
var_id_and_type = f'"{var_id_and_type}"'
|
|
276
|
+
# Use simple variable name only - no type annotations
|
|
277
|
+
var_label = input_var.id
|
|
290
278
|
|
|
291
279
|
lines.append(
|
|
292
|
-
f" {producer_id} -->|{
|
|
280
|
+
f" {producer_id} -->|{var_label}| {node_id}"
|
|
293
281
|
)
|
|
294
282
|
|
|
295
283
|
# Then, register this step's outputs for future steps
|
|
@@ -374,7 +362,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
374
362
|
auth_id = f"AUTH_{_sanitize_id(auth.id)}"
|
|
375
363
|
auth_type = auth.type.upper()
|
|
376
364
|
lines.append(
|
|
377
|
-
f' {auth_id}@{{shape: hex, label: "🔐 {auth.id}
|
|
365
|
+
f' {auth_id}@{{shape: hex, label: "🔐 {auth.id} ({auth_type})"}}'
|
|
378
366
|
)
|
|
379
367
|
|
|
380
368
|
# Models
|
|
@@ -394,7 +382,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
394
382
|
index_id = f"INDEX_{_sanitize_id(index.id)}"
|
|
395
383
|
if isinstance(index, VectorIndex):
|
|
396
384
|
lines.append(
|
|
397
|
-
f' {index_id}@{{shape: cyl, label: "🗂️
|
|
385
|
+
f' {index_id}@{{shape: cyl, label: "🗂️ {index.id}"}}'
|
|
398
386
|
)
|
|
399
387
|
# Connect to embedding model
|
|
400
388
|
emb_model_id = f"EMB_{_sanitize_id(index.embedding_model.id)}"
|
|
@@ -404,7 +392,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
404
392
|
lines.append(f" {index_id} -.->|embeds| {emb_model_id}")
|
|
405
393
|
elif isinstance(index, DocumentIndex):
|
|
406
394
|
lines.append(
|
|
407
|
-
f' {index_id}@{{shape: cyl, label: "📚
|
|
395
|
+
f' {index_id}@{{shape: cyl, label: "📚 {index.id}"}}'
|
|
408
396
|
)
|
|
409
397
|
else:
|
|
410
398
|
lines.append(
|
|
@@ -412,11 +400,15 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
412
400
|
)
|
|
413
401
|
|
|
414
402
|
if index.auth:
|
|
415
|
-
|
|
416
|
-
if isinstance(
|
|
417
|
-
|
|
403
|
+
auth_value = index.auth
|
|
404
|
+
if isinstance(auth_value, str):
|
|
405
|
+
auth_ref = auth_value
|
|
418
406
|
else:
|
|
419
|
-
|
|
407
|
+
auth_ref = getattr(auth_value, "id", None)
|
|
408
|
+
if auth_ref is None:
|
|
409
|
+
auth_ref = str(auth_value)
|
|
410
|
+
|
|
411
|
+
auth_id = f"AUTH_{_sanitize_id(str(auth_ref))}"
|
|
420
412
|
lines.append(f" {index_id} -.->|uses| {auth_id}")
|
|
421
413
|
|
|
422
414
|
# Memories
|
|
@@ -428,7 +420,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
428
420
|
else str(memory.token_limit)
|
|
429
421
|
)
|
|
430
422
|
lines.append(
|
|
431
|
-
f' {memory_id}@{{shape: win-pane, label: "🧠 {memory.id}
|
|
423
|
+
f' {memory_id}@{{shape: win-pane, label: "🧠 {memory.id} ({token_limit}T)"}}'
|
|
432
424
|
)
|
|
433
425
|
|
|
434
426
|
# Tools (if not already covered by flows)
|
|
@@ -444,7 +436,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
444
436
|
lines.append(f" {tool_id} -.->|uses| {auth_id}")
|
|
445
437
|
elif isinstance(tool, PythonFunctionTool):
|
|
446
438
|
lines.append(
|
|
447
|
-
f' {tool_id}@{{shape: rect, label: "🐍 {tool.id}
|
|
439
|
+
f' {tool_id}@{{shape: rect, label: "🐍 {tool.id}"}}'
|
|
448
440
|
)
|
|
449
441
|
else:
|
|
450
442
|
lines.append(
|
|
@@ -459,7 +451,7 @@ def _generate_shared_resources(app: Application) -> list[str]:
|
|
|
459
451
|
def _generate_telemetry_nodes(telemetry: TelemetrySink) -> list[str]:
|
|
460
452
|
"""Generate nodes for telemetry configuration."""
|
|
461
453
|
# Replace :// with a space to avoid markdown link parsing
|
|
462
|
-
safe_endpoint = telemetry.endpoint.replace("://", "://")
|
|
454
|
+
safe_endpoint = telemetry.endpoint.replace("://", "://") # type: ignore[union-attr]
|
|
463
455
|
|
|
464
456
|
lines = [
|
|
465
457
|
' subgraph TELEMETRY ["📊 Observability"]',
|
|
@@ -1,57 +1,61 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qtype
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: DSL for Generative AI Prototyping
|
|
5
|
+
Project-URL: Homepage, https://github.com/bazaarvoice/qtype
|
|
5
6
|
Author-email: Lou Kratz <lou.kratz+qtype@bazaarvoice.com>
|
|
6
7
|
License-Expression: Apache-2.0
|
|
7
|
-
Project-URL: Homepage, https://github.com/bazaarvoice/qtype
|
|
8
|
-
Requires-Python: >=3.10
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
10
8
|
License-File: LICENSE
|
|
11
|
-
Requires-
|
|
12
|
-
Requires-Dist: pydantic>=2.12.4
|
|
13
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
14
|
-
Requires-Dist: python-dotenv>=1.0.0
|
|
15
|
-
Requires-Dist: openai>=1.93.0
|
|
9
|
+
Requires-Python: >=3.10
|
|
16
10
|
Requires-Dist: fsspec>=2025.5.1
|
|
11
|
+
Requires-Dist: google-cloud-aiplatform>=1.120.0
|
|
12
|
+
Requires-Dist: jsonschema>=4.24.0
|
|
17
13
|
Requires-Dist: mkdocs-awesome-pages-plugin>=2.10.1
|
|
18
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: openai>=1.93.0
|
|
19
15
|
Requires-Dist: openapi3-parser>=1.1.21
|
|
16
|
+
Requires-Dist: pip-system-certs>=5.2
|
|
20
17
|
Requires-Dist: pydantic-yaml>=1.6.0
|
|
21
|
-
Requires-Dist:
|
|
18
|
+
Requires-Dist: pydantic>=2.12.4
|
|
19
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
20
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
22
21
|
Provides-Extra: interpreter
|
|
23
|
-
Requires-Dist: aiostream>=0.7.1; extra ==
|
|
24
|
-
Requires-Dist: arize-phoenix-otel>=0.12.1; extra ==
|
|
25
|
-
Requires-Dist: boto3>=1.34.0; extra ==
|
|
26
|
-
Requires-Dist: datasets>=4.4.1; extra ==
|
|
27
|
-
Requires-Dist: diskcache>=5.6.3; extra ==
|
|
28
|
-
Requires-Dist: docling>=2.55.1; extra ==
|
|
29
|
-
Requires-Dist: docx2txt>=0.9; extra ==
|
|
30
|
-
Requires-Dist: fastapi>=0.116.1; extra ==
|
|
31
|
-
Requires-Dist: jsonpath-ng>=1.7.0; extra ==
|
|
32
|
-
Requires-Dist: langfuse>=3.9.0; extra ==
|
|
33
|
-
Requires-Dist: llama-index-embeddings-bedrock>=0.5.2; extra ==
|
|
34
|
-
Requires-Dist: llama-index-embeddings-openai>=0.3.1; extra ==
|
|
35
|
-
Requires-Dist: llama-index-llms-bedrock-converse>=0.10.5; extra ==
|
|
36
|
-
Requires-Dist: llama-index-llms-bedrock>=0.3.8; extra ==
|
|
37
|
-
Requires-Dist: llama-index-llms-vertex>=0.6.1; extra ==
|
|
38
|
-
Requires-Dist: llama-index-postprocessor-bedrock-rerank>=0.5.1; extra ==
|
|
39
|
-
Requires-Dist: llama-index-readers-huggingface-fs>=0.4.1; extra ==
|
|
40
|
-
Requires-Dist: llama-index-vector-stores-qdrant>=0.8.6; extra ==
|
|
41
|
-
Requires-Dist: llama-index>=0.12.45; extra ==
|
|
42
|
-
Requires-Dist: openinference-instrumentation-llama-index>=4.3.4; extra ==
|
|
43
|
-
Requires-Dist: opensearch-py>=2.7.0; extra ==
|
|
44
|
-
Requires-Dist: opentelemetry-exporter-otlp>=1.35.0; extra ==
|
|
45
|
-
Requires-Dist: opentelemetry-sdk>=1.35.0; extra ==
|
|
46
|
-
Requires-Dist: pandas>=2.2.3; extra ==
|
|
47
|
-
Requires-Dist: psycopg2-binary>=2.9.10; extra ==
|
|
48
|
-
Requires-Dist: pyarrow>=21.0.0; extra ==
|
|
49
|
-
Requires-Dist: pyathena[sqlalchemy]>=3.18.0; extra ==
|
|
50
|
-
Requires-Dist: python-magic>=0.4.27; extra ==
|
|
51
|
-
Requires-Dist: s3fs>=2025.7.0; extra ==
|
|
52
|
-
Requires-Dist: sqlalchemy>=2.0.42; extra ==
|
|
53
|
-
Requires-Dist: uvicorn[standard]>=0.35.0; extra ==
|
|
54
|
-
|
|
22
|
+
Requires-Dist: aiostream>=0.7.1; extra == 'interpreter'
|
|
23
|
+
Requires-Dist: arize-phoenix-otel>=0.12.1; extra == 'interpreter'
|
|
24
|
+
Requires-Dist: boto3>=1.34.0; extra == 'interpreter'
|
|
25
|
+
Requires-Dist: datasets>=4.4.1; extra == 'interpreter'
|
|
26
|
+
Requires-Dist: diskcache>=5.6.3; extra == 'interpreter'
|
|
27
|
+
Requires-Dist: docling>=2.55.1; extra == 'interpreter'
|
|
28
|
+
Requires-Dist: docx2txt>=0.9; extra == 'interpreter'
|
|
29
|
+
Requires-Dist: fastapi>=0.116.1; extra == 'interpreter'
|
|
30
|
+
Requires-Dist: jsonpath-ng>=1.7.0; extra == 'interpreter'
|
|
31
|
+
Requires-Dist: langfuse>=3.9.0; extra == 'interpreter'
|
|
32
|
+
Requires-Dist: llama-index-embeddings-bedrock>=0.5.2; extra == 'interpreter'
|
|
33
|
+
Requires-Dist: llama-index-embeddings-openai>=0.3.1; extra == 'interpreter'
|
|
34
|
+
Requires-Dist: llama-index-llms-bedrock-converse>=0.10.5; extra == 'interpreter'
|
|
35
|
+
Requires-Dist: llama-index-llms-bedrock>=0.3.8; extra == 'interpreter'
|
|
36
|
+
Requires-Dist: llama-index-llms-vertex>=0.6.1; extra == 'interpreter'
|
|
37
|
+
Requires-Dist: llama-index-postprocessor-bedrock-rerank>=0.5.1; extra == 'interpreter'
|
|
38
|
+
Requires-Dist: llama-index-readers-huggingface-fs>=0.4.1; extra == 'interpreter'
|
|
39
|
+
Requires-Dist: llama-index-vector-stores-qdrant>=0.8.6; extra == 'interpreter'
|
|
40
|
+
Requires-Dist: llama-index>=0.12.45; extra == 'interpreter'
|
|
41
|
+
Requires-Dist: openinference-instrumentation-llama-index>=4.3.4; extra == 'interpreter'
|
|
42
|
+
Requires-Dist: opensearch-py>=2.7.0; extra == 'interpreter'
|
|
43
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.35.0; extra == 'interpreter'
|
|
44
|
+
Requires-Dist: opentelemetry-sdk>=1.35.0; extra == 'interpreter'
|
|
45
|
+
Requires-Dist: pandas>=2.2.3; extra == 'interpreter'
|
|
46
|
+
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'interpreter'
|
|
47
|
+
Requires-Dist: pyarrow>=21.0.0; extra == 'interpreter'
|
|
48
|
+
Requires-Dist: pyathena[sqlalchemy]>=3.18.0; extra == 'interpreter'
|
|
49
|
+
Requires-Dist: python-magic>=0.4.27; extra == 'interpreter'
|
|
50
|
+
Requires-Dist: s3fs>=2025.7.0; extra == 'interpreter'
|
|
51
|
+
Requires-Dist: sqlalchemy>=2.0.42; extra == 'interpreter'
|
|
52
|
+
Requires-Dist: uvicorn[standard]>=0.35.0; extra == 'interpreter'
|
|
53
|
+
Provides-Extra: mcp
|
|
54
|
+
Requires-Dist: cachetools>=6.2.1; extra == 'mcp'
|
|
55
|
+
Requires-Dist: httpx>=0.28.1; extra == 'mcp'
|
|
56
|
+
Requires-Dist: mcp[cli]>=1.25.0; extra == 'mcp'
|
|
57
|
+
Requires-Dist: tantivy>=0.25.1; extra == 'mcp'
|
|
58
|
+
Description-Content-Type: text/markdown
|
|
55
59
|
|
|
56
60
|
# QType
|
|
57
61
|
|
|
@@ -130,6 +134,23 @@ And go to [http://localhost:8000/ui](http://localhost:8000/ui) to see the user i
|
|
|
130
134
|
|
|
131
135
|
See the [full docs](https://bazaarvoice.github.io/qtype/) for more examples and guides.
|
|
132
136
|
|
|
137
|
+
## ✨ Developing with AI?
|
|
138
|
+
|
|
139
|
+
Use the QType MCP server to speed yourself up! Just set your assistant to run `qtype mcp`.
|
|
140
|
+
For VSCode, just add the following to `.vscode/mcp.json`:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"servers": {
|
|
145
|
+
"qtype": {
|
|
146
|
+
"type": "stdio",
|
|
147
|
+
"command": "qtype",
|
|
148
|
+
"cwd": "${workspaceFolder}",
|
|
149
|
+
"args": ["mcp", "--transport", "stdio"]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
133
154
|
|
|
134
155
|
|
|
135
156
|
## 🤝 Contributing
|
|
@@ -158,4 +179,4 @@ Stay tuned for upcoming features like:
|
|
|
158
179
|
Happy hacking with QType! 🛠️
|
|
159
180
|
|
|
160
181
|
|
|
161
|
-
[](https://github.com/bazaarvoice/qtype/actions/workflows/github_workflows_generate-schema.yml) [](https://github.com/bazaarvoice/qtype/actions/workflows/publish-pypi.yml)
|
|
182
|
+
[](https://github.com/bazaarvoice/qtype/actions/workflows/github_workflows_generate-schema.yml) [](https://github.com/bazaarvoice/qtype/actions/workflows/publish-pypi.yml)
|