plm-skill-kernel 1.0.0__tar.gz → 1.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.
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/PKG-INFO +137 -135
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/README.md +115 -115
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/__init__.py +33 -33
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/__main__.py +13 -13
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/dispatcher.py +141 -141
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/registry.py +80 -80
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/__init__.py +29 -29
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/_registry.py +111 -111
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/context.py +66 -66
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/decorator.py +147 -147
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/sdk/types.py +86 -86
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/server.py +173 -173
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/__init__.py +16 -16
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/agents/__init__.py +13 -13
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/agents/suggest.py +191 -191
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/bpmn/__init__.py +9 -9
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/bpmn/generate.py +147 -147
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/__init__.py +10 -10
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/dedupe.py +162 -162
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/cleansing/normalise.py +178 -178
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/documents/__init__.py +12 -12
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/documents/parse.py +202 -202
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/__init__.py +32 -32
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/_v1_corpus.py +153 -153
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/get_record.py +102 -102
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/resolve.py +143 -143
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/retrieve.py +143 -143
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/search.py +161 -161
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills/knowledge/validate.py +222 -222
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/knowledge_pack_loader.py +17 -17
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/knowledge_search_engine.py +25 -25
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/plm_skill_registry.py +573 -573
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/plm_tool_definitions.py +44 -44
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/skill_orchestrator.py +172 -163
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/PKG-INFO +137 -135
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/requires.txt +3 -0
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/pyproject.toml +6 -1
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/setup.cfg +4 -4
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_agents_suggest_asgi.py +208 -208
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_agents_suggest_unit.py +72 -72
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_dispatcher.py +98 -98
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_documents_parse_asgi.py +197 -197
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_documents_parse_unit.py +99 -99
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_sdk_decorator.py +113 -113
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_server.py +202 -202
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_cleansing.py +203 -203
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_knowledge.py +376 -376
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/tests/test_skills_knowledge_registry.py +81 -81
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel/skills_legacy/__init__.py +0 -0
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/SOURCES.txt +0 -0
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/dependency_links.txt +0 -0
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/entry_points.txt +0 -0
- {plm_skill_kernel-1.0.0 → plm_skill_kernel-1.0.2}/plm_skill_kernel.egg-info/top_level.txt +0 -0
|
@@ -1,135 +1,137 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: plm-skill-kernel
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: TracePulse PLM Skill Kernel — Wave 2 Conv A. Decorator-based Skill SDK + V1 in-process dispatcher + Kernel HTTP server stub matching CR.10 §7.bis (POST /v1/skills/{id}/invoke). Ships 3 starter skills (cleansing.normalise, cleansing.dedupe, bpmn.generate). Sibling of plm-engine-core; the two communicate over the V1.1 HTTP loopback (SKILL_KERNEL_LOOPBACK=on) — no Python-level coupling at the dispatch boundary.
|
|
5
|
-
Author: TracePulse
|
|
6
|
-
License: Proprietary
|
|
7
|
-
Requires-Python: >=3.12
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: plm-shared
|
|
10
|
-
Requires-Dist: pydantic>=2.5.0
|
|
11
|
-
Requires-Dist: fastapi>=0.110
|
|
12
|
-
Requires-Dist: uvicorn>=0.27
|
|
13
|
-
Requires-Dist: httpx>=0.27.0
|
|
14
|
-
Requires-Dist: plm-engine-core
|
|
15
|
-
Requires-Dist: plm-knowledge
|
|
16
|
-
Provides-Extra: test
|
|
17
|
-
Requires-Dist: pytest; extra == "test"
|
|
18
|
-
Requires-Dist: pytest-asyncio; extra == "test"
|
|
19
|
-
Requires-Dist: httpx<1,>=0.27; extra == "test"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
│ ├──
|
|
37
|
-
│ ├──
|
|
38
|
-
│ ├──
|
|
39
|
-
│ ├──
|
|
40
|
-
│
|
|
41
|
-
│
|
|
42
|
-
│ │ ├──
|
|
43
|
-
│ │
|
|
44
|
-
│
|
|
45
|
-
│
|
|
46
|
-
│
|
|
47
|
-
│
|
|
48
|
-
│
|
|
49
|
-
│
|
|
50
|
-
└──
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plm-skill-kernel
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: TracePulse PLM Skill Kernel — Wave 2 Conv A. Decorator-based Skill SDK + V1 in-process dispatcher + Kernel HTTP server stub matching CR.10 §7.bis (POST /v1/skills/{id}/invoke). Ships 3 starter skills (cleansing.normalise, cleansing.dedupe, bpmn.generate). Sibling of plm-engine-core; the two communicate over the V1.1 HTTP loopback (SKILL_KERNEL_LOOPBACK=on) — no Python-level coupling at the dispatch boundary.
|
|
5
|
+
Author: TracePulse
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: plm-shared
|
|
10
|
+
Requires-Dist: pydantic>=2.5.0
|
|
11
|
+
Requires-Dist: fastapi>=0.110
|
|
12
|
+
Requires-Dist: uvicorn>=0.27
|
|
13
|
+
Requires-Dist: httpx>=0.27.0
|
|
14
|
+
Requires-Dist: plm-engine-core
|
|
15
|
+
Requires-Dist: plm-knowledge
|
|
16
|
+
Provides-Extra: test
|
|
17
|
+
Requires-Dist: pytest; extra == "test"
|
|
18
|
+
Requires-Dist: pytest-asyncio; extra == "test"
|
|
19
|
+
Requires-Dist: httpx<1,>=0.27; extra == "test"
|
|
20
|
+
Provides-Extra: docs
|
|
21
|
+
Requires-Dist: pdoc>=14.0; extra == "docs"
|
|
22
|
+
|
|
23
|
+
# plm-skill-kernel
|
|
24
|
+
|
|
25
|
+
Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
|
|
26
|
+
`plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
|
|
27
|
+
in-process dispatcher, and the Kernel HTTP server stub matching CR.10
|
|
28
|
+
§7.bis verbatim.
|
|
29
|
+
|
|
30
|
+
## Layout
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
02_App/plm-skill-kernel/
|
|
34
|
+
├── pyproject.toml # editable install + import-linter contracts
|
|
35
|
+
├── plm_skill_kernel/
|
|
36
|
+
│ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
|
|
37
|
+
│ ├── __main__.py # `python -m plm_skill_kernel` → server
|
|
38
|
+
│ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
|
|
39
|
+
│ ├── dispatcher.py # V1 in-process invoker
|
|
40
|
+
│ ├── registry.py # boot wiring — discovers + registers skills
|
|
41
|
+
│ ├── sdk/
|
|
42
|
+
│ │ ├── decorator.py # `@skill(id=, version=)`
|
|
43
|
+
│ │ ├── context.py # SkillContext Pydantic
|
|
44
|
+
│ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
|
|
45
|
+
│ │ └── _registry.py # in-process decorator registry
|
|
46
|
+
│ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
|
|
47
|
+
│ ├── cleansing/
|
|
48
|
+
│ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
|
|
49
|
+
│ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
|
|
50
|
+
│ └── bpmn/
|
|
51
|
+
│ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
|
|
52
|
+
└── tests/ # unit + ASGI in-process integration
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Editable install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd 02_App/backend
|
|
59
|
+
.\venv\Scripts\Activate.ps1 # Windows
|
|
60
|
+
pip install -e ../plm-skill-kernel
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Mirrors the plm-engine-core editable-install pattern.
|
|
64
|
+
|
|
65
|
+
## Dev launch (Q-W2A-3)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python -m plm_skill_kernel # uvicorn on port 8100
|
|
69
|
+
plm-skill-kernel --port 8100 # equivalent CLI
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The backend at port 8000 is unaffected. The V1.1 loopback round-trip
|
|
73
|
+
(D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
|
|
74
|
+
this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
|
|
75
|
+
|
|
76
|
+
## V1 wire contract
|
|
77
|
+
|
|
78
|
+
`POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
Headers:
|
|
82
|
+
X-Core-Caller: <UUID> (required when caller is Core)
|
|
83
|
+
Idempotency-Key: <uuid> (optional, V1)
|
|
84
|
+
traceparent: <W3C> (optional)
|
|
85
|
+
|
|
86
|
+
Request body (SkillInvokeRequest):
|
|
87
|
+
payload: Dict[str, Any]
|
|
88
|
+
version: str ("1.0.0", etc.)
|
|
89
|
+
autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
|
|
90
|
+
|
|
91
|
+
Response body (SkillInvokeResult):
|
|
92
|
+
ok: bool
|
|
93
|
+
result: Optional[Dict[str, Any]]
|
|
94
|
+
error: Optional[SkillErrorEnvelope]
|
|
95
|
+
deferred_to: Optional[str]
|
|
96
|
+
cancelled: Optional[bool]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Skill authoring (Decision #59 — decorator)
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from plm_skill_kernel import skill, SkillContext
|
|
103
|
+
|
|
104
|
+
@skill(id="cleansing.normalise", version="1.0.0")
|
|
105
|
+
async def normalise(payload: dict, ctx: SkillContext) -> dict:
|
|
106
|
+
return {"normalised": _normalise_records(payload["records"])}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The decorator auto-registers into the in-process registry at module
|
|
110
|
+
import time + carries `version` through to the federated manifest
|
|
111
|
+
builder (CR.9).
|
|
112
|
+
|
|
113
|
+
## Import-linter contracts
|
|
114
|
+
|
|
115
|
+
Two Forbidden contracts live in `pyproject.toml`:
|
|
116
|
+
|
|
117
|
+
1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
|
|
118
|
+
contract preservation. The two communicate over HTTP, not Python.
|
|
119
|
+
2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
|
|
120
|
+
— mirror of the plm-engine-core constraint.
|
|
121
|
+
|
|
122
|
+
Run:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Tests
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
cd 02_App/plm-skill-kernel
|
|
132
|
+
python -m pytest -q
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The V1.1 HTTP round-trip integration test mounts the FastAPI app via
|
|
136
|
+
httpx.AsyncClient(ASGITransport) — no subprocess, no real port
|
|
137
|
+
(Q-W2A-4).
|
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
# plm-skill-kernel
|
|
2
|
-
|
|
3
|
-
Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
|
|
4
|
-
`plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
|
|
5
|
-
in-process dispatcher, and the Kernel HTTP server stub matching CR.10
|
|
6
|
-
§7.bis verbatim.
|
|
7
|
-
|
|
8
|
-
## Layout
|
|
9
|
-
|
|
10
|
-
```
|
|
11
|
-
02_App/plm-skill-kernel/
|
|
12
|
-
├── pyproject.toml # editable install + import-linter contracts
|
|
13
|
-
├── plm_skill_kernel/
|
|
14
|
-
│ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
|
|
15
|
-
│ ├── __main__.py # `python -m plm_skill_kernel` → server
|
|
16
|
-
│ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
|
|
17
|
-
│ ├── dispatcher.py # V1 in-process invoker
|
|
18
|
-
│ ├── registry.py # boot wiring — discovers + registers skills
|
|
19
|
-
│ ├── sdk/
|
|
20
|
-
│ │ ├── decorator.py # `@skill(id=, version=)`
|
|
21
|
-
│ │ ├── context.py # SkillContext Pydantic
|
|
22
|
-
│ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
|
|
23
|
-
│ │ └── _registry.py # in-process decorator registry
|
|
24
|
-
│ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
|
|
25
|
-
│ ├── cleansing/
|
|
26
|
-
│ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
|
|
27
|
-
│ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
|
|
28
|
-
│ └── bpmn/
|
|
29
|
-
│ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
|
|
30
|
-
└── tests/ # unit + ASGI in-process integration
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Editable install
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd 02_App/backend
|
|
37
|
-
.\venv\Scripts\Activate.ps1 # Windows
|
|
38
|
-
pip install -e ../plm-skill-kernel
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Mirrors the plm-engine-core editable-install pattern.
|
|
42
|
-
|
|
43
|
-
## Dev launch (Q-W2A-3)
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
python -m plm_skill_kernel # uvicorn on port 8100
|
|
47
|
-
plm-skill-kernel --port 8100 # equivalent CLI
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
The backend at port 8000 is unaffected. The V1.1 loopback round-trip
|
|
51
|
-
(D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
|
|
52
|
-
this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
|
|
53
|
-
|
|
54
|
-
## V1 wire contract
|
|
55
|
-
|
|
56
|
-
`POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
Headers:
|
|
60
|
-
X-Core-Caller: <UUID> (required when caller is Core)
|
|
61
|
-
Idempotency-Key: <uuid> (optional, V1)
|
|
62
|
-
traceparent: <W3C> (optional)
|
|
63
|
-
|
|
64
|
-
Request body (SkillInvokeRequest):
|
|
65
|
-
payload: Dict[str, Any]
|
|
66
|
-
version: str ("1.0.0", etc.)
|
|
67
|
-
autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
|
|
68
|
-
|
|
69
|
-
Response body (SkillInvokeResult):
|
|
70
|
-
ok: bool
|
|
71
|
-
result: Optional[Dict[str, Any]]
|
|
72
|
-
error: Optional[SkillErrorEnvelope]
|
|
73
|
-
deferred_to: Optional[str]
|
|
74
|
-
cancelled: Optional[bool]
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Skill authoring (Decision #59 — decorator)
|
|
78
|
-
|
|
79
|
-
```python
|
|
80
|
-
from plm_skill_kernel import skill, SkillContext
|
|
81
|
-
|
|
82
|
-
@skill(id="cleansing.normalise", version="1.0.0")
|
|
83
|
-
async def normalise(payload: dict, ctx: SkillContext) -> dict:
|
|
84
|
-
return {"normalised": _normalise_records(payload["records"])}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
The decorator auto-registers into the in-process registry at module
|
|
88
|
-
import time + carries `version` through to the federated manifest
|
|
89
|
-
builder (CR.9).
|
|
90
|
-
|
|
91
|
-
## Import-linter contracts
|
|
92
|
-
|
|
93
|
-
Two Forbidden contracts live in `pyproject.toml`:
|
|
94
|
-
|
|
95
|
-
1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
|
|
96
|
-
contract preservation. The two communicate over HTTP, not Python.
|
|
97
|
-
2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
|
|
98
|
-
— mirror of the plm-engine-core constraint.
|
|
99
|
-
|
|
100
|
-
Run:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Tests
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
cd 02_App/plm-skill-kernel
|
|
110
|
-
python -m pytest -q
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
The V1.1 HTTP round-trip integration test mounts the FastAPI app via
|
|
114
|
-
httpx.AsyncClient(ASGITransport) — no subprocess, no real port
|
|
115
|
-
(Q-W2A-4).
|
|
1
|
+
# plm-skill-kernel
|
|
2
|
+
|
|
3
|
+
Wave 2 Conv A (FTR-604). The Skill Kernel package — sibling of
|
|
4
|
+
`plm-engine-core` — that hosts the decorator-based Skill SDK, the V1
|
|
5
|
+
in-process dispatcher, and the Kernel HTTP server stub matching CR.10
|
|
6
|
+
§7.bis verbatim.
|
|
7
|
+
|
|
8
|
+
## Layout
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
02_App/plm-skill-kernel/
|
|
12
|
+
├── pyproject.toml # editable install + import-linter contracts
|
|
13
|
+
├── plm_skill_kernel/
|
|
14
|
+
│ ├── __init__.py # re-exports `skill`, `SkillContext`, etc.
|
|
15
|
+
│ ├── __main__.py # `python -m plm_skill_kernel` → server
|
|
16
|
+
│ ├── server.py # FastAPI app at POST /v1/skills/{id}/invoke
|
|
17
|
+
│ ├── dispatcher.py # V1 in-process invoker
|
|
18
|
+
│ ├── registry.py # boot wiring — discovers + registers skills
|
|
19
|
+
│ ├── sdk/
|
|
20
|
+
│ │ ├── decorator.py # `@skill(id=, version=)`
|
|
21
|
+
│ │ ├── context.py # SkillContext Pydantic
|
|
22
|
+
│ │ ├── types.py # SkillInvokeRequest / SkillInvokeResult
|
|
23
|
+
│ │ └── _registry.py # in-process decorator registry
|
|
24
|
+
│ └── skills/ # 3 starter skills (Q-W2A-1 nested layout)
|
|
25
|
+
│ ├── cleansing/
|
|
26
|
+
│ │ ├── normalise.py # cleansing.normalise / 1.0.0 / L2
|
|
27
|
+
│ │ └── dedupe.py # cleansing.dedupe / 1.0.0 / L2
|
|
28
|
+
│ └── bpmn/
|
|
29
|
+
│ └── generate.py # bpmn.generate / 1.0.0 / L1 (thin proxy)
|
|
30
|
+
└── tests/ # unit + ASGI in-process integration
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Editable install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd 02_App/backend
|
|
37
|
+
.\venv\Scripts\Activate.ps1 # Windows
|
|
38
|
+
pip install -e ../plm-skill-kernel
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Mirrors the plm-engine-core editable-install pattern.
|
|
42
|
+
|
|
43
|
+
## Dev launch (Q-W2A-3)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python -m plm_skill_kernel # uvicorn on port 8100
|
|
47
|
+
plm-skill-kernel --port 8100 # equivalent CLI
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The backend at port 8000 is unaffected. The V1.1 loopback round-trip
|
|
51
|
+
(D-CONV-M-4 closure) sends HTTP from the Engine Core dispatcher to
|
|
52
|
+
this Kernel server when `SKILL_KERNEL_LOOPBACK=on`.
|
|
53
|
+
|
|
54
|
+
## V1 wire contract
|
|
55
|
+
|
|
56
|
+
`POST /v1/skills/{id}/invoke` — frozen at CR.10 §7.bis.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Headers:
|
|
60
|
+
X-Core-Caller: <UUID> (required when caller is Core)
|
|
61
|
+
Idempotency-Key: <uuid> (optional, V1)
|
|
62
|
+
traceparent: <W3C> (optional)
|
|
63
|
+
|
|
64
|
+
Request body (SkillInvokeRequest):
|
|
65
|
+
payload: Dict[str, Any]
|
|
66
|
+
version: str ("1.0.0", etc.)
|
|
67
|
+
autonomy_hint: Optional[str] ("L1" / "L2" / "L3")
|
|
68
|
+
|
|
69
|
+
Response body (SkillInvokeResult):
|
|
70
|
+
ok: bool
|
|
71
|
+
result: Optional[Dict[str, Any]]
|
|
72
|
+
error: Optional[SkillErrorEnvelope]
|
|
73
|
+
deferred_to: Optional[str]
|
|
74
|
+
cancelled: Optional[bool]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Skill authoring (Decision #59 — decorator)
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from plm_skill_kernel import skill, SkillContext
|
|
81
|
+
|
|
82
|
+
@skill(id="cleansing.normalise", version="1.0.0")
|
|
83
|
+
async def normalise(payload: dict, ctx: SkillContext) -> dict:
|
|
84
|
+
return {"normalised": _normalise_records(payload["records"])}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The decorator auto-registers into the in-process registry at module
|
|
88
|
+
import time + carries `version` through to the federated manifest
|
|
89
|
+
builder (CR.9).
|
|
90
|
+
|
|
91
|
+
## Import-linter contracts
|
|
92
|
+
|
|
93
|
+
Two Forbidden contracts live in `pyproject.toml`:
|
|
94
|
+
|
|
95
|
+
1. `plm_skill_kernel` MUST NOT import `plm_engine_core` — federation
|
|
96
|
+
contract preservation. The two communicate over HTTP, not Python.
|
|
97
|
+
2. `plm_skill_kernel` MUST NOT import `plm_accelerators` (Workbench)
|
|
98
|
+
— mirror of the plm-engine-core constraint.
|
|
99
|
+
|
|
100
|
+
Run:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
lint-imports --config 02_App/plm-skill-kernel/pyproject.toml
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Tests
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd 02_App/plm-skill-kernel
|
|
110
|
+
python -m pytest -q
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The V1.1 HTTP round-trip integration test mounts the FastAPI app via
|
|
114
|
+
httpx.AsyncClient(ASGITransport) — no subprocess, no real port
|
|
115
|
+
(Q-W2A-4).
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
"""TracePulse PLM Skill Kernel — Wave 2 Conv A (FTR-604).
|
|
2
|
-
|
|
3
|
-
Sibling of ``plm-engine-core``. Owns:
|
|
4
|
-
|
|
5
|
-
* The decorator-based Skill SDK (Decision #59 — Q-W2A-1 nested layout).
|
|
6
|
-
* The V1 in-process dispatcher.
|
|
7
|
-
* The Kernel HTTP server stub at ``POST /v1/skills/{id}/invoke``
|
|
8
|
-
matching CR.10 §7.bis verbatim.
|
|
9
|
-
* 3 starter skills harvested per Decision #60 — ``cleansing.normalise``,
|
|
10
|
-
``cleansing.dedupe``, ``bpmn.generate``.
|
|
11
|
-
|
|
12
|
-
The Kernel and the Engine Core are deployed-separable. Their only
|
|
13
|
-
sanctioned interaction is the V1.1 HTTP loopback (env-flagged on
|
|
14
|
-
``SKILL_KERNEL_LOOPBACK``); any Python-level reach-in is forbidden by
|
|
15
|
-
the import-linter contract in ``pyproject.toml``.
|
|
16
|
-
"""
|
|
17
|
-
__version__ = "
|
|
18
|
-
|
|
19
|
-
# The decorator + sdk surface is the public authoring API. Re-exported
|
|
20
|
-
# here so callers write ``from plm_skill_kernel import skill`` rather
|
|
21
|
-
# than the deeper path. Skill author imports stay short + stable.
|
|
22
|
-
from .sdk.decorator import skill
|
|
23
|
-
from .sdk.context import SkillContext
|
|
24
|
-
from .sdk.types import SkillInvokeRequest, SkillInvokeResult, SkillErrorEnvelope
|
|
25
|
-
|
|
26
|
-
__all__ = [
|
|
27
|
-
"SkillContext",
|
|
28
|
-
"SkillErrorEnvelope",
|
|
29
|
-
"SkillInvokeRequest",
|
|
30
|
-
"SkillInvokeResult",
|
|
31
|
-
"__version__",
|
|
32
|
-
"skill",
|
|
33
|
-
]
|
|
1
|
+
"""TracePulse PLM Skill Kernel — Wave 2 Conv A (FTR-604).
|
|
2
|
+
|
|
3
|
+
Sibling of ``plm-engine-core``. Owns:
|
|
4
|
+
|
|
5
|
+
* The decorator-based Skill SDK (Decision #59 — Q-W2A-1 nested layout).
|
|
6
|
+
* The V1 in-process dispatcher.
|
|
7
|
+
* The Kernel HTTP server stub at ``POST /v1/skills/{id}/invoke``
|
|
8
|
+
matching CR.10 §7.bis verbatim.
|
|
9
|
+
* 3 starter skills harvested per Decision #60 — ``cleansing.normalise``,
|
|
10
|
+
``cleansing.dedupe``, ``bpmn.generate``.
|
|
11
|
+
|
|
12
|
+
The Kernel and the Engine Core are deployed-separable. Their only
|
|
13
|
+
sanctioned interaction is the V1.1 HTTP loopback (env-flagged on
|
|
14
|
+
``SKILL_KERNEL_LOOPBACK``); any Python-level reach-in is forbidden by
|
|
15
|
+
the import-linter contract in ``pyproject.toml``.
|
|
16
|
+
"""
|
|
17
|
+
__version__ = "1.0.2"
|
|
18
|
+
|
|
19
|
+
# The decorator + sdk surface is the public authoring API. Re-exported
|
|
20
|
+
# here so callers write ``from plm_skill_kernel import skill`` rather
|
|
21
|
+
# than the deeper path. Skill author imports stay short + stable.
|
|
22
|
+
from .sdk.decorator import skill
|
|
23
|
+
from .sdk.context import SkillContext
|
|
24
|
+
from .sdk.types import SkillInvokeRequest, SkillInvokeResult, SkillErrorEnvelope
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"SkillContext",
|
|
28
|
+
"SkillErrorEnvelope",
|
|
29
|
+
"SkillInvokeRequest",
|
|
30
|
+
"SkillInvokeResult",
|
|
31
|
+
"__version__",
|
|
32
|
+
"skill",
|
|
33
|
+
]
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"""``python -m plm_skill_kernel`` entry — delegates to :func:`server._cli_entry`.
|
|
2
|
-
|
|
3
|
-
Q-W2A-3 picked the standalone launch shape. The ``__main__`` module is
|
|
4
|
-
the canonical Python idiom; the ``plm-skill-kernel`` console script
|
|
5
|
-
points at the same function via ``pyproject.toml [project.scripts]``.
|
|
6
|
-
"""
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
from .server import _cli_entry
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if __name__ == "__main__":
|
|
13
|
-
_cli_entry()
|
|
1
|
+
"""``python -m plm_skill_kernel`` entry — delegates to :func:`server._cli_entry`.
|
|
2
|
+
|
|
3
|
+
Q-W2A-3 picked the standalone launch shape. The ``__main__`` module is
|
|
4
|
+
the canonical Python idiom; the ``plm-skill-kernel`` console script
|
|
5
|
+
points at the same function via ``pyproject.toml [project.scripts]``.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from .server import _cli_entry
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
_cli_entry()
|