@rolealpha/n8n-nodes-rolealpha 0.0.0-stage → 0.5.1
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/LICENSE +21 -0
- package/README.md +339 -2
- package/dist/credentials/ApprovalSealApi.credentials.d.ts +7 -0
- package/dist/credentials/ApprovalSealApi.credentials.js +29 -0
- package/dist/credentials/ApprovalSealApi.credentials.js.map +1 -0
- package/dist/credentials/RoleAlphaAgentKeysApi.credentials.d.ts +11 -0
- package/dist/credentials/RoleAlphaAgentKeysApi.credentials.js +35 -0
- package/dist/credentials/RoleAlphaAgentKeysApi.credentials.js.map +1 -0
- package/dist/credentials/RoleAlphaWebhookApi.credentials.d.ts +8 -0
- package/dist/credentials/RoleAlphaWebhookApi.credentials.js +23 -0
- package/dist/credentials/RoleAlphaWebhookApi.credentials.js.map +1 -0
- package/dist/lib/agentRun.d.ts +73 -0
- package/dist/lib/agentRun.js +170 -0
- package/dist/lib/agentRun.js.map +1 -0
- package/dist/lib/agents.d.ts +19 -0
- package/dist/lib/agents.js +91 -0
- package/dist/lib/agents.js.map +1 -0
- package/dist/lib/graph.d.ts +155 -0
- package/dist/lib/graph.js +380 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/keys.d.ts +12 -0
- package/dist/lib/keys.js +53 -0
- package/dist/lib/keys.js.map +1 -0
- package/dist/lib/mcp.d.ts +52 -0
- package/dist/lib/mcp.js +201 -0
- package/dist/lib/mcp.js.map +1 -0
- package/dist/lib/prompt.d.ts +52 -0
- package/dist/lib/prompt.js +180 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/schedule.d.ts +37 -0
- package/dist/lib/schedule.js +106 -0
- package/dist/lib/schedule.js.map +1 -0
- package/dist/lib/seal.d.ts +22 -0
- package/dist/lib/seal.js +79 -0
- package/dist/lib/seal.js.map +1 -0
- package/dist/lib/settings.d.ts +55 -0
- package/dist/lib/settings.js +105 -0
- package/dist/lib/settings.js.map +1 -0
- package/dist/lib/share.d.ts +156 -0
- package/dist/lib/share.js +208 -0
- package/dist/lib/share.js.map +1 -0
- package/dist/lib/waits.d.ts +142 -0
- package/dist/lib/waits.js +339 -0
- package/dist/lib/waits.js.map +1 -0
- package/dist/lib/webhook.d.ts +12 -0
- package/dist/lib/webhook.js +50 -0
- package/dist/lib/webhook.js.map +1 -0
- package/dist/nodes/ApprovalSeal/ApprovalSeal.node.d.ts +9 -0
- package/dist/nodes/ApprovalSeal/ApprovalSeal.node.js +141 -0
- package/dist/nodes/ApprovalSeal/ApprovalSeal.node.js.map +1 -0
- package/dist/nodes/ApprovalSeal/approvalSeal.svg +1 -0
- package/dist/nodes/RoleAlpha/RoleAlpha.node.d.ts +5 -0
- package/dist/nodes/RoleAlpha/RoleAlpha.node.js +1099 -0
- package/dist/nodes/RoleAlpha/RoleAlpha.node.js.map +1 -0
- package/dist/nodes/RoleAlpha/roleAlpha.svg +1 -0
- package/dist/nodes/RoleAlphaTrigger/RoleAlphaTrigger.node.d.ts +9 -0
- package/dist/nodes/RoleAlphaTrigger/RoleAlphaTrigger.node.js +61 -0
- package/dist/nodes/RoleAlphaTrigger/RoleAlphaTrigger.node.js.map +1 -0
- package/dist/nodes/RoleAlphaTrigger/roleAlpha.svg +1 -0
- package/package.json +56 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 roleALPHA GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,340 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @rolealpha/n8n-nodes-rolealpha
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center"><b>AI agents that know only themselves.</b><br>
|
|
4
|
+
Roles, duties, deciders and guardrails come from roleALPHA, at run time, every time.</p>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://github.com/roleALPHA/n8n-nodes-rolealpha"><b>GitHub</b></a> ·
|
|
8
|
+
<a href="#installation-self-hosted-n8n">Installation</a> ·
|
|
9
|
+
<a href="#nodes">Node reference</a> ·
|
|
10
|
+
<a href="#security">Security</a> ·
|
|
11
|
+
<a href="LICENSE">Licence</a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="package.json"><img
|
|
16
|
+
alt="Version"
|
|
17
|
+
src="https://img.shields.io/github/package-json/v/roleALPHA/n8n-nodes-rolealpha?label=version&color=7c3aed"></a>
|
|
18
|
+
<a href="LICENSE"><img
|
|
19
|
+
alt="Licence: MIT"
|
|
20
|
+
src="https://img.shields.io/badge/licence-MIT-7c3aed"></a>
|
|
21
|
+
<a href="https://docs.n8n.io/integrations/community-nodes/"><img
|
|
22
|
+
alt="n8n community nodes"
|
|
23
|
+
src="https://img.shields.io/badge/n8n-community%20nodes-7c3aed?logo=n8n&logoColor=white"></a>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
You know the moment: somebody new takes over approvals, a role is cut in two, a process gets
|
|
27
|
+
one more step. Then every agent that has a name, an e-mail address or a process ID baked
|
|
28
|
+
into its prompt or its workflow is wrong, and nobody notices until something goes to the
|
|
29
|
+
wrong person. These nodes are built so that this cannot happen. An agent knows its own
|
|
30
|
+
identity and nothing else. What it does, who it hands over to, who decides and which rules
|
|
31
|
+
bind it, it reads from roleALPHA on every run. Change the organisation in roleALPHA, and the
|
|
32
|
+
next run follows. You don't edit code and you don't republish anything.
|
|
33
|
+
|
|
34
|
+
## At a glance
|
|
35
|
+
|
|
36
|
+
- **One runner for every agent.** A single n8n workflow runs any agent on any step. A new
|
|
37
|
+
agent runs as soon as it is `active` in roleALPHA. The scheduler picks it up on its next
|
|
38
|
+
tick.
|
|
39
|
+
- **Nothing hard-coded.** No persons, no roles, no process IDs in workflows or prompts. Only
|
|
40
|
+
technology stays fixed: systems, collections, fields, status values and step custom IDs.
|
|
41
|
+
- **Fail-closed.** If roleALPHA cannot be read, or nobody fills the deciding role, the answer
|
|
42
|
+
is "not allowed". It never falls back to a fixed person.
|
|
43
|
+
- **Agents never approve.** Approvals are checked against the person filling the deciding
|
|
44
|
+
role and sealed. The channel that sends verifies the seal right before anything leaves.
|
|
45
|
+
- **Teams of agents on one step.** Several roles share a step. Each agent does its own part,
|
|
46
|
+
waits for what it needs and is woken when it arrives. Agents that hang are escalated to
|
|
47
|
+
the role that leads their circle.
|
|
48
|
+
- **Limits you can change without republishing.** Retries, wait times, run time and tool
|
|
49
|
+
calls come from a settings table and are clamped to fixed bounds.
|
|
50
|
+
|
|
51
|
+
> **In use, not on npm.** The package runs in production on a self-hosted n8n. It is marked
|
|
52
|
+
> `private` and installed from a tarball. See [Installation](#installation-self-hosted-n8n).
|
|
53
|
+
|
|
54
|
+
## Why it works
|
|
55
|
+
|
|
56
|
+
**The graph is the job description.** The runner starts with an agent and a step. It reads
|
|
57
|
+
the agent's roles (`AGENT_FULFILLS_ROLE`) and the steps those roles are `RESPONSIBLE_FOR`.
|
|
58
|
+
It reads the step's predecessors and successors (`DEPENDS_ON`), and who decides on it
|
|
59
|
+
(`DECIDES_ON`, else `ACCOUNTABLE_FOR`). From that it builds the system prompt. The agent
|
|
60
|
+
itself carries only identity and technology. Its work comes from the purpose and
|
|
61
|
+
accountabilities of its roles. Change the role, and the work changes.
|
|
62
|
+
|
|
63
|
+
**The role first, then the person.** Who decides is a role. Who fills it, a person
|
|
64
|
+
(`EXECUTES`) or an agent, is read only after that. Only persons can approve. An agent that
|
|
65
|
+
fills a deciding role is ignored on purpose. The address a person signs in with must match
|
|
66
|
+
their e-mail in roleALPHA. A display name or a claim by the model never counts.
|
|
67
|
+
|
|
68
|
+
**Each agent does only its own part.** One step can hold many tasks: research, text, visual,
|
|
69
|
+
hand-over. Before a run, **Share** asks a model which of the step's tasks belong to this
|
|
70
|
+
agent's roles. **Share → Check** then keeps only duties that really are accountabilities of
|
|
71
|
+
those roles, and needs on roles that really sit on the step. The agent gets its part, a
|
|
72
|
+
list of what is not its part, and the rules for waiting.
|
|
73
|
+
|
|
74
|
+
**Waiting is part of the job.** If the text is not there yet, the visual cannot be drawn.
|
|
75
|
+
The agent does what it can, records a wait and stops. When the role it waited for finishes
|
|
76
|
+
a run, **Wait → Plan After Run** wakes it again. A duty that closes the step waits only on
|
|
77
|
+
the deliveries it needs: a result that is named, stored in data and needed for the task.
|
|
78
|
+
Informing people or asking them for feedback is no delivery, so a role that only
|
|
79
|
+
communicates never holds a hand-over up.
|
|
80
|
+
|
|
81
|
+
**No double runs, no double wake-ups.** Every run takes a lease first. A second start for
|
|
82
|
+
the same agent, step and records is queued, not run. Every wake-up claims its row before it
|
|
83
|
+
fires, so two runs that plan at the same moment never wake an agent twice. If a run fails
|
|
84
|
+
or dies, its lease is released, and the queued start runs.
|
|
85
|
+
|
|
86
|
+
**Nobody waits forever.** The scheduler finds waits that nobody answered and wakes them
|
|
87
|
+
again. At the attempt limit it stops waking and escalates once to the role that leads the
|
|
88
|
+
circle. The message names that role first, then the people filling it.
|
|
89
|
+
|
|
90
|
+
**Event data is data.** Whatever a trigger delivers (a status change, a comment, a message)
|
|
91
|
+
goes into the prompt marked as data, never as instructions. Guardrails take precedence over
|
|
92
|
+
event content, and texts that one agent leaves for another are cut to fixed sizes.
|
|
93
|
+
|
|
94
|
+
## How a run works
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Scheduler (cron) Event router (one webhook)
|
|
98
|
+
└ roleALPHA: List Agents └ map (collection, status) → step custom ID
|
|
99
|
+
└ roleALPHA: Get Duties └ roleALPHA: Get Step → responsible role → active agent
|
|
100
|
+
└ roleALPHA: Is Due (last runs) ┘
|
|
101
|
+
└──────────────► Runner(agentUuid, step, trigger, event)
|
|
102
|
+
├ roleALPHA: Start Run (run token of the agent, agent:run)
|
|
103
|
+
├ roleALPHA: Get Context (active + guardrails, fail-closed)
|
|
104
|
+
├ roleALPHA: Check Responsibility (fail-closed)
|
|
105
|
+
├ roleALPHA: Get Step
|
|
106
|
+
├ Settings: Resolve (limits from the settings table)
|
|
107
|
+
├ Wait: Check Start (lease, duplicate-run guard)
|
|
108
|
+
├ Share: Build Input → model → Share: Check (cached)
|
|
109
|
+
├ roleALPHA: Build System Prompt
|
|
110
|
+
├ AI Agent (+ data tool limited to the domains of the agent's roles,
|
|
111
|
+
│ + roleALPHA: Tool, read only, as the agent)
|
|
112
|
+
└ Wait: Plan After Run (done row, wake-ups, lease released)
|
|
113
|
+
|
|
114
|
+
Scheduler, every tick
|
|
115
|
+
└ Wait: Find Stale Waits → wake (claimed) · remove dead leases · escalate → Get Circle Lead
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Every read is the agent's own.** With **Connect As: Agent** the node swaps the function
|
|
119
|
+
account token for a run token of the agent (roleALPHA `agent:run`, RFC 8693, 15 minutes).
|
|
120
|
+
Context, step, roles and the read tool of the model then see exactly what the agent may
|
|
121
|
+
see, without admin rights and without a key per agent in n8n. **Start Run** swaps first and
|
|
122
|
+
returns a refusal as data (`code`, `reaction`): an agent that is paused, over budget or not
|
|
123
|
+
bound to the account does not run. There is no fallback to the view of the account.
|
|
124
|
+
|
|
125
|
+
Approval gates follow this order: **Get Decider → Check Approver → Approval Seal: Sign**. The
|
|
126
|
+
workflow that sends runs **Approval Seal: Verify** first and stops if the content changed.
|
|
127
|
+
|
|
128
|
+
## Nodes
|
|
129
|
+
|
|
130
|
+
### roleALPHA (`roleAlpha`)
|
|
131
|
+
|
|
132
|
+
| Resource | Operation | What it does | Credential |
|
|
133
|
+
|---|---|---|---|
|
|
134
|
+
| Agent | Get Context | Reads an agent's context bundle (identity, roles, guardrails). Fails if the agent is not `active` or has no policy, unless you switch that off. Over MCP it reads the `agent` view by default, exactly what the agent gets over its own key. | MCP OAuth2 (default) or roleALPHA Agent Keys API |
|
|
135
|
+
| Agent | Get Context Version | Change check. Cheap and not audited with agent keys; over MCP it reads the bundle. | MCP OAuth2 or roleALPHA Agent Keys API |
|
|
136
|
+
| Agent | Start Run | Swaps the function account token for a run token of the agent (`agent:run`). Returns `started`, or `code` and `reaction` of the refusal (`pause`, `pauseUntilNextPeriod`, `informAdmin`, `retryLater`, …). The token never appears in the output. | MCP OAuth2 with client credentials |
|
|
137
|
+
| Agent | List Agents | Over MCP: every agent of the organisation, paged. With agent keys: one item per key. By default it skips agents that are not active. | MCP OAuth2 or roleALPHA Agent Keys API |
|
|
138
|
+
| Responsibility | Get Duties | Lists the steps the agent's roles are `RESPONSIBLE_FOR`, with the circle. | MCP OAuth2 |
|
|
139
|
+
| Responsibility | Find Step by Custom ID | Looks up a step by an exact custom ID. | MCP OAuth2 |
|
|
140
|
+
| Responsibility | Get Step | Returns a step with its predecessors, successors, parent and child steps, responsible, deciding and accountable roles (with their holders), and policies. With **Role Details** also purpose, accountabilities and domains of each responsible role. | MCP OAuth2 |
|
|
141
|
+
| Responsibility | Get Decider | Returns the `DECIDES_ON` role. If there is none, it returns the `ACCOUNTABLE_FOR` role. | MCP OAuth2 |
|
|
142
|
+
| Responsibility | Check Approver | **Fail-closed.** Is the acting person filling the deciding role? Only persons count; agents never do. | MCP OAuth2 |
|
|
143
|
+
| Responsibility | Check Responsibility | Is one of the agent's roles responsible for this step? | MCP OAuth2 |
|
|
144
|
+
| Responsibility | Get Circle Lead | One item per circle of the agent's roles: the role that leads the circle and its holders, e.g. to escalate to. Recognised from a lead flag on the role, else "Lead Link" in its purpose, else a custom ID ending in `:lead`, else the role that decides on or is accountable for the circle. `lead` is null when none is found. | MCP OAuth2 |
|
|
145
|
+
| Responsibility | Get Role Holders | Returns the persons (with address) and agents filling a role. | MCP OAuth2 |
|
|
146
|
+
| Tool | Call Tool / List Tools | Calls one roleALPHA MCP tool from an allow list, e.g. as the read tool of an AI agent. Tool name `list` returns the allowed tools with their arguments; the organisation is added. Errors come back as data, a refused run ends it. | MCP OAuth2 |
|
|
147
|
+
| Prompt | Build System Prompt | Builds the system prompt from the bundle, the step, the duties and the trigger. Event data is passed as data, never as instructions. With a **Share** it adds the agent's part, what is not its part, the rules for waiting within the step, and returns `task` as the user message. | – |
|
|
148
|
+
| Share | Build Input | Prepares the model call that decides the agent's part of a step: only the accountabilities of its own roles count, the other responsible roles of the step are listed with theirs. Returns `systemMessage`, `prompt` and `schema` for a structured output parser. Needs Get Step with Role Details. | – |
|
|
149
|
+
| Share | Check | Checks the model answer against roleALPHA: drops duties that are no accountability of the agent and needs on roles that are not on the step. Returns `duties` (with `needs`), `notMine`, `waitsFor` and `waitRoleUuids`. | – |
|
|
150
|
+
| Wait | Plan After Run | Decides what follows a run on a step from the stored wait rows: the `done` row to add, which waiting agents of the same step to wake (their awaited role just delivered), which rows to remove, and which waits are stuck at the attempt limit. Covers a result that arrived while the agent was deciding to wait. | – |
|
|
151
|
+
| Wait | Check Start | Duplicate-run guard. After the runner added a lease row for its run (`state = running`), the oldest live lease of the same agent, step and records wins. A later start does not run; it returns a `queueRow` that runs when the busy run ends. Leases older than the run timeout are dead and released. Fail-closed when the own lease is missing. | – |
|
|
152
|
+
| Wait | Find Stale Waits | For a scheduler: waits nobody answered in time (e.g. a person fills the awaited role), queued starts whose busy run died, dead leases, expired rows, and waits at the attempt limit to escalate (`escalate`, reported once). | – |
|
|
153
|
+
| Settings | Resolve | Runner limits from defaults and a settings table (`scope, target, key, value`): default < global < step < agent. Every value is clamped to fixed bounds; unknown keys and unusable values are reported in `settingProblems` and never applied. | – |
|
|
154
|
+
| Schedule | Is Due | Decides from the step `frequency` (and `termin` / due date) whether a run is due in the current period. | – |
|
|
155
|
+
|
|
156
|
+
### Approval Seal (`approvalSeal`)
|
|
157
|
+
|
|
158
|
+
`Sign` seals exactly the approved content together with the approver. Use it after **Check
|
|
159
|
+
Approver**. `Verify` recomputes the seal right before anything is sent and stops the
|
|
160
|
+
workflow if the content changed.
|
|
161
|
+
|
|
162
|
+
- **v3** (current): `HMAC-SHA256(key, canonicalJson(['v3', type, fields, approver]))`. The key
|
|
163
|
+
must have at least 32 characters.
|
|
164
|
+
- **v2** (legacy): the hash that older code nodes wrote. It is only verified, never signed.
|
|
165
|
+
Set **Legacy Key**, and remove it once no v2 seal is open.
|
|
166
|
+
|
|
167
|
+
### roleALPHA Trigger (`roleAlphaTrigger`)
|
|
168
|
+
|
|
169
|
+
Receives `context.changed` webhooks. It checks `X-RA-Signature: sha256=<hmac>` against the raw
|
|
170
|
+
body and answers `401` if the signature is wrong. Register the production URL in roleALPHA
|
|
171
|
+
under the agent → *Context & Access*.
|
|
172
|
+
|
|
173
|
+
## Credentials
|
|
174
|
+
|
|
175
|
+
| Credential | Content |
|
|
176
|
+
|---|---|
|
|
177
|
+
| **MCP OAuth2** (n8n built-in) | Access to the roleALPHA MCP endpoint for one organisation. Used for agents (default source) and for every traversal. The `agent` view needs admin rights on the tenant. For **Connect As: Agent** it must be a roleALPHA function account (grant type Client Credentials) whose role has `agent:run` and that may run the agent ("May run these agents"). |
|
|
178
|
+
| **roleALPHA Agent Keys API** | Optional, for the `Agent Keys` source. `baseUrl` of the data node, and `keys`: `{"<agent uuid>": "agt_…"}`, or a list of `{agentUuid, key, label}`. An agent key reads only its own agent, so it cannot traverse. |
|
|
179
|
+
| **roleALPHA Webhook API** | One signing secret, a JSON list of secrets, or a map from agent UUID to secret. |
|
|
180
|
+
| **Approval Seal API** | `key` (sign and verify) and optionally `legacyKey` (verify v2 only). |
|
|
181
|
+
|
|
182
|
+
Agent keys and webhook secrets are issued in the roleALPHA interface and shown only once.
|
|
183
|
+
Store them nowhere except in these credentials.
|
|
184
|
+
|
|
185
|
+
## Settings
|
|
186
|
+
|
|
187
|
+
The runner reads its limits from a table with the columns `scope, target, key, value`. A row
|
|
188
|
+
with `scope = global` applies to every run. `step` (target: step UUID or custom ID) and
|
|
189
|
+
`agent` (target: agent UUID) narrow it down. The order is default < global < step < agent.
|
|
190
|
+
|
|
191
|
+
| Setting | Default | Bounds | Meaning |
|
|
192
|
+
|---|---|---|---|
|
|
193
|
+
| `maxWaitMinutes` | 60 | 5–10080 | A wait nobody answered is started again by the scheduler after this time |
|
|
194
|
+
| `maxAttempts` | 5 | 1–20 | Wake-ups per wait; at the limit the wait is escalated and never woken again by itself |
|
|
195
|
+
| `keepDoneHours` | 168 | 1–2160 | How long `done` and `escalated` rows are kept |
|
|
196
|
+
| `maxIterations` | 15 | 1–50 | Tool calls of the agent per run |
|
|
197
|
+
| `runTimeoutMinutes` | 15 | 1–120 | A run older than this counts as dead; its lease is released |
|
|
198
|
+
| `escalate` | true | – | Report stuck waits to the role that leads the circle |
|
|
199
|
+
| `shareCacheHours` | 24 | 0–720 | Reuse a share decision while step, roles and trigger kind stay the same (0 = never) |
|
|
200
|
+
|
|
201
|
+
A row with a value outside the bounds is clamped and reported. A wrong row can make the
|
|
202
|
+
runner more careful, never unbounded.
|
|
203
|
+
|
|
204
|
+
Wait rows live in any store of the workflow, for example an n8n data table with the columns
|
|
205
|
+
`state, step_uuid, step_custom_id, agent_uuid, agent_name, roles, waits_for, reason,
|
|
206
|
+
record_keys, event, run_id, attempts, progress, at`.
|
|
207
|
+
|
|
208
|
+
## Security
|
|
209
|
+
|
|
210
|
+
- Every check is fail-closed. If roleALPHA cannot be read, the result is "not allowed".
|
|
211
|
+
- Agents never approve. Check Approver ignores agents that fill the deciding role.
|
|
212
|
+
- Runs act as their agent: the run token carries the agent's view, writes only drafts, and is
|
|
213
|
+
never written to node output. A refused swap stops the run; there is no fallback.
|
|
214
|
+
- Rights go into the tools from the check, never from the model. The data tool sees only the
|
|
215
|
+
collections in the domains of the agent's roles.
|
|
216
|
+
- The prompt marks trigger payloads as data. Guardrails take precedence over event content.
|
|
217
|
+
- Keep `requireActive` and `requireGuardrails` on in production.
|
|
218
|
+
- Settings are clamped to fixed bounds.
|
|
219
|
+
- Duplicate runs are blocked by leases, and wake-ups are claimed before they fire.
|
|
220
|
+
- No credentials are kept in wait, settings or cache rows. The share cache key holds no
|
|
221
|
+
record content, and a cached answer is checked again like a fresh one.
|
|
222
|
+
|
|
223
|
+
Found a security problem? Please do not describe it in a public issue. Open an issue that only
|
|
224
|
+
asks for a contact, and roleALPHA GmbH will get back to you.
|
|
225
|
+
|
|
226
|
+
## Installation (self-hosted n8n)
|
|
227
|
+
|
|
228
|
+
### Requirements
|
|
229
|
+
|
|
230
|
+
- A self-hosted n8n that allows community nodes
|
|
231
|
+
- A roleALPHA organisation and an MCP OAuth2 credential for it
|
|
232
|
+
|
|
233
|
+
### Install
|
|
234
|
+
|
|
235
|
+
In n8n, open **Settings → Community Nodes → Install** and enter
|
|
236
|
+
`@rolealpha/n8n-nodes-rolealpha`. Or, on the n8n host:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
cd ~/.n8n/nodes
|
|
240
|
+
npm install @rolealpha/n8n-nodes-rolealpha
|
|
241
|
+
# restart n8n
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Updating
|
|
245
|
+
|
|
246
|
+
Update the package under **Settings → Community Nodes**, or run
|
|
247
|
+
`npm install @rolealpha/n8n-nodes-rolealpha@latest` in the same folder and restart n8n.
|
|
248
|
+
Workflows keep their nodes. New parameters start with their defaults.
|
|
249
|
+
|
|
250
|
+
### Coming from `n8n-nodes-rolealpha` (up to 0.4.x)
|
|
251
|
+
|
|
252
|
+
Up to 0.4.x the package was installed from a tarball under the name `n8n-nodes-rolealpha`.
|
|
253
|
+
n8n stores the package name in every node type, so a node from the old package is
|
|
254
|
+
`n8n-nodes-rolealpha.roleAlpha` and one from this package is
|
|
255
|
+
`@rolealpha/n8n-nodes-rolealpha.roleAlpha`. Both packages can be installed side by side.
|
|
256
|
+
Install this one, switch each workflow's nodes over, and then remove the old package.
|
|
257
|
+
Credentials are not tied to the package name and stay as they are.
|
|
258
|
+
|
|
259
|
+
### Building from source
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
git clone https://github.com/roleALPHA/n8n-nodes-rolealpha.git
|
|
263
|
+
cd n8n-nodes-rolealpha
|
|
264
|
+
npm install
|
|
265
|
+
npm run build
|
|
266
|
+
npm test
|
|
267
|
+
npm pack # → rolealpha-n8n-nodes-rolealpha-<version>.tgz
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Releasing
|
|
271
|
+
|
|
272
|
+
Bump `version` in `package.json`, commit, and push a tag `v<version>`. The GitHub Action
|
|
273
|
+
**Publish to npm** builds, tests and publishes the package with provenance. It uses npm
|
|
274
|
+
trusted publishing, so there is no npm token anywhere: on npmjs.com the package settings name
|
|
275
|
+
this repository and the workflow file `publish.yml` as its trusted publisher.
|
|
276
|
+
|
|
277
|
+
## Things that trip people up
|
|
278
|
+
|
|
279
|
+
**1. The `agent` view needs admin rights.** **Get Context** reads, by default, exactly what the
|
|
280
|
+
agent would receive over its own key. That view needs admin rights on the tenant. Without
|
|
281
|
+
them, switch to the `caller` view, and know that it shows what the connection may see, not
|
|
282
|
+
what the agent sees.
|
|
283
|
+
|
|
284
|
+
**2. An agent key cannot traverse.** It reads its own agent and nothing else. Every
|
|
285
|
+
Responsibility operation needs the MCP OAuth2 credential.
|
|
286
|
+
|
|
287
|
+
**3. Keep `runTimeoutMinutes` at or above the workflow timeout.** If a lease counts as dead
|
|
288
|
+
before the run really ends, a queued start can run while the first one is still busy.
|
|
289
|
+
|
|
290
|
+
**4. The circle lead must be recognisable.** **Get Circle Lead** looks for a lead flag, "Lead
|
|
291
|
+
Link" in the purpose, a custom ID ending in `:lead`, or the role that decides on or is
|
|
292
|
+
accountable for the circle. If none fits, `lead` is null, and the escalation names the
|
|
293
|
+
circle instead of a role.
|
|
294
|
+
|
|
295
|
+
**5. Write status values exactly.** Steps are mapped to records by step custom ID and status
|
|
296
|
+
value. Those are the technical values that may stay fixed, so a typo in one of them is
|
|
297
|
+
not caught by the graph.
|
|
298
|
+
|
|
299
|
+
## Troubleshooting
|
|
300
|
+
|
|
301
|
+
| Symptom | Cause |
|
|
302
|
+
|---|---|
|
|
303
|
+
| `Agent … is not active in roleALPHA` | The agent's status in roleALPHA is not `active`. Expected: it does not run. |
|
|
304
|
+
| `Agent … is bound by no policy` | No policy binds the agent. Bind one, or switch off `requireGuardrails` for tests only. |
|
|
305
|
+
| `None of the roles is responsible for this step` | None of the agent's roles is `RESPONSIBLE_FOR` the step. Check the role, not the agent. |
|
|
306
|
+
| A start returns `queueRow` instead of running | Another run of the same agent, step and records holds the lease. The queued start runs when that run ends. |
|
|
307
|
+
| `No lease of this run was found; refusing to start` | The runner did not add its lease row before **Check Start**, or the store did not return it. |
|
|
308
|
+
| The agent stops with a max-iterations error | The agent needed more tool calls than `maxIterations`. Raise it for that step with a `step` row in the settings table. |
|
|
309
|
+
| A wait is never woken | Nobody of the awaited role ran on the same records. The scheduler wakes it after `maxWaitMinutes`, and escalates at `maxAttempts`. |
|
|
310
|
+
| `settingProblems` is not empty | A row in the settings table has an unknown key or scope, or a value outside the bounds. The message names the row. |
|
|
311
|
+
| `roleALPHA refused the run: agent_nicht_gebunden` | The function account may not run this agent. Add the agent under "May run these agents" of the account. |
|
|
312
|
+
| `roleALPHA refused the run: kein_agent_run_recht` | No role of the function account has `agent:run`. |
|
|
313
|
+
| `Acting as an agent needs a function account` | The MCP OAuth2 credential uses another grant type. Use the client ID and secret of a function account. |
|
|
314
|
+
| `MCP initialize failed with HTTP 429` | Many runs started at once and roleALPHA turned some away. The client repeats a call turned away with 429 or 503 up to four times (Retry-After, else 1, 2, 4, 8 s). If it still fails, start fewer runs at once. |
|
|
315
|
+
| `Empty MCP response` | The server answered with no body. Reading calls are repeated; a writing tool is not, so it cannot run twice. |
|
|
316
|
+
| `Cannot access "arguments" due to security concerns` | n8n blocks the name `arguments` in expressions and in `$fromAI`. Name the tool input `toolArgs` or `args`. |
|
|
317
|
+
| Webhook answers `401` | The `X-RA-Signature` does not match. Check the secret in **roleALPHA Webhook API**. |
|
|
318
|
+
|
|
319
|
+
## Licence
|
|
320
|
+
|
|
321
|
+
**MIT.** The terms are in [LICENSE](LICENSE). Use it, change it, build on it, commercially
|
|
322
|
+
too. roleALPHA itself is a separate product and not covered by this licence.
|
|
323
|
+
|
|
324
|
+
## Contributing
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
npm install
|
|
328
|
+
npm run build
|
|
329
|
+
npm test
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
| Command | Purpose |
|
|
333
|
+
|---|---|
|
|
334
|
+
| `npm run build` | Compile TypeScript to `dist` and copy the node icons |
|
|
335
|
+
| `npm test` | Compile the tests and run them with Node's test runner (`test/*.test.ts`) |
|
|
336
|
+
| `npm run lint` | `tsc --noEmit` |
|
|
337
|
+
|
|
338
|
+
The logic lives in `lib/` and is tested without n8n. The node files in `nodes/` only map
|
|
339
|
+
parameters to it. Keep it that way: a rule that decides who may act belongs in `lib/` with
|
|
340
|
+
a test.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
/** Key for approval seals. One per circle; never stored in data, notes or chat. */
|
|
3
|
+
export declare class ApprovalSealApi implements ICredentialType {
|
|
4
|
+
name: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApprovalSealApi = void 0;
|
|
4
|
+
/** Key for approval seals. One per circle; never stored in data, notes or chat. */
|
|
5
|
+
class ApprovalSealApi {
|
|
6
|
+
name = 'approvalSealApi';
|
|
7
|
+
displayName = 'Approval Seal API';
|
|
8
|
+
properties = [
|
|
9
|
+
{
|
|
10
|
+
displayName: 'Seal Key',
|
|
11
|
+
name: 'key',
|
|
12
|
+
type: 'string',
|
|
13
|
+
typeOptions: { password: true },
|
|
14
|
+
default: '',
|
|
15
|
+
required: true,
|
|
16
|
+
description: 'Random secret of at least 32 characters (e.g. 48 hex characters)',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Legacy Key (v2)',
|
|
20
|
+
name: 'legacyKey',
|
|
21
|
+
type: 'string',
|
|
22
|
+
typeOptions: { password: true },
|
|
23
|
+
default: '',
|
|
24
|
+
description: 'Key of the older v2 seals written by code nodes. Only used to verify, never to sign. Leave empty once no v2 seal is open.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
exports.ApprovalSealApi = ApprovalSealApi;
|
|
29
|
+
//# sourceMappingURL=ApprovalSealApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApprovalSealApi.credentials.js","sourceRoot":"","sources":["../../credentials/ApprovalSealApi.credentials.ts"],"names":[],"mappings":";;;AAEA,mFAAmF;AACnF,MAAa,eAAe;IAC3B,IAAI,GAAG,iBAAiB,CAAC;IAEzB,WAAW,GAAG,mBAAmB,CAAC;IAElC,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/B,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,kEAAkE;SAC/E;QACD;YACC,WAAW,EAAE,iBAAiB;YAC9B,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/B,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,2HAA2H;SACxI;KACD,CAAC;CACF;AAxBD,0CAwBC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* One credential for every agent this n8n runs: a JSON map agentUuid → agent key.
|
|
4
|
+
* Keys are issued in roleALPHA (agent → "Context & Access") and shown only once.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RoleAlphaAgentKeysApi implements ICredentialType {
|
|
7
|
+
name: string;
|
|
8
|
+
displayName: string;
|
|
9
|
+
documentationUrl: string;
|
|
10
|
+
properties: INodeProperties[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RoleAlphaAgentKeysApi = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* One credential for every agent this n8n runs: a JSON map agentUuid → agent key.
|
|
6
|
+
* Keys are issued in roleALPHA (agent → "Context & Access") and shown only once.
|
|
7
|
+
*/
|
|
8
|
+
class RoleAlphaAgentKeysApi {
|
|
9
|
+
name = 'roleAlphaAgentKeysApi';
|
|
10
|
+
displayName = 'roleALPHA Agent Keys API';
|
|
11
|
+
documentationUrl = 'https://doc.rolealpha.app/entity-type-agent/';
|
|
12
|
+
properties = [
|
|
13
|
+
{
|
|
14
|
+
displayName: 'Data Node URL',
|
|
15
|
+
name: 'baseUrl',
|
|
16
|
+
type: 'string',
|
|
17
|
+
default: '',
|
|
18
|
+
placeholder: 'https://<data-node>.rolealpha.app',
|
|
19
|
+
required: true,
|
|
20
|
+
description: 'Base URL of the roleALPHA data node that serves /api/agents/{uuid}/context',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Agent Keys',
|
|
24
|
+
name: 'keys',
|
|
25
|
+
type: 'string',
|
|
26
|
+
typeOptions: { password: true, rows: 8 },
|
|
27
|
+
default: '',
|
|
28
|
+
required: true,
|
|
29
|
+
placeholder: '{"<agent uuid>": "agt_…"}',
|
|
30
|
+
description: 'JSON map of agent UUID to agent key, or a list of {"agentUuid", "key", "label"}. Adding an entry is all it takes for a new agent to run.',
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
exports.RoleAlphaAgentKeysApi = RoleAlphaAgentKeysApi;
|
|
35
|
+
//# sourceMappingURL=RoleAlphaAgentKeysApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleAlphaAgentKeysApi.credentials.js","sourceRoot":"","sources":["../../credentials/RoleAlphaAgentKeysApi.credentials.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,MAAa,qBAAqB;IACjC,IAAI,GAAG,uBAAuB,CAAC;IAE/B,WAAW,GAAG,0BAA0B,CAAC;IAEzC,gBAAgB,GAAG,8CAA8C,CAAC;IAElE,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,eAAe;YAC5B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,mCAAmC;YAChD,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,4EAA4E;SACzF;QACD;YACC,WAAW,EAAE,YAAY;YACzB,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE;YACxC,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,2BAA2B;YACxC,WAAW,EACV,0IAA0I;SAC3I;KACD,CAAC;CACF;AA7BD,sDA6BC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
/** Signing secrets of roleALPHA context webhooks, shown once when a webhook is registered. */
|
|
3
|
+
export declare class RoleAlphaWebhookApi implements ICredentialType {
|
|
4
|
+
name: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
documentationUrl: string;
|
|
7
|
+
properties: INodeProperties[];
|
|
8
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RoleAlphaWebhookApi = void 0;
|
|
4
|
+
/** Signing secrets of roleALPHA context webhooks, shown once when a webhook is registered. */
|
|
5
|
+
class RoleAlphaWebhookApi {
|
|
6
|
+
name = 'roleAlphaWebhookApi';
|
|
7
|
+
displayName = 'roleALPHA Webhook API';
|
|
8
|
+
documentationUrl = 'https://doc.rolealpha.app/entity-type-agent/';
|
|
9
|
+
properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Signing Secrets',
|
|
12
|
+
name: 'secrets',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: { password: true, rows: 6 },
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
placeholder: '{"<agent uuid>": "<signing secret>"}',
|
|
18
|
+
description: 'One secret, a JSON list of secrets, or a JSON map of agent UUID to secret',
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
exports.RoleAlphaWebhookApi = RoleAlphaWebhookApi;
|
|
23
|
+
//# sourceMappingURL=RoleAlphaWebhookApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleAlphaWebhookApi.credentials.js","sourceRoot":"","sources":["../../credentials/RoleAlphaWebhookApi.credentials.ts"],"names":[],"mappings":";;;AAEA,8FAA8F;AAC9F,MAAa,mBAAmB;IAC/B,IAAI,GAAG,qBAAqB,CAAC;IAE7B,WAAW,GAAG,uBAAuB,CAAC;IAEtC,gBAAgB,GAAG,8CAA8C,CAAC;IAElE,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,iBAAiB;YAC9B,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE;YACxC,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,sCAAsC;YACnD,WAAW,EAAE,2EAA2E;SACxF;KACD,CAAC;CACF;AAnBD,kDAmBC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Acting as an agent (roleALPHA `agent:run`, RFC 8693). The runner holds one function
|
|
3
|
+
* account; for every run it swaps the account token for a run token that carries exactly
|
|
4
|
+
* the view of one agent, valid for 15 minutes. Without a run token nothing runs: there is
|
|
5
|
+
* no fallback to the view of the account.
|
|
6
|
+
*
|
|
7
|
+
* Tokens stay in memory only and are never written to node output.
|
|
8
|
+
*/
|
|
9
|
+
export interface FormReply {
|
|
10
|
+
status: number;
|
|
11
|
+
body: string;
|
|
12
|
+
}
|
|
13
|
+
/** POSTs an x-www-form-urlencoded body; injected so the node uses n8n's helpers and tests fake it. */
|
|
14
|
+
export type FormPost = (url: string, form: Record<string, string>, headers: Record<string, string>) => Promise<FormReply>;
|
|
15
|
+
export interface FunctionAccount {
|
|
16
|
+
tokenUrl: string;
|
|
17
|
+
clientId: string;
|
|
18
|
+
clientSecret: string;
|
|
19
|
+
/** Where the client credentials go: Basic header (default) or form body. */
|
|
20
|
+
authentication?: 'header' | 'body';
|
|
21
|
+
}
|
|
22
|
+
/** What the runner does on a refusal. The code decides, never the text. */
|
|
23
|
+
export type Reaction = 'fixConfig' | 'informAdmin' | 'removeAgent' | 'pause' | 'pauseUntilNextPeriod' | 'retryLater' | 'renewAccountToken' | 'endRun';
|
|
24
|
+
export declare function reactionFor(code: string, status?: number): Reaction;
|
|
25
|
+
export declare class AgentRunError extends Error {
|
|
26
|
+
readonly code: string;
|
|
27
|
+
readonly status: number;
|
|
28
|
+
readonly description: string;
|
|
29
|
+
readonly reaction: Reaction;
|
|
30
|
+
constructor(code: string, status: number, description: string);
|
|
31
|
+
}
|
|
32
|
+
export declare const GRANT_TOKEN_EXCHANGE = "urn:ietf:params:oauth:grant-type:token-exchange";
|
|
33
|
+
export declare const TOKEN_TYPE_ACCESS = "urn:ietf:params:oauth:token-type:access_token";
|
|
34
|
+
export declare function isValidRunId(runId: string): boolean;
|
|
35
|
+
interface Cached {
|
|
36
|
+
token: string;
|
|
37
|
+
expiresAt: number;
|
|
38
|
+
}
|
|
39
|
+
export interface RunToken {
|
|
40
|
+
token: string;
|
|
41
|
+
expiresAt: number;
|
|
42
|
+
agent: {
|
|
43
|
+
uuid: string;
|
|
44
|
+
name: string | null;
|
|
45
|
+
};
|
|
46
|
+
runId: string;
|
|
47
|
+
}
|
|
48
|
+
export interface TokenStore {
|
|
49
|
+
accounts: Map<string, Cached>;
|
|
50
|
+
runs: Map<string, RunToken>;
|
|
51
|
+
}
|
|
52
|
+
/** One store per process: the nodes and sub-workflows of one run swap once and share the token. */
|
|
53
|
+
export declare const PROCESS_STORE: TokenStore;
|
|
54
|
+
/** Holds the account token and the run tokens, kept per account, agent and run. */
|
|
55
|
+
export declare class AgentRunTokens {
|
|
56
|
+
private readonly post;
|
|
57
|
+
private readonly now;
|
|
58
|
+
private readonly accounts;
|
|
59
|
+
private readonly runs;
|
|
60
|
+
constructor(post: FormPost, now?: () => number, store?: TokenStore);
|
|
61
|
+
private accountKey;
|
|
62
|
+
private accountToken;
|
|
63
|
+
/** The run token for one agent and run: cached, swapped again shortly before it expires. */
|
|
64
|
+
runToken(a: FunctionAccount, agentUuid: string, runId: string, opts?: {
|
|
65
|
+
fresh?: boolean;
|
|
66
|
+
}): Promise<RunToken>;
|
|
67
|
+
/** Forgets a run token, e.g. after the MCP endpoint refused it. */
|
|
68
|
+
forget(a: FunctionAccount, agentUuid: string, runId: string): void;
|
|
69
|
+
private prune;
|
|
70
|
+
}
|
|
71
|
+
/** Reads the refusal code of an MCP reply under a run token: JSON-RPC error.message or an OAuth error. */
|
|
72
|
+
export declare function mcpRefusalCode(body: string): string;
|
|
73
|
+
export {};
|