@personaai/runtime 0.15.1 → 0.16.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
@@ -185,14 +185,16 @@ type ResolveUser = (request: RuntimeRequest) => string | null | Promise<string |
185
185
  /**
186
186
  * Every one of these is `false` unless explicitly enabled — always-off by
187
187
  * default so upgrading this package never silently exposes new surface to
188
- * whoever `resolveUser` accepts. These resources are Project-level
189
- * configuration (LLM provider credentials, skill/knowledge-base/vector-store
190
- * management, security audit logs, an agent-building co-pilot) rather than
191
- * things an end user does in a chat session — most hosts should manage them
192
- * via `@personaai/sdk` directly from their own admin surface and never turn
193
- * these on. Turn one on only if you specifically want it reachable through
194
- * whatever `resolveUser` gates (which may not be "any logged-in end user" —
195
- * that's your call).
188
+ * whoever `resolveUser` accepts. Most are Project-level configuration (LLM
189
+ * provider credentials, skill/knowledge-base/vector-store management,
190
+ * security audit logs, an agent-building co-pilot) rather than things an end
191
+ * user does in a chat session — most hosts should manage them via
192
+ * `@personaai/sdk` directly from their own admin surface and never turn
193
+ * these on. `messages` is a per-request action rather than configuration,
194
+ * but it's off for the same reason: a send reaches whatever recipient the
195
+ * caller names. Turn one on only if you specifically want it reachable
196
+ * through whatever `resolveUser` gates (which may not be "any logged-in end
197
+ * user" — that's your call).
196
198
  */
197
199
  interface RuntimeCapabilities {
198
200
  /** Full Agent CRUD (create/get/update/delete/bulk-delete) beyond the always-on read-only `GET /agents` list. @default false */
@@ -215,6 +217,13 @@ interface RuntimeCapabilities {
215
217
  architect?: boolean;
216
218
  /** Full Workflow CRUD, draft authoring, versions, and Mermaid export beyond the always-on execution routes. @default false */
217
219
  workflowsWrite?: boolean;
220
+ /**
221
+ * Outbound SMS/WhatsApp (`POST /messages`, `POST /messages/agent`). Off by
222
+ * default because `to` is any E.164 number and every send spends this
223
+ * Project's Twilio balance — unlike `chat`/`voice` these routes aren't
224
+ * end-user-scoped. @default false
225
+ */
226
+ messages?: boolean;
218
227
  }
219
228
  /**
220
229
  * Serves a list of code-defined REST tools (built with `defineRestTool`
@@ -328,6 +337,6 @@ declare class RuntimeHttpError extends Error {
328
337
  constructor(status: number, code: string, message: string);
329
338
  }
330
339
 
331
- declare const RUNTIME_VERSION = "0.15.0";
340
+ declare const RUNTIME_VERSION = "0.16.0";
332
341
 
333
342
  export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type RcpManifestOptions, 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, type WorkflowNodeContext, createRuntime };
package/dist/index.d.ts CHANGED
@@ -185,14 +185,16 @@ type ResolveUser = (request: RuntimeRequest) => string | null | Promise<string |
185
185
  /**
186
186
  * Every one of these is `false` unless explicitly enabled — always-off by
187
187
  * default so upgrading this package never silently exposes new surface to
188
- * whoever `resolveUser` accepts. These resources are Project-level
189
- * configuration (LLM provider credentials, skill/knowledge-base/vector-store
190
- * management, security audit logs, an agent-building co-pilot) rather than
191
- * things an end user does in a chat session — most hosts should manage them
192
- * via `@personaai/sdk` directly from their own admin surface and never turn
193
- * these on. Turn one on only if you specifically want it reachable through
194
- * whatever `resolveUser` gates (which may not be "any logged-in end user" —
195
- * that's your call).
188
+ * whoever `resolveUser` accepts. Most are Project-level configuration (LLM
189
+ * provider credentials, skill/knowledge-base/vector-store management,
190
+ * security audit logs, an agent-building co-pilot) rather than things an end
191
+ * user does in a chat session — most hosts should manage them via
192
+ * `@personaai/sdk` directly from their own admin surface and never turn
193
+ * these on. `messages` is a per-request action rather than configuration,
194
+ * but it's off for the same reason: a send reaches whatever recipient the
195
+ * caller names. Turn one on only if you specifically want it reachable
196
+ * through whatever `resolveUser` gates (which may not be "any logged-in end
197
+ * user" — that's your call).
196
198
  */
197
199
  interface RuntimeCapabilities {
198
200
  /** Full Agent CRUD (create/get/update/delete/bulk-delete) beyond the always-on read-only `GET /agents` list. @default false */
@@ -215,6 +217,13 @@ interface RuntimeCapabilities {
215
217
  architect?: boolean;
216
218
  /** Full Workflow CRUD, draft authoring, versions, and Mermaid export beyond the always-on execution routes. @default false */
217
219
  workflowsWrite?: boolean;
220
+ /**
221
+ * Outbound SMS/WhatsApp (`POST /messages`, `POST /messages/agent`). Off by
222
+ * default because `to` is any E.164 number and every send spends this
223
+ * Project's Twilio balance — unlike `chat`/`voice` these routes aren't
224
+ * end-user-scoped. @default false
225
+ */
226
+ messages?: boolean;
218
227
  }
219
228
  /**
220
229
  * Serves a list of code-defined REST tools (built with `defineRestTool`
@@ -328,6 +337,6 @@ declare class RuntimeHttpError extends Error {
328
337
  constructor(status: number, code: string, message: string);
329
338
  }
330
339
 
331
- declare const RUNTIME_VERSION = "0.15.0";
340
+ declare const RUNTIME_VERSION = "0.16.0";
332
341
 
333
342
  export { type CreateRuntimeOptions, type ErrorContext, type FileUploadContext, type MemoryWriteContext, RUNTIME_VERSION, type RcpManifestOptions, 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, type WorkflowNodeContext, createRuntime };
package/dist/index.js CHANGED
@@ -131,7 +131,7 @@ function evictStaleRuns(runs, now, graceMs = DEFAULT_RUN_GRACE_MS, maxTracked =
131
131
  }
132
132
 
133
133
  // src/version.ts
134
- var RUNTIME_VERSION = "0.15.0";
134
+ var RUNTIME_VERSION = "0.16.0";
135
135
 
136
136
  // src/routes/health.ts
137
137
  var alwaysOnCapabilities = {
@@ -850,6 +850,92 @@ var createVoiceSession = async (request, ctx) => {
850
850
  return json(201, ticket);
851
851
  };
852
852
 
853
+ // src/routes/messages.ts
854
+ var MESSAGE_CHANNELS = /* @__PURE__ */ new Set(["sms", "whatsapp"]);
855
+ function optionalChannel(body) {
856
+ const value = body.channel;
857
+ if (value === void 0) return void 0;
858
+ if (typeof value !== "string" || !MESSAGE_CHANNELS.has(value)) {
859
+ throw new RuntimeHttpError(400, "INVALID_REQUEST", '"channel" must be "sms" or "whatsapp".');
860
+ }
861
+ return value;
862
+ }
863
+ function optionalStringField(body, field) {
864
+ const value = body[field];
865
+ if (value === void 0) return void 0;
866
+ if (typeof value !== "string" || value.length === 0) {
867
+ throw new RuntimeHttpError(400, "INVALID_REQUEST", `"${field}" must be a non-empty string.`);
868
+ }
869
+ return value;
870
+ }
871
+ function optionalMediaUrl(body) {
872
+ const value = body.mediaUrl;
873
+ if (value === void 0) return void 0;
874
+ if (typeof value === "string" && value.length > 0) return value;
875
+ if (Array.isArray(value) && value.every((entry) => typeof entry === "string" && entry.length > 0)) {
876
+ return value;
877
+ }
878
+ throw new RuntimeHttpError(
879
+ 400,
880
+ "INVALID_REQUEST",
881
+ '"mediaUrl" must be a string or an array of strings.'
882
+ );
883
+ }
884
+ function optionalContentVariables(body) {
885
+ const value = body.contentVariables;
886
+ if (value === void 0) return void 0;
887
+ if (typeof value === "string") return value;
888
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
889
+ return value;
890
+ }
891
+ throw new RuntimeHttpError(
892
+ 400,
893
+ "INVALID_REQUEST",
894
+ '"contentVariables" must be an object or a JSON string.'
895
+ );
896
+ }
897
+ var sendMessage = async (request, ctx) => {
898
+ const body = requireBodyObject(request.body);
899
+ const to = requireStringField(body, "to");
900
+ const channel = optionalChannel(body);
901
+ const text = optionalStringField(body, "body");
902
+ const mediaUrl = optionalMediaUrl(body);
903
+ const contentSid = optionalStringField(body, "contentSid");
904
+ const contentVariables = optionalContentVariables(body);
905
+ if (text === void 0 && contentSid === void 0) {
906
+ throw new RuntimeHttpError(
907
+ 400,
908
+ "INVALID_REQUEST",
909
+ '"body" is required unless "contentSid" is provided.'
910
+ );
911
+ }
912
+ const delivery = await ctx.client.messages.send({
913
+ to,
914
+ ...channel ? { channel } : {},
915
+ ...text ? { body: text } : {},
916
+ ...mediaUrl ? { mediaUrl } : {},
917
+ ...contentSid ? { contentSid } : {},
918
+ ...contentVariables ? { contentVariables } : {}
919
+ });
920
+ return json(200, delivery);
921
+ };
922
+ var sendAgentMessage = async (request, ctx) => {
923
+ const body = requireBodyObject(request.body);
924
+ const agentId = requireStringField(body, "agentId");
925
+ const to = requireStringField(body, "to");
926
+ const prompt = requireStringField(body, "prompt");
927
+ const channel = optionalChannel(body);
928
+ const displayName = optionalStringField(body, "displayName");
929
+ const delivery = await ctx.client.messages.sendFromAgent({
930
+ agentId,
931
+ to,
932
+ prompt,
933
+ ...channel ? { channel } : {},
934
+ ...displayName ? { displayName } : {}
935
+ });
936
+ return json(200, delivery);
937
+ };
938
+
853
939
  // src/routes/agents.ts
854
940
  var listAgents = async (request, ctx) => {
855
941
  const items = await ctx.client.agents.list({
@@ -1579,7 +1665,8 @@ function resolveCapabilities(capabilities) {
1579
1665
  rcpSources: capabilities?.rcpSources ?? false,
1580
1666
  auditLogs: capabilities?.auditLogs ?? false,
1581
1667
  architect: capabilities?.architect ?? false,
1582
- workflowsWrite: capabilities?.workflowsWrite ?? false
1668
+ workflowsWrite: capabilities?.workflowsWrite ?? false,
1669
+ messages: capabilities?.messages ?? false
1583
1670
  };
1584
1671
  }
1585
1672
  function buildRoutes(capabilities) {
@@ -1670,6 +1757,12 @@ function buildRoutes(capabilities) {
1670
1757
  handler: cancelWorkflowRun
1671
1758
  }
1672
1759
  ];
1760
+ if (capabilities.messages) {
1761
+ routes.push(
1762
+ { method: "POST", pattern: ["messages"], handler: sendMessage },
1763
+ { method: "POST", pattern: ["messages", "agent"], handler: sendAgentMessage }
1764
+ );
1765
+ }
1673
1766
  if (capabilities.agentsWrite) {
1674
1767
  routes.push(
1675
1768
  { method: "POST", pattern: ["agents"], handler: createAgent },