c8ctl-plugin-nano 1.59.0 → 1.59.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.
@@ -34,9 +34,10 @@ const isPlainObject = (v) => v != null && typeof v === 'object' && !Array.isArra
34
34
  * element carries `zeebe:agentDefinition agentType="external"`?
35
35
  *
36
36
  * The engine surfaces exactly this eligibility as the pair of fields it stamps on
37
- * an external agent job's activation: an opaque per-activation `jobLease` token
38
- * (distinct from the job's `deadline`; nanobpmn #1106) plus the `elementInstanceKey`
39
- * the AgentInstance correlates on. The engine-native `aiAgentTask`/`aiAgentSubProcess`
37
+ * an external agent job's activation: an opaque per-activation lease token
38
+ * `leaseToken` on the activated job (Camunda v10 ActivatedJobResult; distinct from
39
+ * the job's `deadline`, nanobpmn #1106) plus the `elementInstanceKey` the
40
+ * AgentInstance correlates on. The engine-native `aiAgentTask`/`aiAgentSubProcess`
40
41
  * variants auto-mint their AgentInstance and never create an activatable job, so any
41
42
  * job a worker actually activates that carries a lease token IS an external agent
42
43
  * job. Absence of either field means "not an external agent job" → the producer
@@ -44,7 +45,7 @@ const isPlainObject = (v) => v != null && typeof v === 'object' && !Array.isArra
44
45
  */
45
46
  export function isExternalAgentJob(job) {
46
47
  if (!isPlainObject(job)) return false;
47
- return isNonBlank(job.jobLease) && isNonBlank(job.elementInstanceKey);
48
+ return isNonBlank(job.leaseToken) && isNonBlank(job.elementInstanceKey);
48
49
  }
49
50
 
50
51
  /** Best-effort provider inference from a model identifier (openai/anthropic/…). */
@@ -145,7 +146,7 @@ function contentForResult(result) {
145
146
  *
146
147
  * @param {object} opts
147
148
  * @param {object} opts.camunda Host SDK client (createAgentInstance/updateAgentInstance).
148
- * @param {object} opts.job The activated job (jobKey/jobLease/elementInstanceKey/elementId).
149
+ * @param {object} opts.job The activated job (jobKey/leaseToken/elementInstanceKey/elementId).
149
150
  * @param {object} [opts.profile] The worker profile (model/provider seed the definition).
150
151
  * @param {object} [opts.envelope] The normalized task envelope (task.prompt → systemPrompt).
151
152
  * @param {object} [opts.logger] Output-mode-aware logger (warn/info/debug).
@@ -166,7 +167,12 @@ export function createAgentInstanceProducer(opts = {}) {
166
167
  const classify = typeof sessionAcp?.classifyUpdate === 'function' ? sessionAcp.classifyUpdate : null;
167
168
 
168
169
  const jobKey = job?.jobKey != null ? String(job.jobKey) : '';
169
- const jobLease = job?.jobLease != null ? String(job.jobLease) : '';
170
+ // The activation lease is carried on the job as `leaseToken` (Camunda v10
171
+ // ActivatedJobResult). It is submitted BACK to createAgentInstance/updateAgentInstance
172
+ // as the request-body field `jobLease` (agent-instances.yaml) — the same opaque token,
173
+ // named differently on the two sides of the contract. One internal name here; the
174
+ // translation to `jobLease` happens only at each SDK call below.
175
+ const leaseToken = job?.leaseToken != null ? String(job.leaseToken) : '';
170
176
  const elementInstanceKey = job?.elementInstanceKey != null ? String(job.elementInstanceKey) : '';
171
177
  const elementId = job?.elementId != null ? String(job.elementId) : null;
172
178
 
@@ -212,7 +218,7 @@ export function createAgentInstanceProducer(opts = {}) {
212
218
  agentInstanceKey,
213
219
  elementInstanceKey,
214
220
  jobKey,
215
- jobLease,
221
+ jobLease: leaseToken,
216
222
  history: [turn],
217
223
  };
218
224
  if (status) req.status = status;
@@ -321,7 +327,7 @@ export function createAgentInstanceProducer(opts = {}) {
321
327
  const res = await camunda[SDK_CREATE]({
322
328
  elementInstanceKey,
323
329
  jobKey,
324
- jobLease,
330
+ jobLease: leaseToken,
325
331
  history: [configTurn],
326
332
  });
327
333
  agentInstanceKey =
@@ -425,7 +431,7 @@ export function createAgentInstanceProducer(opts = {}) {
425
431
  agentInstanceKey,
426
432
  elementInstanceKey,
427
433
  jobKey,
428
- jobLease,
434
+ jobLease: leaseToken,
429
435
  status: 'COMPLETED',
430
436
  });
431
437
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c8ctl-plugin-nano",
3
- "version": "1.59.0",
3
+ "version": "1.59.1",
4
4
  "type": "module",
5
5
  "description": "c8ctl plugin to start, inspect, and stop a local Nano BPM (nanobpmn) cluster",
6
6
  "main": "c8ctl-plugin.js",
@@ -73,12 +73,12 @@
73
73
  },
74
74
  "optionalDependencies": {
75
75
  "node-pty": "^1.0.0",
76
- "@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.59.0",
77
- "@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.59.0",
78
- "@nanobpm/c8ctl-plugin-nano-linux-x64": "1.59.0",
79
- "@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.59.0",
80
- "@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.59.0",
81
- "@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.59.0",
82
- "@nanobpm/c8ctl-plugin-nano-win32-x64": "1.59.0"
76
+ "@nanobpm/c8ctl-plugin-nano-darwin-arm64": "1.59.1",
77
+ "@nanobpm/c8ctl-plugin-nano-darwin-x64": "1.59.1",
78
+ "@nanobpm/c8ctl-plugin-nano-linux-x64": "1.59.1",
79
+ "@nanobpm/c8ctl-plugin-nano-linux-arm64": "1.59.1",
80
+ "@nanobpm/c8ctl-plugin-nano-linux-armv7": "1.59.1",
81
+ "@nanobpm/c8ctl-plugin-nano-linux-armv6": "1.59.1",
82
+ "@nanobpm/c8ctl-plugin-nano-win32-x64": "1.59.1"
83
83
  }
84
84
  }
@@ -141,17 +141,22 @@ function mapJob(raw) {
141
141
  const pik = raw.processInstanceKey;
142
142
  if (pik !== undefined && pik !== null) job.processInstanceKey = String(pik);
143
143
  // Engine-native AgentInstance attribution (issue #194): the element instance the
144
- // AgentInstance correlates on, the element id, and the opaque per-activation
145
- // `jobLease` token that lease-gates a `createAgentInstance` for an `external`
146
- // agent job (nanobpmn #1099/#1106). These ride opaquely to the runner exactly as
147
- // the SDK activation surfaces them; absent for ordinary (non-agent) jobs, in which
148
- // case the durable-transcript producer stays inert.
144
+ // AgentInstance correlates on, the element id, and the opaque per-activation lease
145
+ // token that lease-gates a `createAgentInstance` for an `external` agent job
146
+ // (nanobpmn #1099/#1106). The Camunda v10 REST contract carries the lease on the
147
+ // ACTIVATED JOB as `leaseToken` (jobs.yaml ActivatedJobResult) NOT `jobLease`,
148
+ // which is the field name only on the createAgentInstance/updateAgentInstance REQUEST
149
+ // body (agent-instances.yaml). The harness carries ONE internal name — `leaseToken` —
150
+ // all the way through, and translates to `jobLease` only at that SDK body (see
151
+ // agent-instance.mjs). These ride opaquely to the runner exactly as the SDK activation
152
+ // surfaces them; absent for ordinary (non-agent) jobs, in which case the
153
+ // durable-transcript producer stays inert.
149
154
  const eik = raw.elementInstanceKey;
150
155
  if (eik !== undefined && eik !== null) job.elementInstanceKey = String(eik);
151
156
  const eid = raw.elementId;
152
157
  if (eid !== undefined && eid !== null) job.elementId = String(eid);
153
- const lease = raw.jobLease;
154
- if (lease !== undefined && lease !== null) job.jobLease = String(lease);
158
+ const lease = raw.leaseToken;
159
+ if (lease !== undefined && lease !== null) job.leaseToken = String(lease);
155
160
  return job;
156
161
  }
157
162
 
@@ -254,6 +259,12 @@ export function createRawEngineClient(opts = {}) {
254
259
  maxJobsToActivate: req.maxJobsToActivate,
255
260
  timeout: req.lockMs,
256
261
  requestTimeout: req.requestTimeoutMs,
262
+ // Request a per-activation lease (Camunda v10 `withLease`): the engine then
263
+ // stamps each activated job with a distinct opaque `leaseToken`
264
+ // (ActivatedJobResult.leaseToken) which lease-gates the external agent job's
265
+ // `createAgentInstance` (nanobpmn #1099/#1106). Without it the token is absent
266
+ // and the durable AgentInstance producer stays inert.
267
+ withLease: true,
257
268
  };
258
269
  // Give the abort budget slack over the server long-poll so we don't cancel
259
270
  // a still-valid long-poll a hair before the server would answer it.