@farazirfan/costar-server-executor 1.7.37 → 1.7.39

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 (253) hide show
  1. package/dist/agent/agent.d.ts +90 -0
  2. package/dist/agent/agent.d.ts.map +1 -1
  3. package/dist/agent/agent.js +606 -0
  4. package/dist/agent/agent.js.map +1 -1
  5. package/dist/agent/pi-embedded-runner/run.d.ts.map +1 -1
  6. package/dist/agent/pi-embedded-runner/run.js +2 -1
  7. package/dist/agent/pi-embedded-runner/run.js.map +1 -1
  8. package/dist/agent/pi-embedded-runner/system-prompt.d.ts.map +1 -1
  9. package/dist/agent/pi-embedded-runner/system-prompt.js +16 -37
  10. package/dist/agent/pi-embedded-runner/system-prompt.js.map +1 -1
  11. package/dist/agent/pi-embedded-runner/tools.d.ts +4 -1
  12. package/dist/agent/pi-embedded-runner/tools.d.ts.map +1 -1
  13. package/dist/agent/pi-embedded-runner/tools.js +3 -1
  14. package/dist/agent/pi-embedded-runner/tools.js.map +1 -1
  15. package/dist/agent/pi-embedded-runner/types.d.ts +4 -0
  16. package/dist/agent/pi-embedded-runner/types.d.ts.map +1 -1
  17. package/dist/cli/env-loader.d.ts.map +1 -1
  18. package/dist/cli/env-loader.js +1 -0
  19. package/dist/cli/env-loader.js.map +1 -1
  20. package/dist/cli/setup.js +2 -2
  21. package/dist/cli/setup.js.map +1 -1
  22. package/dist/cron/normalize.d.ts +31 -0
  23. package/dist/cron/normalize.d.ts.map +1 -0
  24. package/dist/cron/normalize.js +211 -0
  25. package/dist/cron/normalize.js.map +1 -0
  26. package/dist/cron/scheduler.d.ts +33 -3
  27. package/dist/cron/scheduler.d.ts.map +1 -1
  28. package/dist/cron/scheduler.js +253 -48
  29. package/dist/cron/scheduler.js.map +1 -1
  30. package/dist/heartbeat/runner.d.ts +27 -12
  31. package/dist/heartbeat/runner.d.ts.map +1 -1
  32. package/dist/heartbeat/runner.js +82 -104
  33. package/dist/heartbeat/runner.js.map +1 -1
  34. package/dist/infra/heartbeat-events-filter.d.ts +29 -0
  35. package/dist/infra/heartbeat-events-filter.d.ts.map +1 -0
  36. package/dist/infra/heartbeat-events-filter.js +80 -0
  37. package/dist/infra/heartbeat-events-filter.js.map +1 -0
  38. package/dist/infra/index.d.ts +9 -0
  39. package/dist/infra/index.d.ts.map +1 -0
  40. package/dist/infra/index.js +9 -0
  41. package/dist/infra/index.js.map +1 -0
  42. package/dist/infra/system-events.d.ts +58 -2
  43. package/dist/infra/system-events.d.ts.map +1 -1
  44. package/dist/infra/system-events.js +80 -14
  45. package/dist/infra/system-events.js.map +1 -1
  46. package/dist/server.d.ts.map +1 -1
  47. package/dist/server.js +6 -1
  48. package/dist/server.js.map +1 -1
  49. package/dist/services/platform-keys.d.ts +19 -0
  50. package/dist/services/platform-keys.d.ts.map +1 -0
  51. package/dist/services/platform-keys.js +74 -0
  52. package/dist/services/platform-keys.js.map +1 -0
  53. package/dist/subagent/registry.d.ts +96 -0
  54. package/dist/subagent/registry.d.ts.map +1 -0
  55. package/dist/subagent/registry.js +180 -0
  56. package/dist/subagent/registry.js.map +1 -0
  57. package/dist/tools/complete-turn.d.ts +2 -2
  58. package/dist/tools/complete-turn.js +10 -10
  59. package/dist/tools/complete-turn.js.map +1 -1
  60. package/dist/tools/contacts.d.ts +13 -0
  61. package/dist/tools/contacts.d.ts.map +1 -0
  62. package/dist/tools/contacts.js +80 -0
  63. package/dist/tools/contacts.js.map +1 -0
  64. package/dist/tools/cron.d.ts +17 -2
  65. package/dist/tools/cron.d.ts.map +1 -1
  66. package/dist/tools/cron.js +117 -35
  67. package/dist/tools/cron.js.map +1 -1
  68. package/dist/tools/google-maps.d.ts +6 -6
  69. package/dist/tools/google-maps.d.ts.map +1 -1
  70. package/dist/tools/google-maps.js +207 -262
  71. package/dist/tools/google-maps.js.map +1 -1
  72. package/dist/tools/index.d.ts +17 -7
  73. package/dist/tools/index.d.ts.map +1 -1
  74. package/dist/tools/index.js +40 -9
  75. package/dist/tools/index.js.map +1 -1
  76. package/dist/tools/phone-call.d.ts +11 -0
  77. package/dist/tools/phone-call.d.ts.map +1 -0
  78. package/dist/tools/phone-call.js +151 -0
  79. package/dist/tools/phone-call.js.map +1 -0
  80. package/dist/tools/sessions-spawn.d.ts +33 -0
  81. package/dist/tools/sessions-spawn.d.ts.map +1 -0
  82. package/dist/tools/sessions-spawn.js +164 -0
  83. package/dist/tools/sessions-spawn.js.map +1 -0
  84. package/dist/tools/spotify.d.ts +12 -0
  85. package/dist/tools/spotify.d.ts.map +1 -0
  86. package/dist/tools/spotify.js +251 -0
  87. package/dist/tools/spotify.js.map +1 -0
  88. package/dist/tools/subagents.d.ts +23 -0
  89. package/dist/tools/subagents.d.ts.map +1 -0
  90. package/dist/tools/subagents.js +209 -0
  91. package/dist/tools/subagents.js.map +1 -0
  92. package/dist/tools/whatsapp.d.ts +13 -0
  93. package/dist/tools/whatsapp.d.ts.map +1 -0
  94. package/dist/tools/whatsapp.js +215 -0
  95. package/dist/tools/whatsapp.js.map +1 -0
  96. package/dist/tools/youtube.d.ts +12 -0
  97. package/dist/tools/youtube.d.ts.map +1 -0
  98. package/dist/tools/youtube.js +218 -0
  99. package/dist/tools/youtube.js.map +1 -0
  100. package/dist/utils/asterizk-auth.d.ts +43 -0
  101. package/dist/utils/asterizk-auth.d.ts.map +1 -0
  102. package/dist/utils/asterizk-auth.js +125 -0
  103. package/dist/utils/asterizk-auth.js.map +1 -0
  104. package/dist/web-server.d.ts.map +1 -1
  105. package/dist/web-server.js +132 -0
  106. package/dist/web-server.js.map +1 -1
  107. package/dist/workspace/index.d.ts +3 -4
  108. package/dist/workspace/index.d.ts.map +1 -1
  109. package/dist/workspace/index.js +3 -4
  110. package/dist/workspace/index.js.map +1 -1
  111. package/dist/workspace/templates.d.ts +8 -7
  112. package/dist/workspace/templates.d.ts.map +1 -1
  113. package/dist/workspace/templates.js +18 -127
  114. package/dist/workspace/templates.js.map +1 -1
  115. package/dist/workspace/workspace.d.ts +2 -4
  116. package/dist/workspace/workspace.d.ts.map +1 -1
  117. package/dist/workspace/workspace.js +7 -16
  118. package/dist/workspace/workspace.js.map +1 -1
  119. package/package.json +1 -1
  120. package/public/index.html +231 -0
  121. package/skills/docx/SKILL.md +468 -0
  122. package/skills/docx/scripts/__init__.py +1 -0
  123. package/skills/docx/scripts/accept_changes.py +181 -0
  124. package/skills/docx/scripts/comment.py +347 -0
  125. package/skills/docx/scripts/helpers/__init__.py +0 -0
  126. package/skills/docx/scripts/helpers/merge_runs.py +231 -0
  127. package/skills/docx/scripts/helpers/simplify_redlines.py +240 -0
  128. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  129. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  130. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  131. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  132. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  133. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  134. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  135. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  136. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  137. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  138. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  139. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  140. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  141. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  142. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  143. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  144. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  145. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  146. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  147. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  148. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  149. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  150. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  151. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  152. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  153. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  154. package/skills/docx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  155. package/skills/docx/scripts/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  156. package/skills/docx/scripts/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  157. package/skills/docx/scripts/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  158. package/skills/docx/scripts/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  159. package/skills/docx/scripts/ooxml/schemas/mce/mc.xsd +75 -0
  160. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  161. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  162. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  163. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  164. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  165. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  166. package/skills/docx/scripts/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  167. package/skills/docx/scripts/ooxml/scripts/pack.py +159 -0
  168. package/skills/docx/scripts/ooxml/scripts/unpack.py +29 -0
  169. package/skills/docx/scripts/ooxml/scripts/validate.py +106 -0
  170. package/skills/docx/scripts/ooxml/scripts/validation/__init__.py +15 -0
  171. package/skills/docx/scripts/ooxml/scripts/validation/base.py +1023 -0
  172. package/skills/docx/scripts/ooxml/scripts/validation/docx.py +519 -0
  173. package/skills/docx/scripts/ooxml/scripts/validation/pptx.py +315 -0
  174. package/skills/docx/scripts/ooxml/scripts/validation/redlining.py +284 -0
  175. package/skills/docx/scripts/pack.py +166 -0
  176. package/skills/docx/scripts/templates/comments.xml +3 -0
  177. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  178. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  179. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  180. package/skills/docx/scripts/templates/people.xml +3 -0
  181. package/skills/docx/scripts/unpack.py +134 -0
  182. package/skills/longform-video-generation/SKILL.md +298 -0
  183. package/skills/longform-video-generation/references/advanced_techniques.md +474 -0
  184. package/skills/longform-video-generation/references/google_api_guide.md +288 -0
  185. package/skills/longform-video-generation/scripts/video_generator.py +579 -0
  186. package/skills/pdf/FORMS.md +305 -0
  187. package/skills/pdf/REFERENCE.md +612 -0
  188. package/skills/pdf/SKILL.md +293 -0
  189. package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  190. package/skills/pdf/scripts/check_fillable_fields.py +12 -0
  191. package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  192. package/skills/pdf/scripts/create_validation_image.py +41 -0
  193. package/skills/pdf/scripts/extract_form_field_info.py +152 -0
  194. package/skills/pdf/scripts/extract_form_structure.py +124 -0
  195. package/skills/pdf/scripts/fill_fillable_fields.py +116 -0
  196. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +136 -0
  197. package/skills/pptx/SKILL.md +171 -0
  198. package/skills/pptx/editing.md +205 -0
  199. package/skills/pptx/pptxgenjs.md +377 -0
  200. package/skills/pptx/scripts/add_slide.py +225 -0
  201. package/skills/pptx/scripts/clean.py +309 -0
  202. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  203. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  204. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  205. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  206. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  207. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  208. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  209. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  210. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  211. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  212. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  213. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  214. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  215. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  216. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  217. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  218. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  219. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  220. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  221. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  222. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  223. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  224. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  225. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  226. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  227. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  228. package/skills/pptx/scripts/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  229. package/skills/pptx/scripts/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  230. package/skills/pptx/scripts/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  231. package/skills/pptx/scripts/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  232. package/skills/pptx/scripts/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  233. package/skills/pptx/scripts/ooxml/schemas/mce/mc.xsd +75 -0
  234. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  235. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  236. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  237. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  238. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  239. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  240. package/skills/pptx/scripts/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  241. package/skills/pptx/scripts/ooxml/scripts/pack.py +159 -0
  242. package/skills/pptx/scripts/ooxml/scripts/unpack.py +29 -0
  243. package/skills/pptx/scripts/ooxml/scripts/validate.py +106 -0
  244. package/skills/pptx/scripts/ooxml/scripts/validation/__init__.py +15 -0
  245. package/skills/pptx/scripts/ooxml/scripts/validation/base.py +1023 -0
  246. package/skills/pptx/scripts/ooxml/scripts/validation/docx.py +519 -0
  247. package/skills/pptx/scripts/ooxml/scripts/validation/pptx.py +315 -0
  248. package/skills/pptx/scripts/ooxml/scripts/validation/redlining.py +284 -0
  249. package/skills/pptx/scripts/pack.py +168 -0
  250. package/skills/pptx/scripts/thumbnail.py +318 -0
  251. package/skills/pptx/scripts/unpack.py +86 -0
  252. package/skills/xlsx/SKILL.md +291 -0
  253. package/skills/xlsx/recalc.py +247 -0
@@ -0,0 +1,215 @@
1
+ /**
2
+ * CoStar Server Executor - WhatsApp Tool
3
+ *
4
+ * Send and receive WhatsApp messages via Asterizk API.
5
+ * All operations go through POST /email/whatsapp/manage.
6
+ * Uses draft-then-send pattern: draft message → get draft_id → send draft.
7
+ *
8
+ * Operations: send_message, send_media, get_messages, get_messages_by_contact,
9
+ * get_groups, get_contacts
10
+ */
11
+ import { Type } from "@sinclair/typebox";
12
+ import { jsonResult, readStringParam, readNumberParam, readBooleanParam } from "../utils/tool-helpers.js";
13
+ import { asterizkFetch, handleAsterizkApiError } from "../utils/asterizk-auth.js";
14
+ const WhatsAppSchema = Type.Object({
15
+ operation: Type.Union([
16
+ Type.Literal("send_message"),
17
+ Type.Literal("send_media"),
18
+ Type.Literal("get_messages"),
19
+ Type.Literal("get_messages_by_contact"),
20
+ Type.Literal("get_groups"),
21
+ Type.Literal("get_contacts"),
22
+ ], {
23
+ description: "Operation: send_message (text), send_media (image/video/doc), get_messages (recent inbox), get_messages_by_contact (chat history), get_groups (list groups), get_contacts (list contacts)",
24
+ }),
25
+ phone_number: Type.Optional(Type.String({
26
+ description: "Recipient phone number (digits only or with +). Required for send_message, send_media.",
27
+ })),
28
+ message: Type.Optional(Type.String({ description: "Text message to send. Required for send_message." })),
29
+ group_jid: Type.Optional(Type.String({
30
+ description: "WhatsApp group JID to send to (instead of phone_number). Optional for send_message, send_media.",
31
+ })),
32
+ media_url: Type.Optional(Type.String({ description: "URL of media file to send. Required for send_media." })),
33
+ media_type: Type.Optional(Type.Union([
34
+ Type.Literal("image"),
35
+ Type.Literal("video"),
36
+ Type.Literal("audio"),
37
+ Type.Literal("document"),
38
+ ], { description: "Type of media. Required for send_media." })),
39
+ caption: Type.Optional(Type.String({ description: "Caption for media message. Optional for send_media." })),
40
+ contact_jid: Type.Optional(Type.String({
41
+ description: "WhatsApp JID of contact (e.g., 1234567890@s.whatsapp.net). Required for get_messages_by_contact.",
42
+ })),
43
+ limit: Type.Optional(Type.Number({ description: "Number of messages to retrieve. Default: 50." })),
44
+ unread_only: Type.Optional(Type.Boolean({ description: "Only return unread messages. Default: false." })),
45
+ from_datetime: Type.Optional(Type.String({ description: "Filter messages from this datetime (ISO 8601). Optional." })),
46
+ });
47
+ /**
48
+ * Get the WhatsApp device ID from environment
49
+ */
50
+ function getDeviceId() {
51
+ const deviceId = process.env.WHATSAPP_DEVICE_ID;
52
+ if (!deviceId) {
53
+ throw new Error("WHATSAPP_DEVICE_ID environment variable is required for WhatsApp operations");
54
+ }
55
+ return deviceId;
56
+ }
57
+ /**
58
+ * WhatsApp manage endpoint call
59
+ */
60
+ async function whatsappManage(body) {
61
+ const response = await asterizkFetch("/email/whatsapp/manage", { body });
62
+ if (!response.ok) {
63
+ const errText = await response.text();
64
+ throw new Error(`WhatsApp API error (${response.status}): ${errText}`);
65
+ }
66
+ return response.json();
67
+ }
68
+ /**
69
+ * Draft a message, then immediately send it.
70
+ * Returns the combined result.
71
+ */
72
+ async function draftAndSend(draftBody) {
73
+ // Step 1: Draft
74
+ const draftResult = await whatsappManage(draftBody);
75
+ const draftId = draftResult.draft_id;
76
+ if (!draftId) {
77
+ // Some API versions auto-send — return whatever we got
78
+ return draftResult;
79
+ }
80
+ // Step 2: Send the draft
81
+ const sendResult = await whatsappManage({
82
+ operation: "send_whatsapp_draft",
83
+ device_id: getDeviceId(),
84
+ draft_id: draftId,
85
+ });
86
+ return { draft_id: draftId, draft: draftResult, send: sendResult };
87
+ }
88
+ export function createWhatsAppTool() {
89
+ return {
90
+ name: "whatsapp",
91
+ label: "WhatsApp",
92
+ description: "Send and receive WhatsApp messages. Operations: send_message (text to a contact or group), send_media (image/video/audio/document), get_messages (recent inbox), get_messages_by_contact (chat with specific person), get_groups (list groups), get_contacts (list WhatsApp contacts). Always search contacts first to get the correct phone number or JID.",
93
+ parameters: WhatsAppSchema,
94
+ execute: async (_toolCallId, params) => {
95
+ const operation = readStringParam(params, "operation", { required: true });
96
+ try {
97
+ const deviceId = getDeviceId();
98
+ switch (operation) {
99
+ case "send_message": {
100
+ const phoneNumber = readStringParam(params, "phone_number");
101
+ const groupJid = readStringParam(params, "group_jid");
102
+ const message = readStringParam(params, "message", { required: true });
103
+ if (!phoneNumber && !groupJid) {
104
+ return jsonResult({
105
+ error: "missing_recipient",
106
+ message: "Provide either phone_number or group_jid",
107
+ });
108
+ }
109
+ console.log(`[WHATSAPP] Sending message to ${phoneNumber || groupJid}`);
110
+ const result = await draftAndSend({
111
+ operation: "draft_whatsapp_message",
112
+ device_id: deviceId,
113
+ to: phoneNumber || "",
114
+ message,
115
+ group_jid: groupJid || null,
116
+ });
117
+ return jsonResult({
118
+ status: "sent",
119
+ to: phoneNumber || groupJid,
120
+ message_preview: message.slice(0, 100),
121
+ ...result,
122
+ });
123
+ }
124
+ case "send_media": {
125
+ const phoneNumber = readStringParam(params, "phone_number");
126
+ const groupJid = readStringParam(params, "group_jid");
127
+ const mediaUrl = readStringParam(params, "media_url", { required: true });
128
+ const mediaType = readStringParam(params, "media_type", { required: true });
129
+ const caption = readStringParam(params, "caption") || "";
130
+ if (!phoneNumber && !groupJid) {
131
+ return jsonResult({
132
+ error: "missing_recipient",
133
+ message: "Provide either phone_number or group_jid",
134
+ });
135
+ }
136
+ console.log(`[WHATSAPP] Sending ${mediaType} to ${phoneNumber || groupJid}`);
137
+ const result = await draftAndSend({
138
+ operation: "draft_whatsapp_message_with_media",
139
+ device_id: deviceId,
140
+ to: phoneNumber || "",
141
+ group_jid: groupJid || null,
142
+ media_type: mediaType,
143
+ file_url: mediaUrl,
144
+ caption,
145
+ });
146
+ return jsonResult({
147
+ status: "sent",
148
+ to: phoneNumber || groupJid,
149
+ media_type: mediaType,
150
+ ...result,
151
+ });
152
+ }
153
+ case "get_messages": {
154
+ const limit = readNumberParam(params, "limit") || 50;
155
+ const unreadOnly = readBooleanParam(params, "unread_only", false);
156
+ const fromDatetime = readStringParam(params, "from_datetime");
157
+ console.log(`[WHATSAPP] Getting messages (limit: ${limit}, unread: ${unreadOnly})`);
158
+ const data = await whatsappManage({
159
+ operation: "retrieve_messages",
160
+ device_id: deviceId,
161
+ limit,
162
+ skip: 0,
163
+ unread_only: unreadOnly,
164
+ from_datetime: fromDatetime || null,
165
+ to_datetime: null,
166
+ });
167
+ return jsonResult(data);
168
+ }
169
+ case "get_messages_by_contact": {
170
+ const contactJid = readStringParam(params, "contact_jid", { required: true });
171
+ const limit = readNumberParam(params, "limit") || 50;
172
+ const fromDatetime = readStringParam(params, "from_datetime");
173
+ console.log(`[WHATSAPP] Getting messages for contact ${contactJid} (limit: ${limit})`);
174
+ const data = await whatsappManage({
175
+ operation: "retrieve_msgs_by_contact",
176
+ device_id: deviceId,
177
+ remote_jid: contactJid,
178
+ limit,
179
+ skip: 0,
180
+ from_datetime: fromDatetime || null,
181
+ to_datetime: null,
182
+ });
183
+ return jsonResult(data);
184
+ }
185
+ case "get_groups": {
186
+ console.log(`[WHATSAPP] Getting groups`);
187
+ const data = await whatsappManage({
188
+ operation: "get_groups",
189
+ device_id: deviceId,
190
+ });
191
+ return jsonResult(data);
192
+ }
193
+ case "get_contacts": {
194
+ console.log(`[WHATSAPP] Getting contacts`);
195
+ const data = await whatsappManage({
196
+ operation: "retrieve_contacts",
197
+ device_id: deviceId,
198
+ });
199
+ return jsonResult(data);
200
+ }
201
+ default:
202
+ return jsonResult({
203
+ error: "invalid_operation",
204
+ message: `Unknown operation: ${operation}. Use: send_message, send_media, get_messages, get_messages_by_contact, get_groups, get_contacts`,
205
+ });
206
+ }
207
+ }
208
+ catch (error) {
209
+ console.error(`[WHATSAPP] Error (${operation}):`, error);
210
+ return jsonResult(handleAsterizkApiError(error, operation));
211
+ }
212
+ },
213
+ };
214
+ }
215
+ //# sourceMappingURL=whatsapp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/tools/whatsapp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * CoStar Server Executor - YouTube Tool
3
+ *
4
+ * Search YouTube videos, get details, and fetch transcripts.
5
+ * Uses YouTube Data API v3 for search/details.
6
+ * Uses youtube_transcript_api Python package for transcripts (installed on server).
7
+ *
8
+ * Requires: YOUTUBE_API_KEY env var.
9
+ */
10
+ import type { AnyAgentTool } from "../types/tool.js";
11
+ export declare function createYouTubeTool(): AnyAgentTool;
12
+ //# sourceMappingURL=youtube.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"youtube.d.ts","sourceRoot":"","sources":["../../src/tools/youtube.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA+ErD,wBAAgB,iBAAiB,IAAI,YAAY,CAyKhD"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * CoStar Server Executor - YouTube Tool
3
+ *
4
+ * Search YouTube videos, get details, and fetch transcripts.
5
+ * Uses YouTube Data API v3 for search/details.
6
+ * Uses youtube_transcript_api Python package for transcripts (installed on server).
7
+ *
8
+ * Requires: YOUTUBE_API_KEY env var.
9
+ */
10
+ import { Type } from "@sinclair/typebox";
11
+ import { execSync } from "child_process";
12
+ import { jsonResult, readStringParam, readNumberParam } from "../utils/tool-helpers.js";
13
+ const YouTubeSchema = Type.Object({
14
+ operation: Type.Union([
15
+ Type.Literal("search"),
16
+ Type.Literal("get_video"),
17
+ Type.Literal("get_transcript"),
18
+ ], {
19
+ description: "Operation: search (find videos), get_video (video details — views, likes, description), get_transcript (fetch video transcript/subtitles)",
20
+ }),
21
+ query: Type.Optional(Type.String({ description: "Search query. Required for search." })),
22
+ video_id: Type.Optional(Type.String({
23
+ description: "YouTube video ID (the part after v= in the URL). Required for get_video and get_transcript.",
24
+ })),
25
+ limit: Type.Optional(Type.Number({ description: "Number of search results. Default: 10. Max: 50. Used with search." })),
26
+ language: Type.Optional(Type.String({ description: "Transcript language code (e.g., 'en', 'es'). Default: 'en'. Used with get_transcript." })),
27
+ });
28
+ function getApiKey() {
29
+ const key = process.env.YOUTUBE_API_KEY;
30
+ if (!key) {
31
+ throw new Error("YOUTUBE_API_KEY environment variable is required");
32
+ }
33
+ return key;
34
+ }
35
+ /**
36
+ * Call YouTube Data API v3
37
+ */
38
+ async function youtubeApi(path, params) {
39
+ const apiKey = getApiKey();
40
+ const queryParams = new URLSearchParams({ ...params, key: apiKey });
41
+ const response = await fetch(`https://www.googleapis.com/youtube/v3${path}?${queryParams.toString()}`);
42
+ if (!response.ok) {
43
+ const errText = await response.text();
44
+ throw new Error(`YouTube API error (${response.status}): ${errText}`);
45
+ }
46
+ return response.json();
47
+ }
48
+ /**
49
+ * Format ISO 8601 duration (PT1H2M3S) to human readable
50
+ */
51
+ function formatDuration(iso) {
52
+ const match = iso.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);
53
+ if (!match)
54
+ return iso;
55
+ const h = match[1] ? `${match[1]}h ` : "";
56
+ const m = match[2] ? `${match[2]}m ` : "";
57
+ const s = match[3] ? `${match[3]}s` : "";
58
+ return (h + m + s).trim() || "0s";
59
+ }
60
+ /**
61
+ * Format large numbers (1234567 → 1.2M)
62
+ */
63
+ function formatCount(n) {
64
+ if (n >= 1_000_000)
65
+ return `${(n / 1_000_000).toFixed(1)}M`;
66
+ if (n >= 1_000)
67
+ return `${(n / 1_000).toFixed(1)}K`;
68
+ return String(n);
69
+ }
70
+ export function createYouTubeTool() {
71
+ return {
72
+ name: "youtube",
73
+ label: "YouTube",
74
+ description: "Search YouTube videos, get video details (views, likes, description), and fetch transcripts/subtitles. Use for finding videos, summarizing video content, or researching topics via video. Requires YOUTUBE_API_KEY env var.",
75
+ parameters: YouTubeSchema,
76
+ execute: async (_toolCallId, params) => {
77
+ const operation = readStringParam(params, "operation", { required: true });
78
+ try {
79
+ switch (operation) {
80
+ case "search": {
81
+ const query = readStringParam(params, "query", { required: true });
82
+ const limit = readNumberParam(params, "limit") || 10;
83
+ console.log(`[YOUTUBE] Searching: "${query}" (limit: ${limit})`);
84
+ const data = await youtubeApi("/search", {
85
+ part: "snippet",
86
+ q: query,
87
+ type: "video",
88
+ maxResults: String(limit),
89
+ order: "relevance",
90
+ });
91
+ const items = (data.items || []);
92
+ const results = items.map((item) => {
93
+ const snippet = item.snippet;
94
+ const id = item.id;
95
+ return {
96
+ video_id: id?.videoId,
97
+ title: snippet?.title,
98
+ channel: snippet?.channelTitle,
99
+ description: (snippet?.description || "").slice(0, 200),
100
+ published_at: snippet?.publishedAt,
101
+ url: `https://www.youtube.com/watch?v=${id?.videoId}`,
102
+ };
103
+ });
104
+ return jsonResult({ query, count: results.length, results });
105
+ }
106
+ case "get_video": {
107
+ const videoId = readStringParam(params, "video_id", { required: true });
108
+ console.log(`[YOUTUBE] Getting video details: ${videoId}`);
109
+ const data = await youtubeApi("/videos", {
110
+ part: "snippet,statistics,contentDetails",
111
+ id: videoId,
112
+ });
113
+ const items = (data.items || []);
114
+ if (items.length === 0) {
115
+ return jsonResult({ error: "not_found", message: `Video ${videoId} not found` });
116
+ }
117
+ const item = items[0];
118
+ const snippet = item.snippet;
119
+ const stats = item.statistics;
120
+ const details = item.contentDetails;
121
+ return jsonResult({
122
+ video_id: videoId,
123
+ title: snippet?.title,
124
+ channel: snippet?.channelTitle,
125
+ description: snippet?.description,
126
+ published_at: snippet?.publishedAt,
127
+ duration: formatDuration(details?.duration || ""),
128
+ views: formatCount(Number(stats?.viewCount) || 0),
129
+ likes: formatCount(Number(stats?.likeCount) || 0),
130
+ comments: formatCount(Number(stats?.commentCount) || 0),
131
+ tags: (snippet?.tags || []).slice(0, 10),
132
+ url: `https://www.youtube.com/watch?v=${videoId}`,
133
+ });
134
+ }
135
+ case "get_transcript": {
136
+ const videoId = readStringParam(params, "video_id", { required: true });
137
+ const language = readStringParam(params, "language") || "en";
138
+ console.log(`[YOUTUBE] Getting transcript: ${videoId} (lang: ${language})`);
139
+ try {
140
+ // Use youtube_transcript_api Python package via shell
141
+ const cmd = `python3 -c "
142
+ import json
143
+ from youtube_transcript_api import YouTubeTranscriptApi
144
+ try:
145
+ transcript = YouTubeTranscriptApi.get_transcript('${videoId}', languages=['${language}', 'en'])
146
+ print(json.dumps(transcript))
147
+ except Exception as e:
148
+ print(json.dumps({'error': str(e)}))
149
+ "`;
150
+ const output = execSync(cmd, {
151
+ encoding: "utf-8",
152
+ timeout: 30_000,
153
+ }).trim();
154
+ const parsed = JSON.parse(output);
155
+ if (parsed.error) {
156
+ return jsonResult({
157
+ video_id: videoId,
158
+ error: "transcript_unavailable",
159
+ message: parsed.error,
160
+ });
161
+ }
162
+ // Combine transcript segments into readable text
163
+ const segments = parsed;
164
+ const fullText = segments.map((s) => s.text).join(" ");
165
+ // Also include timestamped segments (first 100 for context window)
166
+ const timestamped = segments.slice(0, 100).map((s) => {
167
+ const mins = Math.floor(s.start / 60);
168
+ const secs = Math.floor(s.start % 60);
169
+ return `[${mins}:${secs.toString().padStart(2, "0")}] ${s.text}`;
170
+ });
171
+ return jsonResult({
172
+ video_id: videoId,
173
+ language,
174
+ segment_count: segments.length,
175
+ full_text: fullText,
176
+ timestamped: timestamped,
177
+ url: `https://www.youtube.com/watch?v=${videoId}`,
178
+ });
179
+ }
180
+ catch (execError) {
181
+ const msg = execError instanceof Error ? execError.message : String(execError);
182
+ // Fallback: python package might not be installed
183
+ if (msg.includes("ModuleNotFoundError") || msg.includes("No module")) {
184
+ return jsonResult({
185
+ video_id: videoId,
186
+ error: "transcript_unavailable",
187
+ message: "youtube_transcript_api package not installed. Install with: pip install youtube_transcript_api",
188
+ });
189
+ }
190
+ return jsonResult({
191
+ video_id: videoId,
192
+ error: "transcript_failed",
193
+ message: msg,
194
+ });
195
+ }
196
+ }
197
+ default:
198
+ return jsonResult({
199
+ error: "invalid_operation",
200
+ message: `Unknown operation: ${operation}. Use: search, get_video, get_transcript`,
201
+ });
202
+ }
203
+ }
204
+ catch (error) {
205
+ console.error(`[YOUTUBE] Error (${operation}):`, error);
206
+ const msg = error instanceof Error ? error.message : String(error);
207
+ if (msg.includes("YOUTUBE_API_KEY")) {
208
+ return jsonResult({
209
+ error: "not_configured",
210
+ message: "YouTube is not configured. YOUTUBE_API_KEY is required.",
211
+ });
212
+ }
213
+ return jsonResult({ error: `${operation}_failed`, message: msg });
214
+ }
215
+ },
216
+ };
217
+ }
218
+ //# sourceMappingURL=youtube.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"youtube.js","sourceRoot":"","sources":["../../src/tools/youtube.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * CoStar Server Executor - Asterizk API Auth Utility
3
+ *
4
+ * Shared utility for authenticating with the Asterizk API (api-dev.asterizk.ai).
5
+ * Used by phone call, WhatsApp, and contacts tools.
6
+ *
7
+ * Flow:
8
+ * 1. Get USER_ID from env
9
+ * 2. Fetch JWT from /email/auth/tokens/{userId} (same endpoint as google-oauth.ts)
10
+ * 3. Use JWT as X-Samantha-JWT header for all Asterizk API calls
11
+ */
12
+ /**
13
+ * Get user ID from environment variable
14
+ */
15
+ export declare function getUserId(): string;
16
+ /**
17
+ * Get user email from environment variable
18
+ */
19
+ export declare function getUserEmail(): string;
20
+ /**
21
+ * Get the Asterizk API base URL
22
+ */
23
+ export declare function getAsterizkApiUrl(): string;
24
+ /**
25
+ * Get authenticated headers for Asterizk API calls
26
+ */
27
+ export declare function getAsterizkHeaders(): Promise<Record<string, string>>;
28
+ /**
29
+ * Make an authenticated fetch to the Asterizk API
30
+ */
31
+ export declare function asterizkFetch(path: string, options?: {
32
+ method?: string;
33
+ body?: unknown;
34
+ timeoutMs?: number;
35
+ }): Promise<Response>;
36
+ /**
37
+ * Handle Asterizk API errors with user-friendly messages
38
+ */
39
+ export declare function handleAsterizkApiError(error: unknown, operation: string): {
40
+ error: string;
41
+ message: string;
42
+ };
43
+ //# sourceMappingURL=asterizk-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asterizk-auth.d.ts","sourceRoot":"","sources":["../../src/utils/asterizk-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAgCD;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQ1E;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,QAAQ,CAAC,CAoBnB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAmCpC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * CoStar Server Executor - Asterizk API Auth Utility
3
+ *
4
+ * Shared utility for authenticating with the Asterizk API (api-dev.asterizk.ai).
5
+ * Used by phone call, WhatsApp, and contacts tools.
6
+ *
7
+ * Flow:
8
+ * 1. Get USER_ID from env
9
+ * 2. Fetch JWT from /email/auth/tokens/{userId} (same endpoint as google-oauth.ts)
10
+ * 3. Use JWT as X-Samantha-JWT header for all Asterizk API calls
11
+ */
12
+ /**
13
+ * Get user ID from environment variable
14
+ */
15
+ export function getUserId() {
16
+ return process.env.USER_ID || "default";
17
+ }
18
+ /**
19
+ * Get user email from environment variable
20
+ */
21
+ export function getUserEmail() {
22
+ const email = process.env.USER_EMAIL;
23
+ if (!email) {
24
+ throw new Error("USER_EMAIL environment variable is required");
25
+ }
26
+ return email;
27
+ }
28
+ /**
29
+ * Get the Asterizk API base URL
30
+ */
31
+ export function getAsterizkApiUrl() {
32
+ return process.env.ASTERIZK_API_URL || "https://api-dev.asterizk.ai";
33
+ }
34
+ /**
35
+ * Fetch Samantha JWT for a user.
36
+ * Uses the same /email/auth/tokens/{userId} endpoint as google-oauth.ts.
37
+ * The access_token in the response IS the Samantha JWT.
38
+ */
39
+ async function getSamanthaJwt(userId) {
40
+ const apiUrl = getAsterizkApiUrl();
41
+ const response = await fetch(`${apiUrl}/email/auth/tokens/${userId}`, {
42
+ method: "GET",
43
+ headers: { "Content-Type": "application/json" },
44
+ });
45
+ if (!response.ok) {
46
+ if (response.status === 404) {
47
+ throw new Error(`No auth tokens found for user ${userId}. Please login in the app.`);
48
+ }
49
+ throw new Error(`Failed to fetch auth tokens: ${response.status} ${response.statusText}`);
50
+ }
51
+ const data = await response.json();
52
+ const jwt = data.access_token || data.google_access_token;
53
+ if (!jwt) {
54
+ throw new Error(`No access token in auth response for user ${userId}`);
55
+ }
56
+ return jwt;
57
+ }
58
+ /**
59
+ * Get authenticated headers for Asterizk API calls
60
+ */
61
+ export async function getAsterizkHeaders() {
62
+ const userId = getUserId();
63
+ const jwt = await getSamanthaJwt(userId);
64
+ return {
65
+ "Content-Type": "application/json",
66
+ "X-Samantha-JWT": jwt,
67
+ };
68
+ }
69
+ /**
70
+ * Make an authenticated fetch to the Asterizk API
71
+ */
72
+ export async function asterizkFetch(path, options = {}) {
73
+ const apiUrl = getAsterizkApiUrl();
74
+ const headers = await getAsterizkHeaders();
75
+ const timeoutMs = options.timeoutMs ?? 30_000;
76
+ const controller = new AbortController();
77
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
78
+ try {
79
+ const response = await fetch(`${apiUrl}${path}`, {
80
+ method: options.method || "POST",
81
+ headers,
82
+ body: options.body ? JSON.stringify(options.body) : undefined,
83
+ signal: controller.signal,
84
+ });
85
+ return response;
86
+ }
87
+ finally {
88
+ clearTimeout(timer);
89
+ }
90
+ }
91
+ /**
92
+ * Handle Asterizk API errors with user-friendly messages
93
+ */
94
+ export function handleAsterizkApiError(error, operation) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ if (message.includes("abort") || message.includes("timeout")) {
97
+ return {
98
+ error: "timeout",
99
+ message: `Request timed out while ${operation}. The server may be slow — please try again.`,
100
+ };
101
+ }
102
+ if (message.includes("No auth tokens") || message.includes("401")) {
103
+ return {
104
+ error: "not_authenticated",
105
+ message: "Authentication expired. Please re-login in the app.",
106
+ };
107
+ }
108
+ if (message.includes("404")) {
109
+ return {
110
+ error: "not_found",
111
+ message: `Resource not found while ${operation}.`,
112
+ };
113
+ }
114
+ if (message.includes("ECONNREFUSED") || message.includes("fetch failed")) {
115
+ return {
116
+ error: "connection_failed",
117
+ message: "Cannot reach the API server. It may be temporarily unavailable.",
118
+ };
119
+ }
120
+ return {
121
+ error: `${operation}_failed`,
122
+ message,
123
+ };
124
+ }
125
+ //# sourceMappingURL=asterizk-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asterizk-auth.js","sourceRoot":"","sources":["../../src/utils/asterizk-auth.ts"],"names":[],"mappings":"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"}