@sentry/junior 0.65.0 → 0.65.1
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/app.d.ts +3 -0
- package/dist/app.js +3299 -1343
- package/dist/chat/agent-dispatch/heartbeat.d.ts +8 -0
- package/dist/chat/agent-dispatch/store.d.ts +2 -2
- package/dist/chat/agent-dispatch/types.d.ts +8 -22
- package/dist/chat/agent-dispatch/validation.d.ts +3 -1
- package/dist/chat/app/production.d.ts +11 -5
- package/dist/chat/capabilities/factory.d.ts +2 -1
- package/dist/chat/capabilities/router.d.ts +3 -2
- package/dist/chat/config.d.ts +5 -0
- package/dist/chat/credentials/broker.d.ts +2 -1
- package/dist/chat/credentials/context.d.ts +28 -0
- package/dist/chat/credentials/subject.d.ts +20 -0
- package/dist/chat/ingress/slack-webhook.d.ts +19 -0
- package/dist/chat/mcp/errors.d.ts +1 -1
- package/dist/chat/plugins/github-permissions.d.ts +11 -0
- package/dist/chat/plugins/types.d.ts +2 -0
- package/dist/chat/prompt.d.ts +2 -0
- package/dist/chat/respond-helpers.d.ts +4 -2
- package/dist/chat/respond.d.ts +23 -13
- package/dist/chat/runtime/processing-reaction.d.ts +1 -0
- package/dist/chat/runtime/reply-executor.d.ts +5 -0
- package/dist/chat/runtime/request-deadline.d.ts +8 -0
- package/dist/chat/runtime/slack-resume.d.ts +4 -5
- package/dist/chat/runtime/slack-runtime.d.ts +10 -0
- package/dist/chat/runtime/thread-context.d.ts +5 -2
- package/dist/chat/runtime/timeout-resume-runner.d.ts +19 -0
- package/dist/chat/runtime/turn-preparation.d.ts +1 -0
- package/dist/chat/runtime/turn.d.ts +13 -0
- package/dist/chat/sandbox/egress-policy.d.ts +1 -1
- package/dist/chat/sandbox/egress-session.d.ts +13 -12
- package/dist/chat/sandbox/sandbox.d.ts +2 -3
- package/dist/chat/services/timeout-resume.d.ts +9 -4
- package/dist/chat/services/turn-session-record.d.ts +19 -2
- package/dist/chat/slack/adapter-context.d.ts +25 -0
- package/dist/chat/slack/conversation-context.d.ts +28 -0
- package/dist/chat/state/turn-session.d.ts +1 -1
- package/dist/chat/task-execution/heartbeat.d.ts +13 -0
- package/dist/chat/task-execution/queue-signing.d.ts +12 -0
- package/dist/chat/task-execution/queue.d.ts +13 -0
- package/dist/chat/task-execution/slack-work.d.ts +32 -0
- package/dist/chat/task-execution/store.d.ts +153 -0
- package/dist/chat/task-execution/vercel-callback.d.ts +21 -0
- package/dist/chat/task-execution/vercel-queue.d.ts +16 -0
- package/dist/chat/task-execution/worker.d.ts +28 -0
- package/dist/{chunk-EDHJIYHS.js → chunk-657CJCUO.js} +218 -62
- package/dist/chunk-6YY4Q3D4.js +12 -0
- package/dist/chunk-75UZ4JLC.js +213 -0
- package/dist/{chunk-PYU2YB35.js → chunk-F57QSMOJ.js} +1 -1
- package/dist/{chunk-K3JNVV4Q.js → chunk-HRQQS63X.js} +2 -2
- package/dist/{chunk-SCQPBJAU.js → chunk-QUXPUKBH.js} +1 -7
- package/dist/{chunk-7KZXQNA6.js → chunk-X2HJLKQT.js} +368 -13
- package/dist/{chunk-OMQ5X5QH.js → chunk-ZOV3XJAH.js} +3 -2
- package/dist/cli/check.js +115 -2
- package/dist/cli/init.js +13 -1
- package/dist/cli/snapshot-warmup.js +3 -3
- package/dist/deployment.d.ts +4 -0
- package/dist/handlers/heartbeat.d.ts +5 -1
- package/dist/handlers/turn-resume.d.ts +3 -2
- package/dist/handlers/webhooks.d.ts +11 -9
- package/dist/nitro.d.ts +3 -1
- package/dist/nitro.js +48 -4
- package/dist/reporting.js +13 -16
- package/dist/vercel.d.ts +1 -1
- package/dist/vercel.js +1 -1
- package/package.json +5 -4
- package/dist/chat/services/turn-continuation-response.d.ts +0 -2
- package/dist/chat/slack/turn-continuation-notice.d.ts +0 -8
- package/dist/chunk-5VDO6LSG.js +0 -104
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
2
|
+
/** Re-drive stale turn continuations whose internal callback vanished. */
|
|
3
|
+
export declare function recoverStaleTimeoutResumes(args: {
|
|
4
|
+
conversationWorkQueue?: ConversationWorkQueue;
|
|
5
|
+
limit?: number;
|
|
6
|
+
nowMs: number;
|
|
7
|
+
}): Promise<number>;
|
|
1
8
|
/** Re-drive stale core dispatches before invoking plugin heartbeat hooks. */
|
|
2
9
|
export declare function recoverStaleDispatches(args: {
|
|
3
10
|
limit?: number;
|
|
@@ -10,5 +17,6 @@ export declare function runTrustedPluginHeartbeats(args: {
|
|
|
10
17
|
}): Promise<void>;
|
|
11
18
|
/** Run the core heartbeat phases. */
|
|
12
19
|
export declare function runHeartbeat(args: {
|
|
20
|
+
conversationWorkQueue?: ConversationWorkQueue;
|
|
13
21
|
nowMs: number;
|
|
14
22
|
}): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StateAdapter } from "chat";
|
|
2
|
-
import type {
|
|
2
|
+
import type { BoundDispatchOptions, DispatchCreateResult, DispatchProjection, DispatchRecord, DispatchStatus } from "./types";
|
|
3
3
|
/** Keep dispatch persistence keys consistent across callback and recovery paths. */
|
|
4
4
|
export declare function getDispatchStorageKey(id: string): string;
|
|
5
5
|
/** Map a dispatch destination to the lock key that serializes Slack delivery. */
|
|
@@ -17,7 +17,7 @@ export declare function getDispatchRecord(id: string): Promise<DispatchRecord |
|
|
|
17
17
|
/** Create a plugin dispatch idempotently from the plugin's idempotency key. */
|
|
18
18
|
export declare function createOrGetDispatch(args: {
|
|
19
19
|
nowMs: number;
|
|
20
|
-
options:
|
|
20
|
+
options: BoundDispatchOptions;
|
|
21
21
|
plugin: string;
|
|
22
22
|
}): Promise<DispatchCreateResult>;
|
|
23
23
|
/** Advance dispatch versions so stale callbacks cannot overwrite newer state. */
|
|
@@ -1,30 +1,16 @@
|
|
|
1
|
+
import type { DispatchOptions as AgentPluginDispatchOptions } from "@sentry/junior-plugin-api";
|
|
2
|
+
import type { CredentialSubject, CredentialSystemActor } from "@/chat/credentials/context";
|
|
1
3
|
export type DispatchStatus = "pending" | "running" | "awaiting_resume" | "completed" | "failed" | "blocked";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export interface DispatchDestination {
|
|
7
|
-
platform: "slack";
|
|
8
|
-
teamId: string;
|
|
9
|
-
channelId: string;
|
|
10
|
-
}
|
|
11
|
-
export interface DispatchCredentialSubject {
|
|
12
|
-
type: "user";
|
|
13
|
-
userId: string;
|
|
14
|
-
allowedWhen: "private-direct-conversation";
|
|
15
|
-
}
|
|
16
|
-
export interface DispatchOptions {
|
|
17
|
-
credentialSubject?: DispatchCredentialSubject;
|
|
18
|
-
destination: DispatchDestination;
|
|
19
|
-
idempotencyKey: string;
|
|
20
|
-
input: string;
|
|
21
|
-
metadata?: Record<string, string>;
|
|
4
|
+
export type DispatchOptions = AgentPluginDispatchOptions;
|
|
5
|
+
export type DispatchDestination = DispatchOptions["destination"];
|
|
6
|
+
export interface BoundDispatchOptions extends Omit<DispatchOptions, "credentialSubject"> {
|
|
7
|
+
credentialSubject?: CredentialSubject;
|
|
22
8
|
}
|
|
23
9
|
export interface DispatchRecord {
|
|
24
|
-
actor:
|
|
10
|
+
actor: CredentialSystemActor;
|
|
25
11
|
attempt: number;
|
|
26
12
|
createdAtMs: number;
|
|
27
|
-
credentialSubject?:
|
|
13
|
+
credentialSubject?: CredentialSubject;
|
|
28
14
|
destination: DispatchDestination;
|
|
29
15
|
errorMessage?: string;
|
|
30
16
|
id: string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import type { DispatchOptions } from "./types";
|
|
1
|
+
import type { BoundDispatchOptions, DispatchOptions } from "./types";
|
|
2
2
|
/** Validate plugin-provided dispatch options before core persists them. */
|
|
3
3
|
export declare function validateDispatchOptions(options: DispatchOptions): void;
|
|
4
|
+
/** Verify runtime-owned access requirements for delegated dispatch credentials. */
|
|
5
|
+
export declare function verifyDispatchCredentialSubjectAccess(options: BoundDispatchOptions): Promise<void>;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { SlackAdapter } from "@chat-adapter/slack";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { createSlackRuntime } from "@/chat/app/factory";
|
|
3
|
+
import type { SlackWebhookServices } from "@/chat/ingress/slack-webhook";
|
|
4
|
+
import type { VercelConversationWorkCallbackOptions } from "@/chat/task-execution/vercel-callback";
|
|
5
|
+
/** Return the lazily initialized production Slack adapter. */
|
|
6
|
+
export declare function getProductionSlackAdapter(): SlackAdapter;
|
|
7
|
+
/** Return the lazily initialized production Slack runtime. */
|
|
8
|
+
export declare function getProductionSlackRuntime(): ReturnType<typeof createSlackRuntime>;
|
|
9
|
+
/** Return production services for Slack webhook ingress. */
|
|
10
|
+
export declare function getProductionSlackWebhookServices(): SlackWebhookServices;
|
|
11
|
+
/** Return the production queue callback options for conversation work. */
|
|
12
|
+
export declare function getProductionConversationWorkOptions(): VercelConversationWorkCallbackOptions;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { CredentialLease } from "@/chat/credentials/broker";
|
|
2
|
+
import type { CredentialContext } from "@/chat/credentials/context";
|
|
2
3
|
import type { UserTokenStore } from "@/chat/credentials/user-token-store";
|
|
3
4
|
/** Create the user token store used by OAuth-backed credential brokers. */
|
|
4
5
|
export declare function createUserTokenStore(): UserTokenStore;
|
|
5
6
|
/** Issue one provider credential lease for host-side sandbox egress proxying. */
|
|
6
7
|
export declare function issueProviderCredentialLease(input: {
|
|
8
|
+
context: CredentialContext;
|
|
7
9
|
provider: string;
|
|
8
|
-
requesterId: string;
|
|
9
10
|
reason: string;
|
|
10
11
|
}): Promise<CredentialLease>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { CredentialBroker, CredentialLease } from "@/chat/credentials/broker";
|
|
2
|
+
import type { CredentialContext } from "@/chat/credentials/context";
|
|
2
3
|
export interface CredentialRouter {
|
|
3
4
|
issue(input: {
|
|
5
|
+
context: CredentialContext;
|
|
4
6
|
provider: string;
|
|
5
7
|
reason: string;
|
|
6
|
-
requesterId?: string;
|
|
7
8
|
}): Promise<CredentialLease>;
|
|
8
9
|
}
|
|
9
10
|
export declare class ProviderCredentialRouter implements CredentialRouter {
|
|
@@ -12,8 +13,8 @@ export declare class ProviderCredentialRouter implements CredentialRouter {
|
|
|
12
13
|
brokersByProvider: Record<string, CredentialBroker>;
|
|
13
14
|
});
|
|
14
15
|
issue(input: {
|
|
16
|
+
context: CredentialContext;
|
|
15
17
|
provider: string;
|
|
16
18
|
reason: string;
|
|
17
|
-
requesterId?: string;
|
|
18
19
|
}): Promise<CredentialLease>;
|
|
19
20
|
}
|
package/dist/chat/config.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
declare const ADVISOR_THINKING_LEVELS: readonly ["minimal", "low", "medium", "high", "xhigh"];
|
|
2
2
|
export type AdvisorThinkingLevel = (typeof ADVISOR_THINKING_LEVELS)[number];
|
|
3
|
+
/**
|
|
4
|
+
* Buffer between the Vercel function timeout and the agent turn timeout so
|
|
5
|
+
* Junior can abort, persist, and schedule continuation before host teardown.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FUNCTION_TIMEOUT_BUFFER_SECONDS = 20;
|
|
3
8
|
export interface BotConfig {
|
|
4
9
|
advisor: AdvisorConfig;
|
|
5
10
|
fastModelId: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CredentialContext } from "@/chat/credentials/context";
|
|
1
2
|
export declare class CredentialUnavailableError extends Error {
|
|
2
3
|
readonly provider: string;
|
|
3
4
|
constructor(provider: string, message: string);
|
|
@@ -16,7 +17,7 @@ export interface CredentialLease {
|
|
|
16
17
|
}
|
|
17
18
|
export interface CredentialBroker {
|
|
18
19
|
issue(input: {
|
|
20
|
+
context: CredentialContext;
|
|
19
21
|
reason: string;
|
|
20
|
-
requesterId?: string;
|
|
21
22
|
}): Promise<CredentialLease>;
|
|
22
23
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentPluginCredentialSubject } from "@sentry/junior-plugin-api";
|
|
2
|
+
export interface CredentialSubjectBinding {
|
|
3
|
+
type: "slack-direct-conversation";
|
|
4
|
+
teamId: string;
|
|
5
|
+
channelId: string;
|
|
6
|
+
signature: string;
|
|
7
|
+
}
|
|
8
|
+
export type CredentialSystemActor = {
|
|
9
|
+
type: "system";
|
|
10
|
+
id: string;
|
|
11
|
+
};
|
|
12
|
+
export type CredentialSubject = AgentPluginCredentialSubject & {
|
|
13
|
+
binding: CredentialSubjectBinding;
|
|
14
|
+
};
|
|
15
|
+
export type CredentialContext = {
|
|
16
|
+
actor: {
|
|
17
|
+
type: "user";
|
|
18
|
+
userId: string;
|
|
19
|
+
};
|
|
20
|
+
subject?: never;
|
|
21
|
+
} | {
|
|
22
|
+
actor: CredentialSystemActor;
|
|
23
|
+
subject?: CredentialSubject;
|
|
24
|
+
};
|
|
25
|
+
/** Return the user whose OAuth token may satisfy this credential request. */
|
|
26
|
+
export declare function credentialUserSubjectId(context: CredentialContext): string | undefined;
|
|
27
|
+
/** Parse an untrusted credential context payload from sandbox egress state. */
|
|
28
|
+
export declare function parseCredentialContext(value: unknown): CredentialContext | undefined;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentPluginCredentialSubject } from "@sentry/junior-plugin-api";
|
|
2
|
+
import type { CredentialSubject } from "@/chat/credentials/context";
|
|
3
|
+
/** Create a delegated user credential subject for a verified Slack DM turn. */
|
|
4
|
+
export declare function createSlackDirectCredentialSubject(input: {
|
|
5
|
+
channelId: string | undefined;
|
|
6
|
+
teamId: string | undefined;
|
|
7
|
+
userId: string | undefined;
|
|
8
|
+
}): AgentPluginCredentialSubject | undefined;
|
|
9
|
+
/** Bind a delegated user subject to the Slack DM destination being dispatched. */
|
|
10
|
+
export declare function bindSlackDirectCredentialSubject(input: {
|
|
11
|
+
channelId: string;
|
|
12
|
+
subject: AgentPluginCredentialSubject;
|
|
13
|
+
teamId: string;
|
|
14
|
+
}): CredentialSubject | undefined;
|
|
15
|
+
/** Verify that a delegated subject was signed for the dispatch destination. */
|
|
16
|
+
export declare function verifySlackDirectCredentialSubject(input: {
|
|
17
|
+
channelId: string;
|
|
18
|
+
subject: CredentialSubject;
|
|
19
|
+
teamId: string;
|
|
20
|
+
}): boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SlackAdapter } from "@chat-adapter/slack";
|
|
2
|
+
import { type StateAdapter } from "chat";
|
|
3
|
+
import type { SlackTurnRuntime } from "@/chat/runtime/slack-runtime";
|
|
4
|
+
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
5
|
+
import type { UserTokenStore } from "@/chat/credentials/user-token-store";
|
|
6
|
+
import type { WaitUntilFn } from "@/handlers/types";
|
|
7
|
+
export interface SlackWebhookServices {
|
|
8
|
+
getUserTokenStore?: () => UserTokenStore;
|
|
9
|
+
getSlackAdapter: () => SlackAdapter;
|
|
10
|
+
queue: ConversationWorkQueue;
|
|
11
|
+
runtime: Pick<SlackTurnRuntime<unknown>, "handleAssistantContextChanged" | "handleAssistantThreadStarted" | "handleNewMention" | "handleSubscribedMessage">;
|
|
12
|
+
state?: StateAdapter;
|
|
13
|
+
}
|
|
14
|
+
/** Handle Slack webhooks by enqueueing durable conversation work. */
|
|
15
|
+
export declare function handleSlackWebhook(args: {
|
|
16
|
+
request: Request;
|
|
17
|
+
services: SlackWebhookServices;
|
|
18
|
+
waitUntil: WaitUntilFn;
|
|
19
|
+
}): Promise<Response>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type GitHubPermissionRequest = Record<string, "read" | "write">;
|
|
2
|
+
export declare const DEFAULT_GITHUB_SYSTEM_READ_SCOPES: Set<string>;
|
|
3
|
+
/** Validate and normalize GitHub App read scopes from plugin configuration. */
|
|
4
|
+
export declare function normalizeGitHubSystemReadPermissionScopes(scopes: string[], context: string): string[];
|
|
5
|
+
/** Convert plugin capabilities into the GitHub App installation permission body. */
|
|
6
|
+
export declare function githubCapabilitiesToPermissions(capabilities: string[], pluginName: string): GitHubPermissionRequest;
|
|
7
|
+
/** Convert configured system scopes into read-only GitHub App permissions. */
|
|
8
|
+
export declare function githubSystemReadPermissionsFromScopes(scopes: string[]): GitHubPermissionRequest;
|
|
9
|
+
/** Intersect installation permissions with the allowed system read scope set. */
|
|
10
|
+
export declare function githubInstallationReadPermissions(permissions: Record<string, string> | undefined, allowedScopes: Set<string>): GitHubPermissionRequest;
|
|
11
|
+
export {};
|
|
@@ -28,6 +28,7 @@ export interface GitHubAppCredentials {
|
|
|
28
28
|
appIdEnv: string;
|
|
29
29
|
privateKeyEnv: string;
|
|
30
30
|
installationIdEnv: string;
|
|
31
|
+
systemReadPermissions?: string[];
|
|
31
32
|
}
|
|
32
33
|
export type PluginCredentials = OAuthBearerCredentials | GitHubAppCredentials;
|
|
33
34
|
export interface PluginNpmRuntimeDependency {
|
|
@@ -115,6 +116,7 @@ export interface PluginManifestConfig {
|
|
|
115
116
|
appIdEnv?: string;
|
|
116
117
|
privateKeyEnv?: string;
|
|
117
118
|
installationIdEnv?: string;
|
|
119
|
+
systemReadPermissions?: string[];
|
|
118
120
|
} | null;
|
|
119
121
|
runtimeDependencies?: PluginRuntimeDependencyConfig[] | null;
|
|
120
122
|
runtimePostinstall?: PluginRuntimePostinstallCommand[] | null;
|
package/dist/chat/prompt.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SlackConversationContext } from "@/chat/slack/conversation-context";
|
|
1
2
|
import type { ThreadArtifactsState } from "@/chat/state/artifacts";
|
|
2
3
|
import type { SkillMetadata, SkillInvocation } from "@/chat/skills";
|
|
3
4
|
import type { ActiveMcpCatalogSummary } from "@/chat/tools/skill/mcp-tool-summary";
|
|
@@ -15,6 +16,7 @@ type TurnContextPromptInput = {
|
|
|
15
16
|
toolGuidance?: ToolPromptContext[];
|
|
16
17
|
runtime?: {
|
|
17
18
|
conversationId?: string;
|
|
19
|
+
slackConversation?: SlackConversationContext;
|
|
18
20
|
};
|
|
19
21
|
invocation: SkillInvocation | null;
|
|
20
22
|
requester?: {
|
|
@@ -63,8 +63,10 @@ export declare function isToolResultError(result: unknown): boolean;
|
|
|
63
63
|
export declare function isAssistantMessage(value: unknown): value is AssistantMessage;
|
|
64
64
|
/** Extract role string from a raw Pi message. */
|
|
65
65
|
export declare function getPiMessageRole(value: unknown): string | undefined;
|
|
66
|
-
/**
|
|
67
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Add bootstrap context only for stored boundaries captured before prompt().
|
|
68
|
+
*/
|
|
69
|
+
export declare function prependMissingRuntimeTurnContext(messages: PiMessage[], turnContextPrompt: string): PiMessage[];
|
|
68
70
|
/** Return whether Pi history already carries session bootstrap context. */
|
|
69
71
|
export declare function hasRuntimeTurnContext(messages: PiMessage[]): boolean;
|
|
70
72
|
/** Remove volatile runtime context before reusing messages as history. */
|
package/dist/chat/respond.d.ts
CHANGED
|
@@ -5,22 +5,21 @@ import type { ImageGenerateToolDeps, WebFetchToolDeps, WebSearchToolDeps } from
|
|
|
5
5
|
import type { PiMessage } from "@/chat/pi/messages";
|
|
6
6
|
import { type SandboxAcquiredState } from "@/chat/sandbox/sandbox";
|
|
7
7
|
import type { AssistantStatusSpec } from "@/chat/slack/assistant-thread/status";
|
|
8
|
+
import type { SlackConversationContext } from "@/chat/slack/conversation-context";
|
|
8
9
|
import { type AssistantReply, type AgentTurnDiagnostics } from "@/chat/services/turn-result";
|
|
10
|
+
import type { CredentialContext } from "@/chat/credentials/context";
|
|
9
11
|
import { type AuthorizationFlowMode } from "@/chat/services/auth-pause";
|
|
10
12
|
export type { AssistantReply, AgentTurnDiagnostics };
|
|
11
13
|
export interface ReplyRequestContext {
|
|
12
14
|
skillDirs?: string[];
|
|
13
|
-
|
|
14
|
-
type: "user";
|
|
15
|
-
userId: string;
|
|
16
|
-
allowedWhen: "private-direct-conversation";
|
|
17
|
-
};
|
|
15
|
+
credentialContext?: CredentialContext;
|
|
18
16
|
requester?: {
|
|
19
17
|
userId?: string;
|
|
20
18
|
userName?: string;
|
|
21
19
|
fullName?: string;
|
|
22
20
|
email?: string;
|
|
23
21
|
};
|
|
22
|
+
slackConversation?: SlackConversationContext;
|
|
24
23
|
correlation?: {
|
|
25
24
|
conversationId?: string;
|
|
26
25
|
threadId?: string;
|
|
@@ -32,8 +31,6 @@ export interface ReplyRequestContext {
|
|
|
32
31
|
messageTs?: string;
|
|
33
32
|
threadTs?: string;
|
|
34
33
|
requesterId?: string;
|
|
35
|
-
actorType?: string;
|
|
36
|
-
actorId?: string;
|
|
37
34
|
};
|
|
38
35
|
toolChannelId?: string;
|
|
39
36
|
conversationContext?: string;
|
|
@@ -43,13 +40,10 @@ export interface ReplyRequestContext {
|
|
|
43
40
|
configuration?: Record<string, unknown>;
|
|
44
41
|
/** Durable Pi transcript for this conversation, excluding ephemeral turn context. */
|
|
45
42
|
piMessages?: PiMessage[];
|
|
43
|
+
/** Absolute wall-clock deadline for this host request, in milliseconds. */
|
|
44
|
+
turnDeadlineAtMs?: number;
|
|
46
45
|
channelConfiguration?: ChannelConfigurationService;
|
|
47
|
-
userAttachments?:
|
|
48
|
-
data?: Buffer;
|
|
49
|
-
mediaType: string;
|
|
50
|
-
filename?: string;
|
|
51
|
-
promptText?: string;
|
|
52
|
-
}>;
|
|
46
|
+
userAttachments?: ReplyRequestAttachment[];
|
|
53
47
|
inboundAttachmentCount?: number;
|
|
54
48
|
omittedImageAttachmentCount?: number;
|
|
55
49
|
sandbox?: {
|
|
@@ -58,12 +52,16 @@ export interface ReplyRequestContext {
|
|
|
58
52
|
};
|
|
59
53
|
onSandboxAcquired?: (sandbox: SandboxAcquiredState) => void | Promise<void>;
|
|
60
54
|
onArtifactStateUpdated?: (artifactState: ThreadArtifactsState) => void | Promise<void>;
|
|
55
|
+
onInputCommitted?: () => void | Promise<void>;
|
|
61
56
|
toolOverrides?: {
|
|
62
57
|
imageGenerate?: ImageGenerateToolDeps;
|
|
63
58
|
webFetch?: WebFetchToolDeps;
|
|
64
59
|
webSearch?: WebSearchToolDeps;
|
|
65
60
|
};
|
|
66
61
|
onStatus?: (status: AssistantStatusSpec) => void | Promise<void>;
|
|
62
|
+
drainSteeringMessages?: (inject: (messages: ReplySteeringMessage[]) => Promise<void>) => Promise<ReplySteeringMessage[]>;
|
|
63
|
+
/** Return true when the durable worker should pause at the next Pi boundary. */
|
|
64
|
+
shouldYield?: () => boolean;
|
|
67
65
|
onAuthPending?: (pendingAuth: ConversationPendingAuthState) => void | Promise<void>;
|
|
68
66
|
onTextDelta?: (deltaText: string) => void | Promise<void>;
|
|
69
67
|
onAssistantMessageStart?: () => void | Promise<void>;
|
|
@@ -72,5 +70,17 @@ export interface ReplyRequestContext {
|
|
|
72
70
|
params: Record<string, unknown>;
|
|
73
71
|
}) => void;
|
|
74
72
|
}
|
|
73
|
+
export interface ReplyRequestAttachment {
|
|
74
|
+
data?: Buffer;
|
|
75
|
+
mediaType: string;
|
|
76
|
+
filename?: string;
|
|
77
|
+
promptText?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface ReplySteeringMessage {
|
|
80
|
+
omittedImageAttachmentCount?: number;
|
|
81
|
+
text: string;
|
|
82
|
+
timestampMs?: number;
|
|
83
|
+
userAttachments?: ReplyRequestAttachment[];
|
|
84
|
+
}
|
|
75
85
|
/** Run a full agent turn: discover skills, execute tools, and return the assistant reply. */
|
|
76
86
|
export declare function generateAssistantReply(messageText: string, context?: ReplyRequestContext): Promise<AssistantReply>;
|
|
@@ -2,6 +2,7 @@ import type { Message, Thread } from "chat";
|
|
|
2
2
|
import type { TurnToolInvocation } from "@/chat/runtime/turn-input";
|
|
3
3
|
/** Controls the automatic Slack processing reaction lifecycle for one message. */
|
|
4
4
|
export interface ProcessingReactionSession {
|
|
5
|
+
complete: () => Promise<void>;
|
|
5
6
|
keep: () => void;
|
|
6
7
|
stop: () => Promise<void>;
|
|
7
8
|
}
|
|
@@ -48,8 +48,13 @@ interface ReplyExecutorDeps {
|
|
|
48
48
|
export declare function createReplyToThread(deps: ReplyExecutorDeps): (thread: Thread, message: Message, options?: {
|
|
49
49
|
beforeFirstResponsePost?: () => Promise<void>;
|
|
50
50
|
explicitMention?: boolean;
|
|
51
|
+
onInputCommitted?: () => Promise<void>;
|
|
51
52
|
onToolInvocation?: (invocation: TurnToolInvocation) => void;
|
|
53
|
+
onTurnCompleted?: () => Promise<void>;
|
|
54
|
+
onTurnStatePersisted?: () => Promise<void>;
|
|
52
55
|
preparedState?: PreparedTurnState;
|
|
53
56
|
queuedMessages?: QueuedTurnMessage[];
|
|
57
|
+
drainSteeringMessages?: (inject: (messages: QueuedTurnMessage[]) => Promise<void>) => Promise<QueuedTurnMessage[]>;
|
|
58
|
+
shouldYield?: () => boolean;
|
|
54
59
|
}) => Promise<void>;
|
|
55
60
|
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface TurnRequestDeadline {
|
|
2
|
+
deadlineAtMs: number;
|
|
3
|
+
startedAtMs: number;
|
|
4
|
+
}
|
|
5
|
+
/** Return the host request deadline inherited by the current async turn. */
|
|
6
|
+
export declare function getTurnRequestDeadline(): TurnRequestDeadline | undefined;
|
|
7
|
+
/** Run work with one host request deadline shared by nested queued turns. */
|
|
8
|
+
export declare function runWithTurnRequestDeadline<T>(callback: () => T, startedAtMs?: number): T;
|
|
@@ -23,12 +23,11 @@ interface ResumeSlackTurnArgs {
|
|
|
23
23
|
/**
|
|
24
24
|
* Resume a paused Slack turn under the normal thread lock.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* never arrived.
|
|
26
|
+
* Started resumes own their terminal side effects: final delivery, pause
|
|
27
|
+
* persistence, or failure response. Returns false only when `beforeStart`
|
|
28
|
+
* proves the resume is stale before generation begins.
|
|
30
29
|
*/
|
|
31
|
-
export declare function resumeSlackTurn(args: ResumeSlackTurnArgs): Promise<
|
|
30
|
+
export declare function resumeSlackTurn(args: ResumeSlackTurnArgs): Promise<boolean>;
|
|
32
31
|
/** Resume an OAuth-paused Slack request through the shared resume runner. */
|
|
33
32
|
export declare function resumeAuthorizedRequest(args: {
|
|
34
33
|
messageText: string;
|
|
@@ -20,8 +20,12 @@ export interface AssistantLifecycleEvent {
|
|
|
20
20
|
}
|
|
21
21
|
export interface ReplyHooks {
|
|
22
22
|
beforeFirstResponsePost?: () => Promise<void>;
|
|
23
|
+
drainSteeringMessages?: (inject: (messages: Message[]) => Promise<void>) => Promise<Message[]>;
|
|
23
24
|
messageContext?: MessageContext;
|
|
25
|
+
onInputCommitted?: () => Promise<void>;
|
|
24
26
|
onToolInvocation?: (invocation: TurnToolInvocation) => void;
|
|
27
|
+
onTurnStatePersisted?: () => Promise<void>;
|
|
28
|
+
shouldYield?: () => boolean;
|
|
25
29
|
}
|
|
26
30
|
export interface SlackTurnRuntimeDependencies<TPreparedState> {
|
|
27
31
|
assistantUserName: string;
|
|
@@ -67,12 +71,18 @@ export interface SlackTurnRuntimeDependencies<TPreparedState> {
|
|
|
67
71
|
replyToThread: (thread: Thread, message: Message, options?: {
|
|
68
72
|
beforeFirstResponsePost?: () => Promise<void>;
|
|
69
73
|
explicitMention?: boolean;
|
|
74
|
+
onInputCommitted?: () => Promise<void>;
|
|
70
75
|
onToolInvocation?: (invocation: TurnToolInvocation) => void;
|
|
76
|
+
onTurnCompleted?: () => Promise<void>;
|
|
77
|
+
onTurnStatePersisted?: () => Promise<void>;
|
|
71
78
|
preparedState?: TPreparedState;
|
|
72
79
|
queuedMessages?: QueuedTurnMessage[];
|
|
80
|
+
drainSteeringMessages?: (inject: (messages: QueuedTurnMessage[]) => Promise<void>) => Promise<QueuedTurnMessage[]>;
|
|
81
|
+
shouldYield?: () => boolean;
|
|
73
82
|
}) => Promise<void>;
|
|
74
83
|
decideSubscribedReply: SubscribedReplyPolicy;
|
|
75
84
|
stripLeadingBotMention: (text: string, options: {
|
|
85
|
+
botUserId?: string;
|
|
76
86
|
stripLeadingSlackMentionToken?: boolean;
|
|
77
87
|
}) => string;
|
|
78
88
|
withSpan: (name: string, op: string, context: Record<string, unknown>, callback: () => Promise<void>) => Promise<void>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Message, Thread } from "chat";
|
|
2
|
-
|
|
2
|
+
interface StripLeadingBotMentionOptions {
|
|
3
|
+
botUserId?: string;
|
|
3
4
|
stripLeadingSlackMentionToken?: boolean;
|
|
4
|
-
}
|
|
5
|
+
}
|
|
6
|
+
export declare function stripLeadingBotMention(text: string, options?: StripLeadingBotMentionOptions): string;
|
|
5
7
|
export declare function getThreadId(thread: Thread, _message: Message): string | undefined;
|
|
6
8
|
export declare function getRunId(thread: Thread, message: Message): string | undefined;
|
|
7
9
|
export declare function getChannelId(thread: Thread, message: Message): string | undefined;
|
|
@@ -22,3 +24,4 @@ export declare function getAssistantThreadContext(message: Message): {
|
|
|
22
24
|
export declare function getMessageTs(message: Message): string | undefined;
|
|
23
25
|
/** Resolve the Slack workspace/team id from the raw inbound message payload. */
|
|
24
26
|
export declare function getTeamId(message: Message): string | undefined;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type TurnContinuationRequest } from "@/chat/services/timeout-resume";
|
|
2
|
+
/** Runtime ports for timeout continuation scheduling. */
|
|
3
|
+
export interface TimeoutResumeRunnerOptions {
|
|
4
|
+
scheduleTurnTimeoutResume?: (request: TurnContinuationRequest) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Resume one durable timeout continuation for a Slack thread.
|
|
8
|
+
*
|
|
9
|
+
* Returns false when the session became stale before generation began.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resumeTimedOutTurn(payload: TurnContinuationRequest, options?: TimeoutResumeRunnerOptions): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Retry timeout continuation when the normal Slack thread lock is briefly busy.
|
|
14
|
+
*
|
|
15
|
+
* Returns false when the session became stale before generation began. A busy
|
|
16
|
+
* lock that is rescheduled still returns true because runnable work remains
|
|
17
|
+
* durable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resumeTimedOutTurnWithLockRetry(payload: TurnContinuationRequest, options?: TimeoutResumeRunnerOptions): Promise<boolean>;
|
|
@@ -24,6 +24,19 @@ export declare class RetryableTurnError extends Error {
|
|
|
24
24
|
constructor(reason: RetryableTurnReason, message: string, metadata?: RetryableTurnMetadata);
|
|
25
25
|
}
|
|
26
26
|
export declare function isRetryableTurnError(error: unknown, reason?: RetryableTurnReason): error is RetryableTurnError;
|
|
27
|
+
/** Error indicating the turn paused voluntarily at a safe continuation boundary. */
|
|
28
|
+
export declare class CooperativeTurnYieldError extends Error {
|
|
29
|
+
readonly code = "cooperative_turn_yield";
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
export declare function isCooperativeTurnYieldError(error: unknown): error is CooperativeTurnYieldError;
|
|
33
|
+
/** Error indicating durable turn input could not be committed by the worker owner. */
|
|
34
|
+
export declare class TurnInputCommitLostError extends Error {
|
|
35
|
+
readonly code = "turn_input_commit_lost";
|
|
36
|
+
constructor(message?: string);
|
|
37
|
+
}
|
|
38
|
+
/** Return whether an error means the durable worker lost input ownership. */
|
|
39
|
+
export declare function isTurnInputCommitLostError(error: unknown): error is TurnInputCommitLostError;
|
|
27
40
|
/** Mark a turn as the active turn in conversation state. */
|
|
28
41
|
export declare function startActiveTurn(args: {
|
|
29
42
|
conversation: ThreadConversationState;
|
|
@@ -5,7 +5,7 @@ export declare function matchesSandboxEgressDomain(host: string, domain: string)
|
|
|
5
5
|
export declare function resolveSandboxEgressProviderForHost(host: string): string | undefined;
|
|
6
6
|
/** Build the policy that forwards provider requests back to Junior for credentials. */
|
|
7
7
|
export declare function buildSandboxEgressNetworkPolicy(input?: {
|
|
8
|
-
|
|
8
|
+
credentialToken?: string;
|
|
9
9
|
}): NetworkPolicy;
|
|
10
10
|
/** Resolve non-secret command environment values for registered sandbox providers. */
|
|
11
11
|
export declare function resolveSandboxCommandEnvironment(): Promise<Record<string, string>>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type CredentialContext } from "@/chat/credentials/context";
|
|
1
2
|
import type { CredentialHeaderTransform } from "@/chat/credentials/broker";
|
|
2
3
|
export declare const SANDBOX_EGRESS_PROXY_PATH = "/api/internal/sandbox-egress";
|
|
3
|
-
export interface
|
|
4
|
-
|
|
4
|
+
export interface SandboxEgressCredentialContext {
|
|
5
|
+
credentials: CredentialContext;
|
|
5
6
|
egressId: string;
|
|
6
7
|
expiresAtMs: number;
|
|
7
8
|
contextId: string;
|
|
@@ -11,17 +12,17 @@ export interface SandboxEgressCredentialLease {
|
|
|
11
12
|
expiresAt: string;
|
|
12
13
|
headerTransforms: CredentialHeaderTransform[];
|
|
13
14
|
}
|
|
14
|
-
/** Create a signed
|
|
15
|
-
export declare function
|
|
16
|
-
|
|
15
|
+
/** Create a signed actor/sandbox context token for lazy sandbox egress auth. */
|
|
16
|
+
export declare function createSandboxEgressCredentialToken(input: {
|
|
17
|
+
credentials: CredentialContext;
|
|
17
18
|
egressId: string;
|
|
18
19
|
ttlMs?: number;
|
|
19
20
|
}): string;
|
|
20
|
-
/** Verify a signed
|
|
21
|
-
export declare function
|
|
22
|
-
/** Cache a short-lived credential lease for repeated forwarded requests for one
|
|
23
|
-
export declare function setSandboxEgressCredentialLease(context:
|
|
24
|
-
/** Load a cached egress credential lease for
|
|
25
|
-
export declare function getSandboxEgressCredentialLease(provider: string, context:
|
|
21
|
+
/** Verify a signed actor/sandbox context token from the proxy URL. */
|
|
22
|
+
export declare function parseSandboxEgressCredentialToken(token: string | undefined): SandboxEgressCredentialContext | undefined;
|
|
23
|
+
/** Cache a short-lived credential lease for repeated forwarded requests for one actor/sandbox context. */
|
|
24
|
+
export declare function setSandboxEgressCredentialLease(context: SandboxEgressCredentialContext, lease: SandboxEgressCredentialLease): Promise<void>;
|
|
25
|
+
/** Load a cached egress credential lease for an actor/sandbox context/provider pair. */
|
|
26
|
+
export declare function getSandboxEgressCredentialLease(provider: string, context: SandboxEgressCredentialContext): Promise<SandboxEgressCredentialLease | undefined>;
|
|
26
27
|
/** Clear a cached egress credential lease after the provider rejects its headers. */
|
|
27
|
-
export declare function clearSandboxEgressCredentialLease(provider: string, context:
|
|
28
|
+
export declare function clearSandboxEgressCredentialLease(provider: string, context: SandboxEgressCredentialContext): Promise<void>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LogContext } from "@/chat/logging";
|
|
2
|
+
import type { CredentialContext } from "@/chat/credentials/context";
|
|
2
3
|
import type { AgentPluginHookRunner } from "@/chat/plugins/agent-hooks";
|
|
3
4
|
import type { SandboxInstance } from "@/chat/sandbox/workspace";
|
|
4
5
|
import type { SkillMetadata } from "@/chat/skills";
|
|
@@ -42,9 +43,7 @@ export declare function createSandboxExecutor(options?: {
|
|
|
42
43
|
sandboxDependencyProfileHash?: string;
|
|
43
44
|
timeoutMs?: number;
|
|
44
45
|
traceContext?: LogContext;
|
|
45
|
-
credentialEgress?:
|
|
46
|
-
requesterId: string;
|
|
47
|
-
};
|
|
46
|
+
credentialEgress?: CredentialContext;
|
|
48
47
|
agentHooks?: AgentPluginHookRunner;
|
|
49
48
|
onSandboxAcquired?: (sandbox: SandboxAcquiredState) => void | Promise<void>;
|
|
50
49
|
runBashCustomCommand?: (command: string) => Promise<{
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
+
import type { StateAdapter } from "chat";
|
|
2
|
+
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
1
3
|
export interface TurnContinuationRequest {
|
|
2
4
|
conversationId: string;
|
|
3
5
|
expectedVersion: number;
|
|
4
6
|
sessionId: string;
|
|
5
7
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
export interface ScheduleTurnTimeoutResumeOptions {
|
|
9
|
+
nowMs?: number;
|
|
10
|
+
queue?: ConversationWorkQueue;
|
|
11
|
+
state?: StateAdapter;
|
|
12
|
+
}
|
|
8
13
|
/** Build the callback request for an awaiting automatic turn continuation. */
|
|
9
14
|
export declare function getAwaitingTurnContinuationRequest(args: {
|
|
10
15
|
conversationId: string;
|
|
11
16
|
sessionId: string;
|
|
12
17
|
}): Promise<TurnContinuationRequest | undefined>;
|
|
13
|
-
/** Schedule
|
|
14
|
-
export declare function scheduleTurnTimeoutResume(request: TurnContinuationRequest): Promise<void>;
|
|
18
|
+
/** Schedule durable conversation work to resume a timed-out turn. */
|
|
19
|
+
export declare function scheduleTurnTimeoutResume(request: TurnContinuationRequest, options?: ScheduleTurnTimeoutResumeOptions): Promise<void>;
|
|
15
20
|
/** Verify and parse an authenticated timeout resume callback request. */
|
|
16
21
|
export declare function verifyTurnTimeoutResumeRequest(request: Request): Promise<TurnContinuationRequest | undefined>;
|