@codeany/open-agent-sdk 0.2.0 → 0.2.1

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 (231) hide show
  1. package/dist/agent.d.ts +113 -0
  2. package/dist/agent.d.ts.map +1 -0
  3. package/dist/agent.js +446 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/engine.d.ts +62 -0
  6. package/dist/engine.d.ts.map +1 -0
  7. package/dist/engine.js +494 -0
  8. package/dist/engine.js.map +1 -0
  9. package/dist/hooks.d.ts +111 -0
  10. package/dist/hooks.d.ts.map +1 -0
  11. package/dist/hooks.js +179 -0
  12. package/dist/hooks.js.map +1 -0
  13. package/dist/index.d.ts +66 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +133 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/mcp/client.d.ts +19 -0
  18. package/dist/mcp/client.d.ts.map +1 -0
  19. package/dist/mcp/client.js +126 -0
  20. package/dist/mcp/client.js.map +1 -0
  21. package/dist/providers/anthropic.d.ts +17 -0
  22. package/dist/providers/anthropic.d.ts.map +1 -0
  23. package/dist/providers/anthropic.js +47 -0
  24. package/dist/providers/anthropic.js.map +1 -0
  25. package/dist/providers/index.d.ts +20 -0
  26. package/dist/providers/index.d.ts.map +1 -0
  27. package/dist/providers/index.js +26 -0
  28. package/dist/providers/index.js.map +1 -0
  29. package/dist/providers/openai.d.ts +26 -0
  30. package/dist/providers/openai.d.ts.map +1 -0
  31. package/dist/providers/openai.js +212 -0
  32. package/dist/providers/openai.js.map +1 -0
  33. package/dist/providers/types.d.ts +84 -0
  34. package/dist/providers/types.d.ts.map +1 -0
  35. package/dist/providers/types.js +11 -0
  36. package/dist/providers/types.js.map +1 -0
  37. package/dist/sdk-mcp-server.d.ts +52 -0
  38. package/dist/sdk-mcp-server.d.ts.map +1 -0
  39. package/dist/sdk-mcp-server.js +57 -0
  40. package/dist/sdk-mcp-server.js.map +1 -0
  41. package/dist/session.d.ts +73 -0
  42. package/dist/session.d.ts.map +1 -0
  43. package/dist/session.js +159 -0
  44. package/dist/session.js.map +1 -0
  45. package/dist/skills/bundled/commit.d.ts +7 -0
  46. package/dist/skills/bundled/commit.d.ts.map +1 -0
  47. package/dist/skills/bundled/commit.js +35 -0
  48. package/dist/skills/bundled/commit.js.map +1 -0
  49. package/dist/skills/bundled/debug.d.ts +7 -0
  50. package/dist/skills/bundled/debug.d.ts.map +1 -0
  51. package/dist/skills/bundled/debug.js +46 -0
  52. package/dist/skills/bundled/debug.js.map +1 -0
  53. package/dist/skills/bundled/index.d.ts +11 -0
  54. package/dist/skills/bundled/index.d.ts.map +1 -0
  55. package/dist/skills/bundled/index.js +26 -0
  56. package/dist/skills/bundled/index.js.map +1 -0
  57. package/dist/skills/bundled/review.d.ts +7 -0
  58. package/dist/skills/bundled/review.d.ts.map +1 -0
  59. package/dist/skills/bundled/review.js +38 -0
  60. package/dist/skills/bundled/review.js.map +1 -0
  61. package/dist/skills/bundled/simplify.d.ts +8 -0
  62. package/dist/skills/bundled/simplify.d.ts.map +1 -0
  63. package/dist/skills/bundled/simplify.js +48 -0
  64. package/dist/skills/bundled/simplify.js.map +1 -0
  65. package/dist/skills/bundled/test.d.ts +7 -0
  66. package/dist/skills/bundled/test.d.ts.map +1 -0
  67. package/dist/skills/bundled/test.js +40 -0
  68. package/dist/skills/bundled/test.js.map +1 -0
  69. package/dist/skills/index.d.ts +7 -0
  70. package/dist/skills/index.d.ts.map +1 -0
  71. package/dist/skills/index.js +8 -0
  72. package/dist/skills/index.js.map +1 -0
  73. package/dist/skills/registry.d.ts +43 -0
  74. package/dist/skills/registry.d.ts.map +1 -0
  75. package/dist/skills/registry.js +111 -0
  76. package/dist/skills/registry.js.map +1 -0
  77. package/dist/skills/types.d.ts +83 -0
  78. package/dist/skills/types.d.ts.map +1 -0
  79. package/dist/skills/types.js +8 -0
  80. package/dist/skills/types.js.map +1 -0
  81. package/dist/tool-helper.d.ts +73 -0
  82. package/dist/tool-helper.d.ts.map +1 -0
  83. package/dist/tool-helper.js +86 -0
  84. package/dist/tool-helper.js.map +1 -0
  85. package/dist/tools/agent-tool.d.ts +17 -0
  86. package/dist/tools/agent-tool.d.ts.map +1 -0
  87. package/dist/tools/agent-tool.js +146 -0
  88. package/dist/tools/agent-tool.js.map +1 -0
  89. package/dist/tools/ask-user.d.ts +18 -0
  90. package/dist/tools/ask-user.d.ts.map +1 -0
  91. package/dist/tools/ask-user.js +72 -0
  92. package/dist/tools/ask-user.js.map +1 -0
  93. package/dist/tools/bash.d.ts +5 -0
  94. package/dist/tools/bash.d.ts.map +1 -0
  95. package/dist/tools/bash.js +67 -0
  96. package/dist/tools/bash.js.map +1 -0
  97. package/dist/tools/config-tool.d.ts +20 -0
  98. package/dist/tools/config-tool.d.ts.map +1 -0
  99. package/dist/tools/config-tool.js +83 -0
  100. package/dist/tools/config-tool.js.map +1 -0
  101. package/dist/tools/cron-tools.d.ts +33 -0
  102. package/dist/tools/cron-tools.d.ts.map +1 -0
  103. package/dist/tools/cron-tools.js +128 -0
  104. package/dist/tools/cron-tools.js.map +1 -0
  105. package/dist/tools/edit.d.ts +5 -0
  106. package/dist/tools/edit.d.ts.map +1 -0
  107. package/dist/tools/edit.js +70 -0
  108. package/dist/tools/edit.js.map +1 -0
  109. package/dist/tools/glob.d.ts +5 -0
  110. package/dist/tools/glob.d.ts.map +1 -0
  111. package/dist/tools/glob.js +75 -0
  112. package/dist/tools/glob.js.map +1 -0
  113. package/dist/tools/grep.d.ts +5 -0
  114. package/dist/tools/grep.d.ts.map +1 -0
  115. package/dist/tools/grep.js +168 -0
  116. package/dist/tools/grep.js.map +1 -0
  117. package/dist/tools/index.d.ts +45 -0
  118. package/dist/tools/index.d.ts.map +1 -0
  119. package/dist/tools/index.js +162 -0
  120. package/dist/tools/index.js.map +1 -0
  121. package/dist/tools/lsp-tool.d.ts +9 -0
  122. package/dist/tools/lsp-tool.d.ts.map +1 -0
  123. package/dist/tools/lsp-tool.js +137 -0
  124. package/dist/tools/lsp-tool.js.map +1 -0
  125. package/dist/tools/mcp-resource-tools.d.ts +14 -0
  126. package/dist/tools/mcp-resource-tools.d.ts.map +1 -0
  127. package/dist/tools/mcp-resource-tools.js +117 -0
  128. package/dist/tools/mcp-resource-tools.js.map +1 -0
  129. package/dist/tools/notebook-edit.d.ts +5 -0
  130. package/dist/tools/notebook-edit.d.ts.map +1 -0
  131. package/dist/tools/notebook-edit.js +85 -0
  132. package/dist/tools/notebook-edit.js.map +1 -0
  133. package/dist/tools/plan-tools.d.ts +12 -0
  134. package/dist/tools/plan-tools.d.ts.map +1 -0
  135. package/dist/tools/plan-tools.js +77 -0
  136. package/dist/tools/plan-tools.js.map +1 -0
  137. package/dist/tools/read.d.ts +5 -0
  138. package/dist/tools/read.d.ts.map +1 -0
  139. package/dist/tools/read.js +66 -0
  140. package/dist/tools/read.js.map +1 -0
  141. package/dist/tools/send-message.d.ts +31 -0
  142. package/dist/tools/send-message.d.ts.map +1 -0
  143. package/dist/tools/send-message.js +77 -0
  144. package/dist/tools/send-message.js.map +1 -0
  145. package/dist/tools/skill-tool.d.ts +9 -0
  146. package/dist/tools/skill-tool.d.ts.map +1 -0
  147. package/dist/tools/skill-tool.js +115 -0
  148. package/dist/tools/skill-tool.js.map +1 -0
  149. package/dist/tools/task-tools.d.ts +48 -0
  150. package/dist/tools/task-tools.d.ts.map +1 -0
  151. package/dist/tools/task-tools.js +242 -0
  152. package/dist/tools/task-tools.js.map +1 -0
  153. package/dist/tools/team-tools.d.ts +34 -0
  154. package/dist/tools/team-tools.d.ts.map +1 -0
  155. package/dist/tools/team-tools.js +103 -0
  156. package/dist/tools/team-tools.js.map +1 -0
  157. package/dist/tools/todo-tool.d.ts +22 -0
  158. package/dist/tools/todo-tool.d.ts.map +1 -0
  159. package/dist/tools/todo-tool.js +93 -0
  160. package/dist/tools/todo-tool.js.map +1 -0
  161. package/dist/tools/tool-search.d.ts +13 -0
  162. package/dist/tools/tool-search.d.ts.map +1 -0
  163. package/dist/tools/tool-search.js +76 -0
  164. package/dist/tools/tool-search.js.map +1 -0
  165. package/dist/tools/types.d.ts +29 -0
  166. package/dist/tools/types.d.ts.map +1 -0
  167. package/dist/tools/types.js +52 -0
  168. package/dist/tools/types.js.map +1 -0
  169. package/dist/tools/web-fetch.d.ts +5 -0
  170. package/dist/tools/web-fetch.d.ts.map +1 -0
  171. package/dist/tools/web-fetch.js +60 -0
  172. package/dist/tools/web-fetch.js.map +1 -0
  173. package/dist/tools/web-search.d.ts +5 -0
  174. package/dist/tools/web-search.d.ts.map +1 -0
  175. package/dist/tools/web-search.js +77 -0
  176. package/dist/tools/web-search.js.map +1 -0
  177. package/dist/tools/worktree-tools.d.ts +10 -0
  178. package/dist/tools/worktree-tools.d.ts.map +1 -0
  179. package/dist/tools/worktree-tools.js +130 -0
  180. package/dist/tools/worktree-tools.js.map +1 -0
  181. package/dist/tools/write.d.ts +5 -0
  182. package/dist/tools/write.d.ts.map +1 -0
  183. package/dist/tools/write.js +40 -0
  184. package/dist/tools/write.js.map +1 -0
  185. package/dist/types.d.ts +423 -0
  186. package/dist/types.d.ts.map +1 -0
  187. package/dist/types.js +5 -0
  188. package/dist/types.js.map +1 -0
  189. package/dist/utils/compact.d.ts +44 -0
  190. package/dist/utils/compact.d.ts.map +1 -0
  191. package/dist/utils/compact.js +162 -0
  192. package/dist/utils/compact.js.map +1 -0
  193. package/dist/utils/context.d.ts +35 -0
  194. package/dist/utils/context.d.ts.map +1 -0
  195. package/dist/utils/context.js +174 -0
  196. package/dist/utils/context.js.map +1 -0
  197. package/dist/utils/fileCache.d.ts +64 -0
  198. package/dist/utils/fileCache.d.ts.map +1 -0
  199. package/dist/utils/fileCache.js +117 -0
  200. package/dist/utils/fileCache.js.map +1 -0
  201. package/dist/utils/messages.d.ts +57 -0
  202. package/dist/utils/messages.d.ts.map +1 -0
  203. package/dist/utils/messages.js +152 -0
  204. package/dist/utils/messages.js.map +1 -0
  205. package/dist/utils/retry.d.ts +48 -0
  206. package/dist/utils/retry.d.ts.map +1 -0
  207. package/dist/utils/retry.js +111 -0
  208. package/dist/utils/retry.js.map +1 -0
  209. package/dist/utils/tokens.d.ts +57 -0
  210. package/dist/utils/tokens.d.ts.map +1 -0
  211. package/dist/utils/tokens.js +134 -0
  212. package/dist/utils/tokens.js.map +1 -0
  213. package/package.json +7 -1
  214. package/.env.example +0 -8
  215. package/examples/01-simple-query.ts +0 -43
  216. package/examples/02-multi-tool.ts +0 -44
  217. package/examples/03-multi-turn.ts +0 -39
  218. package/examples/04-prompt-api.ts +0 -29
  219. package/examples/05-custom-system-prompt.ts +0 -26
  220. package/examples/06-mcp-server.ts +0 -49
  221. package/examples/07-custom-tools.ts +0 -87
  222. package/examples/08-official-api-compat.ts +0 -38
  223. package/examples/09-subagents.ts +0 -48
  224. package/examples/10-permissions.ts +0 -40
  225. package/examples/11-custom-mcp-tools.ts +0 -101
  226. package/examples/12-skills.ts +0 -88
  227. package/examples/13-hooks.ts +0 -88
  228. package/examples/14-openai-compat.ts +0 -71
  229. package/examples/web/index.html +0 -365
  230. package/examples/web/server.ts +0 -157
  231. package/tsconfig.json +0 -19
@@ -1,365 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Open Agent SDK</title>
7
- <style>
8
- *{margin:0;padding:0;box-sizing:border-box}
9
- :root{
10
- --bg:#f5f6f8;--surface:#fff;--border:#e5e7eb;
11
- --text:#1a1a1a;--text2:#6b7280;--accent:#111;
12
- --user-bg:#111;--user-fg:#fff;
13
- --tool-bg:#f3f4f6;--tool-border:#e0e1e4;
14
- --think-bg:#fffbeb;--think-border:#fde68a;
15
- --ok-bg:#ecfdf5;--ok-border:#86efac;--ok-text:#166534;
16
- --err-bg:#fef2f2;--err-border:#fca5a5;--err-text:#991b1b;
17
- --radius:16px;
18
- }
19
- body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif;
20
- background:var(--bg);color:var(--text);height:100vh;display:flex;flex-direction:column}
21
-
22
- /* Header */
23
- header{display:flex;align-items:center;justify-content:space-between;
24
- padding:14px 20px;background:var(--surface);border-bottom:1px solid var(--border)}
25
- header h1{font-size:16px;font-weight:600}
26
- header button{width:34px;height:34px;border-radius:50%;border:1px solid var(--border);
27
- background:var(--surface);font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center}
28
- header button:hover{background:var(--bg)}
29
-
30
- /* Chat */
31
- #chat{flex:1;overflow-y:auto;padding:24px 16px}
32
- #chat-inner{max-width:800px;margin:0 auto;display:flex;flex-direction:column;gap:20px}
33
-
34
- /* Welcome */
35
- #welcome{text-align:center;padding:60px 0 30px}
36
- #welcome h2{font-size:22px;font-weight:600;margin-bottom:22px;color:var(--text)}
37
- .suggestions{display:grid;grid-template-columns:1fr 1fr;gap:10px;max-width:500px;margin:0 auto}
38
- .suggestions button{padding:12px 16px;border:1px solid var(--border);border-radius:12px;
39
- background:var(--surface);cursor:pointer;text-align:left;font-size:13px;color:var(--text);transition:border-color .15s}
40
- .suggestions button:hover{border-color:#999}
41
- .suggestions span{margin-right:6px}
42
-
43
- /* Message rows */
44
- .msg-row{display:flex}
45
- .msg-row.user{justify-content:flex-end}
46
- .msg-row.assistant{justify-content:flex-start}
47
-
48
- /* Bubbles */
49
- .bubble-user{background:var(--user-bg);color:var(--user-fg);padding:10px 16px;
50
- border-radius:18px 18px 4px 18px;max-width:75%;font-size:14px;line-height:1.55;white-space:pre-wrap}
51
- .bubble-assistant{max-width:85%;font-size:14.5px;line-height:1.65}
52
- .bubble-assistant p{margin-bottom:8px}
53
- .bubble-assistant p:last-child{margin-bottom:0}
54
- .bubble-assistant strong{font-weight:600}
55
- .bubble-assistant code{background:#f0f1f3;padding:1px 5px;border-radius:4px;font-size:13px}
56
- .bubble-assistant pre{background:#1e1e1e;color:#d4d4d4;padding:14px 16px;border-radius:10px;
57
- overflow-x:auto;margin:8px 0;font-size:13px;line-height:1.5}
58
- .bubble-assistant pre code{background:none;padding:0;color:inherit}
59
- .bubble-assistant ul,.bubble-assistant ol{padding-left:22px;margin:6px 0}
60
- .bubble-assistant li{margin:3px 0}
61
-
62
- /* Tool call card */
63
- .tool-card{background:var(--tool-bg);border:1px solid var(--tool-border);border-radius:10px;
64
- padding:10px 14px;margin:8px 0;font-size:13px}
65
- .tool-card .tool-hd{display:flex;align-items:center;gap:6px;font-weight:600;margin-bottom:4px}
66
- .tool-card .tool-icon{font-size:15px}
67
- .tool-card .tool-input{color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
68
- .tool-result{margin:4px 0 8px 12px;padding:8px 12px;border-left:3px solid var(--tool-border);
69
- font-size:12.5px;color:var(--text2);max-height:200px;overflow-y:auto;white-space:pre-wrap;word-break:break-all}
70
-
71
- /* Thinking */
72
- .think-box{background:var(--think-bg);border:1px solid var(--think-border);border-radius:10px;
73
- padding:10px 14px;margin:8px 0;font-size:13px;font-style:italic;color:#92400e}
74
-
75
- /* Result banner */
76
- .result-banner{border-radius:10px;padding:10px 16px;font-size:13px;margin:8px 0;display:flex;align-items:center;gap:8px}
77
- .result-banner.ok{background:var(--ok-bg);border:1px solid var(--ok-border);color:var(--ok-text)}
78
- .result-banner.err{background:var(--err-bg);border:1px solid var(--err-border);color:var(--err-text)}
79
-
80
- /* Typing indicator */
81
- .typing{display:flex;align-items:center;gap:4px;padding:8px 0}
82
- .typing span{width:7px;height:7px;background:#aaa;border-radius:50%;animation:bounce .6s infinite alternate}
83
- .typing span:nth-child(2){animation-delay:.15s}
84
- .typing span:nth-child(3){animation-delay:.3s}
85
- @keyframes bounce{to{transform:translateY(-6px);opacity:.4}}
86
-
87
- /* Input area */
88
- #input-area{padding:12px 16px 16px;background:var(--surface);border-top:1px solid var(--border)}
89
- #input-wrap{max-width:800px;margin:0 auto;display:flex;align-items:flex-end;gap:10px;
90
- border:1px solid var(--border);border-radius:26px;padding:6px 8px 6px 18px;background:var(--surface);
91
- transition:border-color .2s}
92
- #input-wrap:focus-within{border-color:#999}
93
- #prompt{flex:1;border:none;outline:none;font-size:14px;line-height:1.5;resize:none;
94
- min-height:24px;max-height:180px;font-family:inherit;background:transparent}
95
- #send-btn{width:38px;height:38px;border-radius:50%;border:none;background:var(--accent);
96
- color:#fff;font-size:18px;cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center;
97
- transition:opacity .15s}
98
- #send-btn:disabled{opacity:.35;cursor:default}
99
-
100
- @keyframes fadeIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
101
- .msg-row,.tool-card,.tool-result,.think-box,.result-banner{animation:fadeIn .2s ease}
102
- </style>
103
- </head>
104
- <body>
105
-
106
- <header>
107
- <h1>Open Agent SDK</h1>
108
- <button onclick="newSession()" title="New session">+</button>
109
- </header>
110
-
111
- <div id="chat">
112
- <div id="chat-inner">
113
- <div id="welcome">
114
- <h2>What can I do for you?</h2>
115
- <div class="suggestions">
116
- <button onclick="useSuggestion(this)"><span>&#128193;</span>List files in this project</button>
117
- <button onclick="useSuggestion(this)"><span>&#128196;</span>Read package.json</button>
118
- <button onclick="useSuggestion(this)"><span>&#128202;</span>Count lines of code</button>
119
- <button onclick="useSuggestion(this)"><span>&#128187;</span>Show system info</button>
120
- </div>
121
- </div>
122
- </div>
123
- </div>
124
-
125
- <div id="input-area">
126
- <div id="input-wrap">
127
- <textarea id="prompt" rows="1" placeholder="Assign a task or ask anything" onkeydown="handleKey(event)" oninput="autoResize()"></textarea>
128
- <button id="send-btn" onclick="sendMessage()">&#8593;</button>
129
- </div>
130
- </div>
131
-
132
- <script>
133
- const chatInner = document.getElementById('chat-inner');
134
- const chatEl = document.getElementById('chat');
135
- const promptEl = document.getElementById('prompt');
136
- const sendBtn = document.getElementById('send-btn');
137
- const welcomeEl = document.getElementById('welcome');
138
-
139
- let streaming = false;
140
-
141
- const TOOL_ICONS = {
142
- Bash:'&#128736;',Read:'&#128196;',Write:'&#128221;',Edit:'&#9998;',
143
- Glob:'&#128269;',Grep:'&#128270;',WebFetch:'&#127760;',WebSearch:'&#128269;',
144
- Agent:'&#129302;',NotebookEdit:'&#128211;',TaskCreate:'&#128203;',
145
- };
146
-
147
- /* ---- helpers ---- */
148
- function esc(s){return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}
149
-
150
- function renderMarkdown(raw){
151
- let h = esc(raw);
152
- // code blocks
153
- h = h.replace(/```(\w*)\n([\s\S]*?)```/g, (_,lang,code) =>
154
- `<pre><code class="lang-${lang}">${code.trim()}</code></pre>`);
155
- // inline code
156
- h = h.replace(/`([^`\n]+)`/g, '<code>$1</code>');
157
- // bold
158
- h = h.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
159
- // unordered lists
160
- h = h.replace(/^[\-\*] (.+)$/gm, '<li>$1</li>');
161
- h = h.replace(/(<li>.*<\/li>\n?)+/g, m => '<ul>'+m+'</ul>');
162
- // ordered lists
163
- h = h.replace(/^\d+\. (.+)$/gm, '<li>$1</li>');
164
- // paragraphs
165
- h = h.replace(/\n{2,}/g, '</p><p>');
166
- h = h.replace(/\n/g, '<br>');
167
- return '<p>'+h+'</p>';
168
- }
169
-
170
- function scrollToBottom(){
171
- requestAnimationFrame(()=>{ chatEl.scrollTop = chatEl.scrollHeight; });
172
- }
173
-
174
- function autoResize(){
175
- promptEl.style.height = 'auto';
176
- promptEl.style.height = Math.min(promptEl.scrollHeight, 180)+'px';
177
- }
178
-
179
- /* ---- actions ---- */
180
- function handleKey(e){
181
- if(e.key==='Enter' && !e.shiftKey){ e.preventDefault(); sendMessage(); }
182
- }
183
-
184
- function useSuggestion(btn){
185
- const text = btn.textContent.replace(/^.\s*/u,'');
186
- promptEl.value = text;
187
- sendMessage();
188
- }
189
-
190
- async function newSession(){
191
- await fetch('/api/new',{method:'POST'});
192
- chatInner.innerHTML = '';
193
- chatInner.appendChild(welcomeEl);
194
- welcomeEl.style.display = '';
195
- }
196
-
197
- async function sendMessage(){
198
- const text = promptEl.value.trim();
199
- if(!text || streaming) return;
200
- streaming = true;
201
- sendBtn.disabled = true;
202
- promptEl.value = '';
203
- autoResize();
204
-
205
- // hide welcome
206
- welcomeEl.style.display = 'none';
207
-
208
- // user bubble
209
- const uRow = document.createElement('div');
210
- uRow.className = 'msg-row user';
211
- uRow.innerHTML = `<div class="bubble-user">${esc(text)}</div>`;
212
- chatInner.appendChild(uRow);
213
- scrollToBottom();
214
-
215
- // typing indicator
216
- const typingEl = document.createElement('div');
217
- typingEl.className = 'msg-row assistant';
218
- typingEl.innerHTML = '<div class="typing"><span></span><span></span><span></span></div>';
219
- chatInner.appendChild(typingEl);
220
- scrollToBottom();
221
-
222
- // assistant wrapper
223
- const aRow = document.createElement('div');
224
- aRow.className = 'msg-row assistant';
225
- const aBubble = document.createElement('div');
226
- aBubble.className = 'bubble-assistant';
227
- aRow.appendChild(aBubble);
228
-
229
- let textAcc = '';
230
- let textEl = null;
231
- let typingRemoved = false;
232
-
233
- function ensureTextEl(){
234
- if(!textEl){
235
- textEl = document.createElement('div');
236
- aBubble.appendChild(textEl);
237
- }
238
- }
239
-
240
- try{
241
- const resp = await fetch('/api/chat',{
242
- method:'POST',
243
- headers:{'Content-Type':'application/json'},
244
- body: JSON.stringify({message:text}),
245
- });
246
-
247
- if(!resp.ok){
248
- throw new Error(`HTTP ${resp.status}: ${await resp.text()}`);
249
- }
250
-
251
- // Two code paths: streaming (ReadableStream) or fallback (text)
252
- if(resp.body && typeof resp.body.getReader === 'function'){
253
- // --- Streaming path ---
254
- const reader = resp.body.getReader();
255
- const decoder = new TextDecoder();
256
- let buf = '';
257
-
258
- while(true){
259
- const {done,value} = await reader.read();
260
- if(done) break;
261
- buf += decoder.decode(value, {stream:true});
262
- processSSEBuffer();
263
- }
264
- // flush remaining
265
- if(buf.trim()) processSSEBuffer();
266
-
267
- function processSSEBuffer(){
268
- const lines = buf.split('\n');
269
- buf = lines.pop() || '';
270
- for(const line of lines) handleSSELine(line);
271
- }
272
- } else {
273
- // --- Fallback: read full text at once (proxy/polyfill environments) ---
274
- const fullText = await resp.text();
275
- for(const line of fullText.split('\n')) handleSSELine(line);
276
- }
277
-
278
- function handleSSELine(line){
279
- const trimmed = line.trim();
280
- if(!trimmed.startsWith('data: ')) return;
281
- let parsed;
282
- try{ parsed = JSON.parse(trimmed.slice(6)); } catch{ return; }
283
- const {event, data} = parsed;
284
- if(!event || !data) return;
285
-
286
- // remove typing on first real event
287
- if(!typingRemoved){ typingRemoved = true; typingEl.remove(); chatInner.appendChild(aRow); }
288
-
289
- switch(event){
290
- case 'text':
291
- textAcc += data.text;
292
- ensureTextEl();
293
- textEl.innerHTML = renderMarkdown(textAcc);
294
- scrollToBottom();
295
- break;
296
-
297
- case 'tool_use':{
298
- textAcc = ''; textEl = null;
299
- const icon = TOOL_ICONS[data.name] || '&#128295;';
300
- const inputStr = typeof data.input === 'string' ? data.input : JSON.stringify(data.input);
301
- const card = document.createElement('div');
302
- card.className = 'tool-card';
303
- card.id = 'tool-'+data.id;
304
- card.innerHTML = `<div class="tool-hd"><span class="tool-icon">${icon}</span>${esc(data.name)}</div>`
305
- + `<div class="tool-input">${esc(inputStr).slice(0,200)}</div>`;
306
- aBubble.appendChild(card);
307
- scrollToBottom();
308
- break;
309
- }
310
-
311
- case 'tool_result':{
312
- const card = document.getElementById('tool-'+data.tool_use_id);
313
- const rd = document.createElement('div');
314
- rd.className = 'tool-result';
315
- rd.textContent = (data.content||'').slice(0,3000);
316
- if(card) card.after(rd); else aBubble.appendChild(rd);
317
- scrollToBottom();
318
- break;
319
- }
320
-
321
- case 'thinking':{
322
- textAcc = ''; textEl = null;
323
- const tb = document.createElement('div');
324
- tb.className = 'think-box';
325
- tb.textContent = data.thinking.slice(0,1000);
326
- aBubble.appendChild(tb);
327
- scrollToBottom();
328
- break;
329
- }
330
-
331
- case 'result':{
332
- const b = document.createElement('div');
333
- b.className = 'result-banner ok';
334
- b.innerHTML = `&#9989; Done &middot; $${(data.cost||0).toFixed(2)} &middot; ${((data.duration_ms||0)/1000).toFixed(1)}s &middot; ${(data.input_tokens||0)+(data.output_tokens||0)} tokens`;
335
- aBubble.appendChild(b);
336
- scrollToBottom();
337
- break;
338
- }
339
-
340
- case 'error':{
341
- const b = document.createElement('div');
342
- b.className = 'result-banner err';
343
- b.innerHTML = `&#10060; Error: ${esc(data.message||'unknown')}`;
344
- aBubble.appendChild(b);
345
- scrollToBottom();
346
- break;
347
- }
348
- }
349
- }
350
-
351
- }catch(err){
352
- if(!typingRemoved){ typingEl.remove(); chatInner.appendChild(aRow); }
353
- const b = document.createElement('div');
354
- b.className = 'result-banner err';
355
- b.textContent = 'Network error: '+err.message;
356
- aBubble.appendChild(b);
357
- }
358
-
359
- streaming = false;
360
- sendBtn.disabled = false;
361
- promptEl.focus();
362
- }
363
- </script>
364
- </body>
365
- </html>
@@ -1,157 +0,0 @@
1
- /**
2
- * Web Chat Server
3
- *
4
- * A lightweight HTTP server providing:
5
- * GET / — serves the chat UI
6
- * POST /api/chat — SSE stream of agent events
7
- * POST /api/new — resets the session
8
- *
9
- * Run: npx tsx examples/web/server.ts
10
- */
11
-
12
- import { createServer, type IncomingMessage, type ServerResponse } from 'http'
13
- import { readFile } from 'fs/promises'
14
- import { join, dirname } from 'path'
15
- import { fileURLToPath } from 'url'
16
- import { createAgent, type Agent } from '../../src/index.js'
17
-
18
- const __dirname = dirname(fileURLToPath(import.meta.url))
19
- const PORT = parseInt(process.env.PORT || '8081')
20
-
21
- let agent: Agent | null = null
22
-
23
- function getOrCreateAgent(): Agent {
24
- if (!agent) {
25
- agent = createAgent({
26
- model: process.env.CODEANY_MODEL || 'claude-sonnet-4-6',
27
- maxTurns: 20,
28
- })
29
- }
30
- return agent
31
- }
32
-
33
- function resetAgent(): void {
34
- agent?.close().catch(() => {})
35
- agent = null
36
- }
37
-
38
- /** Read the full request body as a string. */
39
- function readBody(req: IncomingMessage): Promise<string> {
40
- return new Promise((resolve, reject) => {
41
- const chunks: Buffer[] = []
42
- req.on('data', (c: Buffer) => chunks.push(c))
43
- req.on('end', () => resolve(Buffer.concat(chunks).toString()))
44
- req.on('error', reject)
45
- })
46
- }
47
-
48
- /** Handle POST /api/chat — SSE stream */
49
- async function handleChat(req: IncomingMessage, res: ServerResponse) {
50
- const body = JSON.parse(await readBody(req))
51
- const prompt = body.message?.trim()
52
- if (!prompt) {
53
- res.writeHead(400, { 'Content-Type': 'application/json' })
54
- res.end(JSON.stringify({ error: 'empty message' }))
55
- return
56
- }
57
-
58
- // SSE headers
59
- res.writeHead(200, {
60
- 'Content-Type': 'text/event-stream',
61
- 'Cache-Control': 'no-cache',
62
- 'Connection': 'keep-alive',
63
- 'X-Accel-Buffering': 'no',
64
- })
65
-
66
- const send = (event: string, data: unknown) => {
67
- res.write(`data: ${JSON.stringify({ event, data })}\n\n`)
68
- }
69
-
70
- const ag = getOrCreateAgent()
71
- const startMs = Date.now()
72
-
73
- try {
74
- for await (const ev of ag.query(prompt)) {
75
- switch (ev.type) {
76
- case 'assistant': {
77
- for (const block of ev.message.content) {
78
- if (block.type === 'text') {
79
- send('text', { text: block.text })
80
- } else if (block.type === 'tool_use') {
81
- send('tool_use', {
82
- id: block.id,
83
- name: block.name,
84
- input: block.input,
85
- })
86
- } else if ('thinking' in block) {
87
- send('thinking', { thinking: (block as any).thinking })
88
- }
89
- }
90
- break
91
- }
92
- case 'tool_result':
93
- send('tool_result', {
94
- tool_use_id: ev.result.tool_use_id,
95
- content: ev.result.output,
96
- is_error: false,
97
- })
98
- break
99
- case 'result':
100
- send('result', {
101
- num_turns: ev.num_turns ?? 0,
102
- input_tokens: ev.usage?.input_tokens ?? 0,
103
- output_tokens: ev.usage?.output_tokens ?? 0,
104
- cost: ev.total_cost_usd ?? ev.cost ?? 0,
105
- duration_ms: Date.now() - startMs,
106
- })
107
- break
108
- }
109
- }
110
- } catch (err: any) {
111
- send('error', { message: err.message })
112
- }
113
-
114
- send('done', null)
115
- res.end()
116
- }
117
-
118
- /** Handle POST /api/new */
119
- function handleNewSession(_req: IncomingMessage, res: ServerResponse) {
120
- resetAgent()
121
- res.writeHead(200, { 'Content-Type': 'application/json' })
122
- res.end(JSON.stringify({ ok: true }))
123
- }
124
-
125
- /** Serve the static index.html */
126
- async function serveIndex(_req: IncomingMessage, res: ServerResponse) {
127
- const html = await readFile(join(__dirname, 'index.html'), 'utf-8')
128
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' })
129
- res.end(html)
130
- }
131
-
132
- // --- HTTP Server ---
133
-
134
- const server = createServer(async (req, res) => {
135
- const url = req.url || '/'
136
- const method = req.method || 'GET'
137
-
138
- try {
139
- if (url === '/' && method === 'GET') return await serveIndex(req, res)
140
- if (url === '/api/chat' && method === 'POST') return await handleChat(req, res)
141
- if (url === '/api/new' && method === 'POST') return handleNewSession(req, res)
142
-
143
- res.writeHead(404)
144
- res.end('Not Found')
145
- } catch (err: any) {
146
- console.error(err)
147
- if (!res.headersSent) {
148
- res.writeHead(500, { 'Content-Type': 'application/json' })
149
- }
150
- res.end(JSON.stringify({ error: err.message }))
151
- }
152
- })
153
-
154
- server.listen(PORT, () => {
155
- console.log(`\n Open Agent SDK — Web Chat`)
156
- console.log(` http://localhost:${PORT}\n`)
157
- })
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "declaration": true,
9
- "declarationMap": true,
10
- "sourceMap": true,
11
- "strict": true,
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "resolveJsonModule": true
16
- },
17
- "include": ["src/**/*"],
18
- "exclude": ["node_modules", "dist", "examples"]
19
- }