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/commands/generate.py
CHANGED
|
@@ -2,24 +2,48 @@ import argparse
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import Any, Optional
|
|
6
6
|
|
|
7
7
|
from qtype.dsl.model import Document
|
|
8
8
|
|
|
9
9
|
logger = logging.getLogger(__name__)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
def generate_aws_bedrock_models() -> list[dict[str, Any]]:
|
|
13
|
+
"""Generate AWS Bedrock model definitions.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
List of model definitions for AWS Bedrock models.
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
ImportError: If boto3 is not installed.
|
|
20
|
+
Exception: If AWS API call fails.
|
|
21
|
+
"""
|
|
22
|
+
import boto3 # type: ignore[import-untyped]
|
|
23
|
+
|
|
24
|
+
logger.info("Discovering AWS Bedrock models...")
|
|
25
|
+
client = boto3.client("bedrock")
|
|
26
|
+
models = client.list_foundation_models()
|
|
27
|
+
|
|
28
|
+
model_definitions = []
|
|
29
|
+
for model_summary in models.get("modelSummaries", []):
|
|
30
|
+
model_definitions.append(
|
|
31
|
+
{
|
|
32
|
+
"id": model_summary["modelId"],
|
|
33
|
+
"provider": "aws-bedrock",
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
logger.info(f"Discovered {len(model_definitions)} AWS Bedrock models")
|
|
38
|
+
return model_definitions
|
|
39
|
+
|
|
40
|
+
|
|
12
41
|
def run_dump_commons_library(args: argparse.Namespace) -> None:
|
|
13
42
|
"""Generate commons library tools and AWS Bedrock models."""
|
|
14
|
-
import logging
|
|
15
43
|
from pathlib import Path
|
|
16
44
|
|
|
17
|
-
from qtype.application.facade import QTypeFacade
|
|
18
45
|
from qtype.dsl.model import Model, ModelList
|
|
19
46
|
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
facade = QTypeFacade()
|
|
22
|
-
|
|
23
47
|
try:
|
|
24
48
|
# Generate common tools using convert module functionality
|
|
25
49
|
logger.info("Generating common tools...")
|
|
@@ -38,7 +62,7 @@ def run_dump_commons_library(args: argparse.Namespace) -> None:
|
|
|
38
62
|
# Generate AWS Bedrock models
|
|
39
63
|
logger.info("Generating AWS Bedrock models...")
|
|
40
64
|
try:
|
|
41
|
-
model_definitions =
|
|
65
|
+
model_definitions = generate_aws_bedrock_models()
|
|
42
66
|
|
|
43
67
|
model_list = ModelList(
|
|
44
68
|
root=[
|
|
@@ -51,7 +75,11 @@ def run_dump_commons_library(args: argparse.Namespace) -> None:
|
|
|
51
75
|
)
|
|
52
76
|
|
|
53
77
|
# Convert to YAML and save
|
|
54
|
-
|
|
78
|
+
from pydantic_yaml import to_yaml_str
|
|
79
|
+
|
|
80
|
+
content = to_yaml_str(
|
|
81
|
+
model_list, exclude_none=True, exclude_unset=True
|
|
82
|
+
)
|
|
55
83
|
output_path = Path(f"{args.prefix}/aws.bedrock.models.qtype.yaml")
|
|
56
84
|
output_path.write_text(content, encoding="utf-8")
|
|
57
85
|
logger.info(f"AWS Bedrock models exported to {output_path}")
|
|
@@ -76,6 +104,51 @@ def run_generate_documentation(args: argparse.Namespace) -> None:
|
|
|
76
104
|
generate_documentation(Path(args.output))
|
|
77
105
|
|
|
78
106
|
|
|
107
|
+
def _copy_resource_file(resource, rel_path: Path, output_file: Path) -> None:
|
|
108
|
+
"""Copy a file from a resource directory to an output location."""
|
|
109
|
+
content = resource.get_file(str(rel_path))
|
|
110
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
111
|
+
output_file.write_text(content, encoding="utf-8")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def run_generate_skill(args: argparse.Namespace) -> None:
|
|
115
|
+
"""Generate a Claude skill with QType documentation and examples.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
args: Command-line arguments with 'output' path.
|
|
119
|
+
"""
|
|
120
|
+
from qtype.mcp.server import _docs_resource, _examples_resource
|
|
121
|
+
|
|
122
|
+
output_path = Path(args.output) / "qtype-architect"
|
|
123
|
+
|
|
124
|
+
# Copy skill documentation files
|
|
125
|
+
skills_path = _docs_resource.get_path() / "skills" / "architect"
|
|
126
|
+
skill_count = 0
|
|
127
|
+
for skill_file in skills_path.rglob("*.*"):
|
|
128
|
+
rel_path = skill_file.relative_to(_docs_resource.get_path())
|
|
129
|
+
_copy_resource_file(
|
|
130
|
+
_docs_resource,
|
|
131
|
+
rel_path,
|
|
132
|
+
output_path / rel_path.relative_to("skills/architect"),
|
|
133
|
+
)
|
|
134
|
+
skill_count += 1
|
|
135
|
+
|
|
136
|
+
# Copy all example files
|
|
137
|
+
example_count = 0
|
|
138
|
+
for yaml_file in _examples_resource.get_path().rglob("*.yaml"):
|
|
139
|
+
rel_path = yaml_file.relative_to(_examples_resource.get_path())
|
|
140
|
+
if "legacy" not in rel_path.parts:
|
|
141
|
+
_copy_resource_file(
|
|
142
|
+
_examples_resource, rel_path, output_path / "assets" / rel_path
|
|
143
|
+
)
|
|
144
|
+
example_count += 1
|
|
145
|
+
|
|
146
|
+
logger.info(
|
|
147
|
+
f"Skill generated at {output_path}: "
|
|
148
|
+
f"{skill_count} docs, {example_count} examples"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
79
152
|
def generate_schema(args: argparse.Namespace) -> None:
|
|
80
153
|
"""Generate and output the JSON schema for Document.
|
|
81
154
|
|
|
@@ -118,8 +191,8 @@ def generate_schema(args: argparse.Namespace) -> None:
|
|
|
118
191
|
|
|
119
192
|
schema["$defs"]["qtype_env_var"] = {
|
|
120
193
|
"type": "string",
|
|
121
|
-
"pattern": "^.*\\$\\{[^}:]+(
|
|
122
|
-
"description": "String with environment variable substitution using ${VAR_NAME} or ${VAR_NAME
|
|
194
|
+
"pattern": "^.*\\$\\{[^}:]+(?::-[^}]*)?\\}.*$",
|
|
195
|
+
"description": "String with environment variable substitution using ${VAR_NAME} or ${VAR_NAME:-default} syntax",
|
|
123
196
|
}
|
|
124
197
|
|
|
125
198
|
output = json.dumps(schema, indent=2)
|
|
@@ -180,6 +253,20 @@ def parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
180
253
|
)
|
|
181
254
|
dsl_parser.set_defaults(func=run_generate_documentation)
|
|
182
255
|
|
|
256
|
+
# Parser for generating Agent skills
|
|
257
|
+
skill_parser = generate_subparsers.add_parser(
|
|
258
|
+
"skills",
|
|
259
|
+
help="Generates Agent skills with QType documentation and examples.",
|
|
260
|
+
)
|
|
261
|
+
skill_parser.add_argument(
|
|
262
|
+
"-o",
|
|
263
|
+
"--output",
|
|
264
|
+
type=str,
|
|
265
|
+
default=".claude/skills",
|
|
266
|
+
help="Output directory for the skills (default: .claude/skills)",
|
|
267
|
+
)
|
|
268
|
+
skill_parser.set_defaults(func=run_generate_skill)
|
|
269
|
+
|
|
183
270
|
# Parser for generating the semantic model
|
|
184
271
|
# only add this if networkx and ruff are installed
|
|
185
272
|
try:
|
qtype/commands/mcp.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for starting the QType MCP server.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from qtype.mcp.server import mcp
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main(args: Any) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Start the QType MCP server with the specified transport.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
args: Arguments passed from the command line or calling context.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Update server settings with CLI arguments
|
|
25
|
+
mcp.settings.host = args.host
|
|
26
|
+
mcp.settings.port = args.port
|
|
27
|
+
|
|
28
|
+
logger.info(f"Starting QType MCP server with {args.transport} transport")
|
|
29
|
+
|
|
30
|
+
if args.transport in ("sse", "streamable-http"):
|
|
31
|
+
logger.info(f"Server will be available at {args.host}:{args.port}")
|
|
32
|
+
|
|
33
|
+
# Run the server with the specified transport
|
|
34
|
+
mcp.run(transport=args.transport)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def parser(subparsers: argparse._SubParsersAction) -> None:
|
|
38
|
+
"""Set up the mcp subcommand parser.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
subparsers: The subparsers object to add the command to.
|
|
42
|
+
"""
|
|
43
|
+
cmd_parser = subparsers.add_parser(
|
|
44
|
+
"mcp",
|
|
45
|
+
help="Start the QType MCP server for AI agent integration.",
|
|
46
|
+
)
|
|
47
|
+
cmd_parser.add_argument(
|
|
48
|
+
"-t",
|
|
49
|
+
"--transport",
|
|
50
|
+
type=str,
|
|
51
|
+
choices=["stdio", "sse", "streamable-http"],
|
|
52
|
+
default="stdio",
|
|
53
|
+
help="Transport protocol to use (default: stdio)",
|
|
54
|
+
)
|
|
55
|
+
cmd_parser.add_argument(
|
|
56
|
+
"--host",
|
|
57
|
+
type=str,
|
|
58
|
+
default="0.0.0.0",
|
|
59
|
+
help="Host to bind to for HTTP/SSE transports (default: 0.0.0.0)",
|
|
60
|
+
)
|
|
61
|
+
cmd_parser.add_argument(
|
|
62
|
+
"-p",
|
|
63
|
+
"--port",
|
|
64
|
+
type=int,
|
|
65
|
+
default=8000,
|
|
66
|
+
help="Port to bind to for HTTP/SSE transports (default: 8000)",
|
|
67
|
+
)
|
|
68
|
+
cmd_parser.set_defaults(func=main)
|
qtype/commands/run.py
CHANGED
|
@@ -11,11 +11,10 @@ import warnings
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
|
-
import pandas as pd
|
|
15
14
|
from pydantic.warnings import UnsupportedFieldAttributeWarning
|
|
16
15
|
|
|
17
|
-
from qtype.application.facade import QTypeFacade
|
|
18
16
|
from qtype.base.exceptions import InterpreterError, LoadError, ValidationError
|
|
17
|
+
from qtype.interpreter.converters import read_dataframe_from_file
|
|
19
18
|
|
|
20
19
|
logger = logging.getLogger(__name__)
|
|
21
20
|
|
|
@@ -29,50 +28,124 @@ for name in ["httpx", "urllib3", "qdrant_client", "opensearch"]:
|
|
|
29
28
|
logging.getLogger(name).setLevel(logging.WARNING)
|
|
30
29
|
|
|
31
30
|
|
|
32
|
-
def
|
|
33
|
-
"""
|
|
34
|
-
|
|
31
|
+
def register_telemetry(spec) -> None:
|
|
32
|
+
"""Register telemetry if enabled in the spec."""
|
|
33
|
+
from qtype.interpreter.telemetry import register
|
|
34
|
+
from qtype.semantic.model import Application as SemanticApplication
|
|
35
|
+
|
|
36
|
+
if isinstance(spec, SemanticApplication) and spec.telemetry:
|
|
37
|
+
logger.info(
|
|
38
|
+
f"Telemetry enabled with endpoint: {spec.telemetry.endpoint}"
|
|
39
|
+
)
|
|
40
|
+
secret_mgr = create_secret_manager_for_spec(spec)
|
|
41
|
+
register(spec.telemetry, secret_mgr, spec.id)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def create_secret_manager_for_spec(spec):
|
|
45
|
+
"""Create a secret manager based on the specification."""
|
|
46
|
+
from qtype.interpreter.base.secrets import create_secret_manager
|
|
47
|
+
from qtype.semantic.model import Application as SemanticApplication
|
|
48
|
+
|
|
49
|
+
if isinstance(spec, SemanticApplication):
|
|
50
|
+
return create_secret_manager(spec.secret_manager)
|
|
51
|
+
else:
|
|
52
|
+
raise ValueError(
|
|
53
|
+
"Can't create secret manager for non-Application spec"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
async def execute_workflow(
|
|
58
|
+
path: Path,
|
|
59
|
+
inputs: dict | Any,
|
|
60
|
+
flow_name: str | None = None,
|
|
61
|
+
**kwargs: Any,
|
|
62
|
+
) -> Any:
|
|
63
|
+
"""Execute a complete workflow from document to results.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
path: Path to the QType specification file
|
|
67
|
+
inputs: Dictionary of input values or DataFrame for batch
|
|
68
|
+
flow_name: Optional name of flow to execute
|
|
69
|
+
**kwargs: Additional dependencies for execution
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
DataFrame with results (one row per input)
|
|
35
73
|
"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
74
|
+
import pandas as pd
|
|
75
|
+
from opentelemetry import trace
|
|
76
|
+
|
|
77
|
+
from qtype.interpreter.base.executor_context import ExecutorContext
|
|
78
|
+
from qtype.interpreter.converters import (
|
|
79
|
+
dataframe_to_flow_messages,
|
|
80
|
+
flow_messages_to_dataframe,
|
|
81
|
+
)
|
|
82
|
+
from qtype.interpreter.flow import run_flow
|
|
83
|
+
from qtype.interpreter.types import Session
|
|
84
|
+
from qtype.semantic.loader import load
|
|
85
|
+
from qtype.semantic.model import Application as SemanticApplication
|
|
86
|
+
|
|
87
|
+
# Load the semantic application
|
|
88
|
+
semantic_model, type_registry = load(path)
|
|
89
|
+
assert isinstance(semantic_model, SemanticApplication)
|
|
90
|
+
register_telemetry(semantic_model)
|
|
91
|
+
|
|
92
|
+
# Find the flow to execute
|
|
93
|
+
if flow_name:
|
|
94
|
+
target_flow = None
|
|
95
|
+
for flow in semantic_model.flows:
|
|
96
|
+
if flow.id == flow_name:
|
|
97
|
+
target_flow = flow
|
|
98
|
+
break
|
|
99
|
+
if target_flow is None:
|
|
100
|
+
raise ValueError(f"Flow '{flow_name}' not found")
|
|
101
|
+
else:
|
|
102
|
+
if semantic_model.flows:
|
|
103
|
+
target_flow = semantic_model.flows[0]
|
|
55
104
|
else:
|
|
56
|
-
raise ValueError(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
66
|
-
"application/vnd.ms-excel",
|
|
67
|
-
]:
|
|
68
|
-
return pd.read_excel(file_path)
|
|
69
|
-
elif mime_type in ["application/vnd.parquet", "application/octet-stream"]:
|
|
70
|
-
return pd.read_parquet(file_path)
|
|
105
|
+
raise ValueError("No flows found in application")
|
|
106
|
+
|
|
107
|
+
logger.info(f"Executing flow {target_flow.id} from {path}")
|
|
108
|
+
|
|
109
|
+
# Convert inputs to DataFrame (normalize single dict to 1-row DataFrame)
|
|
110
|
+
if isinstance(inputs, dict):
|
|
111
|
+
input_df = pd.DataFrame([inputs])
|
|
112
|
+
elif isinstance(inputs, pd.DataFrame):
|
|
113
|
+
input_df = inputs
|
|
71
114
|
else:
|
|
72
115
|
raise ValueError(
|
|
73
|
-
f"
|
|
116
|
+
f"Inputs must be dict or DataFrame, got {type(inputs)}"
|
|
74
117
|
)
|
|
75
118
|
|
|
119
|
+
# Create session
|
|
120
|
+
session = Session(
|
|
121
|
+
session_id=kwargs.pop("session_id", "default"),
|
|
122
|
+
conversation_history=kwargs.pop("conversation_history", []),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Convert DataFrame to FlowMessages with type conversion
|
|
126
|
+
initial_messages_list = dataframe_to_flow_messages(
|
|
127
|
+
input_df, target_flow.inputs, session=session
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Execute the flow
|
|
131
|
+
secret_manager = create_secret_manager_for_spec(semantic_model)
|
|
132
|
+
|
|
133
|
+
context = ExecutorContext(
|
|
134
|
+
secret_manager=secret_manager,
|
|
135
|
+
tracer=trace.get_tracer(__name__),
|
|
136
|
+
)
|
|
137
|
+
results = await run_flow(
|
|
138
|
+
target_flow,
|
|
139
|
+
initial_messages_list,
|
|
140
|
+
context=context,
|
|
141
|
+
**kwargs,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Convert results back to DataFrame
|
|
145
|
+
results_df = flow_messages_to_dataframe(results, target_flow)
|
|
146
|
+
|
|
147
|
+
return results_df
|
|
148
|
+
|
|
76
149
|
|
|
77
150
|
def run_flow(args: Any) -> None:
|
|
78
151
|
"""Run a QType YAML spec file by executing its flows.
|
|
@@ -82,7 +155,6 @@ def run_flow(args: Any) -> None:
|
|
|
82
155
|
"""
|
|
83
156
|
import asyncio
|
|
84
157
|
|
|
85
|
-
facade = QTypeFacade()
|
|
86
158
|
spec_path = Path(args.spec)
|
|
87
159
|
|
|
88
160
|
try:
|
|
@@ -90,7 +162,7 @@ def run_flow(args: Any) -> None:
|
|
|
90
162
|
|
|
91
163
|
if args.input_file:
|
|
92
164
|
logger.info(f"Loading input data from file: {args.input_file}")
|
|
93
|
-
input: Any =
|
|
165
|
+
input: Any = read_dataframe_from_file(args.input_file)
|
|
94
166
|
else:
|
|
95
167
|
# Parse input JSON
|
|
96
168
|
try:
|
|
@@ -99,9 +171,9 @@ def run_flow(args: Any) -> None:
|
|
|
99
171
|
logger.error(f"❌ Invalid JSON input: {e}")
|
|
100
172
|
return
|
|
101
173
|
|
|
102
|
-
# Execute the workflow using the
|
|
174
|
+
# Execute the workflow using the standalone function
|
|
103
175
|
result_df = asyncio.run(
|
|
104
|
-
|
|
176
|
+
execute_workflow(
|
|
105
177
|
spec_path,
|
|
106
178
|
flow_name=args.flow,
|
|
107
179
|
inputs=input,
|
qtype/commands/validate.py
CHANGED
|
@@ -10,7 +10,7 @@ import sys
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
|
-
from qtype.base.exceptions import LoadError,
|
|
13
|
+
from qtype.base.exceptions import LoadError, ValidationError
|
|
14
14
|
from qtype.dsl.linker import DuplicateComponentError, ReferenceNotFoundError
|
|
15
15
|
from qtype.dsl.loader import YAMLLoadError
|
|
16
16
|
from qtype.dsl.model import Application as DSLApplication
|
|
@@ -60,9 +60,9 @@ def main(args: Any) -> None:
|
|
|
60
60
|
except ValidationError as e:
|
|
61
61
|
logger.error(f"❌ Validation failed: {e}")
|
|
62
62
|
sys.exit(1)
|
|
63
|
-
except SemanticError as e:
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
# except SemanticError as e:
|
|
64
|
+
# logger.error(f"❌ Semantic validation failed: {e}")
|
|
65
|
+
# sys.exit(1)
|
|
66
66
|
|
|
67
67
|
# If printing is requested, load and print the document
|
|
68
68
|
if args.print:
|