@fungi.computer/parakeet 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-contributions.d.ts +1 -0
- package/dist/commands/awaiting-driver.d.ts +20 -0
- package/dist/commands/awaiting-driver.js +121 -0
- package/dist/commands/builtins.js +6 -4
- package/dist/commands/interactions.d.ts +25 -0
- package/dist/commands/interactions.js +76 -2
- package/dist/commands/run.js +3 -3
- package/dist/commands/slash.d.ts +7 -3
- package/dist/commands/slash.js +2 -0
- package/dist/commands/use-slash-commands.d.ts +13 -0
- package/dist/commands/use-slash-commands.js +58 -1
- package/dist/components/ChatComposer.d.ts +2 -0
- package/dist/components/ChatComposer.js +150 -38
- package/dist/components/ClientRows.js +42 -26
- package/dist/components/CompletionMenu.d.ts +54 -0
- package/dist/components/CompletionMenu.js +52 -0
- package/dist/components/DecisionComposer.d.ts +30 -0
- package/dist/components/DecisionComposer.js +146 -0
- package/dist/components/InteractionPanel.d.ts +10 -1
- package/dist/components/InteractionPanel.js +9 -4
- package/dist/components/SlashMenu.d.ts +1 -3
- package/dist/components/SlashMenu.js +5 -13
- package/dist/components/TimelineItem.d.ts +1 -0
- package/dist/components/TimelineItem.js +3 -3
- package/dist/components/ToolGroup.d.ts +1 -0
- package/dist/components/ToolGroup.js +7 -7
- package/dist/conversation.d.ts +5 -1
- package/dist/conversation.js +72 -20
- package/dist/core/approval-decision.d.ts +198 -0
- package/dist/core/approval-decision.js +291 -0
- package/dist/core/awaiting-answer.d.ts +229 -0
- package/dist/core/awaiting-answer.js +303 -0
- package/dist/core/build-timeline.js +56 -5
- package/dist/core/client-actions.d.ts +1 -0
- package/dist/core/client-actions.js +7 -1
- package/dist/core/draft-storage.d.ts +4 -0
- package/dist/core/draft-storage.js +12 -5
- package/dist/core/session-query.d.ts +8 -0
- package/dist/core/session-query.js +13 -11
- package/dist/headless.d.ts +6 -2
- package/dist/headless.js +5 -1
- package/dist/parakeet.d.ts +6 -2
- package/dist/parakeet.js +15 -6
- package/dist/store/types.d.ts +5 -1
- package/dist/styles.css +395 -113
- package/dist/use-approval-awaiting.d.ts +22 -0
- package/dist/use-approval-awaiting.js +81 -0
- package/dist/use-decision.d.ts +20 -0
- package/dist/use-decision.js +79 -0
- package/docs/api/commands/slash.md +30 -26
- package/docs/api/headless.md +822 -41
- package/docs/api/index.md +13 -4
- package/package.json +13 -7
- package/src/completion-menu.css +71 -0
- package/src/styles.css +174 -46
|
@@ -15,6 +15,7 @@ const recalledPrompt = z.object({
|
|
|
15
15
|
delivery,
|
|
16
16
|
});
|
|
17
17
|
const pendingDraft = z.object({
|
|
18
|
+
status: z.enum(["queued-local", "admitting"]),
|
|
18
19
|
requestId: z.string().min(1),
|
|
19
20
|
content: z.string(),
|
|
20
21
|
submittedDraft: z.string(),
|
|
@@ -31,15 +32,21 @@ const journal = z.object({
|
|
|
31
32
|
});
|
|
32
33
|
/** One owner-scoped journal commits pending text and composer text together. */
|
|
33
34
|
export function draftJournal(scope, storage) {
|
|
34
|
-
const key = `fungi.parakeet.drafts.
|
|
35
|
+
const key = `fungi.parakeet.drafts.v2:${scope}`;
|
|
35
36
|
return {
|
|
36
37
|
read() {
|
|
37
38
|
if (storage === undefined)
|
|
38
39
|
return { draft: "", pending: [] };
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
try {
|
|
41
|
+
const saved = storage.getItem(key);
|
|
42
|
+
return saved === null
|
|
43
|
+
? { draft: "", pending: [] }
|
|
44
|
+
: journal.parse(JSON.parse(saved));
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Preview journals are disposable; a broken load must not break chat.
|
|
48
|
+
return { draft: "", pending: [] };
|
|
49
|
+
}
|
|
43
50
|
},
|
|
44
51
|
write(value) {
|
|
45
52
|
if (storage === undefined)
|
|
@@ -7,6 +7,8 @@ export declare function sessionQueryOptions(session: ParakeetSession): import("@
|
|
|
7
7
|
observation: "connecting" | "live";
|
|
8
8
|
/** Last coherent durable Session state, absent before the first snapshot. */
|
|
9
9
|
snapshot: SessionSnapshot | undefined;
|
|
10
|
+
/** Last successful watch connect or delivered frame, not a cached seed. */
|
|
11
|
+
lastReplyAt: number | undefined;
|
|
10
12
|
/** One retryable user prompt, including image cargo, survives page refreshes. */
|
|
11
13
|
latestPrompt: Readonly<{
|
|
12
14
|
/** Owner-issued identity of the original prompt command. */
|
|
@@ -21,6 +23,8 @@ export declare function sessionQueryOptions(session: ParakeetSession): import("@
|
|
|
21
23
|
observation: "connecting" | "live";
|
|
22
24
|
/** Last coherent durable Session state, absent before the first snapshot. */
|
|
23
25
|
snapshot: SessionSnapshot | undefined;
|
|
26
|
+
/** Last successful watch connect or delivered frame, not a cached seed. */
|
|
27
|
+
lastReplyAt: number | undefined;
|
|
24
28
|
/** One retryable user prompt, including image cargo, survives page refreshes. */
|
|
25
29
|
latestPrompt: Readonly<{
|
|
26
30
|
/** Owner-issued identity of the original prompt command. */
|
|
@@ -36,6 +40,8 @@ export declare function sessionQueryOptions(session: ParakeetSession): import("@
|
|
|
36
40
|
observation: "connecting" | "live";
|
|
37
41
|
/** Last coherent durable Session state, absent before the first snapshot. */
|
|
38
42
|
snapshot: SessionSnapshot | undefined;
|
|
43
|
+
/** Last successful watch connect or delivered frame, not a cached seed. */
|
|
44
|
+
lastReplyAt: number | undefined;
|
|
39
45
|
/** One retryable user prompt, including image cargo, survives page refreshes. */
|
|
40
46
|
latestPrompt: Readonly<{
|
|
41
47
|
/** Owner-issued identity of the original prompt command. */
|
|
@@ -51,6 +57,8 @@ export declare function sessionQueryOptions(session: ParakeetSession): import("@
|
|
|
51
57
|
observation: "connecting" | "live";
|
|
52
58
|
/** Last coherent durable Session state, absent before the first snapshot. */
|
|
53
59
|
snapshot: SessionSnapshot | undefined;
|
|
60
|
+
/** Last successful watch connect or delivered frame, not a cached seed. */
|
|
61
|
+
lastReplyAt: number | undefined;
|
|
54
62
|
/** One retryable user prompt, including image cargo, survives page refreshes. */
|
|
55
63
|
latestPrompt: Readonly<{
|
|
56
64
|
/** Owner-issued identity of the original prompt command. */
|
|
@@ -4,6 +4,7 @@ import { reportFailure } from "../lib/failure.js";
|
|
|
4
4
|
const emptyProjection = Object.freeze({
|
|
5
5
|
observation: "connecting",
|
|
6
6
|
snapshot: undefined,
|
|
7
|
+
lastReplyAt: undefined,
|
|
7
8
|
latestPrompt: undefined,
|
|
8
9
|
});
|
|
9
10
|
// A watch starts with a bounded page, but its update frames keep arriving for
|
|
@@ -60,7 +61,7 @@ async function* observeSession(session, signal) {
|
|
|
60
61
|
yield { kind: "snapshot", value: snapshot };
|
|
61
62
|
}
|
|
62
63
|
else {
|
|
63
|
-
yield { kind: "frame", value: frame };
|
|
64
|
+
yield { kind: "frame", value: frame, snapshot };
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
throw new Error("Session watch ended; current activity is unavailable");
|
|
@@ -81,21 +82,21 @@ function reduceObservation(projection, observation) {
|
|
|
81
82
|
return {
|
|
82
83
|
observation: "live",
|
|
83
84
|
snapshot: observation.value,
|
|
85
|
+
lastReplyAt: Date.now(),
|
|
84
86
|
latestPrompt: latestPrompt(observation.value.messages, projection.latestPrompt),
|
|
85
87
|
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
observation: "live",
|
|
90
|
-
snapshot: observation.value.baseline,
|
|
91
|
-
latestPrompt: latestPrompt(observation.value.baseline.messages),
|
|
92
|
-
}
|
|
93
|
-
: projection;
|
|
94
|
-
const snapshot = applySessionFrame(projection.snapshot, observation.value);
|
|
88
|
+
// The generator owns frame application and always delivers its baseline
|
|
89
|
+
// first. The cache only reduces already-projected observations.
|
|
90
|
+
const snapshot = observation.snapshot;
|
|
95
91
|
return {
|
|
96
92
|
observation: "live",
|
|
97
93
|
snapshot,
|
|
98
|
-
|
|
94
|
+
lastReplyAt: Date.now(),
|
|
95
|
+
latestPrompt: observation.value.kind === "reset" ||
|
|
96
|
+
(observation.value.kind === "update" &&
|
|
97
|
+
observation.value.messages.some((message) => message.value.role === "user"))
|
|
98
|
+
? latestPrompt(snapshot.messages, projection.latestPrompt)
|
|
99
|
+
: projection.latestPrompt,
|
|
99
100
|
};
|
|
100
101
|
}
|
|
101
102
|
/** One shared TanStack observation keyed by Shiitake's logical Session address. */
|
|
@@ -119,6 +120,7 @@ export function seedSessionQuery(queryClient, session, snapshot) {
|
|
|
119
120
|
queryClient.setQueryData(sessionQueryOptions(session).queryKey, {
|
|
120
121
|
observation: "connecting",
|
|
121
122
|
snapshot,
|
|
123
|
+
lastReplyAt: undefined,
|
|
122
124
|
latestPrompt: latestPrompt(snapshot.messages),
|
|
123
125
|
});
|
|
124
126
|
}
|
package/dist/headless.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type { ParakeetDraftIdentity, ParakeetDraftStorage, } from "./core/draft-
|
|
|
4
4
|
export { formatContextUsage, formatTokenCount } from "./core/format-context.js";
|
|
5
5
|
export { formatWhen, oneLine } from "./core/picker-text.js";
|
|
6
6
|
export { providerChoices } from "./provider-choices.js";
|
|
7
|
-
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useStatus, useTimeline, type ComposerController, type ParakeetDraftCheckpoint, type ParakeetModel, type ParakeetObservation, type ParakeetReconnectOutcome, type ParakeetStatus, type ParakeetSessionViewState, type ParakeetUsage, type StatusController, type TimelineController, } from "./conversation.js";
|
|
7
|
+
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useLastSessionReplyAt, useStatus, useTimeline, type ComposerController, type ParakeetDraftCheckpoint, type ParakeetModel, type ParakeetObservation, type ParakeetReconnectOutcome, type ParakeetStatus, type ParakeetSessionViewState, type ParakeetUsage, type StatusController, type TimelineController, } from "./conversation.js";
|
|
8
8
|
export { sessionViewState, queuedSessionLabel, sessionActivityStatus, type SessionActivityStatus, type SessionViewFacts, type SessionViewState as ParakeetOwnerViewState, } from "./core/session-view-state.js";
|
|
9
9
|
export { mergeTerminals } from "./core/session-projection.js";
|
|
10
10
|
export { type SessionActivity, seedSessionQuery, sessionQueryOptions, subscribeSessionActivity, } from "./core/session-query.js";
|
|
@@ -15,7 +15,7 @@ export { contributeSessionCommands, type ParakeetSessionCommandOptions, } from "
|
|
|
15
15
|
export { completeSlash, fuzzyMatch, keyBindings, keyLabel, parseSlashDraft, slashRegistry, type FuzzyMatch, type KeyBindingRow, type SlashCommand, type SlashCommandItem, type SlashCompletion, type SlashParse, type SlashWordItem, } from "./commands/slash.js";
|
|
16
16
|
export { composerHints, fitHints, formatHints, type ComposerHintContext, type ComposerKeys, type KeyHint, } from "./commands/hints.js";
|
|
17
17
|
export { isCancelledOutcome, runSlashDraft, type SlashRuntime, } from "./commands/run.js";
|
|
18
|
-
export { createParakeetInteractions, type ParakeetInteractions, type ParakeetInteractionState, type ParakeetNotice, type ParakeetOpenInteraction, type ParakeetToast, } from "./commands/interactions.js";
|
|
18
|
+
export { createParakeetInteractions, type ParakeetInteractions, type ParakeetAwaiting, type ParakeetInteractionState, type ParakeetNotice, type ParakeetOpenInteraction, type ParakeetToast, } from "./commands/interactions.js";
|
|
19
19
|
export { parakeetBuiltinCommands, type ParakeetBuiltinOptions, } from "./commands/builtins.js";
|
|
20
20
|
export { advertisedCommands, type AdvertisedCatalogError, type AdvertisedCommands, } from "./commands/advertised.js";
|
|
21
21
|
export { useSlashCommands, type ParakeetCommandRuntime, type SlashCommandController, type SlashCommandOptions, } from "./commands/use-slash-commands.js";
|
|
@@ -27,5 +27,9 @@ export { formatToolDuration, toolCallView, toolKindSigils, toolStatusTone, type
|
|
|
27
27
|
export { assistantMessageVisible } from "./core/assistant-visibility.js";
|
|
28
28
|
export { disclosureOpen, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, type ToolDisclosureState, } from "./core/tool-groups.js";
|
|
29
29
|
export { useClientActions } from "./client-contributions.js";
|
|
30
|
+
export { awaitingQueue, awaitingTakeover, decisionView, decisionViewText, initialDecisionState, reduceDecision, type AwaitingItem, type AwaitingKind, type AwaitingQueue, type DecisionEffect, type DecisionIntent, type DecisionOutcome, type DecisionPhase, type DecisionPrompt, type DecisionRowView, type DecisionState, type DecisionView, } from "./core/awaiting-answer.js";
|
|
31
|
+
export { useDecision, type DecisionController } from "./use-decision.js";
|
|
32
|
+
export { useApprovalAwaiting } from "./use-approval-awaiting.js";
|
|
33
|
+
export { approvalCardCopy, approvalRefusal, askApproval, type ApprovalAbandoned, type ApprovalAnswered, type ApprovalAnswerInput, type ApprovalAnswerResult, type ApprovalCard, type ApprovalContent, type ApprovalDecision, type ApprovalEntry, type ApprovalFacts, type ApprovalOutcome, type ApprovalRefused, type ApprovalReview, type ApprovalSource, } from "./core/approval-decision.js";
|
|
30
34
|
export { placeClientTimeline, type PlacedClientCell, } from "./core/client-timeline.js";
|
|
31
35
|
export type { ClientContribution } from "./core/client-contributions.js";
|
package/dist/headless.js
CHANGED
|
@@ -2,7 +2,7 @@ export { formatModelIdentity, formatModelWithLevel, } from "./core/model-identit
|
|
|
2
2
|
export { formatContextUsage, formatTokenCount } from "./core/format-context.js";
|
|
3
3
|
export { formatWhen, oneLine } from "./core/picker-text.js";
|
|
4
4
|
export { providerChoices } from "./provider-choices.js";
|
|
5
|
-
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useStatus, useTimeline, } from "./conversation.js";
|
|
5
|
+
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useLastSessionReplyAt, useStatus, useTimeline, } from "./conversation.js";
|
|
6
6
|
export { sessionViewState, queuedSessionLabel, sessionActivityStatus, } from "./core/session-view-state.js";
|
|
7
7
|
export { mergeTerminals } from "./core/session-projection.js";
|
|
8
8
|
export { seedSessionQuery, sessionQueryOptions, subscribeSessionActivity, } from "./core/session-query.js";
|
|
@@ -22,4 +22,8 @@ export { formatToolDuration, toolCallView, toolKindSigils, toolStatusTone, } fro
|
|
|
22
22
|
export { assistantMessageVisible } from "./core/assistant-visibility.js";
|
|
23
23
|
export { disclosureOpen, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, } from "./core/tool-groups.js";
|
|
24
24
|
export { useClientActions } from "./client-contributions.js";
|
|
25
|
+
export { awaitingQueue, awaitingTakeover, decisionView, decisionViewText, initialDecisionState, reduceDecision, } from "./core/awaiting-answer.js";
|
|
26
|
+
export { useDecision } from "./use-decision.js";
|
|
27
|
+
export { useApprovalAwaiting } from "./use-approval-awaiting.js";
|
|
28
|
+
export { approvalCardCopy, approvalRefusal, askApproval, } from "./core/approval-decision.js";
|
|
25
29
|
export { placeClientTimeline, } from "./core/client-timeline.js";
|
package/dist/parakeet.d.ts
CHANGED
|
@@ -31,6 +31,8 @@ export type ParakeetProps = Readonly<{
|
|
|
31
31
|
composerActionVariant?: "primary" | "outline" | undefined;
|
|
32
32
|
/** Optional caller-owned actions for a completed tool result. */
|
|
33
33
|
renderToolActions?: ((item: ToolItem) => ReactNode) | undefined;
|
|
34
|
+
/** Optional host claim: true hides this item's image parts from the tool body because the host shows them. */
|
|
35
|
+
claimsToolMedia?: ((item: ToolItem) => boolean) | undefined;
|
|
34
36
|
/** Optional caller-owned attachment below a settled assistant reply. */
|
|
35
37
|
renderAssistantAttachment?: ((text: string) => ReactNode) | undefined;
|
|
36
38
|
/** Optional display text; attachments still receive the original reply. */
|
|
@@ -54,6 +56,8 @@ export type ParakeetViewProps = Readonly<{
|
|
|
54
56
|
composerActionVariant?: "primary" | "outline" | undefined;
|
|
55
57
|
/** Optional caller-owned actions for a completed tool result. */
|
|
56
58
|
renderToolActions?: ((item: ToolItem) => ReactNode) | undefined;
|
|
59
|
+
/** Optional host claim: true hides this item's image parts from the tool body because the host shows them. */
|
|
60
|
+
claimsToolMedia?: ((item: ToolItem) => boolean) | undefined;
|
|
57
61
|
/** Optional caller-owned attachment below a settled assistant reply. */
|
|
58
62
|
renderAssistantAttachment?: ((text: string) => ReactNode) | undefined;
|
|
59
63
|
/** Optional display text; attachments still receive the original reply. */
|
|
@@ -72,6 +76,6 @@ export type ParakeetViewProps = Readonly<{
|
|
|
72
76
|
commands?: ParakeetCommandRuntime | undefined;
|
|
73
77
|
}>;
|
|
74
78
|
/** Render the retained conversation surface within one Parakeet provider. */
|
|
75
|
-
export declare function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }: ParakeetViewProps): ReactElement;
|
|
79
|
+
export declare function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }: ParakeetViewProps): ReactElement;
|
|
76
80
|
/** Standalone typed composer and exact-message timeline. */
|
|
77
|
-
export declare function Parakeet({ authorOf, disambiguateAuthors, visitor, markdownPolicy, composerActionVariant, empty, session, clients, renderToolActions, renderAssistantAttachment, formatAssistantText, commands, onLink, onOpen, }: ParakeetProps): ReactElement;
|
|
81
|
+
export declare function Parakeet({ authorOf, disambiguateAuthors, visitor, markdownPolicy, composerActionVariant, empty, session, clients, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, commands, onLink, onOpen, }: ParakeetProps): ReactElement;
|
package/dist/parakeet.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createWhistle } from "@fungi.computer/whistle";
|
|
|
6
6
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
7
7
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
8
8
|
import { ParakeetProvider, useComposer, useClientContributions, useDismissFailedPrompt, useStatus, useTimeline, } from "./conversation.js";
|
|
9
|
+
import { awaitingTakeover } from "./core/awaiting-answer.js";
|
|
9
10
|
import { initialToolDisclosure, toggleDisclosure } from "./core/tool-groups.js";
|
|
10
11
|
import { authorDisplayNames, } from "./core/author-labels.js";
|
|
11
12
|
import { useTimelineItemKey } from "./core/use-timeline-item-key.js";
|
|
@@ -19,7 +20,7 @@ import { useSlashCommands, } from "./commands/use-slash-commands.js";
|
|
|
19
20
|
import { TimelineItem } from "./components/TimelineItem.js";
|
|
20
21
|
import { MarkdownPolicyContext } from "./components/MarkdownRenderer.js";
|
|
21
22
|
/** Render the retained conversation surface within one Parakeet provider. */
|
|
22
|
-
export function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }) {
|
|
23
|
+
export function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }) {
|
|
23
24
|
const textareaRef = useRef(null);
|
|
24
25
|
const [ownCommands] = useState(() => createWhistle());
|
|
25
26
|
const slash = useSlashCommands({
|
|
@@ -31,6 +32,9 @@ export function ParakeetView({ disambiguateAuthors, visitor, composerActionVaria
|
|
|
31
32
|
});
|
|
32
33
|
const clientActions = useClientActions(commands ?? ownCommands);
|
|
33
34
|
const contributions = useClientContributions();
|
|
35
|
+
const { draft } = useComposer();
|
|
36
|
+
// The decision in the composer is not also a footer row.
|
|
37
|
+
const answering = awaitingTakeover(slash.awaiting, draft)?.key;
|
|
34
38
|
const timelineController = useTimeline();
|
|
35
39
|
const placed = useMemo(() => placeClientTimeline(contributions, timelineController.commandAnchors, timelineController.positionAnchors), [
|
|
36
40
|
contributions,
|
|
@@ -43,7 +47,11 @@ export function ParakeetView({ disambiguateAuthors, visitor, composerActionVaria
|
|
|
43
47
|
: null;
|
|
44
48
|
if (anchor instanceof HTMLAnchorElement && onLink?.(anchor.href))
|
|
45
49
|
event.preventDefault();
|
|
46
|
-
}, children: [_jsxs("div", { className: "flex h-full w-full flex-col border-r border-base-300", children: [_jsx(ConversationTimeline, { disambiguateAuthors: visitor === undefined && disambiguateAuthors === true, clientActions: clientActions, onOpen: onOpen, focusAfterJump: textareaRef, empty: empty, renderToolActions: renderToolActions, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText }), contributions.some(({ value }) => value.panel.
|
|
50
|
+
}, children: [_jsxs("div", { className: "flex h-full w-full flex-col border-r border-base-300", children: [_jsx(ConversationTimeline, { disambiguateAuthors: visitor === undefined && disambiguateAuthors === true, clientActions: clientActions, onOpen: onOpen, focusAfterJump: textareaRef, empty: empty, renderToolActions: renderToolActions, claimsToolMedia: claimsToolMedia, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText }), contributions.some(({ entryId, value }) => value.panel.some((row) => JSON.stringify([entryId, row.id]) !== answering)) ? (_jsx("section", { "aria-label": "Session extension controls", className: "w-full shrink-0 border-t border-base-300 bg-base-100", children: contributions.map(({ entryId, value: contribution }) => {
|
|
51
|
+
const value = {
|
|
52
|
+
...contribution,
|
|
53
|
+
panel: contribution.panel.filter((row) => JSON.stringify([entryId, row.id]) !== answering),
|
|
54
|
+
};
|
|
47
55
|
// An extension's retained-event notice and null-anchor rows
|
|
48
56
|
// join its own footer entry; one with no panel row here keeps
|
|
49
57
|
// none of this, rather than growing a section just to show it.
|
|
@@ -92,7 +100,7 @@ function ConversationInteraction({ slash, }) {
|
|
|
92
100
|
slash.store.close();
|
|
93
101
|
}, children: _jsx(DialogContent, { className: "w-[min(32rem,calc(100vw-2rem))] rounded-box bg-base-100 p-md shadow-lg", keepMounted: false, children: open === undefined ? null : (_jsx(InteractionPanel, { host: open.host, onClose: slash.store.close }, open.key)) }) }));
|
|
94
102
|
}
|
|
95
|
-
function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focusAfterJump, empty, renderToolActions, renderAssistantAttachment, formatAssistantText, }) {
|
|
103
|
+
function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focusAfterJump, empty, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, }) {
|
|
96
104
|
const dismissFailed = useDismissFailedPrompt();
|
|
97
105
|
const timelineController = useTimeline();
|
|
98
106
|
const cancelQueued = useCallback((commandId) => {
|
|
@@ -209,7 +217,7 @@ function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focu
|
|
|
209
217
|
item.author.name,
|
|
210
218
|
},
|
|
211
219
|
}
|
|
212
|
-
: item, onDismissFailed: dismissFailed, onCancelQueued: cancelQueued, cancellingQueued: timelineController.cancellingQueued, onToggleTool: toggleTool, renderToolActions: renderToolActions, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText, toolDisclosure: toolDisclosure }), placed.after.get(item.id)?.map(({ entryId, cell }) => (_jsx(ClientRows, { entryId: entryId, rows: cell.rows, actions: clientActions, onOpen: onOpen }, `${entryId}:${cell.id}`)))] }, virtualItem.key));
|
|
220
|
+
: item, onDismissFailed: dismissFailed, onCancelQueued: cancelQueued, cancellingQueued: timelineController.cancellingQueued, onToggleTool: toggleTool, renderToolActions: renderToolActions, claimsToolMedia: claimsToolMedia, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText, toolDisclosure: toolDisclosure }), placed.after.get(item.id)?.map(({ entryId, cell }) => (_jsx(ClientRows, { entryId: entryId, rows: cell.rows, actions: clientActions, onOpen: onOpen }, `${entryId}:${cell.id}`)))] }, virtualItem.key));
|
|
213
221
|
}) })) : before.length > 0 ? (before) : hasMoreHistory ? null : ((empty ?? (_jsx("div", { className: "flex h-full items-center justify-center text-center", children: _jsxs("div", { children: [_jsx("p", { className: "mb-1 text-xs text-base-content", children: "Ready" }), _jsx("p", { className: "text-[10px] text-dim", children: "What would you like to build?" })] }) })))) }), count > 0 ? (_jsx(ScrollToBottomBlob, { direction: "forward", unread: unread, focusAfterJump: focusAfterJump, onJump: jumpToBottom, scrollerRef: scrollerRef })) : null] }));
|
|
214
222
|
}
|
|
215
223
|
/** The owner's queued state and independently contributed waiting controls. */
|
|
@@ -242,6 +250,7 @@ function ConversationComposer({ visitor, textareaRef, composerActionVariant, sla
|
|
|
242
250
|
}, [composer.cancel]);
|
|
243
251
|
const composerProps = {
|
|
244
252
|
queuedRecall: visitor === undefined ? composer : undefined,
|
|
253
|
+
onImagesChange: visitor === undefined ? composer.setImages : undefined,
|
|
245
254
|
statusChips: contributions
|
|
246
255
|
.flatMap(({ value }) => value.chips)
|
|
247
256
|
.sort((left, right) => left.order - right.order)
|
|
@@ -270,6 +279,6 @@ function ConversationComposer({ visitor, textareaRef, composerActionVariant, sla
|
|
|
270
279
|
return _jsx(ChatComposer, { ...composerProps });
|
|
271
280
|
}
|
|
272
281
|
/** Standalone typed composer and exact-message timeline. */
|
|
273
|
-
export function Parakeet({ authorOf, disambiguateAuthors, visitor, markdownPolicy = "session", composerActionVariant, empty, session, clients, renderToolActions, renderAssistantAttachment, formatAssistantText, commands, onLink, onOpen, }) {
|
|
274
|
-
return (_jsx(MarkdownPolicyContext.Provider, { value: markdownPolicy, children: _jsx(ParakeetProvider, { session: session, clients: clients, authorOf: authorOf, children: _jsx(ParakeetView, { disambiguateAuthors: disambiguateAuthors, visitor: visitor, composerActionVariant: composerActionVariant, empty: empty, renderToolActions: renderToolActions, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText, commands: commands, onLink: onLink, onOpen: onOpen }) }) }));
|
|
282
|
+
export function Parakeet({ authorOf, disambiguateAuthors, visitor, markdownPolicy = "session", composerActionVariant, empty, session, clients, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, commands, onLink, onOpen, }) {
|
|
283
|
+
return (_jsx(MarkdownPolicyContext.Provider, { value: markdownPolicy, children: _jsx(ParakeetProvider, { session: session, clients: clients, authorOf: authorOf, children: _jsx(ParakeetView, { disambiguateAuthors: disambiguateAuthors, visitor: visitor, composerActionVariant: composerActionVariant, empty: empty, renderToolActions: renderToolActions, claimsToolMedia: claimsToolMedia, renderAssistantAttachment: renderAssistantAttachment, formatAssistantText: formatAssistantText, commands: commands, onLink: onLink, onOpen: onOpen }) }) }));
|
|
275
284
|
}
|
package/dist/store/types.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export type LocalPromptAdmission = Readonly<{
|
|
|
51
51
|
/** Existing Session delivery intent. */
|
|
52
52
|
delivery: PromptDelivery;
|
|
53
53
|
/** Current local admission result. */
|
|
54
|
-
status: "admitting" | "accepted" | "failed";
|
|
54
|
+
status: "queued-local" | "admitting" | "accepted" | "failed";
|
|
55
55
|
/** User-presentable admission error when status is failed. */
|
|
56
56
|
error?: string;
|
|
57
57
|
}>;
|
|
@@ -73,6 +73,10 @@ export type AssistantMessageItem = Readonly<{
|
|
|
73
73
|
text: string;
|
|
74
74
|
/** Pi's private failed-turn error text; never a terminal or delegation diagnostic. */
|
|
75
75
|
providerError?: string;
|
|
76
|
+
/** Short assistant output retained before a provider failure, not provider prose. */
|
|
77
|
+
errorDetail?: string;
|
|
78
|
+
/** Consecutive failures with the same visible headline and detail. */
|
|
79
|
+
repeatCount?: number;
|
|
76
80
|
/** Assistant reasoning text, when supplied by the model. */
|
|
77
81
|
thinking?: string;
|
|
78
82
|
/** Usage carried by the exact assistant message. */
|