orbitx 0.0.3 → 0.0.5

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 (110) hide show
  1. package/{src/core/ai-provider.ts → dist/core/ai-provider.d.ts} +19 -25
  2. package/dist/core/ai-provider.d.ts.map +1 -0
  3. package/dist/core/ai-provider.js +4 -0
  4. package/dist/core/ai-provider.js.map +1 -0
  5. package/dist/core/base-agent.d.ts +53 -0
  6. package/dist/core/base-agent.d.ts.map +1 -0
  7. package/{src/core/base-agent.ts → dist/core/base-agent.js} +197 -269
  8. package/dist/core/base-agent.js.map +1 -0
  9. package/dist/core/deepseek-provider.d.ts +9 -0
  10. package/dist/core/deepseek-provider.d.ts.map +1 -0
  11. package/{src/core/deepseek-provider.ts → dist/core/deepseek-provider.js} +60 -71
  12. package/dist/core/deepseek-provider.js.map +1 -0
  13. package/dist/core/mcp-client.d.ts +21 -0
  14. package/dist/core/mcp-client.d.ts.map +1 -0
  15. package/{src/core/mcp-client.ts → dist/core/mcp-client.js} +90 -113
  16. package/dist/core/mcp-client.js.map +1 -0
  17. package/dist/core/mcp-computer.d.ts +4 -0
  18. package/dist/core/mcp-computer.d.ts.map +1 -0
  19. package/{src/core/mcp-computer.ts → dist/core/mcp-computer.js} +5 -5
  20. package/dist/core/mcp-computer.js.map +1 -0
  21. package/dist/core/mcp-connection.d.ts +6 -0
  22. package/dist/core/mcp-connection.d.ts.map +1 -0
  23. package/dist/core/mcp-connection.js +10 -0
  24. package/dist/core/mcp-connection.js.map +1 -0
  25. package/dist/core/mcp-ipc-connection.d.ts +20 -0
  26. package/dist/core/mcp-ipc-connection.d.ts.map +1 -0
  27. package/{src/core/mcp-ipc-connection.ts → dist/core/mcp-ipc-connection.js} +126 -153
  28. package/dist/core/mcp-ipc-connection.js.map +1 -0
  29. package/dist/core/mcp-server.d.ts +9 -0
  30. package/dist/core/mcp-server.d.ts.map +1 -0
  31. package/{src/core/mcp-server.ts → dist/core/mcp-server.js} +45 -49
  32. package/dist/core/mcp-server.js.map +1 -0
  33. package/dist/core/mcp.d.ts +29 -0
  34. package/dist/core/mcp.d.ts.map +1 -0
  35. package/dist/core/mcp.js +11 -0
  36. package/dist/core/mcp.js.map +1 -0
  37. package/dist/core/ollama-provider.d.ts +9 -0
  38. package/dist/core/ollama-provider.d.ts.map +1 -0
  39. package/{src/core/ollama-provider.ts → dist/core/ollama-provider.js} +59 -70
  40. package/dist/core/ollama-provider.js.map +1 -0
  41. package/dist/core/skill.d.ts +15 -0
  42. package/dist/core/skill.d.ts.map +1 -0
  43. package/dist/core/skill.js +11 -0
  44. package/dist/core/skill.js.map +1 -0
  45. package/dist/index.d.ts +18 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +16 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/templates/researcher.d.ts +27 -0
  50. package/dist/templates/researcher.d.ts.map +1 -0
  51. package/dist/templates/researcher.js +70 -0
  52. package/dist/templates/researcher.js.map +1 -0
  53. package/dist/templates/simple.d.ts +27 -0
  54. package/dist/templates/simple.d.ts.map +1 -0
  55. package/dist/templates/simple.js +35 -0
  56. package/dist/templates/simple.js.map +1 -0
  57. package/dist/tests/mcp.test.d.ts +2 -0
  58. package/dist/tests/mcp.test.d.ts.map +1 -0
  59. package/{src/tests/mcp.test.ts → dist/tests/mcp.test.js} +55 -73
  60. package/dist/tests/mcp.test.js.map +1 -0
  61. package/dist/tools/fs/index.d.ts +3 -0
  62. package/dist/tools/fs/index.d.ts.map +1 -0
  63. package/dist/tools/fs/index.js +3 -0
  64. package/dist/tools/fs/index.js.map +1 -0
  65. package/dist/tools/fs/read-file.d.ts +4 -0
  66. package/dist/tools/fs/read-file.d.ts.map +1 -0
  67. package/{src/tools/fs/read-file.ts → dist/tools/fs/read-file.js} +49 -54
  68. package/dist/tools/fs/read-file.js.map +1 -0
  69. package/dist/tools/fs/write-file.d.ts +4 -0
  70. package/dist/tools/fs/write-file.d.ts.map +1 -0
  71. package/{src/tools/fs/write-file.ts → dist/tools/fs/write-file.js} +68 -73
  72. package/dist/tools/fs/write-file.js.map +1 -0
  73. package/dist/tools/utils/get-current-time.d.ts +4 -0
  74. package/dist/tools/utils/get-current-time.d.ts.map +1 -0
  75. package/{src/tools/utils/get-current-time.ts → dist/tools/utils/get-current-time.js} +40 -45
  76. package/dist/tools/utils/get-current-time.js.map +1 -0
  77. package/dist/tools/utils/index.d.ts +2 -0
  78. package/dist/tools/utils/index.d.ts.map +1 -0
  79. package/dist/tools/utils/index.js +2 -0
  80. package/dist/tools/utils/index.js.map +1 -0
  81. package/dist/tools/www/fetch.d.ts +4 -0
  82. package/dist/tools/www/fetch.d.ts.map +1 -0
  83. package/{src/tools/www/fetch.ts → dist/tools/www/fetch.js} +147 -161
  84. package/dist/tools/www/fetch.js.map +1 -0
  85. package/dist/tools/www/index.d.ts +4 -0
  86. package/dist/tools/www/index.d.ts.map +1 -0
  87. package/dist/tools/www/index.js +4 -0
  88. package/dist/tools/www/index.js.map +1 -0
  89. package/dist/tools/www/read-web-page.d.ts +4 -0
  90. package/dist/tools/www/read-web-page.d.ts.map +1 -0
  91. package/{src/tools/www/read-web-page.ts → dist/tools/www/read-web-page.js} +330 -350
  92. package/dist/tools/www/read-web-page.js.map +1 -0
  93. package/dist/tools/www/web-search.d.ts +4 -0
  94. package/dist/tools/www/web-search.d.ts.map +1 -0
  95. package/{src/tools/www/web-search.ts → dist/tools/www/web-search.js} +82 -102
  96. package/dist/tools/www/web-search.js.map +1 -0
  97. package/package.json +19 -5
  98. package/.env.example +0 -1
  99. package/orbitx.png +0 -0
  100. package/public/index.html +0 -397
  101. package/src/core/mcp-connection.ts +0 -12
  102. package/src/core/mcp.ts +0 -23
  103. package/src/core/skill.ts +0 -16
  104. package/src/index.ts +0 -17
  105. package/src/templates/researcher.ts +0 -73
  106. package/src/templates/simple.ts +0 -64
  107. package/src/tools/fs/index.ts +0 -2
  108. package/src/tools/utils/index.ts +0 -1
  109. package/src/tools/www/index.ts +0 -3
  110. package/tsconfig.json +0 -34
package/public/index.html DELETED
@@ -1,397 +0,0 @@
1
- <!doctype html>
2
- <html>
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <script src="static/tailwindcss.js"></script>
8
- <style>
9
- * {
10
- box-sizing: border-box;
11
- }
12
-
13
- body {
14
- margin: 0;
15
- font-family: 'Inter', system-ui, sans-serif;
16
- }
17
-
18
- ::-webkit-scrollbar {
19
- width: 6px;
20
- }
21
-
22
- ::-webkit-scrollbar-track {
23
- background: transparent;
24
- }
25
-
26
- ::-webkit-scrollbar-thumb {
27
- background: #d1d5db;
28
- border-radius: 3px;
29
- }
30
-
31
- .dark ::-webkit-scrollbar-thumb {
32
- background: #374151;
33
- }
34
-
35
- .tool-val {
36
- max-width: 260px;
37
- overflow: hidden;
38
- text-overflow: ellipsis;
39
- white-space: nowrap;
40
- }
41
- </style>
42
- <script>
43
- tailwind.config = {
44
- darkMode: 'class',
45
- theme: {
46
- extend: {
47
- fontFamily: { sans: ['Inter', 'system-ui', 'sans-serif'] },
48
- colors: {
49
- surface: { 0: '#f5f5f4', 1: '#fafaf9', 2: '#ffffff' },
50
- accent: { bg: '#eff6ff', text: '#1d4ed8', border: '#bfdbfe' },
51
- pro: { bg: '#f3f0ff', text: '#6d28d9' },
52
- success: { bg: '#f0fdf4', text: '#15803d', border: '#bbf7d0' },
53
- warning: { bg: '#fffbeb', text: '#b45309', border: '#fde68a' },
54
- danger: { bg: '#fff1f2', text: '#be123c', border: '#fecdd3' },
55
- },
56
- animation: {
57
- 'fade-up': 'fadeUp 0.18s ease-out',
58
- 'blink': 'blink 1s step-start infinite',
59
- },
60
- keyframes: {
61
- fadeUp: { '0%': { opacity: 0, transform: 'translateY(6px)' }, '100%': { opacity: 1, transform: 'translateY(0)' } },
62
- blink: { '0%,100%': { opacity: 1 }, '50%': { opacity: 0 } },
63
- }
64
- }
65
- }
66
- }
67
- </script>
68
- </head>
69
-
70
- <body class="bg-stone-100 dark:bg-zinc-900 min-h-screen flex flex-col">
71
-
72
- <!-- Header -->
73
- <header
74
- class="sticky top-0 z-10 bg-white dark:bg-zinc-800 border-b border-stone-200 dark:border-zinc-700 px-4 py-3 flex items-center justify-between">
75
- <div class="flex items-center gap-2.5">
76
- <div class="w-7 h-7 rounded-full bg-violet-100 dark:bg-violet-900 flex items-center justify-center">
77
- <svg class="w-4 h-4 text-violet-600 dark:text-violet-300" viewBox="0 0 24 24" fill="none"
78
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
79
- <path d="M12 2L2 7l10 5 10-5-10-5z" />
80
- <path d="M2 17l10 5 10-5" />
81
- <path d="M2 12l10 5 10-5" />
82
- </svg>
83
- </div>
84
- <span class="font-semibold text-sm text-zinc-800 dark:text-zinc-100">Agent Thread</span>
85
- <span id="status-dot" class="w-2 h-2 rounded-full bg-emerald-400"></span>
86
- </div>
87
- <button onclick="toggleDark()"
88
- class="p-1.5 rounded-lg hover:bg-stone-100 dark:hover:bg-zinc-700 text-zinc-500 dark:text-zinc-400 transition-colors">
89
- <svg id="icon-sun" class="w-4 h-4 hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor"
90
- stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
91
- <circle cx="12" cy="12" r="5" />
92
- <line x1="12" y1="1" x2="12" y2="3" />
93
- <line x1="12" y1="21" x2="12" y2="23" />
94
- <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
95
- <line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
96
- <line x1="1" y1="12" x2="3" y2="12" />
97
- <line x1="21" y1="12" x2="23" y2="12" />
98
- <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
99
- <line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
100
- </svg>
101
- <svg id="icon-moon" class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
102
- stroke-linecap="round" stroke-linejoin="round">
103
- <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
104
- </svg>
105
- </button>
106
- </header>
107
-
108
- <!-- Thread -->
109
- <main id="thread" class="flex-1 overflow-y-auto px-4 py-4 flex flex-col gap-3 max-w-3xl mx-auto w-full"></main>
110
-
111
- <!-- Typing indicator placeholder -->
112
- <div id="typing" class="hidden max-w-3xl mx-auto w-full px-4 pb-2">
113
- <div class="flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-500">
114
- <div class="flex gap-1">
115
- <span class="w-1.5 h-1.5 rounded-full bg-zinc-400 dark:bg-zinc-500 animate-bounce"
116
- style="animation-delay:0ms"></span>
117
- <span class="w-1.5 h-1.5 rounded-full bg-zinc-400 dark:bg-zinc-500 animate-bounce"
118
- style="animation-delay:120ms"></span>
119
- <span class="w-1.5 h-1.5 rounded-full bg-zinc-400 dark:bg-zinc-500 animate-bounce"
120
- style="animation-delay:240ms"></span>
121
- </div>
122
- Agent is working…
123
- </div>
124
- </div>
125
-
126
- <!-- Input -->
127
- <footer class="sticky bottom-0 bg-white dark:bg-zinc-800 border-t border-stone-200 dark:border-zinc-700 px-4 py-3">
128
- <div class="max-w-3xl mx-auto flex gap-2">
129
- <input id="user-input" type="text" placeholder="Send a message…"
130
- class="flex-1 text-sm rounded-xl border border-stone-200 dark:border-zinc-600 bg-stone-50 dark:bg-zinc-700 text-zinc-800 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 px-4 py-2.5 outline-none focus:ring-2 focus:ring-violet-400 focus:border-transparent transition"
131
- onkeydown="if(event.key==='Enter')sendUserMessage()" />
132
- <button onclick="sendUserMessage()"
133
- class="px-4 py-2.5 rounded-xl bg-violet-600 hover:bg-violet-700 active:scale-95 text-white text-sm font-medium transition-all flex items-center gap-1.5">
134
- <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"
135
- stroke-linecap="round" stroke-linejoin="round">
136
- <line x1="22" y1="2" x2="11" y2="13" />
137
- <polygon points="22 2 15 22 11 13 2 9 22 2" />
138
- </svg>
139
- Send
140
- </button>
141
- </div>
142
- </footer>
143
-
144
-
145
- <script>
146
- /* ── ICONS ─────────────────────────────────────────── */
147
- const ICONS = {
148
- search: `<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`,
149
- globe: `<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>`,
150
- code: `<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`,
151
- file: `<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`,
152
- check: `<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`,
153
- cross: `<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>`,
154
- clock: `<svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>`,
155
- agent: `<svg class="w-3.5 h-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>`,
156
- };
157
-
158
- const TOOL_META = {
159
- 'web-search': { icon: ICONS.search, label: 'Web search', color: 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/40' },
160
- 'read-web-page': { icon: ICONS.globe, label: 'Fetch page', color: 'text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/40' },
161
- 'run-code': { icon: ICONS.code, label: 'Run code', color: 'text-purple-600 dark:text-purple-400 bg-purple-50 dark:bg-purple-900/40' },
162
- 'read-file': { icon: ICONS.file, label: 'Read file', color: 'text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-900/40' },
163
- };
164
- function toolMeta(name) { return TOOL_META[name] || { icon: ICONS.code, label: name, color: 'text-zinc-500 bg-zinc-100 dark:bg-zinc-700' }; }
165
-
166
- /* ── STATE ─────────────────────────────────────────── */
167
- // Each entry: { role: 'user'|'assistant'|'tool', content }
168
- // tool content is a JSON string
169
- let messageQueue = [];
170
- let isGenerating = false;
171
- let currentGroupEl = null; // the current agent-block div
172
- let currentGroupItems = []; // items in current agent block
173
-
174
- /* ── DEMO SCRIPT ───────────────────────────────────── */
175
- // Pre-loaded conversation that plays automatically
176
- const DEMO_SCRIPT = [
177
- { role: 'user', content: 'Find me the best price for a flight from Birjand to Tehran.' },
178
- { role: 'assistant', content: 'On it — starting with a broad price search.' },
179
- { role: 'tool', content: JSON.stringify({ tool: 'web-search', inputs: { query: 'best price flights Birjand to Tehran' }, output: '10 results returned', status: 'ok' }) },
180
- { role: 'assistant', content: "Got results. Let me open the top comparison site for live pricing." },
181
- { role: 'tool', content: JSON.stringify({ tool: 'read-web-page', inputs: { url: 'https://zbordirect.com/en/low-cost/from-iran/to-iran/birjand-tehran', outputType: 'text' }, error: 'Navigation timeout of 50000 ms exceeded', status: 'err' }) },
182
- { role: 'assistant', content: 'That site timed out. Trying Trip.com instead.' },
183
- { role: 'tool', content: JSON.stringify({ tool: 'read-web-page', inputs: { url: 'https://us.trip.com/flights/birjand-to-tehran/airfares-xbj-thr/', outputType: 'text' }, error: 'Navigation timeout of 50000 ms exceeded', status: 'err' }) },
184
- { role: 'assistant', content: 'Still failing. Let me search for more reliable comparison sites first.' },
185
- { role: 'tool', content: JSON.stringify({ tool: 'web-search', inputs: { query: 'reliable flight comparison Iran Birjand Tehran' }, output: 'Skyscanner, Jetcost, Kayak, Wego found', status: 'ok' }) },
186
- { role: 'assistant', content: 'Found better options. Reading Skyscanner now.' },
187
- { role: 'tool', content: JSON.stringify({ tool: 'read-web-page', inputs: { url: 'https://www.skyscanner.com.my/routes/xbj/thra/birjand-to-tehran.html', outputType: 'text' }, output: 'Page loaded — 3 airlines, cheapest from ~$42', status: 'ok' }) },
188
- { role: 'assistant', content: "Here's what I found: Iran Air and Mahan Air both operate direct flights (≈90 min). Cheapest one-way is **~$42** on Iran Air, rising to ~$65 on Mahan Air. Book at least 2 weeks out for the best fares." },
189
- { role: 'user', content: 'What about train options between the two cities?' },
190
- { role: 'assistant', content: "Let me look up train schedules from Birjand to Tehran." },
191
- { role: 'tool', content: JSON.stringify({ tool: 'web-search', inputs: { query: 'train Birjand to Tehran schedule Raja Rail' }, output: '6 results found', status: 'ok' }) },
192
- { role: 'assistant', content: 'Fetching the rail operator timetable.' },
193
- { role: 'tool', content: JSON.stringify({ tool: 'read-web-page', inputs: { url: 'https://www.raja.ir/en/trains', outputType: 'text' }, output: 'Timetable loaded — 2 weekly departures', status: 'ok' }) },
194
- { role: 'assistant', content: "Train option: Raja Rail runs **twice weekly** (Tues & Sat), departing 18:00, arriving ~08:30 next day — roughly 14.5 hours. Tickets start at **~450,000 IRR** (~$1.50 at free-market rate) in second class. Much cheaper than flying but significantly longer." },
195
- ];
196
-
197
- /* ── DOM HELPERS ──────────────────────────────────── */
198
- const thread = document.getElementById('thread');
199
- const typingEl = document.getElementById('typing');
200
-
201
- function scrollToBottom() {
202
- thread.scrollTop = thread.scrollHeight;
203
- }
204
-
205
- function showTyping(show) {
206
- typingEl.classList.toggle('hidden', !show);
207
- if (show) typingEl.scrollIntoView({ behavior: 'smooth', block: 'end' });
208
- }
209
-
210
- function trunc(s, n) { return s && s.length > n ? s.slice(0, n) + '…' : s; }
211
-
212
- function md(text) {
213
- return (text || '')
214
- .replace(/\*\*(.+?)\*\*/g, '<strong class="font-semibold">$1</strong>')
215
- .replace(/\n/g, '<br>');
216
- }
217
-
218
- /* ── RENDER: USER BUBBLE ─────────────────────────── */
219
- function appendUserBubble(content) {
220
- // Close any open agent group
221
- currentGroupEl = null;
222
- currentGroupItems = [];
223
-
224
- const wrap = document.createElement('div');
225
- wrap.className = 'flex justify-end animate-fade-up';
226
- wrap.innerHTML = `
227
- <div class="max-w-[72%] bg-violet-600 text-white text-sm rounded-2xl rounded-br-sm px-4 py-2.5 leading-relaxed shadow-sm">
228
- ${md(content)}
229
- </div>`;
230
- thread.appendChild(wrap);
231
- scrollToBottom();
232
- }
233
-
234
- /* ── RENDER: AGENT TEXT inside group ─────────────── */
235
- function getOrCreateAgentGroup() {
236
- if (!currentGroupEl) {
237
- const wrap = document.createElement('div');
238
- wrap.className = 'flex gap-2.5 animate-fade-up';
239
-
240
- const avatarCol = document.createElement('div');
241
- avatarCol.className = 'flex flex-col items-center pt-1 gap-1';
242
- avatarCol.innerHTML = `
243
- <div class="w-7 h-7 rounded-full bg-violet-100 dark:bg-violet-900/60 flex items-center justify-center text-violet-600 dark:text-violet-300 flex-shrink-0">
244
- ${ICONS.agent}
245
- </div>
246
- <div class="agent-line w-px flex-1 bg-stone-200 dark:bg-zinc-700 min-h-0"></div>`;
247
-
248
- const bodyCol = document.createElement('div');
249
- bodyCol.className = 'flex-1 min-w-0 flex flex-col gap-1.5 pb-1';
250
- bodyCol.dataset.agentBody = '1';
251
-
252
- wrap.appendChild(avatarCol);
253
- wrap.appendChild(bodyCol);
254
- thread.appendChild(wrap);
255
- currentGroupEl = bodyCol;
256
- }
257
- return currentGroupEl;
258
- }
259
-
260
- function appendAgentText(content) {
261
- const body = getOrCreateAgentGroup();
262
- const p = document.createElement('p');
263
- p.className = 'text-sm text-zinc-700 dark:text-zinc-200 leading-relaxed';
264
- p.innerHTML = md(content);
265
- body.appendChild(p);
266
- scrollToBottom();
267
- }
268
-
269
- /* ── RENDER: TOOL CARD inside group ──────────────── */
270
- function appendToolCard(data) {
271
- const body = getOrCreateAgentGroup();
272
- const meta = toolMeta(data.tool);
273
- const st = data.status;
274
-
275
- let badgeHtml, resultHtml = '';
276
- if (st === 'ok') {
277
- badgeHtml = `<span class="inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-emerald-50 dark:bg-emerald-900/40 text-emerald-600 dark:text-emerald-400">${ICONS.check} Done</span>`;
278
- if (data.output) resultHtml = `<p class="text-[11px] text-zinc-400 dark:text-zinc-500 mt-1 leading-relaxed">${trunc(data.output, 100)}</p>`;
279
- } else if (st === 'err') {
280
- badgeHtml = `<span class="inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-red-50 dark:bg-red-900/40 text-red-500 dark:text-red-400">${ICONS.cross} Failed</span>`;
281
- if (data.error) resultHtml = `<p class="text-[11px] font-mono text-red-400 dark:text-red-500 mt-1 leading-relaxed">${data.error}</p>`;
282
- } else {
283
- badgeHtml = `<span class="inline-flex items-center gap-1 text-[10px] font-medium px-1.5 py-0.5 rounded-full bg-zinc-100 dark:bg-zinc-700 text-zinc-400 dark:text-zinc-500">${ICONS.clock} Running</span>`;
284
- }
285
-
286
- const kvHtml = Object.entries(data.inputs || {}).map(([k, v]) => `
287
- <span class="text-[10px] text-zinc-400 dark:text-zinc-500">${k}</span>
288
- <span class="tool-val text-[10px] font-mono text-zinc-500 dark:text-zinc-400 bg-stone-100 dark:bg-zinc-800 border border-stone-200 dark:border-zinc-700 rounded px-1.5 py-0.5">${trunc(String(v), 55)}</span>`
289
- ).join('');
290
-
291
- const card = document.createElement('div');
292
- card.className = 'rounded-xl border border-stone-200 dark:border-zinc-700 bg-white dark:bg-zinc-800/60 overflow-hidden';
293
- card.innerHTML = `
294
- <div class="flex items-center gap-2 px-3 py-2 border-b border-stone-100 dark:border-zinc-700/60">
295
- <div class="w-5 h-5 rounded-md flex items-center justify-center flex-shrink-0 ${meta.color}">${meta.icon}</div>
296
- <span class="text-xs font-medium text-zinc-600 dark:text-zinc-300">${meta.label}</span>
297
- <div class="ml-auto">${badgeHtml}</div>
298
- </div>
299
- <div class="px-3 py-2 flex flex-wrap items-center gap-x-2 gap-y-1">
300
- ${kvHtml}
301
- ${resultHtml}
302
- </div>`;
303
- body.appendChild(card);
304
- scrollToBottom();
305
- }
306
-
307
- /* ── MESSAGE PROCESSOR ────────────────────────────── */
308
- async function processMessage(msg) {
309
- await delay(60);
310
- if (msg.role === 'user') {
311
- currentGroupEl = null; // reset group
312
- appendUserBubble(msg.content);
313
- } else if (msg.role === 'assistant') {
314
- await delay(300);
315
- appendAgentText(msg.content);
316
- } else if (msg.role === 'tool') {
317
- let data;
318
- try { data = JSON.parse(msg.content); } catch { data = {}; }
319
- await delay(200);
320
- appendToolCard(data);
321
- }
322
- }
323
-
324
- function delay(ms) { return new Promise(r => setTimeout(r, ms)); }
325
-
326
- async function drainQueue() {
327
- if (isGenerating) return;
328
- isGenerating = true;
329
- showTyping(true);
330
- while (messageQueue.length > 0) {
331
- const msg = messageQueue.shift();
332
- await processMessage(msg);
333
- await delay(msg.role === 'tool' ? 350 : 180);
334
- }
335
- showTyping(false);
336
- isGenerating = false;
337
- }
338
-
339
- function enqueue(msgs) {
340
- messageQueue.push(...msgs);
341
- drainQueue();
342
- }
343
-
344
- /* ── USER INPUT ───────────────────────────────────── */
345
- function sendUserMessage() {
346
- const input = document.getElementById('user-input');
347
- const text = input.value.trim();
348
- if (!text) return;
349
- input.value = '';
350
-
351
- // Immediately show user bubble
352
- currentGroupEl = null;
353
- appendUserBubble(text);
354
-
355
- // Simulate agent reply
356
- const reply = generateAgentReply(text);
357
- messageQueue.push(...reply);
358
- drainQueue();
359
- }
360
-
361
- function generateAgentReply(userText) {
362
- // Simple mock — builds a short tool + response sequence
363
- const q = userText.toLowerCase();
364
- const searchQuery = q.slice(0, 50);
365
- return [
366
- { role: 'assistant', content: `Understood. Let me look that up for you.` },
367
- { role: 'tool', content: JSON.stringify({ tool: 'web-search', inputs: { query: searchQuery }, output: 'Results found', status: 'ok' }) },
368
- { role: 'assistant', content: `I searched for <strong>"${userText}"</strong>. In a real setup the agent would process results here and give you a detailed answer. Try connecting a real API to replace this stub.` },
369
- ];
370
- }
371
-
372
- /* ── DARK MODE ────────────────────────────────────── */
373
- function toggleDark() {
374
- document.documentElement.classList.toggle('dark');
375
- document.getElementById('icon-sun').classList.toggle('hidden');
376
- document.getElementById('icon-moon').classList.toggle('hidden');
377
- }
378
-
379
- /* ── BOOT: play demo script ───────────────────────── */
380
- window.addEventListener('DOMContentLoaded', () => {
381
- // Stagger demo messages with realistic delays
382
- const staggered = DEMO_SCRIPT.map((msg, i) => {
383
- const base = msg.role === 'user' ? 600 : msg.role === 'tool' ? 450 : 300;
384
- return { msg, delay: i * base };
385
- });
386
-
387
- staggered.forEach(({ msg, delay: d }) => {
388
- setTimeout(() => {
389
- messageQueue.push(msg);
390
- if (!isGenerating) drainQueue();
391
- }, d);
392
- });
393
- });
394
- </script>
395
- </body>
396
-
397
- </html>
@@ -1,12 +0,0 @@
1
- import EventEmitter from "events";
2
-
3
- export class MCPConnection extends EventEmitter {
4
- constructor(overrided: boolean = false) {
5
- super();
6
-
7
- if (!overrided)
8
- this.on("write", (data) => this.emit("read", data))
9
- }
10
- }
11
-
12
- export default MCPConnection;
package/src/core/mcp.ts DELETED
@@ -1,23 +0,0 @@
1
- export class MCPTool {
2
- #options;
3
- constructor(options: {
4
- name: string;
5
- description: string;
6
- inputs: {
7
- name: string;
8
- type: "number" | "string" | "boolean" | "object" | "array";
9
- description: string;
10
- required?: boolean;
11
- default?: any;
12
- }[];
13
- execute: (envID: string, inputs: Record<string, any>) => Promise<any>;
14
- }) {
15
- this.#options = options;
16
- }
17
-
18
- getOptions() {
19
- return this.#options;
20
- }
21
- }
22
-
23
- export default MCPTool;
package/src/core/skill.ts DELETED
@@ -1,16 +0,0 @@
1
- export class Skill {
2
- #skill;
3
- constructor(skill: {
4
- name: string;
5
- description: string;
6
- instructions: string;
7
- }) {
8
- this.#skill = skill;
9
- }
10
-
11
- getSkill() {
12
- return this.#skill;
13
- }
14
- }
15
-
16
- export default Skill;
package/src/index.ts DELETED
@@ -1,17 +0,0 @@
1
- export { AIProvider } from "./core/ai-provider";
2
- export { BaseAgent } from "./core/base-agent";
3
- export { DeepSeekProvider } from "./core/deepseek-provider";
4
- export { MCPClient } from "./core/mcp-client";
5
- export { MCPConnection } from "./core/mcp-connection";
6
- export { MCPIPCConnection } from "./core/mcp-ipc-connection";
7
- export { MCPServer } from "./core/mcp-server";
8
- export { MCPTool } from "./core/mcp";
9
- export { OllamaProvider } from "./core/ollama-provider";
10
- export { Skill } from "./core/skill";
11
-
12
- export { ResearcherAgent } from "./templates/researcher";
13
- export { SimpleAgent } from "./templates/simple";
14
-
15
- export { ReadFileTool, WriteFileTool } from "./tools/fs";
16
- export { GetCurrentTimeTool } from "./tools/utils";
17
- export { FetchTool, ReadWebPageTool, WebSearchTool } from "./tools/www";
@@ -1,73 +0,0 @@
1
- import type { Message } from "../core/ai-provider";
2
- import type AIProvider from "../core/ai-provider";
3
- import BaseAgent from "../core/base-agent";
4
- import type MCPTool from "../core/mcp";
5
- import MCPClient from "../core/mcp-client";
6
- import MCPConnection from "../core/mcp-connection";
7
- import MCPServer from "../core/mcp-server";
8
- import type Skill from "../core/skill";
9
- import { ReadWebPageTool, WebSearchTool } from "../tools/www";
10
-
11
- export class ResearcherAgent extends BaseAgent {
12
- constructor({
13
- aiProvider,
14
- instruction = `you are research agent you have some rules you don't know about any true otherwise first search about it
15
- your each topic search iteration contain two step
16
- 1. use web-search tool to get some urls from search engine
17
- 2. read 4 url with best topic near to out search query in this step you execute 4 read-web-page tool call at once
18
- if result is resolve needs we stop otherwise do above operation more
19
- YOU MUST DO two step before decide to response don't do web-search alone!! at less do search and read page operation 3 times to to get as much information as possible`,
20
- tools = [
21
- WebSearchTool,
22
- ReadWebPageTool
23
- ],
24
- skills = [],
25
- maxMemorizeToken = 30000,
26
- initData = {
27
- memory: "",
28
- messagesFull: [],
29
- fullInputMissTokens: 0,
30
- fullInputHitTokens: 0,
31
- fullOutputTokens: 0,
32
- messagesCompact: [],
33
- currentInputMissTokens: 0,
34
- currentInputHitTokens: 0,
35
- currentOutputTokens: 0,
36
- }
37
- }: {
38
- instruction?: string;
39
- tools?: MCPTool[];
40
- aiProvider: AIProvider;
41
- skills?: Skill[];
42
- maxMemorizeToken?: number;
43
- initData?: {
44
- memory: string;
45
- messagesFull: Message[];
46
- fullInputMissTokens: number;
47
- fullInputHitTokens: number;
48
- fullOutputTokens: number;
49
- messagesCompact: Message[];
50
- currentInputMissTokens: number;
51
- currentInputHitTokens: number;
52
- currentOutputTokens: number;
53
- }
54
- }) {
55
- const conn = new MCPConnection();
56
- const mcpServer = new MCPServer(conn);
57
- tools.forEach(tool => {
58
- mcpServer.registerTool(tool);
59
- });
60
- const mcpClient = new MCPClient("DEFAULT_ENV", conn);
61
- super({
62
- aiProvider,
63
- instruction,
64
- mcpClient,
65
- allowedTools: tools,
66
- skills,
67
- maxMemorizeToken,
68
- initData,
69
- });
70
- }
71
- }
72
-
73
- export default ResearcherAgent;
@@ -1,64 +0,0 @@
1
- import type { Message } from "../core/ai-provider";
2
- import type AIProvider from "../core/ai-provider";
3
- import BaseAgent from "../core/base-agent";
4
- import type MCPTool from "../core/mcp";
5
- import MCPClient from "../core/mcp-client";
6
- import MCPConnection from "../core/mcp-connection";
7
- import MCPServer from "../core/mcp-server";
8
- import type Skill from "../core/skill";
9
-
10
- export class SimpleAgent extends BaseAgent {
11
- constructor({
12
- aiProvider,
13
- instruction = "",
14
- tools = [],
15
- skills = [],
16
- maxMemorizeToken = 16000,
17
- initData = {
18
- memory: "",
19
- messagesFull: [],
20
- fullInputMissTokens: 0,
21
- fullInputHitTokens: 0,
22
- fullOutputTokens: 0,
23
- messagesCompact: [],
24
- currentInputMissTokens: 0,
25
- currentInputHitTokens: 0,
26
- currentOutputTokens: 0,
27
- }
28
- }: {
29
- instruction: string;
30
- tools: MCPTool[];
31
- aiProvider: AIProvider;
32
- skills?: Skill[];
33
- maxMemorizeToken?: number;
34
- initData?: {
35
- memory: string;
36
- messagesFull: Message[];
37
- fullInputMissTokens: number;
38
- fullInputHitTokens: number;
39
- fullOutputTokens: number;
40
- messagesCompact: Message[];
41
- currentInputMissTokens: number;
42
- currentInputHitTokens: number;
43
- currentOutputTokens: number;
44
- }
45
- }) {
46
- const conn = new MCPConnection();
47
- const mcpServer = new MCPServer(conn);
48
- tools.forEach(tool => {
49
- mcpServer.registerTool(tool);
50
- });
51
- const mcpClient = new MCPClient("DEFAULT_ENV", conn);
52
- super({
53
- aiProvider,
54
- instruction,
55
- mcpClient,
56
- allowedTools: tools,
57
- skills,
58
- maxMemorizeToken,
59
- initData,
60
- });
61
- }
62
- }
63
-
64
- export default SimpleAgent;
@@ -1,2 +0,0 @@
1
- export { ReadFileTool } from "./read-file";
2
- export { WriteFileTool } from "./write-file";
@@ -1 +0,0 @@
1
- export { GetCurrentTimeTool } from "./get-current-time"
@@ -1,3 +0,0 @@
1
- export { FetchTool } from "./fetch";
2
- export { WebSearchTool } from "./web-search";
3
- export { ReadWebPageTool } from "./read-web-page"
package/tsconfig.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // File Layout
4
- "rootDir": "./src",
5
- "outDir": "./dist",
6
- "module": "esnext",
7
- "moduleResolution": "bundler",
8
- "target": "esnext",
9
- "types": [
10
- "node"
11
- ],
12
- "sourceMap": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- // Stricter Typechecking Options
16
- "noUncheckedIndexedAccess": true,
17
- "exactOptionalPropertyTypes": true,
18
- // Style Options
19
- // "noImplicitReturns": true,
20
- // "noImplicitOverride": true,
21
- // "noUnusedLocals": true,
22
- // "noUnusedParameters": true,
23
- // "noFallthroughCasesInSwitch": true,
24
- // "noPropertyAccessFromIndexSignature": true,
25
- // Recommended Options
26
- "strict": true,
27
- "jsx": "react-jsx",
28
- "verbatimModuleSyntax": true,
29
- "isolatedModules": true,
30
- "noUncheckedSideEffectImports": true,
31
- "moduleDetection": "force",
32
- "skipLibCheck": true,
33
- }
34
- }