orbitals 0.0.1__tar.gz → 0.0.2__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.
- {orbitals-0.0.1 → orbitals-0.0.2}/Dockerfile +7 -10
- {orbitals-0.0.1 → orbitals-0.0.2}/LICENSE +1 -1
- {orbitals-0.0.1 → orbitals-0.0.2}/PKG-INFO +24 -3
- {orbitals-0.0.1 → orbitals-0.0.2}/README.md +3 -2
- {orbitals-0.0.1 → orbitals-0.0.2}/README.scope-guard.md +6 -2
- {orbitals-0.0.1 → orbitals-0.0.2}/pyproject.toml +16 -2
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/types.py +14 -2
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/utils.py +5 -3
- orbitals-0.0.2/src/scripts/playground.ipynb +267 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/uv.lock +25 -5
- orbitals-0.0.1/src/scripts/playground.ipynb +0 -196
- {orbitals-0.0.1 → orbitals-0.0.2}/.dockerignore +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/.gitignore +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/AGENTS.md +0 -0
- /orbitals-0.0.1/assets/Orbitals Banner.png → /orbitals-0.0.2/assets/orbitals-banner.png +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/assets/orbitals.svg +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/assets/scope-guard.svg +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/async_api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/local.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/vllm_serve.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/hf_pipeline/scope_guard.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/cli/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/cli/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/convert_default_model_name.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/serve.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/api.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/base.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/hf.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/vllm.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/modeling.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/prompting.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/__init__.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/main.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/vllm_logging_config.json +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/scripts/push_hf_pipeline.py +0 -0
- {orbitals-0.0.1 → orbitals-0.0.2}/src/scripts/push_model.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM vllm/vllm-openai:v0.
|
|
1
|
+
FROM vllm/vllm-openai:v0.14.1 as builder
|
|
2
2
|
|
|
3
3
|
ARG DEBIAN_FRONTEND=noninteractive
|
|
4
4
|
ARG MODEL
|
|
@@ -17,23 +17,20 @@ COPY pyproject.toml uv.lock README.md /app/
|
|
|
17
17
|
|
|
18
18
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
19
19
|
uv venv -p 3.12 && \
|
|
20
|
-
uv sync --frozen --extra serve --no-install-project --no-dev
|
|
20
|
+
uv sync --frozen --extra scope-guard-serve --no-install-project --no-dev
|
|
21
|
+
|
|
22
|
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
23
|
+
hf download ${MODEL}
|
|
21
24
|
|
|
22
25
|
COPY src /app/src/
|
|
23
26
|
|
|
24
27
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
25
28
|
uv sync --locked --extra serve --no-editable --no-dev
|
|
26
29
|
|
|
27
|
-
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
28
|
-
--mount=type=secret,id=HF_TOKEN \
|
|
29
|
-
hf auth login --token $(cat /run/secrets/HF_TOKEN) && \
|
|
30
|
-
hf download $(scope-classifier convert-default-model-name ${MODEL}) && \
|
|
31
|
-
rm -rf /root/.huggingface
|
|
32
|
-
|
|
33
30
|
# TODO remove next line
|
|
34
31
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
35
32
|
|
|
36
|
-
FROM vllm/vllm-openai:v0.
|
|
33
|
+
FROM vllm/vllm-openai:v0.14.1 as runner
|
|
37
34
|
|
|
38
35
|
WORKDIR /app
|
|
39
36
|
ENV PATH="/app/.venv/bin:$PATH"
|
|
@@ -46,4 +43,4 @@ COPY --from=builder /root/.cache/huggingface/hub /root/.cache/huggingface/hub
|
|
|
46
43
|
EXPOSE 8000
|
|
47
44
|
|
|
48
45
|
ENTRYPOINT ["/bin/bash", "-c"]
|
|
49
|
-
CMD [ "scope-
|
|
46
|
+
CMD [ "orbitals", "scope-guard", "serve", "${MODEL}", "--port", "8000", "--host", "0.0.0.0" ]
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright 2026 Principled Intelligence s.r.l.
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orbitals
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: LLM Guardrails tailored to your Principles
|
|
5
5
|
Author-email: Luigi Procopio <luigi@principled-intelligence.com>, Edoardo Barba <edoardo@principled-intelligence.com>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
License-File: LICENSE
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
8
14
|
Requires-Python: >=3.10
|
|
9
15
|
Requires-Dist: aiohttp
|
|
10
16
|
Requires-Dist: pydantic>=2.0.0
|
|
11
17
|
Requires-Dist: requests
|
|
12
18
|
Requires-Dist: typer>=0.12.3
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'all'
|
|
21
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'all'
|
|
22
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'all'
|
|
23
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'all'
|
|
24
|
+
Requires-Dist: vllm>=0.11.0; extra == 'all'
|
|
25
|
+
Requires-Dist: xgrammar; extra == 'all'
|
|
26
|
+
Provides-Extra: scope-guard-all
|
|
27
|
+
Requires-Dist: accelerate>=1.11.0; extra == 'scope-guard-all'
|
|
28
|
+
Requires-Dist: fastapi[standard]>=0.119.1; extra == 'scope-guard-all'
|
|
29
|
+
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-all'
|
|
30
|
+
Requires-Dist: uvicorn>=0.29.0; extra == 'scope-guard-all'
|
|
31
|
+
Requires-Dist: vllm>=0.11.0; extra == 'scope-guard-all'
|
|
32
|
+
Requires-Dist: xgrammar; extra == 'scope-guard-all'
|
|
13
33
|
Provides-Extra: scope-guard-hf
|
|
14
34
|
Requires-Dist: accelerate>=1.11.0; extra == 'scope-guard-hf'
|
|
15
35
|
Requires-Dist: transformers<5.0.0,>=4.47.0; extra == 'scope-guard-hf'
|
|
@@ -26,7 +46,7 @@ Requires-Dist: xgrammar; extra == 'scope-guard-vllm'
|
|
|
26
46
|
Description-Content-Type: text/markdown
|
|
27
47
|
|
|
28
48
|
<div align="center">
|
|
29
|
-
<img src="assets/
|
|
49
|
+
<img src="assets/orbitals-banner.png" width="70%" />
|
|
30
50
|
<h3 align="center">
|
|
31
51
|
<p>
|
|
32
52
|
<b>LLM Guardrails tailored to your Principles</b>
|
|
@@ -77,7 +97,8 @@ from orbitals.scope_guard import ScopeGuard
|
|
|
77
97
|
|
|
78
98
|
scope_guard = ScopeGuard(
|
|
79
99
|
backend="vllm",
|
|
80
|
-
model="scope-guard"
|
|
100
|
+
model="scope-guard-q", # for the Qwen-family model
|
|
101
|
+
# model="scope-guard-g", # for the Gemma-family model
|
|
81
102
|
)
|
|
82
103
|
|
|
83
104
|
ai_service_description = """
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="assets/
|
|
2
|
+
<img src="assets/orbitals-banner.png" width="70%" />
|
|
3
3
|
<h3 align="center">
|
|
4
4
|
<p>
|
|
5
5
|
<b>LLM Guardrails tailored to your Principles</b>
|
|
@@ -50,7 +50,8 @@ from orbitals.scope_guard import ScopeGuard
|
|
|
50
50
|
|
|
51
51
|
scope_guard = ScopeGuard(
|
|
52
52
|
backend="vllm",
|
|
53
|
-
model="scope-guard"
|
|
53
|
+
model="scope-guard-q", # for the Qwen-family model
|
|
54
|
+
# model="scope-guard-g", # for the Gemma-family model
|
|
54
55
|
)
|
|
55
56
|
|
|
56
57
|
ai_service_description = """
|
|
@@ -55,7 +55,8 @@ from orbitals.scope_guard import ScopeGuard
|
|
|
55
55
|
|
|
56
56
|
scope_guard = ScopeGuard(
|
|
57
57
|
backend="vllm",
|
|
58
|
-
model="scope-guard"
|
|
58
|
+
model="scope-guard-q", # for the Qwen-family model
|
|
59
|
+
# model="scope-guard-g", # for the Gemma-family model
|
|
59
60
|
)
|
|
60
61
|
|
|
61
62
|
ai_service_description = """
|
|
@@ -84,6 +85,9 @@ if result.evidences:
|
|
|
84
85
|
<summary>Hosted Flavor</summary>
|
|
85
86
|
<br>
|
|
86
87
|
|
|
88
|
+
> Open access to the hosted models is coming soon.
|
|
89
|
+
> Need access earlier? Contact us at [orbitals@principled-intelligence.com](mailto:orbitals@principled-intelligence.com).
|
|
90
|
+
|
|
87
91
|
First, we need to install `orbitals` and `scope-guard`. In this case, plain `orbitals` is all we need:
|
|
88
92
|
|
|
89
93
|
```bash
|
|
@@ -225,7 +229,7 @@ All of this is configured via the `orbitals scope-guard serve` command:
|
|
|
225
229
|
pip install orbitals[scope-guard-serve]
|
|
226
230
|
|
|
227
231
|
# start everything
|
|
228
|
-
orbitals scope-guard serve
|
|
232
|
+
orbitals scope-guard serve scope-guard --port 8000
|
|
229
233
|
```
|
|
230
234
|
|
|
231
235
|
Alternatively, we also release a pre-built Docker image:
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "orbitals"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.2"
|
|
8
8
|
description = "LLM Guardrails tailored to your Principles"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
|
|
@@ -17,7 +17,14 @@ authors = [
|
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
keywords = []
|
|
20
|
-
classifiers = [
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
]
|
|
21
28
|
|
|
22
29
|
dependencies = ["pydantic>=2.0.0", "typer>=0.12.3", "requests", "aiohttp"]
|
|
23
30
|
|
|
@@ -30,6 +37,13 @@ scope-guard-serve = [
|
|
|
30
37
|
"uvicorn>=0.29.0",
|
|
31
38
|
"vllm>=0.11.0",
|
|
32
39
|
]
|
|
40
|
+
scope-guard-all = [
|
|
41
|
+
"orbitals[scope-guard-vllm]",
|
|
42
|
+
"orbitals[scope-guard-hf]",
|
|
43
|
+
"orbitals[scope-guard-serve]",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
all = ["orbitals[scope-guard-all]"]
|
|
33
47
|
|
|
34
48
|
[project.scripts]
|
|
35
49
|
orbitals = "orbitals.cli.main:app"
|
|
@@ -1,34 +1,46 @@
|
|
|
1
|
-
from typing import Literal
|
|
1
|
+
from typing import ClassVar, Literal
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class LLMUsage(BaseModel):
|
|
7
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
8
|
+
|
|
7
9
|
prompt_tokens: int
|
|
8
10
|
completion_tokens: int
|
|
9
11
|
total_tokens: int
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class ConversationMessage(BaseModel):
|
|
15
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
16
|
+
|
|
13
17
|
role: Literal["user", "assistant"]
|
|
14
18
|
content: str
|
|
15
19
|
|
|
16
20
|
|
|
17
21
|
class Conversation(BaseModel):
|
|
22
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
23
|
+
|
|
18
24
|
messages: list[ConversationMessage]
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
class SupportingMaterial(BaseModel):
|
|
28
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
29
|
+
|
|
22
30
|
pass
|
|
23
31
|
|
|
24
32
|
|
|
25
33
|
class Principle(BaseModel):
|
|
34
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
35
|
+
|
|
26
36
|
title: str = Field(description="Title of the principle")
|
|
27
37
|
description: str = Field(description="Description of the principle")
|
|
28
38
|
supporting_materials: list[SupportingMaterial] | None
|
|
29
39
|
|
|
30
40
|
|
|
31
41
|
class AIServiceDescription(BaseModel):
|
|
42
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
43
|
+
|
|
32
44
|
identity_role: str = Field(
|
|
33
45
|
description="Identity, role and objectives of the AI Service. Gives a general idea of what the service is about."
|
|
34
46
|
)
|
|
@@ -31,6 +31,7 @@ def maybe_configure_gpu_usage():
|
|
|
31
31
|
|
|
32
32
|
best_idx = None
|
|
33
33
|
best_free = -1
|
|
34
|
+
is_multi_gpu = torch.cuda.device_count() > 1
|
|
34
35
|
|
|
35
36
|
for i in range(torch.cuda.device_count()):
|
|
36
37
|
free_bytes, _ = torch.cuda.mem_get_info(i) # (free, total)
|
|
@@ -39,7 +40,8 @@ def maybe_configure_gpu_usage():
|
|
|
39
40
|
best_free = free_bytes
|
|
40
41
|
|
|
41
42
|
if best_idx is not None:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if is_multi_gpu:
|
|
44
|
+
logging.warning(
|
|
45
|
+
f"Auto-configuring to use GPU {best_idx} with {best_free / 1024**3:.2f} GB free"
|
|
46
|
+
)
|
|
45
47
|
os.environ["CUDA_VISIBLE_DEVICES"] = str(best_idx)
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": 1,
|
|
6
|
+
"id": "f616f063",
|
|
7
|
+
"metadata": {},
|
|
8
|
+
"outputs": [],
|
|
9
|
+
"source": [
|
|
10
|
+
"from orbitals.scope_guard.prompting import ScopeClass"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"cell_type": "code",
|
|
15
|
+
"execution_count": 2,
|
|
16
|
+
"id": "1ff6a768",
|
|
17
|
+
"metadata": {},
|
|
18
|
+
"outputs": [
|
|
19
|
+
{
|
|
20
|
+
"name": "stdout",
|
|
21
|
+
"output_type": "stream",
|
|
22
|
+
"text": [
|
|
23
|
+
"**Name**: Directly Supported\n",
|
|
24
|
+
"**Description**: The user's query can be definitively handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description.\n",
|
|
25
|
+
"\n",
|
|
26
|
+
"**Name**: Potentially Supported\n",
|
|
27
|
+
"**Description**: The user's query can be plausibly handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description. The request is a reasonable extension or interpretation of the service's capabilities that might be within scope.\n",
|
|
28
|
+
"\n",
|
|
29
|
+
"**Name**: Out of Scope\n",
|
|
30
|
+
"**Description**: The user's query is outside the AI Service's role and functionalities. It's incompatible with the service's documented purpose.\n",
|
|
31
|
+
"\n",
|
|
32
|
+
"**Name**: Restricted\n",
|
|
33
|
+
"**Description**: The user's query cannot be handled by the AI Service due to either behavioral restrictions (content/advice the service must refuse to provide) or service limitations (technical constraints, access restrictions, or knowledge scope limitations).\n",
|
|
34
|
+
"**Examples**:\n",
|
|
35
|
+
"* Do not provide personalized financial advice. → User: Should I invest my savings in Bitcoin?\n",
|
|
36
|
+
"* The AI service does not have access to real-time data. → User: What's the current stock price of Apple?\n",
|
|
37
|
+
"* AI service cannot access external databases. → User: Look up my account balance in the system.\n",
|
|
38
|
+
"\n",
|
|
39
|
+
"**Name**: Chit Chat\n",
|
|
40
|
+
"**Description**: The user's query is a casual or social interaction that does not pertain to the AI Service's functionalities, knowledge scope, or operational capabilities.\n"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"source": [
|
|
45
|
+
"print(ScopeClass.get_classes_manifest())"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"cell_type": "code",
|
|
50
|
+
"execution_count": 1,
|
|
51
|
+
"id": "ec2d936b",
|
|
52
|
+
"metadata": {},
|
|
53
|
+
"outputs": [],
|
|
54
|
+
"source": [
|
|
55
|
+
"from orbitals.scope_guard.prompting import SYSTEM_PROMPT"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"cell_type": "code",
|
|
60
|
+
"execution_count": 2,
|
|
61
|
+
"id": "991a9bf0",
|
|
62
|
+
"metadata": {},
|
|
63
|
+
"outputs": [
|
|
64
|
+
{
|
|
65
|
+
"name": "stdout",
|
|
66
|
+
"output_type": "stream",
|
|
67
|
+
"text": [
|
|
68
|
+
"You are an expert AI classifier specialized in classifying user queries given the description of an AI service.\n",
|
|
69
|
+
"\n",
|
|
70
|
+
"Your task is to classify the LAST USER MESSAGE in a conversation between a user and an AI Service. Follow these steps:\n",
|
|
71
|
+
"\n",
|
|
72
|
+
"1. **Extract Evidence**: Identify and quote specific excerpts from the AI Service Description that are relevant to understanding whether and how the AI Service can handle the LAST USER MESSAGE. Look for:\n",
|
|
73
|
+
" - Functionalities that might address the user's query\n",
|
|
74
|
+
" - Explicit restrictions or limitations mentioned\n",
|
|
75
|
+
" - Knowledge scope boundaries\n",
|
|
76
|
+
" - Any relevant service capabilities or constraints\n",
|
|
77
|
+
"\n",
|
|
78
|
+
"2. **Classify**: Based on the evidence extracted, assign one of the classification classes below to the LAST USER MESSAGE.\n",
|
|
79
|
+
"\n",
|
|
80
|
+
"## Classification Classes\n",
|
|
81
|
+
"\n",
|
|
82
|
+
"**Name**: Directly Supported\n",
|
|
83
|
+
"**Description**: The user's query can be definitively handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description.\n",
|
|
84
|
+
"\n",
|
|
85
|
+
"**Name**: Potentially Supported\n",
|
|
86
|
+
"**Description**: The user's query can be plausibly handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description. The request is a reasonable extension or interpretation of the service's capabilities that might be within scope.\n",
|
|
87
|
+
"\n",
|
|
88
|
+
"**Name**: Out of Scope\n",
|
|
89
|
+
"**Description**: The user's query is outside the AI Service's role and functionalities. It's incompatible with the service's documented purpose.\n",
|
|
90
|
+
"\n",
|
|
91
|
+
"**Name**: Restricted\n",
|
|
92
|
+
"**Description**: The user's query cannot be handled by the AI Service due to either behavioral restrictions (content/advice the service must refuse to provide) or service limitations (technical constraints, access restrictions, or knowledge scope limitations).\n",
|
|
93
|
+
"**Examples**:\n",
|
|
94
|
+
"* Do not provide personalized financial advice. → User: Should I invest my savings in Bitcoin?\n",
|
|
95
|
+
"* The AI service does not have access to real-time data. → User: What's the current stock price of Apple?\n",
|
|
96
|
+
"* AI service cannot access external databases. → User: Look up my account balance in the system.\n",
|
|
97
|
+
"\n",
|
|
98
|
+
"**Name**: Chit Chat\n",
|
|
99
|
+
"**Description**: The user's query is a casual or social interaction that does not pertain to the AI Service's functionalities, knowledge scope, or operational capabilities.\n",
|
|
100
|
+
"\n",
|
|
101
|
+
"## Important Guidelines\n",
|
|
102
|
+
"* Base your classification EXCLUSIVELY on the AI Service Description provided.\n",
|
|
103
|
+
"* Pay special attention to RESTRICTIONS, CONSTRAINTS, and LIMITATIONS sections in the AI Service Description.\n",
|
|
104
|
+
"* Extract evidence first, then use it to inform your classification decision.\n",
|
|
105
|
+
"* Quote excerpts verbatim from the AI Service Description as evidence.\n",
|
|
106
|
+
"\n",
|
|
107
|
+
"Output the classification in the following JSON schema:\n",
|
|
108
|
+
"{\"$defs\": {\"ScopeClass\": {\"enum\": [\"Directly Supported\", \"Potentially Supported\", \"Out of Scope\", \"Restricted\", \"Chit Chat\"], \"title\": \"ScopeClass\", \"type\": \"string\"}}, \"properties\": {\"evidences\": {\"anyOf\": [{\"items\": {\"type\": \"string\"}, \"type\": \"array\"}, {\"type\": \"null\"}], \"default\": null, \"description\": \"Excerpts quoted directly from the AI Service Description that are relevant to understanding whether and how the AI Service can handle the LAST USER MESSAGE.\", \"title\": \"Evidences\"}, \"scope_class\": {\"$ref\": \"#/$defs/ScopeClass\", \"description\": \"The classification assigned to the LAST USER MESSAGE based on the evidence extracted from the AI Service Description.\"}}, \"required\": [\"scope_class\"], \"title\": \"ScopeGuardResponseModel\", \"type\": \"object\"}\n"
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"source": [
|
|
113
|
+
"print(SYSTEM_PROMPT)"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"cell_type": "code",
|
|
118
|
+
"execution_count": 1,
|
|
119
|
+
"id": "7f850a8f",
|
|
120
|
+
"metadata": {},
|
|
121
|
+
"outputs": [
|
|
122
|
+
{
|
|
123
|
+
"name": "stderr",
|
|
124
|
+
"output_type": "stream",
|
|
125
|
+
"text": [
|
|
126
|
+
"/home/poccio/principled-intelligence/projects/orbitals/.venv/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
|
127
|
+
" from .autonotebook import tqdm as notebook_tqdm\n"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "stdout",
|
|
132
|
+
"output_type": "stream",
|
|
133
|
+
"text": [
|
|
134
|
+
"<|im_start|>system\n",
|
|
135
|
+
"You are a friendly chatbot who always responds in the style of a pirate<|im_end|>\n",
|
|
136
|
+
"<|im_start|>user\n",
|
|
137
|
+
"How many helicopters can a human eat in one sitting?<|im_end|>\n",
|
|
138
|
+
"<|im_start|>assistant\n",
|
|
139
|
+
"<think>\n",
|
|
140
|
+
"\n",
|
|
141
|
+
"</think>\n",
|
|
142
|
+
"\n",
|
|
143
|
+
"\n"
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"source": [
|
|
148
|
+
"from transformers import AutoTokenizer\n",
|
|
149
|
+
"\n",
|
|
150
|
+
"tokenizer = AutoTokenizer.from_pretrained(\"Qwen/Qwen3-4B\")\n",
|
|
151
|
+
"messages = [\n",
|
|
152
|
+
" {\"role\": \"system\", \"content\": \"You are a friendly chatbot who always responds in the style of a pirate\",},\n",
|
|
153
|
+
" {\"role\": \"user\", \"content\": \"How many helicopters can a human eat in one sitting?\"},\n",
|
|
154
|
+
"]\n",
|
|
155
|
+
"\n",
|
|
156
|
+
"prompt = tokenizer.apply_chat_template(\n",
|
|
157
|
+
" messages, \n",
|
|
158
|
+
" tokenize=False,\n",
|
|
159
|
+
" add_generation_prompt=True,\n",
|
|
160
|
+
" enable_thinking=False,)\n",
|
|
161
|
+
"\n",
|
|
162
|
+
" \n",
|
|
163
|
+
"print(prompt)"
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"cell_type": "code",
|
|
168
|
+
"execution_count": null,
|
|
169
|
+
"id": "475af9cc",
|
|
170
|
+
"metadata": {},
|
|
171
|
+
"outputs": [],
|
|
172
|
+
"source": []
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"cell_type": "code",
|
|
176
|
+
"execution_count": 1,
|
|
177
|
+
"id": "e803ba74",
|
|
178
|
+
"metadata": {},
|
|
179
|
+
"outputs": [
|
|
180
|
+
{
|
|
181
|
+
"ename": "ValidationError",
|
|
182
|
+
"evalue": "3 validation errors for AIServiceDescription\nconduct_guidelines\n Extra inputs are not permitted [type=extra_forbidden, input_value='Respond clearly and fact...ser clarity and safety.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden\nconstraints\n Extra inputs are not permitted [type=extra_forbidden, input_value='Cannot modify shipments,...vailable tracking data.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden\nfallback\n Extra inputs are not permitted [type=extra_forbidden, input_value='If tracking data is miss... inventing information.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden",
|
|
183
|
+
"output_type": "error",
|
|
184
|
+
"traceback": [
|
|
185
|
+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
186
|
+
"\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
|
|
187
|
+
"Cell \u001b[0;32mIn[1], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01morbitals\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mtypes\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m AIServiceDescription\n\u001b[0;32m----> 3\u001b[0m ai_service_description_complete \u001b[38;5;241m=\u001b[39m \u001b[43mAIServiceDescription\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43midentity_role\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mYou are PackAssist, a virtual assistant designed to help users understand and \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtrack their parcel shipments. Your objective is to interpret tracking data and \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mguide users through delivery-related questions.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43mcontext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mThe service operates within a parcel-delivery environment where users interact \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 11\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mto check the status of shipments sent domestically or internationally. Typical \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 12\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43musers are customers awaiting deliveries or sending parcels.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 13\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 14\u001b[0m \u001b[43m \u001b[49m\u001b[43mfunctionalities\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 15\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mRetrieve tracking updates; explain the meaning of tracking events; provide \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 16\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mestimated delivery windows; assist users in understanding delays or routing steps.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[43mknowledge_scope\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mPublic tracking information, standard logistics workflows, typical transit times, \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mand general procedures for parcel movement. No access to payment, refund, or claim \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mprocessing systems.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 22\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 23\u001b[0m \u001b[43m \u001b[49m\u001b[43mconduct_guidelines\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 24\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mRespond clearly and factually; do not speculate on unavailable data; avoid any \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 25\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrefund-related discussion; do not provide financial, legal, or compensation advice; \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 26\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mprioritize user clarity and safety.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 27\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 28\u001b[0m \u001b[43m \u001b[49m\u001b[43mconstraints\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 29\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCannot modify shipments, initiate refunds, open claims, contact drivers, or view \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 30\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43minternal logistics notes. Limited strictly to interpreting publicly available \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 31\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtracking data.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 32\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 33\u001b[0m \u001b[43m \u001b[49m\u001b[43mfallback\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\n\u001b[1;32m 34\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mIf tracking data is missing or the request is outside the allowed scope, inform \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 35\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mthe user clearly and redirect them to alternative support channels without \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 36\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43minventing information.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 37\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 38\u001b[0m \u001b[43m \u001b[49m\u001b[43mwebsite_url\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhttps://www.trackmate-delivery.com\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 39\u001b[0m \u001b[43m)\u001b[49m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28mprint\u001b[39m(ai_service_description_complete\u001b[38;5;241m.\u001b[39mmodel_dump_json(indent\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m4\u001b[39m))\n",
|
|
188
|
+
"File \u001b[0;32m~/principled-intelligence/projects/orbitals/.venv/lib/python3.10/site-packages/pydantic/main.py:250\u001b[0m, in \u001b[0;36mBaseModel.__init__\u001b[0;34m(self, **data)\u001b[0m\n\u001b[1;32m 248\u001b[0m \u001b[38;5;66;03m# `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks\u001b[39;00m\n\u001b[1;32m 249\u001b[0m __tracebackhide__ \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[0;32m--> 250\u001b[0m validated_self \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__pydantic_validator__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mvalidate_python\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mself_instance\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 251\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m validated_self:\n\u001b[1;32m 252\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[1;32m 253\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA custom validator is returning a value other than `self`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 254\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mReturning anything other than `self` from a top level model validator isn\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt supported when validating via `__init__`.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 255\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSee the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.\u001b[39m\u001b[38;5;124m'\u001b[39m,\n\u001b[1;32m 256\u001b[0m stacklevel\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m,\n\u001b[1;32m 257\u001b[0m )\n",
|
|
189
|
+
"\u001b[0;31mValidationError\u001b[0m: 3 validation errors for AIServiceDescription\nconduct_guidelines\n Extra inputs are not permitted [type=extra_forbidden, input_value='Respond clearly and fact...ser clarity and safety.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden\nconstraints\n Extra inputs are not permitted [type=extra_forbidden, input_value='Cannot modify shipments,...vailable tracking data.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden\nfallback\n Extra inputs are not permitted [type=extra_forbidden, input_value='If tracking data is miss... inventing information.', input_type=str]\n For further information visit https://errors.pydantic.dev/2.12/v/extra_forbidden"
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"source": [
|
|
194
|
+
"from orbitals.types import AIServiceDescription\n",
|
|
195
|
+
"\n",
|
|
196
|
+
"ai_service_description_complete = AIServiceDescription(\n",
|
|
197
|
+
" identity_role=(\n",
|
|
198
|
+
" \"You are PackAssist, a virtual assistant designed to help users understand and \"\n",
|
|
199
|
+
" \"track their parcel shipments. Your objective is to interpret tracking data and \"\n",
|
|
200
|
+
" \"guide users through delivery-related questions.\"\n",
|
|
201
|
+
" ),\n",
|
|
202
|
+
" context=(\n",
|
|
203
|
+
" \"The service operates within a parcel-delivery environment where users interact \"\n",
|
|
204
|
+
" \"to check the status of shipments sent domestically or internationally. Typical \"\n",
|
|
205
|
+
" \"users are customers awaiting deliveries or sending parcels.\"\n",
|
|
206
|
+
" ),\n",
|
|
207
|
+
" functionalities=(\n",
|
|
208
|
+
" \"Retrieve tracking updates; explain the meaning of tracking events; provide \"\n",
|
|
209
|
+
" \"estimated delivery windows; assist users in understanding delays or routing steps.\"\n",
|
|
210
|
+
" ),\n",
|
|
211
|
+
" knowledge_scope=(\n",
|
|
212
|
+
" \"Public tracking information, standard logistics workflows, typical transit times, \"\n",
|
|
213
|
+
" \"and general procedures for parcel movement. No access to payment, refund, or claim \"\n",
|
|
214
|
+
" \"processing systems.\"\n",
|
|
215
|
+
" ),\n",
|
|
216
|
+
" conduct_guidelines=(\n",
|
|
217
|
+
" \"Respond clearly and factually; do not speculate on unavailable data; avoid any \"\n",
|
|
218
|
+
" \"refund-related discussion; do not provide financial, legal, or compensation advice; \"\n",
|
|
219
|
+
" \"prioritize user clarity and safety.\"\n",
|
|
220
|
+
" ),\n",
|
|
221
|
+
" constraints=(\n",
|
|
222
|
+
" \"Cannot modify shipments, initiate refunds, open claims, contact drivers, or view \"\n",
|
|
223
|
+
" \"internal logistics notes. Limited strictly to interpreting publicly available \"\n",
|
|
224
|
+
" \"tracking data.\"\n",
|
|
225
|
+
" ),\n",
|
|
226
|
+
" fallback=(\n",
|
|
227
|
+
" \"If tracking data is missing or the request is outside the allowed scope, inform \"\n",
|
|
228
|
+
" \"the user clearly and redirect them to alternative support channels without \"\n",
|
|
229
|
+
" \"inventing information.\"\n",
|
|
230
|
+
" ),\n",
|
|
231
|
+
" website_url=\"https://www.trackmate-delivery.com\",\n",
|
|
232
|
+
")\n",
|
|
233
|
+
"\n",
|
|
234
|
+
"print(ai_service_description_complete.model_dump_json(indent=4))"
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"cell_type": "code",
|
|
239
|
+
"execution_count": null,
|
|
240
|
+
"id": "ba983336",
|
|
241
|
+
"metadata": {},
|
|
242
|
+
"outputs": [],
|
|
243
|
+
"source": []
|
|
244
|
+
}
|
|
245
|
+
],
|
|
246
|
+
"metadata": {
|
|
247
|
+
"kernelspec": {
|
|
248
|
+
"display_name": "orbitals",
|
|
249
|
+
"language": "python",
|
|
250
|
+
"name": "python3"
|
|
251
|
+
},
|
|
252
|
+
"language_info": {
|
|
253
|
+
"codemirror_mode": {
|
|
254
|
+
"name": "ipython",
|
|
255
|
+
"version": 3
|
|
256
|
+
},
|
|
257
|
+
"file_extension": ".py",
|
|
258
|
+
"mimetype": "text/x-python",
|
|
259
|
+
"name": "python",
|
|
260
|
+
"nbconvert_exporter": "python",
|
|
261
|
+
"pygments_lexer": "ipython3",
|
|
262
|
+
"version": "3.10.13"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"nbformat": 4,
|
|
266
|
+
"nbformat_minor": 5
|
|
267
|
+
}
|
|
@@ -2924,7 +2924,7 @@ wheels = [
|
|
|
2924
2924
|
|
|
2925
2925
|
[[package]]
|
|
2926
2926
|
name = "orbitals"
|
|
2927
|
-
version = "0.
|
|
2927
|
+
version = "0.0.2"
|
|
2928
2928
|
source = { editable = "." }
|
|
2929
2929
|
dependencies = [
|
|
2930
2930
|
{ name = "aiohttp" },
|
|
@@ -2934,6 +2934,22 @@ dependencies = [
|
|
|
2934
2934
|
]
|
|
2935
2935
|
|
|
2936
2936
|
[package.optional-dependencies]
|
|
2937
|
+
all = [
|
|
2938
|
+
{ name = "accelerate" },
|
|
2939
|
+
{ name = "fastapi", extra = ["standard"] },
|
|
2940
|
+
{ name = "transformers" },
|
|
2941
|
+
{ name = "uvicorn" },
|
|
2942
|
+
{ name = "vllm" },
|
|
2943
|
+
{ name = "xgrammar" },
|
|
2944
|
+
]
|
|
2945
|
+
scope-guard-all = [
|
|
2946
|
+
{ name = "accelerate" },
|
|
2947
|
+
{ name = "fastapi", extra = ["standard"] },
|
|
2948
|
+
{ name = "transformers" },
|
|
2949
|
+
{ name = "uvicorn" },
|
|
2950
|
+
{ name = "vllm" },
|
|
2951
|
+
{ name = "xgrammar" },
|
|
2952
|
+
]
|
|
2937
2953
|
scope-guard-hf = [
|
|
2938
2954
|
{ name = "accelerate" },
|
|
2939
2955
|
{ name = "transformers" },
|
|
@@ -2962,6 +2978,10 @@ requires-dist = [
|
|
|
2962
2978
|
{ name = "accelerate", marker = "extra == 'scope-guard-hf'", specifier = ">=1.11.0" },
|
|
2963
2979
|
{ name = "aiohttp" },
|
|
2964
2980
|
{ name = "fastapi", extras = ["standard"], marker = "extra == 'scope-guard-serve'", specifier = ">=0.119.1" },
|
|
2981
|
+
{ name = "orbitals", extras = ["scope-guard-all"], marker = "extra == 'all'" },
|
|
2982
|
+
{ name = "orbitals", extras = ["scope-guard-hf"], marker = "extra == 'scope-guard-all'" },
|
|
2983
|
+
{ name = "orbitals", extras = ["scope-guard-serve"], marker = "extra == 'scope-guard-all'" },
|
|
2984
|
+
{ name = "orbitals", extras = ["scope-guard-vllm"], marker = "extra == 'scope-guard-all'" },
|
|
2965
2985
|
{ name = "orbitals", extras = ["scope-guard-vllm"], marker = "extra == 'scope-guard-serve'" },
|
|
2966
2986
|
{ name = "pydantic", specifier = ">=2.0.0" },
|
|
2967
2987
|
{ name = "requests" },
|
|
@@ -2973,7 +2993,7 @@ requires-dist = [
|
|
|
2973
2993
|
{ name = "vllm", marker = "extra == 'scope-guard-vllm'", specifier = ">=0.11.0" },
|
|
2974
2994
|
{ name = "xgrammar", marker = "extra == 'scope-guard-vllm'" },
|
|
2975
2995
|
]
|
|
2976
|
-
provides-extras = ["scope-guard-hf", "scope-guard-vllm", "scope-guard-serve"]
|
|
2996
|
+
provides-extras = ["scope-guard-hf", "scope-guard-vllm", "scope-guard-serve", "scope-guard-all", "all"]
|
|
2977
2997
|
|
|
2978
2998
|
[package.metadata.requires-dev]
|
|
2979
2999
|
dev = [
|
|
@@ -5392,11 +5412,11 @@ wheels = [
|
|
|
5392
5412
|
|
|
5393
5413
|
[[package]]
|
|
5394
5414
|
name = "wcwidth"
|
|
5395
|
-
version = "0.
|
|
5415
|
+
version = "0.5.0"
|
|
5396
5416
|
source = { registry = "https://pypi.org/simple" }
|
|
5397
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
5417
|
+
sdist = { url = "https://files.pythonhosted.org/packages/64/6e/62daec357285b927e82263a81f3b4c1790215bc77c42530ce4a69d501a43/wcwidth-0.5.0.tar.gz", hash = "sha256:f89c103c949a693bf563377b2153082bf58e309919dfb7f27b04d862a0089333", size = 246585, upload-time = "2026-01-27T01:31:44.942Z" }
|
|
5398
5418
|
wheels = [
|
|
5399
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
5419
|
+
{ url = "https://files.pythonhosted.org/packages/f2/3e/45583b67c2ff08ad5a582d316fcb2f11d6cf0a50c7707ac09d212d25bc98/wcwidth-0.5.0-py3-none-any.whl", hash = "sha256:1efe1361b83b0ff7877b81ba57c8562c99cf812158b778988ce17ec061095695", size = 93772, upload-time = "2026-01-27T01:31:43.432Z" },
|
|
5400
5420
|
]
|
|
5401
5421
|
|
|
5402
5422
|
[[package]]
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"cells": [
|
|
3
|
-
{
|
|
4
|
-
"cell_type": "code",
|
|
5
|
-
"execution_count": 1,
|
|
6
|
-
"id": "f616f063",
|
|
7
|
-
"metadata": {},
|
|
8
|
-
"outputs": [],
|
|
9
|
-
"source": [
|
|
10
|
-
"from orbitals.scope_guard.prompting import ScopeClass"
|
|
11
|
-
]
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"cell_type": "code",
|
|
15
|
-
"execution_count": 2,
|
|
16
|
-
"id": "1ff6a768",
|
|
17
|
-
"metadata": {},
|
|
18
|
-
"outputs": [
|
|
19
|
-
{
|
|
20
|
-
"name": "stdout",
|
|
21
|
-
"output_type": "stream",
|
|
22
|
-
"text": [
|
|
23
|
-
"**Name**: Directly Supported\n",
|
|
24
|
-
"**Description**: The user's query can be definitively handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description.\n",
|
|
25
|
-
"\n",
|
|
26
|
-
"**Name**: Potentially Supported\n",
|
|
27
|
-
"**Description**: The user's query can be plausibly handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description. The request is a reasonable extension or interpretation of the service's capabilities that might be within scope.\n",
|
|
28
|
-
"\n",
|
|
29
|
-
"**Name**: Out of Scope\n",
|
|
30
|
-
"**Description**: The user's query is outside the AI Service's role and functionalities. It's incompatible with the service's documented purpose.\n",
|
|
31
|
-
"\n",
|
|
32
|
-
"**Name**: Restricted\n",
|
|
33
|
-
"**Description**: The user's query cannot be handled by the AI Service due to either behavioral restrictions (content/advice the service must refuse to provide) or service limitations (technical constraints, access restrictions, or knowledge scope limitations).\n",
|
|
34
|
-
"**Examples**:\n",
|
|
35
|
-
"* Do not provide personalized financial advice. → User: Should I invest my savings in Bitcoin?\n",
|
|
36
|
-
"* The AI service does not have access to real-time data. → User: What's the current stock price of Apple?\n",
|
|
37
|
-
"* AI service cannot access external databases. → User: Look up my account balance in the system.\n",
|
|
38
|
-
"\n",
|
|
39
|
-
"**Name**: Chit Chat\n",
|
|
40
|
-
"**Description**: The user's query is a casual or social interaction that does not pertain to the AI Service's functionalities, knowledge scope, or operational capabilities.\n"
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
],
|
|
44
|
-
"source": [
|
|
45
|
-
"print(ScopeClass.get_classes_manifest())"
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"cell_type": "code",
|
|
50
|
-
"execution_count": 1,
|
|
51
|
-
"id": "ec2d936b",
|
|
52
|
-
"metadata": {},
|
|
53
|
-
"outputs": [],
|
|
54
|
-
"source": [
|
|
55
|
-
"from orbitals.scope_guard.prompting import SYSTEM_PROMPT"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"cell_type": "code",
|
|
60
|
-
"execution_count": 2,
|
|
61
|
-
"id": "991a9bf0",
|
|
62
|
-
"metadata": {},
|
|
63
|
-
"outputs": [
|
|
64
|
-
{
|
|
65
|
-
"name": "stdout",
|
|
66
|
-
"output_type": "stream",
|
|
67
|
-
"text": [
|
|
68
|
-
"You are an expert AI classifier specialized in classifying user queries given the description of an AI service.\n",
|
|
69
|
-
"\n",
|
|
70
|
-
"Your task is to classify the LAST USER MESSAGE in a conversation between a user and an AI Service. Follow these steps:\n",
|
|
71
|
-
"\n",
|
|
72
|
-
"1. **Extract Evidence**: Identify and quote specific excerpts from the AI Service Description that are relevant to understanding whether and how the AI Service can handle the LAST USER MESSAGE. Look for:\n",
|
|
73
|
-
" - Functionalities that might address the user's query\n",
|
|
74
|
-
" - Explicit restrictions or limitations mentioned\n",
|
|
75
|
-
" - Knowledge scope boundaries\n",
|
|
76
|
-
" - Any relevant service capabilities or constraints\n",
|
|
77
|
-
"\n",
|
|
78
|
-
"2. **Classify**: Based on the evidence extracted, assign one of the classification classes below to the LAST USER MESSAGE.\n",
|
|
79
|
-
"\n",
|
|
80
|
-
"## Classification Classes\n",
|
|
81
|
-
"\n",
|
|
82
|
-
"**Name**: Directly Supported\n",
|
|
83
|
-
"**Description**: The user's query can be definitively handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description.\n",
|
|
84
|
-
"\n",
|
|
85
|
-
"**Name**: Potentially Supported\n",
|
|
86
|
-
"**Description**: The user's query can be plausibly handled by the AI Service given the functionalities, knowledge scope, and capabilities described in the AI Service Description. The request is a reasonable extension or interpretation of the service's capabilities that might be within scope.\n",
|
|
87
|
-
"\n",
|
|
88
|
-
"**Name**: Out of Scope\n",
|
|
89
|
-
"**Description**: The user's query is outside the AI Service's role and functionalities. It's incompatible with the service's documented purpose.\n",
|
|
90
|
-
"\n",
|
|
91
|
-
"**Name**: Restricted\n",
|
|
92
|
-
"**Description**: The user's query cannot be handled by the AI Service due to either behavioral restrictions (content/advice the service must refuse to provide) or service limitations (technical constraints, access restrictions, or knowledge scope limitations).\n",
|
|
93
|
-
"**Examples**:\n",
|
|
94
|
-
"* Do not provide personalized financial advice. → User: Should I invest my savings in Bitcoin?\n",
|
|
95
|
-
"* The AI service does not have access to real-time data. → User: What's the current stock price of Apple?\n",
|
|
96
|
-
"* AI service cannot access external databases. → User: Look up my account balance in the system.\n",
|
|
97
|
-
"\n",
|
|
98
|
-
"**Name**: Chit Chat\n",
|
|
99
|
-
"**Description**: The user's query is a casual or social interaction that does not pertain to the AI Service's functionalities, knowledge scope, or operational capabilities.\n",
|
|
100
|
-
"\n",
|
|
101
|
-
"## Important Guidelines\n",
|
|
102
|
-
"* Base your classification EXCLUSIVELY on the AI Service Description provided.\n",
|
|
103
|
-
"* Pay special attention to RESTRICTIONS, CONSTRAINTS, and LIMITATIONS sections in the AI Service Description.\n",
|
|
104
|
-
"* Extract evidence first, then use it to inform your classification decision.\n",
|
|
105
|
-
"* Quote excerpts verbatim from the AI Service Description as evidence.\n",
|
|
106
|
-
"\n",
|
|
107
|
-
"Output the classification in the following JSON schema:\n",
|
|
108
|
-
"{\"$defs\": {\"ScopeClass\": {\"enum\": [\"Directly Supported\", \"Potentially Supported\", \"Out of Scope\", \"Restricted\", \"Chit Chat\"], \"title\": \"ScopeClass\", \"type\": \"string\"}}, \"properties\": {\"evidences\": {\"anyOf\": [{\"items\": {\"type\": \"string\"}, \"type\": \"array\"}, {\"type\": \"null\"}], \"default\": null, \"description\": \"Excerpts quoted directly from the AI Service Description that are relevant to understanding whether and how the AI Service can handle the LAST USER MESSAGE.\", \"title\": \"Evidences\"}, \"scope_class\": {\"$ref\": \"#/$defs/ScopeClass\", \"description\": \"The classification assigned to the LAST USER MESSAGE based on the evidence extracted from the AI Service Description.\"}}, \"required\": [\"scope_class\"], \"title\": \"ScopeGuardResponseModel\", \"type\": \"object\"}\n"
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
"source": [
|
|
113
|
-
"print(SYSTEM_PROMPT)"
|
|
114
|
-
]
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
"cell_type": "code",
|
|
118
|
-
"execution_count": 1,
|
|
119
|
-
"id": "7f850a8f",
|
|
120
|
-
"metadata": {},
|
|
121
|
-
"outputs": [
|
|
122
|
-
{
|
|
123
|
-
"name": "stderr",
|
|
124
|
-
"output_type": "stream",
|
|
125
|
-
"text": [
|
|
126
|
-
"/home/poccio/principled-intelligence/projects/orbitals/.venv/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
|
|
127
|
-
" from .autonotebook import tqdm as notebook_tqdm\n"
|
|
128
|
-
]
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
"name": "stdout",
|
|
132
|
-
"output_type": "stream",
|
|
133
|
-
"text": [
|
|
134
|
-
"<|im_start|>system\n",
|
|
135
|
-
"You are a friendly chatbot who always responds in the style of a pirate<|im_end|>\n",
|
|
136
|
-
"<|im_start|>user\n",
|
|
137
|
-
"How many helicopters can a human eat in one sitting?<|im_end|>\n",
|
|
138
|
-
"<|im_start|>assistant\n",
|
|
139
|
-
"<think>\n",
|
|
140
|
-
"\n",
|
|
141
|
-
"</think>\n",
|
|
142
|
-
"\n",
|
|
143
|
-
"\n"
|
|
144
|
-
]
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
"source": [
|
|
148
|
-
"from transformers import AutoTokenizer\n",
|
|
149
|
-
"\n",
|
|
150
|
-
"tokenizer = AutoTokenizer.from_pretrained(\"Qwen/Qwen3-4B\")\n",
|
|
151
|
-
"messages = [\n",
|
|
152
|
-
" {\"role\": \"system\", \"content\": \"You are a friendly chatbot who always responds in the style of a pirate\",},\n",
|
|
153
|
-
" {\"role\": \"user\", \"content\": \"How many helicopters can a human eat in one sitting?\"},\n",
|
|
154
|
-
"]\n",
|
|
155
|
-
"\n",
|
|
156
|
-
"prompt = tokenizer.apply_chat_template(\n",
|
|
157
|
-
" messages, \n",
|
|
158
|
-
" tokenize=False,\n",
|
|
159
|
-
" add_generation_prompt=True,\n",
|
|
160
|
-
" enable_thinking=False,)\n",
|
|
161
|
-
"\n",
|
|
162
|
-
" \n",
|
|
163
|
-
"print(prompt)"
|
|
164
|
-
]
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
"cell_type": "code",
|
|
168
|
-
"execution_count": null,
|
|
169
|
-
"id": "475af9cc",
|
|
170
|
-
"metadata": {},
|
|
171
|
-
"outputs": [],
|
|
172
|
-
"source": []
|
|
173
|
-
}
|
|
174
|
-
],
|
|
175
|
-
"metadata": {
|
|
176
|
-
"kernelspec": {
|
|
177
|
-
"display_name": "orbitals",
|
|
178
|
-
"language": "python",
|
|
179
|
-
"name": "python3"
|
|
180
|
-
},
|
|
181
|
-
"language_info": {
|
|
182
|
-
"codemirror_mode": {
|
|
183
|
-
"name": "ipython",
|
|
184
|
-
"version": 3
|
|
185
|
-
},
|
|
186
|
-
"file_extension": ".py",
|
|
187
|
-
"mimetype": "text/x-python",
|
|
188
|
-
"name": "python",
|
|
189
|
-
"nbconvert_exporter": "python",
|
|
190
|
-
"pygments_lexer": "ipython3",
|
|
191
|
-
"version": "3.10.13"
|
|
192
|
-
}
|
|
193
|
-
},
|
|
194
|
-
"nbformat": 4,
|
|
195
|
-
"nbformat_minor": 5
|
|
196
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/convert_default_model_name.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|