@tangle-network/agent-app 0.43.43 → 0.43.44

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.
@@ -0,0 +1,114 @@
1
+ import { F as FileMention } from './parts-1_3y2JmR.js';
2
+
3
+ /**
4
+ * `createSandboxFileIndexRoute` — server side of `@`-file-mentions
5
+ * (companion to sandbox-ui#184's composer mention primitive). Serves a flat,
6
+ * ignore-filtered listing of the workspace sandbox so `useFileMentions`
7
+ * (`/web-react`) can filter it client-side without a round trip per
8
+ * keystroke.
9
+ *
10
+ * Same seam style as `createUploadRoute`: `authorize({ request })` resolves a
11
+ * structural `{ tree(path, opts) }` handle (the shape of the sandbox SDK's
12
+ * `box.fs.tree`) — no SDK import here. `authorize` also carries the
13
+ * cold-box signal: a sandbox that isn't running yet answers `{ status:
14
+ * 'warming' }` directly, never provisions-and-waits inside this route.
15
+ *
16
+ * A box can also be running with its workspace root not yet materialised, which
17
+ * `authorize` cannot see; the route recognises that one signal off `fs.tree`
18
+ * and answers `warming` too, so every consumer gets the retry-and-wait state
19
+ * instead of a 500. Every other `tree()` failure propagates.
20
+ */
21
+
22
+ /** One entry from a structural `tree()` scan. Mirrors the sandbox SDK's
23
+ * `FileTreeFile` (`path`, `size`, `mtime`) — `mtime` is unused here so it's
24
+ * omitted from the structural match. */
25
+ interface SandboxTreeFile {
26
+ path: string;
27
+ size: number;
28
+ }
29
+ /** Structural match of the sandbox SDK's `box.fs.tree` result shape
30
+ * (`FileTreeResult`). `stats.truncated` is the only stat this route reads;
31
+ * the rest ride through unread on the real SDK type. */
32
+ interface SandboxTreeResult {
33
+ root: string;
34
+ files: SandboxTreeFile[];
35
+ stats: {
36
+ truncated: boolean;
37
+ };
38
+ }
39
+ /** Structural match of the sandbox SDK's `box.fs` tree surface. */
40
+ interface SandboxFileTreeSource {
41
+ tree(path: string, options?: {
42
+ maxDepth?: number;
43
+ }): Promise<SandboxTreeResult>;
44
+ }
45
+ interface FileIndexReadyResponse {
46
+ status: 'ready';
47
+ /** Workspace-relative entries. Same shape as `FileMention` (`./wire`) so a
48
+ * client can hand a response entry straight to `fileMentionsToParts` /
49
+ * `buildMentionPromptBlock` without remapping. */
50
+ files: FileMention[];
51
+ /** True when either the underlying scan truncated (SDK-side cap) or this
52
+ * route's own `maxEntries` cap trimmed the filtered list. The client
53
+ * should show "showing first N files" rather than imply completeness. */
54
+ truncated: boolean;
55
+ generatedAt: string;
56
+ }
57
+ /** Cold-box answer: no provisioning happened, no files were scanned. The
58
+ * client shows a warming state and retries — this route never blocks on a
59
+ * box coming up. Two situations produce it: `authorize` reporting a box that
60
+ * is not running, and a running box whose workspace root does not exist yet
61
+ * (see `isMissingRootError`). */
62
+ interface FileIndexWarmingResponse {
63
+ status: 'warming';
64
+ }
65
+ type FileIndexResponse = FileIndexReadyResponse | FileIndexWarmingResponse;
66
+ /** Short-TTL cache seam so repeat popover opens in the same session don't
67
+ * re-scan the workspace. Host-provided (e.g. a KV binding); `key` is
68
+ * whatever `authorize` returns as `cacheKey` — this route treats it opaquely. */
69
+ interface FileIndexCache {
70
+ get(key: string): Promise<FileIndexReadyResponse | null> | FileIndexReadyResponse | null;
71
+ put(key: string, value: FileIndexReadyResponse, options?: {
72
+ ttlSeconds?: number;
73
+ }): Promise<void> | void;
74
+ }
75
+ type FileIndexAuthorization = {
76
+ status: 'ready';
77
+ /** Structural sandbox `fs` handle, usually `ensureWorkspaceSandbox(...)` → `box.fs`. */
78
+ fs: SandboxFileTreeSource;
79
+ /** Workspace root to index (e.g. `/home/agent`). */
80
+ root: string;
81
+ /** Extra ignore segments for this request, merged with the route's
82
+ * defaults + `CreateSandboxFileIndexRouteOptions.ignore`. */
83
+ ignore?: string[];
84
+ /** Opaque cache key for the optional cache seam. Omit to skip caching
85
+ * for this request (e.g. a workspace the host chooses not to cache). */
86
+ cacheKey?: string;
87
+ } | {
88
+ status: 'warming';
89
+ } | {
90
+ status: 'denied';
91
+ response: Response;
92
+ };
93
+ interface CreateSandboxFileIndexRouteOptions {
94
+ /** Authenticate the caller, resolve the sandbox `fs` handle, and signal a
95
+ * cold box — never provisions or waits. */
96
+ authorize(args: {
97
+ request: Request;
98
+ }): Promise<FileIndexAuthorization>;
99
+ /** Extra ignore segments beyond the route's defaults (node_modules, .git,
100
+ * dotfiles/dot-dirs, common build dirs). Matched as exact path-segment
101
+ * names, same rule as the defaults. */
102
+ ignore?: string[];
103
+ /** Passed to `fs.tree` as `options.maxDepth`. Default 12. */
104
+ maxDepth?: number;
105
+ /** Hard cap on entries returned after filtering. Default 5000. */
106
+ maxEntries?: number;
107
+ /** Optional host-provided cache seam. */
108
+ cache?: FileIndexCache;
109
+ /** Cache TTL in seconds when `cache` is set. Default 20. */
110
+ cacheTtlSeconds?: number;
111
+ }
112
+ declare function createSandboxFileIndexRoute(options: CreateSandboxFileIndexRouteOptions): (request: Request) => Promise<Response>;
113
+
114
+ export { type CreateSandboxFileIndexRouteOptions as C, type FileIndexAuthorization as F, type SandboxFileTreeSource as S, type FileIndexCache as a, type FileIndexReadyResponse as b, type FileIndexResponse as c, type FileIndexWarmingResponse as d, type SandboxTreeFile as e, type SandboxTreeResult as f, createSandboxFileIndexRoute as g };
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ export { KeyCrypto, KeyProvisioner, PlanLimit, PlatformBalanceInfo, PlatformBala
17
17
  export { HttpHeadProbeConfig, PreflightProbe, PreflightProbeResult, PreflightProbeVerdict, PreflightReport, RouterChatProbeConfig, SandboxAuthProbeConfig, formatPreflightReport, httpHeadProbe, routerChatProbe, runPreflight, sandboxAuthProbe } from './preflight/index.js';
18
18
  export { ObjectBody, ObjectKeyParts, ObjectStore, PutObjectOptions, R2LikeBucket, R2LikeObjectBody, R2LikeObjectHead, SignObjectUrlArgs, VerifyObjectUrlResult, assertSafeKeySegment, createProxiedArtifactRoute, createR2ObjectStore, objectKey, signObjectUrl, verifyObjectUrl } from './object-store/index.js';
19
19
  export { B as BULK_DELETE_MAX_THREADS, C as ChatStoreInputError, t as threadTitleFromMessage } from './core-7qIM7svy.js';
20
- export { C as ChatFilePart, a as ChatImagePart, b as ChatInteractionPart, c as ChatMessagePart, d as ChatNoticePart, e as ChatPartTime, f as ChatPlanPart, g as ChatReasoningPart, h as ChatStepFinishPart, i as ChatStepStartPart, j as ChatSubtaskPart, k as ChatTextPart, l as ChatToolPart, m as ChatToolState, n as ChatToolStatus, o as ChatUsageTokens, S as StorableHarnessPartKind, p as isChatInteractionPart, q as isChatPlanPart, r as isChatStepFinishPart, s as isChatTextPart, t as isChatToolPart, u as toChatMessageParts } from './parts-DjX0RRTS.js';
20
+ export { C as ChatFilePart, a as ChatImagePart, b as ChatInteractionPart, c as ChatMentionKind, d as ChatMentionPart, e as ChatMessagePart, f as ChatNoticePart, g as ChatPartTime, h as ChatPlanPart, i as ChatReasoningPart, j as ChatStepFinishPart, k as ChatStepStartPart, l as ChatSubtaskPart, m as ChatTextPart, n as ChatToolPart, o as ChatToolState, p as ChatToolStatus, q as ChatUsageTokens, S as StorableHarnessPartKind, r as isChatInteractionPart, s as isChatMentionPart, t as isChatPlanPart, u as isChatStepFinishPart, v as isChatTextPart, w as isChatToolPart, x as mentionInputToPart, y as mentionPartsFromMessageParts, z as toChatMessageParts } from './parts-1_3y2JmR.js';
21
21
  export { DeriveKeyOptions, createFieldCrypto, decodeHexKey, decryptAesGcm, decryptBytes, decryptWithKey, deriveKey, encryptAesGcm, encryptBytes, encryptWithKey } from './crypto/index.js';
22
22
  export { BufferedTurnEvent, BufferedTurnOptions, BufferedTurnTap, D1LikeForTurns, JsonRecord, PersistedChatMessageForTurn, PumpBufferedTurnOptions, ReplayTurnEventsOptions, ResolvedChatTurn, StreamEvent, TURN_EVENTS_MIGRATION_SQL, TURN_STATUS_SCOPE_MIGRATION_SQL, TurnEventStore, TurnStatus, asRecord, asString, buildUserTextParts, coalesceChatStreamEvents, coalesceDeltas, createBufferedTurnTap, createD1TurnEventStore, createMemoryTurnEventStore, encodeEvent, finalizeAssistantParts, getPartKey, mergePersistedPart, messageHasTurnId, normalizeClientTurnId, normalizePersistedPart, normalizeTime, normalizeToolEvent, pumpBufferedTurn, replayTurnEvents, resolveChatTurn, resolveToolId, resolveToolName } from './stream/index.js';
23
23
  export { HubExecClient, HubExecClientOptions, HubExecErrorCode, HubExecResult, HubInvokeDeps, HubInvokeInput, HubInvokeOutcome, ParsedIntegrationAction, invokeIntegrationHub, resolveIntegrationAction } from './integrations/index.js';
@@ -27,7 +27,7 @@ export { ChatPlan, ChatPlanPersistedPart, ChatPlanStatus, PLAN_SUBMITTED_EVENT,
27
27
  export { CreateDurableInteractionRoutePersistenceOptions, DurableAnswerIntentJournal, DurableAnswerIntentRecord, DurableAnswerIntentState, DurableChatConflictError, DurableChatError, DurableChatErrorCode, DurableChatEventProjection, DurableChatGoneError, DurableChatScope, DurableChatStateStore, DurableChatUnavailableError, DurableFollowUpReceipt, DurableInteractionAcknowledgement, DurableInteractionGuarantee, DurableInteractionProjection, DurableInteractionProjectionAdapter, DurableInteractionSettlement, DurableInteractionSettlementFactoryOptions, DurableInteractionSettlementOptions, DurablePlanAuthority, DurablePlanAuthorityCurrentResult, DurablePlanAuthorityDecision, DurablePlanAuthorityResult, DurablePlanAuthorization, DurablePlanCommandJournal, DurablePlanCommandKey, DurablePlanCommandRecord, DurablePlanCommandState, DurablePlanDecision, DurablePlanEffectRecord, DurablePlanProjection, DurablePlanRouteAuthorizeArgs, DurablePlanRouteOptions, DurablePlanRoutes, DurablePlanStateStore, DurablePlanStore, InMemoryDurableChatStateStore, InMemoryDurableChatStore, PreparedDurableInteractionAnswer, applyDurableInteractionAnswer, applyDurableInteractionAsk, applyDurableInteractionCancel, createDurableChatEventProjection, createDurableChatScope, createDurableInteractionProjectionAdapter, createDurableInteractionRoutePersistence, createDurableInteractionSettlement, createDurablePlanRoutes, createInMemoryDurableChatStateStore, durableChatScopeKey, durableInteractionIntentKey, normalizePlanDecision, planAuthorityIdempotencyKey, planCommandKey, planEffectKey, recordDurableInteractionAnswer, recordDurableInteractionCancel, stablePlanReceipt, upsertDurableInteractionAsk } from './durable-chat/index.js';
28
28
  export { CompleteMissionInput, CreateMissionInput, DEFAULT_MISSION_STEP_KINDS, InMemoryMissionStore, MISSION_CONTROL_CHANNEL_ID, MissionApprovalsPort, MissionAuditEvent, MissionConcurrencyError, MissionCostLedger, MissionEngine, MissionEngineOptions, MissionEventSink, MissionGateKind, MissionGateOptions, MissionGateProposal, MissionOutcome, MissionPlanRunOptions, MissionProposalResolution, MissionRecord, MissionService, MissionServiceOptions, MissionState, MissionStatus, MissionStep, MissionStepState, MissionStepStatus, MissionStorePort, MissionStreamEvent, MissionStreamStatus, MissionStreamStep, MissionStreamStepStatus, MissionUpdateGuard, MissionUpdatePatch, ParseMissionBlocksOptions, ParsedMission, ParsedMissionStep, PlanOutcome, RetryableStepError, SandboxDispatch, SandboxDispatchDoneResult, SandboxDispatchInProgressResult, SandboxDispatchInput, SandboxDispatchResult, SetStepStatusPatch, StepGateClassification, StepOutcome, applyMissionEvent, asMissionStreamEvent, budgetGateProposalId, buildAgentMissionPlan, createInMemoryMissionStore, createMissionEngine, createMissionService, isMissionStopRequested, isMissionTerminal, mergeMissionState, noopEventSink, parseMissionBlocks, parseSessionStreamEnvelope, reduceMissionEvents, stepGateProposalId, volumeGateProposalId } from './missions/index.js';
29
29
  export { S as StepAgentActivity, W as WithAgentActivity, s as stepAgentActivity } from './agent-activity-C8ZG0F0M.js';
30
- export { AppToolDescriptor, AuthenticatedSandboxUser, BuildAppToolMcpServersOptions, BuildSandboxToolFileMountsOptions, DEFAULT_SANDBOX_RESOURCES, DriveSandboxTurnOptions, ENV_TOTAL_MAX_BYTES, ENV_VALUE_MAX_BYTES, EnsureWorkspaceSandboxOptions, LivenessProbeConfig, MemberSyncSeam, Outcome, PROVISION_PAYLOAD_MAX_BYTES, ProfileComposeOptions, PromptInputPart, ProviderResolutionConfig, ProvisionPayloadSections, ProvisionProfileSection, ResolveSandboxClientCredentialsOptions, ResolvedModel, SandboxApiCredentials, SandboxBuildContext, SandboxClientCredentials, SandboxCredentialEnvironment, SandboxPermissionLevel, SandboxResourceConfig, SandboxRestoreSpec, SandboxRuntimeAuthRefreshError, SandboxRuntimeConfig, SandboxRuntimeConnection, SandboxScope, SandboxStepTransition, SandboxTerminalTokenOptions, SandboxTerminalTokenResult, SandboxTerminalTokenSubject, SandboxTerminalWsMatch, SandboxToolPathOptions, SandboxToolSpec, ScopedTokenResult, SecretStore, StoppedSandboxResumeFailure, StoppedSandboxResumeRecovery, StreamSandboxPromptOptions, TerminalProxyIdentity, WorkspaceSandboxConnectionArgs, WorkspaceSandboxConnectionHandlerOptions, WorkspaceSandboxEnsureContext, WorkspaceSandboxInstanceLike, WorkspaceSandboxManager, WorkspaceSandboxManagerOptions, WorkspaceSandboxRuntimeProxyArgs, WorkspaceSandboxRuntimeProxyHandlerOptions, WorkspaceSandboxTerminalUpgradeHandlerOptions, WriteProfileFilesOptions, assertEnvWithinLimits, assertProvisionPayloadWithinCap, attachReasoningEffort, bearerSubprotocolToken, bearerToken, buildAppToolMcpServers, buildSandboxRuntimeProxyHeaders, buildSandboxToolFileMounts, buildSandboxToolPathSetupScript, classifySeveredStream, createSandboxTerminalToken, createWorkspaceSandboxConnectionHandler, createWorkspaceSandboxManager, createWorkspaceSandboxRuntimeProxyHandler, createWorkspaceSandboxTerminalUpgradeHandler, deferredCorpusHash, deleteSecret, detectInteractiveQuestion, driveSandboxTurn, encodeSandboxRuntimePath, ensureWorkspaceSandbox, flattenHistory, getClient, isSandboxTerminalWsUpgrade, isTerminalPromptEvent, matchSandboxTerminalWsPath, mergeExtraMcp, mergeHistoryIntoParts, mintSandboxScopedToken, mintTerminalProxyToken, readSecret, resetClientCache, resolveModel, resolveSandboxClientCredentials, runSandboxPrompt, runSandboxToolPathSetup, sandboxToolBinDir, sandboxToolPath, sandboxToolRootDir, secretStoreFromClient, splitDeferredProfileFiles, storeSecret, streamSandboxPrompt, syncSandboxMemberAdd, syncSandboxMemberRemove, syncSandboxMemberRole, terminalTokenFromRequest, verifySandboxTerminalToken, verifyTerminalProxyToken, writeProfileFilesToBox } from './sandbox/index.js';
30
+ export { AppToolDescriptor, AuthenticatedSandboxUser, BuildAppToolMcpServersOptions, BuildSandboxToolFileMountsOptions, DEFAULT_SANDBOX_RESOURCES, DriveSandboxTurnOptions, ENV_TOTAL_MAX_BYTES, ENV_VALUE_MAX_BYTES, EnsureWorkspaceSandboxOptions, LivenessProbeConfig, MemberSyncSeam, Outcome, PROVISION_PAYLOAD_MAX_BYTES, PeekWorkspaceSandboxOutcome, ProfileComposeOptions, PromptInputPart, ProviderResolutionConfig, ProvisionPayloadSections, ProvisionProfileSection, ResolveSandboxClientCredentialsOptions, ResolvedModel, SandboxApiCredentials, SandboxBuildContext, SandboxClientCredentials, SandboxCredentialEnvironment, SandboxExecChannel, SandboxExecOptions, SandboxFileBytesOutcome, SandboxFileSizeOutcome, SandboxPermissionLevel, SandboxResourceConfig, SandboxRestoreSpec, SandboxRuntimeAuthRefreshError, SandboxRuntimeConfig, SandboxRuntimeConnection, SandboxScope, SandboxStepTransition, SandboxTerminalTokenOptions, SandboxTerminalTokenResult, SandboxTerminalTokenSubject, SandboxTerminalWsMatch, SandboxToolPathOptions, SandboxToolSpec, ScopedTokenResult, SecretStore, StoppedSandboxResumeFailure, StoppedSandboxResumeRecovery, StreamSandboxPromptOptions, TerminalProxyIdentity, WorkspaceSandboxConnectionArgs, WorkspaceSandboxConnectionHandlerOptions, WorkspaceSandboxEnsureContext, WorkspaceSandboxInstanceLike, WorkspaceSandboxManager, WorkspaceSandboxManagerOptions, WorkspaceSandboxRuntimeProxyArgs, WorkspaceSandboxRuntimeProxyHandlerOptions, WorkspaceSandboxTerminalUpgradeHandlerOptions, WriteProfileFilesOptions, assertEnvWithinLimits, assertProvisionPayloadWithinCap, attachReasoningEffort, bearerSubprotocolToken, bearerToken, buildAppToolMcpServers, buildSandboxRuntimeProxyHeaders, buildSandboxToolFileMounts, buildSandboxToolPathSetupScript, classifySeveredStream, createSandboxTerminalToken, createWorkspaceSandboxConnectionHandler, createWorkspaceSandboxManager, createWorkspaceSandboxRuntimeProxyHandler, createWorkspaceSandboxTerminalUpgradeHandler, deferredCorpusHash, deleteSecret, detectInteractiveQuestion, driveSandboxTurn, encodeSandboxRuntimePath, ensureWorkspaceSandbox, flattenHistory, getClient, isSandboxTerminalWsUpgrade, isTerminalPromptEvent, matchSandboxTerminalWsPath, mergeExtraMcp, mergeHistoryIntoParts, mintSandboxScopedToken, mintTerminalProxyToken, peekWorkspaceSandbox, readSandboxBinaryBytes, readSecret, resetClientCache, resolveModel, resolveSandboxClientCredentials, runSandboxPrompt, runSandboxToolPathSetup, sandboxToolBinDir, sandboxToolPath, sandboxToolRootDir, secretStoreFromClient, shellQuote, splitDeferredProfileFiles, statSandboxFileSize, storeSecret, streamSandboxPrompt, syncSandboxMemberAdd, syncSandboxMemberRemove, syncSandboxMemberRole, terminalTokenFromRequest, verifySandboxTerminalToken, verifyTerminalProxyToken, writeProfileFilesToBox } from './sandbox/index.js';
31
31
  export { CookieOptions, JsonObject, KvLike, RateLimitResult, RequestContext, SecurityHeaderOptions, addSecurityHeaders, assertMediaUrl, checkRateLimit, clearCookieHeader, extractRequestContext, parseJsonObjectBody, readCookieValue, requireString, serializeCookie } from './web/index.js';
32
32
  export { BuildRedactedDocumentOptions, DEFAULT_REDACTION_PATTERNS, RedactForIngestionOptions, RedactedDocSegment, RedactedDocument, RedactionPattern, RedactionSpan, RevealResult, RevealSpanOptions, buildRedactedDocument, detectSpans, maskSpans, redactForIngestion, revealSpan } from './redact/index.js';
33
33
  export { ApprovalEvent, ApprovalEventSchema, AssetContentMap, AssetFormat, AssetSpec, AssetStatus, AssetVariant, BrandTokens, BrandTokensSchema, ConversionMetrics, ConversionMetricsSchema, CopyContent, CopyContentSchema, CopyPlatform, EmailBodySection, EmailContent, EmailContentSchema, EmailCtaSection, EmailDividerSection, EmailFeatureSection, EmailHeroSection, EmailSection, EmailTestimonialSection, ImageBackground, ImageContent, ImageContentSchema, ImageImageLayer, ImageLayer, ImageLayerType, ImageLogoLayer, ImageShapeLayer, ImageSlide, ImageTextLayer, VideoCaption, VideoContent, VideoContentSchema, VideoCountdownScene, VideoImageRevealScene, VideoScene, VideoSlideScene, VideoTextAnimationScene, parseAssetSpec, safeParseAssetSpec } from './assets/index.js';
package/dist/index.js CHANGED
@@ -289,12 +289,15 @@ import {
289
289
  } from "./chunk-HFC4BTWJ.js";
290
290
  import {
291
291
  isChatInteractionPart,
292
+ isChatMentionPart,
292
293
  isChatPlanPart,
293
294
  isChatStepFinishPart,
294
295
  isChatTextPart,
295
296
  isChatToolPart,
297
+ mentionInputToPart,
298
+ mentionPartsFromMessageParts,
296
299
  toChatMessageParts
297
- } from "./chunk-I2ATYB7R.js";
300
+ } from "./chunk-6E2XJSCT.js";
298
301
  import {
299
302
  INTERACTION_CANCEL_EVENT,
300
303
  INTERACTION_EVENT,
@@ -382,6 +385,8 @@ import {
382
385
  mergeHistoryIntoParts,
383
386
  mintSandboxScopedToken,
384
387
  mintTerminalProxyToken,
388
+ peekWorkspaceSandbox,
389
+ readSandboxBinaryBytes,
385
390
  readSecret,
386
391
  resetClientCache,
387
392
  resolveModel,
@@ -392,7 +397,9 @@ import {
392
397
  sandboxToolPath,
393
398
  sandboxToolRootDir,
394
399
  secretStoreFromClient,
400
+ shellQuote,
395
401
  splitDeferredProfileFiles,
402
+ statSandboxFileSize,
396
403
  storeSecret,
397
404
  streamSandboxPrompt,
398
405
  syncSandboxMemberAdd,
@@ -402,7 +409,7 @@ import {
402
409
  verifySandboxTerminalToken,
403
410
  verifyTerminalProxyToken,
404
411
  writeProfileFilesToBox
405
- } from "./chunk-5GWXCSLQ.js";
412
+ } from "./chunk-5RJNEEO2.js";
406
413
  import {
407
414
  DEFAULT_HARNESS,
408
415
  KNOWN_HARNESSES,
@@ -743,6 +750,7 @@ export {
743
750
  invokeIntegrationHub,
744
751
  isAppToolName,
745
752
  isChatInteractionPart,
753
+ isChatMentionPart,
746
754
  isChatPlanPart,
747
755
  isChatStepFinishPart,
748
756
  isChatTextPart,
@@ -767,6 +775,8 @@ export {
767
775
  maskSpans,
768
776
  matchPreset,
769
777
  matchSandboxTerminalWsPath,
778
+ mentionInputToPart,
779
+ mentionPartsFromMessageParts,
770
780
  mergeExtraMcp,
771
781
  mergeHistoryIntoParts,
772
782
  mergeMissionState,
@@ -797,6 +807,7 @@ export {
797
807
  parsePlanSubmittedEvent,
798
808
  parseSequenceOperations,
799
809
  parseSessionStreamEnvelope,
810
+ peekWorkspaceSandbox,
800
811
  persistedPartToInteraction,
801
812
  persistedPartToPlan,
802
813
  planAuthorityIdempotencyKey,
@@ -811,6 +822,7 @@ export {
811
822
  pumpBufferedTurn,
812
823
  questionInteractionContentSignature,
813
824
  readCookieValue,
825
+ readSandboxBinaryBytes,
814
826
  readSecret,
815
827
  readToolArgs,
816
828
  recordDurableInteractionAnswer,
@@ -860,6 +872,7 @@ export {
860
872
  secondsToFrames,
861
873
  secretStoreFromClient,
862
874
  serializeCookie,
875
+ shellQuote,
863
876
  signObjectUrl,
864
877
  snapHarnessToModel,
865
878
  snapModelToHarness,
@@ -867,6 +880,7 @@ export {
867
880
  splitDeferredProfileFiles,
868
881
  stablePlanReceipt,
869
882
  stampInteractionAnswers,
883
+ statSandboxFileSize,
870
884
  stepActivityFlowTrace,
871
885
  stepAgentActivity,
872
886
  stepGateProposalId,
@@ -0,0 +1,368 @@
1
+ import { Part } from '@tangle-network/agent-interface';
2
+ import { a as ChatInteractionField, b as ChatInteractionStatus, h as InteractionAnswers, N as NoticeKind } from './contract-KfqJh_au.js';
3
+ import { ChatPlanPersistedPart } from './plans/index.js';
4
+
5
+ /**
6
+ * Wire contract between the chat client (composer + `streamChatTurn`) and the
7
+ * assembled server vertical (`createChatTurnRoutes`). Import-free on purpose:
8
+ * `/web-react` re-exports these types into browser bundles, so nothing here may
9
+ * reach a Node builtin or an engine package.
10
+ *
11
+ * The part shape mirrors the sandbox SDK's `PromptInputPart` structurally
12
+ * (text | image | file with filename/mediaType/url/path/content) — derived
13
+ * here, not imported, so the client bundle never touches the SDK.
14
+ */
15
+ interface ChatTurnTextPartInput {
16
+ type: 'text';
17
+ text: string;
18
+ }
19
+ /** A non-text prompt part the upload route hands back and the client echoes
20
+ * on send. `url` carries an inline `data:` URI for small files; `path` is a
21
+ * sandbox workspace reference for large ones (the >1 MiB gateway body cap
22
+ * makes the two-step upload mandatory). */
23
+ interface ChatTurnFilePartInput {
24
+ type: 'image' | 'file';
25
+ filename?: string;
26
+ mediaType?: string;
27
+ url?: string;
28
+ path?: string;
29
+ content?: string;
30
+ }
31
+ type ChatTurnPartInput = ChatTurnTextPartInput | ChatTurnFilePartInput;
32
+ /** POST body for the turn route. `content` may be empty when `parts` carry the
33
+ * message (an image-only send). Product routing fields (workspaceId etc.) ride
34
+ * alongside and are read by the product's `authorize` seam. */
35
+ interface ChatTurnRequestPayload {
36
+ threadId: string;
37
+ content?: string;
38
+ /** Non-text parts from the upload route, echoed back verbatim. */
39
+ parts?: ChatTurnFilePartInput[];
40
+ /** `@`-picked file mentions for this turn — path references into the
41
+ * workspace sandbox, NOT uploads, so they travel in their own field rather
42
+ * than as `parts` entries. A product whose `parts` field is already spoken
43
+ * for (an attachment sentinel) can still send mentions, and mentions
44
+ * persist as their own `ChatMentionPart`s so a retry rebuilds them. The
45
+ * route validates this field with {@link parseFileMentions} and replaces it
46
+ * on the payload with the validated, deduped list. */
47
+ mentions?: FileMention[];
48
+ model?: string;
49
+ effort?: 'auto' | 'low' | 'medium' | 'high';
50
+ harness?: string;
51
+ /** Client-generated idempotency key for the logical turn (retry-safe). */
52
+ turnId?: string;
53
+ [key: string]: unknown;
54
+ }
55
+ /** `fetch` init for the turn route — the one place the client wire shape is
56
+ * serialized, so composer glue and products never drift from the server's
57
+ * parser. */
58
+ declare function chatTurnRequestInit(payload: ChatTurnRequestPayload): RequestInit;
59
+ declare const INLINE_PARTS_MAX_BYTES = 950000;
60
+ declare class ChatTurnInputError extends Error {
61
+ readonly status: number;
62
+ readonly code: string;
63
+ constructor(message: string, status?: number, code?: string);
64
+ }
65
+ declare function promptPartsByteSize(parts: ChatTurnPartInput[]): number;
66
+ /** Throws `ChatTurnInputError` (413) when the parts' inline payload would blow
67
+ * the gateway cap. Path-ref parts are tiny by construction and always pass. */
68
+ declare function assertPromptPartsWithinCap(parts: ChatTurnPartInput[], maxBytes?: number): void;
69
+ /** A file mention resolved from the composer's `@`-picker: the
70
+ * workspace-relative path plus enough metadata to build a prompt part and
71
+ * pointer text. `path` is the canonical identity — the mention pill's
72
+ * `MentionItem.id` for the file kind (`/web-react`'s `useFileMentions`). */
73
+ interface FileMention {
74
+ path: string;
75
+ name: string;
76
+ size?: number;
77
+ }
78
+ /** The `image/*` mime for a mention path by extension, or `undefined` for
79
+ * anything not in the known image set (dispatched as `type: 'file'`). */
80
+ declare function mediaTypeForMentionPath(path: string): string | undefined;
81
+ /** The image/file split a mention is rendered and persisted under — the
82
+ * composer pill's icon, the dispatched part's `type`, and
83
+ * `ChatMentionPart.mentionKind` are all this one value. */
84
+ type ChatMentionKind = 'image' | 'file';
85
+ /** `image` when the path's extension is in the known image set (the same table
86
+ * {@link mediaTypeForMentionPath} reads), `file` otherwise. Exported so a
87
+ * client that needs only the discriminant — a pill icon, a persisted part's
88
+ * `mentionKind` — never re-declares the extension table; two frozen copies of
89
+ * one mime table is how one gains a format and the other doesn't. */
90
+ declare function mentionKindForPath(path: string): ChatMentionKind;
91
+ interface FileMentionsToPartsOptions {
92
+ /** Resolve a mention's workspace-relative path to the absolute path the
93
+ * dispatched part should carry (e.g. a host prefixing the in-box vault
94
+ * root). Default: identity — the path travels unchanged. */
95
+ resolvePath?: (path: string) => string;
96
+ }
97
+ /** Maps resolved file mentions to path-only `ChatTurnFilePartInput`s —
98
+ * `image` vs `file` by extension, and always a `path`, never a `url` (the
99
+ * url/path XOR invariant: a mention is a sandbox path reference, never
100
+ * inline bytes). */
101
+ declare function fileMentionsToParts(mentions: readonly FileMention[], opts?: FileMentionsToPartsOptions): ChatTurnFilePartInput[];
102
+ /** The agent-facing pointer block appended to the dispatched prompt — never
103
+ * persisted in message `content`. Empty array → `''` so callers can append
104
+ * unconditionally. This is the sole producer of that text: the current
105
+ * turn's dispatch and any history projection built from the same mention
106
+ * list both route through here, so the two can't drift apart. */
107
+ declare function buildMentionPromptBlock(mentions: readonly Pick<FileMention, 'name' | 'path'>[]): string;
108
+ /** Hard cap on mentions per turn. Bounds the prompt pointer block, the
109
+ * persisted parts, and whatever media budget a dispatch draws from them. */
110
+ declare const MENTION_MAX_COUNT = 16;
111
+ type SandboxMentionPathCheck = {
112
+ succeeded: true;
113
+ } | {
114
+ succeeded: false;
115
+ error: string;
116
+ };
117
+ /**
118
+ * Validate a workspace-relative sandbox mention path. Rejects traversal (a
119
+ * `..` path segment), absolute paths (leading `/`), backslashes, and null
120
+ * bytes — the four ways a path picked in a client can escape the root the
121
+ * index route scanned.
122
+ *
123
+ * Spaces and unicode are deliberately ALLOWED: in-box filenames are arbitrary,
124
+ * and an ASCII-only charset would silently drop real files from a feature
125
+ * whose whole job is naming them.
126
+ */
127
+ declare function validateSandboxMentionPath(path: unknown): SandboxMentionPathCheck;
128
+ /**
129
+ * Validates the untyped `mentions` array off the wire, mirroring
130
+ * {@link parseChatTurnParts}: the typed list, or `ChatTurnInputError` (400)
131
+ * naming the offending entry. Never sanitizes-and-continues — a traversal path
132
+ * is a rejected request, not a trimmed one.
133
+ *
134
+ * A path repeated within one turn is deduped to its first occurrence rather
135
+ * than rejected: mentioning the same file twice is plausible user input, not
136
+ * an attack.
137
+ */
138
+ declare function parseFileMentions(raw: unknown): FileMention[];
139
+ /** Validates the untyped `parts` array off the wire. Returns the typed parts
140
+ * or throws `ChatTurnInputError` (400) naming the offending entry. */
141
+ declare function parseChatTurnParts(raw: unknown): ChatTurnFilePartInput[];
142
+
143
+ /**
144
+ * The stored shape of `message.parts` — one typed vocabulary for every part a
145
+ * product persists into a chat transcript. NOT an ad-hoc union reverse-
146
+ * engineered from product schemas; each member is matched field-for-field to
147
+ * its canonical source:
148
+ *
149
+ * - `text` / `reasoning` / `tool`: the persisted projection `/stream`'s
150
+ * `normalizePersistedPart` produces from the harness lane's
151
+ * `message.part.updated` events (ADC sidecar
152
+ * `apps/sidecar/src/events/session-events.ts:56` wraps the canonical part in
153
+ * an `{id, sessionID, messageID}` envelope; the projection strips the
154
+ * session/message ids and keeps the per-segment part id).
155
+ * - `file` / `image` / `step-start` / `step-finish`: the sidecar's canonical
156
+ * `MessagePartSchema` members (ADC
157
+ * `apps/sidecar/src/schemas/agent-schemas.ts:50-154`); `step-finish` carries
158
+ * the harness's per-step usage receipt — tokens
159
+ * `{total, input, output, reasoning, cache{write, read}}` + `cost` — which is
160
+ * also the shape the message-level token/cost columns mirror.
161
+ * - `subtask`: `@tangle-network/agent-interface`'s `SubtaskPart` (a spawned
162
+ * sub-agent task).
163
+ * - `interaction` / `notice`: the persisted-part codecs in
164
+ * `/web-react`'s chat-interactions contract (`interactionToPersistedPart`,
165
+ * `noticePart`) — type-only imports, one source of truth for their statuses
166
+ * and field shapes.
167
+ * - `plan`: the durable-plan projection in `/plans`, derived from the sandbox
168
+ * SDK's authoritative plan lifecycle.
169
+ * - `mention`: an `@`-picked reference to a file that already lives in the
170
+ * workspace sandbox (`FileMention` in `/chat-routes`'s wire contract, plus
171
+ * the image/file discriminant). Neither transport lane produces it — the
172
+ * turn route persists it from the request's `mentions` field — but it is a
173
+ * part a product persists into a transcript, so it belongs in this
174
+ * vocabulary rather than in a parallel one.
175
+ *
176
+ * `@tangle-network/agent-interface` exports the canonical wire `Part` union,
177
+ * but its `PartBase` requires the `sessionID`/`messageID` stream envelope that
178
+ * is deliberately NOT persisted, so the stored union is defined here as the
179
+ * envelope-free projection (a type-level coverage check against the peer's
180
+ * `Part['type']` lives in the tests). Contribute-down candidate: if
181
+ * agent-interface grows envelope-free persisted-part types, re-export them
182
+ * here and delete these definitions.
183
+ *
184
+ * Two transport lanes serialize into this SAME stored shape:
185
+ * - harness lane: canonical `message.part.updated` parts, merged/normalized by
186
+ * `/stream` (`mergePersistedPart`, `finalizeAssistantParts`);
187
+ * - router/openai-compat lane: `text_delta`/`tool_call` stream events are
188
+ * mapped INTO canonical part events first (`/runtime`'s `toLoopEvents` +
189
+ * `/stream`'s `normalizeToolEvent`) and then persisted identically — the
190
+ * store never sees a router-specific shape.
191
+ */
192
+
193
+ /** Start/end wall-clock millis, as normalized by `/stream`'s `normalizeTime`. */
194
+ interface ChatPartTime {
195
+ start?: number;
196
+ end?: number;
197
+ }
198
+ /** `id` is the harness's per-segment identity; absent on legacy/router parts,
199
+ * which collapse to a single logical text stream. Never invented client-side. */
200
+ interface ChatTextPart {
201
+ type: 'text';
202
+ text: string;
203
+ id?: string;
204
+ }
205
+ interface ChatReasoningPart {
206
+ type: 'reasoning';
207
+ text: string;
208
+ id?: string;
209
+ time?: ChatPartTime;
210
+ }
211
+ /** Superset of the sidecar's status enum (`pending|running|completed|failed`)
212
+ * and agent-interface's `ToolState` statuses; `error` is the persisted
213
+ * terminal form `/stream`'s `normalizePersistedPart` settles on. */
214
+ type ChatToolStatus = 'pending' | 'running' | 'completed' | 'error' | 'failed';
215
+ interface ChatToolState {
216
+ status: ChatToolStatus;
217
+ input?: unknown;
218
+ output?: unknown;
219
+ error?: string;
220
+ title?: string;
221
+ metadata?: Record<string, unknown>;
222
+ time?: ChatPartTime;
223
+ }
224
+ interface ChatToolPart {
225
+ type: 'tool';
226
+ id: string;
227
+ tool: string;
228
+ callID?: string;
229
+ state: ChatToolState;
230
+ }
231
+ /** Union of the sidecar's legacy (path-based) and AI-SDK (url-based) file
232
+ * shapes; response-side every field besides `type` is optional. */
233
+ interface ChatFilePart {
234
+ type: 'file';
235
+ id?: string;
236
+ filename?: string;
237
+ mediaType?: string;
238
+ url?: string;
239
+ path?: string;
240
+ content?: string;
241
+ }
242
+ interface ChatImagePart {
243
+ type: 'image';
244
+ filename?: string;
245
+ mediaType?: string;
246
+ url?: string;
247
+ path?: string;
248
+ }
249
+ interface ChatSubtaskPart {
250
+ type: 'subtask';
251
+ prompt: string;
252
+ description: string;
253
+ agent: string;
254
+ id?: string;
255
+ }
256
+ /** OpenCode step-boundary marker — no renderable text; preserved so mappers
257
+ * never coerce it into a "[object Object]" text part. */
258
+ interface ChatStepStartPart {
259
+ type: 'step-start';
260
+ }
261
+ /** Per-step usage receipt as the harness reports it (sidecar
262
+ * `StepFinishPartSchema`). The message-level token/cost columns are this
263
+ * shape flattened. */
264
+ interface ChatUsageTokens {
265
+ total?: number;
266
+ input?: number;
267
+ output?: number;
268
+ reasoning?: number;
269
+ cache?: {
270
+ write?: number;
271
+ read?: number;
272
+ };
273
+ }
274
+ interface ChatStepFinishPart {
275
+ type: 'step-finish';
276
+ reason?: string;
277
+ tokens?: ChatUsageTokens;
278
+ cost?: number;
279
+ }
280
+ /** Persisted human-in-the-loop ask — byte-matches
281
+ * `interactionToPersistedPart` in `/web-react`'s chat-interactions contract. */
282
+ interface ChatInteractionPart {
283
+ type: 'interaction';
284
+ id: string;
285
+ kind: string;
286
+ title: string;
287
+ body?: string;
288
+ answerSpec: {
289
+ fields: ChatInteractionField[];
290
+ };
291
+ status: ChatInteractionStatus;
292
+ answers?: InteractionAnswers;
293
+ cancelReason?: string;
294
+ }
295
+ type ChatPlanPart = ChatPlanPersistedPart;
296
+ /** Persisted one-line transcript notice — byte-matches `noticePart` in
297
+ * `/web-react`'s chat-interactions contract. */
298
+ interface ChatNoticePart {
299
+ type: 'notice';
300
+ id: string;
301
+ noticeKind: NoticeKind;
302
+ text: string;
303
+ }
304
+ /**
305
+ * A file the user `@`-mentioned on this turn: a workspace-relative path into
306
+ * the sandbox, never bytes. `type: 'mention'` is its own discriminant
307
+ * precisely so it does NOT collide with the `file`/`image` attachment parts —
308
+ * an attachment carries content the product uploaded, a mention points at
309
+ * something the box already has, and a transcript renders them differently
310
+ * (an inline pill, not an attachment card).
311
+ *
312
+ * `path` is the identity: mentioning one file twice in a turn folds to one
313
+ * part. `turnId` is optional and set by products that rebuild a turn's
314
+ * mentions on retry.
315
+ */
316
+ interface ChatMentionPart {
317
+ type: 'mention';
318
+ mentionKind: ChatMentionKind;
319
+ path: string;
320
+ name: string;
321
+ size?: number;
322
+ turnId?: string;
323
+ }
324
+ type ChatMessagePart = ChatTextPart | ChatReasoningPart | ChatToolPart | ChatFilePart | ChatImagePart | ChatSubtaskPart | ChatStepStartPart | ChatStepFinishPart | ChatInteractionPart | ChatNoticePart | ChatPlanPart | ChatMentionPart;
325
+ /** Every canonical harness wire-part kind must be storable — compile-time
326
+ * guarantee that a new agent-interface part kind cannot silently fall out of
327
+ * the persisted vocabulary. */
328
+ type StorableHarnessPartKind = Part['type'] & ChatMessagePart['type'];
329
+ /**
330
+ * The typed projection at the `/stream` → `/chat-store` boundary. The stream
331
+ * normalizers (`normalizePersistedPart`/`mergePersistedPart`/
332
+ * `finalizeAssistantParts`) deliberately produce untyped `JsonRecord`s — they
333
+ * normalize wire shapes and do not own the stored vocabulary. THIS module
334
+ * owns it, so this is where rows gain the `ChatMessagePart` type: each entry
335
+ * is validated against its kind's required fields and narrowed, junk is
336
+ * dropped, and — enforced by the exhaustiveness check below — no storable
337
+ * kind can silently fall out (the step-finish/interaction trap).
338
+ */
339
+ declare function toChatMessageParts(parts: Array<Record<string, unknown>>): ChatMessagePart[];
340
+ declare function isChatToolPart(part: ChatMessagePart): part is ChatToolPart;
341
+ declare function isChatTextPart(part: ChatMessagePart): part is ChatTextPart;
342
+ declare function isChatInteractionPart(part: ChatMessagePart): part is ChatInteractionPart;
343
+ declare function isChatPlanPart(part: ChatMessagePart): part is ChatPlanPart;
344
+ declare function isChatStepFinishPart(part: ChatMessagePart): part is ChatStepFinishPart;
345
+ /** Widened to `unknown` — unlike its siblings this guard also runs over raw
346
+ * untyped stored rows (a transcript renderer reads `message.parts` before the
347
+ * typed projection), which is exactly what {@link mentionPartsFromMessageParts}
348
+ * needs. `path` and `name` carry the pill; a row missing either is unrenderable.
349
+ *
350
+ * Mirrors the write contract exactly (`parseFileMention` in `/chat-routes`,
351
+ * then {@link mentionInputToPart}): a blank `name` is rejected there and so is
352
+ * rejected here, and `size` — optional, but typed `number` once present — is
353
+ * type-checked so `'12'` or `null` cannot ride through the guard wearing a
354
+ * type it does not have. Negative sizes are NOT re-rejected: the wire screens
355
+ * them, `mentionInputToPart` trusts its input, and a read guard stricter than
356
+ * what the writer can emit would drop rows it produced itself. */
357
+ declare function isChatMentionPart(part: unknown): part is ChatMentionPart;
358
+ /** Every mention part on one message, in stored order. The projection a
359
+ * transcript renderer runs before deciding which mentions the message text
360
+ * already shows inline (see `segmentMentionContent` in `/web-react`). */
361
+ declare function mentionPartsFromMessageParts(parts: ReadonlyArray<Record<string, unknown>> | ReadonlyArray<ChatMessagePart> | null | undefined): ChatMentionPart[];
362
+ /** A validated wire mention (`parseFileMentions` in `/chat-routes`) as the
363
+ * part the turn route persists. An absent/non-finite `size` is DROPPED rather
364
+ * than stored as `undefined`, so a stored row never carries a key that means
365
+ * nothing. */
366
+ declare function mentionInputToPart(input: FileMention): ChatMentionPart;
367
+
368
+ export { type ChatTurnRequestPayload as A, type ChatTurnPartInput as B, type ChatFilePart as C, type ChatTurnFilePartInput as D, ChatTurnInputError as E, type FileMention as F, type ChatTurnTextPartInput as G, type FileMentionsToPartsOptions as H, INLINE_PARTS_MAX_BYTES as I, type SandboxMentionPathCheck as J, assertPromptPartsWithinCap as K, buildMentionPromptBlock as L, MENTION_MAX_COUNT as M, chatTurnRequestInit as N, fileMentionsToParts as O, mediaTypeForMentionPath as P, mentionKindForPath as Q, parseChatTurnParts as R, type StorableHarnessPartKind as S, parseFileMentions as T, promptPartsByteSize as U, validateSandboxMentionPath as V, type ChatImagePart as a, type ChatInteractionPart as b, type ChatMentionKind as c, type ChatMentionPart as d, type ChatMessagePart as e, type ChatNoticePart as f, type ChatPartTime as g, type ChatPlanPart as h, type ChatReasoningPart as i, type ChatStepFinishPart as j, type ChatStepStartPart as k, type ChatSubtaskPart as l, type ChatTextPart as m, type ChatToolPart as n, type ChatToolState as o, type ChatToolStatus as p, type ChatUsageTokens as q, isChatInteractionPart as r, isChatMentionPart as s, isChatPlanPart as t, isChatStepFinishPart as u, isChatTextPart as v, isChatToolPart as w, mentionInputToPart as x, mentionPartsFromMessageParts as y, toChatMessageParts as z };