@endora-commerce/mod-prompt-actions 0.0.0-stage → 0.100.0

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -2
  3. package/dist/backend/entities/prompt-action-request.entity.d.ts +37 -0
  4. package/dist/backend/entities/prompt-action-request.entity.d.ts.map +1 -0
  5. package/dist/backend/entities/prompt-action-request.entity.js +130 -0
  6. package/dist/backend/entities/prompt-action-request.entity.js.map +1 -0
  7. package/dist/backend/index.d.ts +94 -0
  8. package/dist/backend/index.d.ts.map +1 -0
  9. package/dist/backend/index.js +127 -0
  10. package/dist/backend/index.js.map +1 -0
  11. package/dist/backend/routes.admin.d.ts +30 -0
  12. package/dist/backend/routes.admin.d.ts.map +1 -0
  13. package/dist/backend/routes.admin.js +71 -0
  14. package/dist/backend/routes.admin.js.map +1 -0
  15. package/dist/backend/services/bulk-progress-registry.d.ts +82 -0
  16. package/dist/backend/services/bulk-progress-registry.d.ts.map +1 -0
  17. package/dist/backend/services/bulk-progress-registry.js +44 -0
  18. package/dist/backend/services/bulk-progress-registry.js.map +1 -0
  19. package/dist/backend/services/interpreter.service.d.ts +59 -0
  20. package/dist/backend/services/interpreter.service.d.ts.map +1 -0
  21. package/dist/backend/services/interpreter.service.js +270 -0
  22. package/dist/backend/services/interpreter.service.js.map +1 -0
  23. package/dist/backend/services/llm/anthropic-adapter.d.ts +9 -0
  24. package/dist/backend/services/llm/anthropic-adapter.d.ts.map +1 -0
  25. package/dist/backend/services/llm/anthropic-adapter.js +83 -0
  26. package/dist/backend/services/llm/anthropic-adapter.js.map +1 -0
  27. package/dist/backend/services/llm/google-adapter.d.ts +9 -0
  28. package/dist/backend/services/llm/google-adapter.d.ts.map +1 -0
  29. package/dist/backend/services/llm/google-adapter.js +125 -0
  30. package/dist/backend/services/llm/google-adapter.js.map +1 -0
  31. package/dist/backend/services/llm/openai-adapter.d.ts +9 -0
  32. package/dist/backend/services/llm/openai-adapter.d.ts.map +1 -0
  33. package/dist/backend/services/llm/openai-adapter.js +95 -0
  34. package/dist/backend/services/llm/openai-adapter.js.map +1 -0
  35. package/dist/backend/services/llm/provider-factory.d.ts +60 -0
  36. package/dist/backend/services/llm/provider-factory.d.ts.map +1 -0
  37. package/dist/backend/services/llm/provider-factory.js +111 -0
  38. package/dist/backend/services/llm/provider-factory.js.map +1 -0
  39. package/dist/backend/services/llm/provider.d.ts +63 -0
  40. package/dist/backend/services/llm/provider.d.ts.map +1 -0
  41. package/dist/backend/services/llm/provider.js +67 -0
  42. package/dist/backend/services/llm/provider.js.map +1 -0
  43. package/dist/backend/services/plan-executor.service.d.ts +49 -0
  44. package/dist/backend/services/plan-executor.service.d.ts.map +1 -0
  45. package/dist/backend/services/plan-executor.service.js +132 -0
  46. package/dist/backend/services/plan-executor.service.js.map +1 -0
  47. package/dist/backend/services/prompt-request.service.d.ts +84 -0
  48. package/dist/backend/services/prompt-request.service.d.ts.map +1 -0
  49. package/dist/backend/services/prompt-request.service.js +338 -0
  50. package/dist/backend/services/prompt-request.service.js.map +1 -0
  51. package/dist/backend/services/tool-registry.d.ts +17 -0
  52. package/dist/backend/services/tool-registry.d.ts.map +1 -0
  53. package/dist/backend/services/tool-registry.js +89 -0
  54. package/dist/backend/services/tool-registry.js.map +1 -0
  55. package/dist/manifest.d.ts +252 -0
  56. package/dist/manifest.d.ts.map +1 -0
  57. package/dist/manifest.js +199 -0
  58. package/dist/manifest.js.map +1 -0
  59. package/dist/migrations/20260611T140410_prompt_actions_init.d.ts +17 -0
  60. package/dist/migrations/20260611T140410_prompt_actions_init.d.ts.map +1 -0
  61. package/dist/migrations/20260611T140410_prompt_actions_init.js +47 -0
  62. package/dist/migrations/20260611T140410_prompt_actions_init.js.map +1 -0
  63. package/dist/migrations/index.d.ts +27 -0
  64. package/dist/migrations/index.d.ts.map +1 -0
  65. package/dist/migrations/index.js +29 -0
  66. package/dist/migrations/index.js.map +1 -0
  67. package/docs/prompt-actions.md +117 -0
  68. package/i18n/en.json +40 -0
  69. package/i18n/pl.json +40 -0
  70. package/package.json +67 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
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,52 @@
1
- # Temporary Holding Version
1
+ <!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # @endora-commerce/mod-prompt-actions
4
+
5
+ Natural-language prompt mode for the admin command palette: interpret an operator instruction with an LLM, preview the plan, execute it through existing module services after explicit confirmation.
6
+
7
+ ## What this is
8
+
9
+ An **Endora Commerce module package**. Its module id is `prompt_actions` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
10
+
11
+ A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
12
+
13
+ ## Entry points
14
+
15
+ | Import | Contents |
16
+ | --- | --- |
17
+ | `@endora-commerce/mod-prompt-actions` | the module manifest — its id, version, dependencies, settings and activation |
18
+ | `@endora-commerce/mod-prompt-actions/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
19
+ | `@endora-commerce/mod-prompt-actions/migrations` | the module’s own schema migrations, in the order the platform runs them |
20
+
21
+ ## Depends on
22
+
23
+ Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
24
+
25
+ **Endora packages**
26
+
27
+ - `@endora-commerce/contracts`
28
+ - `@endora-commerce/platform`
29
+
30
+ **Third-party**
31
+
32
+ - `@mikro-orm/core` ^6
33
+ - `@mikro-orm/migrations` ^6
34
+ - `@mikro-orm/postgresql` ^6
35
+ - `fastify` ^5
36
+ - `zod` ^4
37
+
38
+ ## What the tarball carries
39
+
40
+ - `dist/` — the compiled JavaScript and its type declarations
41
+ - `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
42
+ - `docs/` — the package’s own pages in the Endora Commerce documentation site
43
+
44
+ ## Install
45
+
46
+ ```bash
47
+ pnpm add @endora-commerce/mod-prompt-actions
48
+ ```
49
+
50
+ ## Licence
51
+
52
+ MIT — the text is in `LICENSE`, beside this file.
@@ -0,0 +1,37 @@
1
+ import { OptionalProps } from '@mikro-orm/core';
2
+ import type { PromptActionClarification, PromptActionPlan, PromptActionResult, PromptActionStatus } from '@endora-commerce/contracts';
3
+ /**
4
+ * PromptActionRequest — feature 043 / data-model §1–§2.
5
+ *
6
+ * One operator-submitted natural-language instruction with its full
7
+ * lifecycle: interpretation output (plan or clarification), the minimal
8
+ * provider-neutral conversation retained for the single clarify round-trip,
9
+ * confirmation, execution result, and the seen-marker driving the
10
+ * "finished while you were away" notice (FR-018).
11
+ *
12
+ * No FK on `admin_user_id` (module_actions precedent — lifecycle owns
13
+ * cleanup, admin users are platform-owned).
14
+ */
15
+ export declare class PromptActionRequest {
16
+ [OptionalProps]?: 'id' | 'createdAt' | 'updatedAt' | 'language' | 'provider' | 'model' | 'plan' | 'clarification' | 'conversation' | 'result' | 'error' | 'bulkOperationId' | 'seenAt' | 'confirmedAt' | 'finishedAt';
17
+ id: string;
18
+ adminUserId: string;
19
+ prompt: string;
20
+ language: string | null;
21
+ status: PromptActionStatus;
22
+ provider: string | null;
23
+ model: string | null;
24
+ plan: PromptActionPlan | null;
25
+ clarification: PromptActionClarification | null;
26
+ /** Provider-neutral transcript retained for the clarify round-trip + diagnostics. */
27
+ conversation: unknown | null;
28
+ result: PromptActionResult | null;
29
+ error: string | null;
30
+ bulkOperationId: string | null;
31
+ seenAt: Date | null;
32
+ confirmedAt: Date | null;
33
+ finishedAt: Date | null;
34
+ createdAt: Date;
35
+ updatedAt: Date;
36
+ }
37
+ //# sourceMappingURL=prompt-action-request.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-action-request.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/prompt-action-request.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAGrF,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;GAWG;AACH,qBAGa,mBAAmB;IAC9B,CAAC,aAAa,CAAC,CAAC,EACZ,IAAI,GACJ,WAAW,GACX,WAAW,GACX,UAAU,GACV,UAAU,GACV,OAAO,GACP,MAAM,GACN,eAAe,GACf,cAAc,GACd,QAAQ,GACR,OAAO,GACP,iBAAiB,GACjB,QAAQ,GACR,aAAa,GACb,YAAY,CAAC;IAGjB,EAAE,EAAE,MAAM,CAAgB;IAG1B,WAAW,EAAG,MAAM,CAAC;IAGrB,MAAM,EAAG,MAAM,CAAC;IAGhB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,MAAM,EAAG,kBAAkB,CAAC;IAG5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG5B,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAGrC,aAAa,EAAE,yBAAyB,GAAG,IAAI,CAAQ;IAEvD,qFAAqF;IAErF,YAAY,EAAE,OAAO,GAAG,IAAI,CAAQ;IAGpC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IAGzC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGtC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAG3B,WAAW,EAAE,IAAI,GAAG,IAAI,CAAQ;IAGhC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAQ;IAG/B,SAAS,EAAE,IAAI,CAAc;IAQ7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,130 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
11
+ import { GlobalEntity } from '@endora-commerce/platform/tenancy';
12
+ import { randomUUID } from 'crypto';
13
+ /**
14
+ * PromptActionRequest — feature 043 / data-model §1–§2.
15
+ *
16
+ * One operator-submitted natural-language instruction with its full
17
+ * lifecycle: interpretation output (plan or clarification), the minimal
18
+ * provider-neutral conversation retained for the single clarify round-trip,
19
+ * confirmation, execution result, and the seen-marker driving the
20
+ * "finished while you were away" notice (FR-018).
21
+ *
22
+ * No FK on `admin_user_id` (module_actions precedent — lifecycle owns
23
+ * cleanup, admin users are platform-owned).
24
+ */
25
+ let PromptActionRequest = class PromptActionRequest {
26
+ [OptionalProps];
27
+ id = randomUUID();
28
+ adminUserId;
29
+ prompt;
30
+ language = null;
31
+ status;
32
+ provider = null;
33
+ model = null;
34
+ plan = null;
35
+ clarification = null;
36
+ /** Provider-neutral transcript retained for the clarify round-trip + diagnostics. */
37
+ conversation = null;
38
+ result = null;
39
+ error = null;
40
+ bulkOperationId = null;
41
+ seenAt = null;
42
+ confirmedAt = null;
43
+ finishedAt = null;
44
+ createdAt = new Date();
45
+ updatedAt = new Date();
46
+ };
47
+ __decorate([
48
+ PrimaryKey({ type: 'uuid' }),
49
+ __metadata("design:type", String)
50
+ ], PromptActionRequest.prototype, "id", void 0);
51
+ __decorate([
52
+ Property({ type: 'uuid', fieldName: 'admin_user_id' }),
53
+ __metadata("design:type", String)
54
+ ], PromptActionRequest.prototype, "adminUserId", void 0);
55
+ __decorate([
56
+ Property({ type: 'text' }),
57
+ __metadata("design:type", String)
58
+ ], PromptActionRequest.prototype, "prompt", void 0);
59
+ __decorate([
60
+ Property({ type: 'string', length: 12, nullable: true }),
61
+ __metadata("design:type", Object)
62
+ ], PromptActionRequest.prototype, "language", void 0);
63
+ __decorate([
64
+ Property({ type: 'string', length: 32 }),
65
+ __metadata("design:type", String)
66
+ ], PromptActionRequest.prototype, "status", void 0);
67
+ __decorate([
68
+ Property({ type: 'string', length: 32, nullable: true }),
69
+ __metadata("design:type", Object)
70
+ ], PromptActionRequest.prototype, "provider", void 0);
71
+ __decorate([
72
+ Property({ type: 'string', length: 120, nullable: true }),
73
+ __metadata("design:type", Object)
74
+ ], PromptActionRequest.prototype, "model", void 0);
75
+ __decorate([
76
+ Property({ type: 'json', nullable: true }),
77
+ __metadata("design:type", Object)
78
+ ], PromptActionRequest.prototype, "plan", void 0);
79
+ __decorate([
80
+ Property({ type: 'json', nullable: true }),
81
+ __metadata("design:type", Object)
82
+ ], PromptActionRequest.prototype, "clarification", void 0);
83
+ __decorate([
84
+ Property({ type: 'json', nullable: true }),
85
+ __metadata("design:type", Object)
86
+ ], PromptActionRequest.prototype, "conversation", void 0);
87
+ __decorate([
88
+ Property({ type: 'json', nullable: true }),
89
+ __metadata("design:type", Object)
90
+ ], PromptActionRequest.prototype, "result", void 0);
91
+ __decorate([
92
+ Property({ type: 'text', nullable: true }),
93
+ __metadata("design:type", Object)
94
+ ], PromptActionRequest.prototype, "error", void 0);
95
+ __decorate([
96
+ Property({ type: 'uuid', fieldName: 'bulk_operation_id', nullable: true }),
97
+ __metadata("design:type", Object)
98
+ ], PromptActionRequest.prototype, "bulkOperationId", void 0);
99
+ __decorate([
100
+ Property({ type: 'datetime', fieldName: 'seen_at', nullable: true }),
101
+ __metadata("design:type", Object)
102
+ ], PromptActionRequest.prototype, "seenAt", void 0);
103
+ __decorate([
104
+ Property({ type: 'datetime', fieldName: 'confirmed_at', nullable: true }),
105
+ __metadata("design:type", Object)
106
+ ], PromptActionRequest.prototype, "confirmedAt", void 0);
107
+ __decorate([
108
+ Property({ type: 'datetime', fieldName: 'finished_at', nullable: true }),
109
+ __metadata("design:type", Object)
110
+ ], PromptActionRequest.prototype, "finishedAt", void 0);
111
+ __decorate([
112
+ Property({ type: 'datetime', fieldName: 'created_at', onCreate: () => new Date() }),
113
+ __metadata("design:type", Date)
114
+ ], PromptActionRequest.prototype, "createdAt", void 0);
115
+ __decorate([
116
+ Property({
117
+ type: 'datetime',
118
+ fieldName: 'updated_at',
119
+ onCreate: () => new Date(),
120
+ onUpdate: () => new Date(),
121
+ }),
122
+ __metadata("design:type", Date)
123
+ ], PromptActionRequest.prototype, "updatedAt", void 0);
124
+ PromptActionRequest = __decorate([
125
+ GlobalEntity(),
126
+ Entity({ tableName: 'prompt_action_requests' }),
127
+ Index({ properties: ['adminUserId', 'createdAt'] })
128
+ ], PromptActionRequest);
129
+ export { PromptActionRequest };
130
+ //# sourceMappingURL=prompt-action-request.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-action-request.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/prompt-action-request.entity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { FastifyRequest } from 'fastify';
2
+ import type { EntityManager } from '@mikro-orm/postgresql';
3
+ import type { AuditPort } from '@endora-commerce/platform/kernel';
4
+ import type { ModuleContext } from '@endora-commerce/platform/kernel';
5
+ import type { RequireAdminFactory } from '@endora-commerce/platform/kernel';
6
+ import { PromptRequestService } from './services/prompt-request.service.js';
7
+ import { PromptActionToolRegistry } from './services/tool-registry.js';
8
+ import { PromptActionBulkProgressRegistry } from './services/bulk-progress-registry.js';
9
+ import { LlmProviderFactory, type CredentialResolvePort, type SettingsReadPort } from './services/llm/provider-factory.js';
10
+ import type { FetchLike } from './services/llm/provider.js';
11
+ import { PromptActionRequest } from './entities/prompt-action-request.entity.js';
12
+ /**
13
+ * `prompt_actions` — the module every other module contributes *into*
14
+ * (feature 072, wave 1).
15
+ *
16
+ * It owns no domain logic. Its whole job is to hold the tool catalogue that
17
+ * `catalog`, `inventory` and `orders` populate, hand a permission-filtered view
18
+ * of it to an LLM, and execute the confirmed plan through the contributors'
19
+ * own services. That inverts the usual direction — this module is nobody's
20
+ * dependency and everybody's dependant — so nothing here is a port. A port is
21
+ * for a name *other* modules resolve; the two names this module publishes are
22
+ * read by the composition root, which is not gated by anything.
23
+ *
24
+ * **`promptActionToolRegistry` is deliberately an ordinary registration.**
25
+ * Making it a port would mean the root gets a 503 while contributing tools if
26
+ * the operator switched the assistant off — at composition time, before the
27
+ * effective state is even loaded. Contribution has to be tolerant; it is the
28
+ * *routes* that gate, and they already do.
29
+ *
30
+ * **No `activation:` declaration, deliberately.** The module already ships
31
+ * `prompt_actions.enabled`, and it is *not* an activation control in the
32
+ * Constitution XVII sense: switching it off is supposed to leave the capability
33
+ * endpoint answering `200 {status: 'disabled'}` and submissions answering `409
34
+ * ASSISTANT_DISABLED`, which is what the admin palette reads to hide the prompt
35
+ * mode. Declaring it as the activation setting would make `ctx.routes` 503 the
36
+ * whole surface instead, including the probe the palette needs to *learn* the
37
+ * module is off. Reconciling a bespoke kill switch with the two-axis machinery
38
+ * is feature 073's problem, not this conversion's; until then the module is
39
+ * gated on the platform axis alone — which is one axis more than it had.
40
+ *
41
+ * The one behaviour change: tool visibility now resolves `effectiveState`
42
+ * rather than `registryCache.isEnabled`. See
43
+ * `test/integration/prompt_actions/deactivated-module-tools.test.ts` — the old
44
+ * seam advertised tools belonging to a module the operator had deactivated.
45
+ */
46
+ export interface PromptActionsCradle {
47
+ readonly emFactory: () => EntityManager;
48
+ readonly auditLogService: AuditPort;
49
+ readonly settingsReadPort: SettingsReadPort;
50
+ readonly settingsChannelResolver: () => Promise<string>;
51
+ readonly requireAdmin: RequireAdminFactory;
52
+ readonly adminContextResolver: (req: FastifyRequest) => {
53
+ adminUserId: string;
54
+ };
55
+ readonly permissionService: {
56
+ hasPermission(adminUserId: string, permission: string): Promise<boolean>;
57
+ };
58
+ readonly credentialsService: CredentialResolvePort;
59
+ /**
60
+ * Pushed into by `catalog` when a deployment ships it, so a delegated bulk
61
+ * request can show live progress. Absent is a supported state — the request
62
+ * simply reports no progress — which is why this module does not declare
63
+ * `catalog` as a dependency for it.
64
+ *
65
+ * D-72 point 4 — a **registry keyed by contributing module**, where it used
66
+ * to be a single name this module defaulted to `undefined` and a composition
67
+ * root overwrote with `catalog`'s resolver. That shape was the last thing
68
+ * keeping `catalog/prompt-tools.js` named in both roots: a module may not
69
+ * write a name another module owns, so `catalog` could not push a resolver
70
+ * into a slot, only into a table.
71
+ */
72
+ readonly promptActionBulkProgressRegistry: PromptActionBulkProgressRegistry;
73
+ /** Test seams; a root overrides them by re-registering the name. */
74
+ readonly promptActionsLlmFetch: FetchLike | undefined;
75
+ readonly promptActionsNow: (() => Date) | undefined;
76
+ readonly promptActionsTtlMinutes: number | undefined;
77
+ readonly promptActionToolRegistry: PromptActionToolRegistry;
78
+ readonly llmProviderFactory: LlmProviderFactory;
79
+ readonly promptRequestService: PromptRequestService;
80
+ }
81
+ export declare function registerModule(ctx: ModuleContext): void;
82
+ /**
83
+ * The module's persisted entity classes, on the `./backend` subpath, as one
84
+ * array and **no named class export** (D-168).
85
+ *
86
+ * This is the shape the platform reads when the package is *installed*: the
87
+ * boot-time loader (`src/packages/package-runtime.ts`, `exported['entities']`)
88
+ * and the static declaration reader (`scripts/lib/package-declarations.ts`),
89
+ * which is the third source of `check:module-boundary`'s `table→owner` map and
90
+ * the package pass of `check-entity-tenant-classification`. A missing array is
91
+ * answered with `[]` — zero entities registered, no error anywhere.
92
+ */
93
+ export declare const entities: (typeof PromptActionRequest)[];
94
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAK5E,OAAO,EACL,oBAAoB,EAErB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,aAAa,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,uBAAuB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,QAAQ,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF,QAAQ,CAAC,iBAAiB,EAAE;QAC1B,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC1E,CAAC;IACF,QAAQ,CAAC,kBAAkB,EAAE,qBAAqB,CAAC;IACnD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,gCAAgC,EAAE,gCAAgC,CAAC;IAC5E,oEAAoE;IACpE,QAAQ,CAAC,qBAAqB,EAAE,SAAS,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IAErD,QAAQ,CAAC,wBAAwB,EAAE,wBAAwB,CAAC;IAC5D,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAChD,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;CACrD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAqIvD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,gCAEpB,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { lazyPort } from '@endora-commerce/platform/kernel';
2
+ import { effectiveState } from '@endora-commerce/platform/kernel';
3
+ import { registerPromptActionsAdminRoutes } from './routes.admin.js';
4
+ import { InterpreterService } from './services/interpreter.service.js';
5
+ import { PlanExecutorService } from './services/plan-executor.service.js';
6
+ import { PromptRequestService, } from './services/prompt-request.service.js';
7
+ import { PromptActionToolRegistry } from './services/tool-registry.js';
8
+ import { PromptActionBulkProgressRegistry } from './services/bulk-progress-registry.js';
9
+ import { LlmProviderFactory, } from './services/llm/provider-factory.js';
10
+ import { PromptActionRequest } from './entities/prompt-action-request.entity.js';
11
+ export function registerModule(ctx) {
12
+ ctx.di.register({
13
+ // A **contribution registry**, and a plain `di.register` on purpose: it must
14
+ // stay one. `catalog`, `inventory` and `orders` push their tool descriptors
15
+ // in from `ctx.onBoot`, and boot hooks run whatever this module's effective
16
+ // state is, so a `providePort` gate here would throw `MODULE_DISABLED`
17
+ // during composition and stop the backend from starting. It would also move
18
+ // every edge into this name from `contributes` to `fails-closed` in the
19
+ // deactivation-consequence ledger, changing the sentence the operator's
20
+ // confirmation dialog renders (issue #192; port-publication.md §1.4).
21
+ promptActionToolRegistry: ctx.asFunction(() => new PromptActionToolRegistry()).singleton(),
22
+ // The second contribution registry, and an ordinary registration for the
23
+ // same reason as the first: a boot hook has to be able to push into it
24
+ // whatever the assistant's own effective state is. The presence question
25
+ // is answered at enumeration, keyed on the module recorded with each
26
+ // entry, and the probe is wired to the kernel here — the class defaults it
27
+ // to always-present so a unit test that builds its own registry keeps
28
+ // answering about the resolvers that test registered.
29
+ promptActionBulkProgressRegistry: ctx
30
+ .asFunction(() => new PromptActionBulkProgressRegistry((moduleId) => effectiveState.isPresent(moduleId)))
31
+ .singleton(),
32
+ promptActionsLlmFetch: ctx.asFunction(() => undefined).singleton(),
33
+ promptActionsNow: ctx.asFunction(() => undefined).singleton(),
34
+ promptActionsTtlMinutes: ctx.asFunction(() => undefined).singleton(),
35
+ llmProviderFactory: ctx
36
+ .asFunction(({ promptActionsLlmFetch }) => {
37
+ // `credentialsService` is a **port**, so it is resolved per call
38
+ // rather than captured. Awilix's strict mode refuses the capture
39
+ // outright — a singleton may not hold a transient — and it is right
40
+ // to: a captured port keeps answering after the operator switches
41
+ // `credentials` off, so the assistant would go on decrypting API
42
+ // keys through a module that is supposed to be absent. Resolving per
43
+ // call turns that into the 503 the port exists to produce, and only
44
+ // on the path that actually needs a secret.
45
+ const credentials = {
46
+ resolve: (configurationCode) => ctx.cradle().credentialsService.resolve(configurationCode),
47
+ };
48
+ return new LlmProviderFactory({
49
+ settings: lazyPort(ctx, 'settingsReadPort'),
50
+ // A function-valued name, so it cannot go through `lazyPort` —
51
+ // that forwards method calls on an object. The closure is the same
52
+ // deferral by hand.
53
+ resolveChannelId: () => ctx.cradle().settingsChannelResolver(),
54
+ credentials,
55
+ ...(promptActionsLlmFetch === undefined
56
+ ? {}
57
+ : { fetchImpl: promptActionsLlmFetch }),
58
+ });
59
+ })
60
+ .singleton(),
61
+ promptRequestService: ctx
62
+ .asFunction(({ emFactory, auditLogService, promptActionToolRegistry, llmProviderFactory, promptActionsNow, promptActionsTtlMinutes, }) => {
63
+ // `maxRounds` is not threaded through a container seam: the old
64
+ // options type carried one and nothing ever passed it. The property
65
+ // it guards is covered where it belongs, in the interpreter's own
66
+ // unit test, which constructs the service directly.
67
+ const interpreter = new InterpreterService({
68
+ registry: promptActionToolRegistry,
69
+ providerFactory: llmProviderFactory,
70
+ ...(promptActionsNow === undefined
71
+ ? {}
72
+ : { now: () => promptActionsNow().getTime() }),
73
+ });
74
+ const visibilityFor = (adminUserId) => ({
75
+ hasPermission: (permission) => ctx.cradle().permissionService.hasPermission(adminUserId, permission),
76
+ // Constitution XVII: presence is the conjunction of both axes. A
77
+ // module the operator deactivated must not appear in the
78
+ // catalogue, or the assistant plans work the platform refuses.
79
+ isModuleInstalled: async (moduleId) => effectiveState.isPresent(moduleId),
80
+ });
81
+ // Read through the registry per call rather than captured out of it:
82
+ // a contributor's boot hook runs after this factory may first be
83
+ // resolved, and — more to the point — an operator switching a
84
+ // contributor off has to change the answer without a restart.
85
+ const bulkProgressReader = (bulkOperationId) => ctx
86
+ .cradle()
87
+ .promptActionBulkProgressRegistry.apply(bulkOperationId);
88
+ return new PromptRequestService({
89
+ emFactory,
90
+ interpreter,
91
+ executor: new PlanExecutorService(promptActionToolRegistry),
92
+ visibilityFor,
93
+ auditLogService,
94
+ bulkProgressReader,
95
+ ...(promptActionsNow === undefined ? {} : { now: promptActionsNow }),
96
+ ...(promptActionsTtlMinutes === undefined
97
+ ? {}
98
+ : { ttlMinutes: promptActionsTtlMinutes }),
99
+ });
100
+ })
101
+ .singleton(),
102
+ });
103
+ ctx.routes(async (app) => {
104
+ const { promptRequestService, llmProviderFactory, requireAdmin, adminContextResolver } = ctx.cradle();
105
+ await registerPromptActionsAdminRoutes(app, {
106
+ requestService: promptRequestService,
107
+ providerFactory: llmProviderFactory,
108
+ requireAdmin,
109
+ resolveAdminContext: adminContextResolver,
110
+ });
111
+ });
112
+ }
113
+ /**
114
+ * The module's persisted entity classes, on the `./backend` subpath, as one
115
+ * array and **no named class export** (D-168).
116
+ *
117
+ * This is the shape the platform reads when the package is *installed*: the
118
+ * boot-time loader (`src/packages/package-runtime.ts`, `exported['entities']`)
119
+ * and the static declaration reader (`scripts/lib/package-declarations.ts`),
120
+ * which is the third source of `check:module-boundary`'s `table→owner` map and
121
+ * the package pass of `check-entity-tenant-classification`. A missing array is
122
+ * answered with `[]` — zero entities registered, no error anywhere.
123
+ */
124
+ export const entities = [
125
+ PromptActionRequest,
126
+ ];
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EACL,oBAAoB,GAErB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EACL,kBAAkB,GAGnB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAwEjF,MAAM,UAAU,cAAc,CAAC,GAAkB;IAC/C,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC;QACd,6EAA6E;QAC7E,4EAA4E;QAC5E,4EAA4E;QAC5E,uEAAuE;QACvE,4EAA4E;QAC5E,wEAAwE;QACxE,wEAAwE;QACxE,sEAAsE;QACtE,wBAAwB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,wBAAwB,EAAE,CAAC,CAAC,SAAS,EAAE;QAE1F,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,qEAAqE;QACrE,2EAA2E;QAC3E,sEAAsE;QACtE,sDAAsD;QACtD,gCAAgC,EAAE,GAAG;aAClC,UAAU,CACT,GAAG,EAAE,CACH,IAAI,gCAAgC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CACzF;aACA,SAAS,EAAE;QAEd,qBAAqB,EAAE,GAAG,CAAC,UAAU,CAAC,GAA0B,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE;QACzF,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,GAA6B,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE;QACvF,uBAAuB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAuB,EAAE,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE;QAExF,kBAAkB,EAAE,GAAG;aACpB,UAAU,CACT,CAAC,EAAE,qBAAqB,EAAuB,EAAE,EAAE;YACjD,iEAAiE;YACjE,iEAAiE;YACjE,oEAAoE;YACpE,kEAAkE;YAClE,iEAAiE;YACjE,qEAAqE;YACrE,oEAAoE;YACpE,4CAA4C;YAC5C,MAAM,WAAW,GAA0B;gBACzC,OAAO,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAC7B,GAAG,CAAC,MAAM,EAAuB,CAAC,kBAAkB,CAAC,OAAO,CAAC,iBAAiB,CAAC;aAClF,CAAC;YACF,OAAO,IAAI,kBAAkB,CAAC;gBAC5B,QAAQ,EAAE,QAAQ,CAAmB,GAAG,EAAE,kBAAkB,CAAC;gBAC7D,+DAA+D;gBAC/D,mEAAmE;gBACnE,oBAAoB;gBACpB,gBAAgB,EAAE,GAAG,EAAE,CACrB,GAAG,CAAC,MAAM,EAAuB,CAAC,uBAAuB,EAAE;gBAC7D,WAAW;gBACX,GAAG,CAAC,qBAAqB,KAAK,SAAS;oBACrC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC,CACF;aACA,SAAS,EAAE;QAEd,oBAAoB,EAAE,GAAG;aACtB,UAAU,CACT,CAAC,EACC,SAAS,EACT,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,GACH,EAAE,EAAE;YACxB,gEAAgE;YAChE,oEAAoE;YACpE,kEAAkE;YAClE,oDAAoD;YACpD,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAC;gBACzC,QAAQ,EAAE,wBAAwB;gBAClC,eAAe,EAAE,kBAAkB;gBACnC,GAAG,CAAC,gBAAgB,KAAK,SAAS;oBAChC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;aACjD,CAAC,CAAC;YAEH,MAAM,aAAa,GAA8B,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBACjE,aAAa,EAAE,CAAC,UAAU,EAAE,EAAE,CAC5B,GAAG,CAAC,MAAM,EAAuB,CAAC,iBAAiB,CAAC,aAAa,CAC/D,WAAW,EACX,UAAU,CACX;gBACH,iEAAiE;gBACjE,yDAAyD;gBACzD,+DAA+D;gBAC/D,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC;aAC1E,CAAC,CAAC;YAEH,qEAAqE;YACrE,iEAAiE;YACjE,8DAA8D;YAC9D,8DAA8D;YAC9D,MAAM,kBAAkB,GAEpB,CAAC,eAAe,EAAE,EAAE,CACtB,GAAG;iBACA,MAAM,EAAuB;iBAC7B,gCAAgC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAE7D,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,SAAS;gBACT,WAAW;gBACX,QAAQ,EAAE,IAAI,mBAAmB,CAAC,wBAAwB,CAAC;gBAC3D,aAAa;gBACb,eAAe;gBACf,kBAAkB;gBAClB,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;gBACpE,GAAG,CAAC,uBAAuB,KAAK,SAAS;oBACvC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,UAAU,EAAE,uBAAuB,EAAE,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC,CACF;aACA,SAAS,EAAE;KACf,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,oBAAoB,EAAE,GACpF,GAAG,CAAC,MAAM,EAAuB,CAAC;QACpC,MAAM,gCAAgC,CAAC,GAAG,EAAE;YAC1C,cAAc,EAAE,oBAAoB;YACpC,eAAe,EAAE,kBAAkB;YACnC,YAAY;YACZ,mBAAmB,EAAE,oBAAoB;SAC1C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,mBAAmB;CACpB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
2
+ import type { PromptRequestService } from './services/prompt-request.service.js';
3
+ import type { LlmProviderFactory } from './services/llm/provider-factory.js';
4
+ import type { RequireAdminFactory } from '@endora-commerce/platform/kernel';
5
+ /**
6
+ * Admin HTTP surface — feature 043 (contracts/prompt-actions-api.md).
7
+ *
8
+ * GET /api/v1/admin/prompt-actions/capability
9
+ * POST /api/v1/admin/prompt-actions/requests
10
+ * GET /api/v1/admin/prompt-actions/requests (?unseen=true&limit=)
11
+ * GET /api/v1/admin/prompt-actions/requests/:id
12
+ * POST /api/v1/admin/prompt-actions/requests/:id/clarify
13
+ * POST /api/v1/admin/prompt-actions/requests/:id/confirm
14
+ * POST /api/v1/admin/prompt-actions/requests/:id/cancel
15
+ * POST /api/v1/admin/prompt-actions/requests/:id/seen
16
+ *
17
+ * All routes are gated by `requireAdmin('prompt_actions:use')`; each
18
+ * planned operation is additionally re-checked against its own permission
19
+ * inside the executor (FR-007).
20
+ */
21
+ export interface PromptActionsRoutesDeps {
22
+ requestService: PromptRequestService;
23
+ providerFactory: LlmProviderFactory;
24
+ requireAdmin: RequireAdminFactory;
25
+ resolveAdminContext: (req: FastifyRequest) => {
26
+ adminUserId: string;
27
+ };
28
+ }
29
+ export declare function registerPromptActionsAdminRoutes(app: FastifyInstance, deps: PromptActionsRoutesDeps): Promise<void>;
30
+ //# sourceMappingURL=routes.admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.admin.d.ts","sourceRoot":"","sources":["../../src/backend/routes.admin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAW/D,OAAO,KAAK,EAAE,oBAAoB,EAAmB,MAAM,sCAAsC,CAAC;AAClG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,oBAAoB,CAAC;IACrC,eAAe,EAAE,kBAAkB,CAAC;IACpC,YAAY,EAAE,mBAAmB,CAAC;IAClC,mBAAmB,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAoHf"}
@@ -0,0 +1,71 @@
1
+ import { ClarifyRequestSchema, ERROR_CODES, PromptActionListQuerySchema, SubmitPromptRequestSchema, } from '@endora-commerce/contracts';
2
+ import { HttpError } from '@endora-commerce/platform/http';
3
+ import { PROMPT_ACTIONS_USE_PERMISSION } from '../manifest.js';
4
+ export async function registerPromptActionsAdminRoutes(app, deps) {
5
+ const { requestService, providerFactory, requireAdmin, resolveAdminContext } = deps;
6
+ const guard = requireAdmin(PROMPT_ACTIONS_USE_PERMISSION);
7
+ const operator = (request) => {
8
+ const { adminUserId } = resolveAdminContext(request);
9
+ const rid = request.headers['x-request-id'];
10
+ const language = request.headers['x-admin-language'];
11
+ return {
12
+ adminUserId,
13
+ language: typeof language === 'string' ? language : null,
14
+ auditCtx: {
15
+ ipAddress: request.ip ?? null,
16
+ userAgent: request.headers['user-agent'] ?? null,
17
+ requestId: typeof rid === 'string' ? rid : null,
18
+ },
19
+ };
20
+ };
21
+ const dto = (row) => ({
22
+ data: {
23
+ id: row.id,
24
+ status: row.status,
25
+ prompt: row.prompt,
26
+ plan: row.plan ?? null,
27
+ clarification: row.clarification ?? null,
28
+ result: row.result ?? null,
29
+ error: row.error ?? null,
30
+ bulkOperationId: row.bulkOperationId ?? null,
31
+ expiresAt: requestService.expiresAt(row)?.toISOString() ?? null,
32
+ seenAt: row.seenAt?.toISOString() ?? null,
33
+ createdAt: row.createdAt.toISOString(),
34
+ },
35
+ });
36
+ app.get('/api/v1/admin/prompt-actions/capability', { preHandler: guard }, async () => ({ data: await providerFactory.capability() }));
37
+ app.post('/api/v1/admin/prompt-actions/requests', { preHandler: guard }, async (request, reply) => {
38
+ const body = SubmitPromptRequestSchema.parse(request.body);
39
+ // Disabled / unconfigured assistants reject before any row is created.
40
+ const capability = await providerFactory.capability();
41
+ if (capability.status === 'disabled') {
42
+ throw new HttpError(409, ERROR_CODES.ASSISTANT_DISABLED, 'The prompt assistant is disabled on this platform.');
43
+ }
44
+ if (capability.status === 'not_configured') {
45
+ throw new HttpError(409, ERROR_CODES.ASSISTANT_NOT_CONFIGURED, 'The prompt assistant is not configured — set the provider, model and API key in Settings.');
46
+ }
47
+ const row = await requestService.submit(operator(request), body.prompt);
48
+ reply.code(201);
49
+ return dto(row);
50
+ });
51
+ app.get('/api/v1/admin/prompt-actions/requests', { preHandler: guard }, async (request) => {
52
+ const q = PromptActionListQuerySchema.parse(request.query ?? {});
53
+ const rows = q.unseen
54
+ ? await requestService.listUnseenFinished(operator(request), q.limit)
55
+ : [];
56
+ return { data: rows.map((r) => dto(r).data) };
57
+ });
58
+ app.get('/api/v1/admin/prompt-actions/requests/:id', { preHandler: guard }, async (request) => dto(await requestService.get(operator(request), request.params.id)));
59
+ app.post('/api/v1/admin/prompt-actions/requests/:id/clarify', { preHandler: guard }, async (request) => {
60
+ const body = ClarifyRequestSchema.parse(request.body);
61
+ const row = await requestService.clarify(operator(request), request.params.id, body);
62
+ return dto(row);
63
+ });
64
+ app.post('/api/v1/admin/prompt-actions/requests/:id/confirm', { preHandler: guard }, async (request) => dto(await requestService.confirm(operator(request), request.params.id)));
65
+ app.post('/api/v1/admin/prompt-actions/requests/:id/cancel', { preHandler: guard }, async (request) => dto(await requestService.cancel(operator(request), request.params.id)));
66
+ app.post('/api/v1/admin/prompt-actions/requests/:id/seen', { preHandler: guard }, async (request, reply) => {
67
+ await requestService.markSeen(operator(request), request.params.id);
68
+ reply.code(204);
69
+ });
70
+ }
71
+ //# sourceMappingURL=routes.admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.admin.js","sourceRoot":"","sources":["../../src/backend/routes.admin.ts"],"names":[],"mappings":"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"}