sideagent 0.2.0 → 0.4.0

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.
@@ -7,9 +7,11 @@ function script(messages, forced) {
7
7
  const text = String(last.content ?? "");
8
8
  const explicit = /CALL (\S+)\s*(\{.*\})?/s.exec(text);
9
9
  if (explicit) return { call: { name: explicit[1], args: explicit[2] ? JSON.parse(explicit[2]) : {} } };
10
- if (/\b(policy|refunds?|terms|docs|warranty)\b/i.test(text)) return { call: { name: "search_knowledge", args: { query: text } } };
10
+ if (/\b(policy|refunds?|terms|docs|warranty)\b/i.test(text))
11
+ return { call: { name: "search_knowledge", args: { query: text } } };
11
12
  if (/\blist\b/i.test(text)) return { call: { name: "listInvoices", args: {} } };
12
- if (/\bcreate\b/i.test(text)) return { call: { name: "createInvoice", args: { body: { customer: "Acme", amount: 100 } } } };
13
+ if (/\bcreate\b/i.test(text))
14
+ return { call: { name: "createInvoice", args: { body: { customer: "Acme", amount: 100 } } } };
13
15
  if (/\bdelete\b/i.test(text)) return { call: { name: "deleteInvoice", args: { id: "1" } } };
14
16
  return { text: "Hello from the mock model." };
15
17
  }
@@ -28,7 +30,17 @@ async function mockLlmHandler(request) {
28
30
  {
29
31
  index: 0,
30
32
  finish_reason: call ? "tool_calls" : "stop",
31
- message: call ? { role: "assistant", content: null, tool_calls: [{ id: "call_1", type: "function", function: { name: call.name, arguments: JSON.stringify(call.args) } }] } : { role: "assistant", content: text }
33
+ message: call ? {
34
+ role: "assistant",
35
+ content: null,
36
+ tool_calls: [
37
+ {
38
+ id: "call_1",
39
+ type: "function",
40
+ function: { name: call.name, arguments: JSON.stringify(call.args) }
41
+ }
42
+ ]
43
+ } : { role: "assistant", content: text }
32
44
  }
33
45
  ]
34
46
  });
@@ -37,11 +49,26 @@ async function mockLlmHandler(request) {
37
49
  if (call) {
38
50
  chunks.push({
39
51
  ...base,
40
- choices: [{ index: 0, delta: { tool_calls: [{ index: 0, id: `call_${Math.random().toString(36).slice(2, 8)}`, type: "function", function: { name: call.name, arguments: JSON.stringify(call.args) } }] } }]
52
+ choices: [
53
+ {
54
+ index: 0,
55
+ delta: {
56
+ tool_calls: [
57
+ {
58
+ index: 0,
59
+ id: `call_${Math.random().toString(36).slice(2, 8)}`,
60
+ type: "function",
61
+ function: { name: call.name, arguments: JSON.stringify(call.args) }
62
+ }
63
+ ]
64
+ }
65
+ }
66
+ ]
41
67
  });
42
68
  chunks.push({ ...base, choices: [{ index: 0, delta: {}, finish_reason: "tool_calls" }] });
43
69
  } else {
44
- for (const w of (text ?? "").split(/(?<= )/)) chunks.push({ ...base, choices: [{ index: 0, delta: { content: w } }] });
70
+ for (const w of (text ?? "").split(/(?<= )/))
71
+ chunks.push({ ...base, choices: [{ index: 0, delta: { content: w } }] });
45
72
  chunks.push({ ...base, choices: [{ index: 0, delta: {}, finish_reason: "stop" }] });
46
73
  }
47
74
  const sse = chunks.map((c) => `data: ${JSON.stringify(c)}
@@ -73,7 +100,11 @@ async function mockEmbeddingsHandler(request) {
73
100
  return Response.json({
74
101
  object: "list",
75
102
  model: "mock-embedding",
76
- data: inputs.map((t, index) => ({ object: "embedding", index, embedding: body.encoding_format === "base64" ? toB64(mockEmbed(t)) : mockEmbed(t) })),
103
+ data: inputs.map((t, index) => ({
104
+ object: "embedding",
105
+ index,
106
+ embedding: body.encoding_format === "base64" ? toB64(mockEmbed(t)) : mockEmbed(t)
107
+ })),
77
108
  usage: { prompt_tokens: 0, total_tokens: 0 }
78
109
  });
79
110
  }
@@ -1,25 +1,34 @@
1
+ import {
2
+ messageText
3
+ } from "../chunk-5H62LFNC.js";
4
+
1
5
  // src/workers-ai/index.ts
2
- import { BaseChatModel } from "@langchain/core/language_models/chat_models";
6
+ import {
7
+ BaseChatModel
8
+ } from "@langchain/core/language_models/chat_models";
3
9
  import { AIMessage, AIMessageChunk } from "@langchain/core/messages";
4
10
  import { ChatGenerationChunk } from "@langchain/core/outputs";
5
11
  import { convertToOpenAITool } from "@langchain/core/utils/function_calling";
6
12
  var isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
7
- function textOf(content) {
8
- if (typeof content === "string") return content;
9
- return content.map((p) => p.type === "text" && typeof p.text === "string" ? p.text : "").join("");
10
- }
11
13
  function toWire(messages) {
12
14
  return messages.map((m) => {
13
15
  const type = m.getType();
14
- const content = textOf(m.content);
16
+ const content = messageText(m.content);
15
17
  if (type === "system") return { role: "system", content };
16
18
  if (type === "human") return { role: "user", content };
17
- if (type === "tool") return { role: "tool", tool_call_id: m.tool_call_id, content };
19
+ if (type === "tool")
20
+ return { role: "tool", tool_call_id: m.tool_call_id, content };
18
21
  const calls = m.tool_calls ?? [];
19
22
  return {
20
23
  role: "assistant",
21
24
  content,
22
- ...calls.length ? { tool_calls: calls.map((c) => ({ id: c.id, type: "function", function: { name: c.name, arguments: JSON.stringify(c.args ?? {}) } })) } : {}
25
+ ...calls.length ? {
26
+ tool_calls: calls.map((c) => ({
27
+ id: c.id,
28
+ type: "function",
29
+ function: { name: c.name, arguments: JSON.stringify(c.args ?? {}) }
30
+ }))
31
+ } : {}
23
32
  };
24
33
  });
25
34
  }
@@ -50,10 +59,15 @@ function parseWorkersAiResponse(res) {
50
59
  for (const item of r.output) {
51
60
  if (!isObj(item)) continue;
52
61
  if (item.type === "function_call") {
53
- toolCalls.push({ id: String(item.call_id ?? item.id ?? newId()), name: String(item.name), args: parseArgs(item.arguments) });
62
+ toolCalls.push({
63
+ id: String(item.call_id ?? item.id ?? newId()),
64
+ name: String(item.name),
65
+ args: parseArgs(item.arguments)
66
+ });
54
67
  } else if (item.type === "message" || item.type === void 0 && Array.isArray(item.content)) {
55
68
  for (const part of Array.isArray(item.content) ? item.content : []) {
56
- if (isObj(part) && (part.type === "output_text" || part.type === "text") && typeof part.text === "string") text += part.text;
69
+ if (isObj(part) && (part.type === "output_text" || part.type === "text") && typeof part.text === "string")
70
+ text += part.text;
57
71
  }
58
72
  }
59
73
  }
@@ -135,7 +149,10 @@ var ChatWorkersAI = class extends BaseChatModel {
135
149
  return "workers-ai";
136
150
  }
137
151
  bindTools(tools, kwargs) {
138
- return this.withConfig({ ...kwargs, tools: tools.map((t) => convertToOpenAITool(t)) });
152
+ return this.withConfig({
153
+ ...kwargs,
154
+ tools: tools.map((t) => convertToOpenAITool(t))
155
+ });
139
156
  }
140
157
  input(messages, options, stream) {
141
158
  return {
@@ -151,8 +168,13 @@ var ChatWorkersAI = class extends BaseChatModel {
151
168
  return this.ai.run(this.modelName, input);
152
169
  }
153
170
  async _generate(messages, options) {
154
- const { text, toolCalls } = parseWorkersAiResponse(await this.run(this.input(messages, options, false), options.signal));
155
- const message = new AIMessage({ content: text, tool_calls: toolCalls.map((c) => ({ type: "tool_call", ...c })) });
171
+ const { text, toolCalls } = parseWorkersAiResponse(
172
+ await this.run(this.input(messages, options, false), options.signal)
173
+ );
174
+ const message = new AIMessage({
175
+ content: text,
176
+ tool_calls: toolCalls.map((c) => ({ type: "tool_call", ...c }))
177
+ });
156
178
  return { generations: [{ text, message }] };
157
179
  }
158
180
  async *_streamResponseChunks(messages, options, runManager) {
@@ -184,7 +206,11 @@ var ChatWorkersAI = class extends BaseChatModel {
184
206
  }
185
207
  if (ev.type === "response.output_text.delta" && typeof ev.delta === "string") delta += ev.delta;
186
208
  if (ev.type === "response.output_item.done" && isObj(ev.item) && ev.item.type === "function_call") {
187
- whole.push({ id: String(ev.item.call_id ?? ev.item.id ?? newId()), name: String(ev.item.name), args: parseArgs(ev.item.arguments) });
209
+ whole.push({
210
+ id: String(ev.item.call_id ?? ev.item.id ?? newId()),
211
+ name: String(ev.item.name),
212
+ args: parseArgs(ev.item.arguments)
213
+ });
188
214
  }
189
215
  if (Array.isArray(ev.tool_calls)) whole.push(...parseWorkersAiResponse({ tool_calls: ev.tool_calls }).toolCalls);
190
216
  if (delta) yield* this.emit({ text: delta, toolCalls: [] }, runManager);
@@ -201,7 +227,13 @@ var ChatWorkersAI = class extends BaseChatModel {
201
227
  text,
202
228
  message: new AIMessageChunk({
203
229
  content: text,
204
- tool_call_chunks: toolCalls.map((c, index) => ({ type: "tool_call_chunk", index, id: c.id, name: c.name, args: JSON.stringify(c.args) }))
230
+ tool_call_chunks: toolCalls.map((c, index) => ({
231
+ type: "tool_call_chunk",
232
+ index,
233
+ id: c.id,
234
+ name: c.name,
235
+ args: JSON.stringify(c.args)
236
+ }))
205
237
  })
206
238
  });
207
239
  yield chunk;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sideagent",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -25,6 +25,10 @@
25
25
  "types": "./dist/protocol.d.ts",
26
26
  "import": "./dist/protocol.js"
27
27
  },
28
+ "./keys": {
29
+ "types": "./dist/keys.d.ts",
30
+ "import": "./dist/keys.js"
31
+ },
28
32
  "./testing": {
29
33
  "types": "./dist/testing/mock-llm.d.ts",
30
34
  "import": "./dist/testing/mock-llm.js"
@@ -39,6 +43,8 @@
39
43
  "build": "tsup",
40
44
  "test": "vitest run",
41
45
  "typecheck": "tsc --noEmit",
46
+ "format": "prettier --write src demo",
47
+ "format:check": "prettier --check src demo",
42
48
  "demo:api": "tsx demo/server.ts",
43
49
  "demo": "tsx demo/server.ts & vite demo",
44
50
  "eval:skill": "cd skills/sideagent && claude plugin eval . --scaffold --allow-tools Write Edit --trust-plugin --no-publish"
@@ -69,6 +75,7 @@
69
75
  "@types/react-dom": "^19.0.0",
70
76
  "@vitejs/plugin-react": "^5.0.0",
71
77
  "hono": "^4.9.0",
78
+ "prettier": "^3.9.10",
72
79
  "react": "^19.0.0",
73
80
  "react-dom": "^19.0.0",
74
81
  "tsup": "^8.5.0",
@@ -43,7 +43,7 @@ Do them in order. Do not skip the review in step 7.
43
43
  <App />
44
44
  </AgentProvider>
45
45
  ```
46
- Use `<AgentChat endpoint="/agent" />` for a floating chat without docking. Different origin plus cookies: add `credentials="include"`.
46
+ Use `<AgentChat endpoint="/agent" />` for a floating chat without docking. Different origin plus cookies: add `credentials="include"`. For an agent hosted on sideagent Cloud, pass `publishableKey="pk_live_…"` instead of `endpoint`.
47
47
  6. **Env vars.** Add `LLM_API_KEY`, `APPROVAL_SECRET`, `APP_ORIGIN`, `API_BASE_URL` to `.env.example`. Never hardcode keys. Never send `LLM_API_KEY` to the browser.
48
48
  7. **Verify, then hand over for review.**
49
49
  - Run the project's typecheck and tests.