@slices.sh/ai-chat 0.1.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/LICENSE +21 -0
- package/dist/exports.json +794 -0
- package/dist/fixture/fixture-approval.d.ts +4 -0
- package/dist/fixture/fixture-approval.js +59 -0
- package/dist/fixture/fixture-artifacts.d.ts +2 -0
- package/dist/fixture/fixture-artifacts.js +48 -0
- package/dist/fixture/fixture-question.d.ts +5 -0
- package/dist/fixture/fixture-question.js +93 -0
- package/dist/fixture/fixture-script.d.ts +35 -0
- package/dist/fixture/fixture-script.js +280 -0
- package/dist/fixture/fixture-selection.d.ts +5 -0
- package/dist/fixture/fixture-selection.js +20 -0
- package/dist/fixture/fixture.d.ts +20 -0
- package/dist/fixture/fixture.js +75 -0
- package/dist/fixture/provider.d.ts +15 -0
- package/dist/fixture/provider.js +14 -0
- package/dist/headless/always-allow.d.ts +2 -0
- package/dist/headless/always-allow.js +24 -0
- package/dist/headless/answer.d.ts +6 -0
- package/dist/headless/answer.js +29 -0
- package/dist/headless/approval-error.d.ts +2 -0
- package/dist/headless/approval-error.js +16 -0
- package/dist/headless/approval-reason.d.ts +2 -0
- package/dist/headless/approval-reason.js +13 -0
- package/dist/headless/approval-receipt.d.ts +4 -0
- package/dist/headless/approval-receipt.js +13 -0
- package/dist/headless/approve.d.ts +4 -0
- package/dist/headless/approve.js +15 -0
- package/dist/headless/branch-navigation.d.ts +2 -0
- package/dist/headless/branch-navigation.js +11 -0
- package/dist/headless/branch-next.d.ts +2 -0
- package/dist/headless/branch-next.js +21 -0
- package/dist/headless/branch-page.d.ts +5 -0
- package/dist/headless/branch-page.js +13 -0
- package/dist/headless/branch-previous.d.ts +2 -0
- package/dist/headless/branch-previous.js +21 -0
- package/dist/headless/cancel-edit.d.ts +2 -0
- package/dist/headless/cancel-edit.js +10 -0
- package/dist/headless/cancel-queue-edit.d.ts +2 -0
- package/dist/headless/cancel-queue-edit.js +15 -0
- package/dist/headless/cancel-queued.d.ts +2 -0
- package/dist/headless/cancel-queued.js +15 -0
- package/dist/headless/chat-dictation/confirm.d.ts +2 -0
- package/dist/headless/chat-dictation/confirm.js +14 -0
- package/dist/headless/chat-dictation/index.d.ts +12 -0
- package/dist/headless/chat-dictation/index.js +9 -0
- package/dist/headless/chat-dictation/input.d.ts +3 -0
- package/dist/headless/chat-dictation/input.js +42 -0
- package/dist/headless/chat-dictation/root.d.ts +3 -0
- package/dist/headless/chat-dictation/root.js +42 -0
- package/dist/headless/chat-dictation/text.d.ts +3 -0
- package/dist/headless/chat-dictation/text.js +14 -0
- package/dist/headless/chat-dictation/voice.d.ts +3 -0
- package/dist/headless/chat-dictation/voice.js +35 -0
- package/dist/headless/citation-content.d.ts +3 -0
- package/dist/headless/citation-content.js +19 -0
- package/dist/headless/citation-description.d.ts +2 -0
- package/dist/headless/citation-description.js +12 -0
- package/dist/headless/citation-root.d.ts +2 -0
- package/dist/headless/citation-root.js +13 -0
- package/dist/headless/citation-title.d.ts +2 -0
- package/dist/headless/citation-title.js +12 -0
- package/dist/headless/citation-trigger.d.ts +2 -0
- package/dist/headless/citation-trigger.js +12 -0
- package/dist/headless/clear-answer.d.ts +5 -0
- package/dist/headless/clear-answer.js +19 -0
- package/dist/headless/composer-root.d.ts +14 -0
- package/dist/headless/composer-root.js +12 -0
- package/dist/headless/composer-standalone.d.ts +3 -0
- package/dist/headless/composer-standalone.js +10 -0
- package/dist/headless/composer.d.ts +3 -0
- package/dist/headless/composer.js +24 -0
- package/dist/headless/context-usage.d.ts +3 -0
- package/dist/headless/context-usage.js +13 -0
- package/dist/headless/contexts.d.ts +77 -0
- package/dist/headless/contexts.js +53 -0
- package/dist/headless/continue.d.ts +4 -0
- package/dist/headless/continue.js +26 -0
- package/dist/headless/copy.d.ts +11 -0
- package/dist/headless/copy.js +21 -0
- package/dist/headless/deny.d.ts +4 -0
- package/dist/headless/deny.js +15 -0
- package/dist/headless/edit-queued.d.ts +2 -0
- package/dist/headless/edit-queued.js +15 -0
- package/dist/headless/edit.d.ts +2 -0
- package/dist/headless/edit.js +17 -0
- package/dist/headless/edited-attachments.d.ts +5 -0
- package/dist/headless/edited-attachments.js +11 -0
- package/dist/headless/edited-input.d.ts +2 -0
- package/dist/headless/edited-input.js +28 -0
- package/dist/headless/empty.d.ts +3 -0
- package/dist/headless/empty.js +12 -0
- package/dist/headless/failed.d.ts +15 -0
- package/dist/headless/failed.js +17 -0
- package/dist/headless/feedback-error.d.ts +2 -0
- package/dist/headless/feedback-error.js +11 -0
- package/dist/headless/feedback-root.d.ts +2 -0
- package/dist/headless/feedback-root.js +24 -0
- package/dist/headless/feedback.d.ts +4 -0
- package/dist/headless/feedback.js +18 -0
- package/dist/headless/file-audio.d.ts +2 -0
- package/dist/headless/file-audio.js +16 -0
- package/dist/headless/file-context.d.ts +4 -0
- package/dist/headless/file-context.js +7 -0
- package/dist/headless/file-img.d.ts +2 -0
- package/dist/headless/file-img.js +21 -0
- package/dist/headless/file-kind-gate.d.ts +5 -0
- package/dist/headless/file-kind-gate.js +11 -0
- package/dist/headless/file-link.d.ts +3 -0
- package/dist/headless/file-link.js +14 -0
- package/dist/headless/file-root.d.ts +5 -0
- package/dist/headless/file-root.js +13 -0
- package/dist/headless/file-unavailable.d.ts +2 -0
- package/dist/headless/file-unavailable.js +12 -0
- package/dist/headless/file-video.d.ts +2 -0
- package/dist/headless/file-video.js +16 -0
- package/dist/headless/follow-ups.d.ts +5 -0
- package/dist/headless/follow-ups.js +20 -0
- package/dist/headless/forget-approval.d.ts +2 -0
- package/dist/headless/forget-approval.js +21 -0
- package/dist/headless/gate-content.d.ts +2 -0
- package/dist/headless/gate-content.js +6 -0
- package/dist/headless/index.d.ts +249 -0
- package/dist/headless/index.js +251 -0
- package/dist/headless/input.d.ts +11 -0
- package/dist/headless/input.js +18 -0
- package/dist/headless/jump-to-latest.d.ts +3 -0
- package/dist/headless/jump-to-latest.js +14 -0
- package/dist/headless/message-edit-root.d.ts +2 -0
- package/dist/headless/message-edit-root.js +13 -0
- package/dist/headless/message-editing.d.ts +2 -0
- package/dist/headless/message-editing.js +10 -0
- package/dist/headless/message-editor.d.ts +2 -0
- package/dist/headless/message-editor.js +19 -0
- package/dist/headless/message-footer.d.ts +3 -0
- package/dist/headless/message-footer.js +15 -0
- package/dist/headless/message-reading.d.ts +2 -0
- package/dist/headless/message-reading.js +10 -0
- package/dist/headless/message.d.ts +11 -0
- package/dist/headless/message.js +34 -0
- package/dist/headless/messages.d.ts +9 -0
- package/dist/headless/messages.js +19 -0
- package/dist/headless/model-picker.d.ts +2 -0
- package/dist/headless/model-picker.js +14 -0
- package/dist/headless/model.d.ts +4 -0
- package/dist/headless/model.js +13 -0
- package/dist/headless/models.d.ts +5 -0
- package/dist/headless/models.js +11 -0
- package/dist/headless/optional-tools.d.ts +7 -0
- package/dist/headless/optional-tools.js +12 -0
- package/dist/headless/other-answer.d.ts +5 -0
- package/dist/headless/other-answer.js +32 -0
- package/dist/headless/part-approval.d.ts +2 -0
- package/dist/headless/part-approval.js +33 -0
- package/dist/headless/part-file.d.ts +6 -0
- package/dist/headless/part-file.js +11 -0
- package/dist/headless/part-question.d.ts +2 -0
- package/dist/headless/part-question.js +57 -0
- package/dist/headless/part-reasoning.d.ts +15 -0
- package/dist/headless/part-reasoning.js +26 -0
- package/dist/headless/part-source.d.ts +5 -0
- package/dist/headless/part-source.js +20 -0
- package/dist/headless/part-text.d.ts +16 -0
- package/dist/headless/part-text.js +29 -0
- package/dist/headless/part-tool.d.ts +16 -0
- package/dist/headless/part-tool.js +14 -0
- package/dist/headless/parts.d.ts +11 -0
- package/dist/headless/parts.js +11 -0
- package/dist/headless/question-back.d.ts +2 -0
- package/dist/headless/question-back.js +16 -0
- package/dist/headless/question-error.d.ts +2 -0
- package/dist/headless/question-error.js +14 -0
- package/dist/headless/question-invalid.d.ts +8 -0
- package/dist/headless/question-invalid.js +18 -0
- package/dist/headless/question-item.d.ts +8 -0
- package/dist/headless/question-item.js +51 -0
- package/dist/headless/question-next.d.ts +3 -0
- package/dist/headless/question-next.js +16 -0
- package/dist/headless/question-other.d.ts +5 -0
- package/dist/headless/question-other.js +22 -0
- package/dist/headless/question-progress.d.ts +8 -0
- package/dist/headless/question-progress.js +14 -0
- package/dist/headless/question-receipt.d.ts +11 -0
- package/dist/headless/question-receipt.js +29 -0
- package/dist/headless/questions.d.ts +3 -0
- package/dist/headless/questions.js +13 -0
- package/dist/headless/queue-editing.d.ts +4 -0
- package/dist/headless/queue-editing.js +11 -0
- package/dist/headless/queue-item.d.ts +2 -0
- package/dist/headless/queue-item.js +10 -0
- package/dist/headless/queue-items.d.ts +2 -0
- package/dist/headless/queue-items.js +11 -0
- package/dist/headless/queue-preview.d.ts +6 -0
- package/dist/headless/queue-preview.js +11 -0
- package/dist/headless/queued-input.d.ts +2 -0
- package/dist/headless/queued-input.js +27 -0
- package/dist/headless/queued.d.ts +17 -0
- package/dist/headless/queued.js +16 -0
- package/dist/headless/read-aloud.d.ts +5 -0
- package/dist/headless/read-aloud.js +19 -0
- package/dist/headless/reasoning-disclosure.d.ts +3 -0
- package/dist/headless/reasoning-disclosure.js +17 -0
- package/dist/headless/reasoning-timer.d.ts +5 -0
- package/dist/headless/reasoning-timer.js +13 -0
- package/dist/headless/references.d.ts +6 -0
- package/dist/headless/references.js +13 -0
- package/dist/headless/regenerate.d.ts +3 -0
- package/dist/headless/regenerate.js +22 -0
- package/dist/headless/remembered-approval.d.ts +2 -0
- package/dist/headless/remembered-approval.js +14 -0
- package/dist/headless/root.d.ts +30 -0
- package/dist/headless/root.js +99 -0
- package/dist/headless/save-edit.d.ts +2 -0
- package/dist/headless/save-edit.js +16 -0
- package/dist/headless/save-queued.d.ts +2 -0
- package/dist/headless/save-queued.js +15 -0
- package/dist/headless/send-now.d.ts +2 -0
- package/dist/headless/send-now.js +17 -0
- package/dist/headless/settings.d.ts +2 -0
- package/dist/headless/settings.js +10 -0
- package/dist/headless/skip-questions.d.ts +6 -0
- package/dist/headless/skip-questions.js +18 -0
- package/dist/headless/source-context.d.ts +5 -0
- package/dist/headless/source-context.js +9 -0
- package/dist/headless/source-link.d.ts +2 -0
- package/dist/headless/source-link.js +13 -0
- package/dist/headless/source-primitives.d.ts +1 -0
- package/dist/headless/source-primitives.js +7 -0
- package/dist/headless/source-root.d.ts +5 -0
- package/dist/headless/source-root.js +9 -0
- package/dist/headless/source-sheet-close.d.ts +2 -0
- package/dist/headless/source-sheet-close.js +12 -0
- package/dist/headless/source-sheet-content.d.ts +3 -0
- package/dist/headless/source-sheet-content.js +16 -0
- package/dist/headless/source-sheet-description.d.ts +2 -0
- package/dist/headless/source-sheet-description.js +12 -0
- package/dist/headless/source-sheet-root.d.ts +2 -0
- package/dist/headless/source-sheet-root.js +13 -0
- package/dist/headless/source-sheet-title.d.ts +2 -0
- package/dist/headless/source-sheet-title.js +12 -0
- package/dist/headless/source-sheet-trigger.d.ts +2 -0
- package/dist/headless/source-sheet-trigger.js +12 -0
- package/dist/headless/source-unavailable.d.ts +2 -0
- package/dist/headless/source-unavailable.js +9 -0
- package/dist/headless/sources.d.ts +14 -0
- package/dist/headless/sources.js +12 -0
- package/dist/headless/speaker.d.ts +13 -0
- package/dist/headless/speaker.js +10 -0
- package/dist/headless/step-boundary.d.ts +4 -0
- package/dist/headless/step-boundary.js +16 -0
- package/dist/headless/stop.d.ts +10 -0
- package/dist/headless/stop.js +18 -0
- package/dist/headless/stopped.d.ts +11 -0
- package/dist/headless/stopped.js +17 -0
- package/dist/headless/submit-answers.d.ts +3 -0
- package/dist/headless/submit-answers.js +12 -0
- package/dist/headless/submit.d.ts +23 -0
- package/dist/headless/submit.js +24 -0
- package/dist/headless/suggestion.d.ts +10 -0
- package/dist/headless/suggestion.js +14 -0
- package/dist/headless/suggestions.d.ts +8 -0
- package/dist/headless/suggestions.js +12 -0
- package/dist/headless/thread.d.ts +3 -0
- package/dist/headless/thread.js +25 -0
- package/dist/headless/timing.d.ts +5 -0
- package/dist/headless/timing.js +13 -0
- package/dist/headless/toggle-tool.d.ts +4 -0
- package/dist/headless/toggle-tool.js +15 -0
- package/dist/headless/tool-error.d.ts +4 -0
- package/dist/headless/tool-error.js +13 -0
- package/dist/headless/tool-input.d.ts +4 -0
- package/dist/headless/tool-input.js +13 -0
- package/dist/headless/tool-output.d.ts +4 -0
- package/dist/headless/tool-output.js +13 -0
- package/dist/headless/tool-renderer.d.ts +13 -0
- package/dist/headless/tool-renderer.js +15 -0
- package/dist/headless/transcript.d.ts +23 -0
- package/dist/headless/transcript.js +24 -0
- package/dist/headless/try-again.d.ts +2 -0
- package/dist/headless/try-again.js +24 -0
- package/dist/headless/unavailable.d.ts +8 -0
- package/dist/headless/unavailable.js +9 -0
- package/dist/headless/usage.d.ts +13 -0
- package/dist/headless/usage.js +15 -0
- package/dist/headless/use-merged-ref.d.ts +2 -0
- package/dist/headless/use-merged-ref.js +17 -0
- package/dist/headless/use-question.d.ts +3 -0
- package/dist/headless/use-question.js +9 -0
- package/dist/headless/waiting.d.ts +13 -0
- package/dist/headless/waiting.js +12 -0
- package/dist/headless/writing.d.ts +13 -0
- package/dist/headless/writing.js +12 -0
- package/dist/hooks/chat-refusal.d.ts +18 -0
- package/dist/hooks/chat-refusal.js +44 -0
- package/dist/hooks/turn-mailbox.d.ts +14 -0
- package/dist/hooks/turn-mailbox.js +114 -0
- package/dist/hooks/use-branches.d.ts +10 -0
- package/dist/hooks/use-branches.js +69 -0
- package/dist/hooks/use-chat-instance.d.ts +28 -0
- package/dist/hooks/use-chat-instance.js +44 -0
- package/dist/hooks/use-chat-settings.d.ts +11 -0
- package/dist/hooks/use-chat-settings.js +33 -0
- package/dist/hooks/use-chat-sink.d.ts +19 -0
- package/dist/hooks/use-chat-sink.js +56 -0
- package/dist/hooks/use-composer.d.ts +33 -0
- package/dist/hooks/use-composer.js +45 -0
- package/dist/hooks/use-context-usage.d.ts +8 -0
- package/dist/hooks/use-context-usage.js +14 -0
- package/dist/hooks/use-copied.d.ts +14 -0
- package/dist/hooks/use-copied.js +22 -0
- package/dist/hooks/use-draft.d.ts +6 -0
- package/dist/hooks/use-draft.js +38 -0
- package/dist/hooks/use-feedback.d.ts +8 -0
- package/dist/hooks/use-feedback.js +28 -0
- package/dist/hooks/use-follow.d.ts +15 -0
- package/dist/hooks/use-follow.js +30 -0
- package/dist/hooks/use-media-load.d.ts +5 -0
- package/dist/hooks/use-media-load.js +12 -0
- package/dist/hooks/use-media.d.ts +3 -0
- package/dist/hooks/use-media.js +9 -0
- package/dist/hooks/use-question-check.d.ts +11 -0
- package/dist/hooks/use-question-check.js +29 -0
- package/dist/hooks/use-question-draft.d.ts +34 -0
- package/dist/hooks/use-question-draft.js +57 -0
- package/dist/hooks/use-question-steps.d.ts +18 -0
- package/dist/hooks/use-question-steps.js +31 -0
- package/dist/hooks/use-question-write.d.ts +8 -0
- package/dist/hooks/use-question-write.js +25 -0
- package/dist/hooks/use-read-aloud.d.ts +8 -0
- package/dist/hooks/use-read-aloud.js +60 -0
- package/dist/hooks/use-reasoning.d.ts +8 -0
- package/dist/hooks/use-reasoning.js +32 -0
- package/dist/hooks/use-remembered-approvals.d.ts +9 -0
- package/dist/hooks/use-remembered-approvals.js +40 -0
- package/dist/hooks/use-reply.d.ts +3 -0
- package/dist/hooks/use-reply.js +9 -0
- package/dist/hooks/use-report-missing-configuration.d.ts +9 -0
- package/dist/hooks/use-report-missing-configuration.js +14 -0
- package/dist/hooks/use-retry-delay.d.ts +5 -0
- package/dist/hooks/use-retry-delay.js +17 -0
- package/dist/hooks/use-sent-draft.d.ts +8 -0
- package/dist/hooks/use-sent-draft.js +25 -0
- package/dist/hooks/use-source-disclosure.d.ts +5 -0
- package/dist/hooks/use-source-disclosure.js +9 -0
- package/dist/hooks/use-sources.d.ts +3 -0
- package/dist/hooks/use-sources.js +9 -0
- package/dist/hooks/use-tool-approval-memory.d.ts +8 -0
- package/dist/hooks/use-tool-approval-memory.js +16 -0
- package/dist/hooks/use-tool-approval.d.ts +10 -0
- package/dist/hooks/use-tool-approval.js +26 -0
- package/dist/hooks/use-turn-queue.d.ts +32 -0
- package/dist/hooks/use-turn-queue.js +33 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +5 -0
- package/dist/next.d.ts +43 -0
- package/dist/next.js +10 -0
- package/dist/services/approval-memory.d.ts +9 -0
- package/dist/services/approval-memory.js +32 -0
- package/dist/services/approval.d.ts +14 -0
- package/dist/services/approval.js +37 -0
- package/dist/services/branches.d.ts +27 -0
- package/dist/services/branches.js +131 -0
- package/dist/services/chat-session.d.ts +20 -0
- package/dist/services/chat-session.js +61 -0
- package/dist/services/choices.d.ts +31 -0
- package/dist/services/choices.js +39 -0
- package/dist/services/continue.d.ts +8 -0
- package/dist/services/continue.js +24 -0
- package/dist/services/errors.d.ts +52 -0
- package/dist/services/errors.js +54 -0
- package/dist/services/media.d.ts +9 -0
- package/dist/services/media.js +19 -0
- package/dist/services/messages.d.ts +44 -0
- package/dist/services/messages.js +0 -0
- package/dist/services/optional.d.ts +7 -0
- package/dist/services/optional.js +7 -0
- package/dist/services/ports.d.ts +31 -0
- package/dist/services/ports.js +0 -0
- package/dist/services/questions.d.ts +67 -0
- package/dist/services/questions.js +119 -0
- package/dist/services/request.d.ts +26 -0
- package/dist/services/request.js +85 -0
- package/dist/services/selection.d.ts +10 -0
- package/dist/services/selection.js +49 -0
- package/dist/services/sources.d.ts +11 -0
- package/dist/services/sources.js +29 -0
- package/dist/services/tools.d.ts +11 -0
- package/dist/services/tools.js +0 -0
- package/dist/services/turn.d.ts +84 -0
- package/dist/services/turn.js +0 -0
- package/dist/services/types.d.ts +23 -0
- package/dist/services/types.js +15 -0
- package/package.json +822 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { QuestionDraftContext, QuestionWriteContext } from "./contexts.js";
|
|
4
|
+
import { useQuestion } from "./use-question.js";
|
|
5
|
+
function ClearAnswer({ name, ...props }) {
|
|
6
|
+
const question = useQuestion(name, "ClearAnswer");
|
|
7
|
+
const draft = useRequired(QuestionDraftContext, "Chat.ClearAnswer requires Chat.PartQuestion.");
|
|
8
|
+
const write = useRequired(QuestionWriteContext, "Chat.ClearAnswer requires Chat.PartQuestion.");
|
|
9
|
+
const element = usePart("button", props, {
|
|
10
|
+
defaults: { type: "button" },
|
|
11
|
+
locked: { disabled: write.pending },
|
|
12
|
+
behavior: { onClick: () => draft.change(name, { type: "clear" }) }
|
|
13
|
+
});
|
|
14
|
+
const filled = draft.answers[name] !== void 0 || draft.other(name).on;
|
|
15
|
+
return question && !question.required && filled ? element : null;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
ClearAnswer
|
|
19
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChatSettings } from "../services/types";
|
|
2
|
+
import type { AiChat } from "../hooks/use-chat-instance";
|
|
3
|
+
import { type RootProps } from "@slices.sh/core/part";
|
|
4
|
+
type ComposerRootProps = RootProps & {
|
|
5
|
+
name: string;
|
|
6
|
+
chat?: AiChat;
|
|
7
|
+
settings?: ChatSettings | null;
|
|
8
|
+
};
|
|
9
|
+
/** Reuses the containing chat, so embedding a composer never starts a second conversation.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated Chat.ComposerRoot becomes a nested Chat.Root, which shares the outer conversation for the same config.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ComposerRoot({ children, ...props }: ComposerRootProps): import("react").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useContext } from "react";
|
|
4
|
+
import { ChatContext, ComposerStandaloneContext } from "./contexts.js";
|
|
5
|
+
import { Root } from "./root.js";
|
|
6
|
+
function ComposerRoot({ children, ...props }) {
|
|
7
|
+
const chat = useContext(ChatContext);
|
|
8
|
+
return /* @__PURE__ */ jsx(ComposerStandaloneContext, { value: chat ? "embedded" : "standalone", children: chat ? children : /* @__PURE__ */ jsx(Root, { ...props, children }) });
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
ComposerRoot
|
|
12
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
2
|
+
/** @deprecated Chat.ComposerStandalone has no replacement: a pattern that draws Chat.Settings only when it stands alone takes a prop for it. */
|
|
3
|
+
export declare function ComposerStandalone({ children }: GateProps): import("react").ReactNode;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
import { ComposerStandaloneContext } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function ComposerStandalone({ children }) {
|
|
6
|
+
return useContext(ComposerStandaloneContext) === "standalone" ? gateContent(children, {}) : null;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
ComposerStandalone
|
|
10
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { ComposerContext } from "./contexts.js";
|
|
4
|
+
function Composer(props) {
|
|
5
|
+
const composer = useRequired(ComposerContext, "Chat.Composer must be inside <Chat.Root>.");
|
|
6
|
+
return usePart("form", props, {
|
|
7
|
+
behavior: {
|
|
8
|
+
onClick: (event) => {
|
|
9
|
+
const target = event.target;
|
|
10
|
+
if (!(target instanceof Element) || target.closest("button,a,input,textarea,select,label,[role=button]"))
|
|
11
|
+
return;
|
|
12
|
+
event.currentTarget.querySelector("textarea")?.focus();
|
|
13
|
+
},
|
|
14
|
+
onSubmit: (event) => {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
composer.submit();
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
attributes: { pending: composer.disabled }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
Composer
|
|
24
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useContextUsage } from "../hooks/use-context-usage.js";
|
|
3
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { ChatContext } from "./contexts.js";
|
|
5
|
+
import { gateContent } from "./gate-content.js";
|
|
6
|
+
function ContextUsage({ children }) {
|
|
7
|
+
const chat = useRequired(ChatContext, "Chat.ContextUsage must be inside <Chat.Root>.");
|
|
8
|
+
const usage = useContextUsage(chat);
|
|
9
|
+
return usage ? gateContent(children, usage) : null;
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
ContextUsage
|
|
13
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ChatFeedbackOptions } from "../services/types";
|
|
2
|
+
import type { Branches } from "../hooks/use-branches";
|
|
3
|
+
import type { SentDraft } from "../hooks/use-sent-draft";
|
|
4
|
+
import type { QueuedTurn } from "../hooks/use-turn-queue";
|
|
5
|
+
import type { Reasoning } from "../hooks/use-reasoning";
|
|
6
|
+
import type { QuestionDraft } from "../hooks/use-question-draft";
|
|
7
|
+
import type { QuestionWrite } from "../hooks/use-question-write";
|
|
8
|
+
import type { QuestionCheck } from "../hooks/use-question-check";
|
|
9
|
+
import type { QuestionSteps } from "../hooks/use-question-steps";
|
|
10
|
+
import type { ToolApprovalMemory } from "../hooks/use-tool-approval-memory";
|
|
11
|
+
import type { ApprovalAutomation } from "../hooks/use-remembered-approvals";
|
|
12
|
+
import type { ToolApproval } from "../hooks/use-tool-approval";
|
|
13
|
+
import type { AiChat, ChatSource } from "../hooks/use-chat-instance";
|
|
14
|
+
import type { Composer, ComposerPlacement, ComposerAttachments } from "../hooks/use-composer";
|
|
15
|
+
import type { Follow } from "../hooks/use-follow";
|
|
16
|
+
import type { TurnQueue } from "../hooks/use-turn-queue";
|
|
17
|
+
import type { AiChatMessage } from "../services/types";
|
|
18
|
+
/**
|
|
19
|
+
* The AI SDK's chat itself, not a copy of its state: every part that needs the transcript,
|
|
20
|
+
* the status or the error reads it with the SDK's `useChat({ chat })`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SettingsContext: import("react").Context<{
|
|
23
|
+
blocked: boolean;
|
|
24
|
+
model: (id: string) => void;
|
|
25
|
+
toggle: (id: string) => void;
|
|
26
|
+
removeLast: () => boolean;
|
|
27
|
+
choices: import("../services/choices").ChatChoices | null;
|
|
28
|
+
selection: import("../services/choices").ChatSelection;
|
|
29
|
+
} | null>;
|
|
30
|
+
export declare const ChatContext: import("react").Context<AiChat | null>;
|
|
31
|
+
/** The config the conversation above talks to, so a Root inside it knows whether it shares it. */
|
|
32
|
+
export declare const ChatConfigContext: import("react").Context<string | null>;
|
|
33
|
+
/** Whether anything answers the chat, for the one gate that says nothing does. */
|
|
34
|
+
export declare const SourceContext: import("react").Context<ChatSource | null>;
|
|
35
|
+
export declare const ComposerContext: import("react").Context<Composer | null>;
|
|
36
|
+
export declare const FollowContext: import("react").Context<Follow | null>;
|
|
37
|
+
export declare const QueueContext: import("react").Context<TurnQueue | null>;
|
|
38
|
+
/** The message a part is drawn for, as the SDK holds it, so `Chat.Copy` needs no props. */
|
|
39
|
+
export declare const MessageScope: import("react").Context<AiChatMessage | null>;
|
|
40
|
+
/** One of its parts, as the SDK holds it, so a gate per kind needs none either. */
|
|
41
|
+
export declare const PartScope: import("react").Context<import("ai").UIMessagePart<import("ai").UIDataTypes, import("ai").UITools> | null>;
|
|
42
|
+
export declare const ApprovalContext: import("react").Context<ToolApproval | null>;
|
|
43
|
+
export declare const ApprovalMemoryContext: import("react").Context<ToolApprovalMemory | null>;
|
|
44
|
+
export declare const ApprovalAutomationContext: import("react").Context<ApprovalAutomation | null>;
|
|
45
|
+
export declare const QuestionInputContext: import("react").Context<{
|
|
46
|
+
title: string;
|
|
47
|
+
questions: {
|
|
48
|
+
name: string;
|
|
49
|
+
title: string;
|
|
50
|
+
choices: {
|
|
51
|
+
value: string;
|
|
52
|
+
label: string;
|
|
53
|
+
description?: string | undefined;
|
|
54
|
+
}[];
|
|
55
|
+
description?: string | undefined;
|
|
56
|
+
multiple?: boolean | undefined;
|
|
57
|
+
required?: boolean | undefined;
|
|
58
|
+
other?: string | undefined;
|
|
59
|
+
}[];
|
|
60
|
+
} | null>;
|
|
61
|
+
export declare const QuestionDraftContext: import("react").Context<QuestionDraft | null>;
|
|
62
|
+
export declare const QuestionCheckContext: import("react").Context<QuestionCheck | null>;
|
|
63
|
+
export declare const QuestionStepsContext: import("react").Context<QuestionSteps | null>;
|
|
64
|
+
export declare const QuestionWriteContext: import("react").Context<QuestionWrite | null>;
|
|
65
|
+
export declare const ReasoningContext: import("react").Context<Reasoning | null>;
|
|
66
|
+
export declare const QueueScope: import("react").Context<QueuedTurn | null>;
|
|
67
|
+
export declare const ComposerStandaloneContext: import("react").Context<ComposerPlacement>;
|
|
68
|
+
export declare const ComposerAttachmentsContext: import("react").Context<ComposerAttachments | null>;
|
|
69
|
+
export declare const BranchContext: import("react").Context<Branches | null>;
|
|
70
|
+
export declare const SentDraftContext: import("react").Context<SentDraft | null>;
|
|
71
|
+
export declare const FeedbackOptionsContext: import("react").Context<ChatFeedbackOptions>;
|
|
72
|
+
export declare const FeedbackContext: import("react").Context<{
|
|
73
|
+
rating: "up" | "down" | null;
|
|
74
|
+
pending: boolean;
|
|
75
|
+
failed: boolean;
|
|
76
|
+
submit: (choice: "up" | "down") => Promise<void>;
|
|
77
|
+
} | null>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const SettingsContext = createContext(null);
|
|
3
|
+
const ChatContext = createContext(null);
|
|
4
|
+
const ChatConfigContext = createContext(null);
|
|
5
|
+
const SourceContext = createContext(null);
|
|
6
|
+
const ComposerContext = createContext(null);
|
|
7
|
+
const FollowContext = createContext(null);
|
|
8
|
+
const QueueContext = createContext(null);
|
|
9
|
+
const MessageScope = createContext(null);
|
|
10
|
+
const PartScope = createContext(null);
|
|
11
|
+
const ApprovalContext = createContext(null);
|
|
12
|
+
const ApprovalMemoryContext = createContext(null);
|
|
13
|
+
const ApprovalAutomationContext = createContext(null);
|
|
14
|
+
const QuestionInputContext = createContext(null);
|
|
15
|
+
const QuestionDraftContext = createContext(null);
|
|
16
|
+
const QuestionCheckContext = createContext(null);
|
|
17
|
+
const QuestionStepsContext = createContext(null);
|
|
18
|
+
const QuestionWriteContext = createContext(null);
|
|
19
|
+
const ReasoningContext = createContext(null);
|
|
20
|
+
const QueueScope = createContext(null);
|
|
21
|
+
const ComposerStandaloneContext = createContext("embedded");
|
|
22
|
+
const ComposerAttachmentsContext = createContext(null);
|
|
23
|
+
const BranchContext = createContext(null);
|
|
24
|
+
const SentDraftContext = createContext(null);
|
|
25
|
+
const FeedbackOptionsContext = createContext({});
|
|
26
|
+
const FeedbackContext = createContext(null);
|
|
27
|
+
export {
|
|
28
|
+
ApprovalAutomationContext,
|
|
29
|
+
ApprovalContext,
|
|
30
|
+
ApprovalMemoryContext,
|
|
31
|
+
BranchContext,
|
|
32
|
+
ChatConfigContext,
|
|
33
|
+
ChatContext,
|
|
34
|
+
ComposerAttachmentsContext,
|
|
35
|
+
ComposerContext,
|
|
36
|
+
ComposerStandaloneContext,
|
|
37
|
+
FeedbackContext,
|
|
38
|
+
FeedbackOptionsContext,
|
|
39
|
+
FollowContext,
|
|
40
|
+
MessageScope,
|
|
41
|
+
PartScope,
|
|
42
|
+
QuestionCheckContext,
|
|
43
|
+
QuestionDraftContext,
|
|
44
|
+
QuestionInputContext,
|
|
45
|
+
QuestionStepsContext,
|
|
46
|
+
QuestionWriteContext,
|
|
47
|
+
QueueContext,
|
|
48
|
+
QueueScope,
|
|
49
|
+
ReasoningContext,
|
|
50
|
+
SentDraftContext,
|
|
51
|
+
SettingsContext,
|
|
52
|
+
SourceContext
|
|
53
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { ChatContext, MessageScope } from "./contexts.js";
|
|
5
|
+
import { isCutOff, isWriting } from "./writing.js";
|
|
6
|
+
function Continue({ prompt, ...props }) {
|
|
7
|
+
const chat = useRequired(ChatContext, "Chat.Continue requires Chat.Root.");
|
|
8
|
+
const message = useRequired(MessageScope, "Chat.Continue requires Chat.Messages.");
|
|
9
|
+
const { messages, status } = useChat({ chat });
|
|
10
|
+
const running = status === "submitted" || status === "streaming";
|
|
11
|
+
const element = usePart("button", props, {
|
|
12
|
+
defaults: { type: "button" },
|
|
13
|
+
locked: { disabled: running },
|
|
14
|
+
behavior: {
|
|
15
|
+
onClick: () => {
|
|
16
|
+
if (chat.status === "submitted" || chat.status === "streaming" || chat.messages.at(-1)?.id !== message.id)
|
|
17
|
+
return;
|
|
18
|
+
void chat.sendMessage({ text: prompt, metadata: { intent: "continue", continues: message.id } });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return messages.at(-1)?.id === message.id && isCutOff(message, isWriting(message, messages, status)) ? element : null;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
Continue
|
|
26
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PartProps } from "@slices.sh/core/part";
|
|
2
|
+
/**
|
|
3
|
+
* Puts this message's text on the clipboard, and says so.
|
|
4
|
+
*
|
|
5
|
+
* The text and nothing else: a reader copying an answer wants the answer, not the reasoning
|
|
6
|
+
* trace above it or the JSON of a tool call beside it. Runs of prose a tool call separated
|
|
7
|
+
* stay separate paragraphs.
|
|
8
|
+
*/
|
|
9
|
+
export declare function Copy(props: PartProps<"button", {
|
|
10
|
+
copied: boolean;
|
|
11
|
+
}>): import("react").ReactNode;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCopied } from "../hooks/use-copied.js";
|
|
3
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { MessageScope } from "./contexts.js";
|
|
5
|
+
function Copy(props) {
|
|
6
|
+
const message = useRequired(MessageScope, "Chat.Copy must be inside <Chat.Messages>.");
|
|
7
|
+
const clipboard = useCopied();
|
|
8
|
+
return usePart("button", props, {
|
|
9
|
+
state: { copied: clipboard.copied },
|
|
10
|
+
defaults: { type: "button" },
|
|
11
|
+
behavior: {
|
|
12
|
+
onClick: () => clipboard.copy(
|
|
13
|
+
message.parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("\n\n")
|
|
14
|
+
)
|
|
15
|
+
},
|
|
16
|
+
attributes: { active: clipboard.copied }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
Copy
|
|
21
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { ApprovalContext } from "./contexts.js";
|
|
4
|
+
function Deny(props) {
|
|
5
|
+
const write = useRequired(ApprovalContext, "Chat.Deny requires Chat.PartApproval.");
|
|
6
|
+
return usePart("button", props, {
|
|
7
|
+
state: { pending: write.pending },
|
|
8
|
+
defaults: { type: "button" },
|
|
9
|
+
locked: { disabled: write.pending },
|
|
10
|
+
behavior: { onClick: () => void write.run({ approved: false }) }
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
Deny
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { QueueContext, QueueScope } from "./contexts.js";
|
|
4
|
+
function EditQueued(props) {
|
|
5
|
+
const queue = useRequired(QueueContext, "Chat.EditQueued requires Chat.Root.");
|
|
6
|
+
const item = useRequired(QueueScope, "Chat.EditQueued requires Chat.QueueItems.");
|
|
7
|
+
return usePart("button", props, {
|
|
8
|
+
defaults: { type: "button" },
|
|
9
|
+
locked: { disabled: false },
|
|
10
|
+
behavior: { onClick: () => queue.change({ type: "begin-edit", id: item.id }) }
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
EditQueued
|
|
15
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { BranchContext, MessageScope, SentDraftContext } from "./contexts.js";
|
|
4
|
+
function Edit(props) {
|
|
5
|
+
const branches = useRequired(BranchContext, "Chat.Edit requires Chat.Root.");
|
|
6
|
+
const message = useRequired(MessageScope, "Chat.Edit requires Chat.Messages.");
|
|
7
|
+
const draft = useRequired(SentDraftContext, "Chat.Edit requires Chat.MessageEditRoot.");
|
|
8
|
+
const element = usePart("button", props, {
|
|
9
|
+
defaults: { type: "button" },
|
|
10
|
+
locked: { disabled: branches.blocked, hidden: draft.value !== null },
|
|
11
|
+
behavior: { onClick: draft.start }
|
|
12
|
+
});
|
|
13
|
+
return message.role === "user" ? element : null;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
Edit
|
|
17
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { MessageScope } from "./contexts.js";
|
|
4
|
+
function EditedAttachments({ children }) {
|
|
5
|
+
const message = useRequired(MessageScope, "Chat.EditedAttachments requires Chat.Messages.");
|
|
6
|
+
const files = message.parts.filter((part) => part.type === "file");
|
|
7
|
+
return files.length ? typeof children === "function" ? children({ files }) : children : null;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
EditedAttachments
|
|
11
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { BranchContext, SentDraftContext } from "./contexts.js";
|
|
4
|
+
function EditedInput(props) {
|
|
5
|
+
const branches = useRequired(BranchContext, "Chat.EditedInput requires Chat.Root.");
|
|
6
|
+
const draft = useRequired(SentDraftContext, "Chat.EditedInput requires Chat.MessageEditRoot.");
|
|
7
|
+
return usePart("textarea", props, {
|
|
8
|
+
defaults: { autoFocus: true },
|
|
9
|
+
locked: { value: draft.value ?? "", disabled: branches.blocked },
|
|
10
|
+
behavior: {
|
|
11
|
+
onChange: (event) => draft.set(event.currentTarget.value),
|
|
12
|
+
onKeyDown: (event) => {
|
|
13
|
+
if (event.nativeEvent.isComposing) return;
|
|
14
|
+
if (event.key === "Escape") {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
draft.cancel();
|
|
17
|
+
}
|
|
18
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
event.currentTarget.form?.requestSubmit();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
EditedInput
|
|
28
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { ChatContext } from "./contexts.js";
|
|
5
|
+
function Empty({ children }) {
|
|
6
|
+
const chat = useRequired(ChatContext, "Chat.Empty must be inside <Chat.Root>.");
|
|
7
|
+
const { messages } = useChat({ chat });
|
|
8
|
+
return messages.length === 0 ? children : null;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
Empty
|
|
12
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
2
|
+
import type { ChatErrorSlug } from "../services/types";
|
|
3
|
+
/**
|
|
4
|
+
* The turn was refused — the SDK's `error` status — and the child is told which refusal it
|
|
5
|
+
* was.
|
|
6
|
+
*
|
|
7
|
+
* The slug reaches the screen because the common ones want different things: a quota
|
|
8
|
+
* refusal wants an upgrade link, an outage wants the retry button, and an unknown chat wants
|
|
9
|
+
* a developer to open `services/ai-chat/config.ts`. One banner for all three would be three
|
|
10
|
+
* lies. → docs/rules/capability-honesty.md
|
|
11
|
+
*/
|
|
12
|
+
export declare function Failed({ children }: GateProps<{
|
|
13
|
+
error: ChatErrorSlug;
|
|
14
|
+
retryIn: number;
|
|
15
|
+
}>): import("react").ReactNode;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { useRetryDelay } from "../hooks/use-retry-delay.js";
|
|
4
|
+
import { refusalOf } from "../hooks/chat-refusal.js";
|
|
5
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
6
|
+
import { ChatContext } from "./contexts.js";
|
|
7
|
+
import { gateContent } from "./gate-content.js";
|
|
8
|
+
function Failed({ children }) {
|
|
9
|
+
const chat = useRequired(ChatContext, "Chat.Failed must be inside <Chat.Root>.");
|
|
10
|
+
const { status, error } = useChat({ chat });
|
|
11
|
+
const { seconds } = useRetryDelay(error);
|
|
12
|
+
if (status !== "error") return null;
|
|
13
|
+
return gateContent(children, { error: refusalOf(error), retryIn: seconds });
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
Failed
|
|
17
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { FeedbackContext } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function FeedbackError({ children }) {
|
|
6
|
+
const feedback = useRequired(FeedbackContext, "Chat.FeedbackError requires Chat.FeedbackRoot.");
|
|
7
|
+
return feedback.failed ? gateContent(children, {}) : null;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FeedbackError
|
|
11
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useContext } from "react";
|
|
4
|
+
import { useFeedback } from "../hooks/use-feedback.js";
|
|
5
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
6
|
+
import { ChatContext, MessageScope, FeedbackContext, FeedbackOptionsContext } from "./contexts.js";
|
|
7
|
+
function FeedbackRoot({ children }) {
|
|
8
|
+
const chat = useRequired(ChatContext, "Chat.FeedbackRoot requires Chat.Root.");
|
|
9
|
+
const message = useRequired(MessageScope, "Chat.FeedbackRoot requires Chat.Messages.");
|
|
10
|
+
const { onFeedback } = useContext(FeedbackOptionsContext);
|
|
11
|
+
return onFeedback && message.role === "assistant" ? /* @__PURE__ */ jsx(Session, { chatId: chat.id, messageId: message.id, onFeedback, children }, chat.id + ":" + message.id) : null;
|
|
12
|
+
}
|
|
13
|
+
function Session({
|
|
14
|
+
chatId,
|
|
15
|
+
messageId,
|
|
16
|
+
onFeedback,
|
|
17
|
+
children
|
|
18
|
+
}) {
|
|
19
|
+
const feedback = useFeedback({ chatId, messageId }, onFeedback);
|
|
20
|
+
return /* @__PURE__ */ jsx(FeedbackContext, { value: feedback, children });
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
FeedbackRoot
|
|
24
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { FeedbackContext } from "./contexts.js";
|
|
4
|
+
function Feedback({ rating, ...props }) {
|
|
5
|
+
const feedback = useRequired(FeedbackContext, "Chat.Feedback requires Chat.FeedbackRoot.");
|
|
6
|
+
return usePart("button", props, {
|
|
7
|
+
defaults: { type: "button" },
|
|
8
|
+
locked: {
|
|
9
|
+
disabled: feedback.pending,
|
|
10
|
+
"aria-pressed": feedback.rating === rating,
|
|
11
|
+
"aria-busy": feedback.pending
|
|
12
|
+
},
|
|
13
|
+
behavior: { onClick: () => void feedback.submit(rating) }
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
Feedback
|
|
18
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { FileContext, FileLoadContext } from "./file-context.js";
|
|
4
|
+
function FileAudio(props) {
|
|
5
|
+
const media = useRequired(FileContext, "Chat.FileAudio requires Chat.FileRoot.");
|
|
6
|
+
const load = useRequired(FileLoadContext, "File media requires Chat.FileRoot.");
|
|
7
|
+
const element = usePart("audio", props, {
|
|
8
|
+
behavior: { onError: load.fail },
|
|
9
|
+
locked: { src: media.url ?? void 0 },
|
|
10
|
+
defaults: { controls: true, preload: "none" }
|
|
11
|
+
});
|
|
12
|
+
return !load.failed && media.url && media.kind === "audio" ? element : null;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
FileAudio
|
|
16
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { FileContext, FileLoadContext } from "./file-context.js";
|
|
4
|
+
function FileImage(props) {
|
|
5
|
+
const media = useRequired(FileContext, "Chat.FileImage requires Chat.FileRoot.");
|
|
6
|
+
const load = useRequired(FileLoadContext, "File media requires Chat.FileRoot.");
|
|
7
|
+
const element = usePart("img", props, {
|
|
8
|
+
behavior: { onError: load.fail },
|
|
9
|
+
locked: { src: media.url ?? void 0 },
|
|
10
|
+
defaults: {
|
|
11
|
+
alt: media.file.filename ?? "",
|
|
12
|
+
loading: "lazy",
|
|
13
|
+
decoding: "async",
|
|
14
|
+
referrerPolicy: "no-referrer"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return !load.failed && media.url && media.kind === "image" ? element : null;
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
FileImage
|
|
21
|
+
};
|