UNPKG

@hashgraphonline/conversational-agent

Version:

Hashgraph Online conversational AI agent implementing HCS-10 communication, HCS-2 registries, and content inscription on Hedera. https://hol.org

173 lines (151 loc) 4.69 kB
import { Bee, PostageBatch } from "@ethersphere/bee-js"; import { PostageBatchCurated, PostageBatchSummary } from "./model"; import { SwarmConfig } from "./config"; import { DEFAULT_GATEWAY_BATCH_ID, NOT_FOUND_STATUS } from "./constants"; export interface ToolResponse { [x: string]: unknown; tools?: { [x: string]: unknown; name: string /* other properties */ }; _meta?: { [x: string]: unknown }; } export function hexToBytes(hex: string): Uint8Array { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16); } return bytes; } export const getBatchSummary = ( batch: PostageBatch | PostageBatchCurated ): PostageBatchSummary => ({ stampID: typeof batch.batchID === "string" ? batch.batchID : batch.batchID.toHex(), usage: batch.usageText, capacity: `${batch.remainingSize.toFormattedString()} remaining out of ${batch.size.toFormattedString()}`, immutable: batch.immutableFlag, ttl: `${batch.duration.represent()} (${batch.duration .toEndDate() .toDateString()})`, }); export const getResponseWithStructuredContent = <T>(data: T): ToolResponse => ({ content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], structuredContent: data, }); export const errorHasStatus = (error: unknown, status: number) => { if (typeof error === "object" && error !== null && "status" in error) { return error.status === status; } return false; }; export const getErrorMessage = (error: unknown) => { if ( typeof error === "object" && error !== null && "responseBody" in error && typeof error.responseBody === "object" && error.responseBody !== null && "message" in error.responseBody ) { return error.responseBody.message as string; } return ""; }; export const runWithTimeout = async <T>( asyncAction: Promise<T>, timeout: number ): Promise<[unknown, boolean]> => { let hasTimedOut = false; const timeoutPromise = new Promise((resolve) => setTimeout(() => { hasTimedOut = true; resolve(true); }, timeout) ); const response = await Promise.race([asyncAction, timeoutPromise]); return [response, hasTimedOut]; }; export const getUploadPostageBatchId = async ( argsPostageBatchId: string | undefined, bee: Bee, config: SwarmConfig, ): Promise<string> => { let postageBatchId = argsPostageBatchId; const autoAssignStamp = config.autoAssignStamp ?? true; let maxRemainingSize = 0; if (!postageBatchId && !autoAssignStamp) { throw new Error('No postageBatchId was provided. Please repeat the prompt and also specify the usable postage batch id.'); } else if (!postageBatchId) { try { const rawPostageBatches = await bee.getPostageBatches(); rawPostageBatches.forEach((batch) => { if (!batch.usable) { return; } const remainingSize = batch.remainingSize.toBytes(); if (remainingSize > maxRemainingSize) { maxRemainingSize = remainingSize; postageBatchId = batch.batchID.toHex(); } }); } catch (error) { if (errorHasStatus(error, NOT_FOUND_STATUS)) { postageBatchId = DEFAULT_GATEWAY_BATCH_ID; } else { throw new Error('Retrieval of postage batches failed.'); } } } if (!postageBatchId) { throw new Error('There is no usable postage batch with capacity.'); } return postageBatchId!; }; const dateUnits: Record<string, number | undefined> = { ms: 1, milli: 1, millis: 1, millisecond: 1, milliseconds: 1, s: 1000, sec: 1000, second: 1000, seconds: 1000, m: 60_000, min: 60_000, minute: 60_000, minutes: 60_000, h: 3_600_000, hour: 3_600_000, hours: 3_600_000, d: 86_400_000, day: 86_400_000, days: 86_400_000, w: 604_800_000, week: 604_800_000, weeks: 604_800_000, month: 2_592_000_000, months: 2_592_000_000, y: 31_536_000_000, year: 31_536_000_000, years: 31_536_000_000, }; // From bee.js export function makeDate(numberWithUnit: string): number { const number = parseFloat(numberWithUnit); if (isNaN(number)) { throw Error("makeDate got NaN for input"); } const unit = numberWithUnit .replace(/^-?[0-9.]+/, "") .trim() .toLowerCase(); const multiplier = dateUnits[unit]; if (!multiplier) { throw Error(`Unknown unit: "${unit}"`); } return number * multiplier; }