@pikku/mongodb 0.12.14 → 0.12.15

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 CHANGED
@@ -1,5 +1,49 @@
1
1
  # @pikku/mongodb
2
2
 
3
+ ## 0.12.15
4
+
5
+ ### Patch Changes
6
+
7
+ - 6dada45: fix(workflow,ai-agent): make a run's owner, entry node and step function authoritative
8
+
9
+ A graph run may only start at a node the graph declared in `meta.entryNodeIds`, and
10
+ the generated `POST /workflow/:workflowName/graph/:nodeId` route that let an HTTP
11
+ caller pick the entry node is gone. `startNode` stays for `PikkuTriggerService`,
12
+ which names a declared entry node anyway.
13
+
14
+ `StepState` now records the `rpcName` the workflow dispatched a step with, and the
15
+ step claim rejects a queue message naming a different function with
16
+ `WorkflowStepFunctionMismatchError` before mutating any status — a step runs under
17
+ the run owner's identity and without the `expose` gate, so the message must not
18
+ choose what runs.
19
+
20
+ `approveStep` takes the caller's session, and the generated status routes and
21
+ streams assert the same `assertWorkflowRunOwner` check: a run started through a
22
+ session may only be read and approved by that session's user. A run with no
23
+ recorded owner (trigger, scheduler, unauthenticated route) has nobody to compare
24
+ against and is still gated by the entrypoint's own `auth`/`permissions`.
25
+
26
+ `AIRunStateService.resolveApproval` is now a compare-and-swap returning whether
27
+ _this_ caller made the claim, and both agent resume paths run a tool only for the
28
+ approvals they claimed — concurrent approvals of one tool call no longer all
29
+ execute it.
30
+
31
+ - Updated dependencies [41c1a95]
32
+ - Updated dependencies [ce96383]
33
+ - Updated dependencies [7e60867]
34
+ - Updated dependencies [f8f1244]
35
+ - Updated dependencies [dcf20cb]
36
+ - Updated dependencies [6512384]
37
+ - Updated dependencies [e3b4c14]
38
+ - Updated dependencies [efd0ed1]
39
+ - Updated dependencies [cba98fb]
40
+ - Updated dependencies [ce96383]
41
+ - Updated dependencies [f8f1244]
42
+ - Updated dependencies [f8f1244]
43
+ - Updated dependencies [6e93a35]
44
+ - Updated dependencies [6dada45]
45
+ - @pikku/core@0.12.80
46
+
3
47
  ## 0.12.14
4
48
 
5
49
  ### Patch Changes
@@ -36,6 +36,6 @@ export declare class MongoDBAIStorageService implements AIStorageService, AIRunS
36
36
  run: AgentRunState;
37
37
  approval: NonNullable<AgentRunState['pendingApprovals']>[number];
38
38
  } | null>;
39
- resolveApproval(toolCallId: string, status: 'approved' | 'denied'): Promise<void>;
39
+ resolveApproval(toolCallId: string, status: 'approved' | 'denied'): Promise<boolean>;
40
40
  close(): Promise<void>;
41
41
  }
@@ -402,7 +402,9 @@ export class MongoDBAIStorageService {
402
402
  return { run, approval };
403
403
  }
404
404
  async resolveApproval(toolCallId, status) {
405
- await this.toolCalls.updateOne({ _id: toolCallId }, { $set: { approvalStatus: status } });
405
+ // Only the caller that moves the tool call off 'pending' has claimed it.
406
+ const result = await this.toolCalls.updateOne({ _id: toolCallId, approvalStatus: 'pending' }, { $set: { approvalStatus: status } });
407
+ return result.modifiedCount > 0;
406
408
  }
407
409
  async close() { }
408
410
  }
@@ -85,6 +85,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
85
85
  return {
86
86
  stepId,
87
87
  status: 'pending',
88
+ rpcName,
88
89
  result: undefined,
89
90
  error: undefined,
90
91
  attemptCount: 1,
@@ -109,6 +110,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
109
110
  return {
110
111
  stepId: row._id,
111
112
  status: row.status,
113
+ rpcName: row.rpcName ?? null,
112
114
  result: row.result ?? undefined,
113
115
  error: row.error ?? undefined,
114
116
  attemptCount,
@@ -238,6 +240,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
238
240
  return {
239
241
  stepId: row._id,
240
242
  status: row.status,
243
+ rpcName: row.rpcName ?? null,
241
244
  result: row.result ?? undefined,
242
245
  error: row.error ?? undefined,
243
246
  attemptCount,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/mongodb",
3
- "version": "0.12.14",
3
+ "version": "0.12.15",
4
4
  "description": "MongoDB services for Pikku — workflow state, agent runs, secrets and channel stores",
5
5
  "author": "yasser.fadl@gmail.com",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "prepublishOnly": "yarn build"
19
19
  },
20
20
  "peerDependencies": {
21
- "@pikku/core": "^0.12.76"
21
+ "@pikku/core": "^0.12.80"
22
22
  },
23
23
  "dependencies": {
24
24
  "mongodb": "^6.12.0"
@@ -565,11 +565,13 @@ export class MongoDBAIStorageService
565
565
  async resolveApproval(
566
566
  toolCallId: string,
567
567
  status: 'approved' | 'denied'
568
- ): Promise<void> {
569
- await this.toolCalls.updateOne(
570
- { _id: toolCallId },
568
+ ): Promise<boolean> {
569
+ // Only the caller that moves the tool call off 'pending' has claimed it.
570
+ const result = await this.toolCalls.updateOne(
571
+ { _id: toolCallId, approvalStatus: 'pending' },
571
572
  { $set: { approvalStatus: status } }
572
573
  )
574
+ return result.modifiedCount > 0
573
575
  }
574
576
 
575
577
  public async close(): Promise<void> {}
@@ -203,6 +203,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
203
203
  return {
204
204
  stepId,
205
205
  status: 'pending',
206
+ rpcName,
206
207
  result: undefined,
207
208
  error: undefined,
208
209
  attemptCount: 1,
@@ -233,6 +234,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
233
234
  return {
234
235
  stepId: row._id,
235
236
  status: row.status as StepState['status'],
237
+ rpcName: row.rpcName ?? null,
236
238
  result: row.result ?? undefined,
237
239
  error: row.error ?? undefined,
238
240
  attemptCount,
@@ -426,6 +428,7 @@ export class MongoDBWorkflowService extends PikkuWorkflowService {
426
428
  return {
427
429
  stepId: row._id,
428
430
  status: row.status as StepState['status'],
431
+ rpcName: row.rpcName ?? null,
429
432
  result: row.result ?? undefined,
430
433
  error: row.error ?? undefined,
431
434
  attemptCount,