@columenlabs/lumen-ai 0.1.147 → 0.1.149

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.
@@ -240,6 +240,12 @@ export declare class Assistant {
240
240
  /** The loop on Anthropic's Messages API, with the advisor and prompt caching. */
241
241
  private loopClaude;
242
242
  /** Swaps the history for a short summary. False with nothing to compact. */
243
+ /**
244
+ * One plain answer from OpenAI, metered on `s`: no tools, no chat. Streamed and read from the raw
245
+ * events like the chat loop, because a ChatGPT plan sign-in answers only streamed calls, takes no
246
+ * output cap and may send its words only as deltas.
247
+ */
248
+ private openaiOnce;
243
249
  private compact;
244
250
  /**
245
251
  * One prompt answered on a task's tier as the person: no chat, no tools. It is for background
@@ -1697,6 +1697,60 @@ export class Assistant {
1697
1697
  return answer;
1698
1698
  }
1699
1699
  /** Swaps the history for a short summary. False with nothing to compact. */
1700
+ /**
1701
+ * One plain answer from OpenAI, metered on `s`: no tools, no chat. Streamed and read from the raw
1702
+ * events like the chat loop, because a ChatGPT plan sign-in answers only streamed calls, takes no
1703
+ * output cap and may send its words only as deltas.
1704
+ */
1705
+ async openaiOnce(clients, s, instructions, input, max, signal) {
1706
+ const client = clients.openai;
1707
+ const plan = !!clients.openaiPlan;
1708
+ let text = '';
1709
+ let done;
1710
+ try {
1711
+ const stream = await client.responses.create({
1712
+ model: s.model.id,
1713
+ instructions,
1714
+ // A plan sign-in takes only a list of items, never bare text ("Input must be a list").
1715
+ input: [{ role: 'user', content: input }],
1716
+ store: false,
1717
+ stream: true,
1718
+ ...(plan ? {} : { max_output_tokens: max }),
1719
+ }, signal ? { signal } : {});
1720
+ for await (const e of stream) {
1721
+ if (e.type === 'response.output_text.delta' && typeof e.delta === 'string')
1722
+ text += e.delta;
1723
+ else if (e.type === 'response.completed' ||
1724
+ e.type === 'response.incomplete' ||
1725
+ e.type === 'response.failed')
1726
+ done = e.response;
1727
+ else if (e.type === 'error') {
1728
+ const er = (e.error ?? e);
1729
+ throw new AssistantError(openaiStreamError(er.code || er.type || '', plan), 'upstream');
1730
+ }
1731
+ }
1732
+ }
1733
+ catch (err) {
1734
+ // The SDK throws a stream's `error` event as an APIError with no HTTP status.
1735
+ if (err instanceof OpenAI.APIError && err.status === undefined) {
1736
+ const er = (err.error ?? {});
1737
+ throw new AssistantError(openaiStreamError(er.code || er.type || err.code || '', plan), 'upstream');
1738
+ }
1739
+ throw err;
1740
+ }
1741
+ if (done?.status === 'failed')
1742
+ throw new AssistantError(openaiStreamError(done.error?.code ?? '', plan), 'upstream');
1743
+ const u = done?.usage;
1744
+ if (u) {
1745
+ const read = u.input_tokens_details?.cached_tokens ?? 0;
1746
+ s.meter.add({
1747
+ input_tokens: Math.max(0, u.input_tokens - read),
1748
+ output_tokens: u.output_tokens,
1749
+ cache_read_input_tokens: read,
1750
+ }, plan);
1751
+ }
1752
+ return text || done?.output_text || '';
1753
+ }
1700
1754
  async compact(clients, s, doc, emit) {
1701
1755
  if (doc.history.length < 2)
1702
1756
  return false;
@@ -1706,21 +1760,7 @@ export class Assistant {
1706
1760
  .join('\n\n');
1707
1761
  let summary = '';
1708
1762
  if (s.model.provider === 'openai' && clients.openai) {
1709
- const res = await clients.openai.responses.create({
1710
- model: s.model.id,
1711
- instructions: system,
1712
- input: chat,
1713
- store: false,
1714
- max_output_tokens: 1500,
1715
- });
1716
- const u = res.usage;
1717
- if (u)
1718
- s.meter.add({
1719
- input_tokens: u.input_tokens - (u.input_tokens_details?.cached_tokens ?? 0),
1720
- output_tokens: u.output_tokens,
1721
- cache_read_input_tokens: u.input_tokens_details?.cached_tokens ?? 0,
1722
- });
1723
- summary = res.output_text ?? '';
1763
+ summary = await this.openaiOnce(clients, s, system, chat, 1500);
1724
1764
  }
1725
1765
  else if (clients.anthropic) {
1726
1766
  const msg = await clients.anthropic.messages.create({
@@ -1764,21 +1804,7 @@ export class Assistant {
1764
1804
  let text = '';
1765
1805
  try {
1766
1806
  if (s.model.provider === 'openai' && clients.openai) {
1767
- const res = await clients.openai.responses.create({
1768
- model: s.model.id,
1769
- instructions: o.system,
1770
- input: o.prompt,
1771
- store: false,
1772
- max_output_tokens: max,
1773
- }, o.signal ? { signal: o.signal } : undefined);
1774
- const u = res.usage;
1775
- if (u)
1776
- s.meter.add({
1777
- input_tokens: u.input_tokens - (u.input_tokens_details?.cached_tokens ?? 0),
1778
- output_tokens: u.output_tokens,
1779
- cache_read_input_tokens: u.input_tokens_details?.cached_tokens ?? 0,
1780
- }, !!clients.openaiPlan);
1781
- text = res.output_text ?? '';
1807
+ text = await this.openaiOnce(clients, s, o.system, o.prompt, max, o.signal);
1782
1808
  }
1783
1809
  else if (clients.anthropic) {
1784
1810
  const msg = await clients.anthropic.messages.create({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@columenlabs/lumen-ai",
3
- "version": "0.1.147",
3
+ "version": "0.1.149",
4
4
  "description": "Lumen's assistant and agent parts: a chat assistant's server (Claude tiers, tools over MCP, the web, hand off, spend caps), serving an MCP server from a Worker, read-only tool sets and metered tool calls.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,8 +41,8 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@anthropic-ai/sdk": "0.133.0",
44
- "@columenlabs/lumen-ops": "0.1.147",
45
- "@columenlabs/lumen-ui-types": "0.1.147",
44
+ "@columenlabs/lumen-ops": "0.1.149",
45
+ "@columenlabs/lumen-ui-types": "0.1.149",
46
46
  "openai": "7.32.0",
47
47
  "zod": "^4.3.6"
48
48
  },