@sentry/junior 0.179.0 → 0.181.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.
Files changed (137) hide show
  1. package/dist/{agent-hooks-32IDCLMW.js → agent-hooks-IQUW6ERD.js} +16 -18
  2. package/dist/api/schema/workspace.d.ts +2 -0
  3. package/dist/api/schema.js +1 -2
  4. package/dist/api.js +202 -199
  5. package/dist/app.d.ts +4 -0
  6. package/dist/app.js +300 -1259
  7. package/dist/catalog-runtime-PMQWNIXA.js +14 -0
  8. package/dist/chat/agent/sandbox.d.ts +0 -2
  9. package/dist/chat/api-turns/routing.d.ts +4 -0
  10. package/dist/chat/api-turns/work.d.ts +5 -0
  11. package/dist/chat/config.d.ts +5 -2
  12. package/dist/chat/configuration/defaults.d.ts +1 -1
  13. package/dist/chat/conversations/projection.d.ts +6 -4
  14. package/dist/chat/ingress/message-router.d.ts +3 -0
  15. package/dist/chat/model-profile.d.ts +8 -10
  16. package/dist/chat/pi/conversation-events.d.ts +3 -2
  17. package/dist/chat/plugins/agent-hooks.d.ts +1 -1
  18. package/dist/chat/plugins/task-queue.d.ts +40 -3
  19. package/dist/chat/plugins/task-runner.d.ts +1 -1
  20. package/dist/chat/queue/callback.d.ts +26 -0
  21. package/dist/chat/queue/sign.d.ts +30 -0
  22. package/dist/chat/sandbox/sandbox.d.ts +0 -2
  23. package/dist/chat/sandbox/session.d.ts +0 -2
  24. package/dist/chat/sandbox/skill-sync.d.ts +1 -1
  25. package/dist/chat/sandbox/snapshot/events.d.ts +23 -0
  26. package/dist/chat/sandbox/snapshot/job-callback.d.ts +5 -0
  27. package/dist/chat/sandbox/snapshot/job-queue.d.ts +26 -0
  28. package/dist/chat/sandbox/snapshot/job-runner.d.ts +11 -0
  29. package/dist/chat/sandbox/snapshot/not-ready-error.d.ts +6 -0
  30. package/dist/chat/sandbox/snapshot/workspace.d.ts +9 -3
  31. package/dist/chat/services/turn-router.d.ts +4 -3
  32. package/dist/chat/services/turn-session-routing.d.ts +1 -0
  33. package/dist/chat/task-execution/queue-signing.d.ts +10 -21
  34. package/dist/chat/task-execution/state.d.ts +48 -0
  35. package/dist/chat/task-execution/store.d.ts +28 -2
  36. package/dist/chat/task-execution/worker.d.ts +4 -1
  37. package/dist/chat/tools/handoff/tool.d.ts +1 -1
  38. package/dist/chat/tools/types.d.ts +2 -0
  39. package/dist/chat/workspaces/types.d.ts +2 -0
  40. package/dist/{chunk-Q5B3WTGG.js → chunk-3KCQEG6W.js} +42 -41
  41. package/dist/{chunk-XZY6G5YZ.js → chunk-3KSSALN4.js} +180 -87
  42. package/dist/{chunk-3AFVR5UC.js → chunk-3X55QRAG.js} +18 -16
  43. package/dist/{chunk-SLGGOASN.js → chunk-4IX32NSL.js} +46 -46
  44. package/dist/{chunk-6ZWRNC4D.js → chunk-6Y5B5PEX.js} +1 -1
  45. package/dist/chunk-7H2VZTWN.js +103 -0
  46. package/dist/{chunk-CGA4ERJ5.js → chunk-CEMMLV5L.js} +1 -1
  47. package/dist/{chunk-FIANEE7Z.js → chunk-CM5HNV2W.js} +6 -6
  48. package/dist/{chunk-TKB25A3L.js → chunk-CZYNWPWD.js} +2 -1
  49. package/dist/{chunk-3I7XE3PA.js → chunk-D6ZD7VXP.js} +49 -38
  50. package/dist/chunk-DKIJ2RP5.js +68 -0
  51. package/dist/{chunk-G2CAC4CV.js → chunk-DSA6WTRP.js} +74 -68
  52. package/dist/{chunk-OOUNJNMR.js → chunk-DWPN6SCH.js} +1 -1
  53. package/dist/{chunk-HQNE5APD.js → chunk-EBMRB6Z6.js} +100 -79
  54. package/dist/{chunk-ZQMG3CL5.js → chunk-EM7EECT5.js} +16 -16
  55. package/dist/{chunk-XSPSCWLH.js → chunk-ETJTXYHY.js} +4 -4
  56. package/dist/{chunk-FTGD2FBP.js → chunk-EU7KJDOG.js} +2 -2
  57. package/dist/{chunk-CJLBLELR.js → chunk-FWILPBVQ.js} +8 -61
  58. package/dist/{chunk-4GWXAILB.js → chunk-GPA3ZSYY.js} +1 -1
  59. package/dist/{chunk-U4TKB6F6.js → chunk-GREV5PJK.js} +108 -5
  60. package/dist/{chunk-KJLHIHFF.js → chunk-GWFRPQNP.js} +43 -230
  61. package/dist/{chunk-YFNAMRGE.js → chunk-HEBMSITT.js} +1 -1
  62. package/dist/chunk-HJ27A6YB.js +218 -0
  63. package/dist/{chunk-R5NWWYIS.js → chunk-HZHUMCNV.js} +5 -5
  64. package/dist/{chunk-RTRBYSF3.js → chunk-IJ6SS4WB.js} +1 -1
  65. package/dist/{chunk-B6ECUSVX.js → chunk-IKKETMQC.js} +8 -8
  66. package/dist/{chunk-R6U7N4FS.js → chunk-KKSVCHDO.js} +10 -3
  67. package/dist/{chunk-JMJNFEDC.js → chunk-KMBU4PJP.js} +9 -54
  68. package/dist/chunk-KQZX24QQ.js +164 -0
  69. package/dist/{chunk-GPLAT6H7.js → chunk-LCNPXLE7.js} +22 -18
  70. package/dist/{chunk-2HIPYNQI.js → chunk-LG5MYY6U.js} +33 -32
  71. package/dist/chunk-LZOQFC5F.js +209 -0
  72. package/dist/chunk-M3QYTBQ6.js +55 -0
  73. package/dist/{chunk-M63DETLL.js → chunk-N7TMSOZH.js} +6 -6
  74. package/dist/{chunk-FIDMHAO6.js → chunk-NQTA72Q3.js} +84 -274
  75. package/dist/{chunk-RZRYOLCE.js → chunk-PBKZQAUA.js} +2315 -1150
  76. package/dist/chunk-PEQXYSSE.js +45 -0
  77. package/dist/{chunk-3TM3FYLQ.js → chunk-PL57B6NC.js} +1 -1
  78. package/dist/{chunk-JT4WMD3C.js → chunk-PPYDHUEL.js} +144 -218
  79. package/dist/{chunk-5IRROPA5.js → chunk-Q2KY27IX.js} +129 -31
  80. package/dist/{chunk-VP4OVRDD.js → chunk-RNMASWLP.js} +69 -73
  81. package/dist/{chunk-FAS6AIMF.js → chunk-TDT2R77B.js} +8 -8
  82. package/dist/{chunk-TIEKUH4Q.js → chunk-TJHSAHQN.js} +4 -3
  83. package/dist/{chunk-H4HBKISO.js → chunk-TXKUKMVO.js} +1 -1
  84. package/dist/chunk-X6GDDWQH.js +60 -0
  85. package/dist/{chunk-GENV6KF2.js → chunk-XYTJUHRZ.js} +108 -76
  86. package/dist/cli/chat.js +47 -43
  87. package/dist/cli/check.js +13 -15
  88. package/dist/cli/env.js +0 -1
  89. package/dist/cli/init.js +0 -1
  90. package/dist/cli/main.js +2 -3
  91. package/dist/cli/plugins.js +18 -20
  92. package/dist/cli/run.js +0 -1
  93. package/dist/cli/snapshot-create.js +14 -16
  94. package/dist/cli/upgrade.js +16 -18
  95. package/dist/{conversation-work-KATFHLG3.js → conversation-work-VIOQ5ZF3.js} +0 -2
  96. package/dist/db/schema/snapshots.d.ts +17 -0
  97. package/dist/db/schema.d.ts +17 -0
  98. package/dist/{db-EJAV7JL6.js → db-QNPVCQPT.js} +8 -10
  99. package/dist/deployment.d.ts +1 -0
  100. package/dist/{discovery-GUFTFBTL.js → discovery-DWVDM7UK.js} +1 -2
  101. package/dist/{experimental-XVDOSRBS.js → experimental-SIJSRDJD.js} +0 -1
  102. package/dist/instrumentation.js +7 -9
  103. package/dist/nitro.js +39 -13
  104. package/dist/{oauth-callback-server-GAVSUBTQ.js → oauth-callback-server-KYMPJOTC.js} +34 -32
  105. package/dist/{oauth-relay-3ZU72UGL.js → oauth-relay-5XPVRPYB.js} +0 -1
  106. package/dist/{plugins-HW4VWW6G.js → plugins-YTYJMMJF.js} +1 -2
  107. package/dist/{runner-34JL64JF.js → runner-3RS2D2ZR.js} +39 -33
  108. package/dist/{sandbox-egress-signals-DXOOBSBI.js → sandbox-egress-signals-FIL7EGPR.js} +5 -6
  109. package/dist/{sentry-JMWTS32N.js → sentry-MB3NL3IR.js} +1 -2
  110. package/dist/skills-5B3Y6XX6.js +27 -0
  111. package/dist/spawn-VYARS3DU.js +37 -0
  112. package/dist/task-runner-4IXKKZHL.js +32 -0
  113. package/dist/validation-Q65QD27B.js +17 -0
  114. package/dist/vercel.js +0 -1
  115. package/dist/version.js +1 -2
  116. package/dist/work-DCMQWAAP.js +45 -0
  117. package/dist/worker-QL3CHLZL.js +22 -0
  118. package/migrations/0035_workspace_snapshot_size_bytes.sql +2 -0
  119. package/migrations/meta/0035_snapshot.json +3048 -0
  120. package/migrations/meta/_journal.json +7 -0
  121. package/package.json +7 -6
  122. package/dist/catalog-runtime-FBVA6WAQ.js +0 -16
  123. package/dist/chat/plugins/task-callback.d.ts +0 -5
  124. package/dist/chat/plugins/task-message.d.ts +0 -23
  125. package/dist/chat/plugins/task-signing.d.ts +0 -31
  126. package/dist/chat/sandbox/snapshot/waiting-error.d.ts +0 -15
  127. package/dist/chat/services/workspace-snapshot-wait.d.ts +0 -27
  128. package/dist/chunk-5I6ORJUY.js +0 -127
  129. package/dist/chunk-6GWA276C.js +0 -72
  130. package/dist/chunk-MLKGABMK.js +0 -9
  131. package/dist/chunk-UT6X7XN7.js +0 -51
  132. package/dist/chunk-WR76IVA5.js +0 -130
  133. package/dist/skills-U545HALM.js +0 -29
  134. package/dist/spawn-I2S4IDUQ.js +0 -37
  135. package/dist/validation-EVXVGA44.js +0 -19
  136. package/dist/work-QOAUPDBU.js +0 -45
  137. package/dist/worker-5GX2IKLZ.js +0 -24
@@ -0,0 +1,14 @@
1
+ import {
2
+ pluginCatalogRuntime
3
+ } from "./chunk-HEBMSITT.js";
4
+ import "./chunk-4IX32NSL.js";
5
+ import "./chunk-CEMMLV5L.js";
6
+ import "./chunk-N7TMSOZH.js";
7
+ import "./chunk-DWPN6SCH.js";
8
+ import "./chunk-TXKUKMVO.js";
9
+ import "./chunk-EBMRB6Z6.js";
10
+ import "./chunk-PEQXYSSE.js";
11
+ import "./chunk-TJHSAHQN.js";
12
+ export {
13
+ pluginCatalogRuntime
14
+ };
@@ -31,8 +31,6 @@ export interface AgentSandboxOptions {
31
31
  actor?: Actor;
32
32
  locationConfiguration?: LocationConfigurationService;
33
33
  configurationValues: Record<string, unknown>;
34
- /** Durable-worker soft yield for long Workspace snapshot waits. */
35
- shouldYield?: () => boolean;
36
34
  getActiveSkill(): Skill | null;
37
35
  prepareSandbox(workspace: SandboxWorkspace): void | Promise<void>;
38
36
  prepareWorkspace?(workspace: SandboxWorkspace, recipe: Workspace, signal?: AbortSignal): Promise<void>;
@@ -10,6 +10,10 @@ declare const apiTurnMailboxMetadataSchema: z.ZodObject<{
10
10
  messageId: z.ZodString;
11
11
  }, z.core.$strict>;
12
12
  export type ApiTurnMailboxMetadata = z.output<typeof apiTurnMailboxMetadataSchema>;
13
+ /** Return the active root API Turn for one Conversation, if it has one. */
14
+ export declare function getActiveApiTurnId(conversationId: string): Promise<string | undefined>;
15
+ /** Return the idle auth-paused root API Turn for one Conversation. */
16
+ export declare function getAuthPausedApiTurnId(conversationId: string): Promise<string | undefined>;
13
17
  /**
14
18
  * Resolve API Turn work from mailbox metadata or an active checkpoint.
15
19
  *
@@ -47,6 +47,11 @@ export declare function createApiConversationId(args: {
47
47
  actorEmail: string;
48
48
  idempotencyKey: string;
49
49
  }): string;
50
+ /** Build the retry-stable Message id used by one API mailbox request. */
51
+ export declare function apiConversationMessageId(args: {
52
+ conversationId: string;
53
+ idempotencyKey: string;
54
+ }): string;
50
55
  /** Stable turn id for one API mailbox message (matches getTurnUserMessage). */
51
56
  export declare function apiTurnIdForMessage(messageId: string): string;
52
57
  /** Rebuild the dashboard actor from durable conversation identity. */
@@ -1,5 +1,5 @@
1
1
  import { type TurnReasoningLevel } from "@/chat/reasoning-level";
2
- import { type ExecutionProfileConfig } from "@/chat/model-profile";
2
+ import { type ModelProfileConfig, type ModelProfile } from "@/chat/model-profile";
3
3
  export declare const DEFAULT_SQL_STATEMENT_TIMEOUT_MS = 30000;
4
4
  /**
5
5
  * Buffer between the Vercel function timeout and the agent turn timeout so
@@ -11,12 +11,13 @@ export declare const CONVERSATION_WORK_SOFT_YIELD_BUFFER_SECONDS = 40;
11
11
  export interface BotConfig {
12
12
  contextWindowTokens: number;
13
13
  crossActorMidRunMode: CrossActorMidRunMode;
14
+ defaultProfile: ModelProfile;
14
15
  embeddingModelId: string;
15
16
  fastModelId: string;
16
17
  guardianModelId: string;
17
18
  imageGenerationModelId: string;
18
19
  loadingMessages: string[];
19
- profiles: Readonly<Record<string, ExecutionProfileConfig>>;
20
+ profiles: Readonly<Record<string, ModelProfileConfig>>;
20
21
  reasoningLevel?: TurnReasoningLevel;
21
22
  visionModelId?: string;
22
23
  maxSlicesPerTurn: number;
@@ -73,6 +74,8 @@ export interface SlackReactionConfig {
73
74
  completedReactionEmoji: string;
74
75
  processingReactionEmoji: string;
75
76
  }
77
+ /** Apply profiles from createApp(). */
78
+ export declare function setProfiles(profiles: Readonly<Record<string, string>> | undefined, defaultProfile: string | undefined): void;
76
79
  /** Return the current Slack reaction emoji config. */
77
80
  export declare function getSlackReactionConfig(): SlackReactionConfig;
78
81
  /** Apply Slack reaction emoji overrides from createApp() options, validating names. */
@@ -1,4 +1,4 @@
1
1
  /** Store install-wide configuration defaults. */
2
- export declare function setConfigDefaults(defaults: Record<string, unknown> | undefined): void;
2
+ export declare function setConfigDefaults(defaults: unknown): void;
3
3
  /** Return the install-wide configuration defaults (empty object when none set). */
4
4
  export declare function getConfigDefaults(): Record<string, unknown>;
@@ -145,14 +145,16 @@ export declare function recordSubscribedReplyRoute(args: {
145
145
  shouldReply: boolean;
146
146
  shouldUnsubscribe?: boolean;
147
147
  }): Promise<void>;
148
- /** Load a previously selected execution profile for a resumed turn. */
148
+ /** Load a previously selected model profile for a resumed turn. */
149
149
  export declare function loadTurnRoute(args: {
150
150
  conversationId: string;
151
151
  turnId: string;
152
- }): Promise<Extract<ConversationEvent["data"], {
152
+ }): Promise<(Extract<ConversationEvent["data"], {
153
153
  type: "turn_routed";
154
- }> | undefined>;
155
- /** Record the execution profile selected for one turn without changing agent history. */
154
+ }> & {
155
+ seq: number;
156
+ }) | undefined>;
157
+ /** Record the model profile selected for one turn without changing agent history. */
156
158
  export declare function recordTurnRoute(args: {
157
159
  conversationId: string;
158
160
  turnId: string;
@@ -1,5 +1,8 @@
1
+ import { Message } from "chat";
1
2
  export type ThreadMessageKind = "new_mention" | "subscribed_message";
2
3
  /** Derive canonical Slack thread IDs from the raw event payload. */
4
+ /** Rebuild a Message onto a normalized Slack thread id. */
5
+ export declare function withNormalizedThreadId(message: Message, threadId: string): Message;
3
6
  export declare function normalizeIncomingSlackThreadId(threadId: string, message: unknown): string;
4
7
  /** Classify an incoming message as a mention or subscribed message. */
5
8
  export declare function determineThreadMessageKind(args: {
@@ -1,14 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import type { BotConfig } from "@/chat/config";
3
3
  import type { TurnReasoningLevel } from "@/chat/reasoning-level";
4
- export declare const STANDARD_MODEL_PROFILE = "standard";
5
- export declare const DEFAULT_HANDOFF_MODEL_PROFILE = "handoff";
6
4
  /** Keep durable profile names stable and safe to expose in tool schemas. */
7
5
  export declare const modelProfileSchema: z.ZodString;
8
- /** A configured model role rather than a provider-specific model id. */
6
+ /** A configured name for a model. */
9
7
  export type ModelProfile = z.output<typeof modelProfileSchema>;
10
- /** Runtime configuration for one named execution profile. */
11
- export interface ExecutionProfileConfig {
8
+ /** Runtime configuration for one named model profile. */
9
+ export interface ModelProfileConfig {
12
10
  modelId: string;
13
11
  reasoningLevel?: TurnReasoningLevel;
14
12
  }
@@ -16,9 +14,9 @@ export interface ExecutionProfileConfig {
16
14
  export declare class ModelProfileNotConfiguredError extends Error {
17
15
  constructor(profile: ModelProfile);
18
16
  }
19
- /** Resolve a stable model profile through the host-owned model catalog. */
17
+ /** Resolve a model id from a configured profile. */
20
18
  export declare function modelIdForProfile(config: BotConfig, profile: ModelProfile): string;
21
- /** Resolve the standard execution profile's model. */
22
- export declare function standardModelId(config: BotConfig): string;
23
- /** Resolve a stable model profile through the host-owned profile catalog. */
24
- export declare function profileConfig(config: BotConfig, profile: ModelProfile): ExecutionProfileConfig;
19
+ /** Resolve the configured default profile's model. */
20
+ export declare function defaultModelId(config: BotConfig): string;
21
+ /** Return one configured profile. */
22
+ export declare function profileConfig(config: BotConfig, profile: ModelProfile): ModelProfileConfig;
@@ -13,7 +13,7 @@ export interface PiConversationProjection {
13
13
  messages: PiMessage[];
14
14
  provenance: ConversationMessageProvenance[];
15
15
  modelProfile: ModelProfile;
16
- modelId: string | undefined;
16
+ replacementSeq: number | undefined;
17
17
  }
18
18
  /** Pi context with the source event sequence for every projected message. */
19
19
  export interface PiConversationEventProjection extends PiConversationProjection {
@@ -32,6 +32,7 @@ export declare function piMessageFromHistoryItem(data: AgentHistoryItem): PiMess
32
32
  * Host-only events are filtered, completed authorization becomes a synthetic
33
33
  * observation, and `maxSeq` reproduces an exact committed boundary.
34
34
  */
35
- export declare function projectConversationEvents(events: ConversationEvent[], options?: {
35
+ export declare function projectConversationEvents(events: ConversationEvent[], options: {
36
+ defaultProfile: ModelProfile;
36
37
  maxSeq?: number;
37
38
  }): PiConversationEventProjection;
@@ -53,7 +53,7 @@ export declare function applyPluginFormatMarkdown(text: string): string;
53
53
  export declare function getPluginSystemPromptContributions(source: ToolRuntimeContext["source"]): Promise<PluginPromptContributionContext[]>;
54
54
  /** Collect request-scoped plugin prompt contributions. */
55
55
  export declare function getPluginUserPromptContributions(args: {
56
- context: Pick<ToolRuntimeContext, "conversationId" | "destination" | "actor" | "source" | "userText">;
56
+ context: Pick<ToolRuntimeContext, "conversationId" | "locationId" | "destination" | "actor" | "resolveActorIdentity" | "source" | "userText">;
57
57
  turnId?: string;
58
58
  }): Promise<PluginPromptContributionContext[]>;
59
59
  /** Collect turn-scoped tools exposed by plugins. */
@@ -1,5 +1,42 @@
1
- import { type PluginTaskQueueMessage } from "./task-message";
1
+ import { z } from "zod";
2
+ /** Deploy topic name. Keep stable for Vercel queue wiring. */
2
3
  export declare const PLUGIN_TASK_QUEUE_TOPIC = "junior_plugin_tasks";
3
- export declare const PLUGIN_TASK_QUEUE_RETENTION_SECONDS: number;
4
- /** Send one plugin task wakeup through Vercel Queues. */
4
+ export declare const pluginTaskParamsSchema: z.ZodObject<{
5
+ conversationId: z.ZodString;
6
+ sessionId: z.ZodString;
7
+ }, z.core.$strict>;
8
+ export type PluginTaskParams = z.output<typeof pluginTaskParamsSchema>;
9
+ export declare const pluginTaskQueueMessageSchema: z.ZodObject<{
10
+ name: z.ZodString;
11
+ params: z.ZodObject<{
12
+ conversationId: z.ZodString;
13
+ sessionId: z.ZodString;
14
+ }, z.core.$strict>;
15
+ plugin: z.ZodString;
16
+ }, z.core.$strict>;
17
+ export type PluginTaskQueueMessage = z.output<typeof pluginTaskQueueMessageSchema>;
18
+ /** Build the stable id used for delivery dedupe and tracing. */
19
+ export declare function pluginTaskId(args: {
20
+ name: string;
21
+ params: PluginTaskParams;
22
+ plugin: string;
23
+ }): string;
24
+ /** Sign a plugin task message for tests and local checks. */
25
+ export declare function signPluginTaskQueueMessage(message: PluginTaskQueueMessage, nowMs?: number): {
26
+ name: string;
27
+ params: {
28
+ conversationId: string;
29
+ sessionId: string;
30
+ };
31
+ plugin: string;
32
+ } & {
33
+ signature: string;
34
+ signatureVersion: "v1";
35
+ signedAtMs: number;
36
+ };
37
+ /** Send one plugin task through the shared signed delivery path. */
5
38
  export declare function sendVercelPluginTask(message: PluginTaskQueueMessage): Promise<void>;
39
+ /** Create the HTTP callback for plugin tasks. */
40
+ export declare function createVercelPluginTaskCallback(): (request: Request) => Promise<Response>;
41
+ /** Register the local-dev consumer for plugin tasks. */
42
+ export declare function registerVercelPluginTaskDevConsumer(): (() => void) | undefined;
@@ -1,4 +1,4 @@
1
- import { type PluginTaskParams, type PluginTaskQueueMessage } from "./task-message";
1
+ import { type PluginTaskParams, type PluginTaskQueueMessage } from "./task-queue";
2
2
  export interface ScheduleSessionCompletedPluginTasksOptions {
3
3
  send?: (message: PluginTaskQueueMessage) => Promise<void>;
4
4
  }
@@ -0,0 +1,26 @@
1
+ /** Shared Vercel Queue callback wiring for signed messages. */
2
+ import { type MessageMetadata } from "@vercel/queue";
3
+ import type { QueueRejectReason, QueueVerifyResult } from "./sign";
4
+ export interface QueueCallbackOptions<Message> {
5
+ consumerGroup: string;
6
+ /** Use `null` when durable state already owns the attempt limit. */
7
+ maxDeliveries: number | null;
8
+ onRejected(reason: QueueRejectReason | string, metadata: MessageMetadata, error?: unknown): void;
9
+ permanentError?: (error: unknown) => string | undefined;
10
+ run(message: Message, metadata: MessageMetadata): Promise<void>;
11
+ /**
12
+ * Acknowledge without checking or running the message.
13
+ * Use for kill switches that must not depend on signing secrets.
14
+ */
15
+ skip?: (metadata: MessageMetadata) => boolean;
16
+ topic: string;
17
+ verify(value: unknown): QueueVerifyResult<Message>;
18
+ visibilityTimeoutSeconds?: number;
19
+ }
20
+ /** Build the HTTP callback and local-dev consumer for one signed queue. */
21
+ export declare function queueCallback<Message>(options: QueueCallbackOptions<Message>): {
22
+ create: () => (requestOrEvent: Request | {
23
+ request: Request;
24
+ }) => Promise<Response>;
25
+ registerDev: () => (() => void) | undefined;
26
+ };
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ export declare const QUEUE_SIGNATURE_MAX_AGE_MS: number;
3
+ export type QueueRejectReason = "expired" | "malformed" | "signature_mismatch";
4
+ export type QueueVerifyResult<Message> = {
5
+ status: "verified";
6
+ message: Message;
7
+ } | {
8
+ status: "rejected";
9
+ reason: QueueRejectReason;
10
+ } | {
11
+ status: "unavailable";
12
+ reason: "invalid_clock" | "missing_secret";
13
+ };
14
+ export interface QueueSignConfig<Message extends object, Version extends string> {
15
+ context: string;
16
+ maxAgeMs?: number;
17
+ schema: z.ZodType<Message>;
18
+ /** Kept for jobs that already signed with `:` instead of null bytes. */
19
+ separator?: string;
20
+ signatureVersion: Version;
21
+ parts(message: Message): readonly string[];
22
+ }
23
+ /** Sign one queue message. */
24
+ export declare function signQueueMessage<Message extends object, Version extends string>(config: QueueSignConfig<Message, Version>, message: Message, nowMs?: number): Message & {
25
+ signature: string;
26
+ signatureVersion: Version;
27
+ signedAtMs: number;
28
+ };
29
+ /** Check one signed queue message. */
30
+ export declare function verifyQueueMessage<Message extends object, Version extends string>(config: QueueSignConfig<Message, Version>, value: unknown, nowMs?: number): QueueVerifyResult<Message>;
@@ -33,8 +33,6 @@ export interface SandboxOptions {
33
33
  skills: SkillMetadata[];
34
34
  referenceFiles: string[];
35
35
  timeoutMs?: number;
36
- /** Durable-worker soft yield for long Workspace snapshot waits. */
37
- shouldYield?: () => boolean;
38
36
  traceContext?: LogContext;
39
37
  tracePropagation?: SandboxEgressTracePropagationConfig;
40
38
  credentialEgress?: CredentialContext;
@@ -38,8 +38,6 @@ interface SandboxRuntimeOptions {
38
38
  skills: SkillMetadata[];
39
39
  referenceFiles: string[];
40
40
  timeoutMs?: number;
41
- /** Durable-worker soft yield for long Workspace snapshot waits. */
42
- shouldYield?: () => boolean;
43
41
  traceContext?: LogContext;
44
42
  commandEnv?: () => Promise<Record<string, string>>;
45
43
  createNetworkPolicy?: (egressId: string, traceHeaders?: TracePropagationHeaders) => NetworkPolicy | undefined;
@@ -8,7 +8,7 @@ export declare function resolveHostDataPath(referenceFiles: string[], sandboxPat
8
8
  export declare function isHostFileMissingError(error: unknown): boolean;
9
9
  /** Copy the current skill set and reference files into a sandbox. */
10
10
  export declare function syncSkillsToSandbox(params: {
11
- sandbox: SandboxSession;
11
+ sandbox: Pick<SandboxSession, "mkDir" | "writeFiles">;
12
12
  skills: SkillMetadata[];
13
13
  referenceFiles?: string[];
14
14
  withSpan: <T>(name: string, op: string, attributes: Record<string, unknown>, callback: () => Promise<T>) => Promise<T>;
@@ -0,0 +1,23 @@
1
+ import type { ResourceEvent, SubscribableResource } from "@sentry/junior-plugin-api";
2
+ export declare const WORKSPACE_SNAPSHOT_NAMESPACE = "junior";
3
+ export declare const WORKSPACE_SNAPSHOT_RESOURCE_TYPE = "workspace_snapshot";
4
+ export declare const WORKSPACE_SNAPSHOT_READY_EVENT = "workspace_snapshot.ready";
5
+ export declare const WORKSPACE_SNAPSHOT_FAILED_EVENT = "workspace_snapshot.failed";
6
+ /** Describe the events that report when a snapshot build ends. */
7
+ export declare function workspaceSnapshotWatch(input: {
8
+ workspaceId: string;
9
+ workspaceName: string;
10
+ }): SubscribableResource;
11
+ type WorkspaceSnapshotResult = {
12
+ workspaceId: string;
13
+ resultId: string;
14
+ occurredAtMs?: number;
15
+ } & ({
16
+ status: "ready";
17
+ } | {
18
+ status: "failed";
19
+ error?: string | null;
20
+ });
21
+ /** Report that a Workspace snapshot build is ready or failed. */
22
+ export declare function workspaceSnapshotFinishedEvent(input: WorkspaceSnapshotResult): ResourceEvent;
23
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare const WORKSPACE_SNAPSHOT_JOB_DEV_CONSUMER_GROUP = "junior_workspace_snapshots_dev";
2
+ /** Create the HTTP route for snapshot build messages. */
3
+ export declare function createVercelWorkspaceSnapshotJobCallback(): (request: Request) => Promise<Response>;
4
+ /** Receive snapshot build messages during local development. */
5
+ export declare function registerVercelWorkspaceSnapshotJobDevConsumer(): (() => void) | undefined;
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ export declare const WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC = "junior_workspace_snapshots";
3
+ declare const workspaceSnapshotJobMessageSchema: z.ZodObject<{
4
+ workspaceId: z.ZodString;
5
+ profileHash: z.ZodString;
6
+ }, z.core.$strict>;
7
+ export type WorkspaceSnapshotJobMessage = z.output<typeof workspaceSnapshotJobMessageSchema>;
8
+ /** Sign a Workspace snapshot job for tests and local checks. */
9
+ export declare function signWorkspaceSnapshotJobMessage(message: WorkspaceSnapshotJobMessage, nowMs?: number): {
10
+ workspaceId: string;
11
+ profileHash: string;
12
+ } & {
13
+ signature: string;
14
+ signatureVersion: "v1";
15
+ signedAtMs: number;
16
+ };
17
+ /** Check that a recent queue message came from Junior. */
18
+ export declare function verifyWorkspaceSnapshotJobMessage(value: unknown, nowMs?: number): import("@/chat/queue/sign").QueueVerifyResult<{
19
+ workspaceId: string;
20
+ profileHash: string;
21
+ }>;
22
+ /** Send a job unless the same Workspace build already has one. */
23
+ export declare function sendWorkspaceSnapshotJob(message: WorkspaceSnapshotJobMessage): Promise<void>;
24
+ /** Send the next job for a Workspace build that is still running. */
25
+ export declare function sendNextWorkspaceSnapshotJob(message: WorkspaceSnapshotJobMessage): Promise<void>;
26
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { Workspace } from "@/chat/workspaces/types";
2
+ import { type WorkspaceSnapshotJobMessage } from "./job-queue";
3
+ /** Run a snapshot build and send another job if it needs more time. */
4
+ export declare function processWorkspaceSnapshotJob(message: WorkspaceSnapshotJobMessage, options?: {
5
+ signal?: AbortSignal;
6
+ }): Promise<void>;
7
+ /** Start a snapshot build when no ready snapshot exists. */
8
+ export declare function ensureWorkspaceSnapshotBuild(input: {
9
+ workspace: Workspace;
10
+ sendAgain?: boolean;
11
+ }): Promise<"ready" | "building">;
@@ -0,0 +1,6 @@
1
+ /** Report that a Workspace snapshot is not ready to use. */
2
+ export declare class WorkspaceSnapshotNotReadyError extends Error {
3
+ constructor(workspaceName: string);
4
+ }
5
+ /** Check an error and its causes for a snapshot that is not ready. */
6
+ export declare function isWorkspaceSnapshotNotReadyError(error: unknown): boolean;
@@ -1,16 +1,22 @@
1
1
  import type { Snapshot } from "@/chat/sandbox/snapshot/resolve";
2
2
  import { type SandboxSession } from "@/chat/sandbox/workspace";
3
3
  import type { Workspace } from "@/chat/workspaces/types";
4
+ /** Return the ready snapshot or report that the Workspace must build one. */
5
+ export declare function requireReadyWorkspaceSnapshot(params: {
6
+ workspace: Workspace;
7
+ runtime: string;
8
+ staleSnapshotId?: string;
9
+ }): Promise<Snapshot>;
4
10
  /**
5
- * Resolve a Workspace snapshot through resumable execution slices.
6
- * Cold builds have one shared one-hour budget across every execution slice.
11
+ * Continue a Workspace snapshot build from its saved state.
12
+ * The full build can run for up to one hour.
7
13
  */
8
14
  export declare function resolveWorkspaceSnapshot(params: {
9
15
  workspace: Workspace;
10
16
  runtime: string;
11
17
  staleSnapshotId?: string;
12
18
  signal?: AbortSignal;
13
- shouldYield?: () => boolean;
19
+ shouldStop?: () => boolean;
14
20
  applyNetworkPolicy(sandbox: SandboxSession): Promise<unknown>;
15
21
  prepareRepositories?(sandbox: SandboxSession, workspace: Workspace, signal?: AbortSignal): Promise<void>;
16
22
  removeCredentialRoute: boolean;
@@ -2,8 +2,8 @@ import type { ThinkingLevel as AgentThinkingLevel } from "@earendil-works/pi-age
2
2
  import type { ThinkingLevel as ProviderThinkingLevel } from "@earendil-works/pi-ai";
3
3
  import { z } from "zod";
4
4
  import { type TurnReasoningLevel } from "@/chat/reasoning-level";
5
- import { type ModelProfile, type ExecutionProfileConfig } from "@/chat/model-profile";
6
- declare function createTurnRouteSchema(profiles: Readonly<Record<string, ExecutionProfileConfig>>): z.ZodObject<{
5
+ import { type ModelProfile, type ModelProfileConfig } from "@/chat/model-profile";
6
+ declare function createTurnRouteSchema(profiles: Readonly<Record<string, ModelProfileConfig>>): z.ZodObject<{
7
7
  reasoning_level: z.ZodEnum<{
8
8
  low: "low";
9
9
  medium: "medium";
@@ -49,9 +49,10 @@ export declare function selectTurnRoute(args: {
49
49
  threadId?: string;
50
50
  };
51
51
  currentTurnBlocks?: string[];
52
+ defaultProfile: ModelProfile;
52
53
  fastModelId: string;
53
54
  messageText: string;
54
- profiles: Readonly<Record<string, ExecutionProfileConfig>>;
55
+ profiles: Readonly<Record<string, ModelProfileConfig>>;
55
56
  }): Promise<TurnRoute>;
56
57
  /** Convert a routing bucket into the Pi Agent reasoning setting for a main turn. */
57
58
  export declare function toPiReasoningLevel(level: TurnRoute["reasoningLevel"]): AgentThinkingLevel | "off";
@@ -8,6 +8,7 @@ import type { Destination, Source } from "@sentry/junior-plugin-api";
8
8
  import type { ConversationStore } from "@/chat/conversations/store";
9
9
  export interface TurnSessionRouting {
10
10
  destination: Destination;
11
+ locationId?: string;
11
12
  source: Source;
12
13
  }
13
14
  /** Require conversation destination and session source from SQL. */
@@ -1,28 +1,17 @@
1
- import { z } from "zod";
1
+ import { type QueueVerifyResult } from "@/chat/queue/sign";
2
2
  import { type ConversationQueueMessage } from "./queue";
3
3
  export declare const CONVERSATION_WORK_QUEUE_SIGNATURE_MAX_SKEW_MS: number;
4
- declare const signedConversationQueueMessageSchema: z.ZodObject<{
5
- schemaVersion: z.ZodLiteral<2>;
6
- conversationId: z.ZodString;
7
- signature: z.ZodString;
8
- signatureVersion: z.ZodLiteral<"v2">;
9
- signedAtMs: z.ZodNumber;
10
- }, z.core.$strict>;
11
- type SignedConversationQueueMessage = z.output<typeof signedConversationQueueMessageSchema>;
12
- export type ConversationQueueMessageVerificationResult = {
13
- message: ConversationQueueMessage;
14
- status: "verified";
15
- } | {
16
- reason: "expired" | "malformed" | "signature_mismatch";
17
- status: "rejected";
18
- } | {
19
- reason: "invalid_clock" | "missing_secret";
20
- status: "unavailable";
21
- };
4
+ export type ConversationQueueMessageVerificationResult = QueueVerifyResult<ConversationQueueMessage>;
22
5
  /** Sign a conversation queue payload before it crosses the public callback route. */
23
- export declare function signConversationQueueMessage(message: ConversationQueueMessage, nowMs?: number): SignedConversationQueueMessage;
6
+ export declare function signConversationQueueMessage(message: ConversationQueueMessage, nowMs?: number): {
7
+ schemaVersion: 2;
8
+ conversationId: string;
9
+ } & {
10
+ signature: string;
11
+ signatureVersion: "v2";
12
+ signedAtMs: number;
13
+ };
24
14
  /** Explain whether a queue payload is verified, rejected, or unavailable. */
25
15
  export declare function verifyConversationQueueMessage(value: unknown, nowMs?: number): ConversationQueueMessageVerificationResult;
26
16
  /** Verify a signed conversation queue payload from the Vercel Queue callback. */
27
17
  export declare function verifySignedConversationQueueMessage(value: unknown, nowMs?: number): ConversationQueueMessage | undefined;
28
- export {};
@@ -86,6 +86,11 @@ export interface Lease {
86
86
  lastCheckInAtMs: number;
87
87
  token: string;
88
88
  }
89
+ /** Durable request to stop the current Conversation run. */
90
+ export interface ConversationStop {
91
+ inboundMessageIds: string[];
92
+ runId: string;
93
+ }
89
94
  export interface ConversationExecution {
90
95
  inboundMessageIds: string[];
91
96
  lastCheckpointAtMs?: number;
@@ -97,6 +102,7 @@ export interface ConversationExecution {
97
102
  pendingMessages: InboundMessage[];
98
103
  runId?: string;
99
104
  status: ExecutionStatus;
105
+ stop?: ConversationStop;
100
106
  updatedAtMs?: number;
101
107
  }
102
108
  export interface Conversation {
@@ -143,6 +149,26 @@ export interface AppendInboundMessageResult {
143
149
  export interface AppendAndEnqueueInboundMessageResult extends AppendInboundMessageResult {
144
150
  queueMessageId?: string;
145
151
  }
152
+ /** Result of requesting that the current Conversation run stop. */
153
+ export type StopConversationWorkResult = {
154
+ status: "no_work";
155
+ } | {
156
+ runId: string;
157
+ status: "requested";
158
+ };
159
+ /** Result of clearing one stop observed by the matching leased run. */
160
+ export interface CompleteConversationStopResult {
161
+ status: "cleared" | "lost_lease" | "none";
162
+ removedInboundMessageIds: string[];
163
+ }
164
+ /** Result of an append that rejects new work while a Conversation is runnable. */
165
+ export type AppendExclusiveInboundMessageResult = AppendInboundMessageResult | {
166
+ status: "active";
167
+ };
168
+ /** Exclusive append result with an optional queue delivery id. */
169
+ export type AppendAndEnqueueExclusiveInboundMessageResult = AppendAndEnqueueInboundMessageResult | {
170
+ status: "active";
171
+ };
146
172
  export interface RequestConversationWorkResult {
147
173
  status: "created" | "updated";
148
174
  }
@@ -168,6 +194,12 @@ export declare function appendInboundMessage(args: {
168
194
  nowMs?: number;
169
195
  state?: StateAdapter;
170
196
  }): Promise<AppendInboundMessageResult>;
197
+ /** Append only when the Conversation has no other runnable work. */
198
+ export declare function appendExclusiveInboundMessage(args: {
199
+ message: InboundMessage;
200
+ nowMs?: number;
201
+ state?: StateAdapter;
202
+ }): Promise<AppendExclusiveInboundMessageResult>;
171
203
  /** Mark a conversation runnable when there is no new mailbox message. */
172
204
  export declare function requestConversationWork(args: {
173
205
  conversationId: string;
@@ -256,6 +288,20 @@ export declare function ackMessages(args: {
256
288
  nowMs?: number;
257
289
  state?: StateAdapter;
258
290
  }): Promise<boolean>;
291
+ /** Persist a stop request for the current run without process affinity. */
292
+ export declare function stopConversationWork(args: {
293
+ conversationId: string;
294
+ nowMs?: number;
295
+ state?: StateAdapter;
296
+ }): Promise<StopConversationWorkResult>;
297
+ /** Clear one observed stop request and discard older human-facing mailbox work. */
298
+ export declare function completeConversationStop(args: {
299
+ conversationId: string;
300
+ leaseToken: string;
301
+ nowMs?: number;
302
+ runId: string;
303
+ state?: StateAdapter;
304
+ }): Promise<CompleteConversationStopResult>;
259
305
  /** Cancel human-facing pending mailbox rows without requiring a worker lease. */
260
306
  export declare function cancelHumanFacingPendingMessages(args: {
261
307
  conversationId: string;
@@ -301,6 +347,8 @@ export declare function completeConversationWork(args: {
301
347
  leaseToken: string;
302
348
  madeProgress?: boolean;
303
349
  nowMs?: number;
350
+ /** Keep a raced stop runnable after a stop-aware adapter returns. */
351
+ resumeIfStopped?: boolean;
304
352
  state?: StateAdapter;
305
353
  }): Promise<"completed" | "lost_lease" | "pending">;
306
354
  /** Failure outcome: `lost_lease` (another owner took over), `recorded` (retry counted), or `skipped` (durable progress was made). */