veryfront 0.1.64 → 0.1.67
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/esm/deno.js +1 -1
- package/esm/src/agent/runtime/index.d.ts +1 -0
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +10 -2
- package/esm/src/channels/control-plane.d.ts +259 -0
- package/esm/src/channels/control-plane.d.ts.map +1 -0
- package/esm/src/channels/control-plane.js +212 -0
- package/esm/src/channels/invoke.d.ts +3 -40
- package/esm/src/channels/invoke.d.ts.map +1 -1
- package/esm/src/channels/invoke.js +9 -106
- package/esm/src/internal-agents/ag-ui-sse.d.ts +35 -0
- package/esm/src/internal-agents/ag-ui-sse.d.ts.map +1 -0
- package/esm/src/internal-agents/ag-ui-sse.js +263 -0
- package/esm/src/internal-agents/control-plane-auth.d.ts +20 -0
- package/esm/src/internal-agents/control-plane-auth.d.ts.map +1 -0
- package/esm/src/internal-agents/control-plane-auth.js +56 -0
- package/esm/src/internal-agents/request-body.d.ts +9 -0
- package/esm/src/internal-agents/request-body.d.ts.map +1 -0
- package/esm/src/internal-agents/request-body.js +28 -0
- package/esm/src/internal-agents/run-stream.d.ts +14 -0
- package/esm/src/internal-agents/run-stream.d.ts.map +1 -0
- package/esm/src/internal-agents/run-stream.js +259 -0
- package/esm/src/internal-agents/schema.d.ts +268 -0
- package/esm/src/internal-agents/schema.d.ts.map +1 -0
- package/esm/src/internal-agents/schema.js +71 -0
- package/esm/src/internal-agents/session-manager.d.ts +63 -0
- package/esm/src/internal-agents/session-manager.d.ts.map +1 -0
- package/esm/src/internal-agents/session-manager.js +258 -0
- package/esm/src/platform/adapters/runtime/deno/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/runtime/deno/adapter.js +4 -13
- package/esm/src/platform/compat/process.d.ts.map +1 -1
- package/esm/src/platform/compat/process.js +42 -5
- package/esm/src/server/bootstrap.js +9 -1
- package/esm/src/server/handlers/request/agent-run-cancel.handler.d.ts +11 -0
- package/esm/src/server/handlers/request/agent-run-cancel.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/agent-run-cancel.handler.js +62 -0
- package/esm/src/server/handlers/request/agent-run-resume.handler.d.ts +11 -0
- package/esm/src/server/handlers/request/agent-run-resume.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/agent-run-resume.handler.js +77 -0
- package/esm/src/server/handlers/request/agent-stream.handler.d.ts +14 -0
- package/esm/src/server/handlers/request/agent-stream.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/agent-stream.handler.js +86 -0
- package/esm/src/server/handlers/request/{channel-assistants.handler.d.ts → internal-agents-list.handler.d.ts} +4 -4
- package/esm/src/server/handlers/request/internal-agents-list.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/internal-agents-list.handler.js +73 -0
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +8 -2
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/agent/runtime/index.ts +12 -2
- package/src/src/channels/control-plane.ts +332 -0
- package/src/src/channels/invoke.ts +12 -157
- package/src/src/internal-agents/ag-ui-sse.ts +327 -0
- package/src/src/internal-agents/control-plane-auth.ts +82 -0
- package/src/src/internal-agents/request-body.ts +42 -0
- package/src/src/internal-agents/run-stream.ts +354 -0
- package/src/src/internal-agents/schema.ts +102 -0
- package/src/src/internal-agents/session-manager.ts +358 -0
- package/src/src/platform/adapters/runtime/deno/adapter.ts +9 -11
- package/src/src/platform/compat/process.ts +56 -3
- package/src/src/server/bootstrap.ts +13 -1
- package/src/src/server/handlers/request/agent-run-cancel.handler.ts +86 -0
- package/src/src/server/handlers/request/agent-run-resume.handler.ts +108 -0
- package/src/src/server/handlers/request/agent-stream.handler.ts +125 -0
- package/src/src/server/handlers/request/internal-agents-list.handler.ts +100 -0
- package/src/src/server/runtime-handler/index.ts +8 -2
- package/esm/src/server/handlers/request/channel-assistants.handler.d.ts.map +0 -1
- package/esm/src/server/handlers/request/channel-assistants.handler.js +0 -71
- package/src/src/server/handlers/request/channel-assistants.handler.ts +0 -94
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as dntShim from "../../../../_dnt.shims.js";
|
|
2
|
+
import {
|
|
3
|
+
ControlPlaneRequestError,
|
|
4
|
+
verifyControlPlaneRequest,
|
|
5
|
+
} from "../../../internal-agents/control-plane-auth.js";
|
|
6
|
+
import {
|
|
7
|
+
type AgentRunSessionManager,
|
|
8
|
+
agentRunSessionManager,
|
|
9
|
+
RunNotActiveError,
|
|
10
|
+
ToolResultConflictError,
|
|
11
|
+
ToolResultNotWaitingError,
|
|
12
|
+
} from "../../../internal-agents/session-manager.js";
|
|
13
|
+
import {
|
|
14
|
+
INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
|
|
15
|
+
InternalAgentRequestBodyTooLargeError,
|
|
16
|
+
readInternalAgentRequestBody,
|
|
17
|
+
} from "../../../internal-agents/request-body.js";
|
|
18
|
+
import { ResumeSignalSchema } from "../../../internal-agents/schema.js";
|
|
19
|
+
import { BaseHandler } from "../response/base.js";
|
|
20
|
+
import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
|
|
21
|
+
import { PRIORITY_MEDIUM_API } from "../../../utils/constants/index.js";
|
|
22
|
+
|
|
23
|
+
const RESUME_PATH_REGEX = /^\/internal\/agents\/runs\/([^/]+)\/resume$/;
|
|
24
|
+
|
|
25
|
+
function getRunId(pathname: string): string | null {
|
|
26
|
+
return RESUME_PATH_REGEX.exec(pathname)?.[1] ?? null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class AgentRunResumeHandler extends BaseHandler {
|
|
30
|
+
metadata: HandlerMetadata = {
|
|
31
|
+
name: "AgentRunResumeHandler",
|
|
32
|
+
priority: PRIORITY_MEDIUM_API as HandlerPriority,
|
|
33
|
+
patterns: [{ pattern: "/internal/agents/runs/", prefix: true, method: "POST" }],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
constructor(private readonly sessionManager: AgentRunSessionManager = agentRunSessionManager) {
|
|
37
|
+
super();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult> {
|
|
41
|
+
if (!this.shouldHandle(req, ctx)) {
|
|
42
|
+
return this.continue();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const runId = getRunId(new URL(req.url).pathname);
|
|
46
|
+
if (!runId) {
|
|
47
|
+
return this.continue();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return this.withProxyContext(ctx, async () => {
|
|
51
|
+
const builder = this.createResponseBuilder(ctx)
|
|
52
|
+
.withCORS(req, ctx.securityConfig?.cors)
|
|
53
|
+
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const rawBody = await readInternalAgentRequestBody(
|
|
57
|
+
req,
|
|
58
|
+
INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
|
|
59
|
+
);
|
|
60
|
+
await verifyControlPlaneRequest(req, ctx, rawBody, {
|
|
61
|
+
expectedSubject: runId,
|
|
62
|
+
expectedSurface: "studio",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const signal = ResumeSignalSchema.parse(JSON.parse(rawBody));
|
|
66
|
+
const outcome = this.sessionManager.submitToolResult(runId, {
|
|
67
|
+
toolCallId: signal.toolCallId,
|
|
68
|
+
result: signal.result,
|
|
69
|
+
isError: signal.isError,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return this.respond(builder.json(outcome, 200));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof InternalAgentRequestBodyTooLargeError) {
|
|
75
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (error instanceof ControlPlaneRequestError) {
|
|
79
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (error instanceof SyntaxError || (error instanceof Error && error.name === "ZodError")) {
|
|
83
|
+
return this.respond(builder.json({ error: "Invalid resume request" }, 400));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (error instanceof ToolResultConflictError) {
|
|
87
|
+
return this.respond(builder.json({ error: "TOOL_RESULT_CONFLICT" }, 409));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (error instanceof ToolResultNotWaitingError) {
|
|
91
|
+
return this.respond(builder.json({ error: "TOOL_RESULT_NOT_WAITING" }, 409));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (error instanceof RunNotActiveError) {
|
|
95
|
+
return this.respond(builder.json({ error: "RUN_NOT_ACTIVE" }, 410));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.logWarn("Internal agent run resume failed", {
|
|
99
|
+
error: error instanceof Error ? error.message : String(error),
|
|
100
|
+
runId,
|
|
101
|
+
projectId: ctx.projectId,
|
|
102
|
+
projectSlug: ctx.projectSlug,
|
|
103
|
+
});
|
|
104
|
+
return this.respond(builder.json({ error: "Internal resume failed" }, 500));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import * as dntShim from "../../../../_dnt.shims.js";
|
|
2
|
+
import type { Agent } from "../../../agent/index.js";
|
|
3
|
+
import { defaultChannelInvokeDeps } from "../../../channels/invoke.js";
|
|
4
|
+
import { type RuntimeAgentDiscoveryDeps } from "../../../channels/control-plane.js";
|
|
5
|
+
import {
|
|
6
|
+
createRuntimeAgentStreamResponse,
|
|
7
|
+
type RuntimeAgentStreamExecutionDeps,
|
|
8
|
+
} from "../../../internal-agents/run-stream.js";
|
|
9
|
+
import {
|
|
10
|
+
ControlPlaneRequestError,
|
|
11
|
+
verifyControlPlaneRequest,
|
|
12
|
+
} from "../../../internal-agents/control-plane-auth.js";
|
|
13
|
+
import {
|
|
14
|
+
INTERNAL_AGENT_STREAM_MAX_BODY_BYTES,
|
|
15
|
+
InternalAgentRequestBodyTooLargeError,
|
|
16
|
+
readInternalAgentRequestBody,
|
|
17
|
+
} from "../../../internal-agents/request-body.js";
|
|
18
|
+
import {
|
|
19
|
+
AgentRunAlreadyExistsError,
|
|
20
|
+
agentRunSessionManager,
|
|
21
|
+
} from "../../../internal-agents/session-manager.js";
|
|
22
|
+
import { RuntimeRunAgentInputSchema } from "../../../internal-agents/schema.js";
|
|
23
|
+
import { BaseHandler } from "../response/base.js";
|
|
24
|
+
import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
|
|
25
|
+
import { PRIORITY_MEDIUM_API } from "../../../utils/constants/index.js";
|
|
26
|
+
|
|
27
|
+
export interface AgentStreamHandlerDeps
|
|
28
|
+
extends RuntimeAgentDiscoveryDeps, RuntimeAgentStreamExecutionDeps {}
|
|
29
|
+
|
|
30
|
+
const defaultDeps: AgentStreamHandlerDeps = {
|
|
31
|
+
...defaultChannelInvokeDeps,
|
|
32
|
+
sessionManager: agentRunSessionManager,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function applyBuilderHeaders(target: dntShim.Response, source: dntShim.Headers): dntShim.Response {
|
|
36
|
+
const headers = new dntShim.Headers(target.headers);
|
|
37
|
+
for (const [key, value] of source.entries()) {
|
|
38
|
+
if (!headers.has(key)) {
|
|
39
|
+
headers.set(key, value);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return new dntShim.Response(target.body, {
|
|
44
|
+
status: target.status,
|
|
45
|
+
statusText: target.statusText,
|
|
46
|
+
headers,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class AgentStreamHandler extends BaseHandler {
|
|
51
|
+
metadata: HandlerMetadata = {
|
|
52
|
+
name: "AgentStreamHandler",
|
|
53
|
+
priority: PRIORITY_MEDIUM_API as HandlerPriority,
|
|
54
|
+
patterns: [{ pattern: "/internal/agents/stream", exact: true, method: "POST" }],
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
constructor(private readonly deps: AgentStreamHandlerDeps = defaultDeps) {
|
|
58
|
+
super();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult> {
|
|
62
|
+
if (!this.shouldHandle(req, ctx)) {
|
|
63
|
+
return this.continue();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return this.withProxyContext(ctx, async () => {
|
|
67
|
+
const builder = this.createResponseBuilder(ctx)
|
|
68
|
+
.withCORS(req, ctx.securityConfig?.cors)
|
|
69
|
+
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
const rawBody = await readInternalAgentRequestBody(
|
|
73
|
+
req,
|
|
74
|
+
INTERNAL_AGENT_STREAM_MAX_BODY_BYTES,
|
|
75
|
+
);
|
|
76
|
+
const payload = RuntimeRunAgentInputSchema.parse(JSON.parse(rawBody));
|
|
77
|
+
await verifyControlPlaneRequest(req, ctx, rawBody, {
|
|
78
|
+
expectedSubject: payload.runId,
|
|
79
|
+
expectedSurface: "studio",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
await this.deps.ensureProjectDiscovery(ctx);
|
|
83
|
+
|
|
84
|
+
const agent = this.deps.getAgent(payload.agentId);
|
|
85
|
+
if (!agent) {
|
|
86
|
+
return this.respond(builder.json({ error: "Agent not found" }, 404));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const response = await createRuntimeAgentStreamResponse(payload, agent as Agent, this.deps);
|
|
90
|
+
return this.respond(applyBuilderHeaders(response, builder.headers));
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error instanceof InternalAgentRequestBodyTooLargeError) {
|
|
93
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (error instanceof ControlPlaneRequestError) {
|
|
97
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (error instanceof SyntaxError) {
|
|
101
|
+
return this.respond(
|
|
102
|
+
builder.json({ error: "Invalid internal agent stream request" }, 400),
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (error instanceof AgentRunAlreadyExistsError) {
|
|
107
|
+
return this.respond(builder.json({ error: error.message }, 409));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (error instanceof Error && error.name === "ZodError") {
|
|
111
|
+
return this.respond(
|
|
112
|
+
builder.json({ error: "Invalid internal agent stream request" }, 400),
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.logWarn("Internal agent stream request failed", {
|
|
117
|
+
error: error instanceof Error ? error.message : String(error),
|
|
118
|
+
projectId: ctx.projectId,
|
|
119
|
+
projectSlug: ctx.projectSlug,
|
|
120
|
+
});
|
|
121
|
+
return this.respond(builder.json({ error: "Internal agent stream failed" }, 500));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as dntShim from "../../../../_dnt.shims.js";
|
|
2
|
+
import { BaseHandler } from "../response/base.js";
|
|
3
|
+
import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
|
|
4
|
+
import {
|
|
5
|
+
type ControlPlaneAgentsListRequest,
|
|
6
|
+
ControlPlaneAgentsListRequestSchema,
|
|
7
|
+
listRuntimeAgents,
|
|
8
|
+
type RuntimeAgentDiscoveryDeps,
|
|
9
|
+
} from "../../../channels/control-plane.js";
|
|
10
|
+
import { defaultChannelInvokeDeps } from "../../../channels/invoke.js";
|
|
11
|
+
import {
|
|
12
|
+
ControlPlaneRequestError,
|
|
13
|
+
verifyControlPlaneRequest,
|
|
14
|
+
} from "../../../internal-agents/control-plane-auth.js";
|
|
15
|
+
import {
|
|
16
|
+
INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
|
|
17
|
+
InternalAgentRequestBodyTooLargeError,
|
|
18
|
+
readInternalAgentRequestBody,
|
|
19
|
+
} from "../../../internal-agents/request-body.js";
|
|
20
|
+
import { PRIORITY_MEDIUM_API } from "../../../utils/constants/index.js";
|
|
21
|
+
import { ZodError } from "zod";
|
|
22
|
+
|
|
23
|
+
export class InternalAgentsListHandler extends BaseHandler {
|
|
24
|
+
metadata: HandlerMetadata = {
|
|
25
|
+
name: "InternalAgentsListHandler",
|
|
26
|
+
priority: PRIORITY_MEDIUM_API as HandlerPriority,
|
|
27
|
+
patterns: [{ pattern: "/internal/agents/list", exact: true, method: "POST" }],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
constructor(private readonly deps: RuntimeAgentDiscoveryDeps = defaultChannelInvokeDeps) {
|
|
31
|
+
super();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult> {
|
|
35
|
+
if (!this.shouldHandle(req, ctx)) {
|
|
36
|
+
return this.continue();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return this.withProxyContext(ctx, async () => {
|
|
40
|
+
const builder = this.createResponseBuilder(ctx)
|
|
41
|
+
.withCORS(req, ctx.securityConfig?.cors)
|
|
42
|
+
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const rawBody = await readInternalAgentRequestBody(
|
|
46
|
+
req,
|
|
47
|
+
INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
|
|
48
|
+
);
|
|
49
|
+
const payload: ControlPlaneAgentsListRequest = ControlPlaneAgentsListRequestSchema.parse(
|
|
50
|
+
JSON.parse(rawBody),
|
|
51
|
+
);
|
|
52
|
+
const claims = await verifyControlPlaneRequest(req, ctx, rawBody, {
|
|
53
|
+
expectedSubject: payload.requestId,
|
|
54
|
+
expectedSurface: payload.surface,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (
|
|
58
|
+
payload.projectId !== claims.project_id ||
|
|
59
|
+
(ctx.projectId !== undefined && payload.projectId !== ctx.projectId)
|
|
60
|
+
) {
|
|
61
|
+
this.logWarn("Internal agents list request body did not match signed claims", {
|
|
62
|
+
projectSlug: ctx.projectSlug,
|
|
63
|
+
projectId: ctx.projectId,
|
|
64
|
+
requestId: payload.requestId,
|
|
65
|
+
signedRequestId: claims.sub,
|
|
66
|
+
surface: payload.surface,
|
|
67
|
+
signedSurface: claims.surface,
|
|
68
|
+
});
|
|
69
|
+
return this.respond(builder.json({ error: "Invalid control-plane signature" }, 401));
|
|
70
|
+
}
|
|
71
|
+
const response = await listRuntimeAgents(ctx, this.deps);
|
|
72
|
+
return this.respond(builder.json(response, 200));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof InternalAgentRequestBodyTooLargeError) {
|
|
75
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (error instanceof ControlPlaneRequestError) {
|
|
79
|
+
this.logWarn("Internal agents list signature verification failed", {
|
|
80
|
+
error: error.message,
|
|
81
|
+
projectSlug: ctx.projectSlug,
|
|
82
|
+
projectId: ctx.projectId,
|
|
83
|
+
});
|
|
84
|
+
return this.respond(builder.json({ error: error.message }, error.status));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (error instanceof SyntaxError || error instanceof ZodError) {
|
|
88
|
+
this.logWarn("Internal agents list request validation failed", {
|
|
89
|
+
error: error instanceof Error ? error.message : String(error),
|
|
90
|
+
projectSlug: ctx.projectSlug,
|
|
91
|
+
projectId: ctx.projectId,
|
|
92
|
+
});
|
|
93
|
+
return this.respond(builder.json({ error: "Invalid internal agents request" }, 400));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -53,7 +53,10 @@ import { HMRHandler } from "../handlers/preview/hmr.handler.js";
|
|
|
53
53
|
import { MarkdownPreviewHandler } from "../handlers/preview/markdown-preview.handler.js";
|
|
54
54
|
import { OpenAPIHandler } from "../handlers/request/openapi.handler.js";
|
|
55
55
|
import { OpenAPIDocsHandler } from "../handlers/request/openapi-docs.handler.js";
|
|
56
|
-
import {
|
|
56
|
+
import { InternalAgentsListHandler } from "../handlers/request/internal-agents-list.handler.js";
|
|
57
|
+
import { AgentStreamHandler } from "../handlers/request/agent-stream.handler.js";
|
|
58
|
+
import { AgentRunResumeHandler } from "../handlers/request/agent-run-resume.handler.js";
|
|
59
|
+
import { AgentRunCancelHandler } from "../handlers/request/agent-run-cancel.handler.js";
|
|
57
60
|
import { ChannelInvokeHandler } from "../handlers/request/channel-invoke.handler.js";
|
|
58
61
|
import { DevDashboardHandler } from "../handlers/dev/dashboard/index.js";
|
|
59
62
|
import { ProjectsHandler } from "../handlers/dev/projects/index.js";
|
|
@@ -206,7 +209,10 @@ export function createVeryfrontHandler(
|
|
|
206
209
|
new DebugContextHandler(),
|
|
207
210
|
new OpenAPIHandler(),
|
|
208
211
|
new OpenAPIDocsHandler(),
|
|
209
|
-
new
|
|
212
|
+
new InternalAgentsListHandler(),
|
|
213
|
+
new AgentStreamHandler(),
|
|
214
|
+
new AgentRunResumeHandler(),
|
|
215
|
+
new AgentRunCancelHandler(),
|
|
210
216
|
new ChannelInvokeHandler(),
|
|
211
217
|
new DevDashboardHandler(),
|
|
212
218
|
new ProjectsHandler(),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"channel-assistants.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/channel-assistants.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAEL,KAAK,iBAAiB,EAIvB,MAAM,6BAA6B,CAAC;AASrC,qBAAa,wBAAyB,SAAQ,WAAW;IAO3C,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,QAAQ,EAAE,eAAe,CAIvB;gBAE2B,IAAI,GAAE,iBAA4C;IAIzE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAgEhF"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { BaseHandler } from "../response/base.js";
|
|
2
|
-
import { ChannelAssistantsRequestSchema, defaultChannelInvokeDeps, listChannelAssistants, verifyDispatchJws, } from "../../../channels/invoke.js";
|
|
3
|
-
import { HTTP_INTERNAL_SERVER_ERROR, PRIORITY_MEDIUM_API, } from "../../../utils/constants/index.js";
|
|
4
|
-
const DISPATCH_JWS_HEADER = "x-veryfront-dispatch-jws";
|
|
5
|
-
const MAX_DISPATCH_SIGNATURE_AGE_SECONDS = 60;
|
|
6
|
-
export class ChannelAssistantsHandler extends BaseHandler {
|
|
7
|
-
deps;
|
|
8
|
-
metadata = {
|
|
9
|
-
name: "ChannelAssistantsHandler",
|
|
10
|
-
priority: PRIORITY_MEDIUM_API,
|
|
11
|
-
patterns: [{ pattern: "/channels/assistants", exact: true, method: "POST" }],
|
|
12
|
-
};
|
|
13
|
-
constructor(deps = defaultChannelInvokeDeps) {
|
|
14
|
-
super();
|
|
15
|
-
this.deps = deps;
|
|
16
|
-
}
|
|
17
|
-
async handle(req, ctx) {
|
|
18
|
-
if (!this.shouldHandle(req, ctx)) {
|
|
19
|
-
return this.continue();
|
|
20
|
-
}
|
|
21
|
-
return this.withProxyContext(ctx, async () => {
|
|
22
|
-
const builder = this.createResponseBuilder(ctx)
|
|
23
|
-
.withCORS(req, ctx.securityConfig?.cors)
|
|
24
|
-
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
25
|
-
const publicKeyPem = ctx.adapter.env.get("CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY");
|
|
26
|
-
if (!publicKeyPem) {
|
|
27
|
-
this.logWarn("Missing CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY for channel assistants endpoint");
|
|
28
|
-
return this.respond(builder.json({ error: "Channel dispatch verification is not configured" }, HTTP_INTERNAL_SERVER_ERROR));
|
|
29
|
-
}
|
|
30
|
-
const projectSlug = ctx.projectSlug;
|
|
31
|
-
if (!projectSlug) {
|
|
32
|
-
this.logWarn("Channel assistants request arrived without resolved project slug");
|
|
33
|
-
return this.respond(builder.json({ error: "Project context is unavailable" }, 400));
|
|
34
|
-
}
|
|
35
|
-
const dispatchJws = req.headers.get(DISPATCH_JWS_HEADER);
|
|
36
|
-
if (!dispatchJws) {
|
|
37
|
-
return this.respond(builder.json({ error: "Missing dispatch signature" }, 401));
|
|
38
|
-
}
|
|
39
|
-
const rawBody = await req.text();
|
|
40
|
-
try {
|
|
41
|
-
await verifyDispatchJws(dispatchJws, rawBody, {
|
|
42
|
-
audience: projectSlug,
|
|
43
|
-
expectedProjectId: ctx.projectId,
|
|
44
|
-
publicKeyPem,
|
|
45
|
-
maxAgeSeconds: MAX_DISPATCH_SIGNATURE_AGE_SECONDS,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
this.logWarn("Channel assistants signature verification failed", {
|
|
50
|
-
error: error instanceof Error ? error.message : String(error),
|
|
51
|
-
projectSlug,
|
|
52
|
-
projectId: ctx.projectId,
|
|
53
|
-
});
|
|
54
|
-
return this.respond(builder.json({ error: "Invalid dispatch signature" }, 401));
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
ChannelAssistantsRequestSchema.parse(JSON.parse(rawBody));
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
this.logWarn("Channel assistants request validation failed", {
|
|
61
|
-
error: error instanceof Error ? error.message : String(error),
|
|
62
|
-
projectSlug,
|
|
63
|
-
projectId: ctx.projectId,
|
|
64
|
-
});
|
|
65
|
-
return this.respond(builder.json({ error: "Invalid channel assistants request" }, 400));
|
|
66
|
-
}
|
|
67
|
-
const response = await listChannelAssistants(ctx, this.deps);
|
|
68
|
-
return this.respond(builder.json(response, 200));
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import * as dntShim from "../../../../_dnt.shims.js";
|
|
2
|
-
import { BaseHandler } from "../response/base.js";
|
|
3
|
-
import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
|
|
4
|
-
import {
|
|
5
|
-
ChannelAssistantsRequestSchema,
|
|
6
|
-
type ChannelInvokeDeps,
|
|
7
|
-
defaultChannelInvokeDeps,
|
|
8
|
-
listChannelAssistants,
|
|
9
|
-
verifyDispatchJws,
|
|
10
|
-
} from "../../../channels/invoke.js";
|
|
11
|
-
import {
|
|
12
|
-
HTTP_INTERNAL_SERVER_ERROR,
|
|
13
|
-
PRIORITY_MEDIUM_API,
|
|
14
|
-
} from "../../../utils/constants/index.js";
|
|
15
|
-
|
|
16
|
-
const DISPATCH_JWS_HEADER = "x-veryfront-dispatch-jws";
|
|
17
|
-
const MAX_DISPATCH_SIGNATURE_AGE_SECONDS = 60;
|
|
18
|
-
|
|
19
|
-
export class ChannelAssistantsHandler extends BaseHandler {
|
|
20
|
-
metadata: HandlerMetadata = {
|
|
21
|
-
name: "ChannelAssistantsHandler",
|
|
22
|
-
priority: PRIORITY_MEDIUM_API as HandlerPriority,
|
|
23
|
-
patterns: [{ pattern: "/channels/assistants", exact: true, method: "POST" }],
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
constructor(private readonly deps: ChannelInvokeDeps = defaultChannelInvokeDeps) {
|
|
27
|
-
super();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult> {
|
|
31
|
-
if (!this.shouldHandle(req, ctx)) {
|
|
32
|
-
return this.continue();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return this.withProxyContext(ctx, async () => {
|
|
36
|
-
const builder = this.createResponseBuilder(ctx)
|
|
37
|
-
.withCORS(req, ctx.securityConfig?.cors)
|
|
38
|
-
.withSecurity(ctx.securityConfig ?? undefined, req);
|
|
39
|
-
|
|
40
|
-
const publicKeyPem = ctx.adapter.env.get("CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY");
|
|
41
|
-
if (!publicKeyPem) {
|
|
42
|
-
this.logWarn("Missing CHANNEL_DISPATCH_SIGNING_PUBLIC_KEY for channel assistants endpoint");
|
|
43
|
-
return this.respond(
|
|
44
|
-
builder.json(
|
|
45
|
-
{ error: "Channel dispatch verification is not configured" },
|
|
46
|
-
HTTP_INTERNAL_SERVER_ERROR,
|
|
47
|
-
),
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const projectSlug = ctx.projectSlug;
|
|
52
|
-
if (!projectSlug) {
|
|
53
|
-
this.logWarn("Channel assistants request arrived without resolved project slug");
|
|
54
|
-
return this.respond(builder.json({ error: "Project context is unavailable" }, 400));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const dispatchJws = req.headers.get(DISPATCH_JWS_HEADER);
|
|
58
|
-
if (!dispatchJws) {
|
|
59
|
-
return this.respond(builder.json({ error: "Missing dispatch signature" }, 401));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const rawBody = await req.text();
|
|
63
|
-
try {
|
|
64
|
-
await verifyDispatchJws(dispatchJws, rawBody, {
|
|
65
|
-
audience: projectSlug,
|
|
66
|
-
expectedProjectId: ctx.projectId,
|
|
67
|
-
publicKeyPem,
|
|
68
|
-
maxAgeSeconds: MAX_DISPATCH_SIGNATURE_AGE_SECONDS,
|
|
69
|
-
});
|
|
70
|
-
} catch (error) {
|
|
71
|
-
this.logWarn("Channel assistants signature verification failed", {
|
|
72
|
-
error: error instanceof Error ? error.message : String(error),
|
|
73
|
-
projectSlug,
|
|
74
|
-
projectId: ctx.projectId,
|
|
75
|
-
});
|
|
76
|
-
return this.respond(builder.json({ error: "Invalid dispatch signature" }, 401));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
ChannelAssistantsRequestSchema.parse(JSON.parse(rawBody));
|
|
81
|
-
} catch (error) {
|
|
82
|
-
this.logWarn("Channel assistants request validation failed", {
|
|
83
|
-
error: error instanceof Error ? error.message : String(error),
|
|
84
|
-
projectSlug,
|
|
85
|
-
projectId: ctx.projectId,
|
|
86
|
-
});
|
|
87
|
-
return this.respond(builder.json({ error: "Invalid channel assistants request" }, 400));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const response = await listChannelAssistants(ctx, this.deps);
|
|
91
|
-
return this.respond(builder.json(response, 200));
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|