@personaai/runtime 0.7.1 → 0.8.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.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChatMessageInput, LogLevel, Logger } from '@personaai/sdk';
1
+ import { ChatMessageInput, CreateRestToolInput, LogLevel, Logger } from '@personaai/sdk';
2
2
 
3
3
  type RuntimeMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
4
4
  /** A single uploaded file — present on `RuntimeRequest.file` for a multipart `POST /files`. */
@@ -148,6 +148,13 @@ interface RuntimeHooks {
148
148
  onVoiceSessionCreate?(ctx: VoiceSessionCreateContext): void | Promise<void>;
149
149
  }
150
150
 
151
+ /**
152
+ * One REST tool definition served by the manifest route — identical to
153
+ * `CreateRestToolInput` from `@personaai/sdk@^0.7.0` (also `defineRestTool`'s
154
+ * return type from `@personaai/sdk/rest-tools`), aliased under this name for
155
+ * clarity at the call site (`createRuntime({ restToolsManifest: { tools } })`).
156
+ */
157
+ type RestToolManifestEntry = CreateRestToolInput;
151
158
  /**
152
159
  * The single point of contact between the host's auth world and the
153
160
  * runtime's world. Receives the inbound request (with `userId: null`) and
@@ -186,6 +193,27 @@ interface RuntimeCapabilities {
186
193
  /** The Architect co-pilot — builds/edits Agents on the caller's behalf via tool calls. @default false */
187
194
  architect?: boolean;
188
195
  }
196
+ /**
197
+ * Serves a list of code-defined REST tools (built with `defineRestTool`
198
+ * from `@personaai/sdk/rest-tools`) as a JSON manifest at
199
+ * `GET {mountPath}/rest-tools/manifest` — register that URL in the Persona
200
+ * dashboard as a REST Tool Source and it discovers/calls these tools live,
201
+ * the same way it discovers an MCP server's tools. This is host-side
202
+ * static data the runtime *serves*, not a Persona-proxy capability — it
203
+ * never calls `PersonaClient` and works even with no `resolveUser`
204
+ * traffic at all.
205
+ */
206
+ interface RestToolsManifestOptions {
207
+ /** REST tool definitions to serve — build each with `defineRestTool` from `@personaai/sdk/rest-tools`, or pass a plain object of the same shape. */
208
+ tools: RestToolManifestEntry[];
209
+ /**
210
+ * Required `Authorization: Bearer <token>` value the manifest route
211
+ * checks incoming requests against — must match the API Key configured
212
+ * on the Persona-side REST Tool Source. Omitting this leaves the route
213
+ * open (no auth) — only acceptable for local/dev testing.
214
+ */
215
+ authToken?: string;
216
+ }
189
217
  interface CreateRuntimeOptions {
190
218
  /** Base URL of the Persona Developer Platform API, e.g. "https://api.persona.hasanraiyan.me". */
191
219
  baseUrl: string;
@@ -228,6 +256,8 @@ interface CreateRuntimeOptions {
228
256
  maxTrackedRuns?: number;
229
257
  /** Opt-in switches for Project-level admin surface. See {@link RuntimeCapabilities} — everything defaults to off. */
230
258
  capabilities?: RuntimeCapabilities;
259
+ /** Serves a code-defined REST tool list for a Persona REST Tool Source to discover. See {@link RestToolsManifestOptions}. Unset by default — the route only exists when this is provided. */
260
+ restToolsManifest?: RestToolsManifestOptions;
231
261
  /** Log level for the runtime — off by default. Overrides the global level set via `setLogLevel()` from `@personaai/sdk`. */
232
262
  logLevel?: LogLevel;
233
263
  /** Custom logger instance — when provided, `logLevel` is ignored. */
@@ -256,4 +286,4 @@ declare class RuntimeHttpError extends Error {
256
286
 
257
287
  declare const RUNTIME_VERSION = "0.5.4";
258
288
 
259
- export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type ResolveUser, type RunContext, type RunResult, type Runtime, type RuntimeBinaryResponse, type RuntimeBufferedResponse, type RuntimeCapabilities, type RuntimeHooks, RuntimeHttpError, type RuntimeMethod, type RuntimeRequest, type RuntimeResponse, type RuntimeStreamResponse, type RuntimeUploadedFile, type ThreadCreateContext, type ToolCallContext, type VoiceSessionCreateContext, createRuntime };
289
+ export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type ResolveUser, type RestToolManifestEntry, type RestToolsManifestOptions, type RunContext, type RunResult, type Runtime, type RuntimeBinaryResponse, type RuntimeBufferedResponse, type RuntimeCapabilities, type RuntimeHooks, RuntimeHttpError, type RuntimeMethod, type RuntimeRequest, type RuntimeResponse, type RuntimeStreamResponse, type RuntimeUploadedFile, type ThreadCreateContext, type ToolCallContext, type VoiceSessionCreateContext, createRuntime };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChatMessageInput, LogLevel, Logger } from '@personaai/sdk';
1
+ import { ChatMessageInput, CreateRestToolInput, LogLevel, Logger } from '@personaai/sdk';
2
2
 
3
3
  type RuntimeMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
4
4
  /** A single uploaded file — present on `RuntimeRequest.file` for a multipart `POST /files`. */
@@ -148,6 +148,13 @@ interface RuntimeHooks {
148
148
  onVoiceSessionCreate?(ctx: VoiceSessionCreateContext): void | Promise<void>;
149
149
  }
150
150
 
151
+ /**
152
+ * One REST tool definition served by the manifest route — identical to
153
+ * `CreateRestToolInput` from `@personaai/sdk@^0.7.0` (also `defineRestTool`'s
154
+ * return type from `@personaai/sdk/rest-tools`), aliased under this name for
155
+ * clarity at the call site (`createRuntime({ restToolsManifest: { tools } })`).
156
+ */
157
+ type RestToolManifestEntry = CreateRestToolInput;
151
158
  /**
152
159
  * The single point of contact between the host's auth world and the
153
160
  * runtime's world. Receives the inbound request (with `userId: null`) and
@@ -186,6 +193,27 @@ interface RuntimeCapabilities {
186
193
  /** The Architect co-pilot — builds/edits Agents on the caller's behalf via tool calls. @default false */
187
194
  architect?: boolean;
188
195
  }
196
+ /**
197
+ * Serves a list of code-defined REST tools (built with `defineRestTool`
198
+ * from `@personaai/sdk/rest-tools`) as a JSON manifest at
199
+ * `GET {mountPath}/rest-tools/manifest` — register that URL in the Persona
200
+ * dashboard as a REST Tool Source and it discovers/calls these tools live,
201
+ * the same way it discovers an MCP server's tools. This is host-side
202
+ * static data the runtime *serves*, not a Persona-proxy capability — it
203
+ * never calls `PersonaClient` and works even with no `resolveUser`
204
+ * traffic at all.
205
+ */
206
+ interface RestToolsManifestOptions {
207
+ /** REST tool definitions to serve — build each with `defineRestTool` from `@personaai/sdk/rest-tools`, or pass a plain object of the same shape. */
208
+ tools: RestToolManifestEntry[];
209
+ /**
210
+ * Required `Authorization: Bearer <token>` value the manifest route
211
+ * checks incoming requests against — must match the API Key configured
212
+ * on the Persona-side REST Tool Source. Omitting this leaves the route
213
+ * open (no auth) — only acceptable for local/dev testing.
214
+ */
215
+ authToken?: string;
216
+ }
189
217
  interface CreateRuntimeOptions {
190
218
  /** Base URL of the Persona Developer Platform API, e.g. "https://api.persona.hasanraiyan.me". */
191
219
  baseUrl: string;
@@ -228,6 +256,8 @@ interface CreateRuntimeOptions {
228
256
  maxTrackedRuns?: number;
229
257
  /** Opt-in switches for Project-level admin surface. See {@link RuntimeCapabilities} — everything defaults to off. */
230
258
  capabilities?: RuntimeCapabilities;
259
+ /** Serves a code-defined REST tool list for a Persona REST Tool Source to discover. See {@link RestToolsManifestOptions}. Unset by default — the route only exists when this is provided. */
260
+ restToolsManifest?: RestToolsManifestOptions;
231
261
  /** Log level for the runtime — off by default. Overrides the global level set via `setLogLevel()` from `@personaai/sdk`. */
232
262
  logLevel?: LogLevel;
233
263
  /** Custom logger instance — when provided, `logLevel` is ignored. */
@@ -256,4 +286,4 @@ declare class RuntimeHttpError extends Error {
256
286
 
257
287
  declare const RUNTIME_VERSION = "0.5.4";
258
288
 
259
- export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type ResolveUser, type RunContext, type RunResult, type Runtime, type RuntimeBinaryResponse, type RuntimeBufferedResponse, type RuntimeCapabilities, type RuntimeHooks, RuntimeHttpError, type RuntimeMethod, type RuntimeRequest, type RuntimeResponse, type RuntimeStreamResponse, type RuntimeUploadedFile, type ThreadCreateContext, type ToolCallContext, type VoiceSessionCreateContext, createRuntime };
289
+ export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type ResolveUser, type RestToolManifestEntry, type RestToolsManifestOptions, type RunContext, type RunResult, type Runtime, type RuntimeBinaryResponse, type RuntimeBufferedResponse, type RuntimeCapabilities, type RuntimeHooks, RuntimeHttpError, type RuntimeMethod, type RuntimeRequest, type RuntimeResponse, type RuntimeStreamResponse, type RuntimeUploadedFile, type ThreadCreateContext, type ToolCallContext, type VoiceSessionCreateContext, createRuntime };
package/dist/index.js CHANGED
@@ -161,6 +161,71 @@ var healthRoute = async (_request, ctx) => {
161
161
  };
162
162
  };
163
163
 
164
+ // src/routeHelpers.ts
165
+ function json(status, value) {
166
+ return {
167
+ kind: "buffered",
168
+ status,
169
+ headers: { "content-type": "application/json" },
170
+ body: JSON.stringify(value)
171
+ };
172
+ }
173
+ function noContent() {
174
+ return { kind: "buffered", status: 204, headers: {}, body: "" };
175
+ }
176
+ function requireParam(params, name) {
177
+ const value = params[name];
178
+ if (!value) {
179
+ throw new RuntimeHttpError(400, "INVALID_REQUEST", `"${name}" path parameter is required.`);
180
+ }
181
+ return value;
182
+ }
183
+ function requireQueryParam(query, name) {
184
+ const value = query[name];
185
+ if (!value) {
186
+ throw new RuntimeHttpError(400, "INVALID_REQUEST", `"${name}" query parameter is required.`);
187
+ }
188
+ return value;
189
+ }
190
+ function toInt(value) {
191
+ if (value === void 0) return void 0;
192
+ const parsed = Number.parseInt(value, 10);
193
+ return Number.isNaN(parsed) ? void 0 : parsed;
194
+ }
195
+ function requireBodyObject(body) {
196
+ if (typeof body !== "object" || body === null) {
197
+ throw new RuntimeHttpError(400, "INVALID_REQUEST", "Request body must be a JSON object.");
198
+ }
199
+ return body;
200
+ }
201
+ function requireStringField(body, field) {
202
+ const value = body[field];
203
+ if (typeof value !== "string" || value.length === 0) {
204
+ throw new RuntimeHttpError(
205
+ 400,
206
+ "INVALID_REQUEST",
207
+ `"${field}" is required and must be a string.`
208
+ );
209
+ }
210
+ return value;
211
+ }
212
+
213
+ // src/routes/restToolsManifest.ts
214
+ var restToolsManifestRoute = async (request, ctx) => {
215
+ const manifest = ctx.restToolsManifest;
216
+ if (!manifest) {
217
+ throw new RuntimeHttpError(404, "NOT_FOUND", "No REST tools manifest is configured.");
218
+ }
219
+ if (manifest.authToken) {
220
+ const header = request.headers.authorization;
221
+ const expected = `Bearer ${manifest.authToken}`;
222
+ if (header !== expected) {
223
+ throw new RuntimeHttpError(401, "UNAUTHORIZED", "Invalid or missing manifest bearer token.");
224
+ }
225
+ }
226
+ return json(200, { tools: manifest.tools });
227
+ };
228
+
164
229
  // src/runDriver.ts
165
230
  import { EventType } from "@personaai/sdk";
166
231
  function formatSseFrame(event) {
@@ -619,55 +684,6 @@ function createResumeRoute(expectedKind) {
619
684
  };
620
685
  }
621
686
 
622
- // src/routeHelpers.ts
623
- function json(status, value) {
624
- return {
625
- kind: "buffered",
626
- status,
627
- headers: { "content-type": "application/json" },
628
- body: JSON.stringify(value)
629
- };
630
- }
631
- function noContent() {
632
- return { kind: "buffered", status: 204, headers: {}, body: "" };
633
- }
634
- function requireParam(params, name) {
635
- const value = params[name];
636
- if (!value) {
637
- throw new RuntimeHttpError(400, "INVALID_REQUEST", `"${name}" path parameter is required.`);
638
- }
639
- return value;
640
- }
641
- function requireQueryParam(query, name) {
642
- const value = query[name];
643
- if (!value) {
644
- throw new RuntimeHttpError(400, "INVALID_REQUEST", `"${name}" query parameter is required.`);
645
- }
646
- return value;
647
- }
648
- function toInt(value) {
649
- if (value === void 0) return void 0;
650
- const parsed = Number.parseInt(value, 10);
651
- return Number.isNaN(parsed) ? void 0 : parsed;
652
- }
653
- function requireBodyObject(body) {
654
- if (typeof body !== "object" || body === null) {
655
- throw new RuntimeHttpError(400, "INVALID_REQUEST", "Request body must be a JSON object.");
656
- }
657
- return body;
658
- }
659
- function requireStringField(body, field) {
660
- const value = body[field];
661
- if (typeof value !== "string" || value.length === 0) {
662
- throw new RuntimeHttpError(
663
- 400,
664
- "INVALID_REQUEST",
665
- `"${field}" is required and must be a string.`
666
- );
667
- }
668
- return value;
669
- }
670
-
671
687
  // src/routes/threads.ts
672
688
  var listThreads = async (request, ctx) => {
673
689
  const items = await ctx.client.threads.list({
@@ -1435,6 +1451,14 @@ function createRuntime(options) {
1435
1451
  );
1436
1452
  const capabilities = resolveCapabilities(options.capabilities);
1437
1453
  const routes = buildRoutes(capabilities);
1454
+ if (options.restToolsManifest) {
1455
+ routes.push({
1456
+ method: "GET",
1457
+ pattern: ["rest-tools", "manifest"],
1458
+ handler: restToolsManifestRoute,
1459
+ requiresAuth: false
1460
+ });
1461
+ }
1438
1462
  const mode = resolveMode(options);
1439
1463
  const heartbeatIntervalMs = options.heartbeatIntervalMs ?? 15e3;
1440
1464
  const runGraceMs = options.runGraceMs ?? DEFAULT_RUN_GRACE_MS;
@@ -1600,7 +1624,8 @@ function createRuntime(options) {
1600
1624
  heartbeatIntervalMs,
1601
1625
  runs,
1602
1626
  capabilities,
1603
- logger: routeLogger
1627
+ logger: routeLogger,
1628
+ restToolsManifest: options.restToolsManifest
1604
1629
  });
1605
1630
  const durationMs = Date.now() - startMs;
1606
1631
  logger.info("handle succeeded", {