@arnilo/prism-server 0.0.5 → 0.0.7
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 +7 -1
- package/README.md +1 -1
- package/dist/handler.js +56 -3
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +8 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [0.0.7] - 2026-07-19
|
|
4
|
+
|
|
5
|
+
- Explicit `agentRuns` lifecycle capabilities expose bounded redacted durable agent status/resume routes through core CAS/fingerprint checks; no lifecycle route is enabled by default.
|
|
6
|
+
|
|
7
|
+
## [0.0.6] - 2026-07-19
|
|
8
|
+
|
|
9
|
+
- Workflow cancellation now forwards the registered revised definition and exact authorized ownership for pre-abort hash/owner verification.
|
|
4
10
|
|
|
5
11
|
## [0.0.5] - 2026-07-16
|
|
6
12
|
|
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ const response = await handler(new Request("https://api.example.test/prism/agent
|
|
|
24
24
|
}));
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Routes: direct/SSE agent run, direct/SSE workflow run, durable workflow enqueue/status/cancel/resume/replay, and optional ownership-scoped schedule create/list/pause/resume/trigger/delete. All bodies, responses, events, queues, concurrency, and timeouts are bounded.
|
|
27
|
+
Routes: direct/SSE agent run, explicitly selected durable agent status/resume through `agentRuns`, direct/SSE workflow run, durable workflow enqueue/status/cancel/resume/replay, and optional ownership-scoped schedule create/list/pause/resume/trigger/delete. `agentRuns` uses core `createAgentRunLifecycle()`; no lifecycle route exists by default. All bodies, responses, events, queues, concurrency, and timeouts are bounded.
|
|
28
28
|
|
|
29
29
|
Nothing is exposed by default. Authorization is required; ownership comes only from its result. No listener, framework, auth provider, user database, credential discovery, or hidden package activation ships.
|
|
30
30
|
|
package/dist/handler.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AgentRunStateError } from "@arnilo/prism";
|
|
1
2
|
import { cancelWorkflowRun, createWorkflowEventBus, enqueueWorkflow, getWorkflowRun, replayWorkflow, resumeWorkflow, runWorkflow, } from "@arnilo/prism-workflows";
|
|
2
3
|
import { resolvePrismServerLimits } from "./limits.js";
|
|
3
4
|
import { PrismServerError } from "./types.js";
|
|
@@ -93,6 +94,38 @@ export function createPrismHandler(options) {
|
|
|
93
94
|
owned.dispose();
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
if (route.kind === "agent-status" || route.kind === "agent-resume") {
|
|
98
|
+
const exposure = options.agentRuns?.[route.capabilityId];
|
|
99
|
+
if (!exposure)
|
|
100
|
+
throw new PrismServerError("Not found", 404, "ERR_PRISM_SERVER_NOT_FOUND");
|
|
101
|
+
if (route.kind === "agent-status") {
|
|
102
|
+
const owned = ownedSignal(request, limits.requestTimeoutMs, options.disconnectAborts ?? true);
|
|
103
|
+
try {
|
|
104
|
+
return respond(json(await awaitWithSignal(exposure.lifecycle.status({ runId: route.runId }, {
|
|
105
|
+
ownership: authorization.ownership,
|
|
106
|
+
signal: owned.signal,
|
|
107
|
+
agentId: route.capabilityId,
|
|
108
|
+
}), owned.signal), 200, limits, options));
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
owned.dispose();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
acquire();
|
|
115
|
+
const owned = ownedSignal(request, limits.requestTimeoutMs, options.disconnectAborts ?? true);
|
|
116
|
+
try {
|
|
117
|
+
const body = await readJsonObject(request, limits.maxRequestBytes, owned.signal);
|
|
118
|
+
return respond(json(await awaitWithSignal(exposure.lifecycle.resume({ runId: route.runId }, readAgentResume(body), {
|
|
119
|
+
ownership: authorization.ownership,
|
|
120
|
+
signal: owned.signal,
|
|
121
|
+
agentId: route.capabilityId,
|
|
122
|
+
}), owned.signal), 200, limits, options));
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
owned.dispose();
|
|
126
|
+
release();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
96
129
|
if (route.kind === "agent-run" || route.kind === "agent-stream") {
|
|
97
130
|
const exposure = options.agents?.[route.capabilityId];
|
|
98
131
|
if (!exposure)
|
|
@@ -197,6 +230,7 @@ export function createPrismHandler(options) {
|
|
|
197
230
|
const result = await awaitWithSignal(cancelWorkflowRun({
|
|
198
231
|
workflowId: exposure.definition.id,
|
|
199
232
|
runId: route.runId,
|
|
233
|
+
workflow: exposure.definition,
|
|
200
234
|
checkpoints: exposure.checkpoints,
|
|
201
235
|
ownership: authorization.ownership,
|
|
202
236
|
signal: owned.signal,
|
|
@@ -321,6 +355,12 @@ function parseRoute(request, base) {
|
|
|
321
355
|
if (group === "agents" && segment === "stream" && parts.length === 3 && request.method === "POST") {
|
|
322
356
|
return { kind: "agent-stream", operation: "agent.stream", capabilityId: id };
|
|
323
357
|
}
|
|
358
|
+
if (group === "agents" && segment === "runs" && runId && validId(runId)) {
|
|
359
|
+
if (parts.length === 4 && request.method === "GET")
|
|
360
|
+
return { kind: "agent-status", operation: "agent.status", capabilityId: id, runId };
|
|
361
|
+
if (parts.length === 5 && action === "resume" && request.method === "POST")
|
|
362
|
+
return { kind: "agent-resume", operation: "agent.resume", capabilityId: id, runId };
|
|
363
|
+
}
|
|
324
364
|
if (group !== "workflows")
|
|
325
365
|
return undefined;
|
|
326
366
|
if (segment === "runs" && parts.length === 3 && request.method === "POST") {
|
|
@@ -458,6 +498,18 @@ function isMessage(value) {
|
|
|
458
498
|
const item = value;
|
|
459
499
|
return ["system", "user", "assistant", "tool"].includes(String(item.role)) && Array.isArray(item.content);
|
|
460
500
|
}
|
|
501
|
+
function readAgentResume(body) {
|
|
502
|
+
if (Object.keys(body).some((key) => key !== "decision" && key !== "expectedVersion")) {
|
|
503
|
+
throw new PrismServerError("Invalid agent resume body", 400, "ERR_PRISM_SERVER_RESUME");
|
|
504
|
+
}
|
|
505
|
+
if (body.decision !== "approve" && body.decision !== "deny") {
|
|
506
|
+
throw new PrismServerError("decision must be approve or deny", 400, "ERR_PRISM_SERVER_RESUME");
|
|
507
|
+
}
|
|
508
|
+
if (!Number.isSafeInteger(body.expectedVersion) || Number(body.expectedVersion) < 1) {
|
|
509
|
+
throw new PrismServerError("expectedVersion must be a positive safe integer", 400, "ERR_PRISM_SERVER_RESUME");
|
|
510
|
+
}
|
|
511
|
+
return { decision: body.decision, expectedVersion: Number(body.expectedVersion) };
|
|
512
|
+
}
|
|
461
513
|
function readResume(body) {
|
|
462
514
|
if (body.decision !== "approve" && body.decision !== "deny") {
|
|
463
515
|
throw new PrismServerError("decision must be approve or deny", 400, "ERR_PRISM_SERVER_RESUME");
|
|
@@ -636,9 +688,10 @@ function errorResponse(error, limits, options) {
|
|
|
636
688
|
? { status: 409, code: workflowCode, message: "Workflow checkpoint operation rejected" }
|
|
637
689
|
: undefined;
|
|
638
690
|
const known = error instanceof PrismServerError;
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const
|
|
691
|
+
const agentState = error instanceof AgentRunStateError;
|
|
692
|
+
const status = mapped?.status ?? (agentState ? 404 : known ? error.status : error instanceof DOMException && error.name === "AbortError" ? 499 : 500);
|
|
693
|
+
const code = mapped?.code ?? (agentState ? "ERR_PRISM_SERVER_NOT_FOUND" : known ? error.code : status === 499 ? "ERR_PRISM_SERVER_ABORTED" : "ERR_PRISM_SERVER_INTERNAL");
|
|
694
|
+
const message = mapped?.message ?? (agentState ? "Not found" : known ? error.message : status === 499 ? "Request aborted" : "Internal server error");
|
|
642
695
|
try {
|
|
643
696
|
return json({ error: { code, message } }, status, limits, options);
|
|
644
697
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createPrismHandler } from "./handler.js";
|
|
2
2
|
export { DEFAULT_MAX_REQUEST_BYTES, HARD_MAX_REQUEST_BYTES, DEFAULT_MAX_RESPONSE_BYTES, HARD_MAX_RESPONSE_BYTES, DEFAULT_MAX_EVENT_BYTES, HARD_MAX_EVENT_BYTES, DEFAULT_MAX_STREAM_BYTES, HARD_MAX_STREAM_BYTES, DEFAULT_MAX_STREAM_EVENTS, HARD_MAX_STREAM_EVENTS, DEFAULT_MAX_CONCURRENT_RUNS, HARD_MAX_CONCURRENT_RUNS, DEFAULT_MAX_QUEUED_EVENTS, HARD_MAX_QUEUED_EVENTS, DEFAULT_REQUEST_TIMEOUT_MS, HARD_REQUEST_TIMEOUT_MS, resolvePrismServerLimits, } from "./limits.js";
|
|
3
3
|
export type { PrismServerLimits, ResolvedPrismServerLimits, } from "./limits.js";
|
|
4
|
-
export type { PrismServerOperation, PrismServerAuthorization, PrismServerAuthorizationInput, PrismServerAuthorizer, PrismAgentExposure, PrismWorkflowExposure, PrismScheduleExposure, CreatePrismHandlerOptions, PrismRequestHandler, } from "./types.js";
|
|
4
|
+
export type { PrismServerOperation, PrismServerAuthorization, PrismServerAuthorizationInput, PrismServerAuthorizer, PrismAgentExposure, PrismAgentRunExposure, PrismWorkflowExposure, PrismScheduleExposure, CreatePrismHandlerOptions, PrismRequestHandler, } from "./types.js";
|
|
5
5
|
export { PrismServerError } from "./types.js";
|
|
6
6
|
export declare const packageName = "@arnilo/prism-server";
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Agent, AgentSession, OwnershipScope, RunOptions, SecretRedactor } from "@arnilo/prism";
|
|
1
|
+
import type { Agent, AgentRunLifecycle, AgentSession, OwnershipScope, RunOptions, SecretRedactor } from "@arnilo/prism";
|
|
2
2
|
import type { RunWorkflowOptions, WorkflowCheckpointAdapter, WorkflowDefinition, WorkflowSchedules } from "@arnilo/prism-workflows";
|
|
3
3
|
import type { PrismServerLimits } from "./limits.js";
|
|
4
|
-
export type PrismServerOperation = "agent.run" | "agent.stream" | "workflow.run" | "workflow.stream" | "workflow.status" | "workflow.cancel" | "workflow.resume" | "workflow.enqueue" | "workflow.replay" | "schedule.create" | "schedule.list" | "schedule.pause" | "schedule.resume" | "schedule.trigger" | "schedule.delete";
|
|
4
|
+
export type PrismServerOperation = "agent.run" | "agent.stream" | "agent.status" | "agent.resume" | "workflow.run" | "workflow.stream" | "workflow.status" | "workflow.cancel" | "workflow.resume" | "workflow.enqueue" | "workflow.replay" | "schedule.create" | "schedule.list" | "schedule.pause" | "schedule.resume" | "schedule.trigger" | "schedule.delete";
|
|
5
5
|
export interface PrismServerAuthorization {
|
|
6
6
|
readonly ownership: OwnershipScope;
|
|
7
7
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
@@ -17,6 +17,10 @@ export interface PrismAgentExposure {
|
|
|
17
17
|
readonly sessionFactory: (authorization: PrismServerAuthorization) => AgentSession | Promise<AgentSession>;
|
|
18
18
|
readonly runOptions?: Omit<RunOptions, "ownership" | "signal" | "redactor">;
|
|
19
19
|
}
|
|
20
|
+
/** Explicit durable status/resume capability. Omit it to expose no agent lifecycle routes. */
|
|
21
|
+
export interface PrismAgentRunExposure {
|
|
22
|
+
readonly lifecycle: AgentRunLifecycle;
|
|
23
|
+
}
|
|
20
24
|
export interface PrismWorkflowExposure {
|
|
21
25
|
readonly definition: WorkflowDefinition;
|
|
22
26
|
readonly checkpoints: WorkflowCheckpointAdapter;
|
|
@@ -25,6 +29,8 @@ export interface PrismWorkflowExposure {
|
|
|
25
29
|
export type PrismScheduleExposure = WorkflowSchedules | ((authorization: PrismServerAuthorization, signal: AbortSignal) => WorkflowSchedules | Promise<WorkflowSchedules>);
|
|
26
30
|
export interface CreatePrismHandlerOptions {
|
|
27
31
|
readonly agents?: Readonly<Record<string, Agent | PrismAgentExposure>>;
|
|
32
|
+
/** Durable agent lifecycle capabilities, separate from direct agent run exposure. */
|
|
33
|
+
readonly agentRuns?: Readonly<Record<string, PrismAgentRunExposure>>;
|
|
28
34
|
readonly workflows?: Readonly<Record<string, PrismWorkflowExposure>>;
|
|
29
35
|
readonly schedules?: PrismScheduleExposure;
|
|
30
36
|
readonly authorize: PrismServerAuthorizer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Optional framework-free Web Request-to-Response handler for explicitly selected Prism agents and workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"pack:dry-run": "npm pack --dry-run"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@arnilo/prism": "0.0.
|
|
29
|
-
"@arnilo/prism-workflows": "0.0.
|
|
28
|
+
"@arnilo/prism": "0.0.7",
|
|
29
|
+
"@arnilo/prism-workflows": "0.0.7"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@arnilo/prism": "file:../..",
|