@cernion/openclaw-energy-tools-sidecar 0.1.0
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.
- package/CHANGELOG.md +12 -0
- package/CONTRIBUTING.md +31 -0
- package/LICENSE +201 -0
- package/README.md +202 -0
- package/SECURITY.md +27 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +1053 -0
- package/docker/.env.example +40 -0
- package/docker/Dockerfile +36 -0
- package/docker/README.md +302 -0
- package/docker/compose.sidecar-it.yml +49 -0
- package/docker/compose.yml +29 -0
- package/docker/entrypoint.sh +249 -0
- package/docker/profiles/cernion-demo/AGENTS.md +45 -0
- package/docker/profiles/cernion-demo/SOUL.md +23 -0
- package/docker/profiles/cernion-demo/TOOLS.md +111 -0
- package/openclaw.plugin.json +136 -0
- package/package.json +52 -0
- package/scripts/sidecar-smoke.mjs +127 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Cernion Energy Tools Sidecar for OpenClaw are documented here.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 - Unreleased
|
|
6
|
+
|
|
7
|
+
- Initial dedicated Cernion Energy Tools Sidecar package for OpenClaw.
|
|
8
|
+
- Exposes Cernion descriptor, tool-list, provider tool calls, Knowledge RAG, OSM grid context, Evidence Router, process-intake, capability/operation resolution, read-only REST plan execution, and direct read-only Cernion API requests.
|
|
9
|
+
- Keeps read-only evidence and process-intake tokens separated.
|
|
10
|
+
- Blocks admin/auth/token/HITL-resolve/provider-tool recursion paths in read-only REST execution.
|
|
11
|
+
- Adds asset-list pagination and CSV/XLS export guidance for `/api/assets...` GET requests.
|
|
12
|
+
- Includes Docker demo workspace and smoke test.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
This repository contains the dedicated Cernion Energy Tools Sidecar for OpenClaw.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm ci
|
|
9
|
+
npm run build
|
|
10
|
+
npm test
|
|
11
|
+
npm run plugin:validate
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Design Rules
|
|
15
|
+
|
|
16
|
+
- Keep Cernion Energy Tools as the provider and policy owner.
|
|
17
|
+
- Do not hard-code new domain routing in the Sidecar when Cernion can expose it through `cernion.ask`, the Evidence Router, capabilities, or operation manifests.
|
|
18
|
+
- Keep read-only evidence and process-intake boundaries separate.
|
|
19
|
+
- Never add admin, auth, token, secret, HITL-resolve, provider-tool recursion, or mutation paths to read-only REST execution.
|
|
20
|
+
- Scrub bearer tokens from all returned payloads and errors.
|
|
21
|
+
- Update README, tests, and `dist/` for user-visible tool or package changes.
|
|
22
|
+
|
|
23
|
+
## Release Checklist
|
|
24
|
+
|
|
25
|
+
- `npm ci`
|
|
26
|
+
- `npm run build`
|
|
27
|
+
- `npm test`
|
|
28
|
+
- `npm run plugin:validate`
|
|
29
|
+
- `npm pack --dry-run`
|
|
30
|
+
- update `CHANGELOG.md`
|
|
31
|
+
- tag the release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Cernion Energy Tools Sidecar for OpenClaw
|
|
2
|
+
|
|
3
|
+
Dedicated OpenClaw tool plugin for Cernion Energy Tools.
|
|
4
|
+
|
|
5
|
+
Cernion Energy Tools is a Swiss Army Knife for energy questions: it combines
|
|
6
|
+
asset inventories, MaStR evidence, grid context, regulatory/procedural
|
|
7
|
+
knowledge, process intake, and read-only operational APIs into one fachliche
|
|
8
|
+
evidence layer. The Sidecar makes that layer available inside OpenClaw so an
|
|
9
|
+
energy-domain assistant can answer with Cernion-backed facts instead of generic
|
|
10
|
+
model memory.
|
|
11
|
+
|
|
12
|
+
The plugin is the ideal fachliche companion for people working in the energy
|
|
13
|
+
sector: grid planning, asset-MDM, Redispatch, Zielnetzplanung, §14a/§14d,
|
|
14
|
+
market communication, storage/PV/load siting, and operational readiness checks.
|
|
15
|
+
|
|
16
|
+
The plugin consumes the Cernion Sidecar contract implemented by Cernion Energy Tools:
|
|
17
|
+
|
|
18
|
+
- `GET /api/agent-sidecar/descriptor`
|
|
19
|
+
- `GET /api/agent-sidecar/mcp/tools`
|
|
20
|
+
- `POST /api/agent-sidecar/mcp/tools/:name/call`
|
|
21
|
+
- `POST /api/agent-sidecar/mcp/tools/cernion.ask/call`
|
|
22
|
+
- `POST /api/knowledge-rag/query`
|
|
23
|
+
- `POST /api/evidence-router/route`
|
|
24
|
+
- `POST /api/copilot-process/intents`
|
|
25
|
+
- `GET /api/_agent/capabilities[?domain=]`
|
|
26
|
+
- `GET /api/_agent/capabilities/:name`
|
|
27
|
+
- `GET /api/_agent/operations[?domain=]`
|
|
28
|
+
|
|
29
|
+
The Cernion provider remains the policy owner. This plugin stores host-side configuration, discovers tools, and forwards calls through separated provider boundaries:
|
|
30
|
+
|
|
31
|
+
- read-only evidence lookup/execution, using the read-only Cernion token
|
|
32
|
+
- read-only regulatory and procedural knowledge lookup through Cernion Knowledge RAG
|
|
33
|
+
- process intake, using a separate process token and creating only `pending_confirmation` receipts
|
|
34
|
+
|
|
35
|
+
It does not implement Cernion domain logic and must not expose admin/token/HITL-resolve actions. Cernion Energy Tools remains the source of truth for capabilities, policies, evidence semantics, and executable read-only REST plans.
|
|
36
|
+
|
|
37
|
+
`cernion.ask` is the generic learning/compile boundary for OpenClaw. It may return a direct read-only REST execution plan that was selected by Cernion's Blueprint/Capability runtime. OpenClaw can then ask this plugin to proxy that plan against the configured Cernion `baseUrl` without learning tokens or hard-coding domain routing in the Sidecar.
|
|
38
|
+
|
|
39
|
+
## Tools
|
|
40
|
+
|
|
41
|
+
- `cernion_sidecar_descriptor` loads the Cernion Energy Tools Sidecar descriptor.
|
|
42
|
+
- `cernion_sidecar_tools` loads the MCP/OpenClaw-like tool list.
|
|
43
|
+
- `cernion_sidecar_call` calls one curated Cernion provider tool through the provider policy gate.
|
|
44
|
+
- `cernion_query_domain_knowledge` queries Cernion Knowledge RAG for regulatory, procedural, and fachliche evidence such as laws, BNetzA guidance, Verfahrensanweisungen, roles, obligations, definitions, and job-help context. It starts the async Knowledge RAG job, waits briefly for the result, and returns an `evidenceAssessment`. This assessment describes primary-source support for hard legal/procedural claims, not the value of Cernion domain knowledge itself. If `evidenceAdequacy` is `low`, OpenClaw should say that Cernion returned useful domain/strategy knowledge but not enough primary-source support for hard obligations.
|
|
45
|
+
- `cernion_query_grid_context` queries Cernion OSM Geo for visible grid infrastructure context such as substations, transformers, voltage-level hints, lines, and topology metrics. Use it for ZNP, Netzanschluss, data-center/PV/BESS/HPC siting, fNAV, and likely critical voltage-level hypotheses. For broad county or region searches, query substations first and enable full topology only for candidate-place drill-down. Treat the result as OSM-based hypothesis evidence, not as a capacity proof or complete grid-operator asset model. For data centers and other large loads, explicit grid-connection availability maps, published capacity, and operator-confirmed Anschlusskapazität outrank generic grid-expansion or OSM proximity evidence.
|
|
46
|
+
- `cernion_route_evidence` calls Cernion's backend Evidence Router and returns read-only endpoint recommendations plus result semantics.
|
|
47
|
+
- `cernion_execute_evidence_endpoint` executes one GET or POST read-only endpoint recommended by `cernion_route_evidence`, requiring `policy.readOnly=true` and `sideEffects=none`. For `/api/assets...` GETs, the Sidecar sets an explicit default `limit=500` when no limit is supplied and adds `_sidecar` pagination/export guidance when the returned rows exhaust the requested limit.
|
|
48
|
+
- `cernion_prepare_process_intent` calls Cernion's separate Process Intake boundary and creates only a `pending_confirmation` receipt. It uses a separate process token.
|
|
49
|
+
- `cernion_ask` calls the generic `cernion.ask` provider tool and returns structured answers, evidence, capability/blueprint hints, and optional read-only REST execution plans.
|
|
50
|
+
- `cernion_resolve_capabilities` resolves llm.txt capability cluster heads to full capability details, optionally filtered by `domain`.
|
|
51
|
+
- `cernion_resolve_capability` resolves a single capability id to full detail.
|
|
52
|
+
- `cernion_resolve_operations` resolves manifest operation clusters to deduplicated operation details, optionally filtered by `domain`.
|
|
53
|
+
- `cernion_execute_rest_plan` proxies one GET-only REST execution plan emitted by Cernion. It validates that the plan is a relative `/api/` path and blocks admin/auth/token/HITL-resolve/provider-tool recursion paths. Asset-list GETs receive explicit limit and pagination/export guidance.
|
|
54
|
+
- `cernion_api_request` performs an authenticated read-only GET against Cernion for fallback resolution or domain data queries. Asset-list GETs receive explicit limit and pagination/export guidance.
|
|
55
|
+
|
|
56
|
+
`cernion_resolve_operations` uses the provider's canonicalized operation list: duplicate `operationId` entries that appear under trailing-slash or service-prefix aliases are returned once with a canonical path and an `aliases` list.
|
|
57
|
+
|
|
58
|
+
The provider tool names currently exposed by Cernion are:
|
|
59
|
+
|
|
60
|
+
- `cernion.ask`
|
|
61
|
+
- `cernion.answer_dossier`
|
|
62
|
+
- `cernion.recommend_capability`
|
|
63
|
+
- `cernion.list_readonly_capabilities`
|
|
64
|
+
- `cernion.get_evidence_status`
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
Configure through OpenClaw plugin settings or environment variables:
|
|
69
|
+
|
|
70
|
+
- `baseUrl` or `CERNION_BASE_URL`: Cernion base URL, for example `https://cernion.example`.
|
|
71
|
+
- `bearerToken` or `CERNION_READONLY_TOKEN`: read-only Cernion Sidecar token.
|
|
72
|
+
- `bearerTokenEnv`: optional alternate token environment variable name.
|
|
73
|
+
- `bearerTokenFile` or `CERNION_READONLY_TOKEN_FILE`: optional path to a local file containing the read-only token.
|
|
74
|
+
- `processBearerToken` or `CERNION_PROCESS_TOKEN`: separate Cernion token for `cernion_prepare_process_intent`.
|
|
75
|
+
- `processBearerTokenEnv`: optional alternate process-token environment variable name.
|
|
76
|
+
- `processBearerTokenFile` or `CERNION_PROCESS_TOKEN_FILE`: optional path to a local file containing the process token.
|
|
77
|
+
- `allowRestProxy` or `CERNION_ALLOW_REST_PROXY`: optional switch for `cernion_execute_rest_plan`, default enabled. Set to `false`, `0`, `no`, or `off` to disable.
|
|
78
|
+
- `timeoutMs`: optional HTTP timeout, default `15000`.
|
|
79
|
+
|
|
80
|
+
Store the token as an OpenClaw secret. The token is sent only as an `Authorization: Bearer ...` header and is scrubbed from returned payloads if a provider accidentally echoes it.
|
|
81
|
+
|
|
82
|
+
## Asset Lists, Pagination, and Exports
|
|
83
|
+
|
|
84
|
+
Cernion asset endpoints can return large MaStR-backed lists. The Sidecar does
|
|
85
|
+
not let those lists silently fall back to the provider default limit:
|
|
86
|
+
|
|
87
|
+
- for `/api/assets...` GET requests without `limit`, it sends `limit=500`;
|
|
88
|
+
- when returned rows exhaust the requested limit, it adds `_sidecar.assetListPagination`;
|
|
89
|
+
- the metadata includes `nextPage` parameters and CSV/XLS `exportOptions`;
|
|
90
|
+
- assistants must not present the returned rows as complete when
|
|
91
|
+
`_sidecar.assetListPagination.limitExhausted=true` or `hasMore=true`.
|
|
92
|
+
|
|
93
|
+
Example guidance for a user-facing answer:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
Cernion returned 500 rows for the current asset query, which exhausts the requested limit. I can continue with the next page or retrieve the complete list as CSV/XLS.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Local Development
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm install
|
|
103
|
+
npm run plugin:build
|
|
104
|
+
npm run plugin:validate
|
|
105
|
+
npm test
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Docker Demo Container
|
|
109
|
+
|
|
110
|
+
The repository includes a Docker-based OpenClaw demo under `docker/`. It starts
|
|
111
|
+
OpenClaw with this plugin installed and exposes the browser Control UI on
|
|
112
|
+
`http://localhost:19101`.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cp docker/.env.example docker/.env
|
|
116
|
+
# edit docker/.env: CERNION_BASE_URL, CERNION_TOKEN, OPENCLAW_MODEL, OPENCLAW_THINKING, and a model-provider key
|
|
117
|
+
docker compose --env-file docker/.env -f docker/compose.yml up --build
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The demo accepts `CERNION_BASE_URL`, `CERNION_TOKEN`,
|
|
121
|
+
`CERNION_READONLY_TOKEN`, and `CERNION_PROCESS_TOKEN` through environment
|
|
122
|
+
variables. No operator workspace, memory, transcripts, or personal OpenClaw
|
|
123
|
+
state are mounted.
|
|
124
|
+
|
|
125
|
+
See [docker/README.md](docker/README.md) for the full end-user walkthrough,
|
|
126
|
+
including the Cernion demo workspace profile and the Meckesheim self-supply
|
|
127
|
+
example prompt.
|
|
128
|
+
|
|
129
|
+
## Local Install
|
|
130
|
+
|
|
131
|
+
From this directory:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
openclaw plugins install .
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Or from GitHub:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
openclaw plugins install https://github.com/SmartEnergySolutions/cernion-openclaw-sidecar
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Or from npm after publication:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
openclaw plugins install @cernion/openclaw-energy-tools-sidecar
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Then configure:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
export CERNION_BASE_URL="https://cernion.example"
|
|
153
|
+
export CERNION_READONLY_TOKEN_FILE="$HOME/.config/cernion/readonly-token"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The token file should contain only the bearer token and should be readable only by the OpenClaw runtime user, for example mode `0600`.
|
|
157
|
+
|
|
158
|
+
## Boundaries
|
|
159
|
+
|
|
160
|
+
Allowed:
|
|
161
|
+
|
|
162
|
+
- read-only/advisory tool discovery
|
|
163
|
+
- calls to curated Cernion Sidecar tools
|
|
164
|
+
- read-only Knowledge RAG queries for regulatory and procedural domain evidence
|
|
165
|
+
- read-only OSM Geo grid-context queries for ZNP and Netzanschluss hypotheses
|
|
166
|
+
- read-only Evidence Router calls and execution of router-recommended GET/POST evidence endpoints
|
|
167
|
+
- Process Intake creation of `pending_confirmation` receipts through a separate process-token boundary
|
|
168
|
+
- resolve calls to the Cernion agent manifest endpoints
|
|
169
|
+
- generic `cernion.ask` calls where Cernion decides capabilities, blueprints, routing, policies, and evidence
|
|
170
|
+
- GET-only proxy execution of Cernion-issued REST plans against the configured provider `baseUrl`
|
|
171
|
+
- structured propagation of `sidecar_policy_blocked`
|
|
172
|
+
|
|
173
|
+
Blocked:
|
|
174
|
+
|
|
175
|
+
- Full Cernion OpenAPI export
|
|
176
|
+
- admin/token/HITL-resolve actions
|
|
177
|
+
- process execution or HITL resolution after Process Intake
|
|
178
|
+
- Sidecar-owned domain routing such as hard-coded MaStR asset tools
|
|
179
|
+
- arbitrary external URLs or non-`/api/` REST proxy paths
|
|
180
|
+
- production mutation
|
|
181
|
+
- secrets in descriptors, logs, or tool responses
|
|
182
|
+
- OpenClaw workspace coupling inside Cernion
|
|
183
|
+
|
|
184
|
+
## Publishing
|
|
185
|
+
|
|
186
|
+
The package name is `@cernion/openclaw-energy-tools-sidecar`. Publishing under
|
|
187
|
+
that scope requires:
|
|
188
|
+
|
|
189
|
+
- access to the `@cernion` npm organization or user scope;
|
|
190
|
+
- an npm automation token stored as `NPM_TOKEN` for GitHub Actions;
|
|
191
|
+
- 2FA/provenance settings compatible with the selected npm release policy;
|
|
192
|
+
- a release tag such as `v0.1.0`.
|
|
193
|
+
|
|
194
|
+
Release checks should pass before publishing:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm ci
|
|
198
|
+
npm run build
|
|
199
|
+
npm test
|
|
200
|
+
npm run plugin:validate
|
|
201
|
+
npm pack --dry-run
|
|
202
|
+
```
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Security fixes are currently prepared on `main` until the first public release is tagged.
|
|
6
|
+
|
|
7
|
+
## Reporting a Vulnerability
|
|
8
|
+
|
|
9
|
+
Do not open public issues for secrets, token exposure, authentication bypasses, policy-boundary bypasses, or unintended write/process execution.
|
|
10
|
+
|
|
11
|
+
Report security concerns privately to the Cernion maintainers through the configured project security channel or by contacting the repository owner directly. Include:
|
|
12
|
+
|
|
13
|
+
- affected Sidecar version or commit;
|
|
14
|
+
- OpenClaw version;
|
|
15
|
+
- Cernion Energy Tools base version if known;
|
|
16
|
+
- minimal reproduction steps;
|
|
17
|
+
- whether any token, tenant data, or process action was exposed.
|
|
18
|
+
|
|
19
|
+
## Security Boundaries
|
|
20
|
+
|
|
21
|
+
The Sidecar must preserve these boundaries:
|
|
22
|
+
|
|
23
|
+
- read-only evidence calls use the read-only Cernion token;
|
|
24
|
+
- process intake uses a separate process token and creates only pending-confirmation receipts;
|
|
25
|
+
- admin, auth, token, secret, HITL-resolve, and provider-tool recursion paths are blocked from read-only REST execution;
|
|
26
|
+
- bearer tokens must not be returned in tool payloads, logs, descriptors, or error envelopes;
|
|
27
|
+
- Cernion Energy Tools remains the policy owner for capabilities, evidence semantics, and process execution.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
type PluginConfig = {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
bearerToken?: string;
|
|
4
|
+
bearerTokenEnv?: string;
|
|
5
|
+
bearerTokenFile?: string;
|
|
6
|
+
processBearerToken?: string;
|
|
7
|
+
processBearerTokenEnv?: string;
|
|
8
|
+
processBearerTokenFile?: string;
|
|
9
|
+
allowRestProxy?: boolean;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
};
|
|
12
|
+
type RequestOptions = {
|
|
13
|
+
method?: "GET" | "POST";
|
|
14
|
+
body?: unknown;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
};
|
|
17
|
+
type RestExecutionPlan = {
|
|
18
|
+
method?: string;
|
|
19
|
+
path: string;
|
|
20
|
+
params?: Record<string, unknown>;
|
|
21
|
+
query?: Record<string, unknown>;
|
|
22
|
+
policy?: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
type EvidenceEndpointPlan = RestExecutionPlan & {
|
|
25
|
+
body?: Record<string, unknown>;
|
|
26
|
+
resultKind?: string;
|
|
27
|
+
purpose?: string;
|
|
28
|
+
};
|
|
29
|
+
type KnowledgeQueryType = "semantic" | "scroll" | "fetch" | "collection_info";
|
|
30
|
+
type DomainKnowledgeQuery = {
|
|
31
|
+
queryType?: KnowledgeQueryType;
|
|
32
|
+
query?: string;
|
|
33
|
+
limit?: number;
|
|
34
|
+
scoreThreshold?: number;
|
|
35
|
+
ids?: Array<string | number>;
|
|
36
|
+
offset?: unknown;
|
|
37
|
+
filter?: Record<string, unknown>;
|
|
38
|
+
withPayload?: boolean;
|
|
39
|
+
withVectors?: boolean;
|
|
40
|
+
waitForResult?: boolean;
|
|
41
|
+
maxWaitMs?: number;
|
|
42
|
+
};
|
|
43
|
+
type DomainKnowledgeEvidenceAssessment = {
|
|
44
|
+
assessmentScope: "primary_source_support";
|
|
45
|
+
evidenceAdequacy: "low" | "medium" | "high";
|
|
46
|
+
strongEvidenceCount: number;
|
|
47
|
+
routingCardCount: number;
|
|
48
|
+
weakOrOffTopicCount: number;
|
|
49
|
+
topScore?: number;
|
|
50
|
+
reasons: string[];
|
|
51
|
+
answerGuidance: string;
|
|
52
|
+
};
|
|
53
|
+
type GridContextQuery = {
|
|
54
|
+
location?: string;
|
|
55
|
+
boundingBox?: Record<string, unknown>;
|
|
56
|
+
gridOperator?: string;
|
|
57
|
+
gridOperatorId?: string;
|
|
58
|
+
voltageLevel?: "NS" | "MS" | "HS" | "EHS";
|
|
59
|
+
includeSubstations?: boolean;
|
|
60
|
+
includeTopology?: boolean;
|
|
61
|
+
includeGeometry?: boolean;
|
|
62
|
+
includeGraphData?: boolean;
|
|
63
|
+
maxResults?: number;
|
|
64
|
+
};
|
|
65
|
+
declare function requireConfig(config: PluginConfig): {
|
|
66
|
+
baseUrl: string;
|
|
67
|
+
bearerToken: string;
|
|
68
|
+
timeoutMs: number;
|
|
69
|
+
};
|
|
70
|
+
declare function requireProcessConfig(config: PluginConfig): {
|
|
71
|
+
baseUrl: string;
|
|
72
|
+
bearerToken: string;
|
|
73
|
+
timeoutMs: number;
|
|
74
|
+
};
|
|
75
|
+
declare function buildUrl(baseUrl: string, path: string): string;
|
|
76
|
+
declare function buildQueryPath(path: string, params?: Record<string, unknown>): string;
|
|
77
|
+
declare function isRestProxyAllowed(config: PluginConfig): boolean;
|
|
78
|
+
declare function validateRestExecutionPlan(plan: RestExecutionPlan): {
|
|
79
|
+
method: "GET";
|
|
80
|
+
path: string;
|
|
81
|
+
params: Record<string, unknown>;
|
|
82
|
+
};
|
|
83
|
+
declare function validateEvidenceEndpointPlan(plan: EvidenceEndpointPlan): {
|
|
84
|
+
method: "GET" | "POST";
|
|
85
|
+
path: string;
|
|
86
|
+
params: Record<string, unknown>;
|
|
87
|
+
body?: Record<string, unknown>;
|
|
88
|
+
};
|
|
89
|
+
declare function executeRestExecutionPlan(config: PluginConfig, plan: RestExecutionPlan, signal?: AbortSignal): Promise<unknown>;
|
|
90
|
+
declare function routeEvidence(config: PluginConfig, request: {
|
|
91
|
+
question: string;
|
|
92
|
+
context?: Record<string, unknown>;
|
|
93
|
+
}, signal?: AbortSignal): Promise<unknown>;
|
|
94
|
+
declare function normalizeDomainKnowledgeQuery(request: DomainKnowledgeQuery): Record<string, unknown>;
|
|
95
|
+
declare function assessDomainKnowledgeEvidence(query: unknown, result: unknown): DomainKnowledgeEvidenceAssessment;
|
|
96
|
+
declare function normalizeGridContextQuery(request: GridContextQuery): Record<string, unknown>;
|
|
97
|
+
declare function assessGridContextEvidence(substations: unknown, topology: unknown): Record<string, unknown>;
|
|
98
|
+
declare function queryGridContext(config: PluginConfig, request: GridContextQuery, signal?: AbortSignal): Promise<Record<string, unknown>>;
|
|
99
|
+
declare function pollCernionJobResult(config: PluginConfig, jobId: string, maxWaitMs: number, signal?: AbortSignal): Promise<unknown>;
|
|
100
|
+
declare function queryDomainKnowledge(config: PluginConfig, request: DomainKnowledgeQuery, signal?: AbortSignal): Promise<unknown>;
|
|
101
|
+
declare function executeEvidenceEndpointPlan(config: PluginConfig, plan: EvidenceEndpointPlan, signal?: AbortSignal): Promise<unknown>;
|
|
102
|
+
declare function requestCernion(config: PluginConfig, path: string, options?: RequestOptions): Promise<unknown>;
|
|
103
|
+
declare function requestCernionProcess(config: PluginConfig, path: string, options?: RequestOptions): Promise<unknown>;
|
|
104
|
+
declare function scrubSecretValues(value: unknown, token?: string): unknown;
|
|
105
|
+
declare const _default: import("openclaw/plugin-sdk/tool-plugin").DefinedToolPluginEntry;
|
|
106
|
+
export default _default;
|
|
107
|
+
export { buildQueryPath, buildUrl, executeEvidenceEndpointPlan, executeRestExecutionPlan, isRestProxyAllowed, normalizeDomainKnowledgeQuery, normalizeGridContextQuery, assessDomainKnowledgeEvidence, assessGridContextEvidence, pollCernionJobResult, queryGridContext, queryDomainKnowledge, requireConfig, requireProcessConfig, requestCernion, requestCernionProcess, routeEvidence, scrubSecretValues, validateEvidenceEndpointPlan, validateRestExecutionPlan, };
|