@tangle-network/agent-app 0.44.28 → 0.44.30

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 (50) hide show
  1. package/dist/assistant/index.d.ts +8 -6
  2. package/dist/assistant/index.js +6 -3
  3. package/dist/assistant/index.js.map +1 -1
  4. package/dist/{attachment-validation-Dvc_Livy.d.ts → attachment-validation-CNkH91Gs.d.ts} +1 -1
  5. package/dist/chat-react/index.d.ts +192 -0
  6. package/dist/chat-react/index.js +179 -0
  7. package/dist/chat-react/index.js.map +1 -0
  8. package/dist/chat-routes/index.d.ts +7 -6
  9. package/dist/chat-routes/index.js +13 -9
  10. package/dist/chat-routes/index.js.map +1 -1
  11. package/dist/chat-store/index.d.ts +6 -5
  12. package/dist/chat-store/index.js +2 -1
  13. package/dist/chat-store/index.js.map +1 -1
  14. package/dist/chunk-4OO7P3ZF.js +292 -0
  15. package/dist/chunk-4OO7P3ZF.js.map +1 -0
  16. package/dist/chunk-4PUMUTLU.js +158 -0
  17. package/dist/chunk-4PUMUTLU.js.map +1 -0
  18. package/dist/{chunk-7775L5NN.js → chunk-BAC2B2KI.js} +170 -7
  19. package/dist/chunk-BAC2B2KI.js.map +1 -0
  20. package/dist/{chunk-PRKSYTMQ.js → chunk-GCH3BUAZ.js} +31 -317
  21. package/dist/chunk-GCH3BUAZ.js.map +1 -0
  22. package/dist/{chunk-BI6NKSO4.js → chunk-IYLJS6VW.js} +3 -84
  23. package/dist/chunk-IYLJS6VW.js.map +1 -0
  24. package/dist/chunk-QY4BRKRJ.js +84 -0
  25. package/dist/chunk-QY4BRKRJ.js.map +1 -0
  26. package/dist/{chunk-C3SRFZGL.js → chunk-QYAQGCHF.js} +2 -154
  27. package/dist/chunk-QYAQGCHF.js.map +1 -0
  28. package/dist/{contract-CEewO6DI.d.ts → contract-CQNvv5th.d.ts} +1 -1
  29. package/dist/interactions/index.d.ts +2 -2
  30. package/dist/{parts-fyPPdDdK.d.ts → parts-7fbe2rj8.d.ts} +4 -274
  31. package/dist/{queue-vRI0Qx3X.d.ts → queue-VTBA5ONX.d.ts} +1 -1
  32. package/dist/sandbox/index.d.ts +253 -1
  33. package/dist/sandbox/index.js +9 -1
  34. package/dist/stream/index.d.ts +3 -3
  35. package/dist/{stream-normalizer-DnuqkZvw.d.ts → stream-normalizer-CnPnMaTp.d.ts} +1 -1
  36. package/dist/teams/index.js +5 -5
  37. package/dist/teams/invitations-api.js +4 -4
  38. package/dist/teams-react/index.js +3 -3
  39. package/dist/{types-DB82fktc.d.ts → types-CCeYywdS.d.ts} +1 -1
  40. package/dist/use-file-mentions-E6a7_cbH.d.ts +98 -0
  41. package/dist/web-react/index.d.ts +13 -104
  42. package/dist/web-react/index.js +17 -12
  43. package/dist/wire-DSp4LzEE.d.ts +272 -0
  44. package/dist/work-product/index.d.ts +3 -3
  45. package/dist/work-product-react/index.d.ts +1 -1
  46. package/package.json +6 -1
  47. package/dist/chunk-7775L5NN.js.map +0 -1
  48. package/dist/chunk-BI6NKSO4.js.map +0 -1
  49. package/dist/chunk-C3SRFZGL.js.map +0 -1
  50. package/dist/chunk-PRKSYTMQ.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { M as FileMention } from './parts-fyPPdDdK.js';
1
+ import { F as FileMention } from './wire-DSp4LzEE.js';
2
2
 
3
3
  /**
4
4
  * `createSandboxFileIndexRoute` — server side of `@`-file-mentions
@@ -0,0 +1,192 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { ModelInfo, HarnessType } from '@tangle-network/sandbox-ui/dashboard';
4
+ export { HarnessType } from '@tangle-network/sandbox-ui/dashboard';
5
+ import { ReasoningLevel, AgentComposer } from '@tangle-network/sandbox-ui/chat';
6
+ export { ReasoningLevel } from '@tangle-network/sandbox-ui/chat';
7
+ import { ReasoningEffort } from '@tangle-network/agent-interface';
8
+ export { ReasoningEffort } from '@tangle-network/agent-interface';
9
+ import { U as UseFileMentionsResult } from '../use-file-mentions-E6a7_cbH.js';
10
+ import { b as ChatAttachmentInput, F as FileMention } from '../wire-DSp4LzEE.js';
11
+
12
+ /**
13
+ * The model half of the composer's agent identity. `models` is the catalog the
14
+ * picker renders; `value` may be a bare or a canonical (provider-prefixed) id —
15
+ * the adapter maps it to canonical form for the picker and hands the canonical
16
+ * id back to `onChange`, so a product that stores bare ids only has to accept
17
+ * canonical ones in its setter.
18
+ */
19
+ interface ComposerModelSelection {
20
+ value: string;
21
+ onChange: (next: string) => void;
22
+ models: ModelInfo[];
23
+ loading?: boolean;
24
+ disabled?: boolean;
25
+ }
26
+ interface ComposerHarnessSelection {
27
+ value: HarnessType;
28
+ onChange: (next: HarnessType) => void;
29
+ /** Restrict the offered backends. Omit to take the context default. */
30
+ available?: ReadonlyArray<HarnessType>;
31
+ disabled?: boolean;
32
+ /**
33
+ * A thread's sidecar session is pinned to one harness at its first message,
34
+ * so once the thread has messages the picker locks. With `onNewChat` the
35
+ * locked chip becomes the informative lock (explains the binding + a button
36
+ * to start a fresh session on another backend).
37
+ */
38
+ locked?: boolean;
39
+ lockReason?: string;
40
+ onNewChat?: () => void;
41
+ }
42
+ interface ComposerEffortSelection {
43
+ value: ReasoningLevel;
44
+ onChange: (next: ReasoningLevel) => void;
45
+ /**
46
+ * Depths this product's backend actually applies. Omit for the default set.
47
+ * `auto` is NOT a member: the picker adds that sentinel itself, so listing it
48
+ * here would offer it twice.
49
+ */
50
+ available?: ReadonlyArray<ReasoningEffort>;
51
+ disabled?: boolean;
52
+ }
53
+ interface ComposerAgentControlsProps {
54
+ model: ComposerModelSelection;
55
+ /** Omit on a router-backed composer: a direct model call has no CLI backend,
56
+ * so the picker would be inert. Model + effort still render. */
57
+ harness?: ComposerHarnessSelection;
58
+ effort?: ComposerEffortSelection;
59
+ className?: string;
60
+ /**
61
+ * Which surface the controls live on. `'chat'` (the default) drops the
62
+ * shell-only `cli-base` backend — it has no conversational agent — and tells
63
+ * the shared control to use its chat-only default set. `'all'` keeps every
64
+ * backend for non-chat / scheduled surfaces.
65
+ */
66
+ context?: 'chat' | 'all';
67
+ /**
68
+ * Trigger layout. `'combined'` (the default) collapses the pickers behind one
69
+ * labeled trigger reading the current selection (`harness · model · effort`).
70
+ * `'gear'` uses an anonymous gear icon instead of the label; `'inline'` lays
71
+ * the pickers out in a row.
72
+ */
73
+ layout?: 'inline' | 'gear' | 'combined';
74
+ /**
75
+ * Where the pickers open. `'down'` pins them downward for a composer floating
76
+ * in open space (the centered entry surface) so a tall menu can't flip up over
77
+ * the heading. Defaults to `'auto'` (collision-aware).
78
+ */
79
+ menuPlacement?: 'auto' | 'down';
80
+ /**
81
+ * Restrict the model catalog to what the selected harness can run instead of
82
+ * letting an incompatible model snap the harness. ON by default: a workspace
83
+ * harness is sandbox-bound, and a silent swap tears down and recreates the
84
+ * sandbox. Turn OFF only on a model-first surface with no bound sandbox.
85
+ */
86
+ filterModelsToHarness?: boolean;
87
+ }
88
+ /**
89
+ * The composer's agent-identity control: harness (agent backend), model, and
90
+ * reasoning effort, over sandbox-ui's `AgentSessionControls`.
91
+ *
92
+ * This is an ADAPTER, not a second implementation. sandbox-ui owns the control
93
+ * and the harness↔model coherence policy (the catalog is filtered to the
94
+ * selected harness, the effort re-clamps to what the harness/model pair
95
+ * supports, and a harness that ignores a picker is marked with its dead control
96
+ * disabled). What lives here is the app-shell wiring every product otherwise
97
+ * re-derives:
98
+ *
99
+ * - MODEL-ID BOUNDARY. Products store bare ids (what a chat send body expects)
100
+ * while the picker matches on canonical provider-prefixed ids. The canonical
101
+ * form goes in; the canonical id comes back out to `onChange`.
102
+ * - HARNESS-SNAP SUPPRESSION. The shared control snaps the model whenever the
103
+ * harness changes, calling the model `onChange` synchronously with a default
104
+ * compatible model. A product that remembers a per-harness pick must ignore
105
+ * that snap, or it both discards the remembered pick and persists it under
106
+ * the wrong harness's key. The guard is armed for exactly the synchronous
107
+ * window of a harness change and disarmed on the next microtask, so it can
108
+ * never stay stuck — a later genuine pick is never swallowed, even when the
109
+ * harness change was a no-op.
110
+ * - CHAT-CONTEXT TRIM. `cli-base` never reaches a conversational surface.
111
+ *
112
+ * Behavioral modes (a plan toggle) are NOT agent identity and do not belong
113
+ * here — they dock on the other side of the composer via `controls`.
114
+ */
115
+ declare function ComposerAgentControls({ model, harness, effort, className, context, layout, menuPlacement, filterModelsToHarness, }: ComposerAgentControlsProps): react.JSX.Element;
116
+
117
+ interface EntryComposerProps {
118
+ /** The one line above the input. Domain copy — always a product parameter. */
119
+ heading?: ReactNode;
120
+ /** Optional supporting line under the heading. */
121
+ subheading?: ReactNode;
122
+ placeholder?: string;
123
+ initialValue?: string;
124
+ sendLabel?: string;
125
+ disabled?: boolean;
126
+ /**
127
+ * Agent identity (harness/model/effort). Pass it and the control row renders;
128
+ * omit it and the composer ships without one. Omitting is a real choice for a
129
+ * surface with nothing to choose — it should never be an oversight, which is
130
+ * why this is one prop rather than a free-form slot a caller can forget.
131
+ */
132
+ agent?: ComposerAgentControlsProps;
133
+ /**
134
+ * Behavioral modes docked on the LEFT (a plan-approval toggle). A mode is an
135
+ * on/off switch, not a value picker, so it sits apart from agent identity.
136
+ */
137
+ modes?: ReactNode;
138
+ /**
139
+ * Upload endpoint for staged attachments. Omit and the attach affordance is
140
+ * hidden — a composer with no place to put a file must not offer one.
141
+ */
142
+ uploadUrl?: string;
143
+ accept?: string;
144
+ onAttachmentError?: (reason: string) => void;
145
+ onRejectFiles?: Parameters<typeof AgentComposer>[0]['onRejectFiles'];
146
+ /**
147
+ * `@`-file mentions. The hook itself is shared (`useFileMentions`), but the
148
+ * cold-box policy around it — whether pressing `@` is worth starting a
149
+ * sandbox — is a per-surface product call, so the result is injected rather
150
+ * than created here.
151
+ */
152
+ mentions?: UseFileMentionsResult;
153
+ mentionPopoverClassName?: string;
154
+ /** Rendered under the composer: suggestion pills, an onboarding nudge, a
155
+ * disclaimer. All domain copy. */
156
+ footer?: ReactNode;
157
+ /** Block submit until a persisted selection has resolved against the catalog,
158
+ * so the first turn cannot go out under the wrong model. Defaults to true. */
159
+ ready?: boolean;
160
+ onSubmit: (prompt: string, attachments: ChatAttachmentInput[], mentions: FileMention[]) => void;
161
+ className?: string;
162
+ composerClassName?: string;
163
+ /** Max width of the centered column. Defaults to the fleet's 820px. */
164
+ maxWidth?: number;
165
+ }
166
+ /**
167
+ * `EntryComposer` — the centered "what do you want to work on?" surface a
168
+ * product shows before a conversation exists (a new thread, an empty session,
169
+ * a workspace overview).
170
+ *
171
+ * It exists because three products each grew their own, and they drifted into
172
+ * three different capability sets rather than three different looks: one lost
173
+ * the attach button, one lost the model and effort pickers entirely, one
174
+ * hand-rolled a `<textarea>` and wired pickers from three separate packages
175
+ * into one row. The composer, the pickers, the attachment queue and the mention
176
+ * index were all ALREADY shared — what was not shared was the assembly, so
177
+ * every product re-derived which controls an entry surface gets, and each
178
+ * re-derivation dropped a different one.
179
+ *
180
+ * Mechanism lives here: layout, the attachment queue, the mention wiring, the
181
+ * submit gate (nothing sends while an upload is pending or failed, or before
182
+ * the model selection has resolved). Domain stays a parameter: `heading`,
183
+ * `placeholder`, `footer` (suggestion pills, disclaimers) and the selections
184
+ * themselves.
185
+ *
186
+ * The docked in-thread composer is NOT this component — it renders
187
+ * `AgentComposer` directly with the same {@link ComposerAgentControls}, because
188
+ * a docked composer has a transcript above it and no hero layout.
189
+ */
190
+ declare function EntryComposer({ heading, subheading, placeholder, initialValue, sendLabel, disabled, agent, modes, uploadUrl, accept, onAttachmentError, onRejectFiles, mentions, mentionPopoverClassName, footer, ready, onSubmit, className, composerClassName, maxWidth, }: EntryComposerProps): react.JSX.Element;
191
+
192
+ export { ComposerAgentControls, type ComposerAgentControlsProps, type ComposerEffortSelection, type ComposerHarnessSelection, type ComposerModelSelection, EntryComposer, type EntryComposerProps };
@@ -0,0 +1,179 @@
1
+ import {
2
+ useComposerAttachments
3
+ } from "../chunk-4OO7P3ZF.js";
4
+ import {
5
+ ATTACHMENT_ACCEPT
6
+ } from "../chunk-IYLJS6VW.js";
7
+ import "../chunk-QYAQGCHF.js";
8
+
9
+ // src/chat-react/composer-agent-controls.tsx
10
+ import { useCallback, useMemo, useRef } from "react";
11
+ import { AgentSessionControls } from "@tangle-network/sandbox-ui/chat";
12
+ import { canonicalModelId } from "@tangle-network/sandbox-ui/dashboard";
13
+ import { jsx } from "react/jsx-runtime";
14
+ function harnessesForContext(available, context) {
15
+ if (!available) return available;
16
+ if (context !== "chat") return available;
17
+ return available.filter((h) => h !== "cli-base");
18
+ }
19
+ function ComposerAgentControls({
20
+ model,
21
+ harness,
22
+ effort,
23
+ className,
24
+ context = "chat",
25
+ layout = "combined",
26
+ menuPlacement,
27
+ filterModelsToHarness = true
28
+ }) {
29
+ const canonicalSelected = useMemo(() => {
30
+ const selected = model.models.find((m) => m.id === model.value);
31
+ if (selected) return canonicalModelId(selected);
32
+ return model.value;
33
+ }, [model.value, model.models]);
34
+ const harnessSwitching = useRef(false);
35
+ const harnessOnChange = harness?.onChange;
36
+ const onHarnessChange = useCallback(
37
+ (next) => {
38
+ harnessSwitching.current = true;
39
+ harnessOnChange?.(next);
40
+ queueMicrotask(() => {
41
+ harnessSwitching.current = false;
42
+ });
43
+ },
44
+ [harnessOnChange]
45
+ );
46
+ const modelOnChange = model.onChange;
47
+ const onModelChange = useCallback(
48
+ (canonical) => {
49
+ if (harnessSwitching.current) return;
50
+ modelOnChange(canonical);
51
+ },
52
+ [modelOnChange]
53
+ );
54
+ return /* @__PURE__ */ jsx(
55
+ AgentSessionControls,
56
+ {
57
+ className,
58
+ context,
59
+ layout,
60
+ menuPlacement,
61
+ filterModelsToHarness,
62
+ model: {
63
+ value: canonicalSelected,
64
+ onChange: onModelChange,
65
+ models: model.models,
66
+ loading: model.loading,
67
+ disabled: model.disabled
68
+ },
69
+ harness: harness ? {
70
+ value: harness.value,
71
+ onChange: onHarnessChange,
72
+ available: harnessesForContext(harness.available, context),
73
+ disabled: harness.disabled,
74
+ locked: harness.locked,
75
+ lockReason: harness.lockReason,
76
+ onNewChat: harness.onNewChat
77
+ } : void 0,
78
+ reasoning: effort ? {
79
+ value: effort.value,
80
+ onChange: effort.onChange,
81
+ available: effort.available,
82
+ disabled: effort.disabled
83
+ } : void 0
84
+ }
85
+ );
86
+ }
87
+
88
+ // src/chat-react/entry-composer.tsx
89
+ import { useState } from "react";
90
+ import { AgentComposer } from "@tangle-network/sandbox-ui/chat";
91
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
92
+ function EntryComposer({
93
+ heading,
94
+ subheading,
95
+ placeholder,
96
+ initialValue = "",
97
+ sendLabel,
98
+ disabled,
99
+ agent,
100
+ modes,
101
+ uploadUrl,
102
+ accept = ATTACHMENT_ACCEPT,
103
+ onAttachmentError,
104
+ onRejectFiles,
105
+ mentions,
106
+ mentionPopoverClassName,
107
+ footer,
108
+ ready = true,
109
+ onSubmit,
110
+ className,
111
+ composerClassName,
112
+ maxWidth = 820
113
+ }) {
114
+ const [value, setValue] = useState(initialValue);
115
+ const attachments = useComposerAttachments({
116
+ uploadUrl,
117
+ enabled: !!uploadUrl,
118
+ onReject: onAttachmentError,
119
+ onError: onAttachmentError
120
+ });
121
+ function submit(prompt) {
122
+ if (!ready || disabled) return;
123
+ const next = prompt.trim();
124
+ if (attachments.hasPending || attachments.hasError) {
125
+ if (attachments.blockReason) onAttachmentError?.(attachments.blockReason);
126
+ return;
127
+ }
128
+ if (!next && attachments.references.length === 0) return;
129
+ onSubmit(next, attachments.references, mentions?.mentions ?? []);
130
+ setValue("");
131
+ attachments.clear();
132
+ mentions?.clearMentions();
133
+ }
134
+ return /* @__PURE__ */ jsx2(
135
+ "div",
136
+ {
137
+ className: className ?? "relative flex flex-1 flex-col items-center justify-center overflow-hidden bg-background px-5",
138
+ children: /* @__PURE__ */ jsxs("div", { className: "w-full", style: { maxWidth }, children: [
139
+ heading ? /* @__PURE__ */ jsx2("h2", { className: "mb-4 text-center text-[1.75rem] font-medium tracking-tight text-foreground", children: heading }) : null,
140
+ subheading ? /* @__PURE__ */ jsx2("p", { className: "mx-auto mb-9 max-w-md text-center text-sm leading-relaxed text-muted-foreground", children: subheading }) : heading ? /* @__PURE__ */ jsx2("div", { className: "mb-7" }) : null,
141
+ /* @__PURE__ */ jsx2(
142
+ AgentComposer,
143
+ {
144
+ className: composerClassName ?? "vt-composer",
145
+ value,
146
+ onChange: setValue,
147
+ onSubmit: () => submit(value),
148
+ placeholder,
149
+ sendLabel,
150
+ disabled,
151
+ autoFocus: true,
152
+ canSubmitAttachmentsOnly: true,
153
+ accept,
154
+ attachments: attachments.composerFiles,
155
+ onAttach: uploadUrl ? (files) => void attachments.addFiles(files) : void 0,
156
+ onRejectFiles,
157
+ onRemoveFile: attachments.removeAttachment,
158
+ onRetryFile: attachments.retry,
159
+ mention: mentions ? {
160
+ ...mentions.mention,
161
+ // Sidebar tone + hairline so the popover reads as app chrome
162
+ // (the same treatment the picker menus get) instead of the
163
+ // brighter overlay tone the component defaults to.
164
+ popoverClassName: mentionPopoverClassName ?? "bg-surface-container-low border-[var(--md3-outline-variant)]"
165
+ } : void 0,
166
+ controls: modes,
167
+ trailing: agent ? /* @__PURE__ */ jsx2(ComposerAgentControls, { menuPlacement: "down", ...agent }) : void 0
168
+ }
169
+ ),
170
+ footer ? /* @__PURE__ */ jsx2("div", { className: "mt-7", children: footer }) : null
171
+ ] })
172
+ }
173
+ );
174
+ }
175
+ export {
176
+ ComposerAgentControls,
177
+ EntryComposer
178
+ };
179
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/chat-react/composer-agent-controls.tsx","../../src/chat-react/entry-composer.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef } from 'react'\nimport { AgentSessionControls } from '@tangle-network/sandbox-ui/chat'\nimport { canonicalModelId } from '@tangle-network/sandbox-ui/dashboard'\nimport type { ModelInfo } from '@tangle-network/sandbox-ui/dashboard'\nimport type { HarnessType, ReasoningEffort, ReasoningLevel } from './types'\n\n/**\n * The model half of the composer's agent identity. `models` is the catalog the\n * picker renders; `value` may be a bare or a canonical (provider-prefixed) id —\n * the adapter maps it to canonical form for the picker and hands the canonical\n * id back to `onChange`, so a product that stores bare ids only has to accept\n * canonical ones in its setter.\n */\nexport interface ComposerModelSelection {\n value: string\n onChange: (next: string) => void\n models: ModelInfo[]\n loading?: boolean\n disabled?: boolean\n}\n\nexport interface ComposerHarnessSelection {\n value: HarnessType\n onChange: (next: HarnessType) => void\n /** Restrict the offered backends. Omit to take the context default. */\n available?: ReadonlyArray<HarnessType>\n disabled?: boolean\n /**\n * A thread's sidecar session is pinned to one harness at its first message,\n * so once the thread has messages the picker locks. With `onNewChat` the\n * locked chip becomes the informative lock (explains the binding + a button\n * to start a fresh session on another backend).\n */\n locked?: boolean\n lockReason?: string\n onNewChat?: () => void\n}\n\nexport interface ComposerEffortSelection {\n value: ReasoningLevel\n onChange: (next: ReasoningLevel) => void\n /**\n * Depths this product's backend actually applies. Omit for the default set.\n * `auto` is NOT a member: the picker adds that sentinel itself, so listing it\n * here would offer it twice.\n */\n available?: ReadonlyArray<ReasoningEffort>\n disabled?: boolean\n}\n\nexport interface ComposerAgentControlsProps {\n model: ComposerModelSelection\n /** Omit on a router-backed composer: a direct model call has no CLI backend,\n * so the picker would be inert. Model + effort still render. */\n harness?: ComposerHarnessSelection\n effort?: ComposerEffortSelection\n className?: string\n /**\n * Which surface the controls live on. `'chat'` (the default) drops the\n * shell-only `cli-base` backend — it has no conversational agent — and tells\n * the shared control to use its chat-only default set. `'all'` keeps every\n * backend for non-chat / scheduled surfaces.\n */\n context?: 'chat' | 'all'\n /**\n * Trigger layout. `'combined'` (the default) collapses the pickers behind one\n * labeled trigger reading the current selection (`harness · model · effort`).\n * `'gear'` uses an anonymous gear icon instead of the label; `'inline'` lays\n * the pickers out in a row.\n */\n layout?: 'inline' | 'gear' | 'combined'\n /**\n * Where the pickers open. `'down'` pins them downward for a composer floating\n * in open space (the centered entry surface) so a tall menu can't flip up over\n * the heading. Defaults to `'auto'` (collision-aware).\n */\n menuPlacement?: 'auto' | 'down'\n /**\n * Restrict the model catalog to what the selected harness can run instead of\n * letting an incompatible model snap the harness. ON by default: a workspace\n * harness is sandbox-bound, and a silent swap tears down and recreates the\n * sandbox. Turn OFF only on a model-first surface with no bound sandbox.\n */\n filterModelsToHarness?: boolean\n}\n\n/**\n * The chat copilot must never offer `cli-base`: it is a shell-only backend with\n * no conversational agent. sandbox-ui's `context='chat'` drops it from the\n * default set, but an explicit `available` list (a plan-filtered one may include\n * `cli-base`) overrides that trim. So strip it here at the data layer whenever\n * the surface is chat — no `cli-base` ever reaches render.\n */\nfunction harnessesForContext(\n available: ReadonlyArray<HarnessType> | undefined,\n context: 'chat' | 'all',\n): ReadonlyArray<HarnessType> | undefined {\n if (!available) return available\n if (context !== 'chat') return available\n return available.filter((h) => h !== 'cli-base')\n}\n\n/**\n * The composer's agent-identity control: harness (agent backend), model, and\n * reasoning effort, over sandbox-ui's `AgentSessionControls`.\n *\n * This is an ADAPTER, not a second implementation. sandbox-ui owns the control\n * and the harness↔model coherence policy (the catalog is filtered to the\n * selected harness, the effort re-clamps to what the harness/model pair\n * supports, and a harness that ignores a picker is marked with its dead control\n * disabled). What lives here is the app-shell wiring every product otherwise\n * re-derives:\n *\n * - MODEL-ID BOUNDARY. Products store bare ids (what a chat send body expects)\n * while the picker matches on canonical provider-prefixed ids. The canonical\n * form goes in; the canonical id comes back out to `onChange`.\n * - HARNESS-SNAP SUPPRESSION. The shared control snaps the model whenever the\n * harness changes, calling the model `onChange` synchronously with a default\n * compatible model. A product that remembers a per-harness pick must ignore\n * that snap, or it both discards the remembered pick and persists it under\n * the wrong harness's key. The guard is armed for exactly the synchronous\n * window of a harness change and disarmed on the next microtask, so it can\n * never stay stuck — a later genuine pick is never swallowed, even when the\n * harness change was a no-op.\n * - CHAT-CONTEXT TRIM. `cli-base` never reaches a conversational surface.\n *\n * Behavioral modes (a plan toggle) are NOT agent identity and do not belong\n * here — they dock on the other side of the composer via `controls`.\n */\nexport function ComposerAgentControls({\n model,\n harness,\n effort,\n className,\n context = 'chat',\n layout = 'combined',\n menuPlacement,\n filterModelsToHarness = true,\n}: ComposerAgentControlsProps) {\n const canonicalSelected = useMemo(() => {\n const selected = model.models.find((m) => m.id === model.value)\n if (selected) return canonicalModelId(selected)\n // Already canonical, or the catalog has not loaded — pass through unchanged\n // so a provider-prefixed id still matches once models arrive.\n return model.value\n }, [model.value, model.models])\n\n const harnessSwitching = useRef(false)\n const harnessOnChange = harness?.onChange\n const onHarnessChange = useCallback(\n (next: HarnessType) => {\n harnessSwitching.current = true\n harnessOnChange?.(next)\n queueMicrotask(() => {\n harnessSwitching.current = false\n })\n },\n [harnessOnChange],\n )\n\n const modelOnChange = model.onChange\n const onModelChange = useCallback(\n (canonical: string) => {\n if (harnessSwitching.current) return\n modelOnChange(canonical)\n },\n [modelOnChange],\n )\n\n return (\n <AgentSessionControls\n className={className}\n context={context}\n layout={layout}\n menuPlacement={menuPlacement}\n filterModelsToHarness={filterModelsToHarness}\n model={{\n value: canonicalSelected,\n onChange: onModelChange,\n models: model.models,\n loading: model.loading,\n disabled: model.disabled,\n }}\n harness={\n harness\n ? {\n value: harness.value,\n onChange: onHarnessChange,\n available: harnessesForContext(harness.available, context),\n disabled: harness.disabled,\n locked: harness.locked,\n lockReason: harness.lockReason,\n onNewChat: harness.onNewChat,\n }\n : undefined\n }\n reasoning={\n effort\n ? {\n value: effort.value,\n onChange: effort.onChange,\n available: effort.available,\n disabled: effort.disabled,\n }\n : undefined\n }\n />\n )\n}\n","import { useState, type ReactNode } from 'react'\nimport { AgentComposer } from '@tangle-network/sandbox-ui/chat'\nimport { ATTACHMENT_ACCEPT, useComposerAttachments } from '../web-react/use-composer-attachments'\nimport type { UseFileMentionsResult } from '../web-react/use-file-mentions'\nimport type { ChatAttachmentInput, FileMention } from '../chat-routes/wire'\nimport {\n ComposerAgentControls,\n type ComposerAgentControlsProps,\n} from './composer-agent-controls'\n\nexport interface EntryComposerProps {\n /** The one line above the input. Domain copy — always a product parameter. */\n heading?: ReactNode\n /** Optional supporting line under the heading. */\n subheading?: ReactNode\n placeholder?: string\n initialValue?: string\n sendLabel?: string\n disabled?: boolean\n /**\n * Agent identity (harness/model/effort). Pass it and the control row renders;\n * omit it and the composer ships without one. Omitting is a real choice for a\n * surface with nothing to choose — it should never be an oversight, which is\n * why this is one prop rather than a free-form slot a caller can forget.\n */\n agent?: ComposerAgentControlsProps\n /**\n * Behavioral modes docked on the LEFT (a plan-approval toggle). A mode is an\n * on/off switch, not a value picker, so it sits apart from agent identity.\n */\n modes?: ReactNode\n /**\n * Upload endpoint for staged attachments. Omit and the attach affordance is\n * hidden — a composer with no place to put a file must not offer one.\n */\n uploadUrl?: string\n accept?: string\n onAttachmentError?: (reason: string) => void\n onRejectFiles?: Parameters<typeof AgentComposer>[0]['onRejectFiles']\n /**\n * `@`-file mentions. The hook itself is shared (`useFileMentions`), but the\n * cold-box policy around it — whether pressing `@` is worth starting a\n * sandbox — is a per-surface product call, so the result is injected rather\n * than created here.\n */\n mentions?: UseFileMentionsResult\n mentionPopoverClassName?: string\n /** Rendered under the composer: suggestion pills, an onboarding nudge, a\n * disclaimer. All domain copy. */\n footer?: ReactNode\n /** Block submit until a persisted selection has resolved against the catalog,\n * so the first turn cannot go out under the wrong model. Defaults to true. */\n ready?: boolean\n onSubmit: (\n prompt: string,\n attachments: ChatAttachmentInput[],\n mentions: FileMention[],\n ) => void\n className?: string\n composerClassName?: string\n /** Max width of the centered column. Defaults to the fleet's 820px. */\n maxWidth?: number\n}\n\n/**\n * `EntryComposer` — the centered \"what do you want to work on?\" surface a\n * product shows before a conversation exists (a new thread, an empty session,\n * a workspace overview).\n *\n * It exists because three products each grew their own, and they drifted into\n * three different capability sets rather than three different looks: one lost\n * the attach button, one lost the model and effort pickers entirely, one\n * hand-rolled a `<textarea>` and wired pickers from three separate packages\n * into one row. The composer, the pickers, the attachment queue and the mention\n * index were all ALREADY shared — what was not shared was the assembly, so\n * every product re-derived which controls an entry surface gets, and each\n * re-derivation dropped a different one.\n *\n * Mechanism lives here: layout, the attachment queue, the mention wiring, the\n * submit gate (nothing sends while an upload is pending or failed, or before\n * the model selection has resolved). Domain stays a parameter: `heading`,\n * `placeholder`, `footer` (suggestion pills, disclaimers) and the selections\n * themselves.\n *\n * The docked in-thread composer is NOT this component — it renders\n * `AgentComposer` directly with the same {@link ComposerAgentControls}, because\n * a docked composer has a transcript above it and no hero layout.\n */\nexport function EntryComposer({\n heading,\n subheading,\n placeholder,\n initialValue = '',\n sendLabel,\n disabled,\n agent,\n modes,\n uploadUrl,\n accept = ATTACHMENT_ACCEPT,\n onAttachmentError,\n onRejectFiles,\n mentions,\n mentionPopoverClassName,\n footer,\n ready = true,\n onSubmit,\n className,\n composerClassName,\n maxWidth = 820,\n}: EntryComposerProps) {\n const [value, setValue] = useState(initialValue)\n const attachments = useComposerAttachments({\n uploadUrl,\n enabled: !!uploadUrl,\n onReject: onAttachmentError,\n onError: onAttachmentError,\n })\n\n function submit(prompt: string) {\n if (!ready || disabled) return\n const next = prompt.trim()\n // A pending or failed upload must not send: the turn would reference an\n // attachment the store does not have. Surface why rather than no-op'ing.\n if (attachments.hasPending || attachments.hasError) {\n if (attachments.blockReason) onAttachmentError?.(attachments.blockReason)\n return\n }\n if (!next && attachments.references.length === 0) return\n onSubmit(next, attachments.references, mentions?.mentions ?? [])\n setValue('')\n attachments.clear()\n mentions?.clearMentions()\n }\n\n return (\n <div\n className={\n className ??\n 'relative flex flex-1 flex-col items-center justify-center overflow-hidden bg-background px-5'\n }\n >\n <div className=\"w-full\" style={{ maxWidth }}>\n {heading ? (\n <h2 className=\"mb-4 text-center text-[1.75rem] font-medium tracking-tight text-foreground\">\n {heading}\n </h2>\n ) : null}\n {subheading ? (\n <p className=\"mx-auto mb-9 max-w-md text-center text-sm leading-relaxed text-muted-foreground\">\n {subheading}\n </p>\n ) : (\n heading ? <div className=\"mb-7\" /> : null\n )}\n <AgentComposer\n className={composerClassName ?? 'vt-composer'}\n value={value}\n onChange={setValue}\n onSubmit={() => submit(value)}\n placeholder={placeholder}\n sendLabel={sendLabel}\n disabled={disabled}\n autoFocus\n canSubmitAttachmentsOnly\n accept={accept}\n attachments={attachments.composerFiles}\n onAttach={uploadUrl ? (files) => void attachments.addFiles(files) : undefined}\n onRejectFiles={onRejectFiles}\n onRemoveFile={attachments.removeAttachment}\n onRetryFile={attachments.retry}\n mention={\n mentions\n ? {\n ...mentions.mention,\n // Sidebar tone + hairline so the popover reads as app chrome\n // (the same treatment the picker menus get) instead of the\n // brighter overlay tone the component defaults to.\n popoverClassName:\n mentionPopoverClassName ??\n 'bg-surface-container-low border-[var(--md3-outline-variant)]',\n }\n : undefined\n }\n controls={modes}\n trailing={\n agent ? <ComposerAgentControls menuPlacement=\"down\" {...agent} /> : undefined\n }\n />\n {footer ? <div className=\"mt-7\">{footer}</div> : null}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["jsx"]}
@@ -1,17 +1,18 @@
1
- import { C as ChatMessagePart, N as ChatTurnRequestPayload, O as ChatTurnPartInput, P as ChatTurnFilePartInput, b as ChatAttachmentPart, a as ChatAttachmentKind, g as ChatMentionPart } from '../parts-fyPPdDdK.js';
2
- export { Q as ChatAttachmentInput, f as ChatMentionKind, R as ChatTurnInputError, T as ChatTurnTextPartInput, U as DISPATCH_MAX_MEDIA_PARTS, V as DISPATCH_MAX_PARTS, W as DISPATCH_REQUEST_MAX_BYTES, X as DISPATCH_STRUCTURAL_RESERVE_BYTES, M as FileMention, Y as FileMentionsToPartsOptions, Z as INLINE_PARTS_MAX_BYTES, _ as MENTION_MAX_COUNT, $ as ProducerErrorEvent, a0 as ProducerNoticeEvent, a1 as ProducerPassthroughEvent, a2 as ProducerPassthroughEventType, a3 as ProducerReasoningEvent, a4 as ProducerTextEvent, a5 as ProducerToolCallEvent, a6 as ProducerToolResultEvent, a7 as ProducerUsageEvent, a8 as ProducerWireEvent, a9 as SandboxMentionPathCheck, aa as assertPromptPartsWithinCap, ab as base64WireLen, ac as buildMentionPromptBlock, ad as chatTurnRequestInit, ae as fileMentionsToParts, af as formatBytes, ag as mediaTypeForMentionPath, ah as mentionKindForPath, ai as parseChatTurnParts, aj as parseFileMentions, ak as promptPartsByteSize, al as validateSandboxMentionPath } from '../parts-fyPPdDdK.js';
3
- export { A as ALLOWED_ATTACHMENT_SNIFFED_MIMES, a as ATTACHMENT_ACCEPT, b as ATTACHMENT_MAX_COUNT, c as AttachmentTypeCheckResult, C as CreateSandboxFileIndexRouteOptions, F as FileIndexAuthorization, d as FileIndexCache, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse, M as MAX_ATTACHMENT_TOTAL_BYTES, h as MAX_BINARY_ATTACHMENT_BYTES, i as MAX_TEXT_ATTACHMENT_BYTES, S as SandboxFileTreeSource, j as SandboxTreeFile, k as SandboxTreeResult, l as SniffResult, m as attachmentSizeErrorMessage, n as attachmentTotalSizeErrorMessage, o as checkAttachmentType, p as createSandboxFileIndexRoute, s as sanitizeAttachmentFileName, q as sniffBinary } from '../attachment-validation-Dvc_Livy.js';
1
+ import { c as ChatTurnRequestPayload, d as ChatTurnPartInput, e as ChatTurnFilePartInput, a as ChatAttachmentKind } from '../wire-DSp4LzEE.js';
2
+ export { b as ChatAttachmentInput, C as ChatMentionKind, f as ChatTurnInputError, g as ChatTurnTextPartInput, D as DISPATCH_MAX_MEDIA_PARTS, h as DISPATCH_MAX_PARTS, i as DISPATCH_REQUEST_MAX_BYTES, j as DISPATCH_STRUCTURAL_RESERVE_BYTES, F as FileMention, k as FileMentionsToPartsOptions, I as INLINE_PARTS_MAX_BYTES, M as MENTION_MAX_COUNT, P as ProducerErrorEvent, l as ProducerNoticeEvent, m as ProducerPassthroughEvent, n as ProducerPassthroughEventType, o as ProducerReasoningEvent, p as ProducerTextEvent, q as ProducerToolCallEvent, r as ProducerToolResultEvent, s as ProducerUsageEvent, t as ProducerWireEvent, S as SandboxMentionPathCheck, u as assertPromptPartsWithinCap, v as base64WireLen, w as buildMentionPromptBlock, x as chatTurnRequestInit, y as fileMentionsToParts, z as formatBytes, A as mediaTypeForMentionPath, B as mentionKindForPath, E as parseChatTurnParts, G as parseFileMentions, H as promptPartsByteSize, J as validateSandboxMentionPath } from '../wire-DSp4LzEE.js';
3
+ export { A as ALLOWED_ATTACHMENT_SNIFFED_MIMES, a as ATTACHMENT_ACCEPT, b as ATTACHMENT_MAX_COUNT, c as AttachmentTypeCheckResult, C as CreateSandboxFileIndexRouteOptions, F as FileIndexAuthorization, d as FileIndexCache, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse, M as MAX_ATTACHMENT_TOTAL_BYTES, h as MAX_BINARY_ATTACHMENT_BYTES, i as MAX_TEXT_ATTACHMENT_BYTES, S as SandboxFileTreeSource, j as SandboxTreeFile, k as SandboxTreeResult, l as SniffResult, m as attachmentSizeErrorMessage, n as attachmentTotalSizeErrorMessage, o as checkAttachmentType, p as createSandboxFileIndexRoute, s as sanitizeAttachmentFileName, q as sniffBinary } from '../attachment-validation-CNkH91Gs.js';
4
4
  import { ChatTurnIdentity, ChatTurnProducer } from '@tangle-network/agent-runtime/durable';
5
+ import { C as ChatMessagePart, a as ChatAttachmentPart, e as ChatMentionPart } from '../parts-7fbe2rj8.js';
5
6
  import { InteractionAnswerRoute, InteractionAnswerRouteOptions } from '../interactions/index.js';
6
7
  import { PersistedChatMessageForTurn } from '../stream/index.js';
7
8
  import { T as TurnEventStore } from '../turn-buffer-BcPfhr1_.js';
8
9
  import { M as ModelFailoverAttempt } from '../failover-D-3UXXTb.js';
9
10
  export { D as DEFAULT_STALE_TURN_LOCK_GRACE_MS, a as DEFAULT_TERMINAL_TURN_LOCK_GRACE_MS, R as ReconcileStaleTurnLockOptions, b as ReconcileStaleTurnLockResult, S as StaleTurnLockSandboxProbeResult, c as StaleTurnLockSessionProbeResult, r as reconcileStaleTurnLock } from '../stale-turn-lock-DucQzvXu.js';
10
- import { J as JsonRecord } from '../stream-normalizer-DnuqkZvw.js';
11
+ import { J as JsonRecord } from '../stream-normalizer-CnPnMaTp.js';
11
12
  import { SandboxExecChannel, PromptInputPart } from '../sandbox/index.js';
12
13
  import '@tangle-network/agent-interface';
13
- import '../contract-CEewO6DI.js';
14
- import '../types-DB82fktc.js';
14
+ import '../contract-CQNvv5th.js';
15
+ import '../types-CCeYywdS.js';
15
16
  import '../plans/index.js';
16
17
  import '@tangle-network/sandbox';
17
18
  import '../auth-DJs6lfAs.js';
@@ -1,3 +1,6 @@
1
+ import {
2
+ createSandboxFileIndexRoute
3
+ } from "../chunk-QY4BRKRJ.js";
1
4
  import {
2
5
  ALLOWED_ATTACHMENT_SNIFFED_MIMES,
3
6
  ATTACHMENT_ACCEPT,
@@ -8,10 +11,9 @@ import {
8
11
  attachmentSizeErrorMessage,
9
12
  attachmentTotalSizeErrorMessage,
10
13
  checkAttachmentType,
11
- createSandboxFileIndexRoute,
12
14
  sanitizeAttachmentFileName,
13
15
  sniffBinary
14
- } from "../chunk-BI6NKSO4.js";
16
+ } from "../chunk-IYLJS6VW.js";
15
17
  import {
16
18
  coalesceDeltas,
17
19
  createBufferedTurnTap,
@@ -31,6 +33,13 @@ import {
31
33
  import {
32
34
  parseJsonObjectBody
33
35
  } from "../chunk-PTUMBMVH.js";
36
+ import {
37
+ attachmentInputToPart,
38
+ attachmentKindForMime,
39
+ mentionInputToPart,
40
+ toChatMessageParts
41
+ } from "../chunk-4PUMUTLU.js";
42
+ import "../chunk-ZVEEWGDK.js";
34
43
  import {
35
44
  ChatTurnInputError,
36
45
  DISPATCH_MAX_MEDIA_PARTS,
@@ -40,23 +49,18 @@ import {
40
49
  INLINE_PARTS_MAX_BYTES,
41
50
  MENTION_MAX_COUNT,
42
51
  assertPromptPartsWithinCap,
43
- attachmentInputToPart,
44
- attachmentKindForMime,
45
52
  base64WireLen,
46
53
  buildMentionPromptBlock,
47
54
  chatTurnRequestInit,
48
55
  fileMentionsToParts,
49
56
  formatBytes,
50
57
  mediaTypeForMentionPath,
51
- mentionInputToPart,
52
58
  mentionKindForPath,
53
59
  parseChatTurnParts,
54
60
  parseFileMentions,
55
61
  promptPartsByteSize,
56
- toChatMessageParts,
57
62
  validateSandboxMentionPath
58
- } from "../chunk-C3SRFZGL.js";
59
- import "../chunk-ZVEEWGDK.js";
63
+ } from "../chunk-QYAQGCHF.js";
60
64
  import {
61
65
  asRecord,
62
66
  asString,
@@ -93,7 +97,7 @@ import {
93
97
  flattenHistory,
94
98
  readSandboxBinaryBytes,
95
99
  statSandboxFileSize
96
- } from "../chunk-7775L5NN.js";
100
+ } from "../chunk-BAC2B2KI.js";
97
101
  import "../chunk-LWSJK546.js";
98
102
  import "../chunk-CQZSAR77.js";
99
103
  import "../chunk-ICOHEZK6.js";