@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,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { ComposerContext } from "./contexts.js";
|
|
4
|
+
function Input(props) {
|
|
5
|
+
const composer = useRequired(ComposerContext, "Chat.Input must be inside <Chat.Root>.");
|
|
6
|
+
return usePart("textarea", props, {
|
|
7
|
+
attributes: { "chat-composer": true },
|
|
8
|
+
defaults: { autoComplete: "off", enterKeyHint: "send" },
|
|
9
|
+
behavior: {
|
|
10
|
+
onChange: (event) => composer.set(event.currentTarget.value),
|
|
11
|
+
onKeyDown: composer.keyDown
|
|
12
|
+
},
|
|
13
|
+
locked: { value: composer.draft, disabled: composer.disabled }
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
Input
|
|
18
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { FollowContext } from "./contexts.js";
|
|
4
|
+
function JumpToLatest(props) {
|
|
5
|
+
const follow = useRequired(FollowContext, "Chat.JumpToLatest must be inside <Chat.Root>.");
|
|
6
|
+
const element = usePart("button", props, {
|
|
7
|
+
defaults: { type: "button" },
|
|
8
|
+
behavior: { onClick: () => follow.jump() }
|
|
9
|
+
});
|
|
10
|
+
return follow.following ? null : element;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
JumpToLatest
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useSentDraft } from "../hooks/use-sent-draft.js";
|
|
4
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
5
|
+
import { MessageScope, SentDraftContext } from "./contexts.js";
|
|
6
|
+
function MessageEditRoot({ children }) {
|
|
7
|
+
const message = useRequired(MessageScope, "Chat.MessageEditRoot requires Chat.Messages.");
|
|
8
|
+
const draft = useSentDraft(message);
|
|
9
|
+
return /* @__PURE__ */ jsx(SentDraftContext, { value: draft, children });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
MessageEditRoot
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { SentDraftContext } from "./contexts.js";
|
|
4
|
+
function MessageEditing({ children }) {
|
|
5
|
+
const draft = useRequired(SentDraftContext, "Chat.MessageEditing requires Chat.MessageEditRoot.");
|
|
6
|
+
return draft.value !== null ? children : null;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
MessageEditing
|
|
10
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { BranchContext, MessageScope, SentDraftContext } from "./contexts.js";
|
|
4
|
+
function MessageEditor(props) {
|
|
5
|
+
const branches = useRequired(BranchContext, "Chat.MessageEditor requires Chat.Root.");
|
|
6
|
+
const message = useRequired(MessageScope, "Chat.MessageEditor requires Chat.Messages.");
|
|
7
|
+
const draft = useRequired(SentDraftContext, "Chat.MessageEditor requires Chat.MessageEditRoot.");
|
|
8
|
+
return usePart("form", props, {
|
|
9
|
+
behavior: {
|
|
10
|
+
onSubmit: (event) => {
|
|
11
|
+
event.preventDefault();
|
|
12
|
+
if (draft.value !== null && branches.edit(message.id, draft.value)) draft.cancel();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
MessageEditor
|
|
19
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
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 { isWriting } from "./writing.js";
|
|
6
|
+
function MessageFooter(props) {
|
|
7
|
+
const message = useRequired(MessageScope, "Chat.MessageFooter must be inside <Chat.Messages>.");
|
|
8
|
+
const chat = useRequired(ChatContext, "Chat.MessageFooter must be inside <Chat.Root>.");
|
|
9
|
+
const { messages, status } = useChat({ chat });
|
|
10
|
+
const element = usePart("div", props, { attributes: { active: messages.at(-1)?.id === message.id } });
|
|
11
|
+
return isWriting(message, messages, status) ? null : element;
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
MessageFooter
|
|
15
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { SentDraftContext } from "./contexts.js";
|
|
4
|
+
function MessageReading({ children }) {
|
|
5
|
+
const draft = useRequired(SentDraftContext, "Chat.MessageReading requires Chat.MessageEditRoot.");
|
|
6
|
+
return draft.value === null ? children : null;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
MessageReading
|
|
10
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PartProps } from "@slices.sh/core/part";
|
|
2
|
+
import type { AiChatMessage } from "../services/types";
|
|
3
|
+
type MessageState = {
|
|
4
|
+
role: AiChatMessage["role"];
|
|
5
|
+
interrupted: boolean;
|
|
6
|
+
streaming: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function Message({ optimizeHistory, ...props }: PartProps<"div", MessageState> & {
|
|
9
|
+
optimizeHistory?: boolean;
|
|
10
|
+
}): import("react").ReactNode;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { MessageScroller } from "@shadcn/react/message-scroller";
|
|
4
|
+
import { useChat } from "@ai-sdk/react";
|
|
5
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
6
|
+
import { ChatContext, MessageScope } from "./contexts.js";
|
|
7
|
+
import { isCutOff, isWriting } from "./writing.js";
|
|
8
|
+
function Message({ optimizeHistory = true, ...props }) {
|
|
9
|
+
const message = useRequired(MessageScope, "Chat.Message must be inside <Chat.Messages>.");
|
|
10
|
+
const chat = useRequired(ChatContext, "Chat.Message must be inside <Chat.Root>.");
|
|
11
|
+
const { messages, status } = useChat({ chat });
|
|
12
|
+
const streaming = isWriting(message, messages, status);
|
|
13
|
+
const interrupted = isCutOff(message, streaming);
|
|
14
|
+
const anchor = message.role === "user" && messages.findLast((item) => item.role === "user")?.id === message.id;
|
|
15
|
+
const historical = optimizeHistory && messages.length > 40 && !anchor && !streaming && !messages.slice(-6).some((item) => item.id === message.id);
|
|
16
|
+
return usePart(
|
|
17
|
+
"div",
|
|
18
|
+
{ ...props, render: props.render ?? /* @__PURE__ */ jsx(MessageScroller.Item, {}) },
|
|
19
|
+
{
|
|
20
|
+
state: { role: message.role, interrupted, streaming },
|
|
21
|
+
defaults: { style: historical ? { contentVisibility: "auto", containIntrinsicSize: "auto 20rem" } : void 0 },
|
|
22
|
+
// `state` carries the role so one rule can style a side; `interrupted` is its own
|
|
23
|
+
// attribute because it is a fact about the message rather than whose it is.
|
|
24
|
+
//
|
|
25
|
+
// `aria-busy` is why the answer being written is told apart: without it a polite log
|
|
26
|
+
// reads a reply a word at a time, and with it the reply is read once, when it is a reply.
|
|
27
|
+
attributes: { state: message.role, invalid: interrupted, pending: streaming },
|
|
28
|
+
locked: { "aria-busy": streaming || void 0, messageId: message.id, scrollAnchor: anchor }
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
Message
|
|
34
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RootProps } from "@slices.sh/core/part";
|
|
2
|
+
/**
|
|
3
|
+
* The transcript's messages, each in its own scope, exactly as the AI SDK holds them.
|
|
4
|
+
*
|
|
5
|
+
* The repeat is a part rather than a `map` in the pattern, because a message is where the
|
|
6
|
+
* looks change most and the iteration never does: a skin decides what a row is, and this
|
|
7
|
+
* decides what the rows are.
|
|
8
|
+
*/
|
|
9
|
+
export declare function Messages({ children }: RootProps): import("react").JSX.Element[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useContext } from "react";
|
|
4
|
+
import { useChat } from "@ai-sdk/react";
|
|
5
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
6
|
+
import { ChatContext, MessageScope, BranchContext } from "./contexts.js";
|
|
7
|
+
function Messages({ children }) {
|
|
8
|
+
const chat = useRequired(ChatContext, "Chat.Messages must be inside <Chat.Root>.");
|
|
9
|
+
const branches = useContext(BranchContext);
|
|
10
|
+
const { messages } = useChat({ chat });
|
|
11
|
+
return messages.map((message) => {
|
|
12
|
+
const page = branches?.page(message.id);
|
|
13
|
+
const key = page?.anchored ? `branch:${page.id}` : `message:${message.id}`;
|
|
14
|
+
return /* @__PURE__ */ jsx(MessageScope, { value: message, children }, key);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
Messages
|
|
19
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { SettingsContext } from "./contexts.js";
|
|
4
|
+
function ModelPicker(props) {
|
|
5
|
+
const settings = useRequired(SettingsContext, "Chat.ModelPicker requires Chat.Root.");
|
|
6
|
+
const part = usePart("select", props, {
|
|
7
|
+
locked: { value: settings.selection.model ?? "", disabled: settings.blocked },
|
|
8
|
+
behavior: { onChange: (event) => settings.model(event.currentTarget.value) }
|
|
9
|
+
});
|
|
10
|
+
return settings.choices?.models?.length ? part : null;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
ModelPicker
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { MessageScope } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function Model({ children }) {
|
|
6
|
+
const message = useRequired(MessageScope, "Chat.Model must be inside <Chat.Messages>.");
|
|
7
|
+
const model = message.metadata?.model;
|
|
8
|
+
if (!model) return null;
|
|
9
|
+
return gateContent(children, { model });
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
Model
|
|
13
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { SettingsContext } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function Models({ children }) {
|
|
6
|
+
const { choices } = useRequired(SettingsContext, "Chat.Models requires Chat.Root.");
|
|
7
|
+
return choices?.models?.length ? gateContent(children, { models: choices.models }) : null;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
Models
|
|
11
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
2
|
+
import type { ChatChoices } from "../services/types";
|
|
3
|
+
export declare function OptionalTools({ selected, children }: GateProps<{
|
|
4
|
+
tools: NonNullable<ChatChoices["tools"]>;
|
|
5
|
+
}> & {
|
|
6
|
+
selected?: boolean;
|
|
7
|
+
}): import("react").ReactNode;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { SettingsContext } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function OptionalTools({ selected = false, children }) {
|
|
6
|
+
const state = useRequired(SettingsContext, "Chat.OptionalTools requires Chat.Root.");
|
|
7
|
+
const tools = state.choices?.tools?.filter((tool) => !selected || state.selection.tools?.includes(tool.id));
|
|
8
|
+
return tools?.length ? gateContent(children, { tools }) : null;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
OptionalTools
|
|
12
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type PartProps } from "@slices.sh/core/part";
|
|
2
|
+
/** The control of the "Other" row, last in the same group as the choices: it replaces the pick of a single question and adds to a multiple one. */
|
|
3
|
+
export declare function OtherAnswer({ name, ...props }: PartProps<"input"> & {
|
|
4
|
+
name: string;
|
|
5
|
+
}): import("react").ReactNode;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { QuestionCheckContext, QuestionDraftContext, QuestionWriteContext } from "./contexts.js";
|
|
4
|
+
import { useQuestion } from "./use-question.js";
|
|
5
|
+
function OtherAnswer({ name, ...props }) {
|
|
6
|
+
const question = useQuestion(name, "OtherAnswer");
|
|
7
|
+
const draft = useRequired(QuestionDraftContext, "Chat.OtherAnswer requires Chat.PartQuestion.");
|
|
8
|
+
const check = useRequired(QuestionCheckContext, "Chat.OtherAnswer requires Chat.PartQuestion.");
|
|
9
|
+
const write = useRequired(QuestionWriteContext, "Chat.OtherAnswer requires Chat.PartQuestion.");
|
|
10
|
+
const multiple = Boolean(question?.multiple);
|
|
11
|
+
const element = usePart("input", props, {
|
|
12
|
+
behavior: {
|
|
13
|
+
onChange: () => draft.change(name, { type: "toggle-other" }),
|
|
14
|
+
onClick: (event) => {
|
|
15
|
+
if (event.currentTarget.checked)
|
|
16
|
+
event.currentTarget.closest("fieldset")?.querySelector("input[type=text]")?.focus();
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
locked: {
|
|
20
|
+
type: multiple ? "checkbox" : "radio",
|
|
21
|
+
name,
|
|
22
|
+
value: "",
|
|
23
|
+
checked: draft.other(name).on,
|
|
24
|
+
disabled: write.pending,
|
|
25
|
+
"aria-invalid": multiple && check.shown(name) ? true : void 0
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return question?.other ? element : null;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
OtherAnswer
|
|
32
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { isToolUIPart } from "ai";
|
|
4
|
+
import { useToolApproval } from "../hooks/use-tool-approval.js";
|
|
5
|
+
import { usePart, useRequired } from "@slices.sh/core/part";
|
|
6
|
+
import { ApprovalContext, ChatContext, PartScope } from "./contexts.js";
|
|
7
|
+
function PartApproval(props) {
|
|
8
|
+
const part = useRequired(PartScope, "Chat.PartApproval requires Chat.Parts.");
|
|
9
|
+
if (!isToolUIPart(part) || part.state !== "approval-requested") return null;
|
|
10
|
+
return /* @__PURE__ */ jsx(Request, { id: part.approval.id, props }, part.approval.id);
|
|
11
|
+
}
|
|
12
|
+
function Request({ id, props }) {
|
|
13
|
+
const chat = useRequired(ChatContext, "Chat.PartApproval requires Chat.Root.");
|
|
14
|
+
const write = useToolApproval(chat, id);
|
|
15
|
+
const element = usePart("div", props, {
|
|
16
|
+
defaults: { role: "group" },
|
|
17
|
+
locked: { "aria-busy": write.pending || void 0 },
|
|
18
|
+
behavior: {
|
|
19
|
+
onKeyDown: (event) => {
|
|
20
|
+
if (event.defaultPrevented || write.pending) return;
|
|
21
|
+
if (event.key === "Escape" || event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
event.stopPropagation();
|
|
24
|
+
void write.run({ approved: event.key !== "Escape" });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx(ApprovalContext, { value: write, children: element });
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
PartApproval
|
|
33
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FileUIPart } from "ai";
|
|
2
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
3
|
+
/** A native file stays visible in history even when the rich media viewer is not installed. */
|
|
4
|
+
export declare function PartFile({ children }: GateProps<{
|
|
5
|
+
file: FileUIPart;
|
|
6
|
+
}>): import("react").ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
3
|
+
import { PartScope } from "./contexts.js";
|
|
4
|
+
import { gateContent } from "./gate-content.js";
|
|
5
|
+
function PartFile({ children }) {
|
|
6
|
+
const part = useRequired(PartScope, "Chat.PartFile requires Chat.Parts.");
|
|
7
|
+
return part.type === "file" ? gateContent(children, { file: part }) : null;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
PartFile
|
|
11
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { isToolUIPart } from "ai";
|
|
4
|
+
import { questionInput, useQuestionDraft } from "../hooks/use-question-draft.js";
|
|
5
|
+
import { useQuestionCheck } from "../hooks/use-question-check.js";
|
|
6
|
+
import { useQuestionSteps } from "../hooks/use-question-steps.js";
|
|
7
|
+
import { useQuestionWrite } from "../hooks/use-question-write.js";
|
|
8
|
+
import { Provide, usePart, useRequired } from "@slices.sh/core/part";
|
|
9
|
+
import {
|
|
10
|
+
ChatContext,
|
|
11
|
+
PartScope,
|
|
12
|
+
QuestionInputContext,
|
|
13
|
+
QuestionDraftContext,
|
|
14
|
+
QuestionCheckContext,
|
|
15
|
+
QuestionStepsContext,
|
|
16
|
+
QuestionWriteContext
|
|
17
|
+
} from "./contexts.js";
|
|
18
|
+
function PartQuestion(props) {
|
|
19
|
+
const part = useRequired(PartScope, "Chat.PartQuestion requires Chat.Parts.");
|
|
20
|
+
const input = questionInput(part);
|
|
21
|
+
if (!input || !isToolUIPart(part) || part.state !== "input-available") return null;
|
|
22
|
+
return /* @__PURE__ */ jsx(Request, { id: part.toolCallId, input, props }, part.toolCallId);
|
|
23
|
+
}
|
|
24
|
+
function Request({ id, input, props }) {
|
|
25
|
+
const chat = useRequired(ChatContext, "Chat.PartQuestion requires Chat.Root.");
|
|
26
|
+
const draft = useQuestionDraft(input);
|
|
27
|
+
const check = useQuestionCheck(input, draft);
|
|
28
|
+
const steps = useQuestionSteps(input, check);
|
|
29
|
+
const write = useQuestionWrite(chat, id);
|
|
30
|
+
const element = usePart("form", props, {
|
|
31
|
+
locked: { "aria-label": input.title, "aria-busy": write.pending || void 0 },
|
|
32
|
+
behavior: {
|
|
33
|
+
onSubmit: (event) => {
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
if (write.pending) return;
|
|
36
|
+
if (steps.index < steps.count - 1) steps.move("next");
|
|
37
|
+
else if (steps.move("finish")) void write.run(draft.answers);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return /* @__PURE__ */ jsx(
|
|
42
|
+
Provide,
|
|
43
|
+
{
|
|
44
|
+
values: [
|
|
45
|
+
[QuestionInputContext, input],
|
|
46
|
+
[QuestionDraftContext, draft],
|
|
47
|
+
[QuestionCheckContext, check],
|
|
48
|
+
[QuestionStepsContext, steps],
|
|
49
|
+
[QuestionWriteContext, write]
|
|
50
|
+
],
|
|
51
|
+
children: element
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
PartQuestion
|
|
57
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReasoningUIPart } from "ai";
|
|
2
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
3
|
+
type PartReasoningState = ReasoningUIPart & {
|
|
4
|
+
streaming: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* A model thinking out loud, the SDK's `reasoning` part, and whether it has stopped.
|
|
8
|
+
*
|
|
9
|
+
* `streaming` is what lets one block be open while it fills and closed once the answer
|
|
10
|
+
* starts, which is the convention every product settled on: the trace is interesting while
|
|
11
|
+
* it is the only thing happening and noise the moment it is not. A trace the SDK still
|
|
12
|
+
* holds as `streaming` on an answer nobody is writing was cut off, and is over too.
|
|
13
|
+
*/
|
|
14
|
+
export declare function PartReasoning({ children }: GateProps<PartReasoningState>): import("react").JSX.Element | null;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useChat } from "@ai-sdk/react";
|
|
4
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
5
|
+
import { useReasoning } from "../hooks/use-reasoning.js";
|
|
6
|
+
import { ChatContext, MessageScope, PartScope, ReasoningContext } from "./contexts.js";
|
|
7
|
+
import { gateContent } from "./gate-content.js";
|
|
8
|
+
import { isWriting } from "./writing.js";
|
|
9
|
+
function PartReasoning({ children }) {
|
|
10
|
+
const part = useRequired(PartScope, "Chat.PartReasoning must be inside <Chat.Parts>.");
|
|
11
|
+
return part.type === "reasoning" ? /* @__PURE__ */ jsx(Trace, { part, children }) : null;
|
|
12
|
+
}
|
|
13
|
+
function Trace({
|
|
14
|
+
part,
|
|
15
|
+
children
|
|
16
|
+
}) {
|
|
17
|
+
const message = useRequired(MessageScope, "Chat.PartReasoning must be inside <Chat.Messages>.");
|
|
18
|
+
const chat = useRequired(ChatContext, "Chat.PartReasoning must be inside <Chat.Root>.");
|
|
19
|
+
const { messages, status } = useChat({ chat });
|
|
20
|
+
const streaming = part.state === "streaming" && isWriting(message, messages, status);
|
|
21
|
+
const reasoning = useReasoning(streaming);
|
|
22
|
+
return /* @__PURE__ */ jsx(ReasoningContext, { value: reasoning, children: gateContent(children, { ...part, streaming }) });
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
PartReasoning
|
|
26
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSources } from "../hooks/use-sources.js";
|
|
3
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { MessageScope, PartScope } from "./contexts.js";
|
|
5
|
+
import { gateContent } from "./gate-content.js";
|
|
6
|
+
function PartSource({ children }) {
|
|
7
|
+
const message = useRequired(MessageScope, "Chat.PartSource requires Chat.Messages.");
|
|
8
|
+
const part = useRequired(PartScope, "Chat.PartSource requires Chat.Parts.");
|
|
9
|
+
const sources = useSources(message);
|
|
10
|
+
if (part.type !== "source-url" && part.type !== "source-document") return null;
|
|
11
|
+
const first = message.parts.find(
|
|
12
|
+
(p) => p.type === part.type && "sourceId" in p && p.sourceId === part.sourceId
|
|
13
|
+
);
|
|
14
|
+
if (first !== part) return null;
|
|
15
|
+
const source = sources.find((s) => s.key === `${part.type}:${part.sourceId}`);
|
|
16
|
+
return source ? gateContent(children, { source }) : null;
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
PartSource
|
|
20
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TextUIPart } from "ai";
|
|
2
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
3
|
+
import type { AiChatMessage } from "../services/types";
|
|
4
|
+
type PartTextState = TextUIPart & {
|
|
5
|
+
role: AiChatMessage["role"];
|
|
6
|
+
streaming: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* One run of prose, the SDK's `text` part. A message has several when something happened
|
|
10
|
+
* between them.
|
|
11
|
+
*
|
|
12
|
+
* The role comes with it because whose text this is decides whether it is markup: a model
|
|
13
|
+
* writes markdown and means it, and a person who types `2 * 3 * 4` means three numbers.
|
|
14
|
+
*/
|
|
15
|
+
export declare function PartText({ children }: GateProps<PartTextState>): import("react").JSX.Element | null;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useChat } from "@ai-sdk/react";
|
|
4
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
5
|
+
import { ChatContext, MessageScope, PartScope } from "./contexts.js";
|
|
6
|
+
import { isWriting } from "./writing.js";
|
|
7
|
+
import { gateContent } from "./gate-content.js";
|
|
8
|
+
function PartText({ children }) {
|
|
9
|
+
const part = useRequired(PartScope, "Chat.PartText must be inside <Chat.Parts>.");
|
|
10
|
+
const message = useRequired(MessageScope, "Chat.PartText must be inside <Chat.Messages>.");
|
|
11
|
+
if (part.type !== "text") return null;
|
|
12
|
+
return /* @__PURE__ */ jsx(Text, { part, message, children });
|
|
13
|
+
}
|
|
14
|
+
function Text({
|
|
15
|
+
part,
|
|
16
|
+
message,
|
|
17
|
+
children
|
|
18
|
+
}) {
|
|
19
|
+
const chat = useRequired(ChatContext, "Chat.PartText requires Chat.Root.");
|
|
20
|
+
const { messages, status } = useChat({ chat });
|
|
21
|
+
return gateContent(children, {
|
|
22
|
+
...part,
|
|
23
|
+
role: message.role,
|
|
24
|
+
streaming: part.state === "streaming" && isWriting(message, messages, status)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
PartText
|
|
29
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type DynamicToolUIPart, type ToolUIPart } from "ai";
|
|
2
|
+
import { type GateProps } from "@slices.sh/core/part";
|
|
3
|
+
type PartToolState = (ToolUIPart | DynamicToolUIPart) & {
|
|
4
|
+
toolName: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* One tool call, the SDK's `tool-<name>` or `dynamic-tool` part, wherever it has got to.
|
|
8
|
+
*
|
|
9
|
+
* The state reaches the screen because the seven of them want different things: an input
|
|
10
|
+
* still arriving is a shimmer, an output is a disclosure, a denial is a sentence and an
|
|
11
|
+
* error is a different sentence. One "called a tool" card for all seven would be six lies.
|
|
12
|
+
* `toolName` is the SDK's own reading of the part's type, beside everything the part holds.
|
|
13
|
+
* → docs/rules/capability-honesty.md
|
|
14
|
+
*/
|
|
15
|
+
export declare function PartTool({ children }: GateProps<PartToolState>): import("react").ReactNode;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { getToolName, isToolUIPart } from "ai";
|
|
3
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { questionInput } from "../hooks/use-question-draft.js";
|
|
5
|
+
import { PartScope } from "./contexts.js";
|
|
6
|
+
import { gateContent } from "./gate-content.js";
|
|
7
|
+
function PartTool({ children }) {
|
|
8
|
+
const part = useRequired(PartScope, "Chat.PartTool must be inside <Chat.Parts>.");
|
|
9
|
+
if (!isToolUIPart(part) || questionInput(part)) return null;
|
|
10
|
+
return gateContent(children, { ...part, toolName: getToolName(part) });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
PartTool
|
|
14
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RootProps } from "@slices.sh/core/part";
|
|
2
|
+
/**
|
|
3
|
+
* A message's parts, in the order the model produced them, exactly as the AI SDK holds them.
|
|
4
|
+
*
|
|
5
|
+
* The order is the content. Reasoning before an answer, a tool call between two halves of
|
|
6
|
+
* one, a citation after both — a transcript that grouped by kind would say the model did
|
|
7
|
+
* things in an order it did not. Each kind gates itself inside here, and a kind no gate
|
|
8
|
+
* draws — a step boundary, an app's own `data-*` part — draws nothing.
|
|
9
|
+
* → docs/rules/states-gate-themselves.md
|
|
10
|
+
*/
|
|
11
|
+
export declare function Parts({ children }: RootProps): import("react").JSX.Element[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRequired } from "@slices.sh/core/part";
|
|
4
|
+
import { MessageScope, PartScope } from "./contexts.js";
|
|
5
|
+
function Parts({ children }) {
|
|
6
|
+
const message = useRequired(MessageScope, "Chat.Parts must be inside <Chat.Messages>.");
|
|
7
|
+
return message.parts.map((part, index) => /* @__PURE__ */ jsx(PartScope, { value: part, children }, `${index}:${part.type}`));
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
Parts
|
|
11
|
+
};
|