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/docs/index.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
**QType is a domain-specific language (DSL) for rapid prototyping of AI applications.**
|
|
4
|
+
It is designed to help developers define modular, composable AI systems using a structured YAML-based specification. QType supports models, prompts, tools, retrievers, and flow orchestration, and is extensible for code generation or live interpretation.
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
Install QType:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install qtype[interpreter]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Create a file `hello_world.qtype.yaml` that answers a question:
|
|
14
|
+
```yaml
|
|
15
|
+
id: hello_world
|
|
16
|
+
|
|
17
|
+
models:
|
|
18
|
+
- type: Model
|
|
19
|
+
id: gpt-4
|
|
20
|
+
provider: openai
|
|
21
|
+
model_id: gpt-4-turbo
|
|
22
|
+
|
|
23
|
+
flows:
|
|
24
|
+
- type: Flow
|
|
25
|
+
id: chat_example
|
|
26
|
+
description: A simple chat flow with OpenAI
|
|
27
|
+
interface:
|
|
28
|
+
type: Conversational
|
|
29
|
+
variables:
|
|
30
|
+
- id: user_message
|
|
31
|
+
type: ChatMessage
|
|
32
|
+
- id: response
|
|
33
|
+
type: ChatMessage
|
|
34
|
+
inputs:
|
|
35
|
+
- user_message
|
|
36
|
+
outputs:
|
|
37
|
+
- response
|
|
38
|
+
steps:
|
|
39
|
+
- type: LLMInference
|
|
40
|
+
id: llm_inference_step
|
|
41
|
+
model: gpt-4
|
|
42
|
+
system_message: "You are a helpful assistant."
|
|
43
|
+
inputs:
|
|
44
|
+
- user_message
|
|
45
|
+
outputs:
|
|
46
|
+
- response
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Put your OpenAI API key into your `.env` file:
|
|
50
|
+
```
|
|
51
|
+
echo "OPENAI_API_KEY=sk-..." >> .env
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Validate its semantic correctness:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
qtype validate hello_world.qtype.yaml
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You should see:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
INFO: ✅ Schema validation successful.
|
|
64
|
+
INFO: ✅ Model validation successful.
|
|
65
|
+
INFO: ✅ Language validation successful
|
|
66
|
+
INFO: ✅ Semantic validation successful
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Launch the interpreter:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
qtype serve hello_world.qtype.yaml
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
And go to [http://localhost:8000/ui](http://localhost:8000/ui) to see the user interface for your application:
|
|
77
|
+
|
|
78
|
+

|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Check out the [Tutorials](Tutorials/01-first-qtype-application.md) guide to learn more.
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Include References and use Modular YAML
|
|
2
|
+
|
|
3
|
+
QType supports including external files in your YAML specifications, allowing you to break large configurations into smaller, manageable modules and reuse common components across multiple applications.
|
|
4
|
+
|
|
5
|
+
## Include Directives
|
|
6
|
+
|
|
7
|
+
### `!include` - YAML File Inclusion
|
|
8
|
+
|
|
9
|
+
The `!include` directive loads and parses external YAML files, merging their content into your main specification:
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
# main.qtype.yaml
|
|
13
|
+
id: main_app
|
|
14
|
+
|
|
15
|
+
# Include reusable components from other files
|
|
16
|
+
auths: !include common/auth.qtype.yaml
|
|
17
|
+
models: !include common/models.qtype.yaml
|
|
18
|
+
tools: !include common/tools.qtype.yaml
|
|
19
|
+
## Conditional References
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
# common/models.qtype.yaml
|
|
24
|
+
- id: shared_gpt4
|
|
25
|
+
provider: openai
|
|
26
|
+
auth: shared_openai_auth
|
|
27
|
+
model_id: gpt-4
|
|
28
|
+
|
|
29
|
+
- id: shared_claude
|
|
30
|
+
provider: anthropic
|
|
31
|
+
auth: shared_anthropic_auth
|
|
32
|
+
model_id: claude-3-5-sonnet-20241022
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
# common/auth.qtype.yaml
|
|
37
|
+
- id: shared_openai_auth
|
|
38
|
+
type: api_key
|
|
39
|
+
api_key: ${OPENAI_KEY}
|
|
40
|
+
|
|
41
|
+
- id: shared_anthropic_auth
|
|
42
|
+
type: api_key
|
|
43
|
+
api_key: ${ANTHROPIC_KEY}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `!include_raw` - Raw Text Inclusion
|
|
47
|
+
|
|
48
|
+
The `!include_raw` directive loads external text files as raw strings, useful for prompts, templates, or documentation:
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
# Application with external prompt files
|
|
52
|
+
id: prompt_app
|
|
53
|
+
|
|
54
|
+
flows:
|
|
55
|
+
- id: chat_flow
|
|
56
|
+
steps:
|
|
57
|
+
- id: system_setup
|
|
58
|
+
model: gpt-4
|
|
59
|
+
system_message: !include_raw prompts/expert_assistant.txt
|
|
60
|
+
|
|
61
|
+
- id: user_interaction
|
|
62
|
+
model: gpt-4
|
|
63
|
+
template: !include_raw templates/response_format.txt
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```txt
|
|
67
|
+
# prompts/expert_assistant.txt
|
|
68
|
+
You are an expert AI assistant with deep knowledge across multiple domains.
|
|
69
|
+
Always provide accurate, helpful, and well-structured responses.
|
|
70
|
+
|
|
71
|
+
When answering questions:
|
|
72
|
+
|
|
73
|
+
1. Be concise but thorough
|
|
74
|
+
2. Provide examples when helpful
|
|
75
|
+
3. Cite sources when making factual claims
|
|
76
|
+
4. Ask for clarification if the question is ambiguous
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```txt
|
|
80
|
+
# templates/response_format.txt
|
|
81
|
+
Based on the user's question: "{user_question}s"
|
|
82
|
+
|
|
83
|
+
Please provide a response in the following format:
|
|
84
|
+
- **Summary**: Brief answer to the question
|
|
85
|
+
- **Details**: More comprehensive explanation
|
|
86
|
+
- **Examples**: Relevant examples if applicable
|
|
87
|
+
- **Next Steps**: Suggested follow-up actions
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## File Path Resolution
|
|
91
|
+
|
|
92
|
+
QType supports multiple path types and protocols:
|
|
93
|
+
|
|
94
|
+
### Local File Paths
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
# Relative paths (relative to the current YAML file)
|
|
98
|
+
models: !include ../shared/models.yaml
|
|
99
|
+
prompts: !include_raw ./prompts/system.txt
|
|
100
|
+
|
|
101
|
+
# Absolute paths
|
|
102
|
+
config: !include /etc/qtype/global-config.yaml
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Remote URLs
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
# HTTP/HTTPS URLs
|
|
109
|
+
shared_config: !include https://config.example.com/qtype/base.yaml
|
|
110
|
+
prompt_library: !include_raw https://prompts.example.com/expert-system.txt
|
|
111
|
+
|
|
112
|
+
# GitHub URLs (via fsspec)
|
|
113
|
+
tools: !include github://company/qtype-configs/main/tools.yaml
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Cloud Storage
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
# S3 URLs
|
|
120
|
+
production_config: !include s3://company-configs/qtype/prod.yaml
|
|
121
|
+
training_data: !include_raw s3://data-bucket/prompts/training.txt
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Environment-Specific Configurations
|
|
125
|
+
|
|
126
|
+
Use file inclusion to manage different environments:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
# base.qtype.yaml - Common configuration
|
|
130
|
+
id: my_app
|
|
131
|
+
|
|
132
|
+
# Include environment-specific overrides
|
|
133
|
+
models: !include environments/${ENV:-development}/models.yaml
|
|
134
|
+
auths: !include environments/${ENV:-development}/auth.yaml
|
|
135
|
+
|
|
136
|
+
flows:
|
|
137
|
+
- id: main_flow
|
|
138
|
+
steps:
|
|
139
|
+
- id: llm_step
|
|
140
|
+
model: primary_model
|
|
141
|
+
system_message: !include_raw prompts/base_system.txt
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
# environments/development/models.yaml
|
|
146
|
+
- id: primary_model
|
|
147
|
+
provider: openai
|
|
148
|
+
model_id: gpt-3.5-turbo # Cheaper for development
|
|
149
|
+
auth: dev_openai_auth
|
|
150
|
+
|
|
151
|
+
- id: secondary_model
|
|
152
|
+
provider: anthropic
|
|
153
|
+
model_id: claude-3-haiku-20240307 # Fast for testing
|
|
154
|
+
auth: dev_anthropic_auth
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
# environments/production/models.yaml
|
|
159
|
+
- id: primary_model
|
|
160
|
+
provider: openai
|
|
161
|
+
model_id: gpt-4o # Best quality for production
|
|
162
|
+
auth: prod_openai_auth
|
|
163
|
+
inference_params:
|
|
164
|
+
temperature: 0.1
|
|
165
|
+
max_tokens: 4000
|
|
166
|
+
|
|
167
|
+
- id: secondary_model
|
|
168
|
+
provider: anthropic
|
|
169
|
+
model_id: claude-3-5-sonnet-20241022 # High quality fallback
|
|
170
|
+
auth: prod_anthropic_auth
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Nested Inclusions
|
|
174
|
+
|
|
175
|
+
Files can include other files, creating a hierarchy of modular components:
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
# main.qtype.yaml
|
|
179
|
+
id: complex_app
|
|
180
|
+
flows: !include flows/index.yaml
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```yaml
|
|
184
|
+
# flows/index.yaml
|
|
185
|
+
- id: data_processing
|
|
186
|
+
description: !include_raw descriptions/data_processing.md
|
|
187
|
+
steps: !include flows/data_processing_steps.yaml
|
|
188
|
+
|
|
189
|
+
- id: user_interaction
|
|
190
|
+
description: !include_raw descriptions/user_interaction.md
|
|
191
|
+
steps: !include flows/user_interaction_steps.yaml
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
# flows/data_processing_steps.yaml
|
|
196
|
+
- id: extract_step
|
|
197
|
+
tools: !include ../tools/extraction.yaml
|
|
198
|
+
|
|
199
|
+
- id: transform_step
|
|
200
|
+
model: !include ../models/transformation_model.yaml
|
|
201
|
+
template: !include_raw ../templates/transform_prompt.txt
|
|
202
|
+
|
|
203
|
+
- id: load_step
|
|
204
|
+
tools: !include ../tools/database.yaml
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Component Libraries
|
|
208
|
+
|
|
209
|
+
Create reusable component libraries:
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
# libraries/ai-models.yaml
|
|
213
|
+
- id: gpt4_creative
|
|
214
|
+
provider: openai
|
|
215
|
+
model_id: gpt-4
|
|
216
|
+
auth: openai_auth
|
|
217
|
+
inference_params:
|
|
218
|
+
temperature: 0.8
|
|
219
|
+
max_tokens: 2000
|
|
220
|
+
|
|
221
|
+
- id: gpt4_analytical
|
|
222
|
+
provider: openai
|
|
223
|
+
model_id: gpt-4
|
|
224
|
+
auth: openai_auth
|
|
225
|
+
inference_params:
|
|
226
|
+
temperature: 0.1
|
|
227
|
+
max_tokens: 4000
|
|
228
|
+
|
|
229
|
+
- id: claude_creative
|
|
230
|
+
provider: anthropic
|
|
231
|
+
model_id: claude-3-5-sonnet-20241022
|
|
232
|
+
auth: anthropic_auth
|
|
233
|
+
inference_params:
|
|
234
|
+
temperature: 0.7
|
|
235
|
+
max_tokens: 8000
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
# libraries/common-tools.yaml
|
|
240
|
+
- id: web_search
|
|
241
|
+
name: search_web
|
|
242
|
+
description: Search the web for current information
|
|
243
|
+
endpoint: https://api.search.com/v1/search
|
|
244
|
+
method: GET
|
|
245
|
+
auth: search_api_auth
|
|
246
|
+
|
|
247
|
+
- id: email_sender
|
|
248
|
+
name: send_email
|
|
249
|
+
description: Send emails via SMTP
|
|
250
|
+
function_name: send_email
|
|
251
|
+
module_path: qtype.commons.email
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
```yaml
|
|
255
|
+
# applications/research-assistant.yaml
|
|
256
|
+
id: research_assistant
|
|
257
|
+
|
|
258
|
+
# Import component libraries
|
|
259
|
+
models: !include ../libraries/ai-models.yaml
|
|
260
|
+
tools: !include ../libraries/common-tools.yaml
|
|
261
|
+
|
|
262
|
+
flows:
|
|
263
|
+
- id: research_flow
|
|
264
|
+
steps:
|
|
265
|
+
- id: search_step
|
|
266
|
+
tools:
|
|
267
|
+
- web_search # From imported library
|
|
268
|
+
|
|
269
|
+
- id: analysis_step
|
|
270
|
+
model: gpt4_analytical # From imported library
|
|
271
|
+
system_message: !include_raw prompts/research_analysis.txt
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Best Practices
|
|
275
|
+
|
|
276
|
+
### 1. Organize by Logical Groupings
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
project/
|
|
280
|
+
├── qtype/
|
|
281
|
+
│ ├── main.qtype.yaml
|
|
282
|
+
│ ├── auth/
|
|
283
|
+
│ │ ├── development.yaml
|
|
284
|
+
│ │ └── production.yaml
|
|
285
|
+
│ ├── models/
|
|
286
|
+
│ │ ├── openai.yaml
|
|
287
|
+
│ │ └── anthropic.yaml
|
|
288
|
+
│ ├── tools/
|
|
289
|
+
│ │ ├── api-tools.yaml
|
|
290
|
+
│ │ └── python-tools.yaml
|
|
291
|
+
│ └── prompts/
|
|
292
|
+
│ ├── system-messages/
|
|
293
|
+
│ └── templates/
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 2. Use Consistent Naming Conventions
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
# ✅ Clear, consistent naming
|
|
300
|
+
models: !include models/openai-models.yaml
|
|
301
|
+
tools: !include tools/api-tools.yaml
|
|
302
|
+
prompts: !include_raw prompts/system-messages/expert.txt
|
|
303
|
+
|
|
304
|
+
# ❌ Inconsistent naming
|
|
305
|
+
models: !include models.yaml
|
|
306
|
+
tools: !include tool_definitions.yml
|
|
307
|
+
prompts: !include_raw prompt.txt
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### 3. Document File Dependencies
|
|
311
|
+
|
|
312
|
+
```yaml
|
|
313
|
+
# main.qtype.yaml
|
|
314
|
+
# Dependencies:
|
|
315
|
+
# - auth/production.yaml (auth providers)
|
|
316
|
+
# - models/openai.yaml (LLM models)
|
|
317
|
+
# - tools/api-tools.yaml (external API tools)
|
|
318
|
+
# - prompts/system.txt (system message)
|
|
319
|
+
|
|
320
|
+
id: production_app
|
|
321
|
+
auths: !include auth/production.yaml
|
|
322
|
+
models: !include models/openai.yaml
|
|
323
|
+
tools: !include tools/api-tools.yaml
|
|
324
|
+
|
|
325
|
+
flows:
|
|
326
|
+
- id: main_flow
|
|
327
|
+
steps:
|
|
328
|
+
- model: production_gpt4
|
|
329
|
+
system_message: !include_raw prompts/system.txt
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Security Considerations
|
|
333
|
+
|
|
334
|
+
### 1. Path Traversal Protection
|
|
335
|
+
QType resolves paths relative to the including file, preventing unauthorized access:
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
# Safe - resolves relative to current file
|
|
339
|
+
config: !include ../shared/config.yaml
|
|
340
|
+
|
|
341
|
+
# Potentially unsafe - absolute paths should be used carefully
|
|
342
|
+
config: !include /etc/passwd # Will fail with appropriate error
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 2. Environment Variable Security
|
|
346
|
+
Use environment variables for sensitive data in included files:
|
|
347
|
+
|
|
348
|
+
```yaml
|
|
349
|
+
# auth.yaml - Don't commit secrets
|
|
350
|
+
- id: production_auth
|
|
351
|
+
type: api_key
|
|
352
|
+
api_key: ${PROD_API_KEY} # Load from environment
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### 3. URL Validation
|
|
356
|
+
Remote URLs are validated and must use secure protocols where appropriate:
|
|
357
|
+
|
|
358
|
+
```yaml
|
|
359
|
+
# ✅ Secure HTTPS
|
|
360
|
+
config: !include https://secure-config.example.com/config.yaml
|
|
361
|
+
|
|
362
|
+
# ⚠️ HTTP should be avoided for sensitive configs
|
|
363
|
+
config: !include http://config.example.com/config.yaml
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
File inclusion makes QType specifications more modular, maintainable, and suitable for complex, multi-environment deployments while keeping sensitive information secure and configurations organized.
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Referencing Entities by ID
|
|
2
|
+
|
|
3
|
+
One of QType's core principles is the ability to define reusable components once and reference them by their unique ID throughout your application. This promotes modularity, reduces duplication, and makes your specifications easier to maintain and validate.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
QType uses a **"define once, reference by ID"** pattern for most components. Components are defined at the application level with a unique ID, then referenced by that ID (as a string) wherever they're needed.
|
|
8
|
+
|
|
9
|
+
The QType validation and resolution system automatically resolves ID references to their actual object definitions, ensuring all components are properly connected and that all references are valid.
|
|
10
|
+
|
|
11
|
+
## Basic Reference Pattern
|
|
12
|
+
|
|
13
|
+
### Models
|
|
14
|
+
|
|
15
|
+
Models are defined at the application level and referenced by ID:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
# ✅ Clean reference-based approach
|
|
19
|
+
id: my_app
|
|
20
|
+
|
|
21
|
+
models:
|
|
22
|
+
- type: Model # Type discriminator required
|
|
23
|
+
id: gpt-4
|
|
24
|
+
provider: openai
|
|
25
|
+
model_id: gpt-4-turbo
|
|
26
|
+
|
|
27
|
+
flows:
|
|
28
|
+
- type: Flow
|
|
29
|
+
id: my_flow
|
|
30
|
+
steps:
|
|
31
|
+
- type: LLMInference
|
|
32
|
+
id: step1
|
|
33
|
+
model: gpt-4 # Reference model by ID (string)
|
|
34
|
+
- type: LLMInference
|
|
35
|
+
id: step2
|
|
36
|
+
model: gpt-4 # Reuse the same model
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Authorization Providers
|
|
40
|
+
|
|
41
|
+
Authorization providers follow the same pattern:
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
authorization_providers:
|
|
45
|
+
- type: APIKeyAuthProvider
|
|
46
|
+
id: openai_auth
|
|
47
|
+
api_key: ${OPENAI_API_KEY}
|
|
48
|
+
|
|
49
|
+
models:
|
|
50
|
+
- type: Model
|
|
51
|
+
id: gpt-4
|
|
52
|
+
provider: openai
|
|
53
|
+
auth: openai_auth # Reference auth by ID
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Memory
|
|
57
|
+
|
|
58
|
+
Memory configurations are centralized and referenced by ID:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
memories:
|
|
62
|
+
- id: chat_memory
|
|
63
|
+
token_limit: 50000
|
|
64
|
+
|
|
65
|
+
flows:
|
|
66
|
+
- type: Flow
|
|
67
|
+
id: chat_flow
|
|
68
|
+
steps:
|
|
69
|
+
- type: LLMInference
|
|
70
|
+
model: gpt-4
|
|
71
|
+
memory: chat_memory # Reference memory by ID
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Variables
|
|
75
|
+
|
|
76
|
+
Variables are declared in the flow's `variables` section and referenced by ID in step inputs/outputs:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
flows:
|
|
80
|
+
- type: Flow
|
|
81
|
+
id: process_question
|
|
82
|
+
variables:
|
|
83
|
+
- id: user_question
|
|
84
|
+
type: text
|
|
85
|
+
- id: llm_response
|
|
86
|
+
type: text
|
|
87
|
+
- id: formatted_output
|
|
88
|
+
type: text
|
|
89
|
+
inputs:
|
|
90
|
+
- user_question
|
|
91
|
+
outputs:
|
|
92
|
+
- formatted_output
|
|
93
|
+
steps:
|
|
94
|
+
- type: LLMInference
|
|
95
|
+
id: llm_step
|
|
96
|
+
model: gpt-4
|
|
97
|
+
inputs:
|
|
98
|
+
- user_question # Reference by ID
|
|
99
|
+
outputs:
|
|
100
|
+
- llm_response # Reference by ID
|
|
101
|
+
|
|
102
|
+
- type: PromptTemplate
|
|
103
|
+
id: format_step
|
|
104
|
+
template: "Response: {llm_response}"
|
|
105
|
+
inputs:
|
|
106
|
+
- llm_response # Reuse the same variable
|
|
107
|
+
outputs:
|
|
108
|
+
- formatted_output
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Tools
|
|
112
|
+
|
|
113
|
+
Tools are defined at the application level and referenced by ID:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
tools:
|
|
117
|
+
- type: PythonFunctionTool
|
|
118
|
+
id: calculator
|
|
119
|
+
name: calculate
|
|
120
|
+
function_name: calculate
|
|
121
|
+
module_path: my_tools
|
|
122
|
+
|
|
123
|
+
flows:
|
|
124
|
+
- type: Flow
|
|
125
|
+
id: my_flow
|
|
126
|
+
steps:
|
|
127
|
+
- type: InvokeTool
|
|
128
|
+
tool: calculator # Reference by ID
|
|
129
|
+
- type: Agent
|
|
130
|
+
model: gpt-4
|
|
131
|
+
tools:
|
|
132
|
+
- calculator # Can also be used by agents
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Advanced Reference Patterns
|
|
136
|
+
|
|
137
|
+
### Custom Types and Complex Data Structures
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
id: type_reference_example
|
|
141
|
+
|
|
142
|
+
# Define reusable custom types
|
|
143
|
+
types:
|
|
144
|
+
- id: Person
|
|
145
|
+
properties:
|
|
146
|
+
name: text
|
|
147
|
+
age: int
|
|
148
|
+
email: text
|
|
149
|
+
- id: PersonList
|
|
150
|
+
properties:
|
|
151
|
+
items: list[Person]
|
|
152
|
+
|
|
153
|
+
# Define variables using custom types
|
|
154
|
+
variables:
|
|
155
|
+
- id: current_user
|
|
156
|
+
type: Person # Reference custom type by ID
|
|
157
|
+
- id: all_users
|
|
158
|
+
type: PersonList # Reference array type by ID
|
|
159
|
+
|
|
160
|
+
flows:
|
|
161
|
+
- id: user_management
|
|
162
|
+
steps:
|
|
163
|
+
- id: get_user
|
|
164
|
+
inputs:
|
|
165
|
+
- id: user_id
|
|
166
|
+
type: text
|
|
167
|
+
outputs:
|
|
168
|
+
- current_user # Uses Person type
|
|
169
|
+
|
|
170
|
+
- id: list_users
|
|
171
|
+
outputs:
|
|
172
|
+
- all_users # Uses PersonList type
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Best Practices
|
|
176
|
+
|
|
177
|
+
### 1. Define Components at the Appropriate Level
|
|
178
|
+
- **Application-level**: Components used across multiple flows
|
|
179
|
+
- **Flow-level**: Components specific to one flow
|
|
180
|
+
- **Step-level**: Simple, one-off configurations
|
|
181
|
+
|
|
182
|
+
### 2. Use Descriptive IDs
|
|
183
|
+
```yaml
|
|
184
|
+
# ✅ Clear and descriptive
|
|
185
|
+
models:
|
|
186
|
+
- id: openai_gpt4_chat
|
|
187
|
+
- id: anthropic_claude_reasoning
|
|
188
|
+
|
|
189
|
+
# ❌ Unclear
|
|
190
|
+
models:
|
|
191
|
+
- id: model1
|
|
192
|
+
- id: m2
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 3. Group Related Components
|
|
196
|
+
```yaml
|
|
197
|
+
# ✅ Well-organized
|
|
198
|
+
auths:
|
|
199
|
+
- id: openai_auth
|
|
200
|
+
- id: anthropic_auth
|
|
201
|
+
|
|
202
|
+
models:
|
|
203
|
+
- id: gpt4_model
|
|
204
|
+
auth: openai_auth
|
|
205
|
+
- id: claude_model
|
|
206
|
+
auth: anthropic_auth
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 4. Leverage References for Configuration Management
|
|
210
|
+
```yaml
|
|
211
|
+
# Different environments can reference different components
|
|
212
|
+
# development.qtype.yaml
|
|
213
|
+
models:
|
|
214
|
+
- id: main_model
|
|
215
|
+
provider: openai
|
|
216
|
+
model_id: gpt-3.5-turbo # Cheaper for dev
|
|
217
|
+
|
|
218
|
+
# production.qtype.yaml
|
|
219
|
+
models:
|
|
220
|
+
- id: main_model
|
|
221
|
+
provider: openai
|
|
222
|
+
model_id: gpt-4o # Better for prod
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Validation and Error Handling
|
|
226
|
+
|
|
227
|
+
QType's validation system ensures:
|
|
228
|
+
|
|
229
|
+
1. **Unique IDs**: No duplicate component IDs within the same scope
|
|
230
|
+
2. **Valid References**: All ID references resolve to actual components
|
|
231
|
+
3. **Type Safety**: Referenced components match expected types
|
|
232
|
+
|
|
233
|
+
Common validation errors:
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
# ❌ This will fail - duplicate ID
|
|
237
|
+
models:
|
|
238
|
+
- id: gpt-4
|
|
239
|
+
provider: openai
|
|
240
|
+
- id: gpt-4 # Error: Duplicate ID
|
|
241
|
+
provider: anthropic
|
|
242
|
+
|
|
243
|
+
# ❌ This will fail - missing reference
|
|
244
|
+
flows:
|
|
245
|
+
- id: my_flow
|
|
246
|
+
steps:
|
|
247
|
+
- model: nonexistent_model # Error: Reference not found
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The reference-by-ID system makes QType specifications more maintainable, reusable, and easier to understand by eliminating duplication and creating clear component relationships.
|
|
251
|
+
|