@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,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { isSkippedQuestion, questionInput } from "../services/types.js";
|
|
4
|
+
const BLANK = { picked: [], other: false, text: "" };
|
|
5
|
+
function answerOf(question, entry) {
|
|
6
|
+
const text = entry.other ? entry.text.trim() : "";
|
|
7
|
+
const values = [...entry.picked, ...text ? [text] : []];
|
|
8
|
+
if (!values.length) return void 0;
|
|
9
|
+
return question.multiple ? values : values[0];
|
|
10
|
+
}
|
|
11
|
+
function applied(entry, question, change) {
|
|
12
|
+
switch (change.type) {
|
|
13
|
+
case "choose":
|
|
14
|
+
if (!question.multiple) return { ...entry, picked: [change.value], other: false };
|
|
15
|
+
return {
|
|
16
|
+
...entry,
|
|
17
|
+
picked: entry.picked.includes(change.value) ? entry.picked.filter((item) => item !== change.value) : [...entry.picked, change.value]
|
|
18
|
+
};
|
|
19
|
+
case "toggle-other":
|
|
20
|
+
return question.multiple ? { ...entry, other: !entry.other } : { ...entry, picked: [], other: true };
|
|
21
|
+
case "select-other":
|
|
22
|
+
return { ...entry, picked: question.multiple ? entry.picked : [], other: true };
|
|
23
|
+
case "write-other":
|
|
24
|
+
return { ...entry, text: change.text, picked: question.multiple ? entry.picked : [], other: true };
|
|
25
|
+
case "clear":
|
|
26
|
+
return BLANK;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function useQuestionDraft(input) {
|
|
30
|
+
const [entries, setEntries] = useState({});
|
|
31
|
+
const change = useCallback(
|
|
32
|
+
(name, edit) => {
|
|
33
|
+
const question = input.questions.find((q) => q.name === name);
|
|
34
|
+
if (!question) return;
|
|
35
|
+
setEntries((current) => ({ ...current, [name]: applied(current[name] ?? BLANK, question, edit) }));
|
|
36
|
+
},
|
|
37
|
+
[input]
|
|
38
|
+
);
|
|
39
|
+
return useMemo(() => {
|
|
40
|
+
const answers = {};
|
|
41
|
+
for (const question of input.questions) {
|
|
42
|
+
const answer = answerOf(question, entries[question.name] ?? BLANK);
|
|
43
|
+
if (answer !== void 0) answers[question.name] = answer;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
answers,
|
|
47
|
+
picked: (name, value) => entries[name]?.picked.includes(value) ?? false,
|
|
48
|
+
other: (name) => ({ on: entries[name]?.other ?? false, text: entries[name]?.text ?? "" }),
|
|
49
|
+
change
|
|
50
|
+
};
|
|
51
|
+
}, [input, entries, change]);
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
isSkippedQuestion,
|
|
55
|
+
questionInput,
|
|
56
|
+
useQuestionDraft
|
|
57
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Questionnaire } from "../services/types";
|
|
2
|
+
import type { QuestionCheck } from "./use-question-check";
|
|
3
|
+
export type StepMove = "back"
|
|
4
|
+
/** Stays, and says why, while the question being left has no good answer. */
|
|
5
|
+
| "next"
|
|
6
|
+
/** Goes where the first answer to fix is, saying why in each, unless every answer can be sent. */
|
|
7
|
+
| "finish";
|
|
8
|
+
export type QuestionSteps = {
|
|
9
|
+
/** Zero-based; a form of one question is its own last step. */
|
|
10
|
+
index: number;
|
|
11
|
+
count: number;
|
|
12
|
+
/** The person went somewhere, so the arriving question takes focus; the first one never does. */
|
|
13
|
+
moved: boolean;
|
|
14
|
+
active(name: string): boolean;
|
|
15
|
+
/** True when the move went through: for finish, when everything can be sent. */
|
|
16
|
+
move(move: StepMove): boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare function useQuestionSteps(input: Questionnaire, check: QuestionCheck): QuestionSteps;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
function useQuestionSteps(input, check) {
|
|
4
|
+
const [index, setIndex] = useState(0);
|
|
5
|
+
const [moved, setMoved] = useState(false);
|
|
6
|
+
const count = input.questions.length;
|
|
7
|
+
const move = useCallback(
|
|
8
|
+
(step) => {
|
|
9
|
+
const go = (to) => {
|
|
10
|
+
setIndex(to);
|
|
11
|
+
setMoved(true);
|
|
12
|
+
return true;
|
|
13
|
+
};
|
|
14
|
+
if (step === "back") return index > 0 && go(index - 1);
|
|
15
|
+
if (step === "next")
|
|
16
|
+
return index < count - 1 && !check.reveal([input.questions[index].name]) && go(index + 1);
|
|
17
|
+
const names = input.questions.map((q) => q.name);
|
|
18
|
+
if (!check.reveal(names)) return true;
|
|
19
|
+
go(names.findIndex((name) => check.problem(name) !== null));
|
|
20
|
+
return false;
|
|
21
|
+
},
|
|
22
|
+
[index, count, input, check]
|
|
23
|
+
);
|
|
24
|
+
return useMemo(
|
|
25
|
+
() => ({ index, count, moved, active: (name) => input.questions[index]?.name === name, move }),
|
|
26
|
+
[index, count, moved, input, move]
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
useQuestionSteps
|
|
31
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type QuestionAnswers } from "../services/types";
|
|
2
|
+
import type { AiChat } from "./use-chat-instance";
|
|
3
|
+
export type QuestionWrite = {
|
|
4
|
+
run(answers: QuestionAnswers): Promise<void>;
|
|
5
|
+
pending: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
};
|
|
8
|
+
export declare function useQuestionWrite(chat: AiChat, id: string): QuestionWrite;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { answerQuestions } from "../services/types.js";
|
|
4
|
+
function useQuestionWrite(chat, id) {
|
|
5
|
+
const [pending, setPending] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const run = useCallback(
|
|
8
|
+
async (answers) => {
|
|
9
|
+
setPending(true);
|
|
10
|
+
setError(null);
|
|
11
|
+
try {
|
|
12
|
+
await answerQuestions(chat, id, answers);
|
|
13
|
+
} catch (error2) {
|
|
14
|
+
setError(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
15
|
+
} finally {
|
|
16
|
+
setPending(false);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
[chat, id]
|
|
20
|
+
);
|
|
21
|
+
return useMemo(() => ({ run, pending, error }), [run, pending, error]);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
useQuestionWrite
|
|
25
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Explicit user playback, one owner at a time; unmount never cancels another message's voice. */
|
|
2
|
+
export declare function useReadAloud(text: string): {
|
|
3
|
+
available: boolean;
|
|
4
|
+
playing: boolean;
|
|
5
|
+
failed: boolean;
|
|
6
|
+
toggle: () => void;
|
|
7
|
+
};
|
|
8
|
+
export type ReadAloud = ReturnType<typeof useReadAloud>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState, useSyncExternalStore } from "react";
|
|
3
|
+
let reading = { owner: null, phase: "idle" };
|
|
4
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
5
|
+
const subscribe = (listener) => {
|
|
6
|
+
listeners.add(listener);
|
|
7
|
+
return () => {
|
|
8
|
+
listeners.delete(listener);
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
const snapshot = () => reading;
|
|
12
|
+
const server = () => IDLE;
|
|
13
|
+
const IDLE = { owner: null, phase: "idle" };
|
|
14
|
+
const supported = () => typeof window !== "undefined" && "speechSynthesis" in window && "SpeechSynthesisUtterance" in window;
|
|
15
|
+
function publish(next) {
|
|
16
|
+
reading = next;
|
|
17
|
+
listeners.forEach((listener) => listener());
|
|
18
|
+
}
|
|
19
|
+
function stop(owner) {
|
|
20
|
+
if (reading.owner !== owner) return;
|
|
21
|
+
publish(IDLE);
|
|
22
|
+
window.speechSynthesis.cancel();
|
|
23
|
+
}
|
|
24
|
+
function useReadAloud(text) {
|
|
25
|
+
const [owner] = useState(() => ({}));
|
|
26
|
+
const current = useSyncExternalStore(subscribe, snapshot, server);
|
|
27
|
+
const available = useSyncExternalStore(subscribe, supported, () => false);
|
|
28
|
+
useEffect(
|
|
29
|
+
() => () => {
|
|
30
|
+
if (supported()) stop(owner);
|
|
31
|
+
},
|
|
32
|
+
[owner, text]
|
|
33
|
+
);
|
|
34
|
+
const playing = current.owner === owner && current.phase === "playing";
|
|
35
|
+
const failed = current.owner === owner && current.phase === "error";
|
|
36
|
+
const toggle = () => {
|
|
37
|
+
if (!available || !text.trim()) return;
|
|
38
|
+
if (reading.owner === owner && reading.phase === "playing") return stop(owner);
|
|
39
|
+
publish(IDLE);
|
|
40
|
+
window.speechSynthesis.cancel();
|
|
41
|
+
const run = { owner, phase: "playing" };
|
|
42
|
+
publish(run);
|
|
43
|
+
try {
|
|
44
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
45
|
+
utterance.onend = () => {
|
|
46
|
+
if (reading === run) publish(IDLE);
|
|
47
|
+
};
|
|
48
|
+
utterance.onerror = () => {
|
|
49
|
+
if (reading === run) publish({ owner, phase: "error" });
|
|
50
|
+
};
|
|
51
|
+
window.speechSynthesis.speak(utterance);
|
|
52
|
+
} catch {
|
|
53
|
+
if (reading === run) publish({ owner, phase: "error" });
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
return { available, playing, failed, toggle };
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
useReadAloud
|
|
60
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type Reasoning = {
|
|
2
|
+
seconds: number | null;
|
|
3
|
+
streaming: boolean;
|
|
4
|
+
open: boolean;
|
|
5
|
+
setOpen(open: boolean): void;
|
|
6
|
+
};
|
|
7
|
+
/** Historical traces have no measured duration; only a trace observed live gets a timer. */
|
|
8
|
+
export declare function useReasoning(streaming: boolean): Reasoning;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
function useReasoning(streaming) {
|
|
4
|
+
const [started] = useState(() => streaming ? Date.now() : null);
|
|
5
|
+
const [seconds, setSeconds] = useState(() => streaming ? 0 : null);
|
|
6
|
+
const [open, set] = useState(streaming);
|
|
7
|
+
const touched = useRef(false);
|
|
8
|
+
const setOpen = useCallback((value) => {
|
|
9
|
+
touched.current = true;
|
|
10
|
+
set(value);
|
|
11
|
+
}, []);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (started === null) return;
|
|
14
|
+
const update = () => setSeconds(Math.max(0, Math.floor((Date.now() - started) / 1e3)));
|
|
15
|
+
if (streaming) {
|
|
16
|
+
const timer = setInterval(update, 1e3);
|
|
17
|
+
return () => clearInterval(timer);
|
|
18
|
+
}
|
|
19
|
+
const finish = setTimeout(update, 0);
|
|
20
|
+
const fold = setTimeout(() => {
|
|
21
|
+
if (!touched.current) set(false);
|
|
22
|
+
}, 1e3);
|
|
23
|
+
return () => {
|
|
24
|
+
clearTimeout(finish);
|
|
25
|
+
clearTimeout(fold);
|
|
26
|
+
};
|
|
27
|
+
}, [streaming, started]);
|
|
28
|
+
return useMemo(() => ({ seconds, streaming, open, setOpen }), [seconds, streaming, open, setOpen]);
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
useReasoning
|
|
32
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AiChat } from "./use-chat-instance";
|
|
2
|
+
import type { ToolApprovalMemory } from "./use-tool-approval-memory";
|
|
3
|
+
export type ApprovalAutomation = {
|
|
4
|
+
failure: {
|
|
5
|
+
id: string;
|
|
6
|
+
error: Error;
|
|
7
|
+
} | null;
|
|
8
|
+
};
|
|
9
|
+
export declare function useRememberedApprovals(chat: AiChat, policy: ToolApprovalMemory): ApprovalAutomation;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { getToolName, isToolUIPart } from "ai";
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { respondToApproval } from "../services/types.js";
|
|
6
|
+
function useRememberedApprovals(chat, policy) {
|
|
7
|
+
const { messages } = useChat({ chat });
|
|
8
|
+
const attempts = useRef(/* @__PURE__ */ new WeakMap());
|
|
9
|
+
const mounted = useRef(true);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
mounted.current = true;
|
|
12
|
+
return () => {
|
|
13
|
+
mounted.current = false;
|
|
14
|
+
};
|
|
15
|
+
}, []);
|
|
16
|
+
const [failure, setFailure] = useState(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!policy.enabled) return;
|
|
19
|
+
let attempted = attempts.current.get(chat);
|
|
20
|
+
if (!attempted) {
|
|
21
|
+
attempted = /* @__PURE__ */ new Set();
|
|
22
|
+
attempts.current.set(chat, attempted);
|
|
23
|
+
}
|
|
24
|
+
for (const message of messages)
|
|
25
|
+
for (const part of message.parts) {
|
|
26
|
+
if (!isToolUIPart(part) || part.state !== "approval-requested" || !policy.tools.includes(getToolName(part)) || attempted.has(part.approval.id))
|
|
27
|
+
continue;
|
|
28
|
+
const id = part.approval.id;
|
|
29
|
+
attempted.add(id);
|
|
30
|
+
void respondToApproval(chat, id, true).catch((error) => {
|
|
31
|
+
if (mounted.current)
|
|
32
|
+
setFailure({ id, error: error instanceof Error ? error : new Error(String(error)) });
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}, [chat, messages, policy]);
|
|
36
|
+
return useMemo(() => ({ failure }), [failure]);
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
useRememberedApprovals
|
|
40
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Chat } from "@ai-sdk/react";
|
|
2
|
+
import type { AiChatMessage } from "../services/types";
|
|
3
|
+
/**
|
|
4
|
+
* Tells the tab when a turn was refused because the server lacks configuration.
|
|
5
|
+
*
|
|
6
|
+
* On the chat whatever made it, because an app that hands the screen its own `Chat` still
|
|
7
|
+
* points it at the installed route, and the route's answer is the same either way.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useReportMissingConfiguration(chat: Chat<AiChatMessage>): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { reportIfMissingConfiguration } from "@slices.sh/core/configuration";
|
|
5
|
+
import { refusalBody } from "./chat-refusal.js";
|
|
6
|
+
function useReportMissingConfiguration(chat) {
|
|
7
|
+
const { error } = useChat({ chat });
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (error) reportIfMissingConfiguration(refusalBody(error));
|
|
10
|
+
}, [error]);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useReportMissingConfiguration
|
|
14
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { retryAtOf } from "./chat-refusal.js";
|
|
4
|
+
function useRetryDelay(error) {
|
|
5
|
+
const deadline = retryAtOf(error);
|
|
6
|
+
const [now, setNow] = useState(() => Date.now());
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (deadline === null) return;
|
|
9
|
+
const tick = () => setNow(Date.now());
|
|
10
|
+
const timer = setInterval(tick, 250);
|
|
11
|
+
return () => clearInterval(timer);
|
|
12
|
+
}, [deadline]);
|
|
13
|
+
return { seconds: deadline === null ? 0 : Math.max(0, Math.ceil((deadline - now) / 1e3)), deadline };
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
useRetryDelay
|
|
17
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
function useSentDraft(message) {
|
|
4
|
+
const text = message.role === "user" ? message.parts.flatMap((part) => part.type === "text" ? [part.text] : []).join("\n") : "";
|
|
5
|
+
const key = message.id + "\0" + text;
|
|
6
|
+
const [state, setState] = useState({ key, value: null });
|
|
7
|
+
if (state.key !== key) setState({ key, value: null });
|
|
8
|
+
const returnFocus = useRef(null);
|
|
9
|
+
const wasEditing = useRef(false);
|
|
10
|
+
const start = useCallback(() => {
|
|
11
|
+
returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
12
|
+
setState({ key, value: text });
|
|
13
|
+
}, [key, text]);
|
|
14
|
+
const set = useCallback((value2) => setState({ key, value: value2 }), [key]);
|
|
15
|
+
const cancel = useCallback(() => setState({ key, value: null }), [key]);
|
|
16
|
+
const value = state.key === key ? state.value : null;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (value === null && wasEditing.current && returnFocus.current?.isConnected) returnFocus.current.focus();
|
|
19
|
+
wasEditing.current = value !== null;
|
|
20
|
+
}, [value]);
|
|
21
|
+
return useMemo(() => ({ value, start, set, cancel }), [value, start, set, cancel]);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
useSentDraft
|
|
25
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AiChat } from "./use-chat-instance";
|
|
2
|
+
export type ToolApprovalMemory = {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
tools: readonly string[];
|
|
5
|
+
remember(tool: string): void;
|
|
6
|
+
forget(tool: string): void;
|
|
7
|
+
};
|
|
8
|
+
export declare function useToolApprovalMemory(chat: AiChat, enabled?: boolean): ToolApprovalMemory;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMemo, useSyncExternalStore } from "react";
|
|
3
|
+
import { toolApprovalMemory } from "../services/types.js";
|
|
4
|
+
const EMPTY = [];
|
|
5
|
+
const server = () => EMPTY;
|
|
6
|
+
function useToolApprovalMemory(chat, enabled = true) {
|
|
7
|
+
const memory = useMemo(() => toolApprovalMemory(chat), [chat]);
|
|
8
|
+
const tools = useSyncExternalStore(memory.watch, memory.snapshot, server);
|
|
9
|
+
return useMemo(
|
|
10
|
+
() => ({ enabled, tools, remember: memory.remember, forget: memory.forget }),
|
|
11
|
+
[enabled, tools, memory]
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
useToolApprovalMemory
|
|
16
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AiChat } from "./use-chat-instance";
|
|
2
|
+
export type ToolApproval = {
|
|
3
|
+
run(input: {
|
|
4
|
+
approved: boolean;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
pending: boolean;
|
|
7
|
+
error: Error | null;
|
|
8
|
+
reset(): void;
|
|
9
|
+
};
|
|
10
|
+
export declare function useToolApproval(chat: AiChat, id: string): ToolApproval;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
import { respondToApproval } from "../services/types.js";
|
|
4
|
+
function useToolApproval(chat, id) {
|
|
5
|
+
const [pending, setPending] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
const reset = useCallback(() => setError(null), []);
|
|
8
|
+
const run = useCallback(
|
|
9
|
+
async ({ approved }) => {
|
|
10
|
+
setPending(true);
|
|
11
|
+
setError(null);
|
|
12
|
+
try {
|
|
13
|
+
await respondToApproval(chat, id, approved);
|
|
14
|
+
} catch (caught) {
|
|
15
|
+
setError(caught instanceof Error ? caught : new Error(String(caught)));
|
|
16
|
+
} finally {
|
|
17
|
+
setPending(false);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
[chat, id]
|
|
21
|
+
);
|
|
22
|
+
return useMemo(() => ({ run, pending, error, reset }), [run, pending, error, reset]);
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
useToolApproval
|
|
26
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FileUIPart } from "ai";
|
|
2
|
+
import { type Blocker } from "../services/types";
|
|
3
|
+
import type { AiChat } from "./use-chat-instance";
|
|
4
|
+
export type QueuedTurn = {
|
|
5
|
+
id: string;
|
|
6
|
+
text: string;
|
|
7
|
+
draft: string | null;
|
|
8
|
+
files?: FileUIPart[];
|
|
9
|
+
};
|
|
10
|
+
export type QueueChange = {
|
|
11
|
+
type: "edit";
|
|
12
|
+
id: string;
|
|
13
|
+
text: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "begin-edit" | "save-edit" | "cancel-edit" | "remove" | "send-now";
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
18
|
+
/** Skips the open question of this tool call, and moves the turn on. */
|
|
19
|
+
| {
|
|
20
|
+
type: "skip-question";
|
|
21
|
+
toolCallId: string;
|
|
22
|
+
};
|
|
23
|
+
export type TurnQueue = {
|
|
24
|
+
enqueue(text: string, files?: readonly FileUIPart[]): void;
|
|
25
|
+
waiting: number;
|
|
26
|
+
items: readonly QueuedTurn[];
|
|
27
|
+
change(action: QueueChange): void;
|
|
28
|
+
/** What holds the queue besides a running turn: null when nothing does. */
|
|
29
|
+
blockedBy: Blocker | null;
|
|
30
|
+
};
|
|
31
|
+
/** FIFO by default. Editing holds its place; Send now explicitly stops and reprioritizes. */
|
|
32
|
+
export declare function useTurnQueue(chat: AiChat): TurnQueue;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useChat } from "@ai-sdk/react";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
4
|
+
import { blockedBy } from "../services/types.js";
|
|
5
|
+
import { createMailbox } from "./turn-mailbox.js";
|
|
6
|
+
const EMPTY = [];
|
|
7
|
+
const server = () => EMPTY;
|
|
8
|
+
function useTurnQueue(chat) {
|
|
9
|
+
const { status, messages } = useChat({ chat });
|
|
10
|
+
const [box] = useState(createMailbox);
|
|
11
|
+
const items = useSyncExternalStore(box.watch, box.snapshot, server);
|
|
12
|
+
useEffect(() => box.open(), [box]);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
box.drain(chat);
|
|
15
|
+
}, [status, messages, box, chat]);
|
|
16
|
+
const enqueue = useCallback(
|
|
17
|
+
(text, files) => {
|
|
18
|
+
const value = text.trim();
|
|
19
|
+
if (!value && !files?.length) return;
|
|
20
|
+
box.apply({ type: "enqueue", text: value, files }, chat);
|
|
21
|
+
},
|
|
22
|
+
[box, chat]
|
|
23
|
+
);
|
|
24
|
+
const change = useCallback((action) => box.apply(action, chat), [box, chat]);
|
|
25
|
+
const waitingFor = blockedBy(messages, status === "submitted" || status === "streaming");
|
|
26
|
+
return useMemo(
|
|
27
|
+
() => ({ enqueue, items, waiting: items.length, change, blockedBy: waitingFor }),
|
|
28
|
+
[enqueue, items, change, waitingFor]
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
useTurnQueue
|
|
33
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AiChatClient } from "./services/types";
|
|
2
|
+
export type { AiChatClient };
|
|
3
|
+
/**
|
|
4
|
+
* Configures the ai-chat service: services/ai-chat/<config>.config.ts has
|
|
5
|
+
* `export default aiChat({ provider: … })`. This module is client-safe: it holds a
|
|
6
|
+
* description, and the server half of the provider is loaded lazily.
|
|
7
|
+
*/
|
|
8
|
+
export declare const aiChat: <Options extends Record<string, unknown>>(options: {
|
|
9
|
+
provider: import("@slices.sh/core").Provider<AiChatClient>;
|
|
10
|
+
} & Options) => import("@slices.sh/core").ServiceConfig<AiChatClient>;
|
package/dist/index.js
ADDED
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
/** app/api/ai-chat/[config]/[[...path]]/route.ts re-exports these. */
|
|
3
|
+
export declare const GET: (request: Request, context: {
|
|
4
|
+
params: Promise<{
|
|
5
|
+
config?: string;
|
|
6
|
+
path?: string[];
|
|
7
|
+
}> | {
|
|
8
|
+
config?: string;
|
|
9
|
+
path?: string[];
|
|
10
|
+
};
|
|
11
|
+
}) => Promise<Response>, POST: (request: Request, context: {
|
|
12
|
+
params: Promise<{
|
|
13
|
+
config?: string;
|
|
14
|
+
path?: string[];
|
|
15
|
+
}> | {
|
|
16
|
+
config?: string;
|
|
17
|
+
path?: string[];
|
|
18
|
+
};
|
|
19
|
+
}) => Promise<Response>, PUT: (request: Request, context: {
|
|
20
|
+
params: Promise<{
|
|
21
|
+
config?: string;
|
|
22
|
+
path?: string[];
|
|
23
|
+
}> | {
|
|
24
|
+
config?: string;
|
|
25
|
+
path?: string[];
|
|
26
|
+
};
|
|
27
|
+
}) => Promise<Response>, PATCH: (request: Request, context: {
|
|
28
|
+
params: Promise<{
|
|
29
|
+
config?: string;
|
|
30
|
+
path?: string[];
|
|
31
|
+
}> | {
|
|
32
|
+
config?: string;
|
|
33
|
+
path?: string[];
|
|
34
|
+
};
|
|
35
|
+
}) => Promise<Response>, DELETE: (request: Request, context: {
|
|
36
|
+
params: Promise<{
|
|
37
|
+
config?: string;
|
|
38
|
+
path?: string[];
|
|
39
|
+
}> | {
|
|
40
|
+
config?: string;
|
|
41
|
+
path?: string[];
|
|
42
|
+
};
|
|
43
|
+
}) => Promise<Response>;
|