@alexkroman1/aai 0.7.2 → 0.7.3

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 (79) hide show
  1. package/dist/cli.js +337 -255
  2. package/dist/sdk/_internal_types.d.ts +4 -18
  3. package/dist/sdk/_internal_types.d.ts.map +1 -1
  4. package/dist/sdk/_internal_types.js +2 -1
  5. package/dist/sdk/_internal_types.js.map +1 -1
  6. package/dist/sdk/_mock_ws.js +1 -1
  7. package/dist/sdk/_mock_ws.js.map +1 -1
  8. package/dist/sdk/builtin_tools.d.ts +6 -2
  9. package/dist/sdk/builtin_tools.d.ts.map +1 -1
  10. package/dist/sdk/builtin_tools.js +1 -8
  11. package/dist/sdk/builtin_tools.js.map +1 -1
  12. package/dist/sdk/capnweb.d.ts +1 -1
  13. package/dist/sdk/capnweb.d.ts.map +1 -1
  14. package/dist/sdk/capnweb.js +43 -10
  15. package/dist/sdk/capnweb.js.map +1 -1
  16. package/dist/sdk/define_agent.d.ts +1 -1
  17. package/dist/sdk/define_agent.d.ts.map +1 -1
  18. package/dist/sdk/define_agent.js +26 -17
  19. package/dist/sdk/define_agent.js.map +1 -1
  20. package/dist/sdk/direct_executor.d.ts +2 -0
  21. package/dist/sdk/direct_executor.d.ts.map +1 -1
  22. package/dist/sdk/direct_executor.js +6 -1
  23. package/dist/sdk/direct_executor.js.map +1 -1
  24. package/dist/sdk/mod.d.ts +2 -1
  25. package/dist/sdk/mod.d.ts.map +1 -1
  26. package/dist/sdk/protocol.d.ts +88 -7
  27. package/dist/sdk/protocol.d.ts.map +1 -1
  28. package/dist/sdk/protocol.js.map +1 -1
  29. package/dist/sdk/runtime.d.ts +6 -4
  30. package/dist/sdk/runtime.d.ts.map +1 -1
  31. package/dist/sdk/runtime.js.map +1 -1
  32. package/dist/sdk/s2s.d.ts +2 -1
  33. package/dist/sdk/s2s.d.ts.map +1 -1
  34. package/dist/sdk/s2s.js +112 -73
  35. package/dist/sdk/s2s.js.map +1 -1
  36. package/dist/sdk/server.d.ts.map +1 -1
  37. package/dist/sdk/server.js +47 -43
  38. package/dist/sdk/server.js.map +1 -1
  39. package/dist/sdk/session.d.ts.map +1 -1
  40. package/dist/sdk/session.js +47 -44
  41. package/dist/sdk/session.js.map +1 -1
  42. package/dist/sdk/system_prompt.d.ts.map +1 -1
  43. package/dist/sdk/system_prompt.js +1 -1
  44. package/dist/sdk/system_prompt.js.map +1 -1
  45. package/dist/sdk/types.d.ts +8 -50
  46. package/dist/sdk/types.d.ts.map +1 -1
  47. package/dist/sdk/types.js +0 -8
  48. package/dist/sdk/types.js.map +1 -1
  49. package/dist/sdk/winterc_server.d.ts +4 -1
  50. package/dist/sdk/winterc_server.d.ts.map +1 -1
  51. package/dist/sdk/winterc_server.js +3 -2
  52. package/dist/sdk/winterc_server.js.map +1 -1
  53. package/dist/sdk/worker_entry.d.ts +3 -1
  54. package/dist/sdk/worker_entry.d.ts.map +1 -1
  55. package/dist/sdk/worker_entry.js +24 -17
  56. package/dist/sdk/worker_entry.js.map +1 -1
  57. package/dist/sdk/worker_shim.d.ts.map +1 -1
  58. package/dist/sdk/worker_shim.js +62 -9
  59. package/dist/sdk/worker_shim.js.map +1 -1
  60. package/dist/sdk/ws_handler.d.ts.map +1 -1
  61. package/dist/sdk/ws_handler.js +65 -58
  62. package/dist/sdk/ws_handler.js.map +1 -1
  63. package/dist/ui/_components/message_list.d.ts.map +1 -1
  64. package/dist/ui/_components/message_list.js +10 -6
  65. package/dist/ui/_components/message_list.js.map +1 -1
  66. package/dist/ui/audio.js +1 -1
  67. package/dist/ui/audio.js.map +1 -1
  68. package/dist/ui/mod.d.ts +10 -2
  69. package/dist/ui/mod.d.ts.map +1 -1
  70. package/dist/ui/mod.js +5 -2
  71. package/dist/ui/mod.js.map +1 -1
  72. package/dist/ui/session.d.ts.map +1 -1
  73. package/dist/ui/session.js +3 -1
  74. package/dist/ui/session.js.map +1 -1
  75. package/package.json +2 -1
  76. package/dist/sdk/_timeout.d.ts +0 -14
  77. package/dist/sdk/_timeout.d.ts.map +0 -1
  78. package/dist/sdk/_timeout.js +0 -24
  79. package/dist/sdk/_timeout.js.map +0 -1
package/dist/cli.js CHANGED
@@ -483,16 +483,16 @@ function getBuiltinToolSchemas(names) {
483
483
  {
484
484
  name,
485
485
  description: def.description,
486
- parameters: z3.toJSONSchema(def.parameters ?? EMPTY_PARAMS2)
486
+ parameters: z3.toJSONSchema(def.parameters ?? EMPTY_PARAMS)
487
487
  }
488
488
  ];
489
489
  });
490
490
  }
491
- var EMPTY_PARAMS2, webSearchParams, BRAVE_SEARCH_URL, BraveSearchResponseSchema, MAX_PAGE_CHARS, MAX_HTML_BYTES, visitWebpageParams, fetchJsonParams, runCodeParams, vectorSearchParams, TOOL_CREATORS;
491
+ var webSearchParams, BRAVE_SEARCH_URL, BraveSearchResponseSchema, MAX_PAGE_CHARS, MAX_HTML_BYTES, visitWebpageParams, fetchJsonParams, runCodeParams, vectorSearchParams, TOOL_CREATORS;
492
492
  var init_builtin_tools = __esm({
493
493
  "dist/sdk/builtin_tools.js"() {
494
494
  "use strict";
495
- EMPTY_PARAMS2 = z3.object({});
495
+ init_internal_types();
496
496
  webSearchParams = z3.object({
497
497
  query: z3.string().describe("The search query"),
498
498
  max_results: z3.number().describe("Maximum number of results to return (default 5)").optional()
@@ -601,6 +601,7 @@ var init_kv = __esm({
601
601
  });
602
602
 
603
603
  // dist/sdk/s2s.js
604
+ import { z as z4 } from "zod";
604
605
  function uint8ToBase64(bytes) {
605
606
  const CHUNK = 32768;
606
607
  const parts = [];
@@ -617,6 +618,73 @@ function base64ToUint8(base64) {
617
618
  }
618
619
  return bytes;
619
620
  }
621
+ function dispatchS2sMessage(target, msg) {
622
+ switch (msg.type) {
623
+ case "session.ready":
624
+ target.dispatchEvent(new CustomEvent("ready", {
625
+ detail: { session_id: msg.session_id }
626
+ }));
627
+ break;
628
+ case "session.updated":
629
+ target.dispatchEvent(new CustomEvent("session_updated", { detail: msg }));
630
+ break;
631
+ case "input.speech.started":
632
+ target.dispatchEvent(new CustomEvent("speech_started"));
633
+ break;
634
+ case "input.speech.stopped":
635
+ target.dispatchEvent(new CustomEvent("speech_stopped"));
636
+ break;
637
+ case "transcript.user.delta":
638
+ target.dispatchEvent(new CustomEvent("user_transcript_delta", {
639
+ detail: { text: msg.text }
640
+ }));
641
+ break;
642
+ case "transcript.user":
643
+ target.dispatchEvent(new CustomEvent("user_transcript", {
644
+ detail: {
645
+ item_id: msg.item_id,
646
+ text: msg.text
647
+ }
648
+ }));
649
+ break;
650
+ case "reply.started":
651
+ target.dispatchEvent(new CustomEvent("reply_started", {
652
+ detail: { reply_id: msg.reply_id }
653
+ }));
654
+ break;
655
+ case "reply.audio": {
656
+ const audioBytes = base64ToUint8(msg.data);
657
+ target.dispatchEvent(new CustomEvent("audio", { detail: { audio: audioBytes } }));
658
+ break;
659
+ }
660
+ case "transcript.agent":
661
+ target.dispatchEvent(new CustomEvent("agent_transcript", {
662
+ detail: { text: msg.text }
663
+ }));
664
+ break;
665
+ case "tool.call":
666
+ target.dispatchEvent(new CustomEvent("tool_call", {
667
+ detail: {
668
+ call_id: msg.call_id,
669
+ name: msg.name,
670
+ args: msg.args
671
+ }
672
+ }));
673
+ break;
674
+ case "reply.done":
675
+ target.dispatchEvent(new CustomEvent("reply_done", {
676
+ detail: { status: msg.status }
677
+ }));
678
+ break;
679
+ case "session.error": {
680
+ const isExpired = msg.code === "session_not_found" || msg.code === "session_forbidden";
681
+ target.dispatchEvent(new CustomEvent(isExpired ? "session_expired" : "error", {
682
+ detail: { code: msg.code, message: msg.message }
683
+ }));
684
+ break;
685
+ }
686
+ }
687
+ }
620
688
  function connectS2s(opts) {
621
689
  const { apiKey, config, createWebSocket, logger: log = consoleLogger } = opts;
622
690
  return new Promise((resolve, reject) => {
@@ -629,8 +697,7 @@ function connectS2s(opts) {
629
697
  function send(msg) {
630
698
  if (ws.readyState !== WS_OPEN)
631
699
  return;
632
- const type = msg.type;
633
- if (type !== "input.audio") {
700
+ if (msg.type !== "input.audio") {
634
701
  log.info(`S2S >> ${JSON.stringify(msg)}`);
635
702
  }
636
703
  ws.send(JSON.stringify(msg));
@@ -659,86 +726,26 @@ function connectS2s(opts) {
659
726
  resolve(handle);
660
727
  });
661
728
  ws.on("message", (data) => {
662
- let msg;
729
+ let raw;
663
730
  try {
664
- msg = JSON.parse(String(data));
731
+ raw = JSON.parse(String(data));
665
732
  } catch {
666
733
  return;
667
734
  }
668
- const type = msg.type;
669
- if (type !== "reply.audio") {
670
- log.info(`S2S << ${JSON.stringify(msg)}`);
735
+ const parsed = S2sServerMessageSchema.safeParse(raw);
736
+ if (!parsed.success) {
737
+ log.info(`S2S << unrecognised message: ${JSON.stringify(raw)}`);
738
+ return;
671
739
  }
672
- switch (type) {
673
- case "session.ready":
674
- target.dispatchEvent(new CustomEvent("ready", {
675
- detail: { session_id: msg.session_id }
676
- }));
677
- break;
678
- case "session.updated":
679
- target.dispatchEvent(new CustomEvent("session_updated", { detail: msg }));
680
- break;
681
- case "input.speech.started":
682
- target.dispatchEvent(new CustomEvent("speech_started"));
683
- break;
684
- case "input.speech.stopped":
685
- target.dispatchEvent(new CustomEvent("speech_stopped"));
686
- break;
687
- case "transcript.user.delta":
688
- target.dispatchEvent(new CustomEvent("user_transcript_delta", {
689
- detail: { text: msg.text }
690
- }));
691
- break;
692
- case "transcript.user":
693
- target.dispatchEvent(new CustomEvent("user_transcript", {
694
- detail: {
695
- item_id: msg.item_id,
696
- text: msg.text
697
- }
698
- }));
699
- break;
700
- case "reply.started":
701
- target.dispatchEvent(new CustomEvent("reply_started", {
702
- detail: { reply_id: msg.reply_id }
703
- }));
704
- break;
705
- case "reply.audio": {
706
- const audioBytes = base64ToUint8(msg.data);
707
- target.dispatchEvent(new CustomEvent("audio", { detail: { audio: audioBytes } }));
708
- break;
709
- }
710
- case "transcript.agent":
711
- target.dispatchEvent(new CustomEvent("agent_transcript", {
712
- detail: { text: msg.text }
713
- }));
714
- break;
715
- case "tool.call":
716
- target.dispatchEvent(new CustomEvent("tool_call", {
717
- detail: {
718
- call_id: msg.call_id,
719
- name: msg.name,
720
- args: msg.args ?? {}
721
- }
722
- }));
723
- break;
724
- case "reply.done":
725
- target.dispatchEvent(new CustomEvent("reply_done", {
726
- detail: { status: msg.status ?? void 0 }
727
- }));
728
- break;
729
- case "session.error": {
730
- const code = msg.code;
731
- const isExpired = code === "session_not_found" || code === "session_forbidden";
732
- target.dispatchEvent(new CustomEvent(isExpired ? "session_expired" : "error", {
733
- detail: { code, message: msg.message }
734
- }));
735
- break;
736
- }
740
+ const msg = parsed.data;
741
+ if (msg.type !== "reply.audio") {
742
+ log.info(`S2S << ${JSON.stringify(msg)}`);
737
743
  }
744
+ dispatchS2sMessage(target, msg);
738
745
  });
739
746
  ws.on("close", (code, reason) => {
740
747
  log.info("S2S WebSocket closed", {
741
- code,
748
+ code: typeof code === "number" ? code : 0,
742
749
  reason: reason instanceof Uint8Array ? new TextDecoder().decode(reason) : String(reason ?? "")
743
750
  });
744
751
  target.dispatchEvent(new CustomEvent("close"));
@@ -756,12 +763,42 @@ function connectS2s(opts) {
756
763
  });
757
764
  });
758
765
  }
759
- var WS_OPEN;
766
+ var WS_OPEN, S2sServerMessageSchema;
760
767
  var init_s2s = __esm({
761
768
  "dist/sdk/s2s.js"() {
762
769
  "use strict";
763
770
  init_runtime();
764
771
  WS_OPEN = 1;
772
+ S2sServerMessageSchema = z4.discriminatedUnion("type", [
773
+ z4.object({ type: z4.literal("session.ready"), session_id: z4.string() }),
774
+ z4.object({ type: z4.literal("session.updated") }).passthrough(),
775
+ z4.object({ type: z4.literal("input.speech.started") }),
776
+ z4.object({ type: z4.literal("input.speech.stopped") }),
777
+ z4.object({ type: z4.literal("transcript.user.delta"), text: z4.string() }),
778
+ z4.object({
779
+ type: z4.literal("transcript.user"),
780
+ item_id: z4.string(),
781
+ text: z4.string()
782
+ }),
783
+ z4.object({ type: z4.literal("reply.started"), reply_id: z4.string() }),
784
+ z4.object({ type: z4.literal("reply.audio"), data: z4.string() }),
785
+ z4.object({ type: z4.literal("transcript.agent"), text: z4.string() }),
786
+ z4.object({
787
+ type: z4.literal("tool.call"),
788
+ call_id: z4.string(),
789
+ name: z4.string(),
790
+ args: z4.record(z4.string(), z4.unknown()).optional().default({})
791
+ }),
792
+ z4.object({
793
+ type: z4.literal("reply.done"),
794
+ status: z4.string().optional()
795
+ }),
796
+ z4.object({
797
+ type: z4.literal("session.error"),
798
+ code: z4.string(),
799
+ message: z4.string()
800
+ })
801
+ ]);
765
802
  }
766
803
  });
767
804
 
@@ -787,7 +824,7 @@ Voice-First Rules:
787
824
  // dist/sdk/system_prompt.js
788
825
  function buildSystemPrompt(config, opts) {
789
826
  const { hasTools } = opts;
790
- const agentInstructions = config.instructions ? `
827
+ const agentInstructions = config.instructions && config.instructions !== DEFAULT_INSTRUCTIONS ? `
791
828
 
792
829
  Agent-Specific Instructions:
793
830
  ${config.instructions}` : "";
@@ -844,10 +881,10 @@ function createS2sSession(opts) {
844
881
  return null;
845
882
  }
846
883
  }
847
- async function invokeHook(hook, ...args) {
884
+ function invokeHook(hook, arg) {
848
885
  if (!hookInvoker)
849
886
  return;
850
- try {
887
+ const run = async () => {
851
888
  switch (hook) {
852
889
  case "onConnect":
853
890
  await hookInvoker.onConnect(id, HOOK_TIMEOUT_MS);
@@ -856,20 +893,21 @@ function createS2sSession(opts) {
856
893
  await hookInvoker.onDisconnect(id, HOOK_TIMEOUT_MS);
857
894
  break;
858
895
  case "onTurn":
859
- await hookInvoker.onTurn(id, args[0], HOOK_TIMEOUT_MS);
896
+ await hookInvoker.onTurn(id, arg, HOOK_TIMEOUT_MS);
860
897
  break;
861
898
  case "onError":
862
- await hookInvoker.onError(id, args[0], HOOK_TIMEOUT_MS);
899
+ await hookInvoker.onError(id, arg, HOOK_TIMEOUT_MS);
863
900
  break;
864
901
  case "onStep":
865
- await hookInvoker.onStep(id, args[0], HOOK_TIMEOUT_MS);
902
+ await hookInvoker.onStep(id, arg, HOOK_TIMEOUT_MS);
866
903
  break;
867
904
  }
868
- } catch (err) {
905
+ };
906
+ run().catch((err) => {
869
907
  log.warn(`${hook} hook failed`, {
870
908
  err: err instanceof Error ? err.message : String(err)
871
909
  });
872
- }
910
+ });
873
911
  }
874
912
  async function handleToolCall(detail) {
875
913
  const { call_id, name, args: parsedArgs } = detail;
@@ -929,6 +967,9 @@ function createS2sSession(opts) {
929
967
  pendingTools.push({ call_id, result });
930
968
  client.event({ type: "tool_call_done", toolCallId: call_id, result });
931
969
  }
970
+ function on(target, event, handler) {
971
+ target.addEventListener(event, handler);
972
+ }
932
973
  async function connectAndSetup() {
933
974
  try {
934
975
  const handle = await _internals3.connectS2s({
@@ -942,54 +983,55 @@ function createS2sSession(opts) {
942
983
  session_id: s2sSessionId
943
984
  });
944
985
  handle.resumeSession(s2sSessionId);
986
+ } else {
987
+ handle.updateSession({
988
+ system_prompt: systemPrompt,
989
+ tools: s2sTools,
990
+ ...agentConfig.greeting ? { greeting: agentConfig.greeting } : {}
991
+ });
945
992
  }
946
- handle.updateSession({
947
- system_prompt: systemPrompt,
948
- tools: s2sTools,
949
- ...agentConfig.greeting ? { greeting: agentConfig.greeting } : {}
950
- });
951
- handle.addEventListener("ready", ((e) => {
993
+ on(handle, "ready", (e) => {
952
994
  s2sSessionId = e.detail.session_id;
953
995
  log.info("S2S session ready", { session_id: s2sSessionId });
954
- }));
955
- handle.addEventListener("session_expired", (() => {
996
+ });
997
+ on(handle, "session_expired", () => {
956
998
  log.info("S2S session expired, reconnecting fresh");
957
999
  s2sSessionId = null;
958
1000
  handle.close();
959
- }));
1001
+ });
960
1002
  handle.addEventListener("speech_started", () => {
961
1003
  client.event({ type: "speech_started" });
962
1004
  });
963
1005
  handle.addEventListener("speech_stopped", () => {
964
1006
  client.event({ type: "speech_stopped" });
965
1007
  });
966
- handle.addEventListener("user_transcript_delta", ((e) => {
1008
+ on(handle, "user_transcript_delta", (e) => {
967
1009
  client.event({
968
1010
  type: "transcript",
969
1011
  text: e.detail.text,
970
1012
  isFinal: false
971
1013
  });
972
- }));
973
- handle.addEventListener("user_transcript", ((e) => {
1014
+ });
1015
+ on(handle, "user_transcript", (e) => {
974
1016
  const { text } = e.detail;
975
1017
  log.info("S2S user transcript", { text });
976
1018
  client.event({ type: "transcript", text, isFinal: true });
977
1019
  client.event({ type: "turn", text });
978
1020
  conversationMessages.push({ role: "user", content: text });
979
1021
  invokeHook("onTurn", text);
980
- }));
1022
+ });
981
1023
  handle.addEventListener("reply_started", () => {
982
1024
  toolCallCount = 0;
983
1025
  });
984
- handle.addEventListener("audio", ((e) => {
1026
+ on(handle, "audio", (e) => {
985
1027
  client.playAudioChunk(e.detail.audio);
986
- }));
987
- handle.addEventListener("agent_transcript", ((e) => {
1028
+ });
1029
+ on(handle, "agent_transcript", (e) => {
988
1030
  const { text } = e.detail;
989
1031
  client.event({ type: "chat", text });
990
1032
  conversationMessages.push({ role: "assistant", content: text });
991
- }));
992
- handle.addEventListener("tool_call", ((e) => {
1033
+ });
1034
+ on(handle, "tool_call", (e) => {
993
1035
  const p = handleToolCall(e.detail).catch((err) => {
994
1036
  log.error("Tool call handler failed", {
995
1037
  err: err instanceof Error ? err.message : String(err)
@@ -999,25 +1041,23 @@ function createS2sSession(opts) {
999
1041
  turnPromise = (prev ?? Promise.resolve()).then(() => p).finally(() => {
1000
1042
  turnPromise = null;
1001
1043
  });
1002
- }));
1003
- handle.addEventListener("reply_done", ((e) => {
1044
+ });
1045
+ on(handle, "reply_done", (e) => {
1004
1046
  if (e.detail.status === "interrupted") {
1005
1047
  log.info("S2S reply interrupted (barge-in)");
1006
1048
  pendingTools = [];
1007
1049
  client.event({ type: "cancelled" });
1008
- } else {
1009
- if (pendingTools.length > 0) {
1010
- for (const tool of pendingTools) {
1011
- s2s?.sendToolResult(tool.call_id, tool.result);
1012
- }
1013
- pendingTools = [];
1014
- } else {
1015
- client.playAudioDone();
1016
- client.event({ type: "tts_done" });
1050
+ } else if (pendingTools.length > 0) {
1051
+ for (const tool of pendingTools) {
1052
+ s2s?.sendToolResult(tool.call_id, tool.result);
1017
1053
  }
1054
+ pendingTools = [];
1055
+ } else {
1056
+ client.playAudioDone();
1057
+ client.event({ type: "tts_done" });
1018
1058
  }
1019
- }));
1020
- handle.addEventListener("error", ((e) => {
1059
+ });
1060
+ on(handle, "error", (e) => {
1021
1061
  log.error("S2S error", {
1022
1062
  code: e.detail.code,
1023
1063
  message: e.detail.message
@@ -1027,7 +1067,7 @@ function createS2sSession(opts) {
1027
1067
  code: "internal",
1028
1068
  message: e.detail.message
1029
1069
  });
1030
- }));
1070
+ });
1031
1071
  handle.addEventListener("close", () => {
1032
1072
  log.info("S2S closed");
1033
1073
  s2s = null;
@@ -1106,31 +1146,80 @@ var init_session = __esm({
1106
1146
  }
1107
1147
  });
1108
1148
 
1149
+ // dist/sdk/vector.js
1150
+ function createMemoryVectorStore() {
1151
+ const store = /* @__PURE__ */ new Map();
1152
+ return {
1153
+ upsert(id, data, metadata) {
1154
+ store.set(id, { data, metadata });
1155
+ return Promise.resolve();
1156
+ },
1157
+ query(text, options) {
1158
+ const topK = options?.topK ?? 10;
1159
+ const query = text.toLowerCase();
1160
+ const results = [];
1161
+ for (const [id, entry] of store) {
1162
+ const data = entry.data.toLowerCase();
1163
+ const words = query.split(/\s+/).filter(Boolean);
1164
+ const matches = words.filter((w) => data.includes(w)).length;
1165
+ if (matches > 0) {
1166
+ results.push({
1167
+ id,
1168
+ score: matches / Math.max(words.length, 1),
1169
+ data: entry.data,
1170
+ metadata: entry.metadata
1171
+ });
1172
+ }
1173
+ }
1174
+ results.sort((a, b) => b.score - a.score);
1175
+ return Promise.resolve(results.slice(0, topK));
1176
+ },
1177
+ remove(ids) {
1178
+ const idArray = Array.isArray(ids) ? ids : [ids];
1179
+ for (const id of idArray) {
1180
+ store.delete(id);
1181
+ }
1182
+ return Promise.resolve();
1183
+ }
1184
+ };
1185
+ }
1186
+ var init_vector = __esm({
1187
+ "dist/sdk/vector.js"() {
1188
+ "use strict";
1189
+ }
1190
+ });
1191
+
1109
1192
  // dist/sdk/worker_entry.js
1110
- import { z as z4 } from "zod";
1193
+ function buildToolContext(opts) {
1194
+ const { env, sessionId, state, kv, vector, messages } = opts;
1195
+ return {
1196
+ sessionId: sessionId ?? "",
1197
+ env: { ...env },
1198
+ abortSignal: AbortSignal.timeout(TOOL_HANDLER_TIMEOUT),
1199
+ state: state ?? {},
1200
+ get kv() {
1201
+ if (!kv)
1202
+ throw new Error("KV not available");
1203
+ return kv;
1204
+ },
1205
+ get vector() {
1206
+ if (!vector)
1207
+ throw new Error("Vector store not available");
1208
+ return vector;
1209
+ },
1210
+ messages: messages ?? []
1211
+ };
1212
+ }
1111
1213
  async function executeToolCall(name, args, options) {
1112
- const { tool, env, sessionId, state, kv, messages } = options;
1113
- const schema = tool.parameters ?? z4.object({});
1214
+ const { tool } = options;
1215
+ const schema = tool.parameters ?? EMPTY_PARAMS;
1114
1216
  const parsed = schema.safeParse(args);
1115
1217
  if (!parsed.success) {
1116
1218
  const issues = (parsed.error?.issues ?? []).map((i) => `${i.path.map(String).join(".")}: ${i.message}`).join(", ");
1117
1219
  return `Error: Invalid arguments for tool "${name}": ${issues}`;
1118
1220
  }
1119
1221
  try {
1120
- const abortSignal = AbortSignal.timeout(TOOL_HANDLER_TIMEOUT);
1121
- const envCopy = { ...env };
1122
- const ctx = {
1123
- sessionId: sessionId ?? "",
1124
- env: envCopy,
1125
- abortSignal,
1126
- state: state ?? {},
1127
- get kv() {
1128
- if (!kv)
1129
- throw new Error("KV not available");
1130
- return kv;
1131
- },
1132
- messages: messages ?? []
1133
- };
1222
+ const ctx = buildToolContext(options);
1134
1223
  const result = await Promise.resolve(tool.execute(parsed.data, ctx));
1135
1224
  if (result == null)
1136
1225
  return "null";
@@ -1148,6 +1237,7 @@ var TOOL_HANDLER_TIMEOUT;
1148
1237
  var init_worker_entry = __esm({
1149
1238
  "dist/sdk/worker_entry.js"() {
1150
1239
  "use strict";
1240
+ init_internal_types();
1151
1241
  TOOL_HANDLER_TIMEOUT = 3e4;
1152
1242
  }
1153
1243
  });
@@ -1173,7 +1263,7 @@ function buildAgentConfig(agent) {
1173
1263
  return config;
1174
1264
  }
1175
1265
  function createDirectExecutor(opts) {
1176
- const { agent, env, kv = createMemoryKv(), vectorSearch, createWebSocket, logger = consoleLogger, metrics = noopMetrics, s2sConfig = DEFAULT_S2S_CONFIG } = opts;
1266
+ const { agent, env, kv = createMemoryKv(), vector = createMemoryVectorStore(), vectorSearch, createWebSocket, logger = consoleLogger, metrics = noopMetrics, s2sConfig = DEFAULT_S2S_CONFIG } = opts;
1177
1267
  const agentConfig = buildAgentConfig(agent);
1178
1268
  const builtinDefs = getBuiltinToolDefs(agent.builtinTools ?? [], vectorSearch ? { vectorSearch } : void 0);
1179
1269
  const allTools = {
@@ -1198,6 +1288,9 @@ function createDirectExecutor(opts) {
1198
1288
  state: getState(sessionId),
1199
1289
  get kv() {
1200
1290
  return kv;
1291
+ },
1292
+ get vector() {
1293
+ return vector;
1201
1294
  }
1202
1295
  };
1203
1296
  }
@@ -1211,6 +1304,7 @@ function createDirectExecutor(opts) {
1211
1304
  sessionId,
1212
1305
  state: getState(sessionId ?? ""),
1213
1306
  kv,
1307
+ vector,
1214
1308
  messages
1215
1309
  });
1216
1310
  };
@@ -1283,6 +1377,7 @@ var init_direct_executor = __esm({
1283
1377
  init_kv();
1284
1378
  init_runtime();
1285
1379
  init_session();
1380
+ init_vector();
1286
1381
  init_worker_entry();
1287
1382
  }
1288
1383
  });
@@ -1313,6 +1408,64 @@ function createClientSink(ws) {
1313
1408
  }
1314
1409
  };
1315
1410
  }
1411
+ function isBinaryData(data) {
1412
+ return globalThis.Buffer?.isBuffer(data) || data instanceof ArrayBuffer || data instanceof Uint8Array;
1413
+ }
1414
+ function toUint8Array(data) {
1415
+ if (data instanceof Uint8Array)
1416
+ return data;
1417
+ if (data instanceof ArrayBuffer)
1418
+ return new Uint8Array(data);
1419
+ const buf = data;
1420
+ return new Uint8Array(buf.buffer ?? data, buf.byteOffset ?? 0, buf.byteLength);
1421
+ }
1422
+ function handleBinaryAudio(data, session, log, ctx, sid) {
1423
+ if (!isBinaryData(data))
1424
+ return false;
1425
+ const chunk = toUint8Array(data);
1426
+ if (!isValidAudioChunk(chunk)) {
1427
+ log.warn("Invalid audio chunk, dropping", {
1428
+ ...ctx,
1429
+ sid,
1430
+ bytes: chunk.byteLength,
1431
+ aligned: chunk.byteLength % 2 === 0
1432
+ });
1433
+ return true;
1434
+ }
1435
+ session.onAudio(chunk);
1436
+ return true;
1437
+ }
1438
+ function handleTextMessage(data, session, log, ctx, sid) {
1439
+ if (typeof data !== "string")
1440
+ return;
1441
+ let json;
1442
+ try {
1443
+ json = JSON.parse(data);
1444
+ } catch {
1445
+ log.warn("Invalid JSON from client", { ...ctx, sid });
1446
+ return;
1447
+ }
1448
+ const parsed = ClientMessageSchema.safeParse(json);
1449
+ if (!parsed.success) {
1450
+ log.warn("Invalid client message", { ...ctx, sid, error: parsed.error.message });
1451
+ return;
1452
+ }
1453
+ const msg = parsed.data;
1454
+ switch (msg.type) {
1455
+ case "audio_ready":
1456
+ session.onAudioReady();
1457
+ break;
1458
+ case "cancel":
1459
+ session.onCancel();
1460
+ break;
1461
+ case "reset":
1462
+ session.onReset();
1463
+ break;
1464
+ case "history":
1465
+ session.onHistory(msg.messages);
1466
+ break;
1467
+ }
1468
+ }
1316
1469
  function wireSessionSocket(ws, opts) {
1317
1470
  const { sessions, logger: log = consoleLogger } = opts;
1318
1471
  const sessionId = crypto.randomUUID();
@@ -1337,56 +1490,10 @@ function wireSessionSocket(ws, opts) {
1337
1490
  ws.addEventListener("message", (event) => {
1338
1491
  if (!session)
1339
1492
  return;
1340
- const msgEvent = event;
1341
- const { data } = msgEvent;
1342
- const isBinary = globalThis.Buffer?.isBuffer(data) || data instanceof ArrayBuffer || data instanceof Uint8Array;
1343
- if (isBinary) {
1344
- const chunk = data instanceof Uint8Array ? data : new Uint8Array(data.buffer ?? data, data.byteOffset ?? 0, data.byteLength ?? data.byteLength);
1345
- if (!isValidAudioChunk(chunk)) {
1346
- log.warn("Invalid audio chunk, dropping", {
1347
- ...ctx,
1348
- sid,
1349
- bytes: chunk.byteLength,
1350
- aligned: chunk.byteLength % 2 === 0
1351
- });
1352
- return;
1353
- }
1354
- session.onAudio(chunk);
1493
+ const { data } = event;
1494
+ if (handleBinaryAudio(data, session, log, ctx, sid))
1355
1495
  return;
1356
- }
1357
- if (typeof data !== "string")
1358
- return;
1359
- let json;
1360
- try {
1361
- json = JSON.parse(data);
1362
- } catch {
1363
- log.warn("Invalid JSON from client", { ...ctx, sid });
1364
- return;
1365
- }
1366
- const parsed = ClientMessageSchema.safeParse(json);
1367
- if (!parsed.success) {
1368
- log.warn("Invalid client message", {
1369
- ...ctx,
1370
- sid,
1371
- error: parsed.error.message
1372
- });
1373
- return;
1374
- }
1375
- const msg = parsed.data;
1376
- switch (msg.type) {
1377
- case "audio_ready":
1378
- session.onAudioReady();
1379
- break;
1380
- case "cancel":
1381
- session.onCancel();
1382
- break;
1383
- case "reset":
1384
- session.onReset();
1385
- break;
1386
- case "history":
1387
- session.onHistory(msg.messages);
1388
- break;
1389
- }
1496
+ handleTextMessage(data, session, log, ctx, sid);
1390
1497
  });
1391
1498
  ws.addEventListener("close", () => {
1392
1499
  log.info("Session disconnected", { ...ctx, sid });
@@ -1414,11 +1521,12 @@ var init_ws_handler = __esm({
1414
1521
 
1415
1522
  // dist/sdk/winterc_server.js
1416
1523
  function createWintercServer(options) {
1417
- const { agent, env, kv = createMemoryKv(), vectorSearch, clientHtml, logger = consoleLogger, metrics = noopMetrics, s2sConfig = DEFAULT_S2S_CONFIG } = options;
1524
+ const { agent, env, kv = createMemoryKv(), vector = createMemoryVectorStore(), vectorSearch, clientHtml, logger = consoleLogger, metrics = noopMetrics, s2sConfig = DEFAULT_S2S_CONFIG } = options;
1418
1525
  const executor = createDirectExecutor({
1419
1526
  agent,
1420
1527
  env,
1421
1528
  kv,
1529
+ vector,
1422
1530
  ...vectorSearch ? { vectorSearch } : {},
1423
1531
  createWebSocket: options.createWebSocket,
1424
1532
  logger,
@@ -1430,8 +1538,7 @@ function createWintercServer(options) {
1430
1538
  protocolVersion: PROTOCOL_VERSION,
1431
1539
  audioFormat: AUDIO_FORMAT,
1432
1540
  sampleRate: s2sConfig.inputSampleRate,
1433
- ttsSampleRate: s2sConfig.outputSampleRate,
1434
- mode: "s2s"
1541
+ ttsSampleRate: s2sConfig.outputSampleRate
1435
1542
  };
1436
1543
  return {
1437
1544
  async fetch(request) {
@@ -1479,6 +1586,7 @@ var init_winterc_server = __esm({
1479
1586
  init_kv();
1480
1587
  init_protocol();
1481
1588
  init_runtime();
1589
+ init_vector();
1482
1590
  init_ws_handler();
1483
1591
  }
1484
1592
  });
@@ -1522,7 +1630,9 @@ function createServer(options) {
1522
1630
  agent,
1523
1631
  env,
1524
1632
  ...kv ? { kv } : {},
1525
- createWebSocket: wsFactory,
1633
+ createWebSocket: wsFactory ?? (() => {
1634
+ throw new Error("WebSocket factory not loaded");
1635
+ }),
1526
1636
  ...clientHtml !== void 0 ? { clientHtml } : {},
1527
1637
  logger,
1528
1638
  s2sConfig
@@ -1539,46 +1649,9 @@ function createServer(options) {
1539
1649
  await getWsFactory();
1540
1650
  const http = await import("node:http");
1541
1651
  const nodeServer = http.createServer(async (req, res) => {
1542
- try {
1543
- const protocol = req.socket.encrypted ? "https" : "http";
1544
- const host = req.headers.host ?? `localhost:${port}`;
1545
- const url = new URL(req.url ?? "/", `${protocol}://${host}`);
1546
- const headers = new Headers();
1547
- for (const [key, val] of Object.entries(req.headers)) {
1548
- if (val)
1549
- headers.set(key, Array.isArray(val) ? val[0] : val);
1550
- }
1551
- const request = new Request(url, {
1552
- method: req.method ?? "GET",
1553
- headers
1554
- });
1555
- const response = await getWinterc().fetch(request);
1556
- res.writeHead(response.status, Object.fromEntries(response.headers));
1557
- const body = await response.text();
1558
- res.end(body);
1559
- } catch (err) {
1560
- res.writeHead(500);
1561
- res.end(err instanceof Error ? err.message : "Internal Server Error");
1562
- }
1652
+ await nodeHttpHandler(req, res, port, getWinterc);
1563
1653
  });
1564
- try {
1565
- const wsMod = await import("ws");
1566
- const WSServer = wsMod.WebSocketServer;
1567
- if (WSServer) {
1568
- const wss = new WSServer({ noServer: true });
1569
- nodeServer.on("upgrade", (req, socket, head) => {
1570
- wss.handleUpgrade(req, socket, head, (ws) => {
1571
- const reqUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
1572
- const resume = reqUrl.searchParams.has("resume");
1573
- getWinterc().handleWebSocket(ws, {
1574
- skipGreeting: resume
1575
- });
1576
- });
1577
- });
1578
- }
1579
- } catch {
1580
- logger.warn("ws package not available for Node.js WebSocket upgrade");
1581
- }
1654
+ attachWsUpgrade(nodeServer, port, getWinterc, logger);
1582
1655
  await new Promise((resolve) => {
1583
1656
  nodeServer.listen(port, () => {
1584
1657
  logger.info(`Agent "${agent.name}" listening on http://localhost:${port}`);
@@ -1599,6 +1672,43 @@ function createServer(options) {
1599
1672
  }
1600
1673
  };
1601
1674
  }
1675
+ async function nodeHttpHandler(req, res, port, getWinterc) {
1676
+ try {
1677
+ const protocol = req.socket.encrypted ? "https" : "http";
1678
+ const host = req.headers.host ?? `localhost:${port}`;
1679
+ const url = new URL(req.url ?? "/", `${protocol}://${host}`);
1680
+ const headers = new Headers();
1681
+ for (const [key, val] of Object.entries(req.headers)) {
1682
+ if (val)
1683
+ headers.set(key, Array.isArray(val) ? val[0] ?? "" : val);
1684
+ }
1685
+ const request = new Request(url, { method: req.method ?? "GET", headers });
1686
+ const response = await getWinterc().fetch(request);
1687
+ res.writeHead(response.status, Object.fromEntries(response.headers));
1688
+ res.end(await response.text());
1689
+ } catch (err) {
1690
+ res.writeHead(500);
1691
+ res.end(err instanceof Error ? err.message : "Internal Server Error");
1692
+ }
1693
+ }
1694
+ function attachWsUpgrade(nodeServer, port, getWinterc, logger) {
1695
+ import("ws").then((wsMod) => {
1696
+ const WSServer = wsMod.WebSocketServer;
1697
+ if (!WSServer)
1698
+ return;
1699
+ const wss = new WSServer({ noServer: true });
1700
+ nodeServer.on("upgrade", (req, socket, head) => {
1701
+ wss.handleUpgrade(req, socket, head, (ws) => {
1702
+ const reqUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
1703
+ getWinterc().handleWebSocket(ws, {
1704
+ skipGreeting: reqUrl.searchParams.has("resume")
1705
+ });
1706
+ });
1707
+ });
1708
+ }).catch(() => {
1709
+ logger.warn("ws package not available for Node.js WebSocket upgrade");
1710
+ });
1711
+ }
1602
1712
  var init_server = __esm({
1603
1713
  "dist/sdk/server.js"() {
1604
1714
  init_runtime();
@@ -2261,39 +2371,11 @@ async function writeBuildOutput(agentDir, bundle) {
2261
2371
  fs3.writeFile(path3.join(buildDir, "index.html"), bundle.html)
2262
2372
  ]);
2263
2373
  }
2264
- async function checkAgent(agentDir) {
2265
- const userFiles = ["agent.ts"];
2266
- for (const f of ["client.tsx", "components.tsx"]) {
2267
- try {
2268
- await fs3.stat(path3.join(agentDir, f));
2269
- userFiles.push(f);
2270
- } catch {
2271
- }
2272
- }
2273
- const checks = [{ args: ["--noEmit", ...userFiles], label: "Type-check" }];
2274
- const results = await Promise.allSettled(
2275
- checks.map(({ args }) => execFileAsync("npx", ["tsc", ...args], { cwd: agentDir }))
2276
- );
2277
- const errors = [];
2278
- for (const [i, r] of results.entries()) {
2279
- if (r.status === "rejected") {
2280
- const label = checks[i]?.label ?? "unknown";
2281
- const msg = r.reason.stderr?.trim() ?? String(r.reason);
2282
- error2(`${label}: ${msg}`);
2283
- errors.push(label);
2284
- }
2285
- }
2286
- if (errors.length > 0) {
2287
- throw new Error(`${errors.join(", ")} failed \u2014 fix the errors above`);
2288
- }
2289
- }
2290
2374
  async function runBuild(opts) {
2291
2375
  const agent = await loadAgent(opts.agentDir);
2292
2376
  if (!agent) {
2293
2377
  throw new Error("No agent found \u2014 run `aai new` first");
2294
2378
  }
2295
- step("Check", agent.slug);
2296
- await checkAgent(opts.agentDir);
2297
2379
  step("Bundle", agent.slug);
2298
2380
  let bundle;
2299
2381
  try {