@honeagents/hone 0.1.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/dist/index.js ADDED
@@ -0,0 +1,570 @@
1
+ 'use strict';
2
+
3
+ // src/agent.ts
4
+ function isAgentOptions(value) {
5
+ return typeof value === "object" && value !== null && "defaultPrompt" in value && "model" in value && "provider" in value;
6
+ }
7
+ function isToolOptions(value) {
8
+ if (typeof value !== "object" || value === null || !("defaultPrompt" in value) || "model" in value || "provider" in value) {
9
+ return false;
10
+ }
11
+ return "_type" in value && value._type === "tool";
12
+ }
13
+ function isTextPromptOptions(value) {
14
+ return typeof value === "object" && value !== null && "defaultPrompt" in value && !("model" in value) && !("provider" in value) && !("_type" in value && value._type === "tool");
15
+ }
16
+ function getAgentNode(id, options, ancestorIds = /* @__PURE__ */ new Set()) {
17
+ const node = getEntityNode(id, "agent", options, ancestorIds);
18
+ return node;
19
+ }
20
+ function getToolNode(id, options, ancestorIds = /* @__PURE__ */ new Set()) {
21
+ const node = getEntityNode(id, "tool", options, ancestorIds);
22
+ return node;
23
+ }
24
+ function getTextPromptNode(id, options, ancestorIds = /* @__PURE__ */ new Set()) {
25
+ const node = getEntityNode(id, "prompt", options, ancestorIds);
26
+ return node;
27
+ }
28
+ function getEntityNode(id, type, options, ancestorIds = /* @__PURE__ */ new Set()) {
29
+ if (options?.params && id in options.params) {
30
+ throw new Error(
31
+ `Self-referencing ${type} detected: ${type} "${id}" cannot reference itself as a parameter`
32
+ );
33
+ }
34
+ if (ancestorIds.has(id)) {
35
+ const path = Array.from(ancestorIds).concat(id).join(" -> ");
36
+ throw new Error(`Circular ${type} reference detected: ${path}`);
37
+ }
38
+ const children = [];
39
+ const newAncestorIds = new Set(ancestorIds).add(id);
40
+ const simpleParams = {};
41
+ for (const [paramId, value] of Object.entries(options?.params || {})) {
42
+ if (typeof value === "string") {
43
+ simpleParams[paramId] = value;
44
+ } else if (isAgentOptions(value)) {
45
+ children.push(getEntityNode(paramId, "agent", value, newAncestorIds));
46
+ } else if (isToolOptions(value)) {
47
+ children.push(getEntityNode(paramId, "tool", value, newAncestorIds));
48
+ } else if (isTextPromptOptions(value)) {
49
+ children.push(getEntityNode(paramId, "prompt", value, newAncestorIds));
50
+ }
51
+ }
52
+ const node = {
53
+ id,
54
+ type,
55
+ majorVersion: options.majorVersion,
56
+ name: options.name,
57
+ params: simpleParams,
58
+ prompt: options.defaultPrompt,
59
+ children
60
+ };
61
+ if (type === "agent" && isAgentOptions(options)) {
62
+ node.model = options.model;
63
+ node.provider = options.provider;
64
+ node.temperature = options.temperature;
65
+ node.maxTokens = options.maxTokens;
66
+ node.topP = options.topP;
67
+ node.frequencyPenalty = options.frequencyPenalty;
68
+ node.presencePenalty = options.presencePenalty;
69
+ node.stopSequences = options.stopSequences;
70
+ node.tools = options.tools;
71
+ }
72
+ return node;
73
+ }
74
+ function evaluateEntity(node) {
75
+ const evaluated = /* @__PURE__ */ new Map();
76
+ function evaluate(node2) {
77
+ if (evaluated.has(node2.id)) {
78
+ return evaluated.get(node2.id);
79
+ }
80
+ const params = { ...node2.params };
81
+ for (const child of node2.children) {
82
+ params[child.id] = evaluate(child);
83
+ }
84
+ validateEntityParams(node2.prompt, params, node2.id, node2.type);
85
+ const result = insertParamsIntoPrompt(node2.prompt, params);
86
+ evaluated.set(node2.id, result);
87
+ return result;
88
+ }
89
+ return evaluate(node);
90
+ }
91
+ function evaluateAgent(node) {
92
+ return evaluateEntity(node);
93
+ }
94
+ function validateEntityParams(prompt, params, nodeId, type) {
95
+ const placeholderRegex = /\{\{(\w+)\}\}/g;
96
+ const matches = prompt.matchAll(placeholderRegex);
97
+ const missingParams = [];
98
+ for (const match of matches) {
99
+ const paramName = match[1];
100
+ if (!(paramName in params)) {
101
+ missingParams.push(paramName);
102
+ }
103
+ }
104
+ if (missingParams.length > 0) {
105
+ const uniqueMissing = [...new Set(missingParams)];
106
+ throw new Error(
107
+ `Missing parameter${uniqueMissing.length > 1 ? "s" : ""} in ${type} "${nodeId}": ${uniqueMissing.join(", ")}`
108
+ );
109
+ }
110
+ }
111
+ function insertParamsIntoPrompt(prompt, params) {
112
+ if (!params) return prompt;
113
+ let result = prompt;
114
+ for (const [key, value] of Object.entries(params)) {
115
+ result = result.replace(new RegExp(`{{${key}}}`, "g"), value);
116
+ }
117
+ return result;
118
+ }
119
+ function traverseEntityNode(node, callback, parentId = null) {
120
+ callback(node, parentId);
121
+ for (const child of node.children) {
122
+ traverseEntityNode(child, callback, node.id);
123
+ }
124
+ }
125
+ function traverseAgentNode(node, callback, parentId = null) {
126
+ traverseEntityNode(
127
+ node,
128
+ callback,
129
+ parentId
130
+ );
131
+ }
132
+ function formatEntityRequest(node) {
133
+ function formatNode(node2) {
134
+ const paramKeys = [
135
+ ...Object.keys(node2.params),
136
+ ...node2.children.map((child) => child.id)
137
+ ];
138
+ return {
139
+ id: node2.id,
140
+ type: node2.type,
141
+ name: node2.name,
142
+ majorVersion: node2.majorVersion,
143
+ prompt: node2.prompt,
144
+ paramKeys,
145
+ childrenIds: node2.children.map((child) => child.id),
146
+ childrenTypes: node2.children.map((child) => child.type),
147
+ // Hyperparameters (only for agents)
148
+ model: node2.model,
149
+ provider: node2.provider,
150
+ temperature: node2.temperature,
151
+ maxTokens: node2.maxTokens,
152
+ topP: node2.topP,
153
+ frequencyPenalty: node2.frequencyPenalty,
154
+ presencePenalty: node2.presencePenalty,
155
+ stopSequences: node2.stopSequences,
156
+ tools: node2.tools
157
+ };
158
+ }
159
+ const map = {};
160
+ traverseEntityNode(node, (currentNode) => {
161
+ map[currentNode.id] = formatNode(currentNode);
162
+ });
163
+ return {
164
+ entities: {
165
+ rootId: node.id,
166
+ rootType: node.type,
167
+ map
168
+ }
169
+ };
170
+ }
171
+ function formatAgentRequest(node) {
172
+ function formatNode(node2) {
173
+ const paramKeys = [
174
+ ...Object.keys(node2.params),
175
+ ...node2.children.map((child) => child.id)
176
+ ];
177
+ return {
178
+ id: node2.id,
179
+ type: node2.type,
180
+ name: node2.name,
181
+ majorVersion: node2.majorVersion,
182
+ prompt: node2.prompt,
183
+ paramKeys,
184
+ childrenIds: node2.children.map((child) => child.id),
185
+ // Hyperparameters
186
+ model: node2.model,
187
+ provider: node2.provider,
188
+ temperature: node2.temperature,
189
+ maxTokens: node2.maxTokens,
190
+ topP: node2.topP,
191
+ frequencyPenalty: node2.frequencyPenalty,
192
+ presencePenalty: node2.presencePenalty,
193
+ stopSequences: node2.stopSequences,
194
+ tools: node2.tools
195
+ };
196
+ }
197
+ const map = {};
198
+ traverseAgentNode(node, (currentNode) => {
199
+ map[currentNode.id] = formatNode(currentNode);
200
+ });
201
+ return {
202
+ agents: {
203
+ rootId: node.id,
204
+ map
205
+ }
206
+ };
207
+ }
208
+ function updateEntityNodes(root, callback) {
209
+ function updateNode(node) {
210
+ const updatedChildren = node.children.map(updateNode);
211
+ const updatedNode = { ...node, children: updatedChildren };
212
+ return callback(updatedNode);
213
+ }
214
+ return updateNode(root);
215
+ }
216
+ function updateAgentNodes(root, callback) {
217
+ return updateEntityNodes(
218
+ root,
219
+ callback
220
+ );
221
+ }
222
+ var getPromptNode = getAgentNode;
223
+ var evaluatePrompt = evaluateAgent;
224
+ var traversePromptNode = traverseAgentNode;
225
+ var formatPromptRequest = formatAgentRequest;
226
+ var updatePromptNodes = updateAgentNodes;
227
+
228
+ // src/client.ts
229
+ var DEFAULT_BASE_URL = "https://honeagents.ai/api";
230
+ var DEFAULT_TIMEOUT = 1e4;
231
+ var Hone = class {
232
+ constructor(config) {
233
+ this.apiKey = config.apiKey;
234
+ this.baseUrl = process.env.HONE_API_URL || config.baseUrl || DEFAULT_BASE_URL;
235
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
236
+ }
237
+ async makeRequest(endpoint, method = "GET", body) {
238
+ const controller = new AbortController();
239
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
240
+ try {
241
+ const url = `${this.baseUrl}${endpoint}`;
242
+ console.log(`Hone API Request: ${method} ${url}`);
243
+ const response = await fetch(url, {
244
+ method,
245
+ headers: {
246
+ "x-api-key": this.apiKey,
247
+ "Content-Type": "application/json",
248
+ "User-Agent": "hone-sdk-typescript/0.1.0"
249
+ },
250
+ body: body ? JSON.stringify(body) : void 0,
251
+ signal: controller.signal
252
+ });
253
+ clearTimeout(timeoutId);
254
+ if (!response.ok) {
255
+ const errorData = await response.json().catch(() => ({}));
256
+ throw new Error(
257
+ `Hone API error (${response.status}): ${errorData.error || errorData.message || response.statusText}`
258
+ );
259
+ }
260
+ return await response.json();
261
+ } catch (error) {
262
+ clearTimeout(timeoutId);
263
+ if (error instanceof Error && error.name === "AbortError") {
264
+ throw new Error(`Hone API request timed out after ${this.timeout}ms`);
265
+ }
266
+ throw error;
267
+ }
268
+ }
269
+ async agent(id, options) {
270
+ const node = getAgentNode(id, options);
271
+ try {
272
+ const formattedRequest = formatEntityRequest(node);
273
+ if (options.extra) {
274
+ const rootEntity = formattedRequest.entities.map[id];
275
+ if (rootEntity) {
276
+ rootEntity.extra = options.extra;
277
+ }
278
+ }
279
+ const response = await this.makeRequest("/sync_entities", "POST", formattedRequest);
280
+ const entityMap = response.entities;
281
+ const updatedAgentNode = updateAgentNodes(node, (agentNode) => {
282
+ const responseItem = entityMap[agentNode.id];
283
+ return {
284
+ ...agentNode,
285
+ prompt: responseItem?.prompt || agentNode.prompt,
286
+ // Update hyperparameters from API response (if present)
287
+ model: responseItem?.model ?? agentNode.model,
288
+ temperature: responseItem?.temperature ?? agentNode.temperature,
289
+ maxTokens: responseItem?.maxTokens ?? agentNode.maxTokens,
290
+ topP: responseItem?.topP ?? agentNode.topP,
291
+ frequencyPenalty: responseItem?.frequencyPenalty ?? agentNode.frequencyPenalty,
292
+ presencePenalty: responseItem?.presencePenalty ?? agentNode.presencePenalty,
293
+ stopSequences: responseItem?.stopSequences ?? agentNode.stopSequences
294
+ };
295
+ });
296
+ const rootResponse = entityMap[id];
297
+ const extraFromResponse = rootResponse?.extra ?? options.extra ?? {};
298
+ return {
299
+ systemPrompt: evaluateAgent(updatedAgentNode),
300
+ model: rootResponse?.model ?? options.model,
301
+ provider: rootResponse?.provider ?? options.provider,
302
+ temperature: rootResponse?.temperature ?? options.temperature ?? null,
303
+ maxTokens: rootResponse?.maxTokens ?? options.maxTokens ?? null,
304
+ topP: rootResponse?.topP ?? options.topP ?? null,
305
+ frequencyPenalty: rootResponse?.frequencyPenalty ?? options.frequencyPenalty ?? null,
306
+ presencePenalty: rootResponse?.presencePenalty ?? options.presencePenalty ?? null,
307
+ stopSequences: rootResponse?.stopSequences ?? options.stopSequences ?? [],
308
+ tools: rootResponse?.tools ?? options.tools ?? [],
309
+ ...extraFromResponse
310
+ };
311
+ } catch (error) {
312
+ console.log("Error fetching agent, using fallback:", error);
313
+ const extraData = options.extra ?? {};
314
+ return {
315
+ systemPrompt: evaluateAgent(node),
316
+ model: options.model,
317
+ provider: options.provider,
318
+ temperature: options.temperature ?? null,
319
+ maxTokens: options.maxTokens ?? null,
320
+ topP: options.topP ?? null,
321
+ frequencyPenalty: options.frequencyPenalty ?? null,
322
+ presencePenalty: options.presencePenalty ?? null,
323
+ stopSequences: options.stopSequences ?? [],
324
+ tools: options.tools ?? [],
325
+ ...extraData
326
+ };
327
+ }
328
+ }
329
+ async tool(id, options) {
330
+ const node = getToolNode(id, options);
331
+ try {
332
+ const formattedRequest = formatEntityRequest(node);
333
+ const response = await this.makeRequest("/sync_entities", "POST", formattedRequest);
334
+ const entityMap = response.entities;
335
+ const updatedToolNode = updateEntityNodes(node, (entityNode) => {
336
+ const responseItem = entityMap[entityNode.id];
337
+ return {
338
+ ...entityNode,
339
+ prompt: responseItem?.prompt || entityNode.prompt
340
+ };
341
+ });
342
+ return {
343
+ prompt: evaluateEntity(updatedToolNode)
344
+ };
345
+ } catch (error) {
346
+ console.log("Error fetching tool, using fallback:", error);
347
+ return {
348
+ prompt: evaluateEntity(node)
349
+ };
350
+ }
351
+ }
352
+ async prompt(id, options) {
353
+ const node = getTextPromptNode(id, options);
354
+ try {
355
+ const formattedRequest = formatEntityRequest(node);
356
+ const response = await this.makeRequest("/sync_entities", "POST", formattedRequest);
357
+ const entityMap = response.entities;
358
+ const updatedPromptNode = updateEntityNodes(node, (entityNode) => {
359
+ const responseItem = entityMap[entityNode.id];
360
+ return {
361
+ ...entityNode,
362
+ prompt: responseItem?.prompt || entityNode.prompt
363
+ };
364
+ });
365
+ return {
366
+ text: evaluateEntity(updatedPromptNode)
367
+ };
368
+ } catch (error) {
369
+ console.log("Error fetching prompt, using fallback:", error);
370
+ return {
371
+ text: evaluateEntity(node)
372
+ };
373
+ }
374
+ }
375
+ async track(id, messages, options) {
376
+ await this.makeRequest("/insert_runs", "POST", {
377
+ id,
378
+ messages,
379
+ sessionId: options.sessionId,
380
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
381
+ });
382
+ }
383
+ };
384
+ function createHoneClient(config) {
385
+ return new Hone(config);
386
+ }
387
+
388
+ // src/providers.ts
389
+ var AIProvider = /* @__PURE__ */ ((AIProvider2) => {
390
+ AIProvider2["OpenAI"] = "openai";
391
+ AIProvider2["Anthropic"] = "anthropic";
392
+ AIProvider2["Google"] = "google";
393
+ AIProvider2["GoogleVertex"] = "google-vertex";
394
+ AIProvider2["Azure"] = "azure";
395
+ AIProvider2["XAI"] = "xai";
396
+ AIProvider2["Mistral"] = "mistral";
397
+ AIProvider2["Cohere"] = "cohere";
398
+ AIProvider2["Groq"] = "groq";
399
+ AIProvider2["TogetherAI"] = "togetherai";
400
+ AIProvider2["Fireworks"] = "fireworks";
401
+ AIProvider2["DeepInfra"] = "deepinfra";
402
+ AIProvider2["DeepSeek"] = "deepseek";
403
+ AIProvider2["Cerebras"] = "cerebras";
404
+ AIProvider2["Perplexity"] = "perplexity";
405
+ AIProvider2["AmazonBedrock"] = "amazon-bedrock";
406
+ AIProvider2["Baseten"] = "baseten";
407
+ return AIProvider2;
408
+ })(AIProvider || {});
409
+ var AI_PROVIDER_VALUES = Object.values(
410
+ AIProvider
411
+ );
412
+ function isValidProvider(value) {
413
+ return AI_PROVIDER_VALUES.includes(value);
414
+ }
415
+ var PROVIDER_DISPLAY_NAMES = {
416
+ openai: "OpenAI",
417
+ anthropic: "Anthropic",
418
+ google: "Google AI",
419
+ "google-vertex": "Google Vertex AI",
420
+ azure: "Azure OpenAI",
421
+ xai: "xAI",
422
+ mistral: "Mistral AI",
423
+ cohere: "Cohere",
424
+ groq: "Groq",
425
+ togetherai: "Together.ai",
426
+ fireworks: "Fireworks",
427
+ deepinfra: "DeepInfra",
428
+ deepseek: "DeepSeek",
429
+ cerebras: "Cerebras",
430
+ perplexity: "Perplexity",
431
+ "amazon-bedrock": "Amazon Bedrock",
432
+ baseten: "Baseten"
433
+ };
434
+ function getProviderDisplayName(provider) {
435
+ return PROVIDER_DISPLAY_NAMES[provider] || provider;
436
+ }
437
+
438
+ // src/tools.ts
439
+ function createToolCallMessage(toolCalls, content = "") {
440
+ return {
441
+ role: "assistant",
442
+ content,
443
+ tool_calls: toolCalls
444
+ };
445
+ }
446
+ function createToolResultMessage(toolCallId, result) {
447
+ const content = typeof result === "string" ? result : JSON.stringify(result);
448
+ return {
449
+ role: "tool",
450
+ content,
451
+ tool_call_id: toolCallId
452
+ };
453
+ }
454
+ function extractOpenAIMessages(response) {
455
+ const messages = [];
456
+ for (const choice of response.choices) {
457
+ const msg = choice.message;
458
+ const message = {
459
+ role: msg.role,
460
+ content: msg.content ?? ""
461
+ };
462
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
463
+ message.tool_calls = msg.tool_calls.map((tc) => ({
464
+ id: tc.id,
465
+ name: tc.function.name,
466
+ arguments: tc.function.arguments
467
+ }));
468
+ }
469
+ messages.push(message);
470
+ }
471
+ return messages;
472
+ }
473
+ function extractAnthropicMessages(response) {
474
+ const messages = [];
475
+ const textBlocks = response.content.filter(
476
+ (block) => block.type === "text"
477
+ );
478
+ const toolUseBlocks = response.content.filter(
479
+ (block) => block.type === "tool_use"
480
+ );
481
+ const textContent = textBlocks.map((b) => b.text).join("\n");
482
+ if (toolUseBlocks.length > 0) {
483
+ const toolCalls = toolUseBlocks.map((block) => ({
484
+ id: block.id,
485
+ name: block.name,
486
+ arguments: JSON.stringify(block.input)
487
+ }));
488
+ messages.push({
489
+ role: "assistant",
490
+ content: textContent,
491
+ tool_calls: toolCalls
492
+ });
493
+ } else {
494
+ messages.push({
495
+ role: response.role,
496
+ content: textContent
497
+ });
498
+ }
499
+ return messages;
500
+ }
501
+ function extractGeminiMessages(response) {
502
+ const messages = [];
503
+ if (!response.candidates || response.candidates.length === 0) {
504
+ return messages;
505
+ }
506
+ for (const candidate of response.candidates) {
507
+ if (!candidate.content?.parts) continue;
508
+ const textParts = [];
509
+ const functionCalls = [];
510
+ for (const part of candidate.content.parts) {
511
+ if ("text" in part) {
512
+ textParts.push(part.text);
513
+ } else if ("functionCall" in part) {
514
+ functionCalls.push(part.functionCall);
515
+ }
516
+ }
517
+ const textContent = textParts.join("\n");
518
+ if (functionCalls.length > 0) {
519
+ const toolCalls = functionCalls.map((fc, index) => ({
520
+ id: `gemini_${fc.name}_${index}_${Date.now()}`,
521
+ name: fc.name,
522
+ arguments: JSON.stringify(fc.args)
523
+ }));
524
+ messages.push({
525
+ role: "assistant",
526
+ content: textContent,
527
+ tool_calls: toolCalls
528
+ });
529
+ } else if (textContent) {
530
+ messages.push({
531
+ role: candidate.content.role === "model" ? "assistant" : candidate.content.role || "assistant",
532
+ content: textContent
533
+ });
534
+ }
535
+ }
536
+ return messages;
537
+ }
538
+ var toolResult = createToolResultMessage;
539
+ var fromOpenAI = extractOpenAIMessages;
540
+ var fromAnthropic = extractAnthropicMessages;
541
+ var fromGemini = extractGeminiMessages;
542
+
543
+ exports.AIProvider = AIProvider;
544
+ exports.AI_PROVIDER_VALUES = AI_PROVIDER_VALUES;
545
+ exports.Hone = Hone;
546
+ exports.createHoneClient = createHoneClient;
547
+ exports.createToolCallMessage = createToolCallMessage;
548
+ exports.createToolResultMessage = createToolResultMessage;
549
+ exports.evaluateAgent = evaluateAgent;
550
+ exports.evaluatePrompt = evaluatePrompt;
551
+ exports.extractAnthropicMessages = extractAnthropicMessages;
552
+ exports.extractGeminiMessages = extractGeminiMessages;
553
+ exports.extractOpenAIMessages = extractOpenAIMessages;
554
+ exports.formatAgentRequest = formatAgentRequest;
555
+ exports.formatPromptRequest = formatPromptRequest;
556
+ exports.fromAnthropic = fromAnthropic;
557
+ exports.fromGemini = fromGemini;
558
+ exports.fromOpenAI = fromOpenAI;
559
+ exports.getAgentNode = getAgentNode;
560
+ exports.getPromptNode = getPromptNode;
561
+ exports.getProviderDisplayName = getProviderDisplayName;
562
+ exports.insertParamsIntoPrompt = insertParamsIntoPrompt;
563
+ exports.isValidProvider = isValidProvider;
564
+ exports.toolResult = toolResult;
565
+ exports.traverseAgentNode = traverseAgentNode;
566
+ exports.traversePromptNode = traversePromptNode;
567
+ exports.updateAgentNodes = updateAgentNodes;
568
+ exports.updatePromptNodes = updatePromptNodes;
569
+ //# sourceMappingURL=index.js.map
570
+ //# sourceMappingURL=index.js.map