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.
Files changed (263) hide show
  1. qtype/` +0 -0
  2. qtype/application/__init__.py +0 -2
  3. qtype/application/converters/tools_from_api.py +67 -57
  4. qtype/application/converters/tools_from_module.py +66 -32
  5. qtype/base/types.py +6 -1
  6. qtype/commands/convert.py +3 -6
  7. qtype/commands/generate.py +97 -10
  8. qtype/commands/mcp.py +68 -0
  9. qtype/commands/run.py +116 -44
  10. qtype/commands/validate.py +4 -4
  11. qtype/docs/.pages +8 -0
  12. qtype/docs/Concepts/mental-model-and-philosophy.md +363 -0
  13. qtype/docs/Contributing/.pages +4 -0
  14. qtype/docs/Contributing/index.md +283 -0
  15. qtype/docs/Contributing/roadmap.md +81 -0
  16. qtype/docs/Decisions/ADR-001-Chat-vs-Completion-Endpoint-Features.md +56 -0
  17. qtype/docs/Gallery/dataflow_pipelines.md +81 -0
  18. qtype/docs/Gallery/dataflow_pipelines.mermaid +45 -0
  19. qtype/docs/Gallery/research_assistant.md +97 -0
  20. qtype/docs/Gallery/research_assistant.mermaid +42 -0
  21. qtype/docs/Gallery/simple_chatbot.md +38 -0
  22. qtype/docs/Gallery/simple_chatbot.mermaid +35 -0
  23. qtype/docs/How To/Authentication/configure_aws_authentication.md +60 -0
  24. qtype/docs/How To/Authentication/use_api_key_authentication.md +40 -0
  25. qtype/docs/How To/Command Line Usage/load_multiple_inputs_from_files.md +77 -0
  26. qtype/docs/How To/Command Line Usage/pass_inputs_on_the_cli.md +52 -0
  27. qtype/docs/How To/Command Line Usage/serve_with_auto_reload.md +27 -0
  28. qtype/docs/How To/Data Processing/adjust_concurrency.md +40 -0
  29. qtype/docs/How To/Data Processing/cache_step_results.md +71 -0
  30. qtype/docs/How To/Data Processing/decode_json_xml.md +24 -0
  31. qtype/docs/How To/Data Processing/explode_collections.md +40 -0
  32. qtype/docs/How To/Data Processing/gather_results.md +68 -0
  33. qtype/docs/How To/Data Processing/invoke_other_flows.md +71 -0
  34. qtype/docs/How To/Data Processing/load_data_from_athena.md +49 -0
  35. qtype/docs/How To/Data Processing/read_data_from_files.md +61 -0
  36. qtype/docs/How To/Data Processing/read_sql_databases.md +46 -0
  37. qtype/docs/How To/Data Processing/write_data_to_file.md +39 -0
  38. qtype/docs/How To/Invoke Models/call_large_language_models.md +51 -0
  39. qtype/docs/How To/Invoke Models/create_embeddings.md +49 -0
  40. qtype/docs/How To/Invoke Models/reuse_prompts_with_templates.md +38 -0
  41. qtype/docs/How To/Language Features/include_qtype_yaml.md +45 -0
  42. qtype/docs/How To/Language Features/include_raw_text_from_other_files.md +48 -0
  43. qtype/docs/How To/Language Features/reference_entities_by_id.md +51 -0
  44. qtype/docs/How To/Language Features/use_agent_skills.md +29 -0
  45. qtype/docs/How To/Language Features/use_environment_variables.md +48 -0
  46. qtype/docs/How To/Language Features/use_optional_variables.md +42 -0
  47. qtype/docs/How To/Language Features/use_qtype_mcp.md +59 -0
  48. qtype/docs/How To/Observability & Debugging/trace_calls_with_open_telemetry.md +49 -0
  49. qtype/docs/How To/Observability & Debugging/validate_qtype_yaml.md +36 -0
  50. qtype/docs/How To/Observability & Debugging/visualize_application_architecture.md +61 -0
  51. qtype/docs/How To/Observability & Debugging/visualize_example.mermaid +35 -0
  52. qtype/docs/How To/Qtype Server/flow_as_ui.png +0 -0
  53. qtype/docs/How To/Qtype Server/serve_flows_as_apis.md +40 -0
  54. qtype/docs/How To/Qtype Server/serve_flows_as_ui.md +41 -0
  55. qtype/docs/How To/Qtype Server/use_conversational_interfaces.md +56 -0
  56. qtype/docs/How To/Qtype Server/use_variables_with_ui_hints.md +48 -0
  57. qtype/docs/How To/Tools & Integration/bind_tool_inputs_and_outputs.md +47 -0
  58. qtype/docs/How To/Tools & Integration/create_tools_from_openapi_specifications.md +85 -0
  59. qtype/docs/How To/Tools & Integration/create_tools_from_python_modules.md +87 -0
  60. qtype/docs/Reference/cli.md +336 -0
  61. qtype/docs/Reference/plugins.md +99 -0
  62. qtype/docs/Reference/semantic-validation-rules.md +184 -0
  63. qtype/docs/Tutorials/.pages +1 -0
  64. qtype/docs/Tutorials/01-first-qtype-application.md +249 -0
  65. qtype/docs/Tutorials/02-conversational-chatbot.md +327 -0
  66. qtype/docs/Tutorials/03-structured-data.md +480 -0
  67. qtype/docs/Tutorials/04-tools-and-function-calling.md +476 -0
  68. qtype/docs/Tutorials/example_chat.png +0 -0
  69. qtype/docs/Tutorials/index.md +92 -0
  70. qtype/docs/components/APIKeyAuthProvider.md +7 -0
  71. qtype/docs/components/APITool.md +10 -0
  72. qtype/docs/components/AWSAuthProvider.md +13 -0
  73. qtype/docs/components/AWSSecretManager.md +5 -0
  74. qtype/docs/components/Agent.md +6 -0
  75. qtype/docs/components/Aggregate.md +7 -0
  76. qtype/docs/components/AggregateStats.md +7 -0
  77. qtype/docs/components/Application.md +22 -0
  78. qtype/docs/components/AuthorizationProvider.md +6 -0
  79. qtype/docs/components/AuthorizationProviderList.md +5 -0
  80. qtype/docs/components/BearerTokenAuthProvider.md +6 -0
  81. qtype/docs/components/BedrockReranker.md +8 -0
  82. qtype/docs/components/ChatContent.md +7 -0
  83. qtype/docs/components/ChatMessage.md +6 -0
  84. qtype/docs/components/Collect.md +6 -0
  85. qtype/docs/components/ConstantPath.md +5 -0
  86. qtype/docs/components/Construct.md +6 -0
  87. qtype/docs/components/CustomType.md +7 -0
  88. qtype/docs/components/Decoder.md +8 -0
  89. qtype/docs/components/DecoderFormat.md +8 -0
  90. qtype/docs/components/DocToTextConverter.md +7 -0
  91. qtype/docs/components/Document.md +7 -0
  92. qtype/docs/components/DocumentEmbedder.md +6 -0
  93. qtype/docs/components/DocumentIndex.md +7 -0
  94. qtype/docs/components/DocumentSearch.md +7 -0
  95. qtype/docs/components/DocumentSource.md +12 -0
  96. qtype/docs/components/DocumentSplitter.md +9 -0
  97. qtype/docs/components/Echo.md +8 -0
  98. qtype/docs/components/Embedding.md +7 -0
  99. qtype/docs/components/EmbeddingModel.md +6 -0
  100. qtype/docs/components/Explode.md +5 -0
  101. qtype/docs/components/FieldExtractor.md +21 -0
  102. qtype/docs/components/FileSource.md +6 -0
  103. qtype/docs/components/FileWriter.md +7 -0
  104. qtype/docs/components/Flow.md +14 -0
  105. qtype/docs/components/FlowInterface.md +7 -0
  106. qtype/docs/components/Index.md +8 -0
  107. qtype/docs/components/IndexUpsert.md +6 -0
  108. qtype/docs/components/InvokeEmbedding.md +7 -0
  109. qtype/docs/components/InvokeFlow.md +8 -0
  110. qtype/docs/components/InvokeTool.md +8 -0
  111. qtype/docs/components/LLMInference.md +9 -0
  112. qtype/docs/components/ListType.md +5 -0
  113. qtype/docs/components/Memory.md +8 -0
  114. qtype/docs/components/MessageRole.md +14 -0
  115. qtype/docs/components/Model.md +10 -0
  116. qtype/docs/components/ModelList.md +5 -0
  117. qtype/docs/components/OAuth2AuthProvider.md +9 -0
  118. qtype/docs/components/PrimitiveTypeEnum.md +20 -0
  119. qtype/docs/components/PromptTemplate.md +7 -0
  120. qtype/docs/components/PythonFunctionTool.md +7 -0
  121. qtype/docs/components/RAGChunk.md +7 -0
  122. qtype/docs/components/RAGDocument.md +10 -0
  123. qtype/docs/components/RAGSearchResult.md +8 -0
  124. qtype/docs/components/Reranker.md +5 -0
  125. qtype/docs/components/SQLSource.md +8 -0
  126. qtype/docs/components/Search.md +7 -0
  127. qtype/docs/components/SearchResult.md +7 -0
  128. qtype/docs/components/SecretManager.md +7 -0
  129. qtype/docs/components/SecretReference.md +7 -0
  130. qtype/docs/components/Source.md +5 -0
  131. qtype/docs/components/Step.md +8 -0
  132. qtype/docs/components/TelemetrySink.md +9 -0
  133. qtype/docs/components/Tool.md +9 -0
  134. qtype/docs/components/ToolList.md +5 -0
  135. qtype/docs/components/TypeList.md +5 -0
  136. qtype/docs/components/Variable.md +8 -0
  137. qtype/docs/components/VariableList.md +5 -0
  138. qtype/docs/components/VectorIndex.md +7 -0
  139. qtype/docs/components/VectorSearch.md +6 -0
  140. qtype/docs/components/VertexAuthProvider.md +9 -0
  141. qtype/docs/components/Writer.md +5 -0
  142. qtype/docs/example_ui.png +0 -0
  143. qtype/docs/index.md +81 -0
  144. qtype/docs/legacy_how_tos/.pages +6 -0
  145. qtype/docs/legacy_how_tos/Configuration/modular-yaml.md +366 -0
  146. qtype/docs/legacy_how_tos/Configuration/phoenix_projects.png +0 -0
  147. qtype/docs/legacy_how_tos/Configuration/phoenix_traces.png +0 -0
  148. qtype/docs/legacy_how_tos/Configuration/reference-by-id.md +251 -0
  149. qtype/docs/legacy_how_tos/Configuration/telemetry-setup.md +259 -0
  150. qtype/docs/legacy_how_tos/Data Types/custom-types.md +52 -0
  151. qtype/docs/legacy_how_tos/Data Types/domain-types.md +113 -0
  152. qtype/docs/legacy_how_tos/Debugging/visualize-apps.md +147 -0
  153. qtype/docs/legacy_how_tos/Tools/api-tools.md +29 -0
  154. qtype/docs/legacy_how_tos/Tools/python-tools.md +299 -0
  155. qtype/docs/skills/architect/SKILL.md +188 -0
  156. qtype/docs/skills/architect/references/cheatsheet.md +198 -0
  157. qtype/docs/skills/architect/references/patterns.md +29 -0
  158. qtype/docs/stylesheets/extra.css +27 -0
  159. qtype/dsl/custom_types.py +2 -1
  160. qtype/dsl/linker.py +23 -7
  161. qtype/dsl/loader.py +3 -3
  162. qtype/dsl/model.py +181 -67
  163. qtype/examples/authentication/aws_authentication.qtype.yaml +63 -0
  164. qtype/examples/conversational_ai/hello_world_chat.qtype.yaml +43 -0
  165. qtype/examples/conversational_ai/simple_chatbot.qtype.yaml +40 -0
  166. qtype/examples/data_processing/athena_query.qtype.yaml +56 -0
  167. qtype/examples/data_processing/batch_inputs.csv +5 -0
  168. qtype/examples/data_processing/batch_processing.qtype.yaml +54 -0
  169. qtype/examples/data_processing/cache_step_results.qtype.yaml +78 -0
  170. qtype/examples/data_processing/collect_results.qtype.yaml +55 -0
  171. qtype/examples/data_processing/create_sample_db.py +129 -0
  172. qtype/examples/data_processing/dataflow_pipelines.qtype.yaml +108 -0
  173. qtype/examples/data_processing/decode_json.qtype.yaml +23 -0
  174. qtype/examples/data_processing/explode_items.qtype.yaml +25 -0
  175. qtype/examples/data_processing/invoke_other_flows.qtype.yaml +98 -0
  176. qtype/examples/data_processing/read_file.qtype.yaml +60 -0
  177. qtype/examples/data_processing/reviews.db +0 -0
  178. qtype/examples/data_processing/sample_article.txt +1 -0
  179. qtype/examples/data_processing/sample_documents.jsonl +5 -0
  180. qtype/examples/invoke_models/create_embeddings.qtype.yaml +28 -0
  181. qtype/examples/invoke_models/simple_llm_call.qtype.yaml +32 -0
  182. qtype/examples/language_features/include_raw.qtype.yaml +27 -0
  183. qtype/examples/language_features/optional_variables.qtype.yaml +32 -0
  184. qtype/examples/language_features/story_prompt.txt +6 -0
  185. qtype/examples/language_features/ui_hints.qtype.yaml +52 -0
  186. qtype/examples/legacy/bedrock/data_analysis_with_telemetry.qtype.yaml +169 -0
  187. qtype/examples/legacy/bedrock/hello_world.qtype.yaml +39 -0
  188. qtype/examples/legacy/bedrock/hello_world_chat.qtype.yaml +37 -0
  189. qtype/examples/legacy/bedrock/hello_world_chat_with_telemetry.qtype.yaml +40 -0
  190. qtype/examples/legacy/bedrock/hello_world_chat_with_thinking.qtype.yaml +40 -0
  191. qtype/examples/legacy/bedrock/hello_world_completion.qtype.yaml +41 -0
  192. qtype/examples/legacy/bedrock/hello_world_completion_with_auth.qtype.yaml +44 -0
  193. qtype/examples/legacy/bedrock/simple_agent_chat.qtype.yaml +46 -0
  194. qtype/examples/legacy/chat_with_langfuse.qtype.yaml +50 -0
  195. qtype/examples/legacy/data/customers.csv +6 -0
  196. qtype/examples/legacy/data_processor.qtype.yaml +48 -0
  197. qtype/examples/legacy/echo/debug_example.qtype.yaml +59 -0
  198. qtype/examples/legacy/echo/prompt.qtype.yaml +22 -0
  199. qtype/examples/legacy/echo/readme.md +29 -0
  200. qtype/examples/legacy/echo/test.qtype.yaml +26 -0
  201. qtype/examples/legacy/echo/video.qtype.yaml +20 -0
  202. qtype/examples/legacy/field_extractor_example.qtype.yaml +137 -0
  203. qtype/examples/legacy/multi_flow_example.qtype.yaml +125 -0
  204. qtype/examples/legacy/openai/hello_world_chat.qtype.yaml +43 -0
  205. qtype/examples/legacy/openai/hello_world_chat_with_telemetry.qtype.yaml +46 -0
  206. qtype/examples/legacy/qtype_plugin_example.py +51 -0
  207. qtype/examples/legacy/rag.qtype.yaml +207 -0
  208. qtype/examples/legacy/sample_data.txt +43 -0
  209. qtype/examples/legacy/time_utilities.qtype.yaml +64 -0
  210. qtype/examples/legacy/vertex/README.md +11 -0
  211. qtype/examples/legacy/vertex/hello_world_chat.qtype.yaml +36 -0
  212. qtype/examples/legacy/vertex/hello_world_completion.qtype.yaml +40 -0
  213. qtype/examples/legacy/vertex/hello_world_completion_with_auth.qtype.yaml +45 -0
  214. qtype/examples/observability_debugging/trace_with_opentelemetry.qtype.yaml +40 -0
  215. qtype/examples/research_assistant/research_assistant.qtype.yaml +94 -0
  216. qtype/examples/research_assistant/tavily.oas.yaml +722 -0
  217. qtype/examples/research_assistant/tavily.qtype.yaml +216 -0
  218. qtype/examples/tutorials/01_hello_world.qtype.yaml +48 -0
  219. qtype/examples/tutorials/02_conversational_chat.qtype.yaml +37 -0
  220. qtype/examples/tutorials/03_structured_data.qtype.yaml +130 -0
  221. qtype/examples/tutorials/04_tools_and_function_calling.qtype.yaml +89 -0
  222. qtype/interpreter/api.py +4 -1
  223. qtype/interpreter/base/base_step_executor.py +3 -1
  224. qtype/interpreter/base/stream_emitter.py +19 -13
  225. qtype/interpreter/conversions.py +7 -3
  226. qtype/interpreter/converters.py +142 -26
  227. qtype/interpreter/executors/agent_executor.py +2 -3
  228. qtype/interpreter/executors/aggregate_executor.py +3 -4
  229. qtype/interpreter/executors/construct_executor.py +15 -15
  230. qtype/interpreter/executors/doc_to_text_executor.py +1 -3
  231. qtype/interpreter/executors/field_extractor_executor.py +13 -12
  232. qtype/interpreter/executors/file_source_executor.py +21 -34
  233. qtype/interpreter/executors/file_writer_executor.py +4 -4
  234. qtype/interpreter/executors/index_upsert_executor.py +1 -1
  235. qtype/interpreter/executors/invoke_embedding_executor.py +1 -4
  236. qtype/interpreter/executors/invoke_flow_executor.py +2 -2
  237. qtype/interpreter/executors/invoke_tool_executor.py +19 -18
  238. qtype/interpreter/executors/llm_inference_executor.py +16 -18
  239. qtype/interpreter/executors/prompt_template_executor.py +1 -3
  240. qtype/interpreter/executors/sql_source_executor.py +1 -1
  241. qtype/interpreter/resource_cache.py +3 -1
  242. qtype/interpreter/rich_progress.py +6 -3
  243. qtype/interpreter/stream/chat/converter.py +25 -17
  244. qtype/interpreter/stream/chat/ui_request_to_domain_type.py +2 -2
  245. qtype/interpreter/tools/function_tool_helper.py +11 -10
  246. qtype/interpreter/types.py +89 -4
  247. qtype/interpreter/typing.py +35 -38
  248. qtype/mcp/__init__.py +0 -0
  249. qtype/mcp/server.py +722 -0
  250. qtype/schema/qtype.schema.json +4016 -0
  251. qtype/semantic/checker.py +20 -1
  252. qtype/semantic/generate.py +6 -9
  253. qtype/semantic/model.py +26 -33
  254. qtype/semantic/resolver.py +7 -0
  255. qtype/semantic/visualize.py +45 -53
  256. {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/METADATA +65 -44
  257. qtype-0.1.13.dist-info/RECORD +352 -0
  258. {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/WHEEL +1 -2
  259. qtype/application/facade.py +0 -177
  260. qtype-0.1.11.dist-info/RECORD +0 -142
  261. qtype-0.1.11.dist-info/top_level.txt +0 -1
  262. {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/entry_points.txt +0 -0
  263. {qtype-0.1.11.dist-info → qtype-0.1.13.dist-info}/licenses/LICENSE +0 -0
@@ -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 = facade.generate_aws_bedrock_models()
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
- content = facade.convert_document(model_list)
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:default} syntax",
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 read_data_from_file(file_path: str) -> pd.DataFrame:
33
- """
34
- Reads a file into a pandas DataFrame based on its MIME type.
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
- from pathlib import Path
37
-
38
- import magic
39
-
40
- mime_type = magic.Magic(mime=True).from_file(file_path)
41
-
42
- if mime_type == "text/csv":
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("")
46
- elif mime_type == "text/plain":
47
- # For text/plain, use file extension to determine format
48
- file_ext = Path(file_path).suffix.lower()
49
- if file_ext == ".csv":
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("")
53
- elif file_ext == ".json":
54
- return pd.read_json(file_path)
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
- f"Unsupported text/plain file extension: {file_ext}. "
59
- "Supported extensions: .csv, .json"
60
- )
61
- )
62
- elif mime_type == "application/json":
63
- return pd.read_json(file_path)
64
- elif mime_type in [
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"Unsupported MIME type for file {file_path}: {mime_type}"
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 = read_data_from_file(args.input_file)
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 facade (now async, returns DataFrame)
174
+ # Execute the workflow using the standalone function
103
175
  result_df = asyncio.run(
104
- facade.execute_workflow(
176
+ execute_workflow(
105
177
  spec_path,
106
178
  flow_name=args.flow,
107
179
  inputs=input,
@@ -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, SemanticError, ValidationError
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
- logger.error(f"❌ Semantic validation failed: {e}")
65
- sys.exit(1)
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:
qtype/docs/.pages ADDED
@@ -0,0 +1,8 @@
1
+ nav:
2
+ - index.md
3
+ - Tutorials
4
+ - Gallery
5
+ - How To
6
+ - Concepts
7
+ - Reference
8
+ - Contributing