@hotmeshio/long-tail 0.4.20 → 0.4.22
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/build/api/escalations/claim.d.ts +2 -0
- package/build/api/escalations/claim.js +10 -6
- package/build/api/escalations/helpers.d.ts +24 -1
- package/build/api/escalations/helpers.js +48 -3
- package/build/api/escalations/metadata.d.ts +10 -2
- package/build/api/escalations/metadata.js +29 -6
- package/build/modules/auth.d.ts +1 -1
- package/build/modules/auth.js +3 -3
- package/build/routes/escalations/metadata.js +2 -1
- package/build/routes/escalations/single.js +1 -1
- package/build/sdk/index.d.ts +2 -0
- package/build/services/auth/bot-api-key.js +6 -24
- package/build/services/auth/service-token.js +6 -18
- package/build/services/auth/sql.d.ts +11 -0
- package/build/services/auth/sql.js +37 -0
- package/build/services/escalation/crud.d.ts +19 -3
- package/build/services/escalation/crud.js +32 -15
- package/build/services/escalation/sql.d.ts +9 -2
- package/build/services/escalation/sql.js +36 -14
- package/build/system/seed/tool-manifests-admin.d.ts +59 -0
- package/build/system/seed/tool-manifests-admin.js +2 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/docs/api/http/escalations.md +38 -2
- package/docs/api/sdk/escalations.md +25 -5
- package/package.json +2 -2
|
@@ -730,6 +730,24 @@ Finds one available (pending + unassigned/expired) escalation matching the metad
|
|
|
730
730
|
| `durationMinutes` | `number` | Claim duration (default 30) |
|
|
731
731
|
| `assignee` | `string` | Claim as a Long Tail user (resolved via `getUserByExternalId`) |
|
|
732
732
|
| `metadata` | `object` | Additional metadata to merge (new keys added, existing overwritten) |
|
|
733
|
+
| `provisionIfAbsent` | `object` | JIT-provision the assignee if they don't exist (superadmin only) |
|
|
734
|
+
|
|
735
|
+
**`provisionIfAbsent`** — when the `assignee` doesn't exist in `lt_users` or lacks the escalation's role, provision them inline:
|
|
736
|
+
|
|
737
|
+
```json
|
|
738
|
+
{
|
|
739
|
+
"key": "orderId",
|
|
740
|
+
"value": "order-123",
|
|
741
|
+
"assignee": "jane.doe",
|
|
742
|
+
"provisionIfAbsent": {
|
|
743
|
+
"displayName": "Jane Doe",
|
|
744
|
+
"email": "jane@example.com",
|
|
745
|
+
"roles": [{ "role": "station-operator", "type": "member" }]
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
Only callers with global escalation access (superadmin, admin/admin) can use this flag. The user is created with the declared roles if absent. If the user exists but lacks a required role, the role is added. The happy path (user exists, has role) adds zero extra queries.
|
|
733
751
|
|
|
734
752
|
**Response 200:**
|
|
735
753
|
|
|
@@ -748,7 +766,9 @@ Finds one available (pending + unassigned/expired) escalation matching the metad
|
|
|
748
766
|
POST /api/escalations/resolve-by-metadata
|
|
749
767
|
```
|
|
750
768
|
|
|
751
|
-
|
|
769
|
+
Single atomic query finds the pending escalation by metadata, auto-claims if unclaimed, and resolves it. RBAC is enforced in the SQL WHERE clause.
|
|
770
|
+
|
|
771
|
+
**Signal guard:** If the escalation has `metadata.signal_id` (created by `conditionLT`), the SQL does NOT resolve it directly. Instead, the endpoint signals the running workflow — `conditionLT` receives the signal and resolves the escalation durably inside the workflow. This preserves the same transactional integrity as the standard resolve-by-ID path.
|
|
752
772
|
|
|
753
773
|
**Body:**
|
|
754
774
|
|
|
@@ -769,4 +789,20 @@ Finds the pending escalation, auto-claims if unclaimed, then resolves it. Suppor
|
|
|
769
789
|
| `assignee` | `string` | Resolve as a Long Tail user (resolved via `getUserByExternalId`) |
|
|
770
790
|
| `metadata` | `object` | Additional metadata to merge (new keys added, existing overwritten) |
|
|
771
791
|
|
|
772
|
-
**Response 200:**
|
|
792
|
+
**Response 200 (non-signal):** Escalation resolved atomically.
|
|
793
|
+
|
|
794
|
+
```json
|
|
795
|
+
{
|
|
796
|
+
"escalation": { "id": "...", "status": "resolved", ... }
|
|
797
|
+
}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**Response 200 (signal-backed):** Workflow signaled; `conditionLT` resolves the escalation durably.
|
|
801
|
+
|
|
802
|
+
```json
|
|
803
|
+
{
|
|
804
|
+
"signaled": true,
|
|
805
|
+
"escalationId": "...",
|
|
806
|
+
"workflowId": "..."
|
|
807
|
+
}
|
|
808
|
+
```
|
|
@@ -542,14 +542,20 @@ const result = await lt.escalations.findByMetadata({
|
|
|
542
542
|
|
|
543
543
|
## claimByMetadata
|
|
544
544
|
|
|
545
|
-
Find and claim an escalation by metadata key-value pair in one atomic call.
|
|
545
|
+
Find and claim an escalation by metadata key-value pair in one atomic call. RBAC is enforced in the SQL WHERE clause.
|
|
546
546
|
|
|
547
547
|
```typescript
|
|
548
548
|
const result = await lt.escalations.claimByMetadata({
|
|
549
549
|
key: 'orderId',
|
|
550
550
|
value: 'order-123',
|
|
551
551
|
durationMinutes: 30,
|
|
552
|
+
assignee: 'jane.doe',
|
|
552
553
|
metadata: { claimedBy: 'jimbo', station: 'scanning' },
|
|
554
|
+
provisionIfAbsent: {
|
|
555
|
+
displayName: 'Jane Doe',
|
|
556
|
+
email: 'jane@example.com',
|
|
557
|
+
roles: [{ role: 'station-operator', type: 'member' }],
|
|
558
|
+
},
|
|
553
559
|
});
|
|
554
560
|
```
|
|
555
561
|
|
|
@@ -562,6 +568,9 @@ const result = await lt.escalations.claimByMetadata({
|
|
|
562
568
|
| `durationMinutes` | `number` | No | Claim duration (default: 30) |
|
|
563
569
|
| `assignee` | `string` | No | Claim as a Long Tail user (resolved via `getUserByExternalId`) |
|
|
564
570
|
| `metadata` | `object` | No | Merge into escalation metadata (single atomic SQL call with the claim) |
|
|
571
|
+
| `provisionIfAbsent` | `object` | No | JIT-provision the assignee if they don't exist or lack the required role (superadmin only) |
|
|
572
|
+
|
|
573
|
+
`provisionIfAbsent` accepts `{ displayName?, email?, roles?: [{ role, type? }] }`. Only callers with global escalation access can use this flag. The happy path (user exists, has role) adds zero extra queries.
|
|
565
574
|
|
|
566
575
|
**Returns:** `LTApiResult<{ escalation, isExtension }>` -- 404 if no match, 409 if already claimed.
|
|
567
576
|
|
|
@@ -571,15 +580,26 @@ const result = await lt.escalations.claimByMetadata({
|
|
|
571
580
|
|
|
572
581
|
## resolveByMetadata
|
|
573
582
|
|
|
574
|
-
Find and resolve an escalation by metadata key-value pair.
|
|
583
|
+
Find and resolve an escalation by metadata key-value pair. Single atomic query with signal guard.
|
|
584
|
+
|
|
585
|
+
If the escalation has `metadata.signal_id` (created by `conditionLT`), the endpoint signals the running workflow instead of resolving directly in the DB. `conditionLT` receives the signal and resolves the escalation durably inside the workflow. This preserves the same transactional integrity as the standard resolve-by-ID path.
|
|
575
586
|
|
|
576
587
|
```typescript
|
|
588
|
+
// Non-signal escalation → resolved atomically
|
|
589
|
+
const result = await lt.escalations.resolveByMetadata({
|
|
590
|
+
key: 'orderId',
|
|
591
|
+
value: 'order-123',
|
|
592
|
+
resolverPayload: { approved: true },
|
|
593
|
+
});
|
|
594
|
+
// result.data.escalation.status === 'resolved'
|
|
595
|
+
|
|
596
|
+
// Signal-backed escalation → workflow signaled
|
|
577
597
|
const result = await lt.escalations.resolveByMetadata({
|
|
578
598
|
key: 'orderId',
|
|
579
599
|
value: 'order-123',
|
|
580
|
-
resolverPayload: { approved: true
|
|
581
|
-
metadata: { completedBy: 'jimbo' },
|
|
600
|
+
resolverPayload: { approved: true },
|
|
582
601
|
});
|
|
602
|
+
// result.data.signaled === true, result.data.workflowId === '...'
|
|
583
603
|
```
|
|
584
604
|
|
|
585
605
|
**Parameters:**
|
|
@@ -592,6 +612,6 @@ const result = await lt.escalations.resolveByMetadata({
|
|
|
592
612
|
| `assignee` | `string` | No | Resolve as a Long Tail user (resolved via `getUserByExternalId`) |
|
|
593
613
|
| `metadata` | `object` | No | Merge into escalation metadata before resolving |
|
|
594
614
|
|
|
595
|
-
**Returns:**
|
|
615
|
+
**Returns:** `LTApiResult<{ escalation }>` for non-signal, `LTApiResult<{ signaled, escalationId, workflowId }>` for signal-backed. 404 if no match.
|
|
596
616
|
|
|
597
617
|
**Auth:** Required
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hotmeshio/long-tail",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.22",
|
|
4
4
|
"description": "Long Tail Workflows — Durable AI workflows with human-in-the-loop escalation. Powered by PostgreSQL.",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@anthropic-ai/sdk": "^0.92.0",
|
|
71
71
|
"@aws-sdk/client-s3": "^3.1017.0",
|
|
72
72
|
"@aws-sdk/s3-request-presigner": "^3.1045.0",
|
|
73
|
-
"@hotmeshio/hotmesh": "^0.19.
|
|
73
|
+
"@hotmeshio/hotmesh": "^0.19.5",
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
75
75
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.215.0",
|
|
76
76
|
"@opentelemetry/resources": "^2.5.1",
|