@bpmsoftwaresolutions/ai-engine-client 1.0.0-beta.11 → 1.0.0-beta.13

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.
Files changed (3) hide show
  1. package/README.md +87 -1
  2. package/package.json +1 -1
  3. package/src/index.js +77 -0
package/README.md CHANGED
@@ -94,7 +94,8 @@ If your deployment enforces bearer auth on operator routes, API-key-only constru
94
94
 
95
95
  Some methods do not return plain JSON:
96
96
 
97
- - Markdown download helpers return `{ text, contentType, fileName }`.
97
+ - Markdown download helpers return `{ text, contentType, fileName, headers }`.
98
+ - LOGA projection helpers return markdown plus governed projection metadata: `{ text, contentType, headers, logaContract, interactionContract, projectionType, projectionVersion, sourceTruth, sourceVersion, correlationId, refreshPolicy, generatedAt, provenance }`.
98
99
  - Binary download helpers return `{ arrayBuffer, contentType, fileName }`.
99
100
 
100
101
  Examples:
@@ -106,10 +107,60 @@ const markdown = await client.downloadProjectCharterReportMarkdown(projectId);
106
107
  console.log(markdown.fileName, markdown.contentType);
107
108
  console.log(markdown.text);
108
109
 
110
+ const logaRoadmap = await client.getLogaProjectRoadmapProjection(projectId);
111
+ console.log(logaRoadmap.projectionType, logaRoadmap.projectionVersion);
112
+ console.log(logaRoadmap.provenance.sourceTruth, logaRoadmap.correlationId);
113
+ console.log(logaRoadmap.text);
114
+
115
+ const logaRoadmapItem = await client.getLogaRoadmapItemProjection(projectId, 'execute-scope-1');
116
+ console.log(logaRoadmapItem.projectionType, logaRoadmapItem.provenance.sourceVersion);
117
+ console.log(logaRoadmapItem.text);
118
+
109
119
  const audio = await client.downloadExternalAudioRender(audioRenderRunId);
110
120
  await fs.promises.writeFile('render.mp3', Buffer.from(audio.arrayBuffer));
111
121
  ```
112
122
 
123
+ ### LOGA Projection Contract
124
+
125
+ LOGA should use the `getLoga*Projection()` methods for runtime documents. These endpoints are governed AI Engine transformations: durable SQL state is normalized into typed projection models, transformed into versioned structured markdown, and served with provenance, refresh, and action metadata for LOGA to render.
126
+
127
+ The client exposes the transport metadata from response headers so LOGA can validate the contract before rendering:
128
+
129
+ - `logaContract`: currently `ai-engine-ui/v1`
130
+ - `interactionContract`: currently `loga-choreography/v1`
131
+ - `projectionType`: for example `operator.project_roadmap`
132
+ - `projectionWorkflow`: currently `loga-document-projection`
133
+ - `projectionVersion`
134
+ - `sourceTruth`: normally `sql`
135
+ - `sourceVersion`
136
+ - `correlationId`
137
+ - `refreshPolicy`
138
+ - `generatedAt`
139
+ - `provenance`: grouped copy of the source/projection/version fields
140
+
141
+ Example:
142
+
143
+ ```js
144
+ import {
145
+ AIEngineClient,
146
+ LOGA_CONTRACT,
147
+ LOGA_INTERACTION_CONTRACT,
148
+ } from '@bpmsoftwaresolutions/ai-engine-client';
149
+
150
+ const client = AIEngineClient.fromEnv();
151
+ const projection = await client.getLogaProjectRoadmapProjection(projectId);
152
+
153
+ if (projection.logaContract !== LOGA_CONTRACT) {
154
+ throw new Error(`Unsupported LOGA contract: ${projection.logaContract}`);
155
+ }
156
+
157
+ console.log(projection.interactionContract === LOGA_INTERACTION_CONTRACT);
158
+ renderLogaMarkdown(projection.text, {
159
+ projectionType: projection.projectionType,
160
+ provenance: projection.provenance,
161
+ });
162
+ ```
163
+
113
164
  ### fromEnv
114
165
 
115
166
  ```js
@@ -321,6 +372,18 @@ Low-level compatibility methods:
321
372
  | `listAzureSqlBacpacBackups({ storageAccount, container, ... })` | List BACPAC exports through the legacy infra-shaped operator API. |
322
373
  | `listAzureSqlBacpacBackupOperations({ databaseName, resourceGroup, serverName, ... })` | List Azure SQL operations through the legacy infra-shaped operator API. |
323
374
 
375
+ ### LOGA Projections
376
+ | Method | Endpoint | Description |
377
+ |---|---|---|
378
+ | `getLogaOperatorHomeProjection()` | `GET /api/operator/projections/home` | Governed operator home runtime markdown document. |
379
+ | `getLogaProjectCatalogProjection()` | `GET /api/operator/projections/project-catalog` | Governed project catalog runtime markdown document. |
380
+ | `getLogaProjectRoadmapProjection(projectId)` | `GET /api/operator/projections/projects/:projectId/roadmap.md` | Governed project roadmap runtime markdown document. |
381
+ | `getLogaRoadmapItemProjection(projectId, itemKey)` | `GET /api/operator/projections/projects/:projectId/roadmap/items/:itemKey` | Governed roadmap item runtime markdown document with item-level navigation, related documents, actions, and evidence. |
382
+ | `getLogaWorkflowRunProjection(workflowRunId)` | `GET /api/operator/projections/workflow-runs/:workflowRunId` | Governed workflow run runtime markdown document. |
383
+ | `getLogaEvidencePacketProjection(packetKey)` | `GET /api/operator/projections/evidence-packets/:packetKey` | Governed evidence packet runtime markdown document. |
384
+
385
+ These methods return markdown as `text` and expose projection headers as top-level fields plus `provenance`. LOGA should render the markdown emitted by AI Engine and use these metadata fields for contract validation, refresh behavior, evidence display, and action choreography.
386
+
324
387
  ### Retrieval Wrapper
325
388
  | Method | Description |
326
389
  |---|---|
@@ -448,6 +511,9 @@ Low-level compatibility methods:
448
511
  | `completeImplementationTask(taskId, { completedBy })` | Mark complete. |
449
512
 
450
513
  ### Governed Implementation
514
+
515
+ Current package version: `1.0.0-beta.13`.
516
+
451
517
  | Method | Description |
452
518
  |---|---|
453
519
  | `importImplementationPacket(body)` | Import an implementation packet. |
@@ -463,6 +529,26 @@ Low-level compatibility methods:
463
529
  | `getWorkflowImplementationRoadmap(workflowId)` | Workflow-linked roadmap. |
464
530
  | `getWorkflowResumeContext(workflowId)` | Resume context. |
465
531
 
532
+ Governed roadmap item mutations must carry claim context. Include the active
533
+ claim in the request body:
534
+
535
+ ```js
536
+ await client.updateImplementationItemStatus(itemId, {
537
+ status: 'done',
538
+ status_reason: 'Evidence attached and gates passed.',
539
+ updated_by: 'operator:loga',
540
+ claimed_item_id: itemId,
541
+ agent_session_id: 'agent-session-id',
542
+ claim_workflow_run_id: 'workflow-run-id',
543
+ });
544
+ ```
545
+
546
+ The same claim envelope applies to `addImplementationItemEvidence()`,
547
+ `addImplementationItemActivity()`, and `updateAcceptanceCheckStatus()`. If the
548
+ claim is missing, AI Engine returns `409` with `error:
549
+ missing_governed_claim`. If the claim exists but unresolved gates remain, AI
550
+ Engine returns the required gate and next action.
551
+
466
552
  ### Skills
467
553
  | Method | Description |
468
554
  |---|---|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmsoftwaresolutions/ai-engine-client",
3
- "version": "1.0.0-beta.11",
3
+ "version": "1.0.0-beta.13",
4
4
  "description": "Thin npm client for the AI Engine operator and retrieval APIs",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -1,5 +1,9 @@
1
1
  const DEFAULT_TIMEOUT_MS = 30000;
2
2
 
3
+ export const LOGA_CONTRACT = 'ai-engine-ui/v1';
4
+ export const LOGA_INTERACTION_CONTRACT = 'loga-choreography/v1';
5
+ export const LOGA_PROJECTION_WORKFLOW = 'loga-document-projection';
6
+
3
7
  function trimTrailingSlash(value) {
4
8
  return String(value || '').replace(/\/+$/, '');
5
9
  }
@@ -28,6 +32,44 @@ function parseContentDispositionFilename(headerValue) {
28
32
  return plainMatch ? plainMatch[1].trim() : null;
29
33
  }
30
34
 
35
+ function readResponseHeader(headers, name) {
36
+ if (!headers || typeof headers.get !== 'function') return null;
37
+ return headers.get(name) || headers.get(name.toLowerCase()) || null;
38
+ }
39
+
40
+ function extractLogaProjectionMetadata(headers) {
41
+ const projectionWorkflow = readResponseHeader(headers, 'x-projection-workflow');
42
+ const projectionVersion = readResponseHeader(headers, 'x-projection-version');
43
+ const sourceVersion = readResponseHeader(headers, 'x-source-version');
44
+ const correlationId = readResponseHeader(headers, 'x-correlation-id');
45
+ const logaContract = readResponseHeader(headers, 'x-loga-contract');
46
+ const projectionType = readResponseHeader(headers, 'x-projection-type');
47
+ const sourceTruth = readResponseHeader(headers, 'x-source-truth');
48
+ const refreshPolicy = readResponseHeader(headers, 'x-refresh-policy');
49
+ const generatedAt = readResponseHeader(headers, 'x-generated-at');
50
+
51
+ return {
52
+ logaContract,
53
+ interactionContract: LOGA_INTERACTION_CONTRACT,
54
+ projectionType,
55
+ projectionWorkflow,
56
+ projectionVersion,
57
+ sourceTruth,
58
+ sourceVersion,
59
+ correlationId,
60
+ refreshPolicy,
61
+ generatedAt,
62
+ provenance: {
63
+ sourceTruth,
64
+ sourceVersion,
65
+ projectionVersion,
66
+ projectionWorkflow,
67
+ correlationId,
68
+ generatedAt,
69
+ },
70
+ };
71
+ }
72
+
31
73
  function isFormDataBody(value) {
32
74
  return typeof FormData !== 'undefined' && value instanceof FormData;
33
75
  }
@@ -709,6 +751,32 @@ export class AIEngineClient {
709
751
  return this._request(`/api/operator/projects/${projectId}/bundle`);
710
752
  }
711
753
 
754
+ // LOGA projections are governed runtime documents, not static reports.
755
+
756
+ async getLogaOperatorHomeProjection() {
757
+ return this._requestLogaProjection('/api/operator/projections/home');
758
+ }
759
+
760
+ async getLogaProjectCatalogProjection() {
761
+ return this._requestLogaProjection('/api/operator/projections/project-catalog');
762
+ }
763
+
764
+ async getLogaProjectRoadmapProjection(projectId) {
765
+ return this._requestLogaProjection(`/api/operator/projections/projects/${projectId}/roadmap.md`);
766
+ }
767
+
768
+ async getLogaRoadmapItemProjection(projectId, itemKey) {
769
+ return this._requestLogaProjection(`/api/operator/projections/projects/${projectId}/roadmap/items/${itemKey}`);
770
+ }
771
+
772
+ async getLogaWorkflowRunProjection(workflowRunId) {
773
+ return this._requestLogaProjection(`/api/operator/projections/workflow-runs/${workflowRunId}`);
774
+ }
775
+
776
+ async getLogaEvidencePacketProjection(packetKey) {
777
+ return this._requestLogaProjection(`/api/operator/projections/evidence-packets/${packetKey}`);
778
+ }
779
+
712
780
  // ─── Roadmaps ──────────────────────────────────────────────────────────────
713
781
 
714
782
  async listProjectRoadmaps({ includeInactive } = {}) {
@@ -1393,12 +1461,21 @@ export class AIEngineClient {
1393
1461
  text: await response.text(),
1394
1462
  contentType,
1395
1463
  fileName: parseContentDispositionFilename(contentDisposition),
1464
+ headers: Object.fromEntries(response.headers.entries()),
1396
1465
  };
1397
1466
  } finally {
1398
1467
  clearTimeout(timeoutHandle);
1399
1468
  }
1400
1469
  }
1401
1470
 
1471
+ async _requestLogaProjection(path, options = {}) {
1472
+ const result = await this._requestText(path, options);
1473
+ return {
1474
+ ...result,
1475
+ ...extractLogaProjectionMetadata(new Headers(result.headers || {})),
1476
+ };
1477
+ }
1478
+
1402
1479
  async _requestBinary(path, { method = 'GET', query, headers, body } = {}) {
1403
1480
  const url = appendQuery(`${this.baseUrl}${path}`, query);
1404
1481
  const controller = new AbortController();