@personaai/runtime 0.9.0 → 0.9.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
@@ -209,6 +209,33 @@ function requireStringField(body, field) {
209
209
  }
210
210
  return value;
211
211
  }
212
+ var MAX_TURN_CONTEXT_BYTES = 2e3;
213
+ function validateTurnContext(value) {
214
+ if (value === void 0) return void 0;
215
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
216
+ throw new RuntimeHttpError(400, "INVALID_CONTEXT", "context must be a flat object.");
217
+ }
218
+ const context = value;
219
+ for (const [key, entry] of Object.entries(context)) {
220
+ const entryType = typeof entry;
221
+ if (entryType !== "string" && entryType !== "number" && entryType !== "boolean") {
222
+ throw new RuntimeHttpError(
223
+ 400,
224
+ "INVALID_CONTEXT",
225
+ `context.${key} must be a string, number, or boolean.`
226
+ );
227
+ }
228
+ }
229
+ const byteLength = new TextEncoder().encode(JSON.stringify(context)).length;
230
+ if (byteLength > MAX_TURN_CONTEXT_BYTES) {
231
+ throw new RuntimeHttpError(
232
+ 400,
233
+ "CONTEXT_TOO_LARGE",
234
+ `context must be ${MAX_TURN_CONTEXT_BYTES} bytes or fewer when serialized.`
235
+ );
236
+ }
237
+ return context;
238
+ }
212
239
 
213
240
  // src/routes/restToolsManifest.ts
214
241
  var restToolsManifestRoute = async (request, ctx) => {
@@ -534,7 +561,12 @@ function parseChatBody(body) {
534
561
  messages: b.messages,
535
562
  threadId: typeof b.threadId === "string" ? b.threadId : void 0,
536
563
  resume: b.resume ?? void 0,
537
- contextOverride: typeof b.contextOverride === "string" ? b.contextOverride : void 0
564
+ contextOverride: typeof b.contextOverride === "string" ? b.contextOverride : void 0,
565
+ // Distinct from contextOverride above — never shown to the model, only
566
+ // ever read live by an RCP tool's resolver. validateTurnContext throws
567
+ // a 400 on any shape violation (not a flat string/number/boolean
568
+ // object, or over the byte cap) rather than coercing/dropping it.
569
+ context: validateTurnContext(b.context)
538
570
  };
539
571
  }
540
572
  var chatRoute = async (request, ctx) => {
@@ -546,7 +578,8 @@ var chatRoute = async (request, ctx) => {
546
578
  threadId: body.threadId,
547
579
  messageCount: body.messages?.length ?? 0,
548
580
  hasResume: !!body.resume,
549
- hasContextOverride: !!body.contextOverride
581
+ hasContextOverride: !!body.contextOverride,
582
+ hasContext: !!body.context
550
583
  });
551
584
  const userId = request.userId;
552
585
  const runCtx = {
@@ -564,7 +597,8 @@ var chatRoute = async (request, ctx) => {
564
597
  messages: body.messages,
565
598
  threadId: body.threadId,
566
599
  resume: body.resume,
567
- contextOverride: body.contextOverride
600
+ contextOverride: body.contextOverride,
601
+ context: body.context
568
602
  });
569
603
  const runId = crypto.randomUUID();
570
604
  logger.info("chat run created", {
@@ -756,7 +790,13 @@ var createVoiceSession = async (request, ctx) => {
756
790
  const body = requireBodyObject(request.body);
757
791
  const agentId = requireStringField(body, "agentId");
758
792
  const threadId = typeof body.threadId === "string" && body.threadId ? body.threadId : void 0;
759
- const ticket = await ctx.client.voice.createSession(agentId, threadId ? { threadId } : {});
793
+ const contextOverride = typeof body.contextOverride === "string" && body.contextOverride ? body.contextOverride : void 0;
794
+ const context = validateTurnContext(body.context);
795
+ const ticket = await ctx.client.voice.createSession(agentId, {
796
+ ...threadId ? { threadId } : {},
797
+ ...contextOverride ? { contextOverride } : {},
798
+ ...context ? { context } : {}
799
+ });
760
800
  await ctx.hooks?.onVoiceSessionCreate?.({
761
801
  userId: request.userId,
762
802
  agentId,