@intelligo-dev/chat 1.0.0-beta.13

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 (94) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +6 -0
  3. package/README.md +116 -0
  4. package/dist/artifact-writer.d.ts +45 -0
  5. package/dist/artifact-writer.d.ts.map +1 -0
  6. package/dist/artifact-writer.js +77 -0
  7. package/dist/artifact-writer.js.map +1 -0
  8. package/dist/attachments.d.ts +56 -0
  9. package/dist/attachments.d.ts.map +1 -0
  10. package/dist/attachments.js +204 -0
  11. package/dist/attachments.js.map +1 -0
  12. package/dist/body.d.ts +72 -0
  13. package/dist/body.d.ts.map +1 -0
  14. package/dist/body.js +174 -0
  15. package/dist/body.js.map +1 -0
  16. package/dist/client.d.ts +65 -0
  17. package/dist/client.d.ts.map +1 -0
  18. package/dist/client.js +61 -0
  19. package/dist/client.js.map +1 -0
  20. package/dist/config.d.ts +322 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +11 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/errors.d.ts +23 -0
  25. package/dist/errors.d.ts.map +1 -0
  26. package/dist/errors.js +41 -0
  27. package/dist/errors.js.map +1 -0
  28. package/dist/feedback.d.ts +22 -0
  29. package/dist/feedback.d.ts.map +1 -0
  30. package/dist/feedback.js +46 -0
  31. package/dist/feedback.js.map +1 -0
  32. package/dist/generation.d.ts +104 -0
  33. package/dist/generation.d.ts.map +1 -0
  34. package/dist/generation.js +85 -0
  35. package/dist/generation.js.map +1 -0
  36. package/dist/handler.d.ts +30 -0
  37. package/dist/handler.d.ts.map +1 -0
  38. package/dist/handler.js +913 -0
  39. package/dist/handler.js.map +1 -0
  40. package/dist/index.d.ts +31 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +20 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/messages.d.ts +19 -0
  45. package/dist/messages.d.ts.map +1 -0
  46. package/dist/messages.js +34 -0
  47. package/dist/messages.js.map +1 -0
  48. package/dist/parts.d.ts +117 -0
  49. package/dist/parts.d.ts.map +1 -0
  50. package/dist/parts.js +13 -0
  51. package/dist/parts.js.map +1 -0
  52. package/dist/quota.d.ts +32 -0
  53. package/dist/quota.d.ts.map +1 -0
  54. package/dist/quota.js +81 -0
  55. package/dist/quota.js.map +1 -0
  56. package/dist/share.d.ts +24 -0
  57. package/dist/share.d.ts.map +1 -0
  58. package/dist/share.js +78 -0
  59. package/dist/share.js.map +1 -0
  60. package/dist/testing.d.ts +36 -0
  61. package/dist/testing.d.ts.map +1 -0
  62. package/dist/testing.js +82 -0
  63. package/dist/testing.js.map +1 -0
  64. package/dist/title.d.ts +7 -0
  65. package/dist/title.d.ts.map +1 -0
  66. package/dist/title.js +15 -0
  67. package/dist/title.js.map +1 -0
  68. package/dist/usage.d.ts +21 -0
  69. package/dist/usage.d.ts.map +1 -0
  70. package/dist/usage.js +35 -0
  71. package/dist/usage.js.map +1 -0
  72. package/dist/windowing.d.ts +38 -0
  73. package/dist/windowing.d.ts.map +1 -0
  74. package/dist/windowing.js +82 -0
  75. package/dist/windowing.js.map +1 -0
  76. package/package.json +78 -0
  77. package/src/artifact-writer.ts +114 -0
  78. package/src/attachments.ts +262 -0
  79. package/src/body.ts +236 -0
  80. package/src/client.ts +133 -0
  81. package/src/config.ts +376 -0
  82. package/src/errors.ts +80 -0
  83. package/src/feedback.ts +62 -0
  84. package/src/generation.ts +150 -0
  85. package/src/handler.ts +1164 -0
  86. package/src/index.ts +93 -0
  87. package/src/messages.ts +39 -0
  88. package/src/parts.ts +143 -0
  89. package/src/quota.ts +105 -0
  90. package/src/share.ts +103 -0
  91. package/src/testing.ts +150 -0
  92. package/src/title.ts +15 -0
  93. package/src/usage.ts +46 -0
  94. package/src/windowing.ts +110 -0
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Conversation windowing: what the model is shown of a long history.
3
+ *
4
+ * Works on `UIMessage`s, the AI SDK's transcript, not stored rows.
5
+ * The default `prepareMessages` applies it; an application that wants
6
+ * to summarise what was pruned does so in its own `prepareMessages`,
7
+ * with its own model, and hands the summary back as `system`.
8
+ */
9
+
10
+ import type { UIMessage } from "ai";
11
+
12
+ type TextPart = { type: "text"; text: string };
13
+
14
+ function isTextPart(part: unknown): part is TextPart {
15
+ return (
16
+ typeof part === "object" &&
17
+ part !== null &&
18
+ (part as { type?: unknown }).type === "text" &&
19
+ typeof (part as { text?: unknown }).text === "string"
20
+ );
21
+ }
22
+
23
+ /** The text parts of a message, joined. Tool and file parts contribute nothing. */
24
+ export function extractText(parts: ReadonlyArray<unknown>): string {
25
+ return parts
26
+ .filter(isTextPart)
27
+ .map((part) => part.text)
28
+ .join(" ");
29
+ }
30
+
31
+ /**
32
+ * A cheap token estimate that does not need a tokenizer.
33
+ *
34
+ * Latin text runs about four characters per token; Cyrillic — and
35
+ * most non-Latin scripts — closer to two, because their byte-pair
36
+ * vocabularies are smaller. A single divisor would under-count a
37
+ * Cyrillic transcript by half and window it far too late.
38
+ */
39
+ export function estimateTokenCount(text: string): number {
40
+ // Stryker disable next-line ConditionalExpression: equivalent — the loop below counts nothing in an empty string and returns 0 either way.
41
+ if (!text) return 0;
42
+ let nonLatin = 0;
43
+ for (const char of text) {
44
+ const code = char.codePointAt(0) ?? 0;
45
+ if (code > 0x024f) nonLatin++;
46
+ }
47
+ const latin = text.length - nonLatin;
48
+ return Math.ceil(latin / 4 + nonLatin / 2);
49
+ }
50
+
51
+ export function estimateConversationTokens(
52
+ messages: ReadonlyArray<UIMessage>
53
+ ): number {
54
+ let total = 0;
55
+ for (const message of messages) {
56
+ // Tool payloads are not text but still cost tokens; count their
57
+ // serialised size at the Latin rate.
58
+ for (const part of message.parts) {
59
+ total += isTextPart(part)
60
+ ? estimateTokenCount(part.text)
61
+ : Math.ceil(JSON.stringify(part).length / 4);
62
+ }
63
+ }
64
+ return total;
65
+ }
66
+
67
+ export type ConversationWindowOptions = {
68
+ /** Keep at most this many non-system messages. */
69
+ maxMessages: number;
70
+ /** Also drop from the front until the estimate fits, when set. */
71
+ maxTokens?: number;
72
+ };
73
+
74
+ export type ConversationWindow = {
75
+ windowed: UIMessage[];
76
+ pruned: UIMessage[];
77
+ };
78
+
79
+ /**
80
+ * Keep the most recent messages, always starting the window on a user
81
+ * turn so the model never sees an assistant reply without the message
82
+ * it answered. System messages are never pruned.
83
+ */
84
+ export function applyConversationWindow(
85
+ messages: ReadonlyArray<UIMessage>,
86
+ options: ConversationWindowOptions
87
+ ): ConversationWindow {
88
+ const system = messages.filter((message) => message.role === "system");
89
+ const turns = messages.filter((message) => message.role !== "system");
90
+
91
+ let start = Math.max(0, turns.length - options.maxMessages);
92
+ // Stryker disable next-line ConditionalExpression: equivalent — with no budget the comparison against undefined is false, so the loop exits on its first test.
93
+ if (options.maxTokens !== undefined) {
94
+ while (
95
+ start < turns.length - 1 &&
96
+ estimateConversationTokens(turns.slice(start)) > options.maxTokens
97
+ ) {
98
+ start++;
99
+ }
100
+ }
101
+ // Open on a user message. If none follows, keep the last turn: a
102
+ // window of nothing is worse than one that opens mid-exchange.
103
+ // Stryker disable next-line OptionalChaining: equivalent — the condition to its left has already proved the index is in range.
104
+ while (start < turns.length - 1 && turns[start]?.role !== "user") start++;
105
+
106
+ return {
107
+ windowed: [...system, ...turns.slice(start)],
108
+ pruned: turns.slice(0, start),
109
+ };
110
+ }