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.
Files changed (42) hide show
  1. {orbitals-0.0.1 → orbitals-0.0.2}/Dockerfile +7 -10
  2. {orbitals-0.0.1 → orbitals-0.0.2}/LICENSE +1 -1
  3. {orbitals-0.0.1 → orbitals-0.0.2}/PKG-INFO +24 -3
  4. {orbitals-0.0.1 → orbitals-0.0.2}/README.md +3 -2
  5. {orbitals-0.0.1 → orbitals-0.0.2}/README.scope-guard.md +6 -2
  6. {orbitals-0.0.1 → orbitals-0.0.2}/pyproject.toml +16 -2
  7. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/types.py +14 -2
  8. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/utils.py +5 -3
  9. orbitals-0.0.2/src/scripts/playground.ipynb +267 -0
  10. {orbitals-0.0.1 → orbitals-0.0.2}/uv.lock +25 -5
  11. orbitals-0.0.1/src/scripts/playground.ipynb +0 -196
  12. {orbitals-0.0.1 → orbitals-0.0.2}/.dockerignore +0 -0
  13. {orbitals-0.0.1 → orbitals-0.0.2}/.gitignore +0 -0
  14. {orbitals-0.0.1 → orbitals-0.0.2}/AGENTS.md +0 -0
  15. /orbitals-0.0.1/assets/Orbitals Banner.png → /orbitals-0.0.2/assets/orbitals-banner.png +0 -0
  16. {orbitals-0.0.1 → orbitals-0.0.2}/assets/orbitals.svg +0 -0
  17. {orbitals-0.0.1 → orbitals-0.0.2}/assets/scope-guard.svg +0 -0
  18. {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/api.py +0 -0
  19. {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/async_api.py +0 -0
  20. {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/local.py +0 -0
  21. {orbitals-0.0.1 → orbitals-0.0.2}/examples/scope-guard/vllm_serve.py +0 -0
  22. {orbitals-0.0.1 → orbitals-0.0.2}/src/hf_pipeline/scope_guard.py +0 -0
  23. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/__init__.py +0 -0
  24. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/cli/__init__.py +0 -0
  25. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/cli/main.py +0 -0
  26. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/__init__.py +0 -0
  27. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/__init__.py +0 -0
  28. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/convert_default_model_name.py +0 -0
  29. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/main.py +0 -0
  30. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/cli/serve.py +0 -0
  31. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/__init__.py +0 -0
  32. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/api.py +0 -0
  33. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/base.py +0 -0
  34. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/hf.py +0 -0
  35. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/guards/vllm.py +0 -0
  36. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/modeling.py +0 -0
  37. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/prompting.py +0 -0
  38. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/__init__.py +0 -0
  39. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/main.py +0 -0
  40. {orbitals-0.0.1 → orbitals-0.0.2}/src/orbitals/scope_guard/serving/vllm_logging_config.json +0 -0
  41. {orbitals-0.0.1 → orbitals-0.0.2}/src/scripts/push_hf_pipeline.py +0 -0
  42. {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.11.2 as builder
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.11.2 as runner
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-classifier", "serve", "${MODEL}", "--backend", "hf", "--port", "8000", "--host", "0.0.0.0" ]
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 [yyyy] [name of copyright owner]
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.1
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/Orbitals Banner.png" width="70%" />
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/Orbitals Banner.png" width="70%" />
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 serve scope-guard --port 8000
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.1"
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
- logging.warning(
43
- f"Auto-configuring VLLM to use GPU {best_idx} with {best_free / 1024**3:.2f} GB free"
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.1.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.4.0"
5415
+ version = "0.5.0"
5396
5416
  source = { registry = "https://pypi.org/simple" }
5397
- sdist = { url = "https://files.pythonhosted.org/packages/98/0a/dc5110cc99c39df65bac29229c4b637a8304e0914850348d98974c8ecfff/wcwidth-0.4.0.tar.gz", hash = "sha256:46478e02cf7149ba150fb93c39880623ee7e5181c64eda167b6a1de51b7a7ba1", size = 237625, upload-time = "2026-01-26T02:35:58.844Z" }
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/b7/f6/da704c5e77281d71723bffbd926b754c0efd57cbcd02e74c2ca374c14cef/wcwidth-0.4.0-py3-none-any.whl", hash = "sha256:8af2c81174b3aa17adf05058c543c267e4e5b6767a28e31a673a658c1d766783", size = 88216, upload-time = "2026-01-26T02:35:57.461Z" },
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