@cryer/star-cli 0.1.1 → 0.1.2
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/README.md +47 -7
- package/dist/main.js +2080 -441
- package/dist/main.js.map +1 -1
- package/dist/stream-Y55NRF2S.js +82 -0
- package/dist/stream-Y55NRF2S.js.map +1 -0
- package/package.json +1 -1
- package/dist/stream-FJQZGETE.js +0 -51
- package/dist/stream-FJQZGETE.js.map +0 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/llm/stream.ts
|
|
4
|
+
import { streamText } from "ai";
|
|
5
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 2e4;
|
|
6
|
+
var DEFAULT_FIRST_PART_TIMEOUT_MS = 12e4;
|
|
7
|
+
async function* streamChat(opts) {
|
|
8
|
+
const controller = new AbortController();
|
|
9
|
+
const onAbort = () => controller.abort();
|
|
10
|
+
opts.abortSignal?.addEventListener("abort", onAbort);
|
|
11
|
+
const result = streamText({
|
|
12
|
+
model: opts.model,
|
|
13
|
+
messages: opts.messages,
|
|
14
|
+
tools: opts.tools,
|
|
15
|
+
abortSignal: controller.signal,
|
|
16
|
+
maxTokens: opts.maxTokens
|
|
17
|
+
});
|
|
18
|
+
const idleTimeoutMs = opts.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
19
|
+
const firstPartTimeoutMs = opts.firstPartTimeoutMs ?? DEFAULT_FIRST_PART_TIMEOUT_MS;
|
|
20
|
+
const iterator = result.fullStream[Symbol.asyncIterator]();
|
|
21
|
+
let seenPart = false;
|
|
22
|
+
try {
|
|
23
|
+
for (; ; ) {
|
|
24
|
+
let timer;
|
|
25
|
+
const idle = new Promise((resolve) => {
|
|
26
|
+
timer = setTimeout(() => resolve(null), seenPart ? idleTimeoutMs : firstPartTimeoutMs);
|
|
27
|
+
});
|
|
28
|
+
const next = await Promise.race([iterator.next(), idle]);
|
|
29
|
+
if (timer) clearTimeout(timer);
|
|
30
|
+
if (next === null) {
|
|
31
|
+
yield { type: "finish", finishReason: "idle-timeout", usage: void 0 };
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (next.done) return;
|
|
35
|
+
seenPart = true;
|
|
36
|
+
const part = next.value;
|
|
37
|
+
switch (part.type) {
|
|
38
|
+
case "text-delta":
|
|
39
|
+
yield { type: "text-delta", text: part.textDelta };
|
|
40
|
+
break;
|
|
41
|
+
case "reasoning":
|
|
42
|
+
yield { type: "reasoning", text: part.textDelta };
|
|
43
|
+
break;
|
|
44
|
+
case "tool-call":
|
|
45
|
+
yield {
|
|
46
|
+
type: "tool-call",
|
|
47
|
+
id: part.toolCallId,
|
|
48
|
+
name: part.toolName,
|
|
49
|
+
args: part.args
|
|
50
|
+
};
|
|
51
|
+
break;
|
|
52
|
+
case "finish": {
|
|
53
|
+
const finite = (n) => Number.isFinite(n) ? n : 0;
|
|
54
|
+
yield {
|
|
55
|
+
type: "finish",
|
|
56
|
+
finishReason: part.finishReason,
|
|
57
|
+
usage: part.usage ? {
|
|
58
|
+
promptTokens: finite(part.usage.promptTokens),
|
|
59
|
+
completionTokens: finite(part.usage.completionTokens),
|
|
60
|
+
totalTokens: finite(part.usage.totalTokens)
|
|
61
|
+
} : void 0
|
|
62
|
+
};
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
case "error":
|
|
66
|
+
if (opts.abortSignal?.aborted) return;
|
|
67
|
+
yield {
|
|
68
|
+
type: "error",
|
|
69
|
+
error: part.error instanceof Error ? part.error : new Error(String(part.error))
|
|
70
|
+
};
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} finally {
|
|
75
|
+
opts.abortSignal?.removeEventListener("abort", onAbort);
|
|
76
|
+
controller.abort();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
streamChat
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=stream-Y55NRF2S.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/llm/stream.ts"],"sourcesContent":["import { type LanguageModel, type ToolSet, streamText } from \"ai\";\nimport type { StreamEvent } from \"../core/events\";\nimport type { CoreMessage } from \"../core/messages\";\n\nexport interface StreamChatOptions {\n model: LanguageModel;\n messages: CoreMessage[];\n tools?: Record<string, unknown>;\n abortSignal?: AbortSignal;\n maxTokens?: number;\n // Idle watchdog: some relays deliver the final content but never send the\n // terminal chunks (or never close the socket). If no stream part arrives\n // within this window once streaming has started, the stream is ended\n // gracefully with what we have.\n idleTimeoutMs?: number;\n // Separate, longer allowance for the very first part: thinking models and\n // slow relays can take a while before producing anything, and a false\n // timeout here would kill a healthy request.\n firstPartTimeoutMs?: number;\n}\n\nconst DEFAULT_IDLE_TIMEOUT_MS = 20_000;\nconst DEFAULT_FIRST_PART_TIMEOUT_MS = 120_000;\n\nexport async function* streamChat(opts: StreamChatOptions): AsyncGenerator<StreamEvent> {\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n opts.abortSignal?.addEventListener(\"abort\", onAbort);\n const result = streamText({\n model: opts.model,\n messages: opts.messages,\n tools: opts.tools as ToolSet | undefined,\n abortSignal: controller.signal,\n maxTokens: opts.maxTokens,\n });\n const idleTimeoutMs = opts.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;\n const firstPartTimeoutMs = opts.firstPartTimeoutMs ?? DEFAULT_FIRST_PART_TIMEOUT_MS;\n const iterator = result.fullStream[Symbol.asyncIterator]();\n let seenPart = false;\n try {\n for (;;) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const idle = new Promise<null>((resolve) => {\n timer = setTimeout(() => resolve(null), seenPart ? idleTimeoutMs : firstPartTimeoutMs);\n });\n const next = await Promise.race([iterator.next(), idle]);\n if (timer) clearTimeout(timer);\n if (next === null) {\n // Note: the AI SDK holds the model's finish part until the source\n // stream closes, so a relay that stops sending without closing can\n // only be detected by this watchdog.\n yield { type: \"finish\", finishReason: \"idle-timeout\", usage: undefined };\n return;\n }\n if (next.done) return;\n seenPart = true;\n const part = next.value;\n switch (part.type) {\n case \"text-delta\":\n yield { type: \"text-delta\", text: part.textDelta };\n break;\n case \"reasoning\":\n yield { type: \"reasoning\", text: part.textDelta };\n break;\n case \"tool-call\":\n yield {\n type: \"tool-call\",\n id: part.toolCallId,\n name: part.toolName,\n args: part.args,\n };\n break;\n case \"finish\": {\n const finite = (n: number) => (Number.isFinite(n) ? n : 0);\n yield {\n type: \"finish\",\n finishReason: part.finishReason,\n usage: part.usage\n ? {\n promptTokens: finite(part.usage.promptTokens),\n completionTokens: finite(part.usage.completionTokens),\n totalTokens: finite(part.usage.totalTokens),\n }\n : undefined,\n };\n return;\n }\n case \"error\":\n // A user-initiated abort surfacing as a stream error is not a failure.\n if (opts.abortSignal?.aborted) return;\n yield {\n type: \"error\",\n error: part.error instanceof Error ? part.error : new Error(String(part.error)),\n };\n break;\n }\n }\n } finally {\n opts.abortSignal?.removeEventListener(\"abort\", onAbort);\n // Cancels the upstream request if it is still open (e.g. a relay that\n // sent its last byte but kept the connection alive).\n controller.abort();\n }\n}\n"],"mappings":";;;AAAA,SAA2C,kBAAkB;AAqB7D,IAAM,0BAA0B;AAChC,IAAM,gCAAgC;AAEtC,gBAAuB,WAAW,MAAsD;AACtF,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,UAAU,MAAM,WAAW,MAAM;AACvC,OAAK,aAAa,iBAAiB,SAAS,OAAO;AACnD,QAAM,SAAS,WAAW;AAAA,IACxB,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,aAAa,WAAW;AAAA,IACxB,WAAW,KAAK;AAAA,EAClB,CAAC;AACD,QAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAM,qBAAqB,KAAK,sBAAsB;AACtD,QAAM,WAAW,OAAO,WAAW,OAAO,aAAa,EAAE;AACzD,MAAI,WAAW;AACf,MAAI;AACF,eAAS;AACP,UAAI;AACJ,YAAM,OAAO,IAAI,QAAc,CAAC,YAAY;AAC1C,gBAAQ,WAAW,MAAM,QAAQ,IAAI,GAAG,WAAW,gBAAgB,kBAAkB;AAAA,MACvF,CAAC;AACD,YAAM,OAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,KAAK,GAAG,IAAI,CAAC;AACvD,UAAI,MAAO,cAAa,KAAK;AAC7B,UAAI,SAAS,MAAM;AAIjB,cAAM,EAAE,MAAM,UAAU,cAAc,gBAAgB,OAAO,OAAU;AACvE;AAAA,MACF;AACA,UAAI,KAAK,KAAM;AACf,iBAAW;AACX,YAAM,OAAO,KAAK;AAClB,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK;AACH,gBAAM,EAAE,MAAM,cAAc,MAAM,KAAK,UAAU;AACjD;AAAA,QACF,KAAK;AACH,gBAAM,EAAE,MAAM,aAAa,MAAM,KAAK,UAAU;AAChD;AAAA,QACF,KAAK;AACH,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,IAAI,KAAK;AAAA,YACT,MAAM,KAAK;AAAA,YACX,MAAM,KAAK;AAAA,UACb;AACA;AAAA,QACF,KAAK,UAAU;AACb,gBAAM,SAAS,CAAC,MAAe,OAAO,SAAS,CAAC,IAAI,IAAI;AACxD,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,cAAc,KAAK;AAAA,YACnB,OAAO,KAAK,QACR;AAAA,cACE,cAAc,OAAO,KAAK,MAAM,YAAY;AAAA,cAC5C,kBAAkB,OAAO,KAAK,MAAM,gBAAgB;AAAA,cACpD,aAAa,OAAO,KAAK,MAAM,WAAW;AAAA,YAC5C,IACA;AAAA,UACN;AACA;AAAA,QACF;AAAA,QACA,KAAK;AAEH,cAAI,KAAK,aAAa,QAAS;AAC/B,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAO,KAAK,iBAAiB,QAAQ,KAAK,QAAQ,IAAI,MAAM,OAAO,KAAK,KAAK,CAAC;AAAA,UAChF;AACA;AAAA,MACJ;AAAA,IACF;AAAA,EACF,UAAE;AACA,SAAK,aAAa,oBAAoB,SAAS,OAAO;AAGtD,eAAW,MAAM;AAAA,EACnB;AACF;","names":[]}
|
package/package.json
CHANGED
package/dist/stream-FJQZGETE.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/llm/stream.ts
|
|
4
|
-
import { streamText } from "ai";
|
|
5
|
-
async function* streamChat(opts) {
|
|
6
|
-
const result = streamText({
|
|
7
|
-
model: opts.model,
|
|
8
|
-
messages: opts.messages,
|
|
9
|
-
tools: opts.tools,
|
|
10
|
-
abortSignal: opts.abortSignal,
|
|
11
|
-
maxTokens: opts.maxTokens
|
|
12
|
-
});
|
|
13
|
-
for await (const part of result.fullStream) {
|
|
14
|
-
switch (part.type) {
|
|
15
|
-
case "text-delta":
|
|
16
|
-
yield { type: "text-delta", text: part.textDelta };
|
|
17
|
-
break;
|
|
18
|
-
case "tool-call":
|
|
19
|
-
yield {
|
|
20
|
-
type: "tool-call",
|
|
21
|
-
id: part.toolCallId,
|
|
22
|
-
name: part.toolName,
|
|
23
|
-
args: part.args
|
|
24
|
-
};
|
|
25
|
-
break;
|
|
26
|
-
case "finish": {
|
|
27
|
-
const finite = (n) => Number.isFinite(n) ? n : 0;
|
|
28
|
-
yield {
|
|
29
|
-
type: "finish",
|
|
30
|
-
finishReason: part.finishReason,
|
|
31
|
-
usage: part.usage ? {
|
|
32
|
-
promptTokens: finite(part.usage.promptTokens),
|
|
33
|
-
completionTokens: finite(part.usage.completionTokens),
|
|
34
|
-
totalTokens: finite(part.usage.totalTokens)
|
|
35
|
-
} : void 0
|
|
36
|
-
};
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
case "error":
|
|
40
|
-
yield {
|
|
41
|
-
type: "error",
|
|
42
|
-
error: part.error instanceof Error ? part.error : new Error(String(part.error))
|
|
43
|
-
};
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export {
|
|
49
|
-
streamChat
|
|
50
|
-
};
|
|
51
|
-
//# sourceMappingURL=stream-FJQZGETE.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/llm/stream.ts"],"sourcesContent":["import { type LanguageModel, type ToolSet, streamText } from \"ai\";\nimport type { StreamEvent } from \"../core/events\";\nimport type { CoreMessage } from \"../core/messages\";\n\nexport interface StreamChatOptions {\n model: LanguageModel;\n messages: CoreMessage[];\n tools?: Record<string, unknown>;\n abortSignal?: AbortSignal;\n maxTokens?: number;\n}\n\nexport async function* streamChat(opts: StreamChatOptions): AsyncGenerator<StreamEvent> {\n const result = streamText({\n model: opts.model,\n messages: opts.messages,\n tools: opts.tools as ToolSet | undefined,\n abortSignal: opts.abortSignal,\n maxTokens: opts.maxTokens,\n });\n for await (const part of result.fullStream) {\n switch (part.type) {\n case \"text-delta\":\n yield { type: \"text-delta\", text: part.textDelta };\n break;\n case \"tool-call\":\n yield {\n type: \"tool-call\",\n id: part.toolCallId,\n name: part.toolName,\n args: part.args,\n };\n break;\n case \"finish\": {\n const finite = (n: number) => (Number.isFinite(n) ? n : 0);\n yield {\n type: \"finish\",\n finishReason: part.finishReason,\n usage: part.usage\n ? {\n promptTokens: finite(part.usage.promptTokens),\n completionTokens: finite(part.usage.completionTokens),\n totalTokens: finite(part.usage.totalTokens),\n }\n : undefined,\n };\n break;\n }\n case \"error\":\n yield {\n type: \"error\",\n error: part.error instanceof Error ? part.error : new Error(String(part.error)),\n };\n break;\n }\n }\n}\n"],"mappings":";;;AAAA,SAA2C,kBAAkB;AAY7D,gBAAuB,WAAW,MAAsD;AACtF,QAAM,SAAS,WAAW;AAAA,IACxB,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,WAAW,KAAK;AAAA,EAClB,CAAC;AACD,mBAAiB,QAAQ,OAAO,YAAY;AAC1C,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,cAAM,EAAE,MAAM,cAAc,MAAM,KAAK,UAAU;AACjD;AAAA,MACF,KAAK;AACH,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,IAAI,KAAK;AAAA,UACT,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,QACb;AACA;AAAA,MACF,KAAK,UAAU;AACb,cAAM,SAAS,CAAC,MAAe,OAAO,SAAS,CAAC,IAAI,IAAI;AACxD,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,cAAc,KAAK;AAAA,UACnB,OAAO,KAAK,QACR;AAAA,YACE,cAAc,OAAO,KAAK,MAAM,YAAY;AAAA,YAC5C,kBAAkB,OAAO,KAAK,MAAM,gBAAgB;AAAA,YACpD,aAAa,OAAO,KAAK,MAAM,WAAW;AAAA,UAC5C,IACA;AAAA,QACN;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,KAAK,iBAAiB,QAAQ,KAAK,QAAQ,IAAI,MAAM,OAAO,KAAK,KAAK,CAAC;AAAA,QAChF;AACA;AAAA,IACJ;AAAA,EACF;AACF;","names":[]}
|