@tangle-network/agent-app 0.43.23 → 0.43.25
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-auth/index.d.ts +163 -0
- package/dist/app-auth/index.js +166 -0
- package/dist/app-auth/index.js.map +1 -0
- package/dist/assets/index.d.ts +2 -2
- package/dist/assistant/index.d.ts +1 -0
- package/dist/assistant/index.js +2 -1
- package/dist/assistant/index.js.map +1 -1
- package/dist/chat-store/index.d.ts +193 -0
- package/dist/chat-store/index.js +194 -0
- package/dist/chat-store/index.js.map +1 -0
- package/dist/chunk-4H77LX3V.js +38 -0
- package/dist/chunk-4H77LX3V.js.map +1 -0
- package/dist/chunk-4TXDD6P2.js +163 -0
- package/dist/chunk-4TXDD6P2.js.map +1 -0
- package/dist/chunk-AVBANQ67.js +295 -0
- package/dist/chunk-AVBANQ67.js.map +1 -0
- package/dist/{chunk-UKYZ4O2O.js → chunk-JJGZ54EB.js} +64 -5
- package/dist/chunk-JJGZ54EB.js.map +1 -0
- package/dist/{chunk-VMY4TKMN.js → chunk-PEPXQTJ3.js} +921 -432
- package/dist/chunk-PEPXQTJ3.js.map +1 -0
- package/dist/chunk-U7DLCPJ6.js +203 -0
- package/dist/chunk-U7DLCPJ6.js.map +1 -0
- package/dist/{chunk-SAOAAA3S.js → chunk-UHXQ3KNX.js} +1 -22
- package/dist/chunk-UHXQ3KNX.js.map +1 -0
- package/dist/contract-DYbTzEDf.d.ts +122 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +172 -88
- package/dist/interactions/index.d.ts +141 -0
- package/dist/interactions/index.js +59 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/parts-BeRnK54I.d.ts +185 -0
- package/dist/platform/index.d.ts +2 -270
- package/dist/platform/index.js +12 -278
- package/dist/platform/index.js.map +1 -1
- package/dist/preset-cloudflare/index.d.ts +0 -10
- package/dist/preset-cloudflare/index.js +1 -1
- package/dist/profile/index.d.ts +33 -2
- package/dist/profile/index.js +37 -1
- package/dist/profile/index.js.map +1 -1
- package/dist/sandbox/index.d.ts +61 -5
- package/dist/sandbox/index.js +13 -1
- package/dist/sso-Df4wtL8D.d.ts +270 -0
- package/dist/teams/index.js +9 -9
- package/dist/teams/invitations-api.js +3 -3
- package/dist/web-react/index.d.ts +206 -96
- package/dist/web-react/index.js +68 -22
- package/package.json +21 -2
- package/dist/chunk-SAOAAA3S.js.map +0 -1
- package/dist/chunk-UKYZ4O2O.js.map +0 -1
- package/dist/chunk-VMY4TKMN.js.map +0 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { C as ChatInteraction, a as ChatInteractionField, b as ChatInteractionStatus, c as ChatSelectField, g as InteractionCancelData, i as InteractionRequestWire } from '../contract-DYbTzEDf.js';
|
|
4
|
+
export { d as ComposerAnswerDelivery, I as INTERACTION_CANCEL_EVENT, e as INTERACTION_EVENT, f as INTERACTION_RESOLVED_EVENT, h as InteractionPersistedPart, N as NoticeKind, j as NoticePersistedPart, P as ParseInteractionResult, k as canTransitionInteractionStatus, l as cancelStatusFor, m as composerAnswerData, n as composerAnswerDeliveries, o as dedupeQuestionInteractionsByContent, p as fieldAcceptsFreeText, q as interactionFromWireRequest, r as interactionPartKey, s as interactionToPersistedPart, t as isRenderableInteractionKind, u as isSafeInteractionFieldKey, v as isTerminalInteractionStatus, w as noticePart, x as noticePartKey, y as parseInteractionCancel, z as parseInteractionRequest, A as persistedPartToInteraction, B as questionInteractionContentSignature } from '../contract-DYbTzEDf.js';
|
|
5
|
+
import { InteractionData } from '@tangle-network/agent-interface';
|
|
4
6
|
export { InteractionData, InteractionOutcome, InteractionRequest } from '@tangle-network/agent-interface';
|
|
5
7
|
import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
6
8
|
import { a as FlowTrace } from '../flow-types-Cb_AblZs.js';
|
|
@@ -8,99 +10,6 @@ export { S as SandboxTerminalConnection, a as SandboxTerminalConnectionResponse,
|
|
|
8
10
|
import { CatalogModel } from '../catalog/index.js';
|
|
9
11
|
import { Harness } from '../harness/index.js';
|
|
10
12
|
|
|
11
|
-
/** Sidecar → client: the agent raised an ask; data = `{ request }`. */
|
|
12
|
-
declare const INTERACTION_EVENT: "interaction";
|
|
13
|
-
/** Sidecar → client: the ask was withdrawn; data = `{ id, reason? }`. */
|
|
14
|
-
declare const INTERACTION_CANCEL_EVENT: "interaction.cancel";
|
|
15
|
-
/** An ask was answered; data = `{ id, status }`. In the wire contract so a
|
|
16
|
-
* server broadcast and a client-local mark share one event name. */
|
|
17
|
-
declare const INTERACTION_RESOLVED_EVENT: "interaction.resolved";
|
|
18
|
-
declare function isRenderableInteractionKind(kind: string): boolean;
|
|
19
|
-
/** Answer/field keys the sidecar will accept: identifier-safe and never a
|
|
20
|
-
* prototype-pollution vector. */
|
|
21
|
-
declare function isSafeInteractionFieldKey(key: string): boolean;
|
|
22
|
-
type ChatSelectField = Extract<InteractionField, {
|
|
23
|
-
type: 'select';
|
|
24
|
-
}> & {
|
|
25
|
-
allowCustom?: boolean;
|
|
26
|
-
};
|
|
27
|
-
type ChatInteractionField = Exclude<InteractionField, {
|
|
28
|
-
type: 'select';
|
|
29
|
-
}> | ChatSelectField;
|
|
30
|
-
/** `InteractionRequest` whose select fields may carry `allowCustom`. */
|
|
31
|
-
type InteractionRequestWire = Omit<InteractionRequest, 'answerSpec'> & {
|
|
32
|
-
answerSpec: {
|
|
33
|
-
fields: ChatInteractionField[];
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
type ChatInteractionStatus = 'pending' | 'answered' | 'declined' | 'cancelled' | 'expired';
|
|
37
|
-
/** The client/persisted view of one ask. `fields` come verbatim off the wire. */
|
|
38
|
-
interface ChatInteraction {
|
|
39
|
-
id: string;
|
|
40
|
-
kind: string;
|
|
41
|
-
title: string;
|
|
42
|
-
body?: string;
|
|
43
|
-
fields: ChatInteractionField[];
|
|
44
|
-
status: ChatInteractionStatus;
|
|
45
|
-
/** Set when status came from an `interaction.cancel` (e.g. "timeout"). */
|
|
46
|
-
cancelReason?: string;
|
|
47
|
-
}
|
|
48
|
-
declare function isTerminalInteractionStatus(status: ChatInteractionStatus): boolean;
|
|
49
|
-
/** Statuses only move forward (pending → terminal); a replayed/stale `pending`
|
|
50
|
-
* must never resurrect a resolved card. */
|
|
51
|
-
declare function canTransitionInteractionStatus(from: ChatInteractionStatus, to: ChatInteractionStatus): boolean;
|
|
52
|
-
/** Maps an `interaction.cancel` reason to the card's terminal status. */
|
|
53
|
-
declare function cancelStatusFor(reason: string | undefined): ChatInteractionStatus;
|
|
54
|
-
/** Content identity for duplicate safety nets. Excludes volatile ids/statuses. */
|
|
55
|
-
declare function questionInteractionContentSignature(interaction: ChatInteraction): string | null;
|
|
56
|
-
declare function dedupeQuestionInteractionsByContent(interactions: ChatInteraction[]): ChatInteraction[];
|
|
57
|
-
type ParseInteractionResult = {
|
|
58
|
-
succeeded: true;
|
|
59
|
-
value: InteractionRequestWire;
|
|
60
|
-
} | {
|
|
61
|
-
succeeded: false;
|
|
62
|
-
error: string;
|
|
63
|
-
};
|
|
64
|
-
/** Parses an `interaction` event's data (`{ request }`). Validates the shape
|
|
65
|
-
* with the agent-interface schema but returns the raw request so a field a
|
|
66
|
-
* pinned schema predates (`allowCustom`) survives. */
|
|
67
|
-
declare function parseInteractionRequest(data: Record<string, unknown> | undefined): ParseInteractionResult;
|
|
68
|
-
interface InteractionCancelData {
|
|
69
|
-
id: string;
|
|
70
|
-
reason?: string;
|
|
71
|
-
}
|
|
72
|
-
declare function parseInteractionCancel(data: Record<string, unknown> | undefined): {
|
|
73
|
-
succeeded: true;
|
|
74
|
-
value: InteractionCancelData;
|
|
75
|
-
} | {
|
|
76
|
-
succeeded: false;
|
|
77
|
-
error: string;
|
|
78
|
-
};
|
|
79
|
-
declare function fieldAcceptsFreeText(field: ChatInteractionField): boolean;
|
|
80
|
-
interface ComposerAnswerDelivery {
|
|
81
|
-
interactionId: string;
|
|
82
|
-
field: ChatInteractionField;
|
|
83
|
-
}
|
|
84
|
-
/** One delivery per pending ask: the first free-text-capable field, else the
|
|
85
|
-
* first field. Zero-field asks are skipped (nothing to carry the text). */
|
|
86
|
-
declare function composerAnswerDeliveries(pending: ChatInteraction[]): ComposerAnswerDelivery[];
|
|
87
|
-
/** Shapes composer text into the respond payload for the routed field
|
|
88
|
-
* (select answers are string arrays on the wire; text answers are strings). */
|
|
89
|
-
declare function composerAnswerData(field: ChatInteractionField, text: string): InteractionData;
|
|
90
|
-
declare function interactionPartKey(id: string): string;
|
|
91
|
-
declare function noticePartKey(id: string): string;
|
|
92
|
-
type NoticeKind = 'warning' | 'auto-declined';
|
|
93
|
-
/** Builds the persisted/streamed `notice` part — a one-line transcript notice
|
|
94
|
-
* explaining an out-of-band event (warning, auto-declined interaction). */
|
|
95
|
-
declare function noticePart(noticeKind: NoticeKind, id: string, text: string): Record<string, unknown>;
|
|
96
|
-
/** Reads a wire request into the client's pending `ChatInteraction`. */
|
|
97
|
-
declare function interactionFromWireRequest(request: InteractionRequestWire): ChatInteraction;
|
|
98
|
-
/** Builds the persisted/streamed `interaction` part from a wire request. */
|
|
99
|
-
declare function interactionToPersistedPart(request: InteractionRequestWire, status: ChatInteractionStatus, cancelReason?: string): Record<string, unknown>;
|
|
100
|
-
/** Reads a persisted/streamed `interaction` part back into a `ChatInteraction`.
|
|
101
|
-
* Returns null (caller logs) when the part is not one of ours. */
|
|
102
|
-
declare function persistedPartToInteraction(part: Record<string, unknown>): ChatInteraction | null;
|
|
103
|
-
|
|
104
13
|
/**
|
|
105
14
|
* Client-side chat-stream consumption — the NDJSON parse loop every agent
|
|
106
15
|
* app's chat UI hand-rolls (and breaks). Normalizes the three line shapes the
|
|
@@ -143,7 +52,10 @@ interface ChatStreamCallbacks {
|
|
|
143
52
|
completionTokens: number;
|
|
144
53
|
}) => void;
|
|
145
54
|
onMetadata?: (data: Record<string, unknown>) => void;
|
|
146
|
-
/** A loop-level error event (the turn failed server-side).
|
|
55
|
+
/** A loop-level error event (the turn failed server-side). Optional, but the
|
|
56
|
+
* error never vanishes: when omitted, the message is synthesized into the
|
|
57
|
+
* transcript via `onText` (rendered by ChatMessages as a text segment) and
|
|
58
|
+
* logged with `console.error`. */
|
|
147
59
|
onErrorEvent?: (message: string) => void;
|
|
148
60
|
/** A sidecar interaction ask (kind: "question"/"plan"/…). The run is BLOCKED
|
|
149
61
|
* in the broker until the user answers; a pending ask is "waiting on the
|
|
@@ -227,6 +139,204 @@ interface ChatComposerProps {
|
|
|
227
139
|
}
|
|
228
140
|
declare function ChatComposer({ onSend, onCancel, isStreaming, disabled, placeholder, value, onValueChange, initialValue, controls, controlsPlacement, onAttach, onAttachFolder, pendingFiles, onRemoveFile, accept, dropTitle, dropDescription, focusShortcut, sendLabel, className, }: ChatComposerProps): react.JSX.Element;
|
|
229
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Shared answer-building + submit plumbing for the interaction cards
|
|
144
|
+
* (question, plan). Client-safe, no React: cards own their state, this owns
|
|
145
|
+
* the wire. Lifted from the gtm-agent fork (the most fix-absorbed of the three
|
|
146
|
+
* product copies), including the 30s submit timeout that keeps a dead route
|
|
147
|
+
* from wedging a card in "Submitting…".
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/** Status-badge labels for an interaction card. `cancelled`/`expired` read the
|
|
151
|
+
* same across cards; each card supplies its own verbs for the other states
|
|
152
|
+
* (a question is answered/declined; a plan is approved/rejected). */
|
|
153
|
+
declare function interactionStatusLabels(labels: {
|
|
154
|
+
pending: string;
|
|
155
|
+
answered: string;
|
|
156
|
+
declined: string;
|
|
157
|
+
}): Record<ChatInteractionStatus, string>;
|
|
158
|
+
/** Terminal-state notes for an interaction card. The expiry/withdrawal lines
|
|
159
|
+
* share one shape around the card's noun ("question"/"plan"); any extra notes
|
|
160
|
+
* (e.g. a plan's `declined` revision line) merge on top. */
|
|
161
|
+
declare function interactionTerminalNotes(noun: string, extra?: Partial<Record<ChatInteractionStatus, string>>): Partial<Record<ChatInteractionStatus, string>>;
|
|
162
|
+
type FieldValues = Record<string, {
|
|
163
|
+
selected?: string[];
|
|
164
|
+
text?: string;
|
|
165
|
+
custom?: string;
|
|
166
|
+
}>;
|
|
167
|
+
/** The submitted value for one field, or null when it has no answer yet. */
|
|
168
|
+
declare function fieldAnswer(field: ChatInteractionField, values: FieldValues): InteractionData[string] | null;
|
|
169
|
+
/** All required fields answered → the respond payload; else null (not
|
|
170
|
+
* submittable yet). Optional unanswered fields are omitted. */
|
|
171
|
+
declare function buildAnswerData(fields: ChatInteractionField[], values: FieldValues): InteractionData | null;
|
|
172
|
+
declare function isLateAnswerableStatus(status: ChatInteractionStatus): boolean;
|
|
173
|
+
/** Secrets must never leave the sidecar answer channel for the visible chat
|
|
174
|
+
* transcript, so a secret-bearing ask cannot be late-answered. */
|
|
175
|
+
declare function hasSecretField(fields: ChatInteractionField[]): boolean;
|
|
176
|
+
/** Renders the late answer as a self-contained chat message: the original
|
|
177
|
+
* question, its context, and the user's answer(s). */
|
|
178
|
+
declare function lateAnswerMessage(interaction: ChatInteraction, data: InteractionData): string;
|
|
179
|
+
declare const INTERACTION_SUBMIT_TIMEOUT_MS = 30000;
|
|
180
|
+
declare const INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
|
|
181
|
+
/** One card submission: which ask, resolved how, with what answers. */
|
|
182
|
+
interface InteractionAnswerSubmission {
|
|
183
|
+
id: string;
|
|
184
|
+
outcome: 'accepted' | 'declined';
|
|
185
|
+
data?: InteractionData;
|
|
186
|
+
}
|
|
187
|
+
type InteractionSubmitResult = {
|
|
188
|
+
ok: true;
|
|
189
|
+
} | {
|
|
190
|
+
ok: false;
|
|
191
|
+
expired: boolean;
|
|
192
|
+
message: string;
|
|
193
|
+
};
|
|
194
|
+
/** The cards' only side-effect seam: POST one resolution, report the normalized
|
|
195
|
+
* outcome. Products bind their route URL + routing fields (workspaceId,
|
|
196
|
+
* threadId, session path param) via `createInteractionAnswerSubmitter` or a
|
|
197
|
+
* hand-rolled implementation. */
|
|
198
|
+
type SubmitInteractionAnswer = (submission: InteractionAnswerSubmission) => Promise<InteractionSubmitResult>;
|
|
199
|
+
/** Extracts the most specific error message a route returned. */
|
|
200
|
+
declare function responseErrorMessage(res: Response): Promise<{
|
|
201
|
+
code?: string;
|
|
202
|
+
message: string;
|
|
203
|
+
}>;
|
|
204
|
+
interface InteractionAnswerSubmitterOptions {
|
|
205
|
+
/** The product's answer route (the POST half of `createInteractionAnswerRoute`).
|
|
206
|
+
* A function when the URL carries the session (e.g. `/api/sessions/${id}/interactions`). */
|
|
207
|
+
url: string | ((submission: InteractionAnswerSubmission) => string);
|
|
208
|
+
/** Extra routing fields merged into the POST body (e.g. workspaceId, threadId). */
|
|
209
|
+
body?: Record<string, unknown> | ((submission: InteractionAnswerSubmission) => Record<string, unknown>);
|
|
210
|
+
timeoutMs?: number;
|
|
211
|
+
fetchImpl?: typeof fetch;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Builds the `SubmitInteractionAnswer` the cards consume: POSTs
|
|
215
|
+
* `{ ...routingFields, id, outcome, data? }` with an abortable timeout and
|
|
216
|
+
* normalizes the outcome. `expired` is the 410 path — the ask is gone
|
|
217
|
+
* (answered elsewhere, timed out, or the session moved on) and the card must
|
|
218
|
+
* flip to the same dead state a cancel event produces.
|
|
219
|
+
*/
|
|
220
|
+
declare function createInteractionAnswerSubmitter(options: InteractionAnswerSubmitterOptions): SubmitInteractionAnswer;
|
|
221
|
+
|
|
222
|
+
type InteractionBadgeVariant = 'outline' | 'default' | 'destructive';
|
|
223
|
+
declare function InteractionBadge({ variant, children }: {
|
|
224
|
+
variant: InteractionBadgeVariant;
|
|
225
|
+
children: string;
|
|
226
|
+
}): react.JSX.Element;
|
|
227
|
+
declare function InteractionActionButton({ variant, onClick, disabled, children, }: {
|
|
228
|
+
variant?: 'primary' | 'outline';
|
|
229
|
+
onClick: () => void;
|
|
230
|
+
disabled?: boolean;
|
|
231
|
+
children: string;
|
|
232
|
+
}): react.JSX.Element;
|
|
233
|
+
interface QuestionOptionListProps {
|
|
234
|
+
/** Radio/checkbox group name — unique per field so selection is isolated. */
|
|
235
|
+
groupName: string;
|
|
236
|
+
/** Stable prefix for per-option input ids (label htmlFor pairing). */
|
|
237
|
+
idPrefix: string;
|
|
238
|
+
options: ChatSelectField['options'];
|
|
239
|
+
/** Checkbox (multi-select) vs radio (single). */
|
|
240
|
+
multi: boolean;
|
|
241
|
+
selectedValues: string[];
|
|
242
|
+
disabled: boolean;
|
|
243
|
+
onToggle: (value: string) => void;
|
|
244
|
+
}
|
|
245
|
+
/** The radio/checkbox option rows for a select field. Renders a fragment of
|
|
246
|
+
* option `<label>` rows so a card keeps its own wrapping layout and appends
|
|
247
|
+
* its own write-in input. */
|
|
248
|
+
declare function QuestionOptionList({ groupName, idPrefix, options, multi, selectedValues, disabled, onToggle, }: QuestionOptionListProps): react.JSX.Element;
|
|
249
|
+
interface InteractionQuestionCardProps {
|
|
250
|
+
interaction: ChatInteraction;
|
|
251
|
+
/** Viewer-vs-editor gate: false renders everything read-only. */
|
|
252
|
+
canWrite: boolean;
|
|
253
|
+
/** POST one resolution to the product's answer route (see
|
|
254
|
+
* `createInteractionAnswerSubmitter`). Never called for late answers. */
|
|
255
|
+
submitAnswer: SubmitInteractionAnswer;
|
|
256
|
+
/** Fired when this card resolves locally (answered, or discovered expired
|
|
257
|
+
* via a 410) so the stream/route state stays in sync. */
|
|
258
|
+
onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>) => void;
|
|
259
|
+
/** Delivers a late answer (the ask expired/was withdrawn) as a fresh chat
|
|
260
|
+
* turn. Return/resolve `false` when the send was rejected so the card stays
|
|
261
|
+
* retryable. Omit to hide the late-answer affordance entirely. */
|
|
262
|
+
onLateAnswer?: (message: string) => boolean | void | Promise<boolean | void>;
|
|
263
|
+
className?: string;
|
|
264
|
+
}
|
|
265
|
+
declare function InteractionQuestionCard({ interaction, canWrite, submitAnswer, onResolved, onLateAnswer, className, }: InteractionQuestionCardProps): react.JSX.Element;
|
|
266
|
+
|
|
267
|
+
interface InteractionPlanCardProps {
|
|
268
|
+
interaction: ChatInteraction;
|
|
269
|
+
/** Viewer-vs-editor gate: false renders everything read-only. */
|
|
270
|
+
canWrite: boolean;
|
|
271
|
+
/** POST one resolution to the product's answer route (see
|
|
272
|
+
* `createInteractionAnswerSubmitter`). */
|
|
273
|
+
submitAnswer: SubmitInteractionAnswer;
|
|
274
|
+
/** Fired when this card resolves locally (approved/rejected, or discovered
|
|
275
|
+
* expired via a 410) so the stream/route state stays in sync. */
|
|
276
|
+
onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>) => void;
|
|
277
|
+
/** Renders the plan body (markdown). Falls back to pre-wrapped plain text. */
|
|
278
|
+
renderMarkdown?: (markdown: string) => ReactNode;
|
|
279
|
+
className?: string;
|
|
280
|
+
}
|
|
281
|
+
declare function InteractionPlanCard({ interaction, canWrite, submitAnswer, onResolved, renderMarkdown, className, }: InteractionPlanCardProps): react.JSX.Element;
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* useChatInteractions — the interaction-state wiring every consumer of
|
|
285
|
+
* `ChatStreamCallbacks.onInteraction` re-implements: an id-keyed,
|
|
286
|
+
* insertion-ordered list with
|
|
287
|
+
*
|
|
288
|
+
* - forward-only status transitions (a replayed/stale `pending` never
|
|
289
|
+
* resurrects a resolved card),
|
|
290
|
+
* - pending-question content dedupe (a re-emitted duplicate ask never renders
|
|
291
|
+
* a second card),
|
|
292
|
+
* - cancel-event application (`interaction.cancel` → cancelled/expired),
|
|
293
|
+
* - local resolution marking (the card's `onResolved`),
|
|
294
|
+
* - reload restore from the answer route's GET list (sidecar registry is the
|
|
295
|
+
* source of truth after a reload),
|
|
296
|
+
* - turn-end settling (client mirror of the server's finalize pass: a turn
|
|
297
|
+
* that completed without a cancel was answered; a failed turn can make no
|
|
298
|
+
* such claim).
|
|
299
|
+
*
|
|
300
|
+
* The reducer functions are pure and exported for non-React consumers/tests;
|
|
301
|
+
* the hook is a thin `useState` shell over them.
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
/** Insert or update one interaction. A terminal existing entry wins over any
|
|
305
|
+
* incoming state for the same id; a new pending ask that duplicates another
|
|
306
|
+
* pending ask's content is dropped. Returns the same array when unchanged. */
|
|
307
|
+
declare function upsertChatInteraction(list: ChatInteraction[], interaction: ChatInteraction): ChatInteraction[];
|
|
308
|
+
/** Applies an `interaction.cancel` event: only a pending ask moves, to
|
|
309
|
+
* `expired` (reason:"timeout") or `cancelled`. */
|
|
310
|
+
declare function cancelChatInteraction(list: ChatInteraction[], cancel: InteractionCancelData): ChatInteraction[];
|
|
311
|
+
/** Marks one ask resolved locally (the card's `onResolved`). Forward-only. */
|
|
312
|
+
declare function resolveChatInteraction(list: ChatInteraction[], id: string, status: Exclude<ChatInteractionStatus, 'pending'>): ChatInteraction[];
|
|
313
|
+
/** Settles every still-pending ask when the turn ends: `answered` for a turn
|
|
314
|
+
* that completed cleanly, `expired` for one that failed. */
|
|
315
|
+
declare function terminalizePendingChatInteractions(list: ChatInteraction[], status: Extract<ChatInteractionStatus, 'answered' | 'expired'>): ChatInteraction[];
|
|
316
|
+
/** Reload restore from the answer route's GET list: every listed ask is
|
|
317
|
+
* outstanding (upserted pending), and every previously-pending ask the sidecar
|
|
318
|
+
* no longer lists was resolved while we were away (settled as answered). */
|
|
319
|
+
declare function restoreChatInteractions(list: ChatInteraction[], outstanding: InteractionRequestWire[]): ChatInteraction[];
|
|
320
|
+
interface UseChatInteractionsResult {
|
|
321
|
+
/** All known interactions, insertion-ordered. */
|
|
322
|
+
interactions: ChatInteraction[];
|
|
323
|
+
/** The asks currently blocking the run (waiting on the user). */
|
|
324
|
+
pending: ChatInteraction[];
|
|
325
|
+
/** Wire to `ChatStreamCallbacks.onInteraction` (and persisted-part replay). */
|
|
326
|
+
upsert: (interaction: ChatInteraction) => void;
|
|
327
|
+
/** Wire to `interaction.cancel` events. */
|
|
328
|
+
applyCancel: (cancel: InteractionCancelData) => void;
|
|
329
|
+
/** Wire to the cards' `onResolved`. */
|
|
330
|
+
markResolved: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>) => void;
|
|
331
|
+
/** Wire to the answer route's GET list after a reload/reconnect. */
|
|
332
|
+
restore: (outstanding: InteractionRequestWire[]) => void;
|
|
333
|
+
/** Settle still-pending asks when the turn ends. */
|
|
334
|
+
terminalizePending: (status: Extract<ChatInteractionStatus, 'answered' | 'expired'>) => void;
|
|
335
|
+
/** Drop everything (thread switch). */
|
|
336
|
+
reset: () => void;
|
|
337
|
+
}
|
|
338
|
+
declare function useChatInteractions(): UseChatInteractionsResult;
|
|
339
|
+
|
|
230
340
|
/**
|
|
231
341
|
* Provider brand marks — real logo path data (simple-icons / SVG Logos, both
|
|
232
342
|
* CC0) inlined so the picker shows actual provider identity instead of
|
|
@@ -656,4 +766,4 @@ declare function useThinkingSeconds(active: boolean): number;
|
|
|
656
766
|
*/
|
|
657
767
|
declare function ChatMessages({ messages, models, renderMarkdown, renderExtras, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, }: ChatMessagesProps): react.JSX.Element;
|
|
658
768
|
|
|
659
|
-
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, AgentSessionControls, type AgentSessionControlsProps, CatalogModel, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps,
|
|
769
|
+
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, AgentSessionControls, type AgentSessionControlsProps, CatalogModel, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps, ChatInteraction, ChatInteractionField, ChatInteractionStatus, type ChatMessageMetrics, type ChatMessageSegment, ChatMessages, type ChatMessagesProps, ChatSelectField, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ComposerFile, type ConsumeChatStreamResult, DEFAULT_EFFORT_LEVELS, type EffortLevel, EffortPicker, type EffortPickerProps, type FieldValues, FlowWaterfall, type FlowWaterfallProps, INTERACTION_SUBMIT_TIMEOUT_MESSAGE, INTERACTION_SUBMIT_TIMEOUT_MS, InteractionActionButton, type InteractionAnswerSubmission, type InteractionAnswerSubmitterOptions, InteractionBadge, type InteractionBadgeVariant, InteractionCancelData, InteractionPlanCard, type InteractionPlanCardProps, InteractionQuestionCard, type InteractionQuestionCardProps, InteractionRequestWire, type InteractionSubmitResult, MissionActivityLane, type MissionActivityLaneProps, ModelPicker, type ModelPickerProps, type ProposalApprovalHandlers, ProviderLogo, type ProviderLogoProps, QuestionOptionList, type QuestionOptionListProps, RunDrillIn, type RunDrillInProps, SeatPaywall, type SeatPaywallProps, type SmoothRevealOptions, type StreamChatOptions, type SubmitInteractionAnswer, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, type UseChatInteractionsResult, type WaterfallRow, activityTone, buildAnswerData, cancelChatInteraction, consumeChatStream, createInteractionAnswerSubmitter, dispatchChatStreamLine, fieldAnswer, formatActivityCost, formatActivityDuration, formatModelCost, formatTokensPerSecond, hasSecretField, interactionStatusLabels, interactionTerminalNotes, isLateAnswerableStatus, lateAnswerMessage, mergeActivityPages, nextRevealCount, pendingApprovalOf, resolveChatInteraction, responseErrorMessage, restoreChatInteractions, streamChatTurn, terminalizePendingChatInteractions, upsertChatInteraction, useChatInteractions, usePending, usePopover, useSmoothText, useThinkingSeconds, waterfallLayout };
|
package/dist/web-react/index.js
CHANGED
|
@@ -7,54 +7,78 @@ import {
|
|
|
7
7
|
DEFAULT_EFFORT_LEVELS,
|
|
8
8
|
EffortPicker,
|
|
9
9
|
FlowWaterfall,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
|
|
11
|
+
INTERACTION_SUBMIT_TIMEOUT_MS,
|
|
12
|
+
InteractionActionButton,
|
|
13
|
+
InteractionBadge,
|
|
14
|
+
InteractionPlanCard,
|
|
15
|
+
InteractionQuestionCard,
|
|
13
16
|
MissionActivityLane,
|
|
14
17
|
ModelPicker,
|
|
15
18
|
ProviderLogo,
|
|
19
|
+
QuestionOptionList,
|
|
16
20
|
RunDrillIn,
|
|
17
21
|
SeatPaywall,
|
|
18
22
|
activityTone,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
composerAnswerData,
|
|
22
|
-
composerAnswerDeliveries,
|
|
23
|
+
buildAnswerData,
|
|
24
|
+
cancelChatInteraction,
|
|
23
25
|
consumeChatStream,
|
|
24
|
-
|
|
26
|
+
createInteractionAnswerSubmitter,
|
|
25
27
|
dispatchChatStreamLine,
|
|
26
|
-
|
|
28
|
+
fieldAnswer,
|
|
27
29
|
formatActivityCost,
|
|
28
30
|
formatActivityDuration,
|
|
29
31
|
formatModelCost,
|
|
30
32
|
formatTokensPerSecond,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
isTerminalInteractionStatus,
|
|
33
|
+
hasSecretField,
|
|
34
|
+
interactionStatusLabels,
|
|
35
|
+
interactionTerminalNotes,
|
|
36
|
+
isLateAnswerableStatus,
|
|
37
|
+
lateAnswerMessage,
|
|
37
38
|
mergeActivityPages,
|
|
38
39
|
nextRevealCount,
|
|
39
|
-
noticePart,
|
|
40
|
-
noticePartKey,
|
|
41
|
-
parseInteractionCancel,
|
|
42
|
-
parseInteractionRequest,
|
|
43
40
|
pendingApprovalOf,
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
resolveChatInteraction,
|
|
42
|
+
responseErrorMessage,
|
|
43
|
+
restoreChatInteractions,
|
|
46
44
|
streamChatTurn,
|
|
45
|
+
terminalizePendingChatInteractions,
|
|
46
|
+
upsertChatInteraction,
|
|
47
|
+
useChatInteractions,
|
|
47
48
|
usePending,
|
|
48
49
|
usePopover,
|
|
49
50
|
useSmoothText,
|
|
50
51
|
useThinkingSeconds,
|
|
51
52
|
waterfallLayout
|
|
52
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-PEPXQTJ3.js";
|
|
53
54
|
import {
|
|
54
55
|
tabTerminalConnectionId,
|
|
55
56
|
useSandboxTerminalConnection
|
|
56
57
|
} from "../chunk-65P3HJY3.js";
|
|
57
58
|
import "../chunk-2QI7XV2T.js";
|
|
59
|
+
import {
|
|
60
|
+
INTERACTION_CANCEL_EVENT,
|
|
61
|
+
INTERACTION_EVENT,
|
|
62
|
+
INTERACTION_RESOLVED_EVENT,
|
|
63
|
+
canTransitionInteractionStatus,
|
|
64
|
+
cancelStatusFor,
|
|
65
|
+
composerAnswerData,
|
|
66
|
+
composerAnswerDeliveries,
|
|
67
|
+
dedupeQuestionInteractionsByContent,
|
|
68
|
+
fieldAcceptsFreeText,
|
|
69
|
+
interactionFromWireRequest,
|
|
70
|
+
interactionPartKey,
|
|
71
|
+
interactionToPersistedPart,
|
|
72
|
+
isRenderableInteractionKind,
|
|
73
|
+
isSafeInteractionFieldKey,
|
|
74
|
+
isTerminalInteractionStatus,
|
|
75
|
+
noticePart,
|
|
76
|
+
noticePartKey,
|
|
77
|
+
parseInteractionCancel,
|
|
78
|
+
parseInteractionRequest,
|
|
79
|
+
persistedPartToInteraction,
|
|
80
|
+
questionInteractionContentSignature
|
|
81
|
+
} from "../chunk-4TXDD6P2.js";
|
|
58
82
|
import "../chunk-E7QYOOON.js";
|
|
59
83
|
export {
|
|
60
84
|
AgentActivityPanel,
|
|
@@ -68,30 +92,46 @@ export {
|
|
|
68
92
|
INTERACTION_CANCEL_EVENT,
|
|
69
93
|
INTERACTION_EVENT,
|
|
70
94
|
INTERACTION_RESOLVED_EVENT,
|
|
95
|
+
INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
|
|
96
|
+
INTERACTION_SUBMIT_TIMEOUT_MS,
|
|
97
|
+
InteractionActionButton,
|
|
98
|
+
InteractionBadge,
|
|
99
|
+
InteractionPlanCard,
|
|
100
|
+
InteractionQuestionCard,
|
|
71
101
|
MissionActivityLane,
|
|
72
102
|
ModelPicker,
|
|
73
103
|
ProviderLogo,
|
|
104
|
+
QuestionOptionList,
|
|
74
105
|
RunDrillIn,
|
|
75
106
|
SeatPaywall,
|
|
76
107
|
activityTone,
|
|
108
|
+
buildAnswerData,
|
|
77
109
|
canTransitionInteractionStatus,
|
|
110
|
+
cancelChatInteraction,
|
|
78
111
|
cancelStatusFor,
|
|
79
112
|
composerAnswerData,
|
|
80
113
|
composerAnswerDeliveries,
|
|
81
114
|
consumeChatStream,
|
|
115
|
+
createInteractionAnswerSubmitter,
|
|
82
116
|
dedupeQuestionInteractionsByContent,
|
|
83
117
|
dispatchChatStreamLine,
|
|
84
118
|
fieldAcceptsFreeText,
|
|
119
|
+
fieldAnswer,
|
|
85
120
|
formatActivityCost,
|
|
86
121
|
formatActivityDuration,
|
|
87
122
|
formatModelCost,
|
|
88
123
|
formatTokensPerSecond,
|
|
124
|
+
hasSecretField,
|
|
89
125
|
interactionFromWireRequest,
|
|
90
126
|
interactionPartKey,
|
|
127
|
+
interactionStatusLabels,
|
|
128
|
+
interactionTerminalNotes,
|
|
91
129
|
interactionToPersistedPart,
|
|
130
|
+
isLateAnswerableStatus,
|
|
92
131
|
isRenderableInteractionKind,
|
|
93
132
|
isSafeInteractionFieldKey,
|
|
94
133
|
isTerminalInteractionStatus,
|
|
134
|
+
lateAnswerMessage,
|
|
95
135
|
mergeActivityPages,
|
|
96
136
|
nextRevealCount,
|
|
97
137
|
noticePart,
|
|
@@ -101,8 +141,14 @@ export {
|
|
|
101
141
|
pendingApprovalOf,
|
|
102
142
|
persistedPartToInteraction,
|
|
103
143
|
questionInteractionContentSignature,
|
|
144
|
+
resolveChatInteraction,
|
|
145
|
+
responseErrorMessage,
|
|
146
|
+
restoreChatInteractions,
|
|
104
147
|
streamChatTurn,
|
|
105
148
|
tabTerminalConnectionId,
|
|
149
|
+
terminalizePendingChatInteractions,
|
|
150
|
+
upsertChatInteraction,
|
|
151
|
+
useChatInteractions,
|
|
106
152
|
usePending,
|
|
107
153
|
usePopover,
|
|
108
154
|
useSandboxTerminalConnection,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-app",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.25",
|
|
4
4
|
"packageManager": "pnpm@10.33.4",
|
|
5
5
|
"description": "Application-shell framework for Tangle agent products: a bounded tool loop, the structured agent→app tool side channel, integration-hub client, per-workspace billing, and crypto — composed over the Tangle agent substrate through typed seams.",
|
|
6
6
|
"keywords": [
|
|
@@ -53,6 +53,11 @@
|
|
|
53
53
|
"import": "./dist/platform/index.js",
|
|
54
54
|
"default": "./dist/platform/index.js"
|
|
55
55
|
},
|
|
56
|
+
"./app-auth": {
|
|
57
|
+
"types": "./dist/app-auth/index.d.ts",
|
|
58
|
+
"import": "./dist/app-auth/index.js",
|
|
59
|
+
"default": "./dist/app-auth/index.js"
|
|
60
|
+
},
|
|
56
61
|
"./runtime": {
|
|
57
62
|
"types": "./dist/runtime/index.d.ts",
|
|
58
63
|
"import": "./dist/runtime/index.js",
|
|
@@ -133,6 +138,11 @@
|
|
|
133
138
|
"import": "./dist/billing/index.js",
|
|
134
139
|
"default": "./dist/billing/index.js"
|
|
135
140
|
},
|
|
141
|
+
"./chat-store": {
|
|
142
|
+
"types": "./dist/chat-store/index.d.ts",
|
|
143
|
+
"import": "./dist/chat-store/index.js",
|
|
144
|
+
"default": "./dist/chat-store/index.js"
|
|
145
|
+
},
|
|
136
146
|
"./crypto": {
|
|
137
147
|
"types": "./dist/crypto/index.d.ts",
|
|
138
148
|
"import": "./dist/crypto/index.js",
|
|
@@ -148,6 +158,11 @@
|
|
|
148
158
|
"import": "./dist/integrations/index.js",
|
|
149
159
|
"default": "./dist/integrations/index.js"
|
|
150
160
|
},
|
|
161
|
+
"./interactions": {
|
|
162
|
+
"types": "./dist/interactions/index.d.ts",
|
|
163
|
+
"import": "./dist/interactions/index.js",
|
|
164
|
+
"default": "./dist/interactions/index.js"
|
|
165
|
+
},
|
|
151
166
|
"./missions": {
|
|
152
167
|
"types": "./dist/missions/index.d.ts",
|
|
153
168
|
"import": "./dist/missions/index.js",
|
|
@@ -358,7 +373,7 @@
|
|
|
358
373
|
"@tangle-network/agent-knowledge": "^1.7.0",
|
|
359
374
|
"@tangle-network/agent-runtime": "^0.79.3",
|
|
360
375
|
"@tangle-network/brand": "^1.0.0",
|
|
361
|
-
"@tangle-network/sandbox": "^0.
|
|
376
|
+
"@tangle-network/sandbox": "^0.10.5",
|
|
362
377
|
"@tangle-network/sandbox-ui": "^0.72.0",
|
|
363
378
|
"@tangle-network/ui": "^11.0.0",
|
|
364
379
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -396,6 +411,7 @@
|
|
|
396
411
|
"@tangle-network/sandbox": ">=0.9.7",
|
|
397
412
|
"@tangle-network/sandbox-ui": ">=0.72.0",
|
|
398
413
|
"@xyflow/react": ">=12.0.0",
|
|
414
|
+
"better-auth": ">=1.6.16",
|
|
399
415
|
"drizzle-orm": ">=0.36",
|
|
400
416
|
"konva": ">=9",
|
|
401
417
|
"lucide-react": ">=1",
|
|
@@ -408,6 +424,9 @@
|
|
|
408
424
|
"@huggingface/transformers": {
|
|
409
425
|
"optional": true
|
|
410
426
|
},
|
|
427
|
+
"better-auth": {
|
|
428
|
+
"optional": true
|
|
429
|
+
},
|
|
411
430
|
"@tangle-network/agent-knowledge": {
|
|
412
431
|
"optional": true
|
|
413
432
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/preset-cloudflare/index.ts"],"sourcesContent":["/**\n * `@tangle-network/agent-app/preset-cloudflare` — the batteries-included default\n * stack.\n *\n * Every fleet agent runs the SAME backend: Cloudflare D1 (SQLite) through\n * Drizzle for state, a KV namespace as the artifact vault, AES-GCM field crypto\n * for PII, and per-workspace budget-capped model keys. The other agent-app\n * modules are pure SEAMS — `./tools` needs an `AppToolHandlers`, `./knowledge`\n * needs a `KnowledgeStateAccessor`, `./billing` needs a `WorkspaceKeyStore` +\n * `KeyCrypto`. This module is the ONE implementation of those seams against the\n * house stack, so a consumer that runs D1 + KV stands the whole shell up with\n * config + bindings and ZERO handler code.\n *\n * Layering:\n * - Drizzle is a PEER (the consumer installs `drizzle-orm`, never bundled). The\n * schema is therefore expressed two ways that need no import here: the plain\n * DDL ({@link PRESET_MIGRATION_SQL}) a consumer runs to create the tables, and\n * a {@link createPresetDrizzleSchema} factory that takes the consumer's\n * `drizzle-orm/sqlite-core` builder module and returns the typed tables. The\n * column names in {@link PRESET_TABLES} are the contract the handlers,\n * accessor, and DDL all agree on.\n * - D1 + KV are STRUCTURAL: {@link D1Like} (Cloudflare `D1Database` satisfies it)\n * and `KvLike` from `../web` (Cloudflare `KVNamespace` satisfies it). No\n * `@cloudflare/workers-types` dependency.\n * - Crypto/billing reuse `../crypto` + `../billing` exactly — this only wires\n * them to the D1 key table.\n */\n\nimport { createFieldCrypto } from '../crypto/index'\nimport {\n createWorkspaceKeyManager,\n type KeyCrypto,\n type KeyProvisioner,\n type WorkspaceKeyManager,\n type WorkspaceKeyRecord,\n type WorkspaceKeyStore,\n} from '../billing/index'\nimport type { KnowledgeStateAccessor } from '../knowledge/index'\nimport type {\n AddCitationArgs,\n AddCitationResult,\n AppToolContext,\n AppToolHandlers,\n RenderUiArgs,\n RenderUiResult,\n ScheduleFollowupArgs,\n ScheduleFollowupResult,\n SubmitProposalArgs,\n SubmitProposalResult,\n} from '../tools/index'\nimport type { KvLike } from '../web/index'\n\n// ---------------------------------------------------------------------------\n// D1 structural seam\n//\n// The minimal surface of Cloudflare's `D1Database` the handlers + accessor use.\n// `D1Database` satisfies it structurally, so the consumer passes `env.DB`\n// directly and tests pass an in-memory fake. We keep it to the\n// prepare/bind/first/run/all shape D1 already exposes — no Drizzle here, so the\n// default handlers run on a fresh Worker with only the D1 binding.\n// ---------------------------------------------------------------------------\n\n/** A prepared, bound D1 statement. */\nexport interface D1PreparedLike {\n bind(...values: unknown[]): D1PreparedLike\n first<T = Record<string, unknown>>(colName?: string): Promise<T | null>\n run(): Promise<unknown>\n all<T = Record<string, unknown>>(): Promise<{ results: T[] }>\n}\n\n/** The D1 surface the preset needs. Cloudflare `D1Database` satisfies it. */\nexport interface D1Like {\n prepare(query: string): D1PreparedLike\n}\n\n// ---------------------------------------------------------------------------\n// Default schema\n//\n// The four tables the default handlers + accessor read/write. Column names are\n// the single source of truth shared by the DDL, the Drizzle factory, the\n// handlers, and the accessor. Every table is workspace-scoped on `workspace_id`\n// (the accessor's default `where` column) so the knowledge `count` rule and the\n// tool writes agree without per-consumer wiring.\n// ---------------------------------------------------------------------------\n\n/** The preset table + column names — the contract the DDL, Drizzle schema,\n * handlers, and accessor share. Exposed so a consumer can reference a column\n * without a string literal. */\nexport const PRESET_TABLES = {\n proposals: {\n name: 'proposals',\n columns: {\n id: 'id',\n workspaceId: 'workspace_id',\n threadId: 'thread_id',\n type: 'type',\n title: 'title',\n description: 'description',\n status: 'status',\n createdBy: 'created_by',\n createdAt: 'created_at',\n },\n },\n threads: {\n name: 'threads',\n columns: {\n id: 'id',\n workspaceId: 'workspace_id',\n title: 'title',\n createdAt: 'created_at',\n },\n },\n knowledge: {\n name: 'knowledge',\n columns: {\n id: 'id',\n workspaceId: 'workspace_id',\n path: 'path',\n kind: 'kind',\n label: 'label',\n content: 'content',\n createdAt: 'created_at',\n },\n },\n deadlines: {\n name: 'deadlines',\n columns: {\n id: 'id',\n workspaceId: 'workspace_id',\n threadId: 'thread_id',\n title: 'title',\n dueDate: 'due_date',\n priority: 'priority',\n status: 'status',\n createdAt: 'created_at',\n },\n },\n workspaceKeys: {\n name: 'workspace_keys',\n columns: {\n id: 'id',\n workspaceId: 'workspace_id',\n keyId: 'key_id',\n keyEncrypted: 'key_encrypted',\n budgetUsd: 'budget_usd',\n expiresAt: 'expires_at',\n revokedAt: 'revoked_at',\n createdAt: 'created_at',\n },\n },\n} as const\n\n/**\n * Plain DDL for the preset schema — run by a consumer to create the tables with\n * ZERO drizzle (`for (const sql of PRESET_MIGRATION_SQL) await db.prepare(sql).run()`,\n * or paste into a `.sql` migration). One statement per table so D1's\n * single-statement `prepare` accepts each. Matches {@link PRESET_TABLES} exactly.\n */\nexport const PRESET_MIGRATION_SQL: readonly string[] = [\n `CREATE TABLE IF NOT EXISTS threads (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n title TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS proposals (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n thread_id TEXT,\n type TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n created_by TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS knowledge (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n path TEXT NOT NULL,\n kind TEXT NOT NULL,\n label TEXT,\n content TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS deadlines (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n thread_id TEXT,\n title TEXT NOT NULL,\n due_date TEXT NOT NULL,\n priority TEXT,\n status TEXT NOT NULL DEFAULT 'scheduled',\n created_at INTEGER NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS workspace_keys (\n id TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL,\n key_id TEXT NOT NULL,\n key_encrypted TEXT NOT NULL,\n budget_usd REAL NOT NULL,\n expires_at INTEGER NOT NULL,\n revoked_at INTEGER,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS idx_proposals_ws ON proposals (workspace_id, status)`,\n `CREATE INDEX IF NOT EXISTS idx_deadlines_ws ON deadlines (workspace_id, status)`,\n `CREATE INDEX IF NOT EXISTS idx_knowledge_ws ON knowledge (workspace_id)`,\n `CREATE INDEX IF NOT EXISTS idx_workspace_keys_ws ON workspace_keys (workspace_id, revoked_at)`,\n]\n\n/** A chainable column builder — every modifier returns the builder so calls\n * like `.notNull().default('pending')` typecheck. The concrete drizzle builders\n * satisfy this structurally. */\nexport interface DrizzleColumnLike {\n primaryKey: () => DrizzleColumnLike\n notNull: () => DrizzleColumnLike\n default: (v: unknown) => DrizzleColumnLike\n}\n\n/** The shape of a `drizzle-orm/sqlite-core` module — the few builders the\n * preset schema uses. The consumer passes the real module; agent-app never\n * imports it (it stays a peer). */\nexport interface DrizzleSqliteCoreLike {\n sqliteTable: (name: string, columns: Record<string, DrizzleColumnLike>) => unknown\n text: (name?: string) => DrizzleColumnLike\n integer: (name?: string, config?: unknown) => DrizzleColumnLike\n real: (name?: string) => DrizzleColumnLike\n}\n\n/**\n * Build the typed Drizzle schema for the preset, given the consumer's\n * `drizzle-orm/sqlite-core` module. Returns one table object per\n * {@link PRESET_TABLES} entry — pass to `drizzle(db, { schema })` for typed\n * queries, or to drizzle-kit for migration generation. agent-app never imports\n * drizzle; the builder module is the seam.\n *\n * ```ts\n * import * as d from 'drizzle-orm/sqlite-core'\n * const schema = createPresetDrizzleSchema(d)\n * ```\n */\nexport function createPresetDrizzleSchema(d: DrizzleSqliteCoreLike) {\n const { sqliteTable, text, integer, real } = d\n const C = PRESET_TABLES\n return {\n threads: sqliteTable(C.threads.name, {\n id: text(C.threads.columns.id).primaryKey(),\n workspaceId: text(C.threads.columns.workspaceId).notNull(),\n title: text(C.threads.columns.title),\n createdAt: integer(C.threads.columns.createdAt).notNull(),\n }),\n proposals: sqliteTable(C.proposals.name, {\n id: text(C.proposals.columns.id).primaryKey(),\n workspaceId: text(C.proposals.columns.workspaceId).notNull(),\n threadId: text(C.proposals.columns.threadId),\n type: text(C.proposals.columns.type).notNull(),\n title: text(C.proposals.columns.title).notNull(),\n description: text(C.proposals.columns.description),\n status: text(C.proposals.columns.status).notNull().default('pending'),\n createdBy: text(C.proposals.columns.createdBy),\n createdAt: integer(C.proposals.columns.createdAt).notNull(),\n }),\n knowledge: sqliteTable(C.knowledge.name, {\n id: text(C.knowledge.columns.id).primaryKey(),\n workspaceId: text(C.knowledge.columns.workspaceId).notNull(),\n path: text(C.knowledge.columns.path).notNull(),\n kind: text(C.knowledge.columns.kind).notNull(),\n label: text(C.knowledge.columns.label),\n content: text(C.knowledge.columns.content),\n createdAt: integer(C.knowledge.columns.createdAt).notNull(),\n }),\n deadlines: sqliteTable(C.deadlines.name, {\n id: text(C.deadlines.columns.id).primaryKey(),\n workspaceId: text(C.deadlines.columns.workspaceId).notNull(),\n threadId: text(C.deadlines.columns.threadId),\n title: text(C.deadlines.columns.title).notNull(),\n dueDate: text(C.deadlines.columns.dueDate).notNull(),\n priority: text(C.deadlines.columns.priority),\n status: text(C.deadlines.columns.status).notNull().default('scheduled'),\n createdAt: integer(C.deadlines.columns.createdAt).notNull(),\n }),\n workspaceKeys: sqliteTable(C.workspaceKeys.name, {\n id: text(C.workspaceKeys.columns.id).primaryKey(),\n workspaceId: text(C.workspaceKeys.columns.workspaceId).notNull(),\n keyId: text(C.workspaceKeys.columns.keyId).notNull(),\n keyEncrypted: text(C.workspaceKeys.columns.keyEncrypted).notNull(),\n budgetUsd: real(C.workspaceKeys.columns.budgetUsd).notNull(),\n expiresAt: integer(C.workspaceKeys.columns.expiresAt).notNull(),\n revokedAt: integer(C.workspaceKeys.columns.revokedAt),\n createdAt: integer(C.workspaceKeys.columns.createdAt).notNull(),\n }),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Default AppToolHandlers over D1 + KV\n// ---------------------------------------------------------------------------\n\n/** The KV-backed vault. `KvLike` (from `../web`) is the structural KV contract;\n * Cloudflare `KVNamespace` satisfies it. Artifacts are stored under their path. */\nexport type VaultKv = KvLike\n\nexport interface PresetToolHandlerOptions {\n /** The D1 database (Cloudflare `D1Database` satisfies {@link D1Like}). */\n db: D1Like\n /** The KV namespace used as the artifact vault. */\n vault: VaultKv\n /** Id generator. Default `crypto.randomUUID`. Injectable for deterministic tests. */\n newId?: () => string\n /** Clock (epoch ms). Default `Date.now`. Injectable for deterministic tests. */\n now?: () => number\n /** Vault path prefix for `render_ui` artifacts. Default `'ui'`. */\n uiPathPrefix?: string\n /** Vault path prefix for `add_citation` artifacts. Default `'citations'`. */\n citationPathPrefix?: string\n}\n\nfunction slug(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64) || 'item'\n}\n\n/**\n * The default {@link AppToolHandlers} for the house stack:\n * - `submit_proposal` → insert a `proposals` row (`status='pending'`), deduped\n * on (workspace, title) so a retried turn doesn't double-queue.\n * - `schedule_followup` → insert a `deadlines` row, deduped on (workspace, title, due_date).\n * - `render_ui` → write the schema JSON as a `ui/<thread>/<slug>.json`\n * vault artifact AND a `knowledge` row pointing at it.\n * - `add_citation` → write the quote as a `citations/<slug>.json` artifact AND\n * a `knowledge` row.\n *\n * Returns the EXACT persisted content from `render_ui` (per the seam contract) so\n * a completion oracle sees real bytes. Pure seam wiring: a consumer that runs\n * D1 + KV gets all four tools with no handler code.\n */\nexport function createPresetToolHandlers(opts: PresetToolHandlerOptions): AppToolHandlers {\n const { db, vault } = opts\n const newId = opts.newId ?? (() => crypto.randomUUID())\n const now = opts.now ?? (() => Date.now())\n const uiPrefix = opts.uiPathPrefix ?? 'ui'\n const citationPrefix = opts.citationPathPrefix ?? 'citations'\n const P = PRESET_TABLES.proposals\n const D = PRESET_TABLES.deadlines\n const K = PRESET_TABLES.knowledge\n\n async function persistArtifact(path: string, body: string): Promise<void> {\n await vault.put(path, body)\n }\n\n async function insertKnowledge(workspaceId: string, path: string, kind: string, label: string | null, content: string): Promise<void> {\n await db\n .prepare(\n `INSERT INTO ${K.name} (${K.columns.id}, ${K.columns.workspaceId}, ${K.columns.path}, ${K.columns.kind}, ${K.columns.label}, ${K.columns.content}, ${K.columns.createdAt}) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .bind(newId(), workspaceId, path, kind, label, content, now())\n .run()\n }\n\n return {\n async submitProposal(args: SubmitProposalArgs, ctx: AppToolContext): Promise<SubmitProposalResult> {\n const existing = await db\n .prepare(`SELECT ${P.columns.id} AS id FROM ${P.name} WHERE ${P.columns.workspaceId} = ? AND ${P.columns.title} = ? LIMIT 1`)\n .bind(ctx.workspaceId, args.title)\n .first<{ id: string }>()\n if (existing) return { proposalId: existing.id, deduped: true }\n\n const id = newId()\n await db\n .prepare(\n `INSERT INTO ${P.name} (${P.columns.id}, ${P.columns.workspaceId}, ${P.columns.threadId}, ${P.columns.type}, ${P.columns.title}, ${P.columns.description}, ${P.columns.status}, ${P.columns.createdBy}, ${P.columns.createdAt}) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, ?)`,\n )\n .bind(id, ctx.workspaceId, ctx.threadId, args.type, args.title, args.description ?? null, ctx.userId, now())\n .run()\n return { proposalId: id, deduped: false }\n },\n\n async scheduleFollowup(args: ScheduleFollowupArgs, ctx: AppToolContext): Promise<ScheduleFollowupResult> {\n const existing = await db\n .prepare(\n `SELECT ${D.columns.id} AS id, ${D.columns.dueDate} AS dueDate FROM ${D.name} WHERE ${D.columns.workspaceId} = ? AND ${D.columns.title} = ? AND ${D.columns.dueDate} = ? LIMIT 1`,\n )\n .bind(ctx.workspaceId, args.title, args.dueDate)\n .first<{ id: string; dueDate: string }>()\n if (existing) return { id: existing.id, dueDate: existing.dueDate, deduped: true }\n\n const id = newId()\n await db\n .prepare(\n `INSERT INTO ${D.name} (${D.columns.id}, ${D.columns.workspaceId}, ${D.columns.threadId}, ${D.columns.title}, ${D.columns.dueDate}, ${D.columns.priority}, ${D.columns.status}, ${D.columns.createdAt}) VALUES (?, ?, ?, ?, ?, ?, 'scheduled', ?)`,\n )\n .bind(id, ctx.workspaceId, ctx.threadId, args.title, args.dueDate, args.priority ?? null, now())\n .run()\n return { id, dueDate: args.dueDate, deduped: false }\n },\n\n async renderUi(args: RenderUiArgs, ctx: AppToolContext): Promise<RenderUiResult> {\n const content = JSON.stringify(args.schema)\n const path = `${uiPrefix}/${ctx.threadId ?? 'global'}/${slug(args.title)}.json`\n await persistArtifact(path, content)\n await insertKnowledge(ctx.workspaceId, path, 'ui', args.title, content)\n return { path, content }\n },\n\n async addCitation(args: AddCitationArgs, ctx: AppToolContext): Promise<AddCitationResult> {\n const citationId = newId()\n const path = `${citationPrefix}/${slug(args.label ?? args.path)}-${citationId.slice(0, 8)}.json`\n const body = JSON.stringify({ sourcePath: args.path, quote: args.quote, label: args.label ?? null })\n await persistArtifact(path, body)\n await insertKnowledge(ctx.workspaceId, path, 'citation', args.label ?? null, body)\n return { citationId, path }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// D1-backed KnowledgeStateAccessor\n// ---------------------------------------------------------------------------\n\nexport interface PresetKnowledgeAccessorOptions {\n db: D1Like\n /** The active workspace — every `count` is scoped to it. */\n workspaceId: string\n /** Workspace config the `satisfiedBy: { config }` rules read. A resolved\n * object (dot-path lookup), or a function the accessor calls per path. */\n config: Record<string, unknown> | ((path: string) => unknown)\n /** The default workspace fk column a `count` rule scopes on when its rule\n * omits `where`. Default `'workspace_id'` (the preset schema convention). */\n defaultWhereColumn?: string\n}\n\nfunction readDotPath(obj: Record<string, unknown>, path: string): unknown {\n let cur: unknown = obj\n for (const part of path.split('.')) {\n if (cur == null || typeof cur !== 'object') return undefined\n cur = (cur as Record<string, unknown>)[part]\n }\n return cur\n}\n\n/**\n * The {@link KnowledgeStateAccessor} over the preset D1 schema — the seam that\n * lets the declarative `satisfiedBy` rules resolve with ZERO consumer code:\n * - `config(path)` reads the supplied workspace config by dot-path.\n * - `count({ table, where, statusIn })` runs `SELECT count(*)` scoped to the\n * active workspace (the rule's `where` column, default `workspace_id`),\n * optionally filtered to `statusIn` via a parameterized `IN (...)`.\n *\n * Identifiers (table/column) are validated against a safe pattern before\n * interpolation — they originate from the product's own config, never model\n * input, but we fail loud rather than build a malformed/injectable query.\n */\nexport function createD1KnowledgeStateAccessor(opts: PresetKnowledgeAccessorOptions): KnowledgeStateAccessor {\n const { db, workspaceId } = opts\n const defaultWhere = opts.defaultWhereColumn ?? 'workspace_id'\n const configFn = typeof opts.config === 'function' ? opts.config : (path: string) => readDotPath(opts.config as Record<string, unknown>, path)\n\n const isIdentifier = (s: string) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s)\n\n return {\n config: configFn,\n async count(query) {\n if (!isIdentifier(query.table)) throw new Error(`unsafe table identifier: ${query.table}`)\n const whereCol = query.where ?? defaultWhere\n if (!isIdentifier(whereCol)) throw new Error(`unsafe where identifier: ${whereCol}`)\n\n let sql = `SELECT count(*) AS n FROM ${query.table} WHERE ${whereCol} = ?`\n const binds: unknown[] = [workspaceId]\n if (query.statusIn && query.statusIn.length > 0) {\n sql += ` AND status IN (${query.statusIn.map(() => '?').join(', ')})`\n binds.push(...query.statusIn)\n }\n const row = await db.prepare(sql).bind(...binds).first<{ n: number }>()\n return row?.n ?? 0\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Crypto + per-workspace key wiring\n// ---------------------------------------------------------------------------\n\n/** Build the {@link KeyCrypto} the billing key store uses — AES-256-GCM field\n * crypto bound to the product's 64-char-hex `ENCRYPTION_KEY` (or a resolver).\n * This is the concrete impl behind the `../billing` `KeyCrypto` seam. */\nexport function createPresetFieldCrypto(key: string | (() => string)): KeyCrypto {\n return createFieldCrypto(key)\n}\n\n/**\n * The {@link WorkspaceKeyStore} over the preset `workspace_keys` table — the\n * persistence seam the per-workspace key manager needs. \"Active\" = a row with a\n * null `revoked_at`. Pure D1 wiring; no key minting (that's the provisioner).\n */\nexport function createPresetWorkspaceKeyStore(db: D1Like): WorkspaceKeyStore {\n const W = PRESET_TABLES.workspaceKeys\n return {\n async getActive(workspaceId: string): Promise<WorkspaceKeyRecord | null> {\n const row = await db\n .prepare(\n `SELECT ${W.columns.id} AS id, ${W.columns.keyId} AS keyId, ${W.columns.keyEncrypted} AS keyEncrypted, ${W.columns.budgetUsd} AS budgetUsd, ${W.columns.expiresAt} AS expiresAt FROM ${W.name} WHERE ${W.columns.workspaceId} = ? AND ${W.columns.revokedAt} IS NULL ORDER BY ${W.columns.createdAt} DESC LIMIT 1`,\n )\n .bind(workspaceId)\n .first<{ id: string; keyId: string; keyEncrypted: string; budgetUsd: number; expiresAt: number | null }>()\n if (!row) return null\n return {\n id: row.id,\n keyId: row.keyId,\n keyEncrypted: row.keyEncrypted,\n budgetUsd: row.budgetUsd,\n expiresAt: row.expiresAt == null ? null : new Date(row.expiresAt),\n }\n },\n async listActive(workspaceId: string): Promise<Array<{ id: string; keyId: string }>> {\n const res = await db\n .prepare(`SELECT ${W.columns.id} AS id, ${W.columns.keyId} AS keyId FROM ${W.name} WHERE ${W.columns.workspaceId} = ? AND ${W.columns.revokedAt} IS NULL`)\n .bind(workspaceId)\n .all<{ id: string; keyId: string }>()\n return res.results\n },\n async insert(record): Promise<void> {\n await db\n .prepare(\n `INSERT INTO ${W.name} (${W.columns.id}, ${W.columns.workspaceId}, ${W.columns.keyId}, ${W.columns.keyEncrypted}, ${W.columns.budgetUsd}, ${W.columns.expiresAt}, ${W.columns.revokedAt}, ${W.columns.createdAt}) VALUES (?, ?, ?, ?, ?, ?, NULL, ?)`,\n )\n .bind(crypto.randomUUID(), record.workspaceId, record.keyId, record.keyEncrypted, record.budgetUsd, record.expiresAt.getTime(), Date.now())\n .run()\n },\n async markRevoked(id: string, now: Date): Promise<void> {\n await db\n .prepare(`UPDATE ${W.name} SET ${W.columns.revokedAt} = ? WHERE ${W.columns.id} = ?`)\n .bind(now.getTime(), id)\n .run()\n },\n }\n}\n\nexport interface PresetBillingOptions {\n db: D1Like\n /** The key provisioner (`@tangle-network/tcloud`'s client satisfies it structurally). */\n provisioner: KeyProvisioner\n /** Field-crypto key (64-char hex) or resolver — encrypts the minted key at rest. */\n encryptionKey: string | (() => string)\n /** Default monthly USD allowance when a call doesn't specify one. */\n defaultBudgetUsd: number\n /** Injectable clock. */\n now?: () => Date\n /** tcloud product the key is scoped to. Default `'router'`. */\n product?: string\n}\n\n/**\n * Stand up the per-workspace budget-capped {@link WorkspaceKeyManager} on the\n * house stack: the preset `workspace_keys` D1 store + AES-GCM field crypto +\n * the consumer's tcloud provisioner. The mint/rotate/rollover/usage LOGIC lives\n * in `../billing`; this only binds it to the preset table + crypto.\n */\nexport function createPresetWorkspaceKeyManager(opts: PresetBillingOptions): WorkspaceKeyManager {\n return createWorkspaceKeyManager({\n provisioner: opts.provisioner,\n store: createPresetWorkspaceKeyStore(opts.db),\n crypto: createPresetFieldCrypto(opts.encryptionKey),\n defaultBudgetUsd: opts.defaultBudgetUsd,\n now: opts.now,\n product: opts.product,\n })\n}\n"],"mappings":"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","names":[]}
|