@journeyrewards/hive-vercel 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +214 -0
- package/dist/index.d.mts +114 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.js +451 -0
- package/dist/index.mjs +429 -0
- package/dist/server.d.mts +38 -0
- package/dist/server.d.ts +38 -0
- package/dist/server.js +168 -0
- package/dist/server.mjs +141 -0
- package/package.json +55 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
// src/hooks.ts
|
|
2
|
+
import {
|
|
3
|
+
useState,
|
|
4
|
+
useEffect,
|
|
5
|
+
useCallback,
|
|
6
|
+
useRef,
|
|
7
|
+
createContext,
|
|
8
|
+
useContext,
|
|
9
|
+
createElement
|
|
10
|
+
} from "react";
|
|
11
|
+
function createClient(config) {
|
|
12
|
+
const baseUrl = config.baseUrl || "https://journey-hive.replit.app";
|
|
13
|
+
const headers = {
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
16
|
+
};
|
|
17
|
+
async function request(method, path, body) {
|
|
18
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
19
|
+
method,
|
|
20
|
+
headers,
|
|
21
|
+
body: body ? JSON.stringify(body) : void 0
|
|
22
|
+
});
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const err = await res.json().catch(() => ({}));
|
|
25
|
+
throw new Error(err?.error?.message || `Request failed with status ${res.status}`);
|
|
26
|
+
}
|
|
27
|
+
return res.json();
|
|
28
|
+
}
|
|
29
|
+
async function* streamRequest(path, body) {
|
|
30
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers,
|
|
33
|
+
body: JSON.stringify(body)
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const err = await res.json().catch(() => ({}));
|
|
37
|
+
throw new Error(err?.error?.message || `Request failed with status ${res.status}`);
|
|
38
|
+
}
|
|
39
|
+
const reader = res.body?.getReader();
|
|
40
|
+
if (!reader) throw new Error("No response body");
|
|
41
|
+
const decoder = new TextDecoder();
|
|
42
|
+
let buffer = "";
|
|
43
|
+
while (true) {
|
|
44
|
+
const { done, value } = await reader.read();
|
|
45
|
+
if (done) break;
|
|
46
|
+
buffer += decoder.decode(value, { stream: true });
|
|
47
|
+
const lines = buffer.split("\n");
|
|
48
|
+
buffer = lines.pop() || "";
|
|
49
|
+
let currentEvent = "";
|
|
50
|
+
for (const line of lines) {
|
|
51
|
+
if (line.startsWith("event: ")) {
|
|
52
|
+
currentEvent = line.slice(7).trim();
|
|
53
|
+
} else if (line.startsWith("data: ")) {
|
|
54
|
+
const dataStr = line.slice(6);
|
|
55
|
+
try {
|
|
56
|
+
const data = JSON.parse(dataStr);
|
|
57
|
+
yield { event: currentEvent, data };
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
config,
|
|
66
|
+
responses: {
|
|
67
|
+
async create(params) {
|
|
68
|
+
if (params.stream) {
|
|
69
|
+
return streamRequest("/v1/responses", params);
|
|
70
|
+
}
|
|
71
|
+
return request("POST", "/v1/responses", params);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
conversations: {
|
|
75
|
+
get: (id) => request("GET", `/v1/conversations/${id}`),
|
|
76
|
+
messages: (id) => request("GET", `/v1/conversations/${id}/messages`)
|
|
77
|
+
},
|
|
78
|
+
agents: {
|
|
79
|
+
get: (id) => request("GET", `/v1/agents/${id}`),
|
|
80
|
+
list: () => request("GET", "/v1/agents"),
|
|
81
|
+
update: (id, params) => request("PATCH", `/v1/agents/${id}`, params)
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
var JourneyHiveContext = createContext(null);
|
|
86
|
+
function JourneyHiveProvider({ apiKey, baseUrl, children }) {
|
|
87
|
+
const clientRef = useRef(null);
|
|
88
|
+
if (!clientRef.current || clientRef.current.config.apiKey !== apiKey || clientRef.current.config.baseUrl !== baseUrl) {
|
|
89
|
+
clientRef.current = createClient({ apiKey, baseUrl });
|
|
90
|
+
}
|
|
91
|
+
return createElement(JourneyHiveContext.Provider, { value: clientRef.current }, children);
|
|
92
|
+
}
|
|
93
|
+
function useJourneyHive() {
|
|
94
|
+
const client = useContext(JourneyHiveContext);
|
|
95
|
+
if (!client) {
|
|
96
|
+
throw new Error("useJourneyHive must be used within a JourneyHiveProvider");
|
|
97
|
+
}
|
|
98
|
+
return client;
|
|
99
|
+
}
|
|
100
|
+
function useResponse(params) {
|
|
101
|
+
const client = useJourneyHive();
|
|
102
|
+
const [data, setData] = useState(null);
|
|
103
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
104
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
105
|
+
const [streamedText, setStreamedText] = useState("");
|
|
106
|
+
const [error, setError] = useState(null);
|
|
107
|
+
const send = useCallback(
|
|
108
|
+
async (input) => {
|
|
109
|
+
setIsLoading(true);
|
|
110
|
+
setIsStreaming(false);
|
|
111
|
+
setStreamedText("");
|
|
112
|
+
setError(null);
|
|
113
|
+
setData(null);
|
|
114
|
+
try {
|
|
115
|
+
const createParams = {
|
|
116
|
+
agent_id: params?.agent_id || "",
|
|
117
|
+
input,
|
|
118
|
+
stream: true,
|
|
119
|
+
...params
|
|
120
|
+
};
|
|
121
|
+
const result = await client.responses.create(createParams);
|
|
122
|
+
if (Symbol.asyncIterator in result) {
|
|
123
|
+
setIsStreaming(true);
|
|
124
|
+
let accumulated = "";
|
|
125
|
+
for await (const { event, data: eventData } of result) {
|
|
126
|
+
if (event === "response.output_text.delta") {
|
|
127
|
+
accumulated += eventData.delta;
|
|
128
|
+
setStreamedText(accumulated);
|
|
129
|
+
} else if (event === "response.completed") {
|
|
130
|
+
setData(eventData);
|
|
131
|
+
} else if (event === "response.failed") {
|
|
132
|
+
throw new Error(eventData.error?.message || "Response failed");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
setIsStreaming(false);
|
|
136
|
+
} else {
|
|
137
|
+
setData(result);
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
141
|
+
} finally {
|
|
142
|
+
setIsLoading(false);
|
|
143
|
+
setIsStreaming(false);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
[client, params]
|
|
147
|
+
);
|
|
148
|
+
return { data, isLoading, isStreaming, streamedText, error, send };
|
|
149
|
+
}
|
|
150
|
+
function useConversation(conversationId) {
|
|
151
|
+
const client = useJourneyHive();
|
|
152
|
+
const [conversation, setConversation] = useState(null);
|
|
153
|
+
const [messages, setMessages] = useState([]);
|
|
154
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
155
|
+
const [error, setError] = useState(null);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (!conversationId) return;
|
|
158
|
+
setIsLoading(true);
|
|
159
|
+
Promise.all([
|
|
160
|
+
client.conversations.get(conversationId),
|
|
161
|
+
client.conversations.messages(conversationId)
|
|
162
|
+
]).then(([conv, msgResult]) => {
|
|
163
|
+
setConversation(conv);
|
|
164
|
+
setMessages(msgResult.data);
|
|
165
|
+
}).catch((err) => setError(err instanceof Error ? err : new Error(String(err)))).finally(() => setIsLoading(false));
|
|
166
|
+
}, [conversationId, client]);
|
|
167
|
+
const sendMessage = useCallback(
|
|
168
|
+
async (input) => {
|
|
169
|
+
if (!conversation) return;
|
|
170
|
+
const optimisticMsg = {
|
|
171
|
+
id: `temp_${Date.now()}`,
|
|
172
|
+
object: "message",
|
|
173
|
+
role: "user",
|
|
174
|
+
content: [{ type: "output_text", text: input }],
|
|
175
|
+
created_at: Math.floor(Date.now() / 1e3)
|
|
176
|
+
};
|
|
177
|
+
setMessages((prev) => [...prev, optimisticMsg]);
|
|
178
|
+
try {
|
|
179
|
+
const result = await client.responses.create({
|
|
180
|
+
agent_id: conversation.agent_id,
|
|
181
|
+
input,
|
|
182
|
+
conversation_id: conversationId
|
|
183
|
+
});
|
|
184
|
+
const response = result;
|
|
185
|
+
if (response.output) {
|
|
186
|
+
const assistantMsg = {
|
|
187
|
+
id: response.output[0]?.id || `msg_${Date.now()}`,
|
|
188
|
+
object: "message",
|
|
189
|
+
role: "assistant",
|
|
190
|
+
content: response.output[0]?.content || [],
|
|
191
|
+
created_at: response.created_at
|
|
192
|
+
};
|
|
193
|
+
setMessages((prev) => [...prev, assistantMsg]);
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
197
|
+
setMessages((prev) => prev.filter((m) => m.id !== optimisticMsg.id));
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
[client, conversation, conversationId]
|
|
201
|
+
);
|
|
202
|
+
return { conversation, messages, isLoading, error, sendMessage };
|
|
203
|
+
}
|
|
204
|
+
function useAgent(agentId) {
|
|
205
|
+
const client = useJourneyHive();
|
|
206
|
+
const [agent, setAgent] = useState(null);
|
|
207
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
208
|
+
const [error, setError] = useState(null);
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
if (!agentId) return;
|
|
211
|
+
setIsLoading(true);
|
|
212
|
+
client.agents.get(agentId).then(setAgent).catch((err) => setError(err instanceof Error ? err : new Error(String(err)))).finally(() => setIsLoading(false));
|
|
213
|
+
}, [agentId, client]);
|
|
214
|
+
const update = useCallback(
|
|
215
|
+
async (params) => {
|
|
216
|
+
try {
|
|
217
|
+
const updated = await client.agents.update(agentId, params);
|
|
218
|
+
setAgent(updated);
|
|
219
|
+
} catch (err) {
|
|
220
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
[client, agentId]
|
|
224
|
+
);
|
|
225
|
+
return { agent, isLoading, error, update };
|
|
226
|
+
}
|
|
227
|
+
function useAgents() {
|
|
228
|
+
const client = useJourneyHive();
|
|
229
|
+
const [agents, setAgents] = useState([]);
|
|
230
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
231
|
+
const [error, setError] = useState(null);
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
setIsLoading(true);
|
|
234
|
+
client.agents.list().then((result) => setAgents(result.data)).catch((err) => setError(err instanceof Error ? err : new Error(String(err)))).finally(() => setIsLoading(false));
|
|
235
|
+
}, [client]);
|
|
236
|
+
return { agents, isLoading, error };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// src/components.tsx
|
|
240
|
+
import {
|
|
241
|
+
useState as useState2,
|
|
242
|
+
useEffect as useEffect2,
|
|
243
|
+
useRef as useRef2,
|
|
244
|
+
useCallback as useCallback2,
|
|
245
|
+
createElement as createElement2
|
|
246
|
+
} from "react";
|
|
247
|
+
function ResponseStream({ agentId, input, onComplete, className }) {
|
|
248
|
+
const { streamedText, isStreaming, isLoading, error, send } = useResponse({ agent_id: agentId });
|
|
249
|
+
const sentRef = useRef2(false);
|
|
250
|
+
useEffect2(() => {
|
|
251
|
+
if (input && !sentRef.current) {
|
|
252
|
+
sentRef.current = true;
|
|
253
|
+
send(input);
|
|
254
|
+
}
|
|
255
|
+
}, [input, send]);
|
|
256
|
+
useEffect2(() => {
|
|
257
|
+
if (!isStreaming && !isLoading && streamedText && onComplete) {
|
|
258
|
+
onComplete(streamedText);
|
|
259
|
+
}
|
|
260
|
+
}, [isStreaming, isLoading, streamedText, onComplete]);
|
|
261
|
+
if (error) {
|
|
262
|
+
return createElement2("div", { className: `jh-error ${className || ""}`.trim() }, error.message);
|
|
263
|
+
}
|
|
264
|
+
return createElement2(
|
|
265
|
+
"div",
|
|
266
|
+
{ className: `jh-response-stream ${className || ""}`.trim() },
|
|
267
|
+
createElement2("div", { className: "jh-stream-content" }, streamedText || ""),
|
|
268
|
+
isStreaming ? createElement2(
|
|
269
|
+
"span",
|
|
270
|
+
{ className: "jh-typing-indicator" },
|
|
271
|
+
createElement2("span", { className: "jh-dot" }),
|
|
272
|
+
createElement2("span", { className: "jh-dot" }),
|
|
273
|
+
createElement2("span", { className: "jh-dot" })
|
|
274
|
+
) : null
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
function MessageBubble({ role, content, timestamp }) {
|
|
278
|
+
const isUser = role === "user";
|
|
279
|
+
const time = timestamp ? new Date(timestamp * 1e3).toLocaleTimeString() : null;
|
|
280
|
+
return createElement2(
|
|
281
|
+
"div",
|
|
282
|
+
{
|
|
283
|
+
className: `jh-message-bubble jh-message-${isUser ? "user" : "assistant"}`,
|
|
284
|
+
style: {
|
|
285
|
+
display: "flex",
|
|
286
|
+
flexDirection: "column",
|
|
287
|
+
alignItems: isUser ? "flex-end" : "flex-start",
|
|
288
|
+
marginBottom: "8px"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
createElement2(
|
|
292
|
+
"div",
|
|
293
|
+
{
|
|
294
|
+
className: "jh-message-content",
|
|
295
|
+
style: {
|
|
296
|
+
padding: "8px 12px",
|
|
297
|
+
borderRadius: "8px",
|
|
298
|
+
maxWidth: "80%"
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
content
|
|
302
|
+
),
|
|
303
|
+
time ? createElement2(
|
|
304
|
+
"span",
|
|
305
|
+
{
|
|
306
|
+
className: "jh-message-time",
|
|
307
|
+
style: { fontSize: "0.75em", opacity: 0.6, marginTop: "2px" }
|
|
308
|
+
},
|
|
309
|
+
time
|
|
310
|
+
) : null
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
function ConversationView({ conversationId, agentId, className }) {
|
|
314
|
+
const { messages, isLoading, error, sendMessage } = useConversation(conversationId);
|
|
315
|
+
const [inputValue, setInputValue] = useState2("");
|
|
316
|
+
const messagesEndRef = useRef2(null);
|
|
317
|
+
useEffect2(() => {
|
|
318
|
+
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
319
|
+
}, [messages]);
|
|
320
|
+
const handleSubmit = useCallback2(
|
|
321
|
+
(e) => {
|
|
322
|
+
e.preventDefault();
|
|
323
|
+
if (!inputValue.trim()) return;
|
|
324
|
+
sendMessage(inputValue.trim());
|
|
325
|
+
setInputValue("");
|
|
326
|
+
},
|
|
327
|
+
[inputValue, sendMessage]
|
|
328
|
+
);
|
|
329
|
+
if (error) {
|
|
330
|
+
return createElement2("div", { className: `jh-error ${className || ""}`.trim() }, error.message);
|
|
331
|
+
}
|
|
332
|
+
return createElement2(
|
|
333
|
+
"div",
|
|
334
|
+
{
|
|
335
|
+
className: `jh-conversation-view ${className || ""}`.trim(),
|
|
336
|
+
style: { display: "flex", flexDirection: "column", height: "100%" }
|
|
337
|
+
},
|
|
338
|
+
createElement2(
|
|
339
|
+
"div",
|
|
340
|
+
{
|
|
341
|
+
className: "jh-messages",
|
|
342
|
+
style: { flex: 1, overflowY: "auto", padding: "16px" }
|
|
343
|
+
},
|
|
344
|
+
isLoading ? createElement2("div", { className: "jh-loading" }, "Loading messages...") : messages.map((msg) => {
|
|
345
|
+
const text = msg.content?.map((c) => c.type === "output_text" ? c.text : "").join("") || "";
|
|
346
|
+
return createElement2(MessageBubble, {
|
|
347
|
+
key: msg.id,
|
|
348
|
+
role: msg.role,
|
|
349
|
+
content: text,
|
|
350
|
+
timestamp: msg.created_at
|
|
351
|
+
});
|
|
352
|
+
}),
|
|
353
|
+
createElement2("div", { ref: messagesEndRef })
|
|
354
|
+
),
|
|
355
|
+
createElement2(
|
|
356
|
+
"form",
|
|
357
|
+
{
|
|
358
|
+
onSubmit: handleSubmit,
|
|
359
|
+
className: "jh-input-form",
|
|
360
|
+
style: { display: "flex", padding: "8px", gap: "8px" }
|
|
361
|
+
},
|
|
362
|
+
createElement2("input", {
|
|
363
|
+
type: "text",
|
|
364
|
+
value: inputValue,
|
|
365
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
366
|
+
placeholder: "Type a message...",
|
|
367
|
+
className: "jh-input",
|
|
368
|
+
style: { flex: 1, padding: "8px", borderRadius: "4px", border: "1px solid #ccc" }
|
|
369
|
+
}),
|
|
370
|
+
createElement2(
|
|
371
|
+
"button",
|
|
372
|
+
{
|
|
373
|
+
type: "submit",
|
|
374
|
+
className: "jh-send-button",
|
|
375
|
+
style: { padding: "8px 16px", borderRadius: "4px" }
|
|
376
|
+
},
|
|
377
|
+
"Send"
|
|
378
|
+
)
|
|
379
|
+
)
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
function AgentStatus({ agent }) {
|
|
383
|
+
const statusColors = {
|
|
384
|
+
active: "#22c55e",
|
|
385
|
+
sleeping: "#eab308",
|
|
386
|
+
provisioning: "#3b82f6",
|
|
387
|
+
error: "#ef4444",
|
|
388
|
+
stopped: "#6b7280"
|
|
389
|
+
};
|
|
390
|
+
const color = statusColors[agent.status] || "#6b7280";
|
|
391
|
+
return createElement2(
|
|
392
|
+
"span",
|
|
393
|
+
{
|
|
394
|
+
className: "jh-agent-status",
|
|
395
|
+
style: {
|
|
396
|
+
display: "inline-flex",
|
|
397
|
+
alignItems: "center",
|
|
398
|
+
gap: "6px",
|
|
399
|
+
padding: "2px 8px",
|
|
400
|
+
borderRadius: "9999px",
|
|
401
|
+
fontSize: "0.75em",
|
|
402
|
+
fontWeight: 500,
|
|
403
|
+
border: `1px solid ${color}`,
|
|
404
|
+
color
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
createElement2("span", {
|
|
408
|
+
style: {
|
|
409
|
+
width: "6px",
|
|
410
|
+
height: "6px",
|
|
411
|
+
borderRadius: "50%",
|
|
412
|
+
backgroundColor: color
|
|
413
|
+
}
|
|
414
|
+
}),
|
|
415
|
+
agent.status
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
export {
|
|
419
|
+
AgentStatus,
|
|
420
|
+
ConversationView,
|
|
421
|
+
JourneyHiveProvider,
|
|
422
|
+
MessageBubble,
|
|
423
|
+
ResponseStream,
|
|
424
|
+
useAgent,
|
|
425
|
+
useAgents,
|
|
426
|
+
useConversation,
|
|
427
|
+
useJourneyHive,
|
|
428
|
+
useResponse
|
|
429
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
|
|
3
|
+
declare function verifyApiKey(key: string): boolean;
|
|
4
|
+
interface JourneyHiveHandlerConfig {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
allowedAgentIds?: string[];
|
|
8
|
+
}
|
|
9
|
+
declare function createJourneyHiveHandler(config: JourneyHiveHandlerConfig): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
10
|
+
declare class JourneyHiveServerClient {
|
|
11
|
+
private baseUrl;
|
|
12
|
+
private headers;
|
|
13
|
+
constructor(config: {
|
|
14
|
+
apiKey: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
});
|
|
17
|
+
private request;
|
|
18
|
+
createResponse(params: {
|
|
19
|
+
agent_id: string;
|
|
20
|
+
input: string;
|
|
21
|
+
conversation_id?: string;
|
|
22
|
+
instructions?: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}): Promise<unknown>;
|
|
25
|
+
getAgent(agentId: string): Promise<unknown>;
|
|
26
|
+
listAgents(): Promise<unknown>;
|
|
27
|
+
updateAgent(agentId: string, params: any): Promise<unknown>;
|
|
28
|
+
createConversation(params: {
|
|
29
|
+
agent_id: string;
|
|
30
|
+
external_user_id?: string;
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
getConversation(conversationId: string): Promise<unknown>;
|
|
34
|
+
getMessages(conversationId: string): Promise<unknown>;
|
|
35
|
+
getUsage(days?: number): Promise<unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { JourneyHiveServerClient, createJourneyHiveHandler, verifyApiKey };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
+
|
|
3
|
+
declare function verifyApiKey(key: string): boolean;
|
|
4
|
+
interface JourneyHiveHandlerConfig {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
allowedAgentIds?: string[];
|
|
8
|
+
}
|
|
9
|
+
declare function createJourneyHiveHandler(config: JourneyHiveHandlerConfig): (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
10
|
+
declare class JourneyHiveServerClient {
|
|
11
|
+
private baseUrl;
|
|
12
|
+
private headers;
|
|
13
|
+
constructor(config: {
|
|
14
|
+
apiKey: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
});
|
|
17
|
+
private request;
|
|
18
|
+
createResponse(params: {
|
|
19
|
+
agent_id: string;
|
|
20
|
+
input: string;
|
|
21
|
+
conversation_id?: string;
|
|
22
|
+
instructions?: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}): Promise<unknown>;
|
|
25
|
+
getAgent(agentId: string): Promise<unknown>;
|
|
26
|
+
listAgents(): Promise<unknown>;
|
|
27
|
+
updateAgent(agentId: string, params: any): Promise<unknown>;
|
|
28
|
+
createConversation(params: {
|
|
29
|
+
agent_id: string;
|
|
30
|
+
external_user_id?: string;
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
getConversation(conversationId: string): Promise<unknown>;
|
|
34
|
+
getMessages(conversationId: string): Promise<unknown>;
|
|
35
|
+
getUsage(days?: number): Promise<unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { JourneyHiveServerClient, createJourneyHiveHandler, verifyApiKey };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
JourneyHiveServerClient: () => JourneyHiveServerClient,
|
|
24
|
+
createJourneyHiveHandler: () => createJourneyHiveHandler,
|
|
25
|
+
verifyApiKey: () => verifyApiKey
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(server_exports);
|
|
28
|
+
function verifyApiKey(key) {
|
|
29
|
+
return typeof key === "string" && (key.startsWith("jh_live_") || key.startsWith("jh_test_")) && key.length > 16;
|
|
30
|
+
}
|
|
31
|
+
function createJourneyHiveHandler(config) {
|
|
32
|
+
const baseUrl = config.baseUrl || "https://journey-hive.replit.app";
|
|
33
|
+
const headers = {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
36
|
+
};
|
|
37
|
+
return async function handler(req, res) {
|
|
38
|
+
if (req.method !== "POST") {
|
|
39
|
+
res.status(405).json({ error: { message: "Method not allowed" } });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const { action, ...params } = req.body;
|
|
43
|
+
if (config.allowedAgentIds && params.agent_id) {
|
|
44
|
+
if (!config.allowedAgentIds.includes(params.agent_id)) {
|
|
45
|
+
res.status(403).json({ error: { message: "Agent not allowed" } });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let path;
|
|
50
|
+
let method = "POST";
|
|
51
|
+
switch (action) {
|
|
52
|
+
case "create_response":
|
|
53
|
+
path = "/v1/responses";
|
|
54
|
+
break;
|
|
55
|
+
case "list_agents":
|
|
56
|
+
path = "/v1/agents";
|
|
57
|
+
method = "GET";
|
|
58
|
+
break;
|
|
59
|
+
case "get_agent":
|
|
60
|
+
path = `/v1/agents/${params.agent_id}`;
|
|
61
|
+
method = "GET";
|
|
62
|
+
break;
|
|
63
|
+
case "create_conversation":
|
|
64
|
+
path = "/v1/conversations";
|
|
65
|
+
break;
|
|
66
|
+
case "get_conversation":
|
|
67
|
+
path = `/v1/conversations/${params.conversation_id}`;
|
|
68
|
+
method = "GET";
|
|
69
|
+
break;
|
|
70
|
+
case "get_messages":
|
|
71
|
+
path = `/v1/conversations/${params.conversation_id}/messages`;
|
|
72
|
+
method = "GET";
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
res.status(400).json({ error: { message: `Unknown action: ${action}` } });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const fetchOptions = {
|
|
80
|
+
method,
|
|
81
|
+
headers
|
|
82
|
+
};
|
|
83
|
+
if (method === "POST") {
|
|
84
|
+
const { action: _action, ...bodyParams } = params;
|
|
85
|
+
fetchOptions.body = JSON.stringify(bodyParams);
|
|
86
|
+
}
|
|
87
|
+
const response = await fetch(`${baseUrl}${path}`, fetchOptions);
|
|
88
|
+
if (params.stream && action === "create_response") {
|
|
89
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
90
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
91
|
+
res.setHeader("Connection", "keep-alive");
|
|
92
|
+
const reader = response.body?.getReader();
|
|
93
|
+
if (!reader) {
|
|
94
|
+
res.status(500).json({ error: { message: "No response body" } });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const decoder = new TextDecoder();
|
|
98
|
+
try {
|
|
99
|
+
while (true) {
|
|
100
|
+
const { done, value } = await reader.read();
|
|
101
|
+
if (done) break;
|
|
102
|
+
res.write(decoder.decode(value, { stream: true }));
|
|
103
|
+
}
|
|
104
|
+
} finally {
|
|
105
|
+
res.end();
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const data = await response.json();
|
|
110
|
+
res.status(response.status).json(data);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
const message = err instanceof Error ? err.message : "Internal server error";
|
|
113
|
+
res.status(500).json({ error: { message } });
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
var JourneyHiveServerClient = class {
|
|
118
|
+
constructor(config) {
|
|
119
|
+
this.baseUrl = config.baseUrl || "https://journey-hive.replit.app";
|
|
120
|
+
this.headers = {
|
|
121
|
+
"Content-Type": "application/json",
|
|
122
|
+
Authorization: `Bearer ${config.apiKey}`
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async request(method, path, body) {
|
|
126
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
127
|
+
method,
|
|
128
|
+
headers: this.headers,
|
|
129
|
+
body: body ? JSON.stringify(body) : void 0
|
|
130
|
+
});
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
const err = await res.json().catch(() => ({}));
|
|
133
|
+
throw new Error(err?.error?.message || `Request failed with status ${res.status}`);
|
|
134
|
+
}
|
|
135
|
+
return res.json();
|
|
136
|
+
}
|
|
137
|
+
async createResponse(params) {
|
|
138
|
+
return this.request("POST", "/v1/responses", params);
|
|
139
|
+
}
|
|
140
|
+
async getAgent(agentId) {
|
|
141
|
+
return this.request("GET", `/v1/agents/${agentId}`);
|
|
142
|
+
}
|
|
143
|
+
async listAgents() {
|
|
144
|
+
return this.request("GET", "/v1/agents");
|
|
145
|
+
}
|
|
146
|
+
async updateAgent(agentId, params) {
|
|
147
|
+
return this.request("PATCH", `/v1/agents/${agentId}`, params);
|
|
148
|
+
}
|
|
149
|
+
async createConversation(params) {
|
|
150
|
+
return this.request("POST", "/v1/conversations", params);
|
|
151
|
+
}
|
|
152
|
+
async getConversation(conversationId) {
|
|
153
|
+
return this.request("GET", `/v1/conversations/${conversationId}`);
|
|
154
|
+
}
|
|
155
|
+
async getMessages(conversationId) {
|
|
156
|
+
return this.request("GET", `/v1/conversations/${conversationId}/messages`);
|
|
157
|
+
}
|
|
158
|
+
async getUsage(days) {
|
|
159
|
+
const query = days ? `?days=${days}` : "";
|
|
160
|
+
return this.request("GET", `/v1/usage${query}`);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
164
|
+
0 && (module.exports = {
|
|
165
|
+
JourneyHiveServerClient,
|
|
166
|
+
createJourneyHiveHandler,
|
|
167
|
+
verifyApiKey
|
|
168
|
+
});
|