@@ -652,9 +652,53 @@ export const wait = {
652652 }
653653 ) ;
654654 } ,
655+ /**
656+ * This allows you to start some work on another API (or one of your own services)
657+ * and continue the run when a callback URL we give you is hit with the result.
658+ *
659+ * You should send the callback URL to the other service, and then that service will
660+ * make a request to the callback URL with the result.
661+ *
662+ * @example
663+ *
664+ * ```ts
665+ * //wait for the prediction to complete
666+ const prediction = await wait.forHttpCallback<Prediction>(
667+ async (url) => {
668+ //pass the provided URL to Replicate's webhook
669+ await replicate.predictions.create({
670+ version:
671+ "19deaef633fd44776c82edf39fd60e95a7250b8ececf11a725229dc75a81f9ca",
672+ input: payload,
673+ // pass the provided URL to Replicate's webhook, so they can "callback"
674+ webhook: url,
675+ webhook_events_filter: ["completed"],
676+ });
677+ },
678+ {
679+ timeout: "2m",
680+ }
681+ );
682+
683+ //the value of prediction is the body of the webook that Replicate sent
684+ const result = prediction.output;
685+ * ```
686+ *
687+ * @param callback
688+ * @param options
689+ * @param requestOptions
690+ * @returns
691+ */
655692 async forHttpCallback < TResult > (
656693 callback : ( url : string ) => Promise < void > ,
657694 options ?: CreateWaitpointTokenRequestBody & {
695+ /**
696+ * If set to true, this will cause the waitpoint to release the current run from the queue's concurrency.
697+ *
698+ * This is useful if you want to allow other runs to execute while waiting
699+ *
700+ * @default false
701+ */
658702 releaseConcurrency ?: boolean ;
659703 } ,
660704 requestOptions ?: ApiRequestOptions
@@ -762,123 +806,6 @@ export const wait = {
762806 // 10. Receive the result here and import the packet, then get the result in the right format
763807 // 11. Make unwrap work
764808 } ,
765- async forHttpCallbackWithSchema < TSchema extends HttpCallbackSchema > (
766- schema : TSchema ,
767- callback : ( url : string ) => Promise < void > ,
768- options ?: CreateWaitpointTokenRequestBody & {
769- releaseConcurrency ?: boolean ;
770- } ,
771- requestOptions ?: ApiRequestOptions
772- ) : Promise < HttpCallbackResult < HttpCallbackResultTypeFromSchema < TSchema > > > {
773- const ctx = taskContext . ctx ;
774-
775- if ( ! ctx ) {
776- throw new Error ( "wait.forHttpCallback can only be used from inside a task.run()" ) ;
777- }
778-
779- const apiClient = apiClientManager . clientOrThrow ( ) ;
780-
781- const waitpoint = await apiClient . createWaitpointHttpCallback ( options ?? { } , requestOptions ) ;
782-
783- return tracer . startActiveSpan (
784- `wait.forHttpCallback()` ,
785- async ( span ) => {
786- const [ error ] = await tryCatch ( callback ( waitpoint . url ) ) ;
787-
788- if ( error ) {
789- throw new Error ( `You threw an error in your callback: ${ error . message } ` , {
790- cause : error ,
791- } ) ;
792- }
793-
794- const response = await apiClient . waitForWaitpointToken ( {
795- runFriendlyId : ctx . run . id ,
796- waitpointFriendlyId : waitpoint . id ,
797- releaseConcurrency : options ?. releaseConcurrency ,
798- } ) ;
799-
800- if ( ! response . success ) {
801- throw new Error ( `Failed to wait for wait for HTTP callback ${ waitpoint . id } ` ) ;
802- }
803-
804- const result = await runtime . waitUntil ( waitpoint . id ) ;
805-
806- const data = result . output
807- ? await conditionallyImportAndParsePacket (
808- { data : result . output , dataType : result . outputType ?? "application/json" } ,
809- apiClient
810- )
811- : undefined ;
812-
813- if ( result . ok ) {
814- try {
815- const parser = schema ? getSchemaParseFn < inferSchemaIn < TSchema > > ( schema ) : undefined ;
816-
817- if ( ! parser ) {
818- throw new Error ( "No parser found for schema" ) ;
819- }
820-
821- const parsedOutput = await parser ( data ) ;
822-
823- return {
824- ok : result . ok ,
825- output : parsedOutput ,
826- } ;
827- } catch ( error ) {
828- const err = error instanceof Error ? error : new Error ( String ( error ) ) ;
829- span . recordException ( err ) ;
830- span . setStatus ( {
831- code : SpanStatusCode . ERROR ,
832- } ) ;
833-
834- return {
835- ok : false ,
836- error : err ,
837- } ;
838- }
839- } else {
840- const error = new WaitpointTimeoutError ( data . message ) ;
841-
842- span . recordException ( error ) ;
843- span . setStatus ( {
844- code : SpanStatusCode . ERROR ,
845- } ) ;
846-
847- return {
848- ok : result . ok ,
849- error,
850- } ;
851- }
852- } ,
853- {
854- attributes : {
855- [ SemanticInternalAttributes . STYLE_ICON ] : "wait" ,
856- [ SemanticInternalAttributes . ENTITY_TYPE ] : "waitpoint" ,
857- [ SemanticInternalAttributes . ENTITY_ID ] : waitpoint . id ,
858- ...accessoryAttributes ( {
859- items : [
860- {
861- text : waitpoint . id ,
862- variant : "normal" ,
863- } ,
864- ] ,
865- style : "codepath" ,
866- } ) ,
867- id : waitpoint . id ,
868- isCached : waitpoint . isCached ,
869- idempotencyKey : options ?. idempotencyKey ,
870- idempotencyKeyTTL : options ?. idempotencyKeyTTL ,
871- timeout : options ?. timeout
872- ? typeof options . timeout === "string"
873- ? options . timeout
874- : options . timeout . toISOString ( )
875- : undefined ,
876- tags : options ?. tags ,
877- url : waitpoint . url ,
878- } ,
879- }
880- ) ;
881- } ,
882809} ;
883810
884811function nameForWaitOptions ( options : WaitForOptions ) : string {
0 commit comments