g8e 1.4.1__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.
- g8e-1.4.1/PKG-INFO +81 -0
- g8e-1.4.1/README.md +59 -0
- g8e-1.4.1/g8e/__init__.py +14 -0
- g8e-1.4.1/g8e/constants.py +125 -0
- g8e-1.4.1/g8e/enums.py +136 -0
- g8e-1.4.1/g8e/models/__init__.py +63 -0
- g8e-1.4.1/g8e/models/base.py +55 -0
- g8e-1.4.1/g8e/models/context.py +84 -0
- g8e-1.4.1/g8e/models/events.py +100 -0
- g8e-1.4.1/g8e/models/internal_api.py +47 -0
- g8e-1.4.1/g8e/models/settings.py +78 -0
- g8e-1.4.1/g8e.egg-info/PKG-INFO +81 -0
- g8e-1.4.1/g8e.egg-info/SOURCES.txt +16 -0
- g8e-1.4.1/g8e.egg-info/dependency_links.txt +1 -0
- g8e-1.4.1/g8e.egg-info/requires.txt +2 -0
- g8e-1.4.1/g8e.egg-info/top_level.txt +1 -0
- g8e-1.4.1/pyproject.toml +54 -0
- g8e-1.4.1/setup.cfg +4 -0
g8e-1.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: g8e
|
|
3
|
+
Version: 1.4.1
|
|
4
|
+
Summary: g8e Protocol Constants and Models
|
|
5
|
+
Author: Lateralus Labs, LLC
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/g8e-ai/g8e
|
|
8
|
+
Project-URL: Repository, https://github.com/g8e-ai/g8e
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: protobuf>=4.0.0
|
|
22
|
+
|
|
23
|
+
# g8e
|
|
24
|
+
|
|
25
|
+
Python protocol library for the g8e zero-trust execution platform. Provides protocol constants, dynamic enums, and Pydantic models for building g8e-compatible clients and services.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Requires Python 3.10 or later. Dependencies are `pydantic>=2.0.0` and `protobuf>=4.0.0`.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install g8e
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Constants
|
|
38
|
+
|
|
39
|
+
The `g8e.constants` module loads JSON protocol constants from `protocol/constants/` at import time. It exports dicts for events, status, collections, headers, channels, pubsub, intents, prompts, timestamps, document IDs, platform configuration, agents, network, API paths, key-value keys, and sender identifiers. The module also exports the `ComponentName` `StrEnum` and individual HTTP header string constants for session, context, and g8e-specific headers.
|
|
40
|
+
|
|
41
|
+
Set the `G8E_PROTOCOL_DIR` environment variable to override the default protocol directory resolution. The loader checks this variable first, then falls back to the relative path from the package, then to `/app/protocol/constants` for containerized environments.
|
|
42
|
+
|
|
43
|
+
### Enums
|
|
44
|
+
|
|
45
|
+
The `g8e.enums` module dynamically generates `StrEnum` and `IntEnum` classes from the `STATUS` and `EVENTS` protocol constants. Enum member names use SCREAMING_SNAKE_CASE; values preserve the raw protocol wire format. Integer-valued categories produce `IntEnum`; all others produce `StrEnum`. Access enums by PascalCase name via attribute lookup, for example `g8e.enums.OperatorToolName` or `g8e.enums.EventType`.
|
|
46
|
+
|
|
47
|
+
### Models
|
|
48
|
+
|
|
49
|
+
The `g8e.models` package provides Pydantic v2 models for protocol data structures. All models extend `G8eBaseModel`, which configures `populate_by_name` and `extra="ignore"`, and defaults `exclude_none` on serialization. The `UTCDatetime` annotated type serializes datetimes to ISO 8601 with a `Z` suffix.
|
|
50
|
+
|
|
51
|
+
- **`g8e/models/base.py`**: `G8eBaseModel`, `UTCDatetime`, and re-exports of Pydantic `Field`, `ConfigDict`, `field_validator`, `model_validator`.
|
|
52
|
+
- **`g8e/models/context.py`**: `RequestContext` and `BoundOperator`. `RequestContext` validates session identity for `CLIENT` source components, requiring either `web_session_id` or `cli_session_id` and a `user_id`.
|
|
53
|
+
- **`g8e/models/events.py`**: SSE wire models (`SessionEventWire`, `BackgroundEventWire`) and AI event payload models for chat processing, tool lifecycle, citations, errors, thinking, turn completion, retry, and triage clarification.
|
|
54
|
+
- **`g8e/models/internal_api.py`**: `ChatMessageRequest`, `ChatStartedResponse`, and `ResourceCreationRequest` for internal API interactions.
|
|
55
|
+
- **`g8e/models/settings.py`**: `G8eeUserSettings`, `PlatformSettings`, and nested settings models for LLM providers, search, eval judge, command validation, and batch execution.
|
|
56
|
+
|
|
57
|
+
### Examples
|
|
58
|
+
|
|
59
|
+
Working examples are in `protocol/python/examples/`. Run `constants_example.py` for constants and headers usage, or `models_example.py` for model instantiation, serialization, and validation.
|
|
60
|
+
|
|
61
|
+
## Components
|
|
62
|
+
|
|
63
|
+
- **`g8e/constants.py`**: Runtime loader for JSON protocol constants from `protocol/constants/`. Exports dict constants, `ComponentName` enum, and HTTP header string constants.
|
|
64
|
+
- **`g8e/enums.py`**: Dynamic `StrEnum` and `IntEnum` generation from `STATUS` and `EVENTS` protocol constants.
|
|
65
|
+
- **`g8e/models/`**: Pydantic v2 models for protocol data structures, SSE events, internal API requests, and user settings.
|
|
66
|
+
|
|
67
|
+
## Protocol Versioning
|
|
68
|
+
|
|
69
|
+
This package follows semantic versioning. Major version changes indicate breaking protocol changes. Minor version changes add new protocol features. Patch version changes include bug fixes and non-breaking enhancements.
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
Apache License 2.0. See `protocol/LICENSE` for details.
|
|
74
|
+
|
|
75
|
+
## Contributing
|
|
76
|
+
|
|
77
|
+
Protocol changes require coordination across all g8e components. Submit protocol change proposals via GitHub issues with clear justification and impact analysis.
|
|
78
|
+
|
|
79
|
+
## Support
|
|
80
|
+
|
|
81
|
+
For protocol questions and support, open a GitHub issue or visit https://github.com/g8e-ai/g8e
|
g8e-1.4.1/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# g8e
|
|
2
|
+
|
|
3
|
+
Python protocol library for the g8e zero-trust execution platform. Provides protocol constants, dynamic enums, and Pydantic models for building g8e-compatible clients and services.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Requires Python 3.10 or later. Dependencies are `pydantic>=2.0.0` and `protobuf>=4.0.0`.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install g8e
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Constants
|
|
16
|
+
|
|
17
|
+
The `g8e.constants` module loads JSON protocol constants from `protocol/constants/` at import time. It exports dicts for events, status, collections, headers, channels, pubsub, intents, prompts, timestamps, document IDs, platform configuration, agents, network, API paths, key-value keys, and sender identifiers. The module also exports the `ComponentName` `StrEnum` and individual HTTP header string constants for session, context, and g8e-specific headers.
|
|
18
|
+
|
|
19
|
+
Set the `G8E_PROTOCOL_DIR` environment variable to override the default protocol directory resolution. The loader checks this variable first, then falls back to the relative path from the package, then to `/app/protocol/constants` for containerized environments.
|
|
20
|
+
|
|
21
|
+
### Enums
|
|
22
|
+
|
|
23
|
+
The `g8e.enums` module dynamically generates `StrEnum` and `IntEnum` classes from the `STATUS` and `EVENTS` protocol constants. Enum member names use SCREAMING_SNAKE_CASE; values preserve the raw protocol wire format. Integer-valued categories produce `IntEnum`; all others produce `StrEnum`. Access enums by PascalCase name via attribute lookup, for example `g8e.enums.OperatorToolName` or `g8e.enums.EventType`.
|
|
24
|
+
|
|
25
|
+
### Models
|
|
26
|
+
|
|
27
|
+
The `g8e.models` package provides Pydantic v2 models for protocol data structures. All models extend `G8eBaseModel`, which configures `populate_by_name` and `extra="ignore"`, and defaults `exclude_none` on serialization. The `UTCDatetime` annotated type serializes datetimes to ISO 8601 with a `Z` suffix.
|
|
28
|
+
|
|
29
|
+
- **`g8e/models/base.py`**: `G8eBaseModel`, `UTCDatetime`, and re-exports of Pydantic `Field`, `ConfigDict`, `field_validator`, `model_validator`.
|
|
30
|
+
- **`g8e/models/context.py`**: `RequestContext` and `BoundOperator`. `RequestContext` validates session identity for `CLIENT` source components, requiring either `web_session_id` or `cli_session_id` and a `user_id`.
|
|
31
|
+
- **`g8e/models/events.py`**: SSE wire models (`SessionEventWire`, `BackgroundEventWire`) and AI event payload models for chat processing, tool lifecycle, citations, errors, thinking, turn completion, retry, and triage clarification.
|
|
32
|
+
- **`g8e/models/internal_api.py`**: `ChatMessageRequest`, `ChatStartedResponse`, and `ResourceCreationRequest` for internal API interactions.
|
|
33
|
+
- **`g8e/models/settings.py`**: `G8eeUserSettings`, `PlatformSettings`, and nested settings models for LLM providers, search, eval judge, command validation, and batch execution.
|
|
34
|
+
|
|
35
|
+
### Examples
|
|
36
|
+
|
|
37
|
+
Working examples are in `protocol/python/examples/`. Run `constants_example.py` for constants and headers usage, or `models_example.py` for model instantiation, serialization, and validation.
|
|
38
|
+
|
|
39
|
+
## Components
|
|
40
|
+
|
|
41
|
+
- **`g8e/constants.py`**: Runtime loader for JSON protocol constants from `protocol/constants/`. Exports dict constants, `ComponentName` enum, and HTTP header string constants.
|
|
42
|
+
- **`g8e/enums.py`**: Dynamic `StrEnum` and `IntEnum` generation from `STATUS` and `EVENTS` protocol constants.
|
|
43
|
+
- **`g8e/models/`**: Pydantic v2 models for protocol data structures, SSE events, internal API requests, and user settings.
|
|
44
|
+
|
|
45
|
+
## Protocol Versioning
|
|
46
|
+
|
|
47
|
+
This package follows semantic versioning. Major version changes indicate breaking protocol changes. Minor version changes add new protocol features. Patch version changes include bug fixes and non-breaking enhancements.
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
Apache License 2.0. See `protocol/LICENSE` for details.
|
|
52
|
+
|
|
53
|
+
## Contributing
|
|
54
|
+
|
|
55
|
+
Protocol changes require coordination across all g8e components. Submit protocol change proposals via GitHub issues with clear justification and impact analysis.
|
|
56
|
+
|
|
57
|
+
## Support
|
|
58
|
+
|
|
59
|
+
For protocol questions and support, open a GitHub issue or visit https://github.com/g8e-ai/g8e
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
__version__ = "1.4.1"
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
# Protocol Constants Loader for Python
|
|
21
|
+
# Provides a single entry point for protocol constants shared across components.
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
def _get_protocol_dir() -> Path:
|
|
26
|
+
"""Find the protocol directory."""
|
|
27
|
+
# 1. Check environment variable
|
|
28
|
+
if "G8E_PROTOCOL_DIR" in os.environ:
|
|
29
|
+
return Path(os.environ["G8E_PROTOCOL_DIR"]) / "constants"
|
|
30
|
+
|
|
31
|
+
# 2. Check relative to this file
|
|
32
|
+
# protocol/python/g8e/constants.py -> protocol/constants
|
|
33
|
+
rel_path = Path(__file__).parent.parent.parent / "constants"
|
|
34
|
+
if rel_path.exists():
|
|
35
|
+
return rel_path
|
|
36
|
+
|
|
37
|
+
# 3. Fallback for containerized environments
|
|
38
|
+
container_path = Path("/app/protocol/constants")
|
|
39
|
+
if container_path.exists():
|
|
40
|
+
return container_path
|
|
41
|
+
|
|
42
|
+
return Path("./protocol/constants")
|
|
43
|
+
|
|
44
|
+
_PROTOCOL_CONSTANTS_DIR = _get_protocol_dir()
|
|
45
|
+
|
|
46
|
+
def _load_protocol_json(filename: str) -> dict[str, Any]:
|
|
47
|
+
path = _PROTOCOL_CONSTANTS_DIR / filename
|
|
48
|
+
if not path.exists():
|
|
49
|
+
logger.warning("Protocol JSON %s not found at %s", filename, path)
|
|
50
|
+
return {}
|
|
51
|
+
|
|
52
|
+
with open(path, encoding="utf-8") as f:
|
|
53
|
+
return json.load(f)
|
|
54
|
+
|
|
55
|
+
# Exported constants
|
|
56
|
+
EVENTS = _load_protocol_json("events.json")
|
|
57
|
+
STATUS = _load_protocol_json("status.json")
|
|
58
|
+
MSG = _load_protocol_json("senders.json")
|
|
59
|
+
COLLECTIONS = _load_protocol_json("collections.json")
|
|
60
|
+
KV = _load_protocol_json("kv_keys.json")
|
|
61
|
+
CHANNELS = _load_protocol_json("channels.json")
|
|
62
|
+
PUBSUB = _load_protocol_json("pubsub.json")
|
|
63
|
+
INTENTS = _load_protocol_json("intents.json")
|
|
64
|
+
PROMPTS = _load_protocol_json("prompts.json")
|
|
65
|
+
TIMESTAMP = _load_protocol_json("timestamp.json")
|
|
66
|
+
HEADERS = _load_protocol_json("headers.json")
|
|
67
|
+
DOCUMENT_IDS = _load_protocol_json("document_ids.json")
|
|
68
|
+
PLATFORM = _load_protocol_json("platform.json")
|
|
69
|
+
AGENTS = _load_protocol_json("agents.json")
|
|
70
|
+
NETWORK = _load_protocol_json("network.json")
|
|
71
|
+
API_PATHS = _load_protocol_json("api_paths.json")
|
|
72
|
+
|
|
73
|
+
from enum import StrEnum
|
|
74
|
+
|
|
75
|
+
# Helper to get Component names (formerly ComponentName enum)
|
|
76
|
+
class ComponentName(StrEnum):
|
|
77
|
+
CLIENT = "client"
|
|
78
|
+
G8EE = "g8ee"
|
|
79
|
+
G8EO = "g8eo"
|
|
80
|
+
OPERATOR = "g8eo" # Alias
|
|
81
|
+
|
|
82
|
+
# Headers from g8ee/app/constants/headers.py
|
|
83
|
+
HTTP_ACCEL_BUFFERING_HEADER = "X-Accel-Buffering"
|
|
84
|
+
HTTP_ACCEPT_HEADER = "Accept"
|
|
85
|
+
HTTP_ACCEPT_LANGUAGE_HEADER = "Accept-Language"
|
|
86
|
+
HTTP_ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"
|
|
87
|
+
HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"
|
|
88
|
+
HTTP_ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers"
|
|
89
|
+
HTTP_ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method"
|
|
90
|
+
HTTP_API_KEY_HEADER = "X-API-Key"
|
|
91
|
+
HTTP_AUTHORIZATION_HEADER = "Authorization"
|
|
92
|
+
HTTP_BEARER_PREFIX = "Bearer"
|
|
93
|
+
HTTP_CACHE_CONTROL_HEADER = "Cache-Control"
|
|
94
|
+
HTTP_CONTENT_LANGUAGE_HEADER = "Content-Language"
|
|
95
|
+
HTTP_CONTENT_TYPE_HEADER = "Content-Type"
|
|
96
|
+
HTTP_COOKIE_HEADER = "Cookie"
|
|
97
|
+
HTTP_FORWARDED_FOR_HEADER = "X-Forwarded-For"
|
|
98
|
+
HTTP_LAST_EVENT_ID_HEADER = "Last-Event-ID"
|
|
99
|
+
HTTP_PRAGMA_HEADER = "Pragma"
|
|
100
|
+
HTTP_REQUESTED_WITH_HEADER = "X-Requested-With"
|
|
101
|
+
HTTP_SET_COOKIE_HEADER = "Set-Cookie"
|
|
102
|
+
HTTP_USER_AGENT_HEADER = "User-Agent"
|
|
103
|
+
HTTP_G8E_CLIENT_HEADER = "X-G8E-Client"
|
|
104
|
+
HTTP_G8E_OPERATOR_STATUS_HEADER = "X-G8E-Operator-Status"
|
|
105
|
+
HTTP_G8E_SYSTEM_FINGERPRINT_HEADER = "X-G8E-System-Fingerprint"
|
|
106
|
+
HTTP_G8E_SERVICE_HEADER = "X-G8E-Service"
|
|
107
|
+
|
|
108
|
+
# Session Headers
|
|
109
|
+
WEB_SESSION_ID_HEADER = "X-G8E-Web-Session-ID"
|
|
110
|
+
CLI_SESSION_ID_HEADER = "X-G8E-CLI-Session-ID"
|
|
111
|
+
OPERATOR_ID_HEADER = "X-G8E-Operator-ID"
|
|
112
|
+
OPERATOR_API_KEY_HEADER = "X-G8E-Operator-API-Key"
|
|
113
|
+
|
|
114
|
+
# Context Headers
|
|
115
|
+
PROXY_ORGANIZATION_ID_HEADER = "X-Proxy-Organization-Id"
|
|
116
|
+
PROXY_USER_EMAIL_HEADER = "X-Proxy-User-Email"
|
|
117
|
+
PROXY_USER_ID_HEADER = "X-Proxy-User-Id"
|
|
118
|
+
CASE_ID_HEADER = "X-G8E-Case-ID"
|
|
119
|
+
USER_ID_HEADER = "X-G8E-User-ID"
|
|
120
|
+
ORGANIZATION_ID_HEADER = "X-G8E-Organization-ID"
|
|
121
|
+
INVESTIGATION_ID_HEADER = "X-G8E-Investigation-ID"
|
|
122
|
+
TASK_ID_HEADER = "X-G8E-Task-ID"
|
|
123
|
+
BOUND_OPERATORS_HEADER = "X-G8E-Bound-Operators"
|
|
124
|
+
EXECUTION_ID_HEADER = "X-G8E-Request-ID"
|
|
125
|
+
COMPONENT_NAME_HEADER = "X-G8E-Source-Component"
|
g8e-1.4.1/g8e/enums.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Dynamic enum generation from protocol constants.
|
|
2
|
+
|
|
3
|
+
Generates Python ``StrEnum`` / ``IntEnum`` classes from the ``STATUS`` and
|
|
4
|
+
``EVENTS`` dicts in :mod:`g8e.constants`, so downstream consumers (g8ee,
|
|
5
|
+
evals, CLI) can use typed enums instead of raw string lookups.
|
|
6
|
+
|
|
7
|
+
Categories whose values are integer-like produce ``IntEnum``; all others
|
|
8
|
+
produce ``StrEnum``.
|
|
9
|
+
|
|
10
|
+
Enum **member names** are SCREAMING_SNAKE_CASE (derived from the JSON
|
|
11
|
+
``_python_const`` or PascalCase event keys). Enum **values** preserve
|
|
12
|
+
the raw protocol wire format (e.g. ``"g8e.v1.ai.llm.chat.iteration.thinking.started"``,
|
|
13
|
+
``"user.cancelled"``, ``"G8E-1000"``) so they round-trip exactly to
|
|
14
|
+
Go/protobuf/JVM consumers.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import re
|
|
20
|
+
from enum import StrEnum, IntEnum
|
|
21
|
+
from functools import lru_cache
|
|
22
|
+
|
|
23
|
+
from g8e.constants import STATUS, EVENTS
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Categories that use integer values
|
|
27
|
+
_INT_CATEGORIES: frozenset[str] = frozenset({
|
|
28
|
+
"citation_layout",
|
|
29
|
+
"priority",
|
|
30
|
+
"scrubber_priority",
|
|
31
|
+
"severity",
|
|
32
|
+
"slash_tier",
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _to_pascal(snake: str) -> str:
|
|
37
|
+
"""Convert snake_case to PascalCase, handling dotted names."""
|
|
38
|
+
parts = snake.replace(".", "_").split("_")
|
|
39
|
+
return "".join(p.capitalize() for p in parts)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _pascal_to_screaming_snake(name: str) -> str:
|
|
43
|
+
"""Convert PascalCase to SCREAMING_SNAKE_CASE.
|
|
44
|
+
|
|
45
|
+
Handles consecutive capitals: ``AiLLMChat`` -> ``AI_LLM_CHAT``,
|
|
46
|
+
``G8eActionType`` -> ``G8E_ACTION_TYPE``.
|
|
47
|
+
"""
|
|
48
|
+
s = re.sub(r"(?<=[a-z0-9])(?=[A-Z])", "_", name)
|
|
49
|
+
s = re.sub(r"(?<=[A-Z])(?=[A-Z][a-z])", "_", s)
|
|
50
|
+
s = re.sub(r"(?<=[a-z])(?=[0-9])", "_", s)
|
|
51
|
+
return s.upper()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@lru_cache(maxsize=None)
|
|
55
|
+
def _build_enum(cat_name: str) -> type:
|
|
56
|
+
"""Build an enum class from a STATUS category."""
|
|
57
|
+
cat_vals = STATUS["status"][cat_name]
|
|
58
|
+
|
|
59
|
+
# Determine base class
|
|
60
|
+
sample_val = next(iter(cat_vals.values()))["value"]
|
|
61
|
+
is_int = isinstance(sample_val, (int,)) or (
|
|
62
|
+
isinstance(sample_val, str) and sample_val.lstrip("-").isdigit()
|
|
63
|
+
)
|
|
64
|
+
base = IntEnum if (is_int or cat_name in _INT_CATEGORIES) else StrEnum
|
|
65
|
+
|
|
66
|
+
# Build members
|
|
67
|
+
members: dict[str, str | int] = {}
|
|
68
|
+
for _key, meta in cat_vals.items():
|
|
69
|
+
py_name = meta["_python_const"]
|
|
70
|
+
raw_val = meta["value"]
|
|
71
|
+
if base is IntEnum:
|
|
72
|
+
members[py_name] = int(raw_val)
|
|
73
|
+
else:
|
|
74
|
+
members[py_name] = str(raw_val)
|
|
75
|
+
|
|
76
|
+
cls_name = _to_pascal(cat_name)
|
|
77
|
+
cls = base(cls_name, members) # type: ignore[arg-type]
|
|
78
|
+
return cls
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@lru_cache(maxsize=None)
|
|
82
|
+
def _build_event_type_enum() -> type:
|
|
83
|
+
"""Build the EventType enum from the EVENTS dict.
|
|
84
|
+
|
|
85
|
+
Event keys are PascalCase (e.g. ``AiLLMChatIterationStarted``).
|
|
86
|
+
Member names are SCREAMING_SNAKE_CASE; values preserve the raw
|
|
87
|
+
protocol wire format (e.g. ``g8e.v1.ai.llm.chat.iteration.started``).
|
|
88
|
+
"""
|
|
89
|
+
evts = EVENTS.get("events", {})
|
|
90
|
+
members: dict[str, str] = {}
|
|
91
|
+
for key, meta in evts.items():
|
|
92
|
+
member_name = _pascal_to_screaming_snake(key)
|
|
93
|
+
members[member_name] = meta["value"]
|
|
94
|
+
|
|
95
|
+
return StrEnum("EventType", members) # type: ignore[arg-type]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _to_snake(pascal: str) -> str:
|
|
99
|
+
"""Convert PascalCase to snake_case, handling consecutive capitals.
|
|
100
|
+
|
|
101
|
+
e.g. AISource -> ai_source, G8eActionType -> g8e_action_type,
|
|
102
|
+
ApprovalErrorType -> approval_error_type
|
|
103
|
+
"""
|
|
104
|
+
# Insert _ before each uppercase that follows a lowercase or digit,
|
|
105
|
+
# and before each uppercase that precedes a lowercase
|
|
106
|
+
s = re.sub(r"(?<=[a-z0-9])(?=[A-Z])", "_", pascal)
|
|
107
|
+
s = re.sub(r"(?<=[A-Z])(?=[A-Z][a-z])", "_", s)
|
|
108
|
+
return s.lower()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def __getattr__(name: str):
|
|
112
|
+
"""Dynamic attribute access: g8e.enums.OperatorToolName, EventType, etc."""
|
|
113
|
+
if name == "EventType":
|
|
114
|
+
return _build_event_type_enum()
|
|
115
|
+
|
|
116
|
+
snake = _to_snake(name)
|
|
117
|
+
if snake in STATUS["status"]:
|
|
118
|
+
return _build_enum(snake)
|
|
119
|
+
|
|
120
|
+
# Try dotted-name conversion (e.g. ApprovalErrorType -> approval.error.type)
|
|
121
|
+
for cat in STATUS["status"]:
|
|
122
|
+
pascal = _to_pascal(cat)
|
|
123
|
+
if pascal == name:
|
|
124
|
+
return _build_enum(cat)
|
|
125
|
+
|
|
126
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def __dir__() -> list[str]:
|
|
130
|
+
"""List all available enum class names."""
|
|
131
|
+
names = [_to_pascal(cat) for cat in STATUS["status"]]
|
|
132
|
+
names.append("EventType")
|
|
133
|
+
return names
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
__all__ = [_to_pascal(cat) for cat in STATUS["status"]] + ["EventType"]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from .base import G8eBaseModel, UTCDatetime, Field, ConfigDict
|
|
15
|
+
from .context import RequestContext, BoundOperator
|
|
16
|
+
from .internal_api import (
|
|
17
|
+
ResourceCreationRequest,
|
|
18
|
+
ChatMessageRequest,
|
|
19
|
+
ChatStartedResponse,
|
|
20
|
+
)
|
|
21
|
+
from .settings import G8eeUserSettings, PlatformSettings
|
|
22
|
+
from .events import (
|
|
23
|
+
SessionEventWire,
|
|
24
|
+
BackgroundEventWire,
|
|
25
|
+
AiProcessingStoppedPayload,
|
|
26
|
+
AIToolLifecyclePayload,
|
|
27
|
+
ChatCitationsReadyPayload,
|
|
28
|
+
ChatErrorPayload,
|
|
29
|
+
ChatProcessingStartedPayload,
|
|
30
|
+
ChatResponseChunkPayload,
|
|
31
|
+
ChatResponseCompletePayload,
|
|
32
|
+
ChatRetryPayload,
|
|
33
|
+
ChatThinkingPayload,
|
|
34
|
+
ChatTurnCompletePayload,
|
|
35
|
+
TriageClarificationQuestionsPayload,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"G8eBaseModel",
|
|
40
|
+
"UTCDatetime",
|
|
41
|
+
"Field",
|
|
42
|
+
"ConfigDict",
|
|
43
|
+
"RequestContext",
|
|
44
|
+
"BoundOperator",
|
|
45
|
+
"ResourceCreationRequest",
|
|
46
|
+
"ChatMessageRequest",
|
|
47
|
+
"ChatStartedResponse",
|
|
48
|
+
"G8eeUserSettings",
|
|
49
|
+
"PlatformSettings",
|
|
50
|
+
"SessionEventWire",
|
|
51
|
+
"BackgroundEventWire",
|
|
52
|
+
"AiProcessingStoppedPayload",
|
|
53
|
+
"AIToolLifecyclePayload",
|
|
54
|
+
"ChatCitationsReadyPayload",
|
|
55
|
+
"ChatErrorPayload",
|
|
56
|
+
"ChatProcessingStartedPayload",
|
|
57
|
+
"ChatResponseChunkPayload",
|
|
58
|
+
"ChatResponseCompletePayload",
|
|
59
|
+
"ChatRetryPayload",
|
|
60
|
+
"ChatThinkingPayload",
|
|
61
|
+
"ChatTurnCompletePayload",
|
|
62
|
+
"TriageClarificationQuestionsPayload",
|
|
63
|
+
]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from datetime import UTC, datetime
|
|
15
|
+
from typing import Any, Annotated
|
|
16
|
+
|
|
17
|
+
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer, ValidationError, field_validator, model_validator
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"ConfigDict",
|
|
21
|
+
"Field",
|
|
22
|
+
"G8eBaseModel",
|
|
23
|
+
"UTCDatetime",
|
|
24
|
+
"ValidationError",
|
|
25
|
+
"field_validator",
|
|
26
|
+
"model_validator",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
def _to_iso_z(dt: datetime) -> str:
|
|
30
|
+
"""Serialize a datetime to ISO 8601 with Z suffix (UTC canonical form)."""
|
|
31
|
+
if dt.tzinfo is None:
|
|
32
|
+
dt = dt.replace(tzinfo=UTC)
|
|
33
|
+
else:
|
|
34
|
+
dt = dt.astimezone(UTC)
|
|
35
|
+
return dt.strftime("%Y-%m-%dT%H:%M:%S") + (f".{dt.microsecond:06d}" if dt.microsecond else "") + "Z"
|
|
36
|
+
|
|
37
|
+
UTCDatetime = Annotated[
|
|
38
|
+
datetime,
|
|
39
|
+
PlainSerializer(lambda dt: _to_iso_z(dt) if dt else None, return_type=str | None, when_used="json"),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
class G8eBaseModel(BaseModel):
|
|
43
|
+
"""Base model for all g8e domain objects in the protocol package."""
|
|
44
|
+
model_config = ConfigDict(
|
|
45
|
+
populate_by_name=True,
|
|
46
|
+
extra="ignore",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def model_dump(self, **kwargs: Any) -> dict[str, Any]:
|
|
50
|
+
kwargs.setdefault("exclude_none", True)
|
|
51
|
+
return super().model_dump(**kwargs)
|
|
52
|
+
|
|
53
|
+
def model_dump_json(self, **kwargs: Any) -> str:
|
|
54
|
+
kwargs.setdefault("exclude_none", True)
|
|
55
|
+
return super().model_dump_json(**kwargs)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from .base import G8eBaseModel, Field, model_validator
|
|
15
|
+
from ..constants import ComponentName
|
|
16
|
+
|
|
17
|
+
class BoundOperator(G8eBaseModel):
|
|
18
|
+
"""Represents a bound Operator in the protocol context."""
|
|
19
|
+
operator_id: str = Field(..., description="Unique Operator identifier")
|
|
20
|
+
operator_session_id: str | None = Field(default=None, description="Operator session identifier")
|
|
21
|
+
bound_web_session_id: str | None = Field(default=None, description="Web session ID this Operator is bound to")
|
|
22
|
+
status: str | None = Field(default=None, description="Operator status")
|
|
23
|
+
|
|
24
|
+
class RequestContext(G8eBaseModel):
|
|
25
|
+
"""Request context embedded in request bodies instead of headers.
|
|
26
|
+
|
|
27
|
+
Stabilized protocol version of the RequestContext model.
|
|
28
|
+
"""
|
|
29
|
+
web_session_id: str | None = Field(
|
|
30
|
+
default=None,
|
|
31
|
+
description="Web user session ID"
|
|
32
|
+
)
|
|
33
|
+
cli_session_id: str | None = Field(
|
|
34
|
+
default=None,
|
|
35
|
+
description="CLI session ID"
|
|
36
|
+
)
|
|
37
|
+
user_id: str | None = Field(
|
|
38
|
+
default=None,
|
|
39
|
+
description="User identifier"
|
|
40
|
+
)
|
|
41
|
+
organization_id: str | None = Field(
|
|
42
|
+
default=None,
|
|
43
|
+
description="Organization identifier"
|
|
44
|
+
)
|
|
45
|
+
case_id: str | None = Field(
|
|
46
|
+
default=None,
|
|
47
|
+
description="Current case ID"
|
|
48
|
+
)
|
|
49
|
+
investigation_id: str | None = Field(
|
|
50
|
+
default=None,
|
|
51
|
+
description="Current investigation ID"
|
|
52
|
+
)
|
|
53
|
+
task_id: str | None = Field(
|
|
54
|
+
default=None,
|
|
55
|
+
description="Current task ID"
|
|
56
|
+
)
|
|
57
|
+
bound_operators: list[BoundOperator] = Field(
|
|
58
|
+
default_factory=list,
|
|
59
|
+
description="List of all bound operators"
|
|
60
|
+
)
|
|
61
|
+
execution_id: str | None = Field(
|
|
62
|
+
default=None,
|
|
63
|
+
description="Unique execution identifier"
|
|
64
|
+
)
|
|
65
|
+
source_component: str = Field(
|
|
66
|
+
description="Component that created this context"
|
|
67
|
+
)
|
|
68
|
+
system_fingerprint: str | None = Field(
|
|
69
|
+
default=None,
|
|
70
|
+
description="System fingerprint of the caller"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
@model_validator(mode="after")
|
|
74
|
+
def validate_session_identity(self):
|
|
75
|
+
"""Basic validation of session identity."""
|
|
76
|
+
if self.source_component == ComponentName.CLIENT:
|
|
77
|
+
if self.web_session_id and self.cli_session_id:
|
|
78
|
+
raise ValueError("Context cannot have both web_session_id and cli_session_id")
|
|
79
|
+
|
|
80
|
+
if not self.web_session_id and not self.cli_session_id:
|
|
81
|
+
raise ValueError("Context must have either web_session_id or cli_session_id for CLIENT source")
|
|
82
|
+
if not self.user_id:
|
|
83
|
+
raise ValueError("user_id is required for CLIENT source")
|
|
84
|
+
return self
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from typing import Any
|
|
15
|
+
from .base import G8eBaseModel, UTCDatetime
|
|
16
|
+
|
|
17
|
+
class _SSEEventBody(G8eBaseModel):
|
|
18
|
+
type: str
|
|
19
|
+
data: dict[str, Any]
|
|
20
|
+
|
|
21
|
+
class SessionEventWire(G8eBaseModel):
|
|
22
|
+
web_session_id: str | None = None
|
|
23
|
+
cli_session_id: str | None = None
|
|
24
|
+
user_id: str
|
|
25
|
+
event: _SSEEventBody
|
|
26
|
+
|
|
27
|
+
class BackgroundEventWire(G8eBaseModel):
|
|
28
|
+
user_id: str
|
|
29
|
+
event: _SSEEventBody
|
|
30
|
+
|
|
31
|
+
# AI SSE event payloads (Wire shapes)
|
|
32
|
+
class AiProcessingStoppedPayload(G8eBaseModel):
|
|
33
|
+
reason: str
|
|
34
|
+
timestamp: UTCDatetime
|
|
35
|
+
|
|
36
|
+
class AIToolLifecyclePayload(G8eBaseModel):
|
|
37
|
+
tool_name: str
|
|
38
|
+
display_label: str | None = None
|
|
39
|
+
display_icon: str | None = None
|
|
40
|
+
display_detail: str | None = None
|
|
41
|
+
category: str | None = None
|
|
42
|
+
execution_id: str
|
|
43
|
+
status: str
|
|
44
|
+
query: str | None = None
|
|
45
|
+
content: str | None = None
|
|
46
|
+
results: list[dict[str, Any]] | None = None
|
|
47
|
+
error: str | None = None
|
|
48
|
+
port: str | None = None
|
|
49
|
+
host: str | None = None
|
|
50
|
+
is_open: bool | None = None
|
|
51
|
+
timestamp: str | None = None
|
|
52
|
+
|
|
53
|
+
class ChatCitationsReadyPayload(G8eBaseModel):
|
|
54
|
+
grounding_metadata: dict[str, Any]
|
|
55
|
+
timestamp: str | None = None
|
|
56
|
+
|
|
57
|
+
class ChatErrorPayload(G8eBaseModel):
|
|
58
|
+
error: str
|
|
59
|
+
timestamp: str | None = None
|
|
60
|
+
|
|
61
|
+
class ChatProcessingStartedPayload(G8eBaseModel):
|
|
62
|
+
agent_mode: str
|
|
63
|
+
timestamp: str | None = None
|
|
64
|
+
|
|
65
|
+
class ChatResponseChunkPayload(G8eBaseModel):
|
|
66
|
+
content: str
|
|
67
|
+
timestamp: str | None = None
|
|
68
|
+
|
|
69
|
+
class ChatResponseCompletePayload(G8eBaseModel):
|
|
70
|
+
content: str
|
|
71
|
+
finish_reason: str
|
|
72
|
+
has_citations: bool
|
|
73
|
+
grounding_metadata: dict[str, Any]
|
|
74
|
+
token_usage: dict[str, Any]
|
|
75
|
+
agent_mode: str
|
|
76
|
+
timestamp: str | None = None
|
|
77
|
+
|
|
78
|
+
class ChatRetryPayload(G8eBaseModel):
|
|
79
|
+
attempt: int
|
|
80
|
+
max_attempts: int
|
|
81
|
+
timestamp: str | None = None
|
|
82
|
+
|
|
83
|
+
class ChatThinkingPayload(G8eBaseModel):
|
|
84
|
+
thinking: str | None
|
|
85
|
+
action_type: str
|
|
86
|
+
timestamp: str | None = None
|
|
87
|
+
|
|
88
|
+
class ChatTurnCompletePayload(G8eBaseModel):
|
|
89
|
+
turn: int
|
|
90
|
+
timestamp: str | None = None
|
|
91
|
+
|
|
92
|
+
class TriageClarificationQuestionsPayload(G8eBaseModel):
|
|
93
|
+
questions: list[str]
|
|
94
|
+
complexity: str
|
|
95
|
+
complexity_confidence: str
|
|
96
|
+
intent: str
|
|
97
|
+
intent_confidence: str
|
|
98
|
+
intent_summary: str
|
|
99
|
+
request_posture: str
|
|
100
|
+
posture_confidence: str
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from typing import Any
|
|
15
|
+
from .base import G8eBaseModel, Field
|
|
16
|
+
from .context import RequestContext
|
|
17
|
+
|
|
18
|
+
class ResourceCreationRequest(G8eBaseModel):
|
|
19
|
+
"""Typed request to create new case and investigation resources."""
|
|
20
|
+
create_case: bool = Field(default=False)
|
|
21
|
+
case_title: str | None = Field(default=None)
|
|
22
|
+
|
|
23
|
+
class ChatMessageRequest(G8eBaseModel):
|
|
24
|
+
"""Request model for chat messages."""
|
|
25
|
+
context: RequestContext = Field(...)
|
|
26
|
+
message: str = Field(...)
|
|
27
|
+
attachments: list[dict[str, Any]] | None = Field(default_factory=list)
|
|
28
|
+
sentinel_mode: bool = Field(default=True)
|
|
29
|
+
resource_creation: ResourceCreationRequest | None = Field(default=None)
|
|
30
|
+
llm_primary_provider: str | None = Field(default=None)
|
|
31
|
+
llm_assistant_provider: str | None = Field(default=None)
|
|
32
|
+
llm_lite_provider: str | None = Field(default=None)
|
|
33
|
+
llm_primary_model: str | None = Field(default=None)
|
|
34
|
+
llm_assistant_model: str | None = Field(default=None)
|
|
35
|
+
llm_lite_model: str | None = Field(default=None)
|
|
36
|
+
llm_primary_api_key: str | None = Field(default=None)
|
|
37
|
+
llm_primary_endpoint: str | None = Field(default=None)
|
|
38
|
+
llm_assistant_api_key: str | None = Field(default=None)
|
|
39
|
+
llm_assistant_endpoint: str | None = Field(default=None)
|
|
40
|
+
llm_lite_api_key: str | None = Field(default=None)
|
|
41
|
+
llm_lite_endpoint: str | None = Field(default=None)
|
|
42
|
+
|
|
43
|
+
class ChatStartedResponse(G8eBaseModel):
|
|
44
|
+
"""Response for POST /chat."""
|
|
45
|
+
success: bool
|
|
46
|
+
case_id: str
|
|
47
|
+
investigation_id: str
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
from .base import G8eBaseModel, Field, ConfigDict
|
|
15
|
+
|
|
16
|
+
class SearchSettings(G8eBaseModel):
|
|
17
|
+
"""Unified search configuration."""
|
|
18
|
+
enabled: bool = Field(False)
|
|
19
|
+
project_id: str | None = Field(None)
|
|
20
|
+
engine_id: str | None = Field(None)
|
|
21
|
+
location: str = Field("global")
|
|
22
|
+
api_key: str | None = Field(None)
|
|
23
|
+
|
|
24
|
+
class EvalJudgeSettings(G8eBaseModel):
|
|
25
|
+
"""Evaluation judge configuration."""
|
|
26
|
+
model_config = ConfigDict(
|
|
27
|
+
populate_by_name=True,
|
|
28
|
+
extra="ignore",
|
|
29
|
+
)
|
|
30
|
+
model: str | None = Field(None, alias="eval_judge_model")
|
|
31
|
+
max_output_tokens: int = Field(4096, alias="eval_judge_max_tokens")
|
|
32
|
+
|
|
33
|
+
class CommandValidationSettings(G8eBaseModel):
|
|
34
|
+
"""Operator command safety and validation configuration."""
|
|
35
|
+
enable_whitelisting: bool = Field(False)
|
|
36
|
+
whitelisted_commands: str = Field("")
|
|
37
|
+
enable_blacklisting: bool = Field(True)
|
|
38
|
+
|
|
39
|
+
class BatchExecutionSettings(G8eBaseModel):
|
|
40
|
+
"""Batch execution configuration for Operator tools."""
|
|
41
|
+
max_concurrency: int = Field(10, ge=1, le=64)
|
|
42
|
+
fail_fast: bool = Field(False)
|
|
43
|
+
|
|
44
|
+
class LLMSettings(G8eBaseModel):
|
|
45
|
+
"""LLM provider configuration."""
|
|
46
|
+
model_config = ConfigDict(
|
|
47
|
+
populate_by_name=True,
|
|
48
|
+
extra="ignore",
|
|
49
|
+
)
|
|
50
|
+
primary_provider: str | None = Field(default=None, alias="llm_primary_provider")
|
|
51
|
+
assistant_provider: str | None = Field(default=None, alias="llm_assistant_provider")
|
|
52
|
+
lite_provider: str | None = Field(default=None, alias="llm_lite_provider")
|
|
53
|
+
primary_model: str | None = Field(default=None, alias="llm_model")
|
|
54
|
+
assistant_model: str | None = Field(default=None, alias="llm_assistant_model")
|
|
55
|
+
lite_model: str | None = Field(default=None, alias="llm_lite_model")
|
|
56
|
+
primary_api_key: str | None = Field(default=None)
|
|
57
|
+
primary_endpoint: str | None = Field(default=None)
|
|
58
|
+
assistant_api_key: str | None = Field(default=None)
|
|
59
|
+
assistant_endpoint: str | None = Field(default=None)
|
|
60
|
+
lite_api_key: str | None = Field(default=None)
|
|
61
|
+
lite_endpoint: str | None = Field(default=None)
|
|
62
|
+
|
|
63
|
+
class PlatformSettings(G8eBaseModel):
|
|
64
|
+
"""Platform governance and feature configuration."""
|
|
65
|
+
governance_enabled: bool = Field(True)
|
|
66
|
+
l1_doctrine_enabled: bool = Field(True)
|
|
67
|
+
l2_consensus_enabled: bool = Field(True)
|
|
68
|
+
l3_notary_enabled: bool = Field(True)
|
|
69
|
+
audit_enabled: bool = Field(True)
|
|
70
|
+
sentinel_enabled: bool = Field(True)
|
|
71
|
+
|
|
72
|
+
class G8eeUserSettings(G8eBaseModel):
|
|
73
|
+
"""Per-user settings for g8ee Engine."""
|
|
74
|
+
llm: LLMSettings
|
|
75
|
+
search: SearchSettings = Field(default_factory=SearchSettings)
|
|
76
|
+
eval_judge: EvalJudgeSettings = Field(default_factory=EvalJudgeSettings)
|
|
77
|
+
command_validation: CommandValidationSettings = Field(default_factory=CommandValidationSettings)
|
|
78
|
+
batch_execution: BatchExecutionSettings = Field(default_factory=BatchExecutionSettings)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: g8e
|
|
3
|
+
Version: 1.4.1
|
|
4
|
+
Summary: g8e Protocol Constants and Models
|
|
5
|
+
Author: Lateralus Labs, LLC
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/g8e-ai/g8e
|
|
8
|
+
Project-URL: Repository, https://github.com/g8e-ai/g8e
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: protobuf>=4.0.0
|
|
22
|
+
|
|
23
|
+
# g8e
|
|
24
|
+
|
|
25
|
+
Python protocol library for the g8e zero-trust execution platform. Provides protocol constants, dynamic enums, and Pydantic models for building g8e-compatible clients and services.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Requires Python 3.10 or later. Dependencies are `pydantic>=2.0.0` and `protobuf>=4.0.0`.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install g8e
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Constants
|
|
38
|
+
|
|
39
|
+
The `g8e.constants` module loads JSON protocol constants from `protocol/constants/` at import time. It exports dicts for events, status, collections, headers, channels, pubsub, intents, prompts, timestamps, document IDs, platform configuration, agents, network, API paths, key-value keys, and sender identifiers. The module also exports the `ComponentName` `StrEnum` and individual HTTP header string constants for session, context, and g8e-specific headers.
|
|
40
|
+
|
|
41
|
+
Set the `G8E_PROTOCOL_DIR` environment variable to override the default protocol directory resolution. The loader checks this variable first, then falls back to the relative path from the package, then to `/app/protocol/constants` for containerized environments.
|
|
42
|
+
|
|
43
|
+
### Enums
|
|
44
|
+
|
|
45
|
+
The `g8e.enums` module dynamically generates `StrEnum` and `IntEnum` classes from the `STATUS` and `EVENTS` protocol constants. Enum member names use SCREAMING_SNAKE_CASE; values preserve the raw protocol wire format. Integer-valued categories produce `IntEnum`; all others produce `StrEnum`. Access enums by PascalCase name via attribute lookup, for example `g8e.enums.OperatorToolName` or `g8e.enums.EventType`.
|
|
46
|
+
|
|
47
|
+
### Models
|
|
48
|
+
|
|
49
|
+
The `g8e.models` package provides Pydantic v2 models for protocol data structures. All models extend `G8eBaseModel`, which configures `populate_by_name` and `extra="ignore"`, and defaults `exclude_none` on serialization. The `UTCDatetime` annotated type serializes datetimes to ISO 8601 with a `Z` suffix.
|
|
50
|
+
|
|
51
|
+
- **`g8e/models/base.py`**: `G8eBaseModel`, `UTCDatetime`, and re-exports of Pydantic `Field`, `ConfigDict`, `field_validator`, `model_validator`.
|
|
52
|
+
- **`g8e/models/context.py`**: `RequestContext` and `BoundOperator`. `RequestContext` validates session identity for `CLIENT` source components, requiring either `web_session_id` or `cli_session_id` and a `user_id`.
|
|
53
|
+
- **`g8e/models/events.py`**: SSE wire models (`SessionEventWire`, `BackgroundEventWire`) and AI event payload models for chat processing, tool lifecycle, citations, errors, thinking, turn completion, retry, and triage clarification.
|
|
54
|
+
- **`g8e/models/internal_api.py`**: `ChatMessageRequest`, `ChatStartedResponse`, and `ResourceCreationRequest` for internal API interactions.
|
|
55
|
+
- **`g8e/models/settings.py`**: `G8eeUserSettings`, `PlatformSettings`, and nested settings models for LLM providers, search, eval judge, command validation, and batch execution.
|
|
56
|
+
|
|
57
|
+
### Examples
|
|
58
|
+
|
|
59
|
+
Working examples are in `protocol/python/examples/`. Run `constants_example.py` for constants and headers usage, or `models_example.py` for model instantiation, serialization, and validation.
|
|
60
|
+
|
|
61
|
+
## Components
|
|
62
|
+
|
|
63
|
+
- **`g8e/constants.py`**: Runtime loader for JSON protocol constants from `protocol/constants/`. Exports dict constants, `ComponentName` enum, and HTTP header string constants.
|
|
64
|
+
- **`g8e/enums.py`**: Dynamic `StrEnum` and `IntEnum` generation from `STATUS` and `EVENTS` protocol constants.
|
|
65
|
+
- **`g8e/models/`**: Pydantic v2 models for protocol data structures, SSE events, internal API requests, and user settings.
|
|
66
|
+
|
|
67
|
+
## Protocol Versioning
|
|
68
|
+
|
|
69
|
+
This package follows semantic versioning. Major version changes indicate breaking protocol changes. Minor version changes add new protocol features. Patch version changes include bug fixes and non-breaking enhancements.
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
Apache License 2.0. See `protocol/LICENSE` for details.
|
|
74
|
+
|
|
75
|
+
## Contributing
|
|
76
|
+
|
|
77
|
+
Protocol changes require coordination across all g8e components. Submit protocol change proposals via GitHub issues with clear justification and impact analysis.
|
|
78
|
+
|
|
79
|
+
## Support
|
|
80
|
+
|
|
81
|
+
For protocol questions and support, open a GitHub issue or visit https://github.com/g8e-ai/g8e
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
g8e/__init__.py
|
|
4
|
+
g8e/constants.py
|
|
5
|
+
g8e/enums.py
|
|
6
|
+
g8e.egg-info/PKG-INFO
|
|
7
|
+
g8e.egg-info/SOURCES.txt
|
|
8
|
+
g8e.egg-info/dependency_links.txt
|
|
9
|
+
g8e.egg-info/requires.txt
|
|
10
|
+
g8e.egg-info/top_level.txt
|
|
11
|
+
g8e/models/__init__.py
|
|
12
|
+
g8e/models/base.py
|
|
13
|
+
g8e/models/context.py
|
|
14
|
+
g8e/models/events.py
|
|
15
|
+
g8e/models/internal_api.py
|
|
16
|
+
g8e/models/settings.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
g8e
|
g8e-1.4.1/pyproject.toml
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright (c) 2026 Lateralus Labs, LLC.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
|
|
14
|
+
[build-system]
|
|
15
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
16
|
+
build-backend = "setuptools.build_meta"
|
|
17
|
+
|
|
18
|
+
[project]
|
|
19
|
+
name = "g8e"
|
|
20
|
+
version = "1.4.1"
|
|
21
|
+
description = "g8e Protocol Constants and Models"
|
|
22
|
+
readme = "README.md"
|
|
23
|
+
requires-python = ">=3.10"
|
|
24
|
+
license = {text = "Apache-2.0"}
|
|
25
|
+
authors = [
|
|
26
|
+
{name = "Lateralus Labs, LLC"}
|
|
27
|
+
]
|
|
28
|
+
classifiers = [
|
|
29
|
+
"Development Status :: 4 - Beta",
|
|
30
|
+
"Intended Audience :: Developers",
|
|
31
|
+
"License :: OSI Approved :: Apache Software License",
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Programming Language :: Python :: 3.13",
|
|
37
|
+
"Programming Language :: Python :: 3.14",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
dependencies = [
|
|
41
|
+
"pydantic>=2.0.0",
|
|
42
|
+
"protobuf>=4.0.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/g8e-ai/g8e"
|
|
47
|
+
Repository = "https://github.com/g8e-ai/g8e"
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.packages.find]
|
|
50
|
+
where = ["."]
|
|
51
|
+
include = ["g8e*"]
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.package-data]
|
|
54
|
+
g8e = ["*.json", "**/*.json"]
|
g8e-1.4.1/setup.cfg
ADDED