@opengeni/api-router 2.12.1-canary.0 → 2.12.3

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/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createOpenGeniSlackBotInteractionClient,
8
8
  startSlackInteractionPump,
9
9
  startTemporalScheduleCleanupPump
10
- } from "./chunk-Y3EPAIEQ.js";
10
+ } from "./chunk-552H26YK.js";
11
11
 
12
12
  // src/index.ts
13
13
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/api-router",
3
- "version": "2.12.1-canary.0",
3
+ "version": "2.12.3",
4
4
  "description": "OpenGeni HTTP surface: the Hono adapter/router (createApp), routes, MCP HTTP transport, and HTTP access adapters over @opengeni/core. An engine-distribution surface — its runtime closure includes engine-internal packages.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,24 +43,24 @@
43
43
  "@hono/zod-validator": "^0.7.6",
44
44
  "@llamaindex/liteparse": "2.14.2",
45
45
  "@modelcontextprotocol/sdk": "^1.29.0",
46
- "@opengeni/agent-proto": "^0.5.1-canary.24",
47
- "@opengeni/artifact-tool": "^0.3.24-canary.0",
48
- "@opengeni/capabilities": "^0.3.3-canary.6",
49
- "@opengeni/codemode": "^0.5.4-canary.0",
50
- "@opengeni/codex": "^0.2.22-canary.6",
51
- "@opengeni/config": "^1.1.0-canary.0",
52
- "@opengeni/contracts": "^3.0.0-canary.0",
53
- "@opengeni/core": "^2.9.1-canary.0",
54
- "@opengeni/db": "^4.3.0-canary.0",
55
- "@opengeni/documents": "^0.8.24-canary.0",
56
- "@opengeni/events": "^0.4.22-canary.0",
57
- "@opengeni/github": "^0.7.8-canary.0",
58
- "@opengeni/network": "^0.3.1-canary.6",
59
- "@opengeni/observability": "^0.8.24-canary.0",
60
- "@opengeni/runtime": "^2.5.1-canary.0",
61
- "@opengeni/storage": "^0.2.125-canary.0",
62
- "@opengeni/tool-gateway": "^0.1.5-canary.0",
63
- "@opengeni/xai-subscription": "^0.1.4-canary.6",
46
+ "@opengeni/agent-proto": "^0.5.1",
47
+ "@opengeni/artifact-tool": "^0.3.25",
48
+ "@opengeni/capabilities": "^0.3.3",
49
+ "@opengeni/codemode": "^0.5.5",
50
+ "@opengeni/codex": "^0.2.22",
51
+ "@opengeni/config": "^1.1.1",
52
+ "@opengeni/contracts": "^3.0.1",
53
+ "@opengeni/core": "^2.9.3",
54
+ "@opengeni/db": "^4.3.2",
55
+ "@opengeni/documents": "^0.8.26",
56
+ "@opengeni/events": "^0.4.24",
57
+ "@opengeni/github": "^0.7.9",
58
+ "@opengeni/network": "^0.3.1",
59
+ "@opengeni/observability": "^0.8.25",
60
+ "@opengeni/runtime": "^2.5.2",
61
+ "@opengeni/storage": "^0.2.126",
62
+ "@opengeni/tool-gateway": "^0.1.6",
63
+ "@opengeni/xai-subscription": "^0.1.4",
64
64
  "@temporalio/client": "^1.17.0",
65
65
  "better-auth": "^1.6.14",
66
66
  "hono": "^4.12.18",
package/src/mcp/server.ts CHANGED
@@ -15,6 +15,8 @@ import {
15
15
  } from "../site-uploads";
16
16
  import {
17
17
  CreateScheduledTaskRequest,
18
+ CreateSessionRequest,
19
+ GoalSpec,
18
20
  boundSessionMcpText as capSessionDiscoveryText,
19
21
  compactSessionMcpListRow,
20
22
  sessionMcpIncludesRelatedWork,
@@ -376,6 +378,45 @@ function orchestrationFailureCode(tool: OrchestrationToolName, error: HTTPExcept
376
378
  return `${tool}_${suffix}`.slice(0, ORCHESTRATION_FAILURE_CODE_MAX_LENGTH);
377
379
  }
378
380
 
381
+ function sessionCreateValidationFailureResult(error: z4.ZodError) {
382
+ // Only call with issues from the raw request preflight, never downstream errors.
383
+ // Paths may contain caller-controlled record keys, and custom issue messages
384
+ // may contain values. Only publish canonical field names and fixed type labels.
385
+ const details = error.issues.slice(0, 5).map((issue) => {
386
+ const [field, goalField] = issue.path;
387
+ let path =
388
+ typeof field === "string" && Object.hasOwn(CreateSessionRequest.out.shape, field)
389
+ ? field
390
+ : "request";
391
+ if (
392
+ field === "goal" &&
393
+ typeof goalField === "string" &&
394
+ Object.hasOwn(GoalSpec.shape, goalField)
395
+ ) {
396
+ path += `.${goalField}`;
397
+ }
398
+ const expected =
399
+ issue.code === "invalid_type" &&
400
+ ["string", "number", "boolean", "object", "array", "int"].includes(issue.expected)
401
+ ? `expected ${issue.expected === "int" ? "integer" : issue.expected}`
402
+ : "failed schema validation";
403
+ return `${path} ${expected}`;
404
+ });
405
+ const envelope = {
406
+ error: {
407
+ code: "session_create_invalid_request",
408
+ message: boundedOrchestrationFailureMessage(
409
+ `Invalid session create request: ${details.join("; ") || "request failed schema validation"}${error.issues.length > 5 ? "; additional fields failed validation" : ""}.`,
410
+ ),
411
+ },
412
+ };
413
+ return {
414
+ content: [{ type: "text" as const, text: JSON.stringify(envelope, null, 2) }],
415
+ structuredContent: envelope,
416
+ isError: true as const,
417
+ };
418
+ }
419
+
379
420
  function orchestrationFailureEnvelope(tool: OrchestrationToolName, error: unknown) {
380
421
  if (error instanceof SessionSpawnDeniedError) {
381
422
  const denial = sessionSpawnDenialEnvelope(error);
@@ -5102,7 +5143,7 @@ function registerWorkspaceOrchestrationTools(
5102
5143
  "Concise semantic title for the child session. Omit only when the delegated goal or initial message already provides a suitable title; OpenGeni derives a sensitive-safe bounded fallback from that text.",
5103
5144
  ),
5104
5145
  instructions: z4.string().min(1).max(SESSION_INSTRUCTIONS_MAX_CHARACTERS).optional(),
5105
- goal: z4.unknown().optional(),
5146
+ goal: GoalSpec.optional(),
5106
5147
  resources: z4
5107
5148
  .array(z4.unknown())
5108
5149
  .optional()
@@ -5211,22 +5252,28 @@ function registerWorkspaceOrchestrationTools(
5211
5252
  await authorizeFirstPartySession(deps, grant, callerSessionId, "session.child.create");
5212
5253
  }
5213
5254
  const { machineTarget, title, projectId, ...request } = args;
5255
+ const rawRequest = {
5256
+ ...request,
5257
+ ...(projectId !== undefined ? { channelId: projectId } : {}),
5258
+ ...(machineTarget
5259
+ ? {
5260
+ targetSandboxId: machineTarget.targetSandboxId,
5261
+ ...(machineTarget.workingDir !== undefined
5262
+ ? { workingDir: machineTarget.workingDir }
5263
+ : {}),
5264
+ }
5265
+ : {}),
5266
+ };
5267
+ // Keep authorization above validation and let core parse the original
5268
+ // request. Only this preflight's failures are attributable to input;
5269
+ // arbitrary downstream schema failures retain the private fallback.
5270
+ const validation = CreateSessionRequest.safeParse(rawRequest);
5271
+ if (!validation.success) return sessionCreateValidationFailureResult(validation.error);
5214
5272
  const result = await createSessionForRequestWithOutcome(
5215
5273
  deps,
5216
5274
  grant,
5217
5275
  grant.workspaceId,
5218
- {
5219
- ...request,
5220
- ...(projectId !== undefined ? { channelId: projectId } : {}),
5221
- ...(machineTarget
5222
- ? {
5223
- targetSandboxId: machineTarget.targetSandboxId,
5224
- ...(machineTarget.workingDir !== undefined
5225
- ? { workingDir: machineTarget.workingDir }
5226
- : {}),
5227
- }
5228
- : {}),
5229
- },
5276
+ rawRequest,
5230
5277
  undefined,
5231
5278
  title === undefined ? {} : { automaticTitleCandidate: title },
5232
5279
  );