@poodle64/librarian 2026.9.21 → 2026.9.22

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.
Files changed (28) hide show
  1. package/README.md +129 -6
  2. package/dist/chat.svelte.d.ts +189 -0
  3. package/dist/chat.svelte.js +554 -0
  4. package/dist/client.d.ts +29 -6
  5. package/dist/client.js +11 -3
  6. package/dist/components/agent-transcript/agent-transcript.svelte +39 -5
  7. package/dist/components/agent-transcript/agent-transcript.svelte.d.ts +9 -0
  8. package/dist/components/answer-mark/answer-mark.svelte +223 -0
  9. package/dist/components/answer-mark/answer-mark.svelte.d.ts +11 -0
  10. package/dist/components/answer-mark/index.d.ts +2 -0
  11. package/dist/components/answer-mark/index.js +2 -0
  12. package/dist/components/conversation/conversation.svelte +21 -3
  13. package/dist/components/conversation/conversation.svelte.d.ts +9 -0
  14. package/dist/components/conversation-list/conversation-list.svelte +496 -0
  15. package/dist/components/conversation-list/conversation-list.svelte.d.ts +26 -0
  16. package/dist/components/conversation-list/index.d.ts +2 -0
  17. package/dist/components/conversation-list/index.js +2 -0
  18. package/dist/components/fair-use-notice/fair-use-notice.svelte +97 -0
  19. package/dist/components/fair-use-notice/fair-use-notice.svelte.d.ts +11 -0
  20. package/dist/components/fair-use-notice/index.d.ts +2 -0
  21. package/dist/components/fair-use-notice/index.js +2 -0
  22. package/dist/components/working/working.svelte +8 -3
  23. package/dist/components/working/working.svelte.d.ts +3 -0
  24. package/dist/copy.d.ts +40 -0
  25. package/dist/copy.js +36 -1
  26. package/dist/session.svelte.js +1 -1
  27. package/dist/transcript.svelte.js +1 -1
  28. package/package.json +5 -1
package/dist/copy.d.ts CHANGED
@@ -31,6 +31,8 @@ export interface LibrarianCopy {
31
31
  answerFailed: string;
32
32
  /** Shown when the stream never opened, or died mid-answer. */
33
33
  unreachable: string;
34
+ /** Shown on a question stopped before a word of its answer came. */
35
+ noAnswer: string;
34
36
  /** Heading over the list of what an answer cited. */
35
37
  sources: string;
36
38
  /** Heading over the follow-up questions the persona offered. */
@@ -55,6 +57,41 @@ export interface LibrarianCopy {
55
57
  /** An artefact card's action, and the same action while it is open. */
56
58
  openArtefact: string;
57
59
  showingArtefact: string;
60
+ /** Beside the clock while the question waits behind someone else's. */
61
+ waiting: string;
62
+ /** Beside the clock on an answer this page did not start. */
63
+ stillAnswering: string;
64
+ /** The answer mark: the two verdicts, the optional note, and after. */
65
+ markHelpful: string;
66
+ markNotHelpful: string;
67
+ markNote: string;
68
+ markSend: string;
69
+ markNoted: string;
70
+ markFailed: string;
71
+ /** The fair-use notice, while there are questions left and once there are
72
+ * none, filled by `fill()`: `{resets}` is a time already, "midnight" or
73
+ * "2:00 pm". */
74
+ questionsLeft: string;
75
+ limitReached: string;
76
+ /** `{resets}` when the allowance comes back at the turn of the day. */
77
+ midnight: string;
78
+ support: string;
79
+ /** The conversation list. */
80
+ pastQuestions: string;
81
+ newQuestion: string;
82
+ readingPastQuestions: string;
83
+ noPastQuestions: string;
84
+ pastQuestionsFailed: string;
85
+ conversationActions: string;
86
+ rename: string;
87
+ download: string;
88
+ delete: string;
89
+ save: string;
90
+ cancel: string;
91
+ deletePrompt: string;
92
+ renameFailed: string;
93
+ downloadFailed: string;
94
+ deleteFailed: string;
58
95
  }
59
96
  /**
60
97
  * The display name for a persona a host identified by its slug.
@@ -71,6 +108,9 @@ export declare function personaName(name: string): string;
71
108
  * says it is, and a sentence that guesses is wrong for half of them.
72
109
  */
73
110
  export declare function copyFor(name?: string): LibrarianCopy;
111
+ /** A sentence with `{name}` places, filled. A place with no value stays as
112
+ * written, so a host's override that drops one loses nothing else. */
113
+ export declare function fill(template: string, values: Record<string, string | number>): string;
74
114
  /** The library's own words, for a host that names no persona. */
75
115
  export declare const DEFAULT_COPY: LibrarianCopy;
76
116
  /**
package/dist/copy.js CHANGED
@@ -59,6 +59,7 @@ export function copyFor(name = DEFAULT_PERSONA) {
59
59
  // simply stops is the one thing a reader must not have to guess about.
60
60
  answerFailed: `${who} stopped before finishing this one.`,
61
61
  unreachable: `${who} can't be reached right now.`,
62
+ noAnswer: 'Stopped before an answer came.',
62
63
  sources: 'Sources',
63
64
  suggestions: 'Ask next',
64
65
  scope: `What ${who} answers from`,
@@ -74,9 +75,43 @@ export function copyFor(name = DEFAULT_PERSONA) {
74
75
  closeSource: 'Close source',
75
76
  documentUnavailable: "That document can't be opened right now.",
76
77
  openArtefact: 'Open',
77
- showingArtefact: 'Showing'
78
+ showingArtefact: 'Showing',
79
+ waiting: `${who} is answering another question first`,
80
+ stillAnswering: `${who} is still answering`,
81
+ markHelpful: 'Helpful',
82
+ markNotHelpful: 'Not helpful',
83
+ markNote: 'Anything to add? (optional)',
84
+ markSend: 'Send',
85
+ markNoted: 'Thanks, noted.',
86
+ markFailed: "That couldn't be sent. Nothing was recorded.",
87
+ // The industry wording, whole: the number, that it is a fair-use limit
88
+ // rather than a fault, and when it comes back. No apology.
89
+ questionsLeft: '{remaining} of {limit} questions left today. Resets at {resets}.',
90
+ limitReached: "You've reached today's fair-use limit of {limit} questions. It resets at {resets}.",
91
+ midnight: 'midnight',
92
+ support: 'Support',
93
+ pastQuestions: 'Past questions',
94
+ newQuestion: 'New question',
95
+ readingPastQuestions: 'Reading your past questions…',
96
+ noPastQuestions: 'No past questions yet.',
97
+ pastQuestionsFailed: "Your past questions couldn't be read just now.",
98
+ conversationActions: 'More',
99
+ rename: 'Rename',
100
+ download: 'Download',
101
+ delete: 'Delete',
102
+ save: 'Save',
103
+ cancel: 'Cancel',
104
+ deletePrompt: 'Delete this conversation? It goes from every device.',
105
+ renameFailed: "That conversation couldn't be renamed.",
106
+ downloadFailed: "That conversation couldn't be downloaded.",
107
+ deleteFailed: "That conversation couldn't be deleted."
78
108
  };
79
109
  }
110
+ /** A sentence with `{name}` places, filled. A place with no value stays as
111
+ * written, so a host's override that drops one loses nothing else. */
112
+ export function fill(template, values) {
113
+ return template.replace(/\{(\w+)\}/g, (place, key) => key in values ? String(values[key]) : place);
114
+ }
80
115
  /** The library's own words, for a host that names no persona. */
81
116
  export const DEFAULT_COPY = copyFor();
82
117
  /**
@@ -96,7 +96,7 @@ export class Session {
96
96
  }
97
97
  /** The words of a replayed frame: a bare string, or its text blocks. */
98
98
  function said(event) {
99
- const content = event.message?.content;
99
+ const content = typeof event.message === 'object' ? event.message.content : undefined;
100
100
  if (typeof content === 'string')
101
101
  return content;
102
102
  return contentOf(event)
@@ -299,7 +299,7 @@ export function fold(into, state, event) {
299
299
  }
300
300
  /** A message's content blocks; a user frame may carry a bare string instead. */
301
301
  export function contentOf(event) {
302
- const content = event.message?.content;
302
+ const content = typeof event.message === 'object' ? event.message.content : undefined;
303
303
  return Array.isArray(content) ? content : [];
304
304
  }
305
305
  function wholeBlock(block, index) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poodle64/librarian",
3
- "version": "2026.9.21",
3
+ "version": "2026.9.22",
4
4
  "description": "An agent's conversation surface as a consumable Svelte 5 package: the stream client, transcript state and self-styling chat components (transcript, composer, markdown) every household app renders instead of rebuilding, speaking as whichever persona the app names.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/session.svelte.d.ts",
31
31
  "svelte": "./dist/session.svelte.js"
32
32
  },
33
+ "./chat": {
34
+ "types": "./dist/chat.svelte.d.ts",
35
+ "svelte": "./dist/chat.svelte.js"
36
+ },
33
37
  "./history": {
34
38
  "types": "./dist/history.svelte.d.ts",
35
39
  "svelte": "./dist/history.svelte.js"