Skip to main content

turnframe_runtime/compose/
copy.rs

1//! The codes and the copy of what composition writes itself.
2
3use turnframe_core::locale::LocalizedText;
4
5/// Stable codes of the notices composition emits itself.
6pub mod notice {
7    /// A command did not commit, so nothing may be claimed about it.
8    pub const COMMAND_FAILED: &str = "turnframe.notice.command_failed";
9    /// An external effect was attempted and its result is not known yet (I15).
10    pub const VERIFICATION_IN_PROGRESS: &str = "turnframe.notice.verification_in_progress";
11    /// The case moved while the turn was being planned.
12    pub const REVISION_CONFLICT: &str = "turnframe.notice.revision_conflict";
13    /// A card the turn wanted to show could not be persisted, so it is not
14    /// there and nothing refers to it (§15.5).
15    pub const INTERACTION_UNAVAILABLE: &str = "turnframe.notice.interaction_unavailable";
16    /// The final state could not be verified, so no follow-up was generated.
17    pub const CASE_REFRESH_UNAVAILABLE: &str = "turnframe.notice.case_refresh_unavailable";
18    /// A model-authored block claimed something no receipt backs and was
19    /// withheld (§17.4, I16).
20    /// The turn spent its resource budget, so nothing further was generated
21    /// (spec §11.1). The deterministic blocks are unaffected.
22    pub const BUDGET_EXHAUSTED: &str = "turnframe.notice.budget_exhausted";
23    /// The user answered a card by declining the instruction it was guarding,
24    /// so that instruction was not carried out (spec §13.3).
25    pub const INSTRUCTION_DECLINED: &str = "turnframe.notice.instruction_declined";
26}
27
28/// Server-authored copy for everything composition writes itself.
29#[derive(Debug, Clone, PartialEq, Eq)]
30#[non_exhaustive]
31pub struct CompositionCopy {
32    /// Body of the [`notice::COMMAND_FAILED`] notice.
33    pub command_failed: LocalizedText,
34    /// Body of the [`notice::VERIFICATION_IN_PROGRESS`] notice.
35    pub verification_in_progress: LocalizedText,
36    /// Body of the [`notice::REVISION_CONFLICT`] notice.
37    pub revision_conflict: LocalizedText,
38    /// Body of the [`notice::INTERACTION_UNAVAILABLE`] notice.
39    pub interaction_unavailable: LocalizedText,
40    /// Body of the [`notice::CASE_REFRESH_UNAVAILABLE`] notice.
41    pub case_refresh_unavailable: LocalizedText,
42    /// Text of an answer the runtime could not produce at all.
43    pub answer_unsupported: LocalizedText,
44    /// Text of an answer whose sources were unavailable.
45    pub answer_source_unavailable: LocalizedText,
46    /// Text of an answer no model wrote this time.
47    pub answer_not_written: LocalizedText,
48    /// Body of the [`notice::BUDGET_EXHAUSTED`] notice.
49    pub budget_exhausted: LocalizedText,
50    /// Body of the [`notice::INSTRUCTION_DECLINED`] notice.
51    pub instruction_declined: LocalizedText,
52    /// The text of an answer that ran past the configured length.
53    ///
54    /// Only reachable in a deployment that configured a length at all; the
55    /// library ships none.
56    pub answer_too_long: LocalizedText,
57}
58
59impl CompositionCopy {
60    /// The built-in copy: English, with Italian.
61    #[must_use]
62    pub fn standard() -> Self {
63        crate::copy::ServerCopy::translated(Self::english(), "it", ITALIAN)
64    }
65
66    /// English alone.
67    #[must_use]
68    pub fn english() -> Self {
69        Self {
70            command_failed: LocalizedText::new("That did not go through, so nothing was changed."),
71            verification_in_progress: LocalizedText::new(
72                "The request was sent and its result is not confirmed yet. It is being verified.",
73            ),
74            revision_conflict: LocalizedText::new(
75                "This record changed while the request was being prepared, so it was not applied.",
76            ),
77            interaction_unavailable: LocalizedText::new(
78                "The confirmation could not be prepared, so nothing is waiting for an answer.",
79            ),
80            case_refresh_unavailable: LocalizedText::new(
81                "The latest state could not be verified, so no follow-up was prepared.",
82            ),
83            answer_unsupported: LocalizedText::new(
84                "This question is outside what can be answered here.",
85            ),
86            answer_source_unavailable: LocalizedText::new(
87                "The sources needed to answer this were not available.",
88            ),
89            answer_not_written: LocalizedText::new(
90                "The answer to this could not be written just now. Asking again usually works.",
91            ),
92            budget_exhausted: LocalizedText::new(
93                "This turn reached its limit, so nothing further was written. What was already recorded still stands.",
94            ),
95            instruction_declined: LocalizedText::new(
96                "You said no, so that instruction was not carried out.",
97            ),
98            answer_too_long: LocalizedText::new(
99                "The reply came back longer than this assistant is set up to send, so it was not sent.",
100            ),
101        }
102    }
103}
104
105impl Default for CompositionCopy {
106    fn default() -> Self {
107        Self::standard()
108    }
109}
110
111crate::copy::server_copy!(
112    CompositionCopy,
113    [
114        command_failed,
115        verification_in_progress,
116        revision_conflict,
117        interaction_unavailable,
118        case_refresh_unavailable,
119        answer_unsupported,
120        answer_source_unavailable,
121        answer_not_written,
122        budget_exhausted,
123        instruction_declined,
124        answer_too_long
125    ]
126);
127
128/// The built-in Italian of [`CompositionCopy`], by field.
129const ITALIAN: &[(&str, &str)] = &[
130    (
131        "command_failed",
132        "Non è andato a buon fine, quindi non è cambiato nulla.",
133    ),
134    (
135        "verification_in_progress",
136        "La richiesta è stata inviata e il risultato non è ancora confermato: è in verifica.",
137    ),
138    (
139        "revision_conflict",
140        "Questa scheda è cambiata mentre la richiesta veniva preparata, quindi non è stata applicata.",
141    ),
142    (
143        "interaction_unavailable",
144        "Non è stato possibile preparare la conferma, quindi non c'è nulla in attesa di risposta.",
145    ),
146    (
147        "case_refresh_unavailable",
148        "Non è stato possibile verificare lo stato più recente, quindi non ho preparato il passo successivo.",
149    ),
150    (
151        "answer_unsupported",
152        "A questa domanda non posso rispondere da qui.",
153    ),
154    (
155        "answer_source_unavailable",
156        "Le fonti necessarie per rispondere non erano disponibili.",
157    ),
158    (
159        "answer_not_written",
160        "Al momento non è stato possibile scrivere la risposta. Di solito basta chiedere di nuovo.",
161    ),
162    (
163        "budget_exhausted",
164        "Questa richiesta ha raggiunto il suo limite, quindi non ho scritto altro. Quello che è già stato registrato resta valido.",
165    ),
166    (
167        "instruction_declined",
168        "Hai detto di no, quindi quell'istruzione non è stata eseguita.",
169    ),
170    (
171        "answer_too_long",
172        "La risposta era più lunga di quanto questo assistente possa inviare, quindi non è stata inviata.",
173    ),
174];