@fungi.computer/parakeet 0.0.0-stage → 0.0.1
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/LICENSE +21 -0
- package/README.md +186 -2
- package/dist/account-commands.d.ts +102 -0
- package/dist/account-commands.js +239 -0
- package/dist/agent-head.d.ts +4 -0
- package/dist/agent-head.js +2 -0
- package/dist/client-contributions.d.ts +20 -0
- package/dist/client-contributions.js +41 -0
- package/dist/commands/advertised.d.ts +23 -0
- package/dist/commands/advertised.js +72 -0
- package/dist/commands/builtins.d.ts +14 -0
- package/dist/commands/builtins.js +91 -0
- package/dist/commands/hints.d.ts +36 -0
- package/dist/commands/hints.js +64 -0
- package/dist/commands/interactions.d.ts +55 -0
- package/dist/commands/interactions.js +101 -0
- package/dist/commands/run.d.ts +11 -0
- package/dist/commands/run.js +61 -0
- package/dist/commands/slash.d.ts +124 -0
- package/dist/commands/slash.js +182 -0
- package/dist/commands/use-slash-commands.d.ts +57 -0
- package/dist/commands/use-slash-commands.js +207 -0
- package/dist/components/AgentHead.d.ts +27 -0
- package/dist/components/AgentHead.js +53 -0
- package/dist/components/ChatComposer.d.ts +43 -0
- package/dist/components/ChatComposer.js +209 -0
- package/dist/components/ChatMessage.d.ts +8 -0
- package/dist/components/ChatMessage.js +16 -0
- package/dist/components/ClientRows.d.ts +11 -0
- package/dist/components/ClientRows.js +46 -0
- package/dist/components/CodeBlock.d.ts +11 -0
- package/dist/components/CodeBlock.js +38 -0
- package/dist/components/InteractionPanel.d.ts +15 -0
- package/dist/components/InteractionPanel.js +42 -0
- package/dist/components/MarkdownRenderer.d.ts +6 -0
- package/dist/components/MarkdownRenderer.js +48 -0
- package/dist/components/RunFailureNotice.d.ts +7 -0
- package/dist/components/RunFailureNotice.js +13 -0
- package/dist/components/ShiitakeAvatar.d.ts +19 -0
- package/dist/components/ShiitakeAvatar.js +20 -0
- package/dist/components/SlashMenu.d.ts +8 -0
- package/dist/components/SlashMenu.js +50 -0
- package/dist/components/ThinkingBlock.d.ts +3 -0
- package/dist/components/ThinkingBlock.js +18 -0
- package/dist/components/TimelineItem.d.ts +15 -0
- package/dist/components/TimelineItem.js +35 -0
- package/dist/components/ToolGroup.d.ts +12 -0
- package/dist/components/ToolGroup.js +90 -0
- package/dist/components/WaitingNotice.d.ts +7 -0
- package/dist/components/WaitingNotice.js +8 -0
- package/dist/components/avatar-presentation.d.ts +23 -0
- package/dist/components/avatar-presentation.js +16 -0
- package/dist/components/sprite-service.d.ts +2 -0
- package/dist/components/sprite-service.js +9 -0
- package/dist/components/still-frame-cache.d.ts +16 -0
- package/dist/components/still-frame-cache.js +63 -0
- package/dist/conversation.d.ts +164 -0
- package/dist/conversation.js +760 -0
- package/dist/core/assistant-visibility.d.ts +3 -0
- package/dist/core/assistant-visibility.js +4 -0
- package/dist/core/author-labels.d.ts +16 -0
- package/dist/core/author-labels.js +16 -0
- package/dist/core/build-timeline.d.ts +36 -0
- package/dist/core/build-timeline.js +328 -0
- package/dist/core/client-actions.d.ts +35 -0
- package/dist/core/client-actions.js +128 -0
- package/dist/core/client-contributions.d.ts +24 -0
- package/dist/core/client-contributions.js +115 -0
- package/dist/core/client-timeline.d.ts +33 -0
- package/dist/core/client-timeline.js +72 -0
- package/dist/core/format-context.d.ts +11 -0
- package/dist/core/format-context.js +20 -0
- package/dist/core/format-tokens.d.ts +2 -0
- package/dist/core/format-tokens.js +6 -0
- package/dist/core/model-identity.d.ts +3 -0
- package/dist/core/model-identity.js +7 -0
- package/dist/core/session-projection.d.ts +11 -0
- package/dist/core/session-projection.js +191 -0
- package/dist/core/session-query.d.ts +118 -0
- package/dist/core/session-query.js +187 -0
- package/dist/core/session-view-state.d.ts +66 -0
- package/dist/core/session-view-state.js +114 -0
- package/dist/core/tool-contract.d.ts +15 -0
- package/dist/core/tool-contract.js +3 -0
- package/dist/core/tool-groups.d.ts +36 -0
- package/dist/core/tool-groups.js +151 -0
- package/dist/core/tool-view.d.ts +182 -0
- package/dist/core/tool-view.js +618 -0
- package/dist/headless.d.ts +28 -0
- package/dist/headless.js +24 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +4 -0
- package/dist/lib/failure.d.ts +2 -0
- package/dist/lib/failure.js +9 -0
- package/dist/markdown.d.ts +3 -0
- package/dist/markdown.js +6 -0
- package/dist/model-commands.d.ts +44 -0
- package/dist/model-commands.js +232 -0
- package/dist/parakeet.d.ts +77 -0
- package/dist/parakeet.js +276 -0
- package/dist/provider-choices.d.ts +8 -0
- package/dist/provider-choices.js +43 -0
- package/dist/reload-command.d.ts +43 -0
- package/dist/reload-command.js +72 -0
- package/dist/session-commands.d.ts +53 -0
- package/dist/session-commands.js +259 -0
- package/dist/session.d.ts +24 -0
- package/dist/session.js +1 -0
- package/dist/store/types.d.ts +163 -0
- package/dist/store/types.js +1 -0
- package/dist/styles.css +19156 -0
- package/docs/api/README.md +15 -0
- package/docs/api/commands/slash.md +321 -0
- package/docs/api/headless.md +2510 -0
- package/docs/api/index.md +1253 -0
- package/package.json +79 -3
- package/src/styles.css +268 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ParakeetProvider, useComposer, useStatus, useTimeline, useMarkdown, disclosureOpen, formatToolDuration, formatModelIdentity, formatContextUsage, formatTokenCount, initialToolDisclosure, toggleAllDisclosure, toggleDisclosure, toolCallDefaultOpen, toolGroupDefaultOpen, visibleToolCalls, } from "./headless.js";
|
|
2
|
+
export { Parakeet, ParakeetView } from "./parakeet.js";
|
|
3
|
+
export { InteractionPanel, } from "./components/InteractionPanel.js";
|
|
4
|
+
export * from "./agent-head.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as Redacted from "effect/Redacted";
|
|
2
|
+
/** Report an operation failure without exposing Session or tool contents. */
|
|
3
|
+
export function reportFailure(operation, cause) {
|
|
4
|
+
console.error(JSON.stringify({
|
|
5
|
+
event: "parakeet_operation_failed",
|
|
6
|
+
operation,
|
|
7
|
+
causeKind: cause instanceof Error ? "error" : "non_error",
|
|
8
|
+
}), Redacted.make(cause));
|
|
9
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { BlockNode as MarkdownBlock, InlineNode as MarkdownInline, } from "@tanstack/markdown";
|
|
2
|
+
/** Parse chat Markdown for headless hosts, including terminal presentation. */
|
|
3
|
+
export declare function useMarkdown(content: string): import("@tanstack/markdown").MarkdownDocument;
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { parseMarkdown } from "@tanstack/markdown/parser";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
/** Parse chat Markdown for headless hosts, including terminal presentation. */
|
|
4
|
+
export function useMarkdown(content) {
|
|
5
|
+
return useMemo(() => parseMarkdown(content, { allowHtml: false, frontmatter: false }), [content]);
|
|
6
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ModelPreference } from "@fungi.computer/shiitake/model-preference";
|
|
2
|
+
import { type WhistleAvailability, type WhistleRuntime, type WhistleContribution } from "@fungi.computer/whistle";
|
|
3
|
+
import { type ModelAccountContext } from "./account-commands.js";
|
|
4
|
+
/** A host's maintained catalog projection; no credentials or provider execution. */
|
|
5
|
+
export type SessionModelChoice = Readonly<{
|
|
6
|
+
/** Stable provider identity used in a Session preference. */
|
|
7
|
+
providerId: string;
|
|
8
|
+
/** Provider label displayed by clients. */
|
|
9
|
+
providerName: string;
|
|
10
|
+
/** Model identity within this provider. */
|
|
11
|
+
id: string;
|
|
12
|
+
/** Human-facing model label. */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Thinking levels supported by this catalog entry. */
|
|
15
|
+
reasoning: readonly NonNullable<ModelPreference["reasoning"]>[];
|
|
16
|
+
}>;
|
|
17
|
+
export type ModelPreferenceOwner = Readonly<{
|
|
18
|
+
modelPreference: Readonly<{
|
|
19
|
+
read: () => Promise<ModelPreference | null>;
|
|
20
|
+
set: (preference: ModelPreference | null) => Promise<void>;
|
|
21
|
+
}>;
|
|
22
|
+
}>;
|
|
23
|
+
/** Contribution identity, catalog and optional local model-picker presentation. */
|
|
24
|
+
export type SessionModelCommandOptions = Readonly<{
|
|
25
|
+
/** Shared credential owner and policy for the interactive provider flow. */
|
|
26
|
+
account: ModelAccountContext;
|
|
27
|
+
/** Host source that owns the contribution lease. */
|
|
28
|
+
sourceId: string;
|
|
29
|
+
/** Namespace for the semantic model command. */
|
|
30
|
+
namespace: string;
|
|
31
|
+
/** Catalog used to describe and validate explicit selections. */
|
|
32
|
+
models: readonly SessionModelChoice[];
|
|
33
|
+
/** Read the live catalog after interactive provider sign-in. */
|
|
34
|
+
refreshModels: (signal: AbortSignal) => Promise<readonly SessionModelChoice[]>;
|
|
35
|
+
/** Current semantic availability, checked again before dispatch. */
|
|
36
|
+
availability?: () => WhistleAvailability;
|
|
37
|
+
}>;
|
|
38
|
+
/** Describe and invoke the ordinary model-preference owner from any client. */
|
|
39
|
+
export declare function sessionModelCommandDefinitions(session: ModelPreferenceOwner, options: SessionModelCommandOptions): WhistleContribution["commands"];
|
|
40
|
+
/** Contribute one model action; owners may update its definitions through the lease. */
|
|
41
|
+
export declare function contributeModelCommands(commands: Pick<WhistleRuntime, "contribute">, session: ModelPreferenceOwner, options: SessionModelCommandOptions): Readonly<{
|
|
42
|
+
update: (commands: WhistleContribution["commands"]) => void;
|
|
43
|
+
dispose: () => void;
|
|
44
|
+
}>;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { modelPreferenceJsonSchema, parseModelPreference, } from "@fungi.computer/shiitake/model-preference";
|
|
2
|
+
import { WhistleActionError, } from "@fungi.computer/whistle";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { loginRegistry, signInProvider, } from "./account-commands.js";
|
|
5
|
+
import { providerChoices } from "./provider-choices.js";
|
|
6
|
+
const defaultChoice = "default";
|
|
7
|
+
function modelLabel(model) {
|
|
8
|
+
return `${model.providerName} · ${model.name}`;
|
|
9
|
+
}
|
|
10
|
+
/** Current model first, then providers and models by name; no provider is favoured. */
|
|
11
|
+
function orderModels(models, current) {
|
|
12
|
+
return [...models].sort((left, right) => {
|
|
13
|
+
const leftCurrent = left.id === current?.modelId && left.providerId === current.providerId;
|
|
14
|
+
const rightCurrent = right.id === current?.modelId && right.providerId === current.providerId;
|
|
15
|
+
if (leftCurrent !== rightCurrent)
|
|
16
|
+
return leftCurrent ? -1 : 1;
|
|
17
|
+
return (left.providerName.localeCompare(right.providerName) ||
|
|
18
|
+
left.name.localeCompare(right.name));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function chooseReasoning(interaction, model, current) {
|
|
22
|
+
if (model.reasoning.length === 0)
|
|
23
|
+
return undefined;
|
|
24
|
+
const answer = await interaction.prompt({
|
|
25
|
+
type: "choice",
|
|
26
|
+
message: `Thinking level for ${model.name}`,
|
|
27
|
+
options: [
|
|
28
|
+
{ value: defaultChoice, label: "Model default" },
|
|
29
|
+
...model.reasoning.map((level) => ({
|
|
30
|
+
value: level,
|
|
31
|
+
label: level === current ? `${level} (current)` : level,
|
|
32
|
+
})),
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
return model.reasoning.find((level) => level === answer);
|
|
36
|
+
}
|
|
37
|
+
/** Leave one Whistle option for inheriting the Agent model. */
|
|
38
|
+
const maximumModelOptions = 255;
|
|
39
|
+
async function chooseProviderModels(interaction, models, account, refreshModels) {
|
|
40
|
+
const { owner } = account;
|
|
41
|
+
const [access, registry] = await Promise.all([
|
|
42
|
+
owner.access(interaction.signal),
|
|
43
|
+
owner
|
|
44
|
+
.providers(interaction.signal)
|
|
45
|
+
.then((providers) => loginRegistry(providers, account)),
|
|
46
|
+
]);
|
|
47
|
+
// The default is discoverable before its authenticated catalog exists.
|
|
48
|
+
const providers = registry.filter((provider) => provider.id === "fungi");
|
|
49
|
+
for (const model of new Map(models.map((model) => [model.providerId, model])).values()) {
|
|
50
|
+
const provider = registry.find((candidate) => candidate.id === model.providerId);
|
|
51
|
+
if (providers.some((candidate) => candidate.id === model.providerId))
|
|
52
|
+
continue;
|
|
53
|
+
if (provider)
|
|
54
|
+
providers.push(provider);
|
|
55
|
+
else if (access.some((candidate) => candidate.providerId === model.providerId &&
|
|
56
|
+
account.policy.loginAllowed({
|
|
57
|
+
providerId: candidate.providerId,
|
|
58
|
+
method: candidate.type === "oauth" ? "subscription" : "api_key",
|
|
59
|
+
host: account.host,
|
|
60
|
+
scope: account.scope,
|
|
61
|
+
})))
|
|
62
|
+
providers.push({
|
|
63
|
+
id: model.providerId,
|
|
64
|
+
name: model.providerName,
|
|
65
|
+
methods: [],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const providerId = await interaction.prompt({
|
|
69
|
+
type: "choice",
|
|
70
|
+
message: "Model",
|
|
71
|
+
collapsedGroup: "More providers",
|
|
72
|
+
options: [
|
|
73
|
+
{ value: defaultChoice, label: "Use agent model" },
|
|
74
|
+
...providerChoices(providers, access, owner.popularProviderIds, "model").slice(0, maximumModelOptions),
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
if (providerId === defaultChoice)
|
|
78
|
+
return null;
|
|
79
|
+
const provider = providers.find((candidate) => candidate.id === providerId);
|
|
80
|
+
if (!provider)
|
|
81
|
+
throw new WhistleActionError("provider_unavailable", "Choose a listed provider.");
|
|
82
|
+
let catalog = models;
|
|
83
|
+
if (!access.some((candidate) => candidate.providerId === providerId)) {
|
|
84
|
+
await signInProvider(owner, provider, interaction);
|
|
85
|
+
catalog = await refreshModels(interaction.signal);
|
|
86
|
+
}
|
|
87
|
+
const selectedModels = catalog
|
|
88
|
+
.filter((model) => model.providerId === providerId)
|
|
89
|
+
.slice(0, maximumModelOptions);
|
|
90
|
+
if (selectedModels.length === 0)
|
|
91
|
+
throw new WhistleActionError("model_unavailable", `${provider.name} has no available models. Retry /model.`);
|
|
92
|
+
return selectedModels;
|
|
93
|
+
}
|
|
94
|
+
/** Describe and invoke the ordinary model-preference owner from any client. */
|
|
95
|
+
export function sessionModelCommandDefinitions(session, options) {
|
|
96
|
+
const preferenceSchema = z
|
|
97
|
+
.record(z.string(), z.json())
|
|
98
|
+
.parse(modelPreferenceJsonSchema);
|
|
99
|
+
const knownChoices = options.models.map((model) => ({
|
|
100
|
+
title: `${model.providerName} · ${model.name}`,
|
|
101
|
+
properties: {
|
|
102
|
+
providerId: { const: model.providerId },
|
|
103
|
+
modelId: { const: model.id },
|
|
104
|
+
reasoning: model.reasoning.length === 0 ? false : { enum: [...model.reasoning] },
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
const selectionSchema = knownChoices.length === 0
|
|
108
|
+
? { not: {} }
|
|
109
|
+
: { allOf: [preferenceSchema, { oneOf: knownChoices }] };
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
id: "model",
|
|
113
|
+
title: "Model",
|
|
114
|
+
category: "Settings",
|
|
115
|
+
description: "Choose a model",
|
|
116
|
+
projections: {
|
|
117
|
+
agent: {},
|
|
118
|
+
palette: {},
|
|
119
|
+
help: {},
|
|
120
|
+
slash: { aliases: ["model"] },
|
|
121
|
+
},
|
|
122
|
+
action: {
|
|
123
|
+
inputSchema: {
|
|
124
|
+
anyOf: [{ type: "null", title: "Use agent model" }, selectionSchema],
|
|
125
|
+
},
|
|
126
|
+
outputSchema: { anyOf: [{ type: "null" }, preferenceSchema] },
|
|
127
|
+
},
|
|
128
|
+
availability: options.availability ?? (() => ({ status: "available" })),
|
|
129
|
+
handler: async (input) => {
|
|
130
|
+
if (input.arguments === undefined) {
|
|
131
|
+
const interaction = input.interaction;
|
|
132
|
+
if (input.origin === "agent" || interaction === undefined)
|
|
133
|
+
return session.modelPreference.read();
|
|
134
|
+
const current = await session.modelPreference.read();
|
|
135
|
+
const ordered = await chooseProviderModels(interaction, orderModels(options.models, current), options.account, options.refreshModels);
|
|
136
|
+
if (ordered === null) {
|
|
137
|
+
await session.modelPreference.set(null);
|
|
138
|
+
return session.modelPreference.read();
|
|
139
|
+
}
|
|
140
|
+
const answer = await interaction.prompt({
|
|
141
|
+
type: "choice",
|
|
142
|
+
message: "Model",
|
|
143
|
+
options: [
|
|
144
|
+
{ value: defaultChoice, label: "Use agent model" },
|
|
145
|
+
...ordered.map((model, index) => ({
|
|
146
|
+
value: String(index),
|
|
147
|
+
label: model.providerId === current?.providerId &&
|
|
148
|
+
model.id === current.modelId
|
|
149
|
+
? `${modelLabel(model)} (current)`
|
|
150
|
+
: modelLabel(model),
|
|
151
|
+
})),
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
const model = answer === defaultChoice ? undefined : ordered[Number(answer)];
|
|
155
|
+
let chosen = null;
|
|
156
|
+
if (model !== undefined) {
|
|
157
|
+
const reasoning = await chooseReasoning(interaction, model, current?.reasoning);
|
|
158
|
+
chosen =
|
|
159
|
+
reasoning === undefined
|
|
160
|
+
? { providerId: model.providerId, modelId: model.id }
|
|
161
|
+
: {
|
|
162
|
+
providerId: model.providerId,
|
|
163
|
+
modelId: model.id,
|
|
164
|
+
reasoning,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
await session.modelPreference.set(chosen);
|
|
168
|
+
// The mounted owner's effective-model label confirms the choice.
|
|
169
|
+
// A success notice would keep the choice dialog focused until Esc.
|
|
170
|
+
return session.modelPreference.read();
|
|
171
|
+
}
|
|
172
|
+
let preference;
|
|
173
|
+
try {
|
|
174
|
+
preference = parseModelPreference(input.arguments);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
throw new WhistleActionError("invalid_model_preference", "Model preference arguments are invalid");
|
|
178
|
+
}
|
|
179
|
+
if (preference !== null) {
|
|
180
|
+
const selected = preference;
|
|
181
|
+
const model = options.models.find((choice) => choice.providerId === selected.providerId &&
|
|
182
|
+
choice.id === selected.modelId);
|
|
183
|
+
if (model === undefined)
|
|
184
|
+
throw new WhistleActionError("model_unavailable", "That model is not in the current catalog");
|
|
185
|
+
if (selected.reasoning !== undefined &&
|
|
186
|
+
!model.reasoning.includes(selected.reasoning))
|
|
187
|
+
throw new WhistleActionError("reasoning_unavailable", "That thinking level is not supported by this model");
|
|
188
|
+
}
|
|
189
|
+
await session.modelPreference.set(preference);
|
|
190
|
+
return session.modelPreference.read();
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: "thinking",
|
|
195
|
+
title: "Thinking level",
|
|
196
|
+
category: "Settings",
|
|
197
|
+
description: "Choose thinking effort",
|
|
198
|
+
projections: {
|
|
199
|
+
palette: { order: 1 },
|
|
200
|
+
help: {},
|
|
201
|
+
slash: { aliases: ["thinking"] },
|
|
202
|
+
},
|
|
203
|
+
availability: options.availability ?? (() => ({ status: "available" })),
|
|
204
|
+
handler: async (input) => {
|
|
205
|
+
const interaction = input.interaction;
|
|
206
|
+
if (interaction === undefined)
|
|
207
|
+
throw new WhistleActionError("interaction_required", "Choosing a thinking level needs a person.");
|
|
208
|
+
const current = await session.modelPreference.read();
|
|
209
|
+
const model = options.models.find((choice) => choice.providerId === current?.providerId &&
|
|
210
|
+
choice.id === current.modelId);
|
|
211
|
+
if (current === null || model === undefined)
|
|
212
|
+
throw new WhistleActionError("model_required", "Choose a model with /model before its thinking level.");
|
|
213
|
+
if (model.reasoning.length === 0)
|
|
214
|
+
throw new WhistleActionError("reasoning_unavailable", `${model.name} has no thinking levels.`);
|
|
215
|
+
const reasoning = await chooseReasoning(interaction, model, current.reasoning);
|
|
216
|
+
const chosen = reasoning === undefined
|
|
217
|
+
? { providerId: model.providerId, modelId: model.id }
|
|
218
|
+
: { providerId: model.providerId, modelId: model.id, reasoning };
|
|
219
|
+
await session.modelPreference.set(chosen);
|
|
220
|
+
return session.modelPreference.read();
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
/** Contribute one model action; owners may update its definitions through the lease. */
|
|
226
|
+
export function contributeModelCommands(commands, session, options) {
|
|
227
|
+
return commands.contribute({
|
|
228
|
+
sourceId: options.sourceId,
|
|
229
|
+
namespace: options.namespace,
|
|
230
|
+
commands: sessionModelCommandDefinitions(session, options),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ClientEntryV1 } from "@fungi.computer/shiitake/client-entry";
|
|
2
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
3
|
+
import { type ParakeetAuthorOf } from "./core/author-labels.js";
|
|
4
|
+
import type { ToolItem } from "./store/types.js";
|
|
5
|
+
import type { ParakeetSession } from "./session.js";
|
|
6
|
+
import type { RowV1 } from "@fungi.computer/gills";
|
|
7
|
+
import { type ParakeetCommandRuntime } from "./commands/use-slash-commands.js";
|
|
8
|
+
/** Public composer options for an anonymous visitor conversation. */
|
|
9
|
+
export type ParakeetVisitor = Readonly<{
|
|
10
|
+
/** Agent display name used by the visitor's composer. */
|
|
11
|
+
agentName: string;
|
|
12
|
+
}>;
|
|
13
|
+
/** Props for the standalone retained conversation surface. */
|
|
14
|
+
export type ParakeetProps = Readonly<{
|
|
15
|
+
/** Show short identity suffixes for same-named authors; never in visitor mode. */
|
|
16
|
+
disambiguateAuthors?: boolean | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Read the author to show from a message's opaque host metadata. Absent,
|
|
19
|
+
* lines show no author.
|
|
20
|
+
*/
|
|
21
|
+
authorOf?: ParakeetAuthorOf | undefined;
|
|
22
|
+
/** Visitor mode hides internal readouts and disables slash commands. */
|
|
23
|
+
visitor?: ParakeetVisitor | undefined;
|
|
24
|
+
/** Visitor conversations render Markdown without loading images or unsafe links. */
|
|
25
|
+
markdownPolicy?: "session" | "visitor";
|
|
26
|
+
/** The typed Session client observed by the conversation surface. */
|
|
27
|
+
session: ParakeetSession;
|
|
28
|
+
/** Client entries selected by the host's composition root. */
|
|
29
|
+
clients?: readonly ClientEntryV1[] | undefined;
|
|
30
|
+
/** Optional Caps action style for a host-specific quieter composer. */
|
|
31
|
+
composerActionVariant?: "primary" | "outline" | undefined;
|
|
32
|
+
/** Optional caller-owned actions for a completed tool result. */
|
|
33
|
+
renderToolActions?: ((item: ToolItem) => ReactNode) | undefined;
|
|
34
|
+
/** Optional caller-owned attachment below a settled assistant reply. */
|
|
35
|
+
renderAssistantAttachment?: ((text: string) => ReactNode) | undefined;
|
|
36
|
+
/** Optional display text; attachments still receive the original reply. */
|
|
37
|
+
formatAssistantText?: ((text: string) => string) | undefined;
|
|
38
|
+
/** Host navigation for transcript links; true prevents browser navigation. */
|
|
39
|
+
onLink?: ((href: string) => boolean) | undefined;
|
|
40
|
+
/** Authorize and open a typed target through the host's navigation owner. */
|
|
41
|
+
onOpen?: ((target: NonNullable<RowV1["open"]>) => void) | undefined;
|
|
42
|
+
/** Optional caller-owned empty conversation state. */
|
|
43
|
+
empty?: ReactNode | undefined;
|
|
44
|
+
/** Optional host Whistle runtime; Parakeet makes its own when omitted. */
|
|
45
|
+
commands?: ParakeetCommandRuntime | undefined;
|
|
46
|
+
}>;
|
|
47
|
+
/** Props for the reusable retained conversation view. */
|
|
48
|
+
export type ParakeetViewProps = Readonly<{
|
|
49
|
+
/** Show short identity suffixes for same-named authors; never in visitor mode. */
|
|
50
|
+
disambiguateAuthors?: boolean | undefined;
|
|
51
|
+
/** Visitor mode hides internal readouts and disables slash commands. */
|
|
52
|
+
visitor?: ParakeetVisitor | undefined;
|
|
53
|
+
/** Optional Caps action style for a host-specific quieter composer. */
|
|
54
|
+
composerActionVariant?: "primary" | "outline" | undefined;
|
|
55
|
+
/** Optional caller-owned actions for a completed tool result. */
|
|
56
|
+
renderToolActions?: ((item: ToolItem) => ReactNode) | undefined;
|
|
57
|
+
/** Optional caller-owned attachment below a settled assistant reply. */
|
|
58
|
+
renderAssistantAttachment?: ((text: string) => ReactNode) | undefined;
|
|
59
|
+
/** Optional display text; attachments still receive the original reply. */
|
|
60
|
+
formatAssistantText?: ((text: string) => string) | undefined;
|
|
61
|
+
/** Host navigation for transcript links; true prevents browser navigation. */
|
|
62
|
+
onLink?: ((href: string) => boolean) | undefined;
|
|
63
|
+
/** Authorize and open a typed target through the host's navigation owner. */
|
|
64
|
+
onOpen?: ((target: NonNullable<RowV1["open"]>) => void) | undefined;
|
|
65
|
+
/** Optional caller-owned empty conversation state. */
|
|
66
|
+
empty?: ReactNode | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Optional host Whistle runtime holding the host's own commands. Parakeet
|
|
69
|
+
* adds its built-ins and the Session's advertised commands to it, and makes
|
|
70
|
+
* a private runtime when this is omitted.
|
|
71
|
+
*/
|
|
72
|
+
commands?: ParakeetCommandRuntime | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
/** 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;
|
|
76
|
+
/** 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;
|