qtype 0.0.1__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/__init__.py +0 -0
- qtype/cli.py +73 -0
- qtype/commands/__init__.py +5 -0
- qtype/commands/convert.py +76 -0
- qtype/commands/generate.py +107 -0
- qtype/commands/run.py +200 -0
- qtype/commands/validate.py +83 -0
- qtype/commons/__init__.py +0 -0
- qtype/commons/generate.py +88 -0
- qtype/commons/tools.py +192 -0
- qtype/converters/__init__.py +0 -0
- qtype/converters/tools_from_api.py +24 -0
- qtype/converters/tools_from_module.py +326 -0
- qtype/converters/types.py +20 -0
- qtype/dsl/__init__.py +1 -0
- qtype/dsl/base_types.py +31 -0
- qtype/dsl/document.py +108 -0
- qtype/dsl/domain_types.py +56 -0
- qtype/dsl/model.py +685 -0
- qtype/dsl/validator.py +439 -0
- qtype/interpreter/__init__.py +1 -0
- qtype/interpreter/api.py +104 -0
- qtype/interpreter/conversions.py +148 -0
- qtype/interpreter/exceptions.py +10 -0
- qtype/interpreter/flow.py +37 -0
- qtype/interpreter/resource_cache.py +37 -0
- qtype/interpreter/step.py +67 -0
- qtype/interpreter/steps/__init__.py +0 -0
- qtype/interpreter/steps/agent.py +114 -0
- qtype/interpreter/steps/condition.py +36 -0
- qtype/interpreter/steps/decoder.py +84 -0
- qtype/interpreter/steps/llm_inference.py +127 -0
- qtype/interpreter/steps/prompt_template.py +54 -0
- qtype/interpreter/steps/search.py +24 -0
- qtype/interpreter/steps/tool.py +53 -0
- qtype/interpreter/telemetry.py +16 -0
- qtype/interpreter/typing.py +78 -0
- qtype/loader.py +341 -0
- qtype/semantic/__init__.py +0 -0
- qtype/semantic/errors.py +4 -0
- qtype/semantic/generate.py +383 -0
- qtype/semantic/model.py +354 -0
- qtype/semantic/resolver.py +97 -0
- qtype-0.0.1.dist-info/METADATA +120 -0
- qtype-0.0.1.dist-info/RECORD +49 -0
- qtype-0.0.1.dist-info/WHEEL +5 -0
- qtype-0.0.1.dist-info/entry_points.txt +2 -0
- qtype-0.0.1.dist-info/licenses/LICENSE +202 -0
- qtype-0.0.1.dist-info/top_level.txt +1 -0
qtype/dsl/document.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, Type, Union, get_args, get_origin
|
|
4
|
+
|
|
5
|
+
import qtype.dsl.model as dsl
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _format_type_name(field_type: Any) -> str:
|
|
9
|
+
"""Format a type annotation for display in documentation."""
|
|
10
|
+
# Handle ForwardRef objects
|
|
11
|
+
if hasattr(field_type, "__forward_arg__"):
|
|
12
|
+
return str(field_type.__forward_arg__)
|
|
13
|
+
|
|
14
|
+
# Handle Union types (including | syntax)
|
|
15
|
+
origin = get_origin(field_type)
|
|
16
|
+
args = get_args(field_type)
|
|
17
|
+
|
|
18
|
+
if origin is Union or (
|
|
19
|
+
hasattr(field_type, "__class__")
|
|
20
|
+
and field_type.__class__.__name__ == "UnionType"
|
|
21
|
+
):
|
|
22
|
+
return " | ".join(_format_type_name(arg) for arg in args)
|
|
23
|
+
|
|
24
|
+
# Handle list types
|
|
25
|
+
if origin is list:
|
|
26
|
+
if args:
|
|
27
|
+
inner_type = _format_type_name(args[0])
|
|
28
|
+
return f"list[{inner_type}]"
|
|
29
|
+
return "list"
|
|
30
|
+
|
|
31
|
+
# Handle dict types
|
|
32
|
+
if origin is dict:
|
|
33
|
+
if len(args) == 2:
|
|
34
|
+
key_type = _format_type_name(args[0])
|
|
35
|
+
value_type = _format_type_name(args[1])
|
|
36
|
+
return f"dict[{key_type}, {value_type}]"
|
|
37
|
+
return "dict"
|
|
38
|
+
|
|
39
|
+
# Handle basic types
|
|
40
|
+
if hasattr(field_type, "__name__"):
|
|
41
|
+
type_name = field_type.__name__
|
|
42
|
+
if type_name == "NoneType":
|
|
43
|
+
return "None"
|
|
44
|
+
return str(type_name)
|
|
45
|
+
|
|
46
|
+
return str(field_type)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def generate_class_docstring(output_file: Path, cls: Type[Any]) -> None:
|
|
50
|
+
"""Generates markdown documentation for a given DSL class.
|
|
51
|
+
|
|
52
|
+
The generated markdown contains a table of the class members and their descriptions.
|
|
53
|
+
The docstring of the class is used as the main description.
|
|
54
|
+
The field descriptions from Pydantic model_fields are used to describe each member.
|
|
55
|
+
"""
|
|
56
|
+
class_name = cls.__name__
|
|
57
|
+
docstring = cls.__doc__ or "No documentation available."
|
|
58
|
+
|
|
59
|
+
with output_file.open("w", encoding="utf-8") as file:
|
|
60
|
+
file.write(f"# {class_name}\n\n{docstring}\n\n## Members\n")
|
|
61
|
+
|
|
62
|
+
# Handle Pydantic models by checking for model_fields
|
|
63
|
+
if hasattr(cls, "model_fields") and hasattr(cls, "__annotations__"):
|
|
64
|
+
# Process Pydantic model fields
|
|
65
|
+
for field_name in cls.__annotations__:
|
|
66
|
+
if field_name in cls.model_fields:
|
|
67
|
+
field_info = cls.model_fields[field_name]
|
|
68
|
+
field_type = field_info.annotation
|
|
69
|
+
field_description = getattr(
|
|
70
|
+
field_info, "description", None
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Format the type name for display
|
|
74
|
+
type_name = _format_type_name(field_type)
|
|
75
|
+
|
|
76
|
+
# Use field description or fallback
|
|
77
|
+
description = (
|
|
78
|
+
field_description or "(No documentation available.)"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
file.write(
|
|
82
|
+
f"- **{field_name}** (`{type_name}`): {description}\n"
|
|
83
|
+
)
|
|
84
|
+
else:
|
|
85
|
+
# Fallback to inspect.getmembers for non-Pydantic classes
|
|
86
|
+
members = inspect.getmembers(
|
|
87
|
+
cls, lambda a: not inspect.isroutine(a)
|
|
88
|
+
)
|
|
89
|
+
for name, value in members:
|
|
90
|
+
if not name.startswith("_"):
|
|
91
|
+
member_doc = (
|
|
92
|
+
value.__doc__ or "(No documentation available.)"
|
|
93
|
+
)
|
|
94
|
+
file.write(f"- **{name}**: {member_doc}\n")
|
|
95
|
+
|
|
96
|
+
file.write("\n---\n")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def generate_documentation(output_prefix: Path) -> None:
|
|
100
|
+
"""Generates markdown documentation for all DSL classes.
|
|
101
|
+
The documentation is saved in the specified output prefix directory.
|
|
102
|
+
Args:
|
|
103
|
+
output_prefix (Path): The directory where the documentation files will be saved.
|
|
104
|
+
"""
|
|
105
|
+
# Get all classes from the DSL model module
|
|
106
|
+
for name, cls in inspect.getmembers(dsl, inspect.isclass): # noqa: F821
|
|
107
|
+
if cls.__module__ == dsl.__name__ and not name.startswith("_"):
|
|
108
|
+
generate_class_docstring(output_prefix / f"{name}.md", cls)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from qtype.dsl.base_types import PrimitiveTypeEnum, StrictBaseModel
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Embedding(StrictBaseModel):
|
|
12
|
+
"""A standard, built-in representation of a vector embedding."""
|
|
13
|
+
|
|
14
|
+
vector: list[float] = Field(
|
|
15
|
+
..., description="The vector representation of the embedding."
|
|
16
|
+
)
|
|
17
|
+
source_text: str | None = Field(
|
|
18
|
+
None, description="The original text that was embedded."
|
|
19
|
+
)
|
|
20
|
+
metadata: dict[str, str] | None = Field(
|
|
21
|
+
None, description="Optional metadata associated with the embedding."
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MessageRole(str, Enum):
|
|
26
|
+
assistant = "assistant"
|
|
27
|
+
chatbot = "chatbot"
|
|
28
|
+
developer = "developer"
|
|
29
|
+
function = "function"
|
|
30
|
+
model = "model"
|
|
31
|
+
system = "system"
|
|
32
|
+
tool = "tool"
|
|
33
|
+
user = "user"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ChatContent(StrictBaseModel):
|
|
37
|
+
type: PrimitiveTypeEnum = Field(
|
|
38
|
+
..., description="The type of content, such as 'text', 'image', etc."
|
|
39
|
+
)
|
|
40
|
+
content: Any = Field(
|
|
41
|
+
...,
|
|
42
|
+
description="The actual content, which can be a string, image data, etc.",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ChatMessage(StrictBaseModel):
|
|
47
|
+
"""A standard, built-in representation of a chat message."""
|
|
48
|
+
|
|
49
|
+
role: MessageRole = Field(
|
|
50
|
+
...,
|
|
51
|
+
description="The role of the message sender (e.g., 'user', 'assistant').",
|
|
52
|
+
)
|
|
53
|
+
blocks: list[ChatContent] = Field(
|
|
54
|
+
...,
|
|
55
|
+
description="The content blocks of the chat message, which can include text, images, or other media.",
|
|
56
|
+
)
|