yera 0.1.0__py3-none-any.whl → 0.2.0__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 (192) hide show
  1. infra_mvp/base_client.py +29 -0
  2. infra_mvp/base_server.py +68 -0
  3. infra_mvp/monitoring/__init__.py +15 -0
  4. infra_mvp/monitoring/metrics.py +185 -0
  5. infra_mvp/stream/README.md +56 -0
  6. infra_mvp/stream/__init__.py +14 -0
  7. infra_mvp/stream/__main__.py +101 -0
  8. infra_mvp/stream/agents/demos/financial/chart_additions_plan.md +170 -0
  9. infra_mvp/stream/agents/demos/financial/portfolio_assistant_stream.json +1571 -0
  10. infra_mvp/stream/agents/reference/blocks/action.json +170 -0
  11. infra_mvp/stream/agents/reference/blocks/button.json +66 -0
  12. infra_mvp/stream/agents/reference/blocks/date.json +65 -0
  13. infra_mvp/stream/agents/reference/blocks/input_prompt.json +94 -0
  14. infra_mvp/stream/agents/reference/blocks/layout.json +288 -0
  15. infra_mvp/stream/agents/reference/blocks/markdown.json +344 -0
  16. infra_mvp/stream/agents/reference/blocks/slider.json +67 -0
  17. infra_mvp/stream/agents/reference/blocks/spinner.json +110 -0
  18. infra_mvp/stream/agents/reference/blocks/table.json +56 -0
  19. infra_mvp/stream/agents/reference/chat_dynamics/branching_test_stream.json +145 -0
  20. infra_mvp/stream/app.py +49 -0
  21. infra_mvp/stream/container.py +112 -0
  22. infra_mvp/stream/schemas/__init__.py +16 -0
  23. infra_mvp/stream/schemas/agent.py +24 -0
  24. infra_mvp/stream/schemas/interaction.py +28 -0
  25. infra_mvp/stream/schemas/session.py +30 -0
  26. infra_mvp/stream/server.py +321 -0
  27. infra_mvp/stream/services/__init__.py +12 -0
  28. infra_mvp/stream/services/agent_service.py +40 -0
  29. infra_mvp/stream/services/event_converter.py +83 -0
  30. infra_mvp/stream/services/session_service.py +247 -0
  31. yera/__init__.py +50 -1
  32. yera/agents/__init__.py +2 -0
  33. yera/agents/context.py +41 -0
  34. yera/agents/dataclasses.py +69 -0
  35. yera/agents/decorator.py +207 -0
  36. yera/agents/discovery.py +124 -0
  37. yera/agents/typing/__init__.py +0 -0
  38. yera/agents/typing/coerce.py +408 -0
  39. yera/agents/typing/utils.py +19 -0
  40. yera/agents/typing/validate.py +206 -0
  41. yera/cli.py +377 -0
  42. yera/config/__init__.py +1 -0
  43. yera/config/config_utils.py +164 -0
  44. yera/config/function_config.py +55 -0
  45. yera/config/logging.py +18 -0
  46. yera/config/tool_config.py +8 -0
  47. yera/config2/__init__.py +8 -0
  48. yera/config2/dataclasses.py +534 -0
  49. yera/config2/keyring.py +270 -0
  50. yera/config2/paths.py +28 -0
  51. yera/config2/read.py +113 -0
  52. yera/config2/setup.py +109 -0
  53. yera/config2/setup_handlers/__init__.py +1 -0
  54. yera/config2/setup_handlers/anthropic.py +126 -0
  55. yera/config2/setup_handlers/azure.py +236 -0
  56. yera/config2/setup_handlers/base.py +125 -0
  57. yera/config2/setup_handlers/llama_cpp.py +205 -0
  58. yera/config2/setup_handlers/ollama.py +157 -0
  59. yera/config2/setup_handlers/openai.py +137 -0
  60. yera/config2/write.py +87 -0
  61. yera/dsl/__init__.py +0 -0
  62. yera/dsl/functions.py +94 -0
  63. yera/dsl/struct.py +20 -0
  64. yera/dsl/workspace.py +79 -0
  65. yera/events/__init__.py +57 -0
  66. yera/events/blocks/__init__.py +68 -0
  67. yera/events/blocks/action.py +57 -0
  68. yera/events/blocks/bar_chart.py +92 -0
  69. yera/events/blocks/base/__init__.py +20 -0
  70. yera/events/blocks/base/base.py +166 -0
  71. yera/events/blocks/base/chart.py +288 -0
  72. yera/events/blocks/base/layout.py +111 -0
  73. yera/events/blocks/buttons.py +37 -0
  74. yera/events/blocks/columns.py +26 -0
  75. yera/events/blocks/container.py +24 -0
  76. yera/events/blocks/date_picker.py +50 -0
  77. yera/events/blocks/exit.py +39 -0
  78. yera/events/blocks/form.py +24 -0
  79. yera/events/blocks/input_echo.py +22 -0
  80. yera/events/blocks/input_request.py +31 -0
  81. yera/events/blocks/line_chart.py +97 -0
  82. yera/events/blocks/markdown.py +67 -0
  83. yera/events/blocks/slider.py +54 -0
  84. yera/events/blocks/spinner.py +55 -0
  85. yera/events/blocks/system_prompt.py +22 -0
  86. yera/events/blocks/table.py +291 -0
  87. yera/events/models/__init__.py +39 -0
  88. yera/events/models/block_data.py +112 -0
  89. yera/events/models/in_event.py +7 -0
  90. yera/events/models/out_event.py +75 -0
  91. yera/events/runtime.py +187 -0
  92. yera/events/stream.py +91 -0
  93. yera/models/__init__.py +0 -0
  94. yera/models/data_classes.py +20 -0
  95. yera/models/llm_atlas_proxy.py +44 -0
  96. yera/models/llm_context.py +99 -0
  97. yera/models/llm_interfaces/__init__.py +0 -0
  98. yera/models/llm_interfaces/anthropic.py +153 -0
  99. yera/models/llm_interfaces/aws_bedrock.py +14 -0
  100. yera/models/llm_interfaces/azure_openai.py +143 -0
  101. yera/models/llm_interfaces/base.py +26 -0
  102. yera/models/llm_interfaces/interface_registry.py +74 -0
  103. yera/models/llm_interfaces/llama_cpp.py +136 -0
  104. yera/models/llm_interfaces/mock.py +29 -0
  105. yera/models/llm_interfaces/ollama_interface.py +118 -0
  106. yera/models/llm_interfaces/open_ai.py +150 -0
  107. yera/models/llm_workspace.py +19 -0
  108. yera/models/model_atlas.py +139 -0
  109. yera/models/model_definition.py +38 -0
  110. yera/models/model_factory.py +33 -0
  111. yera/opaque/__init__.py +9 -0
  112. yera/opaque/base.py +20 -0
  113. yera/opaque/decorator.py +8 -0
  114. yera/opaque/markdown.py +57 -0
  115. yera/opaque/opaque_function.py +25 -0
  116. yera/tools/__init__.py +29 -0
  117. yera/tools/atlas_tool.py +20 -0
  118. yera/tools/base.py +24 -0
  119. yera/tools/decorated_tool.py +18 -0
  120. yera/tools/decorator.py +35 -0
  121. yera/tools/tool_atlas.py +51 -0
  122. yera/tools/tool_utils.py +361 -0
  123. yera/ui/dist/404.html +1 -0
  124. yera/ui/dist/__next.__PAGE__.txt +10 -0
  125. yera/ui/dist/__next._full.txt +23 -0
  126. yera/ui/dist/__next._head.txt +6 -0
  127. yera/ui/dist/__next._index.txt +5 -0
  128. yera/ui/dist/__next._tree.txt +7 -0
  129. yera/ui/dist/_next/static/chunks/4c4688e1ff21ad98.js +1 -0
  130. yera/ui/dist/_next/static/chunks/652cd53c27924d50.js +4 -0
  131. yera/ui/dist/_next/static/chunks/786d2107b51e8499.css +1 -0
  132. yera/ui/dist/_next/static/chunks/7de9141b1af425c3.js +1 -0
  133. yera/ui/dist/_next/static/chunks/87ef65064d3524c1.js +2 -0
  134. yera/ui/dist/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  135. yera/ui/dist/_next/static/chunks/a6dad97d9634a72d.js.map +1 -0
  136. yera/ui/dist/_next/static/chunks/c4c79d5d0b280aeb.js +1 -0
  137. yera/ui/dist/_next/static/chunks/dc2d2a247505d66f.css +5 -0
  138. yera/ui/dist/_next/static/chunks/f773f714b55ec620.js +37 -0
  139. yera/ui/dist/_next/static/chunks/turbopack-98b3031e1b1dbc33.js +4 -0
  140. yera/ui/dist/_next/static/lnhYLzJ1-a5EfNbW1uFF6/_buildManifest.js +11 -0
  141. yera/ui/dist/_next/static/lnhYLzJ1-a5EfNbW1uFF6/_clientMiddlewareManifest.json +1 -0
  142. yera/ui/dist/_next/static/lnhYLzJ1-a5EfNbW1uFF6/_ssgManifest.js +1 -0
  143. yera/ui/dist/_next/static/media/14e23f9b59180572-s.9c448f3c.woff2 +0 -0
  144. yera/ui/dist/_next/static/media/2a65768255d6b625-s.p.d19752fb.woff2 +0 -0
  145. yera/ui/dist/_next/static/media/2b2eb4836d2dad95-s.f36de3af.woff2 +0 -0
  146. yera/ui/dist/_next/static/media/31183d9fd602dc89-s.c4ff9b73.woff2 +0 -0
  147. yera/ui/dist/_next/static/media/3fcb63a1ac6a562e-s.2f77a576.woff2 +0 -0
  148. yera/ui/dist/_next/static/media/45ec8de98929b0f6-s.81056204.woff2 +0 -0
  149. yera/ui/dist/_next/static/media/4fa387ec64143e14-s.c1fdd6c2.woff2 +0 -0
  150. yera/ui/dist/_next/static/media/65c558afe41e89d6-s.e2c8389a.woff2 +0 -0
  151. yera/ui/dist/_next/static/media/67add6cc0f54b8cf-s.8ce53448.woff2 +0 -0
  152. yera/ui/dist/_next/static/media/7178b3e590c64307-s.b97b3418.woff2 +0 -0
  153. yera/ui/dist/_next/static/media/797e433ab948586e-s.p.dbea232f.woff2 +0 -0
  154. yera/ui/dist/_next/static/media/8a480f0b521d4e75-s.8e0177b5.woff2 +0 -0
  155. yera/ui/dist/_next/static/media/a8ff2d5d0ccb0d12-s.fc5b72a7.woff2 +0 -0
  156. yera/ui/dist/_next/static/media/aae5f0be330e13db-s.p.853e26d6.woff2 +0 -0
  157. yera/ui/dist/_next/static/media/b11a6ccf4a3edec7-s.2113d282.woff2 +0 -0
  158. yera/ui/dist/_next/static/media/b49b0d9b851e4899-s.4f3fa681.woff2 +0 -0
  159. yera/ui/dist/_next/static/media/bbc41e54d2fcbd21-s.799d8ef8.woff2 +0 -0
  160. yera/ui/dist/_next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2 +0 -0
  161. yera/ui/dist/_next/static/media/favicon.0b3bf435.ico +0 -0
  162. yera/ui/dist/_not-found/__next._full.txt +14 -0
  163. yera/ui/dist/_not-found/__next._head.txt +6 -0
  164. yera/ui/dist/_not-found/__next._index.txt +5 -0
  165. yera/ui/dist/_not-found/__next._not-found.__PAGE__.txt +5 -0
  166. yera/ui/dist/_not-found/__next._not-found.txt +4 -0
  167. yera/ui/dist/_not-found/__next._tree.txt +2 -0
  168. yera/ui/dist/_not-found.html +1 -0
  169. yera/ui/dist/_not-found.txt +14 -0
  170. yera/ui/dist/agent-icon.svg +3 -0
  171. yera/ui/dist/favicon.ico +0 -0
  172. yera/ui/dist/file.svg +1 -0
  173. yera/ui/dist/globe.svg +1 -0
  174. yera/ui/dist/index.html +1 -0
  175. yera/ui/dist/index.txt +23 -0
  176. yera/ui/dist/logo/full_logo.png +0 -0
  177. yera/ui/dist/logo/rune_logo.png +0 -0
  178. yera/ui/dist/logo/rune_logo_borderless.png +0 -0
  179. yera/ui/dist/logo/text_logo.png +0 -0
  180. yera/ui/dist/next.svg +1 -0
  181. yera/ui/dist/send.png +0 -0
  182. yera/ui/dist/send_single.png +0 -0
  183. yera/ui/dist/vercel.svg +1 -0
  184. yera/ui/dist/window.svg +1 -0
  185. yera/utils/__init__.py +1 -0
  186. yera/utils/path_utils.py +38 -0
  187. yera-0.2.0.dist-info/METADATA +65 -0
  188. yera-0.2.0.dist-info/RECORD +190 -0
  189. {yera-0.1.0.dist-info → yera-0.2.0.dist-info}/WHEEL +1 -1
  190. yera-0.2.0.dist-info/entry_points.txt +2 -0
  191. yera-0.1.0.dist-info/METADATA +0 -11
  192. yera-0.1.0.dist-info/RECORD +0 -4
@@ -0,0 +1,164 @@
1
+ import inspect
2
+ import textwrap
3
+ from collections.abc import Callable
4
+ from pathlib import Path
5
+ from typing import Any, TypeVar, get_type_hints
6
+
7
+ import tomllib
8
+ from pydantic import BaseModel, ValidationError
9
+
10
+ from yera.config.function_config import FunctionConfig, ParameterInfo, ParameterKind
11
+
12
+ TModel = TypeVar("TModel", bound=BaseModel)
13
+
14
+
15
+ def read_config_file(cfg_path: Path | str | None = None) -> str:
16
+ if cfg_path is None:
17
+ home = Path.home() / ".yera"
18
+ home.mkdir(parents=True, exist_ok=True)
19
+ cfg_path = home / "global_cfg.toml"
20
+
21
+ with open(cfg_path) as f:
22
+ return f.read()
23
+
24
+
25
+ def parse_toml_string(toml_str):
26
+ cfg = tomllib.loads(toml_str)
27
+ validate_config(cfg)
28
+ return cfg
29
+
30
+
31
+ def validate_config(cfg_obj):
32
+ if not isinstance(cfg_obj, dict):
33
+ raise TypeError("cfg_obj must be a dictionary")
34
+
35
+ if "models" not in cfg_obj or "agents" not in cfg_obj:
36
+ raise KeyError("Configuration must contain 'models' and 'agents' keys")
37
+
38
+
39
+ def validate_schema(d: dict, cls: type[BaseModel]) -> bool:
40
+ try:
41
+ cls.model_validate(d)
42
+ return True
43
+ except ValidationError:
44
+ return False
45
+
46
+
47
+ def build_config_map(cfg_obj, cls: type[TModel]) -> dict[str, TModel]:
48
+ def walk(val, results, path):
49
+ if not isinstance(val, dict):
50
+ raise TypeError(
51
+ f"Something's gone wrong. The input is not a dict: {type(val)} {val}"
52
+ )
53
+
54
+ if validate_schema(val, cls):
55
+ results[path] = cls.model_validate(val)
56
+ return results
57
+ for k, v in val.items():
58
+ results = walk(v, results, f"{path}.{k}" if path else k)
59
+
60
+ return results
61
+
62
+ return walk(cfg_obj, {}, "")
63
+
64
+
65
+ def _strip_decorators(source: str) -> str:
66
+ lines = source.splitlines()
67
+ # Remove leading decorators until we hit 'def'
68
+ body_start = 0
69
+ for i, line in enumerate(lines):
70
+ if line.lstrip().startswith("def "):
71
+ body_start = i
72
+ break
73
+ return "\n".join(lines[body_start:])
74
+
75
+
76
+ def _extract_function_body(source: str) -> str:
77
+ # source begins with 'def name(...):' line
78
+ lines = source.splitlines()
79
+ if not lines:
80
+ return ""
81
+ # Drop the signature line
82
+ body_lines = lines[1:]
83
+ # Dedent body
84
+ return textwrap.dedent("\n".join(body_lines)).rstrip()
85
+
86
+
87
+ def _type_annotation_to_str(annotation: Any) -> str:
88
+ if annotation is inspect.Signature.empty:
89
+ return "Any"
90
+ try:
91
+ if hasattr(annotation, "__origin__") and annotation.__origin__ is not None:
92
+ # This is a generic type like list[str], dict[str, int], etc.
93
+ return str(annotation)
94
+ if hasattr(annotation, "__name__"):
95
+ # This is a simple type like str, int, etc.
96
+ return annotation.__name__
97
+ # Fallback to string representation
98
+ return str(annotation)
99
+ except Exception:
100
+ return "Any"
101
+
102
+
103
+ def _map_parameter_kind_to_enum(kind: inspect._ParameterKind) -> ParameterKind:
104
+ """Convert inspect.Parameter.kind to our enum."""
105
+ mapping = {
106
+ inspect.Parameter.POSITIONAL_OR_KEYWORD: ParameterKind.POSITIONAL_OR_KEYWORD,
107
+ inspect.Parameter.VAR_POSITIONAL: ParameterKind.VAR_POSITIONAL,
108
+ inspect.Parameter.KEYWORD_ONLY: ParameterKind.KEYWORD_ONLY,
109
+ inspect.Parameter.VAR_KEYWORD: ParameterKind.VAR_KEYWORD,
110
+ }
111
+ return mapping[kind]
112
+
113
+
114
+ def extract_function_config(func: Callable) -> FunctionConfig:
115
+ def extract_content():
116
+ source = inspect.getsource(func)
117
+ source = _strip_decorators(source)
118
+ content = _extract_function_body(source)
119
+ return content
120
+
121
+ sig = inspect.signature(func)
122
+ type_hints = get_type_hints(func)
123
+
124
+ def extract_parameters():
125
+ parameters = []
126
+ for name, param in sig.parameters.items():
127
+ if name == "self":
128
+ continue
129
+
130
+ annotation = type_hints.get(name, inspect.Signature.empty)
131
+ type_annotation = _type_annotation_to_str(annotation)
132
+ kind = _map_parameter_kind_to_enum(param.kind)
133
+ default = (
134
+ param.default if param.default is not inspect.Signature.empty else None
135
+ )
136
+
137
+ parameters.append(
138
+ ParameterInfo(
139
+ name=name,
140
+ type_annotation=type_annotation,
141
+ kind=kind,
142
+ default=default,
143
+ )
144
+ )
145
+ return parameters
146
+
147
+ def extract_output_signature():
148
+ output_annotation = type_hints.get("return", inspect.Signature.empty)
149
+ output_signature = _type_annotation_to_str(output_annotation)
150
+ return output_signature
151
+
152
+ def extract_module_path():
153
+ module_path = getattr(func, "__module__", None)
154
+ if module_path == "__main__":
155
+ module_path = None # Don't store __main__ as it's not useful
156
+ return module_path
157
+
158
+ return FunctionConfig(
159
+ content=extract_content(),
160
+ name=func.__name__,
161
+ parameters=extract_parameters(),
162
+ output_signature=extract_output_signature(),
163
+ module_path=extract_module_path(),
164
+ )
@@ -0,0 +1,55 @@
1
+ import warnings
2
+ from enum import Enum
3
+ from typing import Any
4
+
5
+ from pydantic import BaseModel, field_validator
6
+
7
+
8
+ class ParameterKind(str, Enum):
9
+ POSITIONAL_OR_KEYWORD = "POSITIONAL_OR_KEYWORD"
10
+ VAR_POSITIONAL = "VAR_POSITIONAL" # *args
11
+ KEYWORD_ONLY = "KEYWORD_ONLY" # keyword-only parameters
12
+ VAR_KEYWORD = "VAR_KEYWORD" # **kwargs
13
+
14
+
15
+ class ParameterInfo(BaseModel):
16
+ name: str
17
+ type_annotation: str
18
+ kind: ParameterKind
19
+ default: Any | None = None
20
+
21
+ @field_validator("default")
22
+ @classmethod
23
+ def validate_default_for_kind(cls, v, info):
24
+ """Validate parameter defaults and warn about mutable defaults."""
25
+ if "kind" in info.data:
26
+ kind = info.data["kind"]
27
+ name = info.data.get("name", "unknown")
28
+
29
+ # Validate that VAR_POSITIONAL and VAR_KEYWORD cannot have non-None defaults
30
+ if (
31
+ kind in (ParameterKind.VAR_POSITIONAL, ParameterKind.VAR_KEYWORD)
32
+ and v is not None
33
+ ):
34
+ raise ValueError(
35
+ f"Parameter kind '{kind}' cannot have a default value (got {v})"
36
+ )
37
+
38
+ # Warn about mutable defaults (Python best practice violation)
39
+ if v is not None and isinstance(v, list | dict | set):
40
+ warnings.warn(
41
+ f"Parameter '{name}' has a mutable default value ({type(v).__name__}). "
42
+ f"This can lead to unexpected behavior as the same object is reused across calls. "
43
+ f"Consider using 'None' as default and creating a new object inside the function.",
44
+ UserWarning,
45
+ stacklevel=3,
46
+ )
47
+ return v
48
+
49
+
50
+ class FunctionConfig(BaseModel):
51
+ content: str
52
+ name: str
53
+ parameters: list[ParameterInfo] # Replaces input_signature and parameter_defaults
54
+ output_signature: str
55
+ module_path: str | None = None
yera/config/logging.py ADDED
@@ -0,0 +1,18 @@
1
+ from copy import deepcopy
2
+ from logging.config import dictConfig
3
+
4
+ from uvicorn.config import LOGGING_CONFIG
5
+
6
+ # Make a copy to avoid mutating the original
7
+ LOG_CONFIG = deepcopy(LOGGING_CONFIG)
8
+
9
+ # Add root logger configuration for your application logs
10
+ LOG_CONFIG["root"] = {
11
+ "level": "INFO",
12
+ "handlers": ["default"],
13
+ }
14
+
15
+
16
+ def setup_logging():
17
+ """Configure logging for the application."""
18
+ dictConfig(LOG_CONFIG)
@@ -0,0 +1,8 @@
1
+ from pydantic import BaseModel
2
+
3
+ from yera.config.function_config import FunctionConfig
4
+
5
+
6
+ class ToolConfig(BaseModel):
7
+ function_config: FunctionConfig
8
+ security_rank: int
@@ -0,0 +1,8 @@
1
+ """Configuration management for Yera.
2
+
3
+ This module handles configuration file management, credential storage,
4
+ and application settings.
5
+
6
+ """
7
+
8
+ __all__ = []