kiarina-llm 1.0.0__tar.gz

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.
@@ -0,0 +1,39 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.so
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .ruff_cache/
9
+ .mypy_cache/
10
+ .pytest_cache/
11
+ .coverage
12
+ coverage.xml
13
+ htmlcov/
14
+
15
+ # uv
16
+ .uv_cache/
17
+
18
+ # Virtual environments & config
19
+ .venv/
20
+ .env
21
+
22
+ # IDE
23
+ .vscode/
24
+ *.code-workspace
25
+
26
+ # OS
27
+ .DS_Store
28
+
29
+ # Project specific
30
+ *.log
31
+ tmp/
32
+ ai.yaml
33
+
34
+ # Test data
35
+ tests/data/large/
36
+
37
+ # mise tasks (always include)
38
+ !mise-tasks/
39
+ !mise-tasks/**
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [1.0.0] - 2025-09-09
11
+
12
+ ### Added
13
+ - Initial release of kiarina-llm
14
+ - RunContext management for LLM pipeline processing
15
+ - Type-safe FSName validation for filesystem-safe names
16
+ - Type-safe IDStr validation for identifiers
17
+ - Configuration management using pydantic-settings-manager
18
+ - Environment variable configuration support
19
+ - Runtime configuration overrides
20
+ - Cross-platform compatibility with Windows reserved name validation
21
+ - Full type hints and Pydantic validation
22
+ - Comprehensive test suite
23
+
24
+ ### Features
25
+ - **RunContext**: Structured context information holder
26
+ - Application author and name (filesystem safe)
27
+ - Tenant, user, agent, and runner identifiers
28
+ - Time zone and language settings
29
+ - Extensible metadata support
30
+ - **Type Safety**: Custom Pydantic types for validation
31
+ - FSName: Filesystem-safe names with cross-platform validation
32
+ - IDStr: Identifier strings with pattern validation
33
+ - **Configuration**: Flexible settings management
34
+ - Environment variable support with KIARINA_LLM_RUN_CONTEXT_ prefix
35
+ - Runtime configuration overrides
36
+ - Default value management
37
+
38
+ ### Dependencies
39
+ - pydantic>=2.10.1
40
+ - pydantic-settings>=2.10.1
41
+ - pydantic-settings-manager>=2.1.0
@@ -0,0 +1,286 @@
1
+ Metadata-Version: 2.4
2
+ Name: kiarina-llm
3
+ Version: 1.0.0
4
+ Summary: LLM utilities and context management for kiarina namespace
5
+ Project-URL: Homepage, https://github.com/kiarina/kiarina-python
6
+ Project-URL: Repository, https://github.com/kiarina/kiarina-python
7
+ Project-URL: Issues, https://github.com/kiarina/kiarina-python/issues
8
+ Project-URL: Changelog, https://github.com/kiarina/kiarina-python/blob/main/packages/kiarina-llm/CHANGELOG.md
9
+ Project-URL: Documentation, https://github.com/kiarina/kiarina-python/tree/main/packages/kiarina-llm#readme
10
+ Author-email: kiarina <kiarinadawa@gmail.com>
11
+ Maintainer-email: kiarina <kiarinadawa@gmail.com>
12
+ License: MIT
13
+ Keywords: agent,ai,context,llm,pydantic,runner,settings
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: pydantic-settings-manager>=2.1.0
26
+ Requires-Dist: pydantic-settings>=2.10.1
27
+ Requires-Dist: pydantic>=2.10.1
28
+ Description-Content-Type: text/markdown
29
+
30
+ # kiarina-llm
31
+
32
+ A Python library for LLM utilities and context management with type safety and configuration management.
33
+
34
+ ## Features
35
+
36
+ - **RunContext Management**: Structured context information for LLM pipeline processing
37
+ - **Type Safety**: Full type hints and Pydantic validation
38
+ - **Configuration Management**: Use `pydantic-settings-manager` for flexible configuration
39
+ - **Filesystem Safe Names**: Validated names for cross-platform compatibility
40
+ - **ID Validation**: Structured ID types with pattern validation
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install kiarina-llm
46
+ ```
47
+
48
+ ## Quick Start
49
+
50
+ ### Basic RunContext Usage
51
+
52
+ ```python
53
+ from kiarina.llm.run_context import create_run_context
54
+
55
+ # Create a run context with default settings
56
+ context = create_run_context(
57
+ tenant_id="tenant-123",
58
+ user_id="user-456",
59
+ agent_id="my-agent",
60
+ time_zone="Asia/Tokyo",
61
+ language="ja"
62
+ )
63
+
64
+ print(f"User: {context.user_id}")
65
+ print(f"Agent: {context.agent_id}")
66
+ print(f"Time Zone: {context.time_zone}")
67
+ print(f"Language: {context.language}")
68
+ ```
69
+
70
+ ### Configuration Management
71
+
72
+ ```python
73
+ from kiarina.llm.run_context import settings_manager
74
+
75
+ # Configure default values
76
+ settings_manager.user_config = {
77
+ "app_author": "MyCompany",
78
+ "app_name": "MyAIApp",
79
+ "tenant_id": "default-tenant",
80
+ "user_id": "default-user",
81
+ "time_zone": "America/New_York",
82
+ "language": "en"
83
+ }
84
+
85
+ # Create context with configured defaults
86
+ context = create_run_context(
87
+ agent_id="specialized-agent" # Override only specific values
88
+ )
89
+ ```
90
+
91
+ ### Environment Variable Configuration
92
+
93
+ Configure defaults using environment variables:
94
+
95
+ ```bash
96
+ export KIARINA_LLM_RUN_CONTEXT_APP_AUTHOR="MyCompany"
97
+ export KIARINA_LLM_RUN_CONTEXT_APP_NAME="MyAIApp"
98
+ export KIARINA_LLM_RUN_CONTEXT_TENANT_ID="prod-tenant"
99
+ export KIARINA_LLM_RUN_CONTEXT_TIME_ZONE="Asia/Tokyo"
100
+ export KIARINA_LLM_RUN_CONTEXT_LANGUAGE="ja"
101
+ ```
102
+
103
+ ## RunContext Fields
104
+
105
+ The `RunContext` model includes the following fields:
106
+
107
+ | Field | Type | Description | Example |
108
+ |-------|------|-------------|---------|
109
+ | `app_author` | `FSName` | Application author (filesystem safe) | `"MyCompany"` |
110
+ | `app_name` | `FSName` | Application name (filesystem safe) | `"MyAIApp"` |
111
+ | `tenant_id` | `IDStr` | Tenant identifier | `"tenant-123"` |
112
+ | `user_id` | `IDStr` | User identifier | `"user-456"` |
113
+ | `agent_id` | `IDStr` | Agent identifier | `"my-agent"` |
114
+ | `runner_id` | `IDStr` | Runner identifier | `"linux"` (auto-detected) |
115
+ | `time_zone` | `str` | IANA time zone | `"Asia/Tokyo"` |
116
+ | `language` | `str` | ISO 639-1 language code | `"ja"` |
117
+ | `metadata` | `dict[str, Any]` | Additional metadata | `{"version": "1.0"}` |
118
+
119
+ ## Type Validation
120
+
121
+ ### FSName (Filesystem Safe Name)
122
+
123
+ The `FSName` type ensures names are safe for use across different filesystems:
124
+
125
+ ```python
126
+ from kiarina.llm.run_context import create_run_context
127
+
128
+ # Valid names
129
+ context = create_run_context(
130
+ app_author="My Company", # Spaces allowed
131
+ app_name="My-App_v1.0" # Hyphens, underscores, dots allowed
132
+ )
133
+
134
+ # Invalid names (will raise ValidationError)
135
+ try:
136
+ create_run_context(app_author="My App.") # Ends with dot
137
+ except ValueError as e:
138
+ print(f"Validation error: {e}")
139
+
140
+ try:
141
+ create_run_context(app_author=".hidden") # Starts with dot
142
+ except ValueError as e:
143
+ print(f"Validation error: {e}")
144
+
145
+ try:
146
+ create_run_context(app_author="CON") # Windows reserved name
147
+ except ValueError as e:
148
+ print(f"Validation error: {e}")
149
+ ```
150
+
151
+ ### IDStr (ID String)
152
+
153
+ The `IDStr` type validates identifiers:
154
+
155
+ ```python
156
+ # Valid IDs
157
+ context = create_run_context(
158
+ tenant_id="tenant-123",
159
+ user_id="user.456",
160
+ agent_id="agent_v1.0"
161
+ )
162
+
163
+ # Invalid IDs (will raise ValidationError)
164
+ try:
165
+ create_run_context(tenant_id="") # Empty string
166
+ except ValueError as e:
167
+ print(f"Validation error: {e}")
168
+
169
+ try:
170
+ create_run_context(user_id="user@domain") # Invalid character
171
+ except ValueError as e:
172
+ print(f"Validation error: {e}")
173
+ ```
174
+
175
+ ## Advanced Usage
176
+
177
+ ### Custom Metadata
178
+
179
+ ```python
180
+ context = create_run_context(
181
+ tenant_id="tenant-123",
182
+ user_id="user-456",
183
+ metadata={
184
+ "session_id": "session-789",
185
+ "request_id": "req-abc123",
186
+ "version": "1.0.0",
187
+ "features": ["feature-a", "feature-b"]
188
+ }
189
+ )
190
+
191
+ print(f"Session: {context.metadata['session_id']}")
192
+ print(f"Features: {context.metadata['features']}")
193
+ ```
194
+
195
+ ### Integration with PlatformDirs
196
+
197
+ The `app_author` and `app_name` fields are designed to work with libraries like `platformdirs`:
198
+
199
+ ```python
200
+ from platformdirs import user_data_dir
201
+ from kiarina.llm.run_context import create_run_context
202
+
203
+ context = create_run_context(
204
+ app_author="MyCompany",
205
+ app_name="MyAIApp"
206
+ )
207
+
208
+ # Use with platformdirs
209
+ data_dir = user_data_dir(
210
+ appname=context.app_name,
211
+ appauthor=context.app_author
212
+ )
213
+ print(f"Data directory: {data_dir}")
214
+ ```
215
+
216
+ ## Configuration Reference
217
+
218
+ | Setting | Environment Variable | Default | Description |
219
+ |---------|---------------------|---------|-------------|
220
+ | `app_author` | `KIARINA_LLM_RUN_CONTEXT_APP_AUTHOR` | `"kiarina"` | Default application author |
221
+ | `app_name` | `KIARINA_LLM_RUN_CONTEXT_APP_NAME` | `"myaikit"` | Default application name |
222
+ | `tenant_id` | `KIARINA_LLM_RUN_CONTEXT_TENANT_ID` | `""` | Default tenant ID |
223
+ | `user_id` | `KIARINA_LLM_RUN_CONTEXT_USER_ID` | `""` | Default user ID |
224
+ | `agent_id` | `KIARINA_LLM_RUN_CONTEXT_AGENT_ID` | `""` | Default agent ID |
225
+ | `runner_id` | `KIARINA_LLM_RUN_CONTEXT_RUNNER_ID` | `platform.system().lower()` | Default runner ID |
226
+ | `time_zone` | `KIARINA_LLM_RUN_CONTEXT_TIME_ZONE` | `"UTC"` | Default time zone |
227
+ | `language` | `KIARINA_LLM_RUN_CONTEXT_LANGUAGE` | `"en"` | Default language |
228
+
229
+ ## Development
230
+
231
+ ### Prerequisites
232
+
233
+ - Python 3.12+
234
+
235
+ ### Setup
236
+
237
+ ```bash
238
+ # Clone the repository
239
+ git clone https://github.com/kiarina/kiarina-python.git
240
+ cd kiarina-python
241
+
242
+ # Setup development environment (installs tools, syncs dependencies, downloads test data)
243
+ mise run setup
244
+ ```
245
+
246
+ ### Running Tests
247
+
248
+ ```bash
249
+ # Run format, lint, type checks and tests
250
+ mise run package kiarina-llm
251
+
252
+ # Coverage report
253
+ mise run package:test kiarina-llm --coverage
254
+
255
+ # Run specific tests
256
+ uv run --group test pytest packages/kiarina-llm/tests/run_context/
257
+ ```
258
+
259
+ ## Dependencies
260
+
261
+ - [pydantic](https://docs.pydantic.dev/) - Data validation using Python type hints
262
+ - [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) - Settings management
263
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Advanced settings management
264
+
265
+ ## Roadmap
266
+
267
+ This package is in active development. Planned features include:
268
+
269
+ - **Chat Model Management**: Unified interface for different LLM providers
270
+ - **Agent Framework**: Tools for building LLM agents
271
+ - **Pipeline Management**: Workflow management for LLM processing
272
+ - **Memory Management**: Context and conversation memory handling
273
+ - **Tool Integration**: Framework for LLM tool calling
274
+
275
+ ## License
276
+
277
+ This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.
278
+
279
+ ## Contributing
280
+
281
+ This is a personal project, but contributions are welcome! Please feel free to submit issues or pull requests.
282
+
283
+ ## Related Projects
284
+
285
+ - [kiarina-python](https://github.com/kiarina/kiarina-python) - The main monorepo containing this package
286
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Configuration management library used by this package
@@ -0,0 +1,257 @@
1
+ # kiarina-llm
2
+
3
+ A Python library for LLM utilities and context management with type safety and configuration management.
4
+
5
+ ## Features
6
+
7
+ - **RunContext Management**: Structured context information for LLM pipeline processing
8
+ - **Type Safety**: Full type hints and Pydantic validation
9
+ - **Configuration Management**: Use `pydantic-settings-manager` for flexible configuration
10
+ - **Filesystem Safe Names**: Validated names for cross-platform compatibility
11
+ - **ID Validation**: Structured ID types with pattern validation
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install kiarina-llm
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### Basic RunContext Usage
22
+
23
+ ```python
24
+ from kiarina.llm.run_context import create_run_context
25
+
26
+ # Create a run context with default settings
27
+ context = create_run_context(
28
+ tenant_id="tenant-123",
29
+ user_id="user-456",
30
+ agent_id="my-agent",
31
+ time_zone="Asia/Tokyo",
32
+ language="ja"
33
+ )
34
+
35
+ print(f"User: {context.user_id}")
36
+ print(f"Agent: {context.agent_id}")
37
+ print(f"Time Zone: {context.time_zone}")
38
+ print(f"Language: {context.language}")
39
+ ```
40
+
41
+ ### Configuration Management
42
+
43
+ ```python
44
+ from kiarina.llm.run_context import settings_manager
45
+
46
+ # Configure default values
47
+ settings_manager.user_config = {
48
+ "app_author": "MyCompany",
49
+ "app_name": "MyAIApp",
50
+ "tenant_id": "default-tenant",
51
+ "user_id": "default-user",
52
+ "time_zone": "America/New_York",
53
+ "language": "en"
54
+ }
55
+
56
+ # Create context with configured defaults
57
+ context = create_run_context(
58
+ agent_id="specialized-agent" # Override only specific values
59
+ )
60
+ ```
61
+
62
+ ### Environment Variable Configuration
63
+
64
+ Configure defaults using environment variables:
65
+
66
+ ```bash
67
+ export KIARINA_LLM_RUN_CONTEXT_APP_AUTHOR="MyCompany"
68
+ export KIARINA_LLM_RUN_CONTEXT_APP_NAME="MyAIApp"
69
+ export KIARINA_LLM_RUN_CONTEXT_TENANT_ID="prod-tenant"
70
+ export KIARINA_LLM_RUN_CONTEXT_TIME_ZONE="Asia/Tokyo"
71
+ export KIARINA_LLM_RUN_CONTEXT_LANGUAGE="ja"
72
+ ```
73
+
74
+ ## RunContext Fields
75
+
76
+ The `RunContext` model includes the following fields:
77
+
78
+ | Field | Type | Description | Example |
79
+ |-------|------|-------------|---------|
80
+ | `app_author` | `FSName` | Application author (filesystem safe) | `"MyCompany"` |
81
+ | `app_name` | `FSName` | Application name (filesystem safe) | `"MyAIApp"` |
82
+ | `tenant_id` | `IDStr` | Tenant identifier | `"tenant-123"` |
83
+ | `user_id` | `IDStr` | User identifier | `"user-456"` |
84
+ | `agent_id` | `IDStr` | Agent identifier | `"my-agent"` |
85
+ | `runner_id` | `IDStr` | Runner identifier | `"linux"` (auto-detected) |
86
+ | `time_zone` | `str` | IANA time zone | `"Asia/Tokyo"` |
87
+ | `language` | `str` | ISO 639-1 language code | `"ja"` |
88
+ | `metadata` | `dict[str, Any]` | Additional metadata | `{"version": "1.0"}` |
89
+
90
+ ## Type Validation
91
+
92
+ ### FSName (Filesystem Safe Name)
93
+
94
+ The `FSName` type ensures names are safe for use across different filesystems:
95
+
96
+ ```python
97
+ from kiarina.llm.run_context import create_run_context
98
+
99
+ # Valid names
100
+ context = create_run_context(
101
+ app_author="My Company", # Spaces allowed
102
+ app_name="My-App_v1.0" # Hyphens, underscores, dots allowed
103
+ )
104
+
105
+ # Invalid names (will raise ValidationError)
106
+ try:
107
+ create_run_context(app_author="My App.") # Ends with dot
108
+ except ValueError as e:
109
+ print(f"Validation error: {e}")
110
+
111
+ try:
112
+ create_run_context(app_author=".hidden") # Starts with dot
113
+ except ValueError as e:
114
+ print(f"Validation error: {e}")
115
+
116
+ try:
117
+ create_run_context(app_author="CON") # Windows reserved name
118
+ except ValueError as e:
119
+ print(f"Validation error: {e}")
120
+ ```
121
+
122
+ ### IDStr (ID String)
123
+
124
+ The `IDStr` type validates identifiers:
125
+
126
+ ```python
127
+ # Valid IDs
128
+ context = create_run_context(
129
+ tenant_id="tenant-123",
130
+ user_id="user.456",
131
+ agent_id="agent_v1.0"
132
+ )
133
+
134
+ # Invalid IDs (will raise ValidationError)
135
+ try:
136
+ create_run_context(tenant_id="") # Empty string
137
+ except ValueError as e:
138
+ print(f"Validation error: {e}")
139
+
140
+ try:
141
+ create_run_context(user_id="user@domain") # Invalid character
142
+ except ValueError as e:
143
+ print(f"Validation error: {e}")
144
+ ```
145
+
146
+ ## Advanced Usage
147
+
148
+ ### Custom Metadata
149
+
150
+ ```python
151
+ context = create_run_context(
152
+ tenant_id="tenant-123",
153
+ user_id="user-456",
154
+ metadata={
155
+ "session_id": "session-789",
156
+ "request_id": "req-abc123",
157
+ "version": "1.0.0",
158
+ "features": ["feature-a", "feature-b"]
159
+ }
160
+ )
161
+
162
+ print(f"Session: {context.metadata['session_id']}")
163
+ print(f"Features: {context.metadata['features']}")
164
+ ```
165
+
166
+ ### Integration with PlatformDirs
167
+
168
+ The `app_author` and `app_name` fields are designed to work with libraries like `platformdirs`:
169
+
170
+ ```python
171
+ from platformdirs import user_data_dir
172
+ from kiarina.llm.run_context import create_run_context
173
+
174
+ context = create_run_context(
175
+ app_author="MyCompany",
176
+ app_name="MyAIApp"
177
+ )
178
+
179
+ # Use with platformdirs
180
+ data_dir = user_data_dir(
181
+ appname=context.app_name,
182
+ appauthor=context.app_author
183
+ )
184
+ print(f"Data directory: {data_dir}")
185
+ ```
186
+
187
+ ## Configuration Reference
188
+
189
+ | Setting | Environment Variable | Default | Description |
190
+ |---------|---------------------|---------|-------------|
191
+ | `app_author` | `KIARINA_LLM_RUN_CONTEXT_APP_AUTHOR` | `"kiarina"` | Default application author |
192
+ | `app_name` | `KIARINA_LLM_RUN_CONTEXT_APP_NAME` | `"myaikit"` | Default application name |
193
+ | `tenant_id` | `KIARINA_LLM_RUN_CONTEXT_TENANT_ID` | `""` | Default tenant ID |
194
+ | `user_id` | `KIARINA_LLM_RUN_CONTEXT_USER_ID` | `""` | Default user ID |
195
+ | `agent_id` | `KIARINA_LLM_RUN_CONTEXT_AGENT_ID` | `""` | Default agent ID |
196
+ | `runner_id` | `KIARINA_LLM_RUN_CONTEXT_RUNNER_ID` | `platform.system().lower()` | Default runner ID |
197
+ | `time_zone` | `KIARINA_LLM_RUN_CONTEXT_TIME_ZONE` | `"UTC"` | Default time zone |
198
+ | `language` | `KIARINA_LLM_RUN_CONTEXT_LANGUAGE` | `"en"` | Default language |
199
+
200
+ ## Development
201
+
202
+ ### Prerequisites
203
+
204
+ - Python 3.12+
205
+
206
+ ### Setup
207
+
208
+ ```bash
209
+ # Clone the repository
210
+ git clone https://github.com/kiarina/kiarina-python.git
211
+ cd kiarina-python
212
+
213
+ # Setup development environment (installs tools, syncs dependencies, downloads test data)
214
+ mise run setup
215
+ ```
216
+
217
+ ### Running Tests
218
+
219
+ ```bash
220
+ # Run format, lint, type checks and tests
221
+ mise run package kiarina-llm
222
+
223
+ # Coverage report
224
+ mise run package:test kiarina-llm --coverage
225
+
226
+ # Run specific tests
227
+ uv run --group test pytest packages/kiarina-llm/tests/run_context/
228
+ ```
229
+
230
+ ## Dependencies
231
+
232
+ - [pydantic](https://docs.pydantic.dev/) - Data validation using Python type hints
233
+ - [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) - Settings management
234
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Advanced settings management
235
+
236
+ ## Roadmap
237
+
238
+ This package is in active development. Planned features include:
239
+
240
+ - **Chat Model Management**: Unified interface for different LLM providers
241
+ - **Agent Framework**: Tools for building LLM agents
242
+ - **Pipeline Management**: Workflow management for LLM processing
243
+ - **Memory Management**: Context and conversation memory handling
244
+ - **Tool Integration**: Framework for LLM tool calling
245
+
246
+ ## License
247
+
248
+ This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.
249
+
250
+ ## Contributing
251
+
252
+ This is a personal project, but contributions are welcome! Please feel free to submit issues or pull requests.
253
+
254
+ ## Related Projects
255
+
256
+ - [kiarina-python](https://github.com/kiarina/kiarina-python) - The main monorepo containing this package
257
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Configuration management library used by this package
@@ -0,0 +1,45 @@
1
+ [project]
2
+ name = "kiarina-llm"
3
+ version = "1.0.0"
4
+ description = "LLM utilities and context management for kiarina namespace"
5
+ readme = "README.md"
6
+ license = { text = "MIT" }
7
+ authors = [
8
+ { name = "kiarina", email = "kiarinadawa@gmail.com" }
9
+ ]
10
+ maintainers = [
11
+ { name = "kiarina", email = "kiarinadawa@gmail.com" }
12
+ ]
13
+ keywords = ["llm", "ai", "context", "pydantic", "settings", "agent", "runner"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ "Topic :: Software Development :: Libraries :: Python Modules",
24
+ "Typing :: Typed",
25
+ ]
26
+ requires-python = ">=3.12"
27
+ dependencies = [
28
+ "pydantic>=2.10.1",
29
+ "pydantic-settings>=2.10.1",
30
+ "pydantic-settings-manager>=2.1.0",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/kiarina/kiarina-python"
35
+ Repository = "https://github.com/kiarina/kiarina-python"
36
+ Issues = "https://github.com/kiarina/kiarina-python/issues"
37
+ Changelog = "https://github.com/kiarina/kiarina-python/blob/main/packages/kiarina-llm/CHANGELOG.md"
38
+ Documentation = "https://github.com/kiarina/kiarina-python/tree/main/packages/kiarina-llm#readme"
39
+
40
+ [build-system]
41
+ requires = ["hatchling"]
42
+ build-backend = "hatchling.build"
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages = ["src/kiarina"]
@@ -0,0 +1,3 @@
1
+ from importlib.metadata import version
2
+
3
+ __version__ = version("kiarina-llm")
File without changes
@@ -0,0 +1,9 @@
1
+ from ._model import RunContext
2
+ from ._registry import create_run_context
3
+ from .settings import settings_manager
4
+
5
+ __all__ = [
6
+ "create_run_context",
7
+ "RunContext",
8
+ "settings_manager",
9
+ ]
@@ -0,0 +1,76 @@
1
+ from typing import Any
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from ._types.fs_name import FSName
6
+ from ._types.id_str import IDStr
7
+
8
+
9
+ class RunContext(BaseModel):
10
+ """
11
+ Run Context
12
+
13
+ Holds the context information used in the LLM pipeline processing.
14
+ """
15
+
16
+ app_author: FSName
17
+ """
18
+ Application author
19
+
20
+ Used in PlatformDirs.
21
+ """
22
+
23
+ app_name: FSName
24
+ """
25
+ Application name
26
+
27
+ Used in PlatformDirs.
28
+ """
29
+
30
+ tenant_id: IDStr
31
+ """
32
+ Tenant ID
33
+
34
+ Identifier for the tenant to which the user belongs.
35
+ """
36
+
37
+ user_id: IDStr
38
+ """
39
+ User ID
40
+
41
+ Identifier for the user.
42
+ """
43
+
44
+ agent_id: IDStr
45
+ """
46
+ Agent ID
47
+
48
+ Identifier for the agent used by the user.
49
+ """
50
+
51
+ runner_id: IDStr
52
+ """
53
+ Runner ID
54
+
55
+ Identifier for the runner used by the AI.
56
+ """
57
+
58
+ time_zone: str
59
+ """
60
+ Time Zone
61
+
62
+ IANA Time Zone.
63
+ Specify in continent/city format.
64
+ Example: "Asia/Tokyo"
65
+ """
66
+
67
+ language: str
68
+ """
69
+ Language
70
+
71
+ ISO 639-1 code.
72
+ Example: "en" (English), "ja" (Japanese)
73
+ """
74
+
75
+ metadata: dict[str, Any] = Field(default_factory=lambda: {})
76
+ """Metadata"""
@@ -0,0 +1,34 @@
1
+ from typing import Any
2
+
3
+ from ._model import RunContext
4
+ from .settings import settings_manager
5
+
6
+
7
+ def create_run_context(
8
+ *,
9
+ app_author: str | None = None,
10
+ app_name: str | None = None,
11
+ tenant_id: str | None = None,
12
+ user_id: str | None = None,
13
+ agent_id: str | None = None,
14
+ runner_id: str | None = None,
15
+ time_zone: str | None = None,
16
+ language: str | None = None,
17
+ metadata: dict[str, Any] | None = None,
18
+ ) -> RunContext:
19
+ """
20
+ Create RunContext
21
+ """
22
+ settings = settings_manager.settings
23
+
24
+ return RunContext(
25
+ app_author=app_author if app_author is not None else settings.app_author,
26
+ app_name=app_name if app_name is not None else settings.app_name,
27
+ tenant_id=tenant_id if tenant_id is not None else settings.tenant_id,
28
+ user_id=user_id if user_id is not None else settings.user_id,
29
+ agent_id=agent_id if agent_id is not None else settings.agent_id,
30
+ runner_id=runner_id if runner_id is not None else settings.runner_id,
31
+ time_zone=time_zone if time_zone is not None else settings.time_zone,
32
+ language=language if language is not None else settings.language,
33
+ metadata=metadata if metadata is not None else settings.metadata,
34
+ )
@@ -0,0 +1,52 @@
1
+ from typing import Annotated
2
+
3
+ from pydantic import AfterValidator, StringConstraints
4
+
5
+ FS_NAME_PATTERN = r"^[A-Za-z0-9._ -]+$"
6
+ """
7
+ File system name pattern
8
+
9
+ Permit ASCII letters, dots, underscores, hyphens, and spaces.
10
+ Detailed constraints are checked by validation functions.
11
+ """
12
+
13
+ WINDOWS_RESERVED = {
14
+ "con",
15
+ "prn",
16
+ "aux",
17
+ "nul",
18
+ *{f"com{i}" for i in range(1, 10)},
19
+ *{f"lpt{i}" for i in range(1, 10)},
20
+ }
21
+ """
22
+ Set of reserved names in Windows
23
+
24
+ Uppercase and lowercase letters are ignored.
25
+ """
26
+
27
+
28
+ def _validate_fs_name(v: str) -> str:
29
+ name = v.strip()
30
+
31
+ if name.lower() in WINDOWS_RESERVED:
32
+ raise ValueError(f"'{v}' is a reserved name on Windows")
33
+
34
+ # Prohibiting names beginning with a dot
35
+ if name.startswith("."):
36
+ raise ValueError(f"'{v}' cannot start with a dot")
37
+
38
+ # Prohibiting endings with a dot or space
39
+ if name.endswith(".") or name.endswith(" "):
40
+ raise ValueError(f"'{v}' cannot end with a dot or space")
41
+
42
+ return v
43
+
44
+
45
+ FSName = Annotated[
46
+ str,
47
+ StringConstraints(min_length=1, pattern=FS_NAME_PATTERN),
48
+ AfterValidator(_validate_fs_name),
49
+ ]
50
+ """
51
+ Filesystem Safe Name Type
52
+ """
@@ -0,0 +1,15 @@
1
+ from typing import Annotated
2
+
3
+ from pydantic import StringConstraints
4
+
5
+ ID_PATTERN = r"^[a-zA-Z0-9._-]+$"
6
+ """
7
+ Permitted ID patterns
8
+
9
+ Alphanumeric characters, dot, underscore, hyphen, one character or more.
10
+ """
11
+
12
+ IDStr = Annotated[str, StringConstraints(min_length=1, pattern=ID_PATTERN)]
13
+ """
14
+ ID String type
15
+ """
@@ -0,0 +1,80 @@
1
+ import platform
2
+ from typing import Any
3
+
4
+ from pydantic import Field
5
+ from pydantic_settings import BaseSettings, SettingsConfigDict
6
+ from pydantic_settings_manager import SettingsManager
7
+
8
+
9
+ class RunContextSettings(BaseSettings):
10
+ """
11
+ Run Context Settings
12
+ """
13
+
14
+ model_config = SettingsConfigDict(env_prefix="KIARINA_LLM_RUN_CONTEXT_")
15
+
16
+ app_author: str = "kiarina"
17
+ """
18
+ Default value for the application author.
19
+
20
+ Alphanumeric characters, dots, underscores, hyphens, and spaces are allowed.
21
+ Leading and trailing dots, as well as spaces, are not allowed.
22
+ """
23
+
24
+ app_name: str = "kiarina-llm"
25
+ """
26
+ Default value for the application name.
27
+
28
+ Alphanumeric characters, dots, underscores, hyphens, and spaces are allowed.
29
+ Leading and trailing dots, as well as spaces, are not allowed.
30
+ """
31
+
32
+ tenant_id: str = ""
33
+ """
34
+ Default value for the tenant ID.
35
+
36
+ Alphanumeric characters, underscores, and hyphens are allowed.
37
+ """
38
+
39
+ user_id: str = ""
40
+ """
41
+ Default value for the user ID.
42
+
43
+ Alphanumeric characters, underscores, and hyphens are allowed.
44
+ """
45
+
46
+ agent_id: str = ""
47
+ """
48
+ Default value for the agent ID.
49
+
50
+ Alphanumeric characters, underscores, and hyphens are allowed.
51
+ """
52
+
53
+ runner_id: str = Field(default_factory=lambda: platform.system().lower())
54
+ """
55
+ Default value for the runner ID.
56
+
57
+ Alphanumeric characters, underscores, and hyphens are allowed.
58
+ """
59
+
60
+ time_zone: str = "UTC"
61
+ """
62
+ Default value for the time zone.
63
+
64
+ IANA time zone names are used.
65
+ Example: "Asia/Tokyo"
66
+ """
67
+
68
+ language: str = "en"
69
+ """
70
+ Default value for the language.
71
+
72
+ ISO 639-1 codes are used.
73
+ Example: "ja"
74
+ """
75
+
76
+ metadata: dict[str, Any] = Field(default_factory=dict)
77
+ """Default value for the metadata."""
78
+
79
+
80
+ settings_manager = SettingsManager(RunContextSettings)
File without changes
File without changes
@@ -0,0 +1,12 @@
1
+ import pytest
2
+
3
+ from kiarina.llm.run_context import settings_manager
4
+
5
+
6
+ @pytest.fixture(scope="session", autouse=True)
7
+ def setup_settings():
8
+ settings_manager.user_config = {
9
+ "tenant_id": "test-tenant",
10
+ "user_id": "test-user",
11
+ "agent_id": "test-agent",
12
+ }
@@ -0,0 +1,39 @@
1
+ from kiarina.llm.run_context import create_run_context, settings_manager
2
+
3
+
4
+ def test_create_run_context_with_settings():
5
+ """Test that RunContext is created using configuration values"""
6
+ context = create_run_context()
7
+ settings = settings_manager.settings
8
+ assert context.app_author == settings.app_author
9
+ assert context.app_name == settings.app_name
10
+ assert context.tenant_id == settings.tenant_id
11
+ assert context.user_id == settings.user_id
12
+ assert context.time_zone == settings.time_zone
13
+ assert context.language == settings.language
14
+ assert context.metadata == settings.metadata
15
+
16
+
17
+ def test_create_run_context_with_overrides():
18
+ """Test that RunContext is created with argument overrides"""
19
+ context = create_run_context(
20
+ app_author="TestCompany",
21
+ app_name="TestApp",
22
+ tenant_id="tenant-123",
23
+ user_id="user-456",
24
+ agent_id="agent-789",
25
+ runner_id="test-runner",
26
+ time_zone="Asia/Tokyo",
27
+ language="ja",
28
+ metadata={"version": "1.0.0"},
29
+ )
30
+
31
+ assert context.app_author == "TestCompany"
32
+ assert context.app_name == "TestApp"
33
+ assert context.tenant_id == "tenant-123"
34
+ assert context.user_id == "user-456"
35
+ assert context.agent_id == "agent-789"
36
+ assert context.runner_id == "test-runner"
37
+ assert context.time_zone == "Asia/Tokyo"
38
+ assert context.language == "ja"
39
+ assert context.metadata == {"version": "1.0.0"}
@@ -0,0 +1,87 @@
1
+ import pytest
2
+
3
+ from kiarina.llm.run_context import create_run_context
4
+
5
+
6
+ # fmt: off
7
+ @pytest.mark.parametrize("name", [
8
+ "MyApp",
9
+ "My App",
10
+ "My-App",
11
+ "My_App",
12
+ "My.App",
13
+ "My App v1.0",
14
+ "Test-App_v2.1",
15
+ "Test App ", # Trailing space is stripped, so this becomes valid
16
+ "Test ", # Trailing space is stripped, so this becomes valid
17
+ ])
18
+ # fmt: on
19
+ def test_fs_name_valid(name):
20
+ """Test that valid FSName values are accepted"""
21
+ context = create_run_context(app_author=name, app_name=name)
22
+ assert context.app_author == name
23
+ assert context.app_name == name
24
+
25
+
26
+ # fmt: off
27
+ @pytest.mark.parametrize("name,expected_match", [
28
+ # Names ending with dots (spaces are stripped, so they're actually valid)
29
+ ("Test App.", "cannot end with a dot or space"),
30
+ ("Test.", "cannot end with a dot or space"),
31
+
32
+ # Names starting with dots
33
+ (".hidden", "cannot start with a dot"),
34
+ (".test", "cannot start with a dot"),
35
+ (".myapp", "cannot start with a dot"),
36
+
37
+ # Windows reserved names
38
+ ("CON", "is a reserved name on Windows"),
39
+ ("con", "is a reserved name on Windows"),
40
+ ("Con", "is a reserved name on Windows"),
41
+ ("PRN", "is a reserved name on Windows"),
42
+ ("prn", "is a reserved name on Windows"),
43
+ ("Prn", "is a reserved name on Windows"),
44
+ ("AUX", "is a reserved name on Windows"),
45
+ ("aux", "is a reserved name on Windows"),
46
+ ("Aux", "is a reserved name on Windows"),
47
+ ("NUL", "is a reserved name on Windows"),
48
+ ("nul", "is a reserved name on Windows"),
49
+ ("Nul", "is a reserved name on Windows"),
50
+ ("COM1", "is a reserved name on Windows"),
51
+ ("com1", "is a reserved name on Windows"),
52
+ ("Com1", "is a reserved name on Windows"),
53
+ ("COM9", "is a reserved name on Windows"),
54
+ ("com9", "is a reserved name on Windows"),
55
+ ("Com9", "is a reserved name on Windows"),
56
+ ("LPT1", "is a reserved name on Windows"),
57
+ ("lpt1", "is a reserved name on Windows"),
58
+ ("Lpt1", "is a reserved name on Windows"),
59
+ ("LPT9", "is a reserved name on Windows"),
60
+ ("lpt9", "is a reserved name on Windows"),
61
+ ("Lpt9", "is a reserved name on Windows"),
62
+
63
+ # Empty string
64
+ ("", None), # No specific match pattern for empty string
65
+
66
+ # Invalid characters
67
+ ("Test/App", None),
68
+ ("Test\\App", None),
69
+ ("Test:App", None),
70
+ ("Test*App", None),
71
+ ("Test?App", None),
72
+ ("Test\"App", None),
73
+ ("Test<App", None),
74
+ ("Test>App", None),
75
+ ("Test|App", None),
76
+ ("Test@App", None),
77
+ ("Test#App", None),
78
+ ])
79
+ # fmt: on
80
+ def test_fs_name_invalid(name, expected_match):
81
+ """Test that invalid FSName values are rejected"""
82
+ if expected_match:
83
+ with pytest.raises(ValueError, match=expected_match):
84
+ create_run_context(app_author=name)
85
+ else:
86
+ with pytest.raises(ValueError):
87
+ create_run_context(app_author=name)
@@ -0,0 +1,73 @@
1
+ import pytest
2
+
3
+ from kiarina.llm.run_context import create_run_context
4
+
5
+
6
+ @pytest.mark.parametrize(
7
+ "id_str",
8
+ [
9
+ "simple",
10
+ "with-hyphen",
11
+ "with_underscore",
12
+ "with.dot",
13
+ "mixed-id_v1.0",
14
+ "123",
15
+ "id123",
16
+ "a",
17
+ "A",
18
+ "ID-123_v2.0",
19
+ "tenant.123",
20
+ "user.456",
21
+ "agent.v1.0",
22
+ "runner.test",
23
+ "tenant-123",
24
+ "user_456",
25
+ "agent-v1_0",
26
+ "runner_test-1",
27
+ ],
28
+ )
29
+ def test_id_str_valid(id_str):
30
+ """Test that valid IDStr values are accepted"""
31
+ context = create_run_context(
32
+ tenant_id=id_str,
33
+ user_id=id_str,
34
+ agent_id=id_str,
35
+ runner_id=id_str,
36
+ )
37
+ assert context.tenant_id == id_str
38
+ assert context.user_id == id_str
39
+ assert context.agent_id == id_str
40
+ assert context.runner_id == id_str
41
+
42
+
43
+ @pytest.mark.parametrize(
44
+ "id_str",
45
+ [
46
+ "", # Empty string
47
+ "id@domain",
48
+ "id with space",
49
+ "id/path",
50
+ "id\\path",
51
+ "id:port",
52
+ "id*wildcard",
53
+ "id?query",
54
+ 'id"quote',
55
+ "id<bracket",
56
+ "id>bracket",
57
+ "id|pipe",
58
+ "id#hash",
59
+ "id%percent",
60
+ "id&ampersand",
61
+ "id+plus",
62
+ "id=equals",
63
+ "id[bracket]",
64
+ "id{brace}",
65
+ "id(paren)",
66
+ "id,comma",
67
+ "id;semicolon",
68
+ ],
69
+ )
70
+ def test_id_str_invalid(id_str):
71
+ """Test that invalid IDStr values are rejected"""
72
+ with pytest.raises(ValueError):
73
+ create_run_context(tenant_id=id_str)
@@ -0,0 +1,36 @@
1
+ import pytest
2
+
3
+ from kiarina.llm.run_context import RunContext
4
+
5
+
6
+ def test_valid():
7
+ data = {
8
+ "app_author": "TestCompany",
9
+ "app_name": "TestApp",
10
+ "tenant_id": "tenant-123",
11
+ "user_id": "user-456",
12
+ "agent_id": "agent-789",
13
+ "runner_id": "runner-001",
14
+ "time_zone": "UTC",
15
+ "language": "en",
16
+ "metadata": {"key": "value"},
17
+ }
18
+
19
+ run_context = RunContext.model_validate(data)
20
+ assert run_context.model_dump() == data
21
+
22
+
23
+ def test_invalid():
24
+ with pytest.raises(Exception):
25
+ RunContext.model_validate(
26
+ {
27
+ "app_author": "Invalid/Name", # Invalid character
28
+ "app_name": "TestApp",
29
+ "tenant_id": "tenant-123",
30
+ "user_id": "user-456",
31
+ "agent_id": "agent-789",
32
+ "runner_id": "runner-001",
33
+ "time_zone": "UTC",
34
+ "language": "en",
35
+ }
36
+ )