qtype 0.1.12__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 +28 -22
- qtype/application/converters/tools_from_module.py +66 -32
- qtype/commands/generate.py +90 -7
- qtype/commands/run.py +116 -44
- qtype/docs/.pages +8 -0
- {docs → qtype/docs}/Concepts/mental-model-and-philosophy.md +1 -1
- qtype/docs/Contributing/.pages +4 -0
- {docs → qtype/docs}/Contributing/index.md +8 -1
- {docs → qtype/docs}/Gallery/dataflow_pipelines.md +3 -2
- {docs → qtype/docs}/Gallery/research_assistant.md +3 -4
- {docs → qtype/docs}/Gallery/simple_chatbot.md +3 -1
- {docs → qtype/docs}/How To/Authentication/configure_aws_authentication.md +2 -2
- {docs → qtype/docs}/How To/Authentication/use_api_key_authentication.md +2 -2
- {docs → qtype/docs}/How To/Command Line Usage/load_multiple_inputs_from_files.md +24 -9
- {docs → qtype/docs}/How To/Command Line Usage/pass_inputs_on_the_cli.md +3 -3
- {docs → qtype/docs}/How To/Command Line Usage/serve_with_auto_reload.md +3 -2
- {docs → qtype/docs}/How To/Data Processing/adjust_concurrency.md +3 -4
- {docs → qtype/docs}/How To/Data Processing/cache_step_results.md +2 -2
- {docs → qtype/docs}/How To/Data Processing/decode_json_xml.md +1 -1
- {docs → qtype/docs}/How To/Data Processing/explode_collections.md +2 -2
- {docs → qtype/docs}/How To/Data Processing/gather_results.md +4 -4
- 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
- {docs → qtype/docs}/How To/Data Processing/read_sql_databases.md +2 -3
- {docs → qtype/docs}/How To/Data Processing/write_data_to_file.md +1 -2
- {docs → qtype/docs}/How To/Invoke Models/call_large_language_models.md +1 -1
- {docs → qtype/docs}/How To/Invoke Models/create_embeddings.md +1 -1
- {docs → qtype/docs}/How To/Invoke Models/reuse_prompts_with_templates.md +2 -3
- {docs → qtype/docs}/How To/Language Features/include_raw_text_from_other_files.md +2 -1
- {docs → qtype/docs}/How To/Language Features/reference_entities_by_id.md +2 -2
- qtype/docs/How To/Language Features/use_agent_skills.md +29 -0
- {docs → qtype/docs}/How To/Language Features/use_environment_variables.md +2 -1
- qtype/docs/How To/Language Features/use_optional_variables.md +42 -0
- {docs → qtype/docs}/How To/Language Features/use_qtype_mcp.md +4 -4
- {docs → qtype/docs}/How To/Observability & Debugging/trace_calls_with_open_telemetry.md +1 -1
- {docs → qtype/docs}/How To/Observability & Debugging/validate_qtype_yaml.md +3 -2
- {docs → qtype/docs}/How To/Observability & Debugging/visualize_application_architecture.md +1 -1
- {docs → qtype/docs}/How To/Qtype Server/serve_flows_as_apis.md +3 -3
- {docs → qtype/docs}/How To/Qtype Server/serve_flows_as_ui.md +2 -3
- {docs → qtype/docs}/How To/Qtype Server/use_conversational_interfaces.md +1 -4
- {docs → qtype/docs}/How To/Qtype Server/use_variables_with_ui_hints.md +3 -2
- {docs → qtype/docs}/How To/Tools & Integration/bind_tool_inputs_and_outputs.md +1 -2
- {docs → qtype/docs}/How To/Tools & Integration/create_tools_from_openapi_specifications.md +10 -14
- {docs → qtype/docs}/How To/Tools & Integration/create_tools_from_python_modules.md +5 -8
- {docs → qtype/docs}/Reference/cli.md +13 -15
- {docs → qtype/docs}/Reference/plugins.md +4 -0
- {docs → qtype/docs}/Reference/semantic-validation-rules.md +6 -1
- qtype/docs/Tutorials/.pages +1 -0
- {docs → qtype/docs}/Tutorials/01-first-qtype-application.md +3 -2
- {docs → qtype/docs}/Tutorials/02-conversational-chatbot.md +3 -3
- {docs → qtype/docs}/Tutorials/03-structured-data.md +9 -10
- {docs → qtype/docs}/Tutorials/04-tools-and-function-calling.md +12 -19
- {docs → qtype/docs}/components/APITool.md +1 -1
- qtype/docs/components/Aggregate.md +7 -0
- qtype/docs/components/Collect.md +6 -0
- qtype/docs/components/Construct.md +6 -0
- {docs → qtype/docs}/components/DocumentEmbedder.md +0 -1
- {docs → qtype/docs}/components/DocumentSplitter.md +0 -1
- qtype/docs/components/Explode.md +5 -0
- {docs → qtype/docs}/components/FieldExtractor.md +2 -1
- qtype/docs/components/InvokeFlow.md +8 -0
- qtype/docs/components/InvokeTool.md +8 -0
- {docs → qtype/docs}/components/PrimitiveTypeEnum.md +0 -1
- {docs → qtype/docs}/components/Source.md +0 -1
- {docs → qtype/docs}/components/Step.md +0 -1
- {docs → qtype/docs}/components/Tool.md +2 -2
- {docs → qtype/docs}/components/Variable.md +2 -0
- qtype/docs/legacy_how_tos/.pages +6 -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/linker.py +8 -0
- qtype/dsl/model.py +177 -84
- qtype/examples/data_processing/athena_query.qtype.yaml +56 -0
- qtype/examples/data_processing/batch_inputs.csv +5 -0
- qtype/examples/data_processing/create_sample_db.py +129 -0
- qtype/examples/data_processing/invoke_other_flows.qtype.yaml +98 -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/language_features/optional_variables.qtype.yaml +32 -0
- qtype/examples/language_features/story_prompt.txt +6 -0
- qtype/examples/legacy/data/customers.csv +6 -0
- qtype/examples/legacy/echo/readme.md +29 -0
- qtype/examples/legacy/qtype_plugin_example.py +51 -0
- qtype/examples/legacy/sample_data.txt +43 -0
- qtype/examples/legacy/vertex/README.md +11 -0
- qtype/examples/research_assistant/tavily.qtype.yaml +216 -0
- {examples → qtype/examples}/tutorials/03_structured_data.qtype.yaml +2 -2
- {examples → qtype/examples}/tutorials/04_tools_and_function_calling.qtype.yaml +5 -5
- qtype/interpreter/base/stream_emitter.py +19 -13
- 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 +18 -31
- 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/tools/function_tool_helper.py +11 -10
- qtype/interpreter/types.py +89 -4
- qtype/interpreter/typing.py +31 -32
- qtype/mcp/server.py +312 -57
- {schema → qtype/schema}/qtype.schema.json +77 -79
- qtype/semantic/checker.py +19 -0
- qtype/semantic/generate.py +3 -6
- qtype/semantic/model.py +26 -33
- qtype/semantic/resolver.py +7 -0
- qtype/semantic/visualize.py +8 -3
- {qtype-0.1.12.dist-info → qtype-0.1.13.dist-info}/METADATA +47 -46
- qtype-0.1.13.dist-info/RECORD +352 -0
- {qtype-0.1.12.dist-info → qtype-0.1.13.dist-info}/WHEEL +1 -2
- docs/How To/Data Processing/read_data_from_files.md +0 -35
- docs/components/Aggregate.md +0 -8
- docs/components/InvokeFlow.md +0 -8
- docs/components/InvokeTool.md +0 -8
- docs/components/ToolParameter.md +0 -6
- examples/research_assistant/tavily.qtype.yaml +0 -289
- qtype/application/facade.py +0 -177
- qtype-0.1.12.dist-info/RECORD +0 -325
- qtype-0.1.12.dist-info/top_level.txt +0 -1
- {docs → qtype/docs}/Contributing/roadmap.md +0 -0
- {docs → qtype/docs}/Decisions/ADR-001-Chat-vs-Completion-Endpoint-Features.md +0 -0
- {docs → qtype/docs}/Gallery/dataflow_pipelines.mermaid +0 -0
- {docs → qtype/docs}/Gallery/research_assistant.mermaid +0 -0
- {docs → qtype/docs}/Gallery/simple_chatbot.mermaid +0 -0
- {docs → qtype/docs}/How To/Language Features/include_qtype_yaml.md +0 -0
- {docs → qtype/docs}/How To/Observability & Debugging/visualize_example.mermaid +0 -0
- {docs → qtype/docs}/How To/Qtype Server/flow_as_ui.png +0 -0
- {docs → qtype/docs}/Tutorials/example_chat.png +0 -0
- {docs → qtype/docs}/Tutorials/index.md +0 -0
- {docs → qtype/docs}/components/APIKeyAuthProvider.md +0 -0
- {docs → qtype/docs}/components/AWSAuthProvider.md +0 -0
- {docs → qtype/docs}/components/AWSSecretManager.md +0 -0
- {docs → qtype/docs}/components/Agent.md +0 -0
- {docs → qtype/docs}/components/AggregateStats.md +0 -0
- {docs → qtype/docs}/components/Application.md +0 -0
- {docs → qtype/docs}/components/AuthorizationProvider.md +0 -0
- {docs → qtype/docs}/components/AuthorizationProviderList.md +0 -0
- {docs → qtype/docs}/components/BearerTokenAuthProvider.md +0 -0
- {docs → qtype/docs}/components/BedrockReranker.md +0 -0
- {docs → qtype/docs}/components/ChatContent.md +0 -0
- {docs → qtype/docs}/components/ChatMessage.md +0 -0
- {docs → qtype/docs}/components/ConstantPath.md +0 -0
- {docs → qtype/docs}/components/CustomType.md +0 -0
- {docs → qtype/docs}/components/Decoder.md +0 -0
- {docs → qtype/docs}/components/DecoderFormat.md +0 -0
- {docs → qtype/docs}/components/DocToTextConverter.md +0 -0
- {docs → qtype/docs}/components/Document.md +0 -0
- {docs → qtype/docs}/components/DocumentIndex.md +0 -0
- {docs → qtype/docs}/components/DocumentSearch.md +0 -0
- {docs → qtype/docs}/components/DocumentSource.md +0 -0
- {docs → qtype/docs}/components/Echo.md +0 -0
- {docs → qtype/docs}/components/Embedding.md +0 -0
- {docs → qtype/docs}/components/EmbeddingModel.md +0 -0
- {docs → qtype/docs}/components/FileSource.md +0 -0
- {docs → qtype/docs}/components/FileWriter.md +0 -0
- {docs → qtype/docs}/components/Flow.md +0 -0
- {docs → qtype/docs}/components/FlowInterface.md +0 -0
- {docs → qtype/docs}/components/Index.md +0 -0
- {docs → qtype/docs}/components/IndexUpsert.md +0 -0
- {docs → qtype/docs}/components/InvokeEmbedding.md +0 -0
- {docs → qtype/docs}/components/LLMInference.md +0 -0
- {docs → qtype/docs}/components/ListType.md +0 -0
- {docs → qtype/docs}/components/Memory.md +0 -0
- {docs → qtype/docs}/components/MessageRole.md +0 -0
- {docs → qtype/docs}/components/Model.md +0 -0
- {docs → qtype/docs}/components/ModelList.md +0 -0
- {docs → qtype/docs}/components/OAuth2AuthProvider.md +0 -0
- {docs → qtype/docs}/components/PromptTemplate.md +0 -0
- {docs → qtype/docs}/components/PythonFunctionTool.md +0 -0
- {docs → qtype/docs}/components/RAGChunk.md +0 -0
- {docs → qtype/docs}/components/RAGDocument.md +0 -0
- {docs → qtype/docs}/components/RAGSearchResult.md +0 -0
- {docs → qtype/docs}/components/Reranker.md +0 -0
- {docs → qtype/docs}/components/SQLSource.md +0 -0
- {docs → qtype/docs}/components/Search.md +0 -0
- {docs → qtype/docs}/components/SearchResult.md +0 -0
- {docs → qtype/docs}/components/SecretManager.md +0 -0
- {docs → qtype/docs}/components/SecretReference.md +0 -0
- {docs → qtype/docs}/components/TelemetrySink.md +0 -0
- {docs → qtype/docs}/components/ToolList.md +0 -0
- {docs → qtype/docs}/components/TypeList.md +0 -0
- {docs → qtype/docs}/components/VariableList.md +0 -0
- {docs → qtype/docs}/components/VectorIndex.md +0 -0
- {docs → qtype/docs}/components/VectorSearch.md +0 -0
- {docs → qtype/docs}/components/VertexAuthProvider.md +0 -0
- {docs → qtype/docs}/components/Writer.md +0 -0
- {docs → qtype/docs}/example_ui.png +0 -0
- {docs → qtype/docs}/index.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Configuration/modular-yaml.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Configuration/phoenix_projects.png +0 -0
- {docs → qtype/docs}/legacy_how_tos/Configuration/phoenix_traces.png +0 -0
- {docs → qtype/docs}/legacy_how_tos/Configuration/reference-by-id.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Configuration/telemetry-setup.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Data Types/custom-types.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Data Types/domain-types.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Debugging/visualize-apps.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Tools/api-tools.md +0 -0
- {docs → qtype/docs}/legacy_how_tos/Tools/python-tools.md +0 -0
- {examples → qtype/examples}/authentication/aws_authentication.qtype.yaml +0 -0
- {examples → qtype/examples}/conversational_ai/hello_world_chat.qtype.yaml +0 -0
- {examples → qtype/examples}/conversational_ai/simple_chatbot.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/batch_processing.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/cache_step_results.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/collect_results.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/dataflow_pipelines.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/decode_json.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/explode_items.qtype.yaml +0 -0
- {examples → qtype/examples}/data_processing/read_file.qtype.yaml +0 -0
- {examples → qtype/examples}/invoke_models/create_embeddings.qtype.yaml +0 -0
- {examples → qtype/examples}/invoke_models/simple_llm_call.qtype.yaml +0 -0
- {examples → qtype/examples}/language_features/include_raw.qtype.yaml +0 -0
- {examples → qtype/examples}/language_features/ui_hints.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/data_analysis_with_telemetry.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world_chat.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world_chat_with_telemetry.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world_chat_with_thinking.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world_completion.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/hello_world_completion_with_auth.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/bedrock/simple_agent_chat.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/chat_with_langfuse.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/data_processor.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/echo/debug_example.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/echo/prompt.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/echo/test.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/echo/video.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/field_extractor_example.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/multi_flow_example.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/openai/hello_world_chat.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/openai/hello_world_chat_with_telemetry.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/rag.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/time_utilities.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/vertex/hello_world_chat.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/vertex/hello_world_completion.qtype.yaml +0 -0
- {examples → qtype/examples}/legacy/vertex/hello_world_completion_with_auth.qtype.yaml +0 -0
- {examples → qtype/examples}/observability_debugging/trace_with_opentelemetry.qtype.yaml +0 -0
- {examples → qtype/examples}/research_assistant/research_assistant.qtype.yaml +0 -0
- {examples → qtype/examples}/research_assistant/tavily.oas.yaml +0 -0
- {examples → qtype/examples}/tutorials/01_hello_world.qtype.yaml +0 -0
- {examples → qtype/examples}/tutorials/02_conversational_chat.qtype.yaml +0 -0
- {qtype-0.1.12.dist-info → qtype-0.1.13.dist-info}/entry_points.txt +0 -0
- {qtype-0.1.12.dist-info → qtype-0.1.13.dist-info}/licenses/LICENSE +0 -0
qtype/`
ADDED
|
File without changes
|
qtype/application/__init__.py
CHANGED
|
@@ -26,7 +26,7 @@ from qtype.dsl.model import (
|
|
|
26
26
|
BearerTokenAuthProvider,
|
|
27
27
|
CustomType,
|
|
28
28
|
OAuth2AuthProvider,
|
|
29
|
-
|
|
29
|
+
Variable,
|
|
30
30
|
VariableType,
|
|
31
31
|
)
|
|
32
32
|
|
|
@@ -202,9 +202,9 @@ def create_tool_parameters_from_body(
|
|
|
202
202
|
existing_custom_types: dict[str, CustomType],
|
|
203
203
|
schema_name_map: dict[int, str],
|
|
204
204
|
default_param_name: str,
|
|
205
|
-
) ->
|
|
205
|
+
) -> list[Variable]:
|
|
206
206
|
"""
|
|
207
|
-
Convert an OpenAPI Response or RequestBody to a
|
|
207
|
+
Convert an OpenAPI Response or RequestBody to a list of Variables.
|
|
208
208
|
|
|
209
209
|
If the body has only one content type with an Object schema, flatten its properties
|
|
210
210
|
to individual parameters. Otherwise, create a single parameter with the body type.
|
|
@@ -216,18 +216,18 @@ def create_tool_parameters_from_body(
|
|
|
216
216
|
default_param_name: Name to use for non-flattened parameter
|
|
217
217
|
|
|
218
218
|
Returns:
|
|
219
|
-
|
|
219
|
+
List of Variable objects
|
|
220
220
|
"""
|
|
221
221
|
# Check if we have content to analyze
|
|
222
222
|
if not hasattr(oas, "content") or not oas.content:
|
|
223
|
-
return
|
|
223
|
+
return []
|
|
224
224
|
|
|
225
225
|
content = oas.content[0]
|
|
226
226
|
input_type = to_variable_type(
|
|
227
227
|
content, existing_custom_types, schema_name_map
|
|
228
228
|
)
|
|
229
229
|
|
|
230
|
-
# Convert CustomType to string ID for
|
|
230
|
+
# Convert CustomType to string ID for Variable
|
|
231
231
|
input_type_value = (
|
|
232
232
|
input_type.id if isinstance(input_type, CustomType) else input_type
|
|
233
233
|
)
|
|
@@ -240,7 +240,7 @@ def create_tool_parameters_from_body(
|
|
|
240
240
|
custom_type = existing_custom_types[input_type.id]
|
|
241
241
|
|
|
242
242
|
# Flatten the custom type properties to individual parameters
|
|
243
|
-
flattened_parameters =
|
|
243
|
+
flattened_parameters = []
|
|
244
244
|
for prop_name, prop_type_str in custom_type.properties.items():
|
|
245
245
|
# Check if the property is optional (has '?' suffix)
|
|
246
246
|
is_optional = prop_type_str.endswith("?")
|
|
@@ -248,8 +248,10 @@ def create_tool_parameters_from_body(
|
|
|
248
248
|
prop_type_str.rstrip("?") if is_optional else prop_type_str
|
|
249
249
|
)
|
|
250
250
|
|
|
251
|
-
flattened_parameters
|
|
252
|
-
|
|
251
|
+
flattened_parameters.append(
|
|
252
|
+
Variable.model_construct(
|
|
253
|
+
id=prop_name, type=clean_type, optional=is_optional
|
|
254
|
+
)
|
|
253
255
|
)
|
|
254
256
|
|
|
255
257
|
# remove the type from existing_custom_types to avoid confusion
|
|
@@ -258,11 +260,11 @@ def create_tool_parameters_from_body(
|
|
|
258
260
|
return flattened_parameters
|
|
259
261
|
|
|
260
262
|
# If not flattening, create a single parameter (e.g., for simple types or arrays)
|
|
261
|
-
return
|
|
262
|
-
|
|
263
|
-
type=input_type_value, optional=False
|
|
263
|
+
return [
|
|
264
|
+
Variable.model_construct(
|
|
265
|
+
id=default_param_name, type=input_type_value, optional=False
|
|
264
266
|
)
|
|
265
|
-
|
|
267
|
+
]
|
|
266
268
|
|
|
267
269
|
|
|
268
270
|
def to_api_tool(
|
|
@@ -297,7 +299,7 @@ def to_api_tool(
|
|
|
297
299
|
).replace("\n", " ")
|
|
298
300
|
|
|
299
301
|
# Process inputs from request body and parameters
|
|
300
|
-
inputs =
|
|
302
|
+
inputs = []
|
|
301
303
|
if operation.request_body and operation.request_body.content:
|
|
302
304
|
# Create input parameters from request body using the new function
|
|
303
305
|
input_params = create_tool_parameters_from_body(
|
|
@@ -306,27 +308,31 @@ def to_api_tool(
|
|
|
306
308
|
schema_name_map,
|
|
307
309
|
default_param_name="request",
|
|
308
310
|
)
|
|
309
|
-
inputs.
|
|
311
|
+
inputs.extend(input_params)
|
|
310
312
|
|
|
311
313
|
# Add path and query parameters as inputs
|
|
312
|
-
parameters =
|
|
314
|
+
parameters = []
|
|
313
315
|
for param in operation.parameters:
|
|
314
316
|
if param.schema:
|
|
315
317
|
param_type = _schema_to_qtype_type(
|
|
316
318
|
param.schema, existing_custom_types, schema_name_map
|
|
317
319
|
)
|
|
318
|
-
# Convert to appropriate type for
|
|
320
|
+
# Convert to appropriate type for Variable
|
|
319
321
|
param_type_value = (
|
|
320
322
|
param_type.id
|
|
321
323
|
if isinstance(param_type, CustomType)
|
|
322
324
|
else param_type
|
|
323
325
|
)
|
|
324
|
-
parameters
|
|
325
|
-
|
|
326
|
+
parameters.append(
|
|
327
|
+
Variable.model_construct(
|
|
328
|
+
id=param.name,
|
|
329
|
+
type=param_type_value,
|
|
330
|
+
optional=not param.required,
|
|
331
|
+
)
|
|
326
332
|
)
|
|
327
333
|
|
|
328
334
|
# Process outputs from responses
|
|
329
|
-
outputs =
|
|
335
|
+
outputs = []
|
|
330
336
|
# Find the success response (200-299 status codes) or default response
|
|
331
337
|
success_response = next(
|
|
332
338
|
(r for r in operation.responses if r.code and 200 <= r.code < 300),
|
|
@@ -339,9 +345,9 @@ def to_api_tool(
|
|
|
339
345
|
success_response,
|
|
340
346
|
existing_custom_types,
|
|
341
347
|
schema_name_map,
|
|
342
|
-
default_param_name="
|
|
348
|
+
default_param_name=f"{tool_id}_response",
|
|
343
349
|
)
|
|
344
|
-
outputs.
|
|
350
|
+
outputs.extend(output_params)
|
|
345
351
|
|
|
346
352
|
return APITool(
|
|
347
353
|
id=tool_id,
|
|
@@ -10,7 +10,7 @@ from qtype.dsl.model import (
|
|
|
10
10
|
CustomType,
|
|
11
11
|
ListType,
|
|
12
12
|
PythonFunctionTool,
|
|
13
|
-
|
|
13
|
+
Variable,
|
|
14
14
|
VariableType,
|
|
15
15
|
)
|
|
16
16
|
|
|
@@ -43,14 +43,19 @@ def tools_from_module(
|
|
|
43
43
|
f"No public functions found in module '{module_path}'"
|
|
44
44
|
)
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
# Registry of actual Pydantic classes for validation
|
|
47
|
+
custom_type_registry: dict[str, Type[BaseModel]] = {}
|
|
48
|
+
# CustomType instances for YAML output
|
|
49
|
+
custom_type_models: dict[str, CustomType] = {}
|
|
47
50
|
|
|
48
51
|
# Create Tool instances from functions
|
|
49
52
|
tools = [
|
|
50
|
-
_create_tool_from_function(
|
|
53
|
+
_create_tool_from_function(
|
|
54
|
+
func_name, func_info, custom_type_registry, custom_type_models
|
|
55
|
+
)
|
|
51
56
|
for func_name, func_info in functions.items()
|
|
52
57
|
]
|
|
53
|
-
return (tools, list(
|
|
58
|
+
return (tools, list(custom_type_models.values()))
|
|
54
59
|
except ImportError as e:
|
|
55
60
|
raise ImportError(f"Cannot import module '{module_path}': {e}") from e
|
|
56
61
|
|
|
@@ -116,7 +121,8 @@ def _get_module_functions(
|
|
|
116
121
|
def _create_tool_from_function(
|
|
117
122
|
func_name: str,
|
|
118
123
|
func_info: dict[str, Any],
|
|
119
|
-
|
|
124
|
+
custom_type_registry: dict[str, Type[BaseModel]],
|
|
125
|
+
custom_type_models: dict[str, CustomType],
|
|
120
126
|
) -> PythonFunctionTool:
|
|
121
127
|
"""
|
|
122
128
|
Convert function metadata into a Tool instance.
|
|
@@ -135,29 +141,38 @@ def _create_tool_from_function(
|
|
|
135
141
|
else f"Function {func_name}"
|
|
136
142
|
)
|
|
137
143
|
|
|
138
|
-
# Create input parameters
|
|
139
|
-
inputs =
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
# Create input parameters as list of Variables
|
|
145
|
+
inputs = [
|
|
146
|
+
Variable.model_validate(
|
|
147
|
+
{
|
|
148
|
+
"id": p["name"],
|
|
149
|
+
"type": _map_python_type_to_variable_type(
|
|
150
|
+
p["type"], custom_type_registry, custom_type_models
|
|
151
|
+
),
|
|
152
|
+
"optional": p["default"] != inspect.Parameter.empty,
|
|
153
|
+
},
|
|
154
|
+
context={"custom_types": custom_type_registry},
|
|
143
155
|
)
|
|
144
156
|
for p in func_info["parameters"]
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
# # quick hack
|
|
148
|
-
# for k, v in inputs.items():
|
|
149
|
-
# if inspect.isclass(v.type) and issubclass(v.type, BaseModel):
|
|
150
|
-
# v.type = str(v.type.__name__)
|
|
157
|
+
]
|
|
151
158
|
|
|
152
159
|
# Create output parameter based on return type
|
|
153
160
|
tool_id = func_info["module"] + "." + func_name
|
|
154
161
|
|
|
155
162
|
output_type = _map_python_type_to_variable_type(
|
|
156
|
-
func_info["return_type"],
|
|
163
|
+
func_info["return_type"], custom_type_registry, custom_type_models
|
|
157
164
|
)
|
|
158
165
|
|
|
159
|
-
outputs =
|
|
160
|
-
|
|
166
|
+
outputs = [
|
|
167
|
+
Variable.model_validate(
|
|
168
|
+
{
|
|
169
|
+
"id": f"{func_name}_result",
|
|
170
|
+
"type": output_type,
|
|
171
|
+
"optional": False,
|
|
172
|
+
},
|
|
173
|
+
context={"custom_types": custom_type_registry},
|
|
174
|
+
)
|
|
175
|
+
]
|
|
161
176
|
|
|
162
177
|
return PythonFunctionTool(
|
|
163
178
|
id=tool_id,
|
|
@@ -172,7 +187,8 @@ def _create_tool_from_function(
|
|
|
172
187
|
|
|
173
188
|
def _pydantic_to_custom_types(
|
|
174
189
|
model_cls: Type[BaseModel],
|
|
175
|
-
|
|
190
|
+
custom_type_registry: dict[str, Type[BaseModel]],
|
|
191
|
+
custom_type_models: dict[str, CustomType],
|
|
176
192
|
) -> str:
|
|
177
193
|
"""
|
|
178
194
|
Converts a Pydantic BaseModel class into a QType CustomType.
|
|
@@ -184,15 +200,20 @@ def _pydantic_to_custom_types(
|
|
|
184
200
|
|
|
185
201
|
Args:
|
|
186
202
|
model_cls: The Pydantic model class to convert.
|
|
203
|
+
custom_type_registry: Registry of actual Pydantic classes for validation
|
|
204
|
+
custom_type_models: Dictionary of CustomType models for YAML output
|
|
187
205
|
|
|
188
206
|
Returns:
|
|
189
|
-
|
|
207
|
+
The model name as a string type reference
|
|
190
208
|
"""
|
|
191
209
|
properties = {}
|
|
192
210
|
model_name = model_cls.__name__
|
|
193
|
-
if model_name in
|
|
211
|
+
if model_name in custom_type_registry:
|
|
194
212
|
return model_name # Already processed
|
|
195
213
|
|
|
214
|
+
# Register the actual class for validation
|
|
215
|
+
custom_type_registry[model_name] = model_cls
|
|
216
|
+
|
|
196
217
|
for field_name, field_info in model_cls.model_fields.items():
|
|
197
218
|
# Use the annotation (the type hint) for the field
|
|
198
219
|
field_type = field_info.annotation
|
|
@@ -202,22 +223,27 @@ def _pydantic_to_custom_types(
|
|
|
202
223
|
)
|
|
203
224
|
elif get_origin(field_type) is Union:
|
|
204
225
|
# Assume the union means it's optional
|
|
226
|
+
# TODO: support proper unions
|
|
205
227
|
field_type = [
|
|
206
228
|
t for t in get_args(field_type) if t is not type(None)
|
|
207
229
|
][0]
|
|
208
|
-
rv = _map_python_type_to_type_str(
|
|
230
|
+
rv = _map_python_type_to_type_str(
|
|
231
|
+
field_type, custom_type_registry, custom_type_models
|
|
232
|
+
)
|
|
209
233
|
properties[field_name] = f"{rv}?"
|
|
210
234
|
elif get_origin(field_type) is list:
|
|
211
235
|
inner_type = get_args(field_type)[0]
|
|
212
|
-
rv = _map_python_type_to_type_str(
|
|
236
|
+
rv = _map_python_type_to_type_str(
|
|
237
|
+
inner_type, custom_type_registry, custom_type_models
|
|
238
|
+
)
|
|
213
239
|
properties[field_name] = f"list[{rv}]"
|
|
214
240
|
else:
|
|
215
241
|
properties[field_name] = _map_python_type_to_type_str(
|
|
216
|
-
field_type,
|
|
242
|
+
field_type, custom_type_registry, custom_type_models
|
|
217
243
|
)
|
|
218
244
|
|
|
219
|
-
# Add the
|
|
220
|
-
|
|
245
|
+
# Add the CustomType model for YAML output
|
|
246
|
+
custom_type_models[model_name] = CustomType(
|
|
221
247
|
id=model_name,
|
|
222
248
|
properties=properties,
|
|
223
249
|
description=model_cls.__doc__ or f"Custom type for {model_name}",
|
|
@@ -227,7 +253,8 @@ def _pydantic_to_custom_types(
|
|
|
227
253
|
|
|
228
254
|
def _map_python_type_to_variable_type(
|
|
229
255
|
python_type: Any,
|
|
230
|
-
|
|
256
|
+
custom_type_registry: dict[str, Type[BaseModel]],
|
|
257
|
+
custom_type_models: dict[str, CustomType],
|
|
231
258
|
) -> str | VariableType:
|
|
232
259
|
"""
|
|
233
260
|
Map Python type annotations to QType VariableType.
|
|
@@ -248,7 +275,9 @@ def _map_python_type_to_variable_type(
|
|
|
248
275
|
element_type_annotation = args[0]
|
|
249
276
|
# Recursively map the element type
|
|
250
277
|
element_type = _map_python_type_to_variable_type(
|
|
251
|
-
element_type_annotation,
|
|
278
|
+
element_type_annotation,
|
|
279
|
+
custom_type_registry,
|
|
280
|
+
custom_type_models,
|
|
252
281
|
)
|
|
253
282
|
# Support lists of both primitive types and custom types
|
|
254
283
|
if isinstance(element_type, PrimitiveTypeEnum):
|
|
@@ -281,7 +310,9 @@ def _map_python_type_to_variable_type(
|
|
|
281
310
|
return python_type.__name__
|
|
282
311
|
elif inspect.isclass(python_type) and issubclass(python_type, BaseModel):
|
|
283
312
|
# If it's a Pydantic model, create or retrieve its CustomType definition
|
|
284
|
-
return _pydantic_to_custom_types(
|
|
313
|
+
return _pydantic_to_custom_types(
|
|
314
|
+
python_type, custom_type_registry, custom_type_models
|
|
315
|
+
)
|
|
285
316
|
raise ValueError(
|
|
286
317
|
f"Unsupported Python type '{python_type}' for VariableType mapping"
|
|
287
318
|
)
|
|
@@ -289,9 +320,12 @@ def _map_python_type_to_variable_type(
|
|
|
289
320
|
|
|
290
321
|
def _map_python_type_to_type_str(
|
|
291
322
|
python_type: Any,
|
|
292
|
-
|
|
323
|
+
custom_type_registry: dict[str, Type[BaseModel]],
|
|
324
|
+
custom_type_models: dict[str, CustomType],
|
|
293
325
|
) -> str:
|
|
294
|
-
var_type = _map_python_type_to_variable_type(
|
|
326
|
+
var_type = _map_python_type_to_variable_type(
|
|
327
|
+
python_type, custom_type_registry, custom_type_models
|
|
328
|
+
)
|
|
295
329
|
if isinstance(var_type, PrimitiveTypeEnum):
|
|
296
330
|
return var_type.value
|
|
297
331
|
elif inspect.isclass(python_type):
|
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=[
|
|
@@ -80,6 +104,51 @@ def run_generate_documentation(args: argparse.Namespace) -> None:
|
|
|
80
104
|
generate_documentation(Path(args.output))
|
|
81
105
|
|
|
82
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
|
+
|
|
83
152
|
def generate_schema(args: argparse.Namespace) -> None:
|
|
84
153
|
"""Generate and output the JSON schema for Document.
|
|
85
154
|
|
|
@@ -184,6 +253,20 @@ def parser(subparsers: argparse._SubParsersAction) -> None:
|
|
|
184
253
|
)
|
|
185
254
|
dsl_parser.set_defaults(func=run_generate_documentation)
|
|
186
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
|
+
|
|
187
270
|
# Parser for generating the semantic model
|
|
188
271
|
# only add this if networkx and ruff are installed
|
|
189
272
|
try:
|