1010import cliProgress from "cli-progress" ;
1111import { Humanloop , HumanloopClient } from "index" ;
1212import { AsyncFunction } from "otel" ;
13+ import pMap from "p-map" ;
1314
1415import {
1516 BooleanEvaluatorStatsResponse ,
16- CreateEvaluatorLogRequest ,
1717 CreateEvaluatorLogResponse ,
1818 CreateFlowLogResponse ,
1919 CreatePromptLogResponse ,
@@ -51,13 +51,10 @@ type LogResponse =
5151 | CreatePromptLogResponse
5252 | CreateToolLogResponse
5353 | CreateEvaluatorLogResponse ;
54- type LogRequest =
55- | FlowLogRequest
56- | PromptLogRequest
57- | ToolLogRequest
58- | CreateEvaluatorLogRequest ;
5954
6055export function overloadLog < T extends Flows | Prompts > ( client : T ) : T {
56+ const originalLog = client . log . bind ( client ) ;
57+
6158 // @ts -ignore
6259 const _overloadedLog : T [ "log" ] = async (
6360 request : FlowLogRequest | PromptLogRequest ,
@@ -83,20 +80,22 @@ export function overloadLog<T extends Flows | Prompts>(client: T): T {
8380 } ;
8481 }
8582
86- response = await client . log ( request , options ) ;
83+ // @ts -ignore
84+ response = await originalLog ( request , options ) ;
8785
86+ // @ts -ignore
8887 uploadCallback ( response . id ) ;
8988 } else {
90- response = await client . log ( request , options ) ;
89+ // @ts -ignore
90+ response = await originalLog ( request , options ) ;
9191 }
9292
9393 return response ;
9494 } ;
9595
96- return {
97- ...client ,
98- log : _overloadedLog ,
99- } ;
96+ client . log = _overloadedLog . bind ( client ) ;
97+
98+ return client ;
10099}
101100
102101export async function runEval (
@@ -105,6 +104,7 @@ export async function runEval(
105104 dataset : Dataset ,
106105 name ?: string ,
107106 evaluators : Evaluator [ ] = [ ] ,
107+ workers : number = 8 ,
108108) : Promise < EvaluatorCheck [ ] > {
109109 // Get or create the file on Humanloop
110110 if ( ! file . path && ! file . id ) {
@@ -145,6 +145,7 @@ export async function runEval(
145145 }
146146 const updatedData = { ...rest , ...version } as FlowRequest ;
147147 hlFile = await client . flows . upsert ( updatedData ) ;
148+ break ;
148149 }
149150 case "prompt" : {
150151 hlFile = await client . prompts . upsert ( {
@@ -307,7 +308,6 @@ export async function runEval(
307308 path : hlFile . path ,
308309 uploadCallback : async ( logId : string , datapoint : DatapointResponse ) => {
309310 await runLocalEvaluators ( client , logId , datapoint , localEvaluators ) ;
310- progressBar . increment ( ) ;
311311 } ,
312312 } ) ;
313313
@@ -327,11 +327,8 @@ export async function runEval(
327327 try {
328328 evaluationContext . addDatapoint ( datapoint , runId ) ;
329329 let output : string ;
330- if ( "messages" in datapoint ) {
331- output = await function_ ! ( {
332- ...datapoint . inputs ,
333- messages : datapoint . messages ,
334- } ) ;
330+ if ( "messages" in datapoint && datapoint . messages !== undefined ) {
331+ output = await function_ ! ( datapoint . inputs , datapoint . messages ) ;
335332 } else {
336333 output = await function_ ! ( datapoint . inputs ) ;
337334 }
@@ -356,10 +353,7 @@ export async function runEval(
356353
357354 // The log function will take care of the sourceDatapointId and runId from the context
358355 // See overloadLog in this module for more details
359- console . debug (
360- `function_ ${ function_ } is a simple callable, datapoint context was not consumed` ,
361- ) ;
362- logFunc ( {
356+ await logFunc ( {
363357 inputs : datapoint . inputs ,
364358 output : output ,
365359 startTime : start_time ,
@@ -368,13 +362,14 @@ export async function runEval(
368362 }
369363 } catch ( e ) {
370364 const errorMessage = e instanceof Error ? e . message : String ( e ) ;
371- logFunc ( {
365+ await logFunc ( {
372366 inputs : datapoint . inputs ,
373367 error : errorMessage ,
374368 sourceDatapointId : datapoint . id ,
375369 startTime : start_time ,
376370 endTime : new Date ( ) ,
377371 } ) ;
372+ // console.log(e);
378373 console . warn (
379374 `\nYour ${ type } 's callable failed for Datapoint: ${ datapoint . id } .\nError: ${ errorMessage } ` ,
380375 ) ;
@@ -396,11 +391,14 @@ export async function runEval(
396391 ) ;
397392 const totalDatapoints = hlDataset . datapoints ! . length ;
398393 progressBar . start ( totalDatapoints , 0 ) ;
399- const promises = hlDataset . datapoints ! . map ( async ( datapoint ) => {
400- await processDatapoint ( datapoint , runId ) ;
401- progressBar . increment ( ) ;
402- } ) ;
403- await Promise . all ( promises ) ;
394+ await pMap (
395+ hlDataset . datapoints ! ,
396+ async ( datapoint ) => {
397+ await processDatapoint ( datapoint , runId ) ;
398+ progressBar . increment ( ) ;
399+ } ,
400+ { concurrency : workers } ,
401+ ) ;
404402 progressBar . stop ( ) ;
405403 } else {
406404 // TODO: trigger run when updated API is available
@@ -466,8 +464,9 @@ function getLogFunction(
466464 fileId : string ,
467465 versionId : string ,
468466 runId : string ,
469- ) : ( args : LogRequest ) => Promise < LogResponse > {
467+ ) {
470468 /** Returns the appropriate log function pre-filled with common parameters. */
469+
471470 const logRequest = {
472471 // TODO: why does the Log `id` field refer to the file ID in the API?
473472 // Why are both `id` and `version_id` needed in the API?
@@ -478,22 +477,21 @@ function getLogFunction(
478477
479478 switch ( type ) {
480479 case "flow" :
481- return ( args : FlowLogRequest ) =>
482- client . flows . log ( {
480+ return async ( args : FlowLogRequest ) =>
481+ await client . flows . log ( {
483482 ...logRequest ,
484483 traceStatus : "complete" ,
485484 ...args ,
486485 } ) ;
487486 case "prompt" :
488- return ( args : PromptLogRequest ) =>
489- client . prompts . log ( { ...logRequest , ...args } ) ;
490- case "evaluator" :
491- // @ts -ignore
492- return ( args : CreateEvaluatorLogRequest ) =>
493- client . evaluators . log ( { ...logRequest , ...args } ) ;
487+ return async ( args : PromptLogRequest ) =>
488+ await client . prompts . log ( { ...logRequest , ...args } ) ;
489+ // case "evaluator":
490+ // return (args: CreateEvaluatorLogRequest) =>
491+ // client.evaluators.log({ ...logRequest, ...args });
494492 case "tool" :
495- return ( args : ToolLogRequest ) =>
496- client . tools . log ( { ...logRequest , ...args } ) ;
493+ return async ( args : ToolLogRequest ) =>
494+ await client . tools . log ( { ...logRequest , ...args } ) ;
497495 default :
498496 throw new Error ( `Unsupported File version: ${ type } ` ) ;
499497 }
@@ -517,15 +515,16 @@ async function runLocalEvaluators(
517515 judgment = evalFunction ( log ) ;
518516 }
519517
520- client . evaluators . log ( {
518+ await client . evaluators . log ( {
519+ path : evaluator . path ,
521520 versionId : evaluator . versionId ,
522521 parentId : logId ,
523522 judgment : judgment ,
524523 startTime : startTime ,
525524 endTime : new Date ( ) ,
526525 } ) ;
527526 } catch ( e ) {
528- client . evaluators . log ( {
527+ await client . evaluators . log ( {
529528 versionId : evaluator . versionId ,
530529 parentId : logId ,
531530 error : e instanceof Error ? e . message : String ( e ) ,
0 commit comments