@fungi.computer/parakeet 0.4.0 → 0.6.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/README.md +17 -1
- 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 +158 -40
- package/dist/components/ClientRows.js +42 -26
- package/dist/components/CodeBlock.js +3 -2
- package/dist/components/CompletionMenu.d.ts +54 -0
- package/dist/components/CompletionMenu.js +52 -0
- package/dist/components/ComposerModelKey.d.ts +11 -0
- package/dist/components/ComposerModelKey.js +9 -0
- package/dist/components/ComposerShell.d.ts +47 -0
- package/dist/components/ComposerShell.js +29 -0
- package/dist/components/DecisionComposer.d.ts +30 -0
- package/dist/components/DecisionComposer.js +145 -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 +4 -4
- package/dist/components/ToolGroup.d.ts +1 -0
- package/dist/components/ToolGroup.js +8 -8
- package/dist/conversation-opening.d.ts +1 -1
- package/dist/conversation-opening.js +2 -2
- package/dist/conversation.d.ts +5 -1
- package/dist/conversation.js +84 -29
- 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 +61 -7
- package/dist/core/client-actions.d.ts +1 -0
- package/dist/core/client-actions.js +7 -1
- package/dist/core/composer-model-name.d.ts +3 -0
- package/dist/core/composer-model-name.js +21 -0
- package/dist/core/display-text.d.ts +2 -0
- package/dist/core/display-text.js +7 -0
- package/dist/core/draft-storage.d.ts +6 -0
- package/dist/core/draft-storage.js +25 -5
- package/dist/core/session-projection.d.ts +1 -0
- package/dist/core/session-projection.js +3 -2
- package/dist/core/session-query.d.ts +8 -0
- package/dist/core/session-query.js +13 -11
- package/dist/core/session-view-state.d.ts +2 -4
- package/dist/core/session-view-state.js +27 -9
- package/dist/core/tool-groups.d.ts +3 -0
- package/dist/core/tool-groups.js +37 -1
- package/dist/core/tool-view.d.ts +6 -0
- package/dist/core/tool-view.js +33 -0
- package/dist/core/use-timeline-item-key.d.ts +3 -4
- package/dist/core/use-timeline-item-key.js +8 -14
- package/dist/headless.d.ts +10 -5
- package/dist/headless.js +9 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/parakeet.d.ts +6 -2
- package/dist/parakeet.js +24 -17
- package/dist/store/types.d.ts +14 -1
- package/dist/styles.css +911 -162
- 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 +917 -54
- package/docs/api/index.md +166 -5
- package/package.json +17 -8
- package/src/completion-menu.css +72 -0
- package/src/composer-shell.css +125 -0
- package/src/styles.css +99 -53
- package/dist/components/WaitingNotice.d.ts +0 -7
- package/dist/components/WaitingNotice.js +0 -8
|
@@ -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
|
}
|
|
@@ -56,10 +56,8 @@ export type SessionActivityStatus = "cancelling" | "idle" | "queued" | "retrying
|
|
|
56
56
|
/** Decide a Session's view state from its activity, terminals and progress. */
|
|
57
57
|
export declare function sessionViewState(facts: SessionViewFacts): SessionViewState;
|
|
58
58
|
export declare function sameRunningWork(left: AgentRunningWork | null, right: AgentRunningWork | null): boolean;
|
|
59
|
-
/**
|
|
60
|
-
export declare function
|
|
61
|
-
kind: "queued";
|
|
62
|
-
}>): string;
|
|
59
|
+
/** Activity only: queued messages belong in the transcript, never in this label. */
|
|
60
|
+
export declare function sessionStateLabel(state: SessionViewState, waitingOnYou?: boolean): "thinking" | "streaming" | "running a tool" | "idle" | "waiting on you" | "failed";
|
|
63
61
|
/** Whether two view states say the same thing, so a readout can stay stable. */
|
|
64
62
|
export declare function sameSessionViewState(left: SessionViewState, right: SessionViewState): boolean;
|
|
65
63
|
/** Coarse activity for a view state: what the composer gates on. */
|
|
@@ -67,19 +67,37 @@ export function sameRunningWork(left, right) {
|
|
|
67
67
|
if (left === null || right === null)
|
|
68
68
|
return left === right;
|
|
69
69
|
if (left.kind === "session" && right.kind === "session")
|
|
70
|
-
return (left.sessionId === right.sessionId &&
|
|
70
|
+
return (left.sessionId === right.sessionId &&
|
|
71
|
+
left.commandId === right.commandId &&
|
|
72
|
+
left.title === right.title);
|
|
71
73
|
if (left.kind === "host" && right.kind === "host")
|
|
72
74
|
return left.lane === right.lane && left.jobId === right.jobId;
|
|
73
75
|
return false;
|
|
74
76
|
}
|
|
75
|
-
/**
|
|
76
|
-
export function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
:
|
|
77
|
+
/** Activity only: queued messages belong in the transcript, never in this label. */
|
|
78
|
+
export function sessionStateLabel(state, waitingOnYou = false) {
|
|
79
|
+
switch (state.kind) {
|
|
80
|
+
case "queued":
|
|
81
|
+
// Executor occupancy is the only Agent activity fact in a queued view.
|
|
82
|
+
// Its identity/title is not a state and must never become a status label.
|
|
83
|
+
return state.runningWork === null ? "idle" : "thinking";
|
|
84
|
+
case "thinking":
|
|
85
|
+
case "cancelling":
|
|
86
|
+
case "compacting":
|
|
87
|
+
case "retrying":
|
|
88
|
+
return "thinking";
|
|
89
|
+
case "responding":
|
|
90
|
+
return "streaming";
|
|
91
|
+
case "running_tool":
|
|
92
|
+
return "running a tool";
|
|
93
|
+
case "error":
|
|
94
|
+
return "failed";
|
|
95
|
+
case "idle":
|
|
96
|
+
case "waiting_for_you":
|
|
97
|
+
// A completed turn is idle; an actual attention/approval request is
|
|
98
|
+
// what makes the caller show "waiting on you".
|
|
99
|
+
return waitingOnYou ? "waiting on you" : "idle";
|
|
100
|
+
}
|
|
83
101
|
}
|
|
84
102
|
/** Whether two view states say the same thing, so a readout can stay stable. */
|
|
85
103
|
export function sameSessionViewState(left, right) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ProjectedItem, TimelineItem, ToolGroupItem, ToolItem } from "../store/types.js";
|
|
2
2
|
import { type ToolCallView } from "./tool-view.js";
|
|
3
|
+
import type { SessionToolOutput } from "@fungi.computer/shiitake/client";
|
|
4
|
+
/** Overlay only running calls; settled rows and their lazy result views stay shared. */
|
|
5
|
+
export declare function overlayToolOutput(items: readonly TimelineItem[], output: readonly SessionToolOutput[]): readonly TimelineItem[];
|
|
3
6
|
/** Build one group from a non-empty run of consecutive calls. */
|
|
4
7
|
export declare function toolGroup(tools: readonly [ToolItem, ...ToolItem[]]): ToolGroupItem;
|
|
5
8
|
/**
|
package/dist/core/tool-groups.js
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
import { assistantMessageVisible } from "./assistant-visibility.js";
|
|
2
|
-
import { toolCallView } from "./tool-view.js";
|
|
2
|
+
import { liveOutputLines, toolCallView, } from "./tool-view.js";
|
|
3
|
+
/** Overlay only running calls; settled rows and their lazy result views stay shared. */
|
|
4
|
+
export function overlayToolOutput(items, output) {
|
|
5
|
+
if (output.length === 0)
|
|
6
|
+
return items;
|
|
7
|
+
return items.map((item) => {
|
|
8
|
+
if (item.kind !== "tool_group")
|
|
9
|
+
return item;
|
|
10
|
+
const tools = item.tools.map((tool) => {
|
|
11
|
+
const slot = output.find((candidate) => candidate.toolCallId === tool.id);
|
|
12
|
+
if (tool.status !== "running" || slot === undefined)
|
|
13
|
+
return tool;
|
|
14
|
+
return {
|
|
15
|
+
...tool,
|
|
16
|
+
live: {
|
|
17
|
+
lines: liveOutputLines(slot.tail),
|
|
18
|
+
droppedBytes: slot.droppedBytes,
|
|
19
|
+
revision: slot.revision,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
if (tools.every((tool, index) => tool === item.tools[index]))
|
|
24
|
+
return item;
|
|
25
|
+
const calls = item.calls.map((call, index) => {
|
|
26
|
+
const tool = tools[index];
|
|
27
|
+
return tool === undefined || tool === item.tools[index]
|
|
28
|
+
? call
|
|
29
|
+
: toolCallView(tool);
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
...item,
|
|
33
|
+
tools,
|
|
34
|
+
calls,
|
|
35
|
+
active: calls.find((call) => call.id === item.active?.id),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
3
39
|
const nouns = {
|
|
4
40
|
code: ["ran", "script", "scripts"],
|
|
5
41
|
command: ["ran", "command", "commands"],
|
package/dist/core/tool-view.d.ts
CHANGED
|
@@ -173,7 +173,13 @@ export type ToolCallView = Readonly<{
|
|
|
173
173
|
error?: string | undefined;
|
|
174
174
|
/** Expanded body sections, in display order. */
|
|
175
175
|
sections: readonly ToolCallSection[];
|
|
176
|
+
/** Replaceable output while the call runs. */
|
|
177
|
+
live?: ToolItem["live"];
|
|
176
178
|
}>;
|
|
179
|
+
/** Neutral lines from a bounded live tail. */
|
|
180
|
+
export declare function liveOutputLines(tail: string): readonly string[];
|
|
181
|
+
/** Live output stays visible when folded, independent of result disclosure. */
|
|
182
|
+
export declare function toolLiveLines(call: ToolCallView, open: boolean): readonly string[];
|
|
177
183
|
/** Items shown before "more" for excerpts, matches, and output. */
|
|
178
184
|
export declare const toolPreviewLineLimit = 12;
|
|
179
185
|
/** Build the renderer-neutral view of one call. */
|
package/dist/core/tool-view.js
CHANGED
|
@@ -4,6 +4,7 @@ import { formatPatch, parsePatch, structuredPatch, } from "diff";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { reportFailure } from "../lib/failure.js";
|
|
7
|
+
import { sanitizeDisplayText } from "./display-text.js";
|
|
7
8
|
/** Shared tool status meaning, used by the browser and native presentations. */
|
|
8
9
|
export function toolStatusTone(status) {
|
|
9
10
|
if (status === "error")
|
|
@@ -27,6 +28,37 @@ export const toolKindSigils = {
|
|
|
27
28
|
/** Artwork for search results. */
|
|
28
29
|
search: "search",
|
|
29
30
|
};
|
|
31
|
+
/** Neutral lines from a bounded live tail. */
|
|
32
|
+
export function liveOutputLines(tail) {
|
|
33
|
+
if (tail === "")
|
|
34
|
+
return [];
|
|
35
|
+
// Replacement dominance counts decoded code points, not rendered graphemes.
|
|
36
|
+
const characters = Array.from(tail);
|
|
37
|
+
if (characters.filter((character) => character === "\ufffd").length >
|
|
38
|
+
characters.length / 2)
|
|
39
|
+
return [
|
|
40
|
+
`[binary output, ${String(new TextEncoder().encode(tail).byteLength)} bytes]`,
|
|
41
|
+
];
|
|
42
|
+
return stripAnsi(tail)
|
|
43
|
+
.replace(/\r\n/gu, "\n")
|
|
44
|
+
.replace(/\n$/u, "")
|
|
45
|
+
.split("\n")
|
|
46
|
+
.map((line) => sanitizeDisplayText(line.slice(line.lastIndexOf("\r") + 1)));
|
|
47
|
+
}
|
|
48
|
+
/** Live output stays visible when folded, independent of result disclosure. */
|
|
49
|
+
export function toolLiveLines(call, open) {
|
|
50
|
+
const live = call.live;
|
|
51
|
+
if (live === undefined)
|
|
52
|
+
return [];
|
|
53
|
+
if (!open)
|
|
54
|
+
return live.lines.slice(-6);
|
|
55
|
+
return [
|
|
56
|
+
...(live.droppedBytes === 0
|
|
57
|
+
? []
|
|
58
|
+
: [`… ${String(Math.ceil(live.droppedBytes / 1024))} KiB earlier`]),
|
|
59
|
+
...live.lines,
|
|
60
|
+
];
|
|
61
|
+
}
|
|
30
62
|
/** Items shown before "more" for excerpts, matches, and output. */
|
|
31
63
|
export const toolPreviewLineLimit = 12;
|
|
32
64
|
/** Diff lines shown before "more". */
|
|
@@ -600,6 +632,7 @@ export function toolCallView(item) {
|
|
|
600
632
|
kind,
|
|
601
633
|
label: target.label,
|
|
602
634
|
name: item.name,
|
|
635
|
+
live: item.status === "running" ? item.live : undefined,
|
|
603
636
|
paths: target.paths,
|
|
604
637
|
get sections() {
|
|
605
638
|
return getDetails().sections;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { TimelineItem } from "../store/types.js";
|
|
2
2
|
/**
|
|
3
|
-
* The virtualizer's row-key callback.
|
|
4
|
-
* but not
|
|
5
|
-
*
|
|
6
|
-
* tail rows changes. Settled rows are keyed from the settled list alone.
|
|
3
|
+
* The virtualizer's row-key callback. Progress replaces row payloads, including
|
|
4
|
+
* live overlays on settled calls, but not row keys. Keep the callback and its
|
|
5
|
+
* measurements until the order or identity of the combined rows changes.
|
|
7
6
|
*/
|
|
8
7
|
export declare function useTimelineItemKey(settled: readonly TimelineItem[], tail: readonly TimelineItem[]): (index: number) => string | number;
|
|
@@ -9,21 +9,15 @@ function sameKeys(a, b) {
|
|
|
9
9
|
return a.length === b.length && a.every((key, index) => key === b[index]);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* The virtualizer's row-key callback.
|
|
13
|
-
* but not
|
|
14
|
-
*
|
|
15
|
-
* tail rows changes. Settled rows are keyed from the settled list alone.
|
|
12
|
+
* The virtualizer's row-key callback. Progress replaces row payloads, including
|
|
13
|
+
* live overlays on settled calls, but not row keys. Keep the callback and its
|
|
14
|
+
* measurements until the order or identity of the combined rows changes.
|
|
16
15
|
*/
|
|
17
16
|
export function useTimelineItemKey(settled, tail) {
|
|
18
|
-
const next = tail.map(rowKey);
|
|
17
|
+
const next = [...settled, ...tail].map(rowKey);
|
|
19
18
|
const [previous, setPrevious] = useState(next);
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
setPrevious(
|
|
23
|
-
return useCallback((index) =>
|
|
24
|
-
const item = settled[index];
|
|
25
|
-
if (item !== undefined)
|
|
26
|
-
return rowKey(item);
|
|
27
|
-
return tailKeys[index - settled.length] ?? index;
|
|
28
|
-
}, [settled, tailKeys]);
|
|
19
|
+
const keys = sameKeys(previous, next) ? previous : next;
|
|
20
|
+
if (keys !== previous)
|
|
21
|
+
setPrevious(keys);
|
|
22
|
+
return useCallback((index) => keys[index] ?? index, [keys]);
|
|
29
23
|
}
|
package/dist/headless.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export { formatModelIdentity, formatModelWithLevel, } from "./core/model-identity.js";
|
|
2
2
|
export type { QueuedRecallState, QueuedRecallOutcome, } from "./core/queued-recall.js";
|
|
3
3
|
export type { ParakeetDraftIdentity, ParakeetDraftStorage, } from "./core/draft-storage.js";
|
|
4
|
+
export { sanitizeDisplayText } from "./core/display-text.js";
|
|
4
5
|
export { formatContextUsage, formatTokenCount } from "./core/format-context.js";
|
|
5
6
|
export { formatWhen, oneLine } from "./core/picker-text.js";
|
|
6
7
|
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";
|
|
8
|
-
export { sessionViewState,
|
|
9
|
-
export { mergeTerminals } from "./core/session-projection.js";
|
|
8
|
+
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";
|
|
9
|
+
export { sessionViewState, sessionStateLabel, sessionActivityStatus, type SessionActivityStatus, type SessionViewFacts, type SessionViewState as ParakeetOwnerViewState, } from "./core/session-view-state.js";
|
|
10
|
+
export { applySessionFrame, mergeTerminals, } from "./core/session-projection.js";
|
|
10
11
|
export { type SessionActivity, seedSessionQuery, sessionQueryOptions, subscribeSessionActivity, } from "./core/session-query.js";
|
|
11
12
|
export { accountCommandDefinitions, contributeAccountCommands, loginRegistry, type AccountCommandOptions, type AccountOwner, type ProviderAccess, type ModelAccountContext, type LoginHost, type LoginMethod, type LoginMethodKind, type LoginPolicy, type LoginProvider, type LoginScope, } from "./account-commands.js";
|
|
12
13
|
export { contributeModelCommands, sessionModelCommandDefinitions, type SessionModelChoice, type SessionModelCommandOptions, } from "./model-commands.js";
|
|
@@ -15,7 +16,7 @@ export { contributeSessionCommands, type ParakeetSessionCommandOptions, } from "
|
|
|
15
16
|
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
17
|
export { composerHints, fitHints, formatHints, type ComposerHintContext, type ComposerKeys, type KeyHint, } from "./commands/hints.js";
|
|
17
18
|
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";
|
|
19
|
+
export { createParakeetInteractions, type ParakeetInteractions, type ParakeetAwaiting, type ParakeetInteractionState, type ParakeetNotice, type ParakeetOpenInteraction, type ParakeetToast, } from "./commands/interactions.js";
|
|
19
20
|
export { parakeetBuiltinCommands, type ParakeetBuiltinOptions, } from "./commands/builtins.js";
|
|
20
21
|
export { advertisedCommands, type AdvertisedCatalogError, type AdvertisedCommands, } from "./commands/advertised.js";
|
|
21
22
|
export { useSlashCommands, type ParakeetCommandRuntime, type SlashCommandController, type SlashCommandOptions, } from "./commands/use-slash-commands.js";
|
|
@@ -23,9 +24,13 @@ export type { ParakeetSession, ParakeetSessionCommand, ParakeetPromptResult, } f
|
|
|
23
24
|
export type { AssistantMessageItem as ParakeetAssistantMessageItem, TimelineItem as ParakeetTimelineItem, ToolGroupItem as ParakeetToolGroupItem, ToolItem as ParakeetToolItem, UserMessageItem as ParakeetUserMessageItem, } from "./store/types.js";
|
|
24
25
|
export type { ToolArguments as ParakeetToolArguments } from "./core/tool-contract.js";
|
|
25
26
|
export { useMarkdown, type MarkdownBlock, type MarkdownInline, } from "./markdown.js";
|
|
26
|
-
export { formatToolDuration, toolCallView, toolKindSigils, toolStatusTone, type ToolCallSection as ParakeetToolCallSection, type ToolCallView as ParakeetToolCallView, type ToolDiffFile as ParakeetToolDiffFile, type ToolDiffHunk as ParakeetToolDiffHunk, type ToolDiffLine as ParakeetToolDiffLine, type ToolDiffRow as ParakeetToolDiffRow, type ToolExcerptLine as ParakeetToolExcerptLine, type ToolKind as ParakeetToolKind, type ToolMatch as ParakeetToolMatch, type ToolOutputLine as ParakeetToolOutputLine, } from "./core/tool-view.js";
|
|
27
|
+
export { formatToolDuration, toolCallView, toolKindSigils, toolLiveLines, toolStatusTone, type ToolCallSection as ParakeetToolCallSection, type ToolCallView as ParakeetToolCallView, type ToolDiffFile as ParakeetToolDiffFile, type ToolDiffHunk as ParakeetToolDiffHunk, type ToolDiffLine as ParakeetToolDiffLine, type ToolDiffRow as ParakeetToolDiffRow, type ToolExcerptLine as ParakeetToolExcerptLine, type ToolKind as ParakeetToolKind, type ToolMatch as ParakeetToolMatch, type ToolOutputLine as ParakeetToolOutputLine, } from "./core/tool-view.js";
|
|
27
28
|
export { assistantMessageVisible } from "./core/assistant-visibility.js";
|
|
28
29
|
export { disclosureOpen, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, type ToolDisclosureState, } from "./core/tool-groups.js";
|
|
29
30
|
export { useClientActions } from "./client-contributions.js";
|
|
31
|
+
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";
|
|
32
|
+
export { useDecision, type DecisionController } from "./use-decision.js";
|
|
33
|
+
export { useApprovalAwaiting } from "./use-approval-awaiting.js";
|
|
34
|
+
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
35
|
export { placeClientTimeline, type PlacedClientCell, } from "./core/client-timeline.js";
|
|
31
36
|
export type { ClientContribution } from "./core/client-contributions.js";
|
package/dist/headless.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { formatModelIdentity, formatModelWithLevel, } from "./core/model-identity.js";
|
|
2
|
+
export { sanitizeDisplayText } from "./core/display-text.js";
|
|
2
3
|
export { formatContextUsage, formatTokenCount } from "./core/format-context.js";
|
|
3
4
|
export { formatWhen, oneLine } from "./core/picker-text.js";
|
|
4
5
|
export { providerChoices } from "./provider-choices.js";
|
|
5
|
-
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useStatus, useTimeline, } from "./conversation.js";
|
|
6
|
-
export { sessionViewState,
|
|
7
|
-
export { mergeTerminals } from "./core/session-projection.js";
|
|
6
|
+
export { ParakeetProvider, useComposer, useClientContributions, useParakeetInteractions, useExtensionSlots, useParakeetSession, useLastSessionReplyAt, useStatus, useTimeline, } from "./conversation.js";
|
|
7
|
+
export { sessionViewState, sessionStateLabel, sessionActivityStatus, } from "./core/session-view-state.js";
|
|
8
|
+
export { applySessionFrame, mergeTerminals, } from "./core/session-projection.js";
|
|
8
9
|
export { seedSessionQuery, sessionQueryOptions, subscribeSessionActivity, } from "./core/session-query.js";
|
|
9
10
|
export { accountCommandDefinitions, contributeAccountCommands, loginRegistry, } from "./account-commands.js";
|
|
10
11
|
export { contributeModelCommands, sessionModelCommandDefinitions, } from "./model-commands.js";
|
|
@@ -18,8 +19,12 @@ export { parakeetBuiltinCommands, } from "./commands/builtins.js";
|
|
|
18
19
|
export { advertisedCommands, } from "./commands/advertised.js";
|
|
19
20
|
export { useSlashCommands, } from "./commands/use-slash-commands.js";
|
|
20
21
|
export { useMarkdown, } from "./markdown.js";
|
|
21
|
-
export { formatToolDuration, toolCallView, toolKindSigils, toolStatusTone, } from "./core/tool-view.js";
|
|
22
|
+
export { formatToolDuration, toolCallView, toolKindSigils, toolLiveLines, toolStatusTone, } from "./core/tool-view.js";
|
|
22
23
|
export { assistantMessageVisible } from "./core/assistant-visibility.js";
|
|
23
24
|
export { disclosureOpen, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, } from "./core/tool-groups.js";
|
|
24
25
|
export { useClientActions } from "./client-contributions.js";
|
|
26
|
+
export { awaitingQueue, awaitingTakeover, decisionView, decisionViewText, initialDecisionState, reduceDecision, } from "./core/awaiting-answer.js";
|
|
27
|
+
export { useDecision } from "./use-decision.js";
|
|
28
|
+
export { useApprovalAwaiting } from "./use-approval-awaiting.js";
|
|
29
|
+
export { approvalCardCopy, approvalRefusal, askApproval, } from "./core/approval-decision.js";
|
|
25
30
|
export { placeClientTimeline, } from "./core/client-timeline.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { ParakeetProvider, useComposer, useStatus, useTimeline, useMarkdown, disclosureOpen, formatToolDuration, formatModelIdentity, formatModelWithLevel, formatContextUsage, formatTokenCount, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, } from "./headless.js";
|
|
2
2
|
export { Parakeet, ParakeetView } from "./parakeet.js";
|
|
3
|
+
export { ComposerModelKey, type ComposerModelKeyProps, } from "./components/ComposerModelKey.js";
|
|
4
|
+
export { composerSendState } from "./components/ComposerShell.js";
|
|
5
|
+
export { ComposerShell, useComposerTextareaSize, type ComposerShellProps, type ComposerShellRow, } from "./components/ComposerShell.js";
|
|
3
6
|
export type { ParakeetVisitor } from "./parakeet.js";
|
|
4
7
|
export { InteractionPanel, type InteractionPanelProps, } from "./components/InteractionPanel.js";
|
|
5
8
|
export type { QueuedRecallState, QueuedRecallOutcome, ParakeetAssistantMessageItem, ComposerController, ParakeetDraftCheckpoint, ParakeetDraftIdentity, ParakeetDraftStorage, ParakeetModel, ParakeetSession, ParakeetStatus, ParakeetTimelineItem, ParakeetToolArguments, ParakeetToolCallSection, ParakeetToolCallView, ParakeetToolDiffFile, ParakeetToolDiffHunk, ParakeetToolDiffLine, ParakeetToolDiffRow, ParakeetToolExcerptLine, ParakeetToolMatch, ParakeetToolOutputLine, ParakeetToolGroupItem, ParakeetToolItem, ParakeetToolKind, ToolDisclosureState, ParakeetUsage, ParakeetUserMessageItem, StatusController, TimelineController, MarkdownBlock, MarkdownInline, } from "./headless.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { ParakeetProvider, useComposer, useStatus, useTimeline, useMarkdown, disclosureOpen, formatToolDuration, formatModelIdentity, formatModelWithLevel, formatContextUsage, formatTokenCount, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, } from "./headless.js";
|
|
2
2
|
export { Parakeet, ParakeetView } from "./parakeet.js";
|
|
3
|
+
export { ComposerModelKey, } from "./components/ComposerModelKey.js";
|
|
4
|
+
export { composerSendState } from "./components/ComposerShell.js";
|
|
5
|
+
export { ComposerShell, useComposerTextareaSize, } from "./components/ComposerShell.js";
|
|
3
6
|
export { InteractionPanel, } from "./components/InteractionPanel.js";
|
|
4
7
|
export * from "./agent-head.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";
|
|
@@ -14,12 +15,11 @@ import { ClientRows } from "./components/ClientRows.js";
|
|
|
14
15
|
import { useClientActions } from "./client-contributions.js";
|
|
15
16
|
import { placeClientTimeline } from "./core/client-timeline.js";
|
|
16
17
|
import { InteractionPanel } from "./components/InteractionPanel.js";
|
|
17
|
-
import { WaitingNotice } from "./components/WaitingNotice.js";
|
|
18
18
|
import { useSlashCommands, } from "./commands/use-slash-commands.js";
|
|
19
19
|
import { TimelineItem } from "./components/TimelineItem.js";
|
|
20
20
|
import { MarkdownPolicyContext } from "./components/MarkdownRenderer.js";
|
|
21
21
|
/** Render the retained conversation surface within one Parakeet provider. */
|
|
22
|
-
export function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }) {
|
|
22
|
+
export function ParakeetView({ disambiguateAuthors, visitor, composerActionVariant, empty, commands, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, onLink, onOpen, }) {
|
|
23
23
|
const textareaRef = useRef(null);
|
|
24
24
|
const [ownCommands] = useState(() => createWhistle());
|
|
25
25
|
const slash = useSlashCommands({
|
|
@@ -31,6 +31,9 @@ export function ParakeetView({ disambiguateAuthors, visitor, composerActionVaria
|
|
|
31
31
|
});
|
|
32
32
|
const clientActions = useClientActions(commands ?? ownCommands);
|
|
33
33
|
const contributions = useClientContributions();
|
|
34
|
+
const { draft } = useComposer();
|
|
35
|
+
// The decision in the composer is not also a footer row.
|
|
36
|
+
const answering = awaitingTakeover(slash.awaiting, draft)?.key;
|
|
34
37
|
const timelineController = useTimeline();
|
|
35
38
|
const placed = useMemo(() => placeClientTimeline(contributions, timelineController.commandAnchors, timelineController.positionAnchors), [
|
|
36
39
|
contributions,
|
|
@@ -43,7 +46,11 @@ export function ParakeetView({ disambiguateAuthors, visitor, composerActionVaria
|
|
|
43
46
|
: null;
|
|
44
47
|
if (anchor instanceof HTMLAnchorElement && onLink?.(anchor.href))
|
|
45
48
|
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.
|
|
49
|
+
}, 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 }) => {
|
|
50
|
+
const value = {
|
|
51
|
+
...contribution,
|
|
52
|
+
panel: contribution.panel.filter((row) => JSON.stringify([entryId, row.id]) !== answering),
|
|
53
|
+
};
|
|
47
54
|
// An extension's retained-event notice and null-anchor rows
|
|
48
55
|
// join its own footer entry; one with no panel row here keeps
|
|
49
56
|
// none of this, rather than growing a section just to show it.
|
|
@@ -92,7 +99,7 @@ function ConversationInteraction({ slash, }) {
|
|
|
92
99
|
slash.store.close();
|
|
93
100
|
}, 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
101
|
}
|
|
95
|
-
function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focusAfterJump, empty, renderToolActions, renderAssistantAttachment, formatAssistantText, }) {
|
|
102
|
+
function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focusAfterJump, empty, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, }) {
|
|
96
103
|
const dismissFailed = useDismissFailedPrompt();
|
|
97
104
|
const timelineController = useTimeline();
|
|
98
105
|
const cancelQueued = useCallback((commandId) => {
|
|
@@ -160,7 +167,7 @@ function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focu
|
|
|
160
167
|
timelineController.jumpToLatest();
|
|
161
168
|
timeline.scrollToEnd({ behavior: "smooth" });
|
|
162
169
|
}, [timeline, timelineController]);
|
|
163
|
-
return (_jsxs("div", { className: "prose relative min-h-0 flex-1", children: [_jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "sr-only", children: sessionReadout(sessionStatus.status, sessionStatus.viewState) }), sessionStatus.observation.status === "unavailable" ? (_jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-1 text-xs text-dim", role: "status", children: [_jsx("span", { children: sessionStatus.observation.reason }), _jsx(
|
|
170
|
+
return (_jsxs("div", { className: "prose relative min-h-0 flex-1", children: [_jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "sr-only", children: sessionReadout(sessionStatus.status, sessionStatus.viewState) }), sessionStatus.observation.status === "unavailable" ? (_jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-1 text-xs text-dim", role: "status", children: [_jsx("span", { children: sessionStatus.observation.reason }), _jsx(Button, { variant: "outline", size: "xs", onClick: () => void sessionStatus.reconnect(), type: "button", children: "Reconnect" })] })) : null, _jsx("div", { className: "h-full min-h-0 overflow-y-auto", "data-chat-scroller": true, ref: scrollerRef, onScroll: (event) => {
|
|
164
171
|
const top = event.currentTarget.scrollTop;
|
|
165
172
|
if (previousScrollTop.current !== undefined &&
|
|
166
173
|
top < previousScrollTop.current)
|
|
@@ -209,24 +216,23 @@ function ConversationTimeline({ disambiguateAuthors, clientActions, onOpen, focu
|
|
|
209
216
|
item.author.name,
|
|
210
217
|
},
|
|
211
218
|
}
|
|
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));
|
|
219
|
+
: 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
220
|
}) })) : 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
221
|
}
|
|
215
|
-
/**
|
|
222
|
+
/** Independently contributed waiting controls; queued messages stay in the transcript. */
|
|
216
223
|
function ConversationWaiting({ clientActions, }) {
|
|
217
224
|
const { viewState } = useStatus();
|
|
218
225
|
const contributions = useClientContributions();
|
|
219
226
|
const extensionWaiting = viewState.kind === "idle"
|
|
220
227
|
? contributions.find(({ value }) => value.waiting !== null)
|
|
221
228
|
: undefined;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}, children: extensionWaiting.value.waiting.cancel.label })] })), _jsx(WaitingNotice, { waiting: waiting })] }));
|
|
229
|
+
return (_jsx(_Fragment, { children: extensionWaiting?.value.waiting === undefined ||
|
|
230
|
+
extensionWaiting.value.waiting === null ? null : (_jsxs("div", { className: "flex items-center gap-2 px-3 text-xs", children: [_jsx("span", { children: extensionWaiting.value.waiting.summary }), _jsx(Button, { size: "xs", variant: "outline", disabled: !clientActions.enabled ||
|
|
231
|
+
clientActions.state.get(extensionWaiting.value.waiting.cancel)
|
|
232
|
+
?.pending === true, onClick: () => {
|
|
233
|
+
if (extensionWaiting.value.waiting !== null)
|
|
234
|
+
void clientActions.execute(extensionWaiting.entryId, extensionWaiting.value.waiting.cancel, true);
|
|
235
|
+
}, children: extensionWaiting.value.waiting.cancel.label })] })) }));
|
|
230
236
|
}
|
|
231
237
|
function ConversationComposer({ visitor, textareaRef, composerActionVariant, slash, }) {
|
|
232
238
|
const composer = useComposer();
|
|
@@ -242,6 +248,7 @@ function ConversationComposer({ visitor, textareaRef, composerActionVariant, sla
|
|
|
242
248
|
}, [composer.cancel]);
|
|
243
249
|
const composerProps = {
|
|
244
250
|
queuedRecall: visitor === undefined ? composer : undefined,
|
|
251
|
+
onImagesChange: visitor === undefined ? composer.setImages : undefined,
|
|
245
252
|
statusChips: contributions
|
|
246
253
|
.flatMap(({ value }) => value.chips)
|
|
247
254
|
.sort((left, right) => left.order - right.order)
|
|
@@ -270,6 +277,6 @@ function ConversationComposer({ visitor, textareaRef, composerActionVariant, sla
|
|
|
270
277
|
return _jsx(ChatComposer, { ...composerProps });
|
|
271
278
|
}
|
|
272
279
|
/** 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 }) }) }));
|
|
280
|
+
export function Parakeet({ authorOf, disambiguateAuthors, visitor, markdownPolicy = "session", composerActionVariant, empty, session, clients, renderToolActions, claimsToolMedia, renderAssistantAttachment, formatAssistantText, commands, onLink, onOpen, }) {
|
|
281
|
+
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
282
|
}
|
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. */
|
|
@@ -101,6 +105,15 @@ export type ToolItem = Readonly<{
|
|
|
101
105
|
startedAt?: number;
|
|
102
106
|
/** Owner-confirmed activity or result; unknown when neither is available. */
|
|
103
107
|
status: "completed" | "error" | "running" | "unknown";
|
|
108
|
+
/** Replaceable display-only output, never part of the durable result. */
|
|
109
|
+
live?: Readonly<{
|
|
110
|
+
/** Neutral output lines. */
|
|
111
|
+
lines: readonly string[];
|
|
112
|
+
/** Raw producer bytes omitted before this tail. */
|
|
113
|
+
droppedBytes: number;
|
|
114
|
+
/** Owner-issued output revision. */
|
|
115
|
+
revision: number;
|
|
116
|
+
}>;
|
|
104
117
|
}>;
|
|
105
118
|
/**
|
|
106
119
|
* One maximal run of consecutive tool calls between conversation rows. A lone
|