Skip to content

Commit

Permalink
Merge pull request #77 from nevermined-io/fix/library
Browse files Browse the repository at this point in the history
fix: adaptations to integrate with client
  • Loading branch information
aaitor authored Oct 23, 2024
2 parents dfd850b + 7d4e784 commit 66d1fa1
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 124 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [v0.5.2](https://github.com/nevermined-io/payments/compare/v0.5.1...v0.5.2)

> 22 October 2024
- feat: createAgent method [`60d8332`](https://github.com/nevermined-io/payments/commit/60d8332bbcdd0d8f1014a7e1f49b7092d20c8bab)
- fix: adaptations to integrate with client [`f833203`](https://github.com/nevermined-io/payments/commit/f83320361a6dbb2cf880277f462914fd493dfb07)
- chore: format [`1dc16fd`](https://github.com/nevermined-io/payments/commit/1dc16fdbf7be2974dd7bb6495b9a00244f339c0f)

#### [v0.5.1](https://github.com/nevermined-io/payments/compare/v0.5.0...v0.5.1)

> 18 October 2024
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nevermined-io/payments",
"version": "0.5.1",
"version": "0.5.3",
"description": "Typescript SDK to interact with the Nevermined Payments Protocol",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -30,6 +30,7 @@
},
"devDependencies": {
"@types/node": "^20.11.19",
"@types/uuid": "10.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"eslint": "^8.56.0",
Expand All @@ -51,6 +52,7 @@
"socket.io-client": "4.7.5",
"axios": "^1.7.7",
"jose": "^5.2.4",
"js-file-download": "^0.4.12"
"js-file-download": "^0.4.12",
"uuid": "^10.0.0"
}
}
25 changes: 6 additions & 19 deletions src/api/nvm-backend.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import axios from 'axios'
import { io } from 'socket.io-client'
import { decodeJwt } from 'jose'
import { isEthereumAddress, sleep } from '../common/utils'
import { AgentExecutionStatus } from '../common/types'
import { isEthereumAddress } from '../utils'
import { sleep } from '../common/helper'

export interface BackendApiOptions {
/**
Expand Down Expand Up @@ -161,12 +162,11 @@ export class NVMBackendApi {
throw new Error('Unable to subscribe to the server becase a key was not provided')

if (this.socketClient && this.socketClient.connected) {
console.log('nvm-backend:: Already connected to the websocket server')
// nvm-backend:: Already connected to the websocket server
return
}
try {
console.log(`nvm-backend:: Connecting to websocket server: ${this.opts.webSocketHost}`)
console.log(JSON.stringify(this.opts.webSocketOptions))
// nvm-backend:: Connecting to websocket server: ${this.opts.webSocketHost}
this.socketClient = io(this.opts.webSocketHost!, this.opts.webSocketOptions)
await this.socketClient.connect()
for (let i = 0; i < 5; i++) {
Expand All @@ -178,7 +178,6 @@ export class NVMBackendApi {
if (!this.socketClient.connected) {
throw new Error('Unable to connect to the websocket server')
}
console.log('is connected: ', this.socketClient.connected)
} catch (error) {
throw new Error(
`Unable to initialize websocket client: ${this.opts.webSocketHost} - ${(error as Error).message}`,
Expand All @@ -204,9 +203,8 @@ export class NVMBackendApi {
await this.connectSocket()
// await this.socketClient.emit('subscribe-agent', '')
await this.socketClient.on('connect', async () => {
console.log(`nvm-backend:: On:: ${this.socketClient.id} Connected to the server`)
// nvm-backend:: On:: ${this.socketClient.id} Connected to the server
})
console.log(`Subscription Options: ${JSON.stringify(opts)}`)
await this.socketClient.emit('_join-rooms', JSON.stringify(opts))

// await this.socketClient.on('task-updated', (data: any) => {
Expand All @@ -215,21 +213,13 @@ export class NVMBackendApi {
// })
opts.subscribeEventTypes.forEach(async (eventType) => {
await this.socketClient.on(eventType, (data: any) => {
// console.log(`RECEIVED STEP data: ${JSON.stringify(data)}`)
_callback(data)
})
})
}

private async eventHandler(data: any, _callback: (err?: any) => any, _opts: SubscriptionOptions) {
_callback(data)
// if (opts.subscribeEventTypes.length > 0) {
// if (opts.subscribeEventTypes.includes(data.event)) {
// _callback(data)
// }
// } else {
// _callback(data)
// }
}

protected async _emitStepEvents(
Expand All @@ -246,7 +236,7 @@ export class NVMBackendApi {

disconnect() {
this.disconnectSocket()
console.log('nvm-backend:: Disconnected from the server')
// nvm-backend:: Disconnected from the server
}

parseUrl(uri: string, reqOptions: HTTPRequestOptions) {
Expand Down Expand Up @@ -284,9 +274,6 @@ export class NVMBackendApi {
}

async post(url: string, data: any, reqOptions: HTTPRequestOptions) {
console.log('POST URL', this.parseUrl(url, reqOptions))
console.log('POST DATA', data)
console.log('POST HEADERS', this.parseHeaders(reqOptions.headers || {}))
return axios({
method: 'POST',
url: this.parseUrl(url, reqOptions),
Expand Down
48 changes: 35 additions & 13 deletions src/api/query-api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AgentExecutionStatus } from '../common/types'
import { AgentExecutionStatus, Step } from '../common/types'
import {
BackendApiOptions,
DefaultSubscriptionOptions,
Expand Down Expand Up @@ -49,7 +49,7 @@ export class AIQueryOptions {
/**
* The Nevermined Proxy that needs to be used to interact with the AI Agent/Service.
*/
proxyHost?: string
neverminedProxyUri?: string
}

/**
Expand Down Expand Up @@ -78,15 +78,15 @@ export class AIQueryApi extends NVMBackendApi {
opts: SubscriptionOptions = DefaultSubscriptionOptions,
) {
await super._subscribe(_callback, opts).then(() => {
console.log('query-api:: Subscribed to server')
// query-api:: Subscribed to server
})
try {
if (opts.getPendingEventsOnSubscribe) {
console.log('query-api:: Emitting pending events')
// query-api:: Emitting pending events
await super._emitStepEvents(AgentExecutionStatus.Pending, opts.joinAgentRooms)
}
} catch {
console.warn('query-api:: Unable to get pending events')
// query-api:: Unable to get pending events
}
}

Expand Down Expand Up @@ -129,15 +129,13 @@ export class AIQueryApi extends NVMBackendApi {
*/
async createTask(did: string, task: any, queryOpts: AIQueryOptions) {
const endpoint = TASK_ENDPOINT.replace('{did}', did)
console.log('endpoint', endpoint)
const reqOptions: HTTPRequestOptions = {
sendThroughProxy: true,
...(queryOpts.proxyHost && { proxyHost: queryOpts.proxyHost }),
...(queryOpts.neverminedProxyUri && { proxyHost: queryOpts.neverminedProxyUri }),
...(queryOpts.accessToken && {
headers: { Authorization: `Bearer ${queryOpts.accessToken}` },
}),
}
console.log('reqOptions', reqOptions)
return this.post(endpoint, task, reqOptions)
}

Expand Down Expand Up @@ -172,12 +170,11 @@ export class AIQueryApi extends NVMBackendApi {
async getTaskWithSteps(did: string, taskId: string, queryOpts: AIQueryOptions) {
const reqOptions: HTTPRequestOptions = {
sendThroughProxy: true,
...(queryOpts.proxyHost && { proxyHost: queryOpts.proxyHost }),
...(queryOpts.neverminedProxyUri && { proxyHost: queryOpts.neverminedProxyUri }),
...(queryOpts.accessToken && {
headers: { Authorization: `Bearer ${queryOpts.accessToken}` },
}),
}
console.log('reqOptions', reqOptions)
return this.get(GET_TASK_ENDPOINT.replace('{did}', did).replace('{taskId}', taskId), reqOptions)
}

Expand Down Expand Up @@ -207,6 +204,7 @@ export class AIQueryApi extends NVMBackendApi {
* const result = await payments.query.updateStep(step.did, step.task_id, step.step_id, {
* step_id: step.step_id,
* task_id: step.task_id,
* did: step.did,
* step_status: AgentExecutionStatus.Completed,
* is_last: true,
* output: 'LFG!',
Expand All @@ -215,12 +213,14 @@ export class AIQueryApi extends NVMBackendApi {
* ```
*
* @param did - Agent DID
* @param taskId - Task ID
* @param stepId - Step ID
* @param step - The Step object to update. @see https://docs.nevermined.io/docs/protocol/query-protocol#steps-attributes
* @returns The result of the operation
*/
async updateStep(did: string, taskId: string, stepId: string, step: any) {
async updateStep(did: string, step: Partial<Step>) {
const { task_id: taskId, step_id: stepId } = step
if (!taskId || !stepId)
throw new Error('The step object must contain the task_id and step_id attributes')

const endpoint = UPDATE_STEP_ENDPOINT.replace('{did}', did)
.replace('{taskId}', taskId)
.replace('{stepId}', stepId)
Expand Down Expand Up @@ -263,6 +263,28 @@ export class AIQueryApi extends NVMBackendApi {
return this.post(SEARCH_STEPS_ENDPOINT, searchParams, { sendThroughProxy: false })
}

/**
* It retrieves the complete information of a specific step given a stepId
*
* @remarks
* This method is used by the AI Agent to retrieve information about the steps part of tasks created by users to the agents owned by the user
*
* @example
* ```
* await paymentsBuilder.query.getStep('step-1234')
* ```
*
* @param stepId - the id of the step to retrieve
* @returns The complete step information
*/
async getStep(stepId: string) {
const result = await this.searchSteps({ step_id: stepId })
if (result.status === 200 && result.data && result.data.steps && result.data.steps.length > 0) {
return result.data.steps[0]
}
throw new Error(`Step with id ${stepId} not found`)
}

/**
* It retrieves all the steps that the agent needs to execute to complete a specific task associated to the user.
*
Expand Down
16 changes: 16 additions & 0 deletions src/common/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Endpoint } from '../payments'

export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

export const jsonReplacer = (_key: any, value: { toString: () => any }) => {
return typeof value === 'bigint' ? value.toString() : value
}

export const getServiceHostFromEndpoints = (endpoints: Endpoint[]): string => {
let serviceHost = ''
endpoints.some((endpoint) => {
const _endpoint = Object.values(endpoint)[0]
serviceHost = new URL(_endpoint).origin
})
return serviceHost
}
50 changes: 24 additions & 26 deletions src/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const FIRST_STEP_NAME = 'init'

/**
* A task defines something that the agent should execute.
*/
Expand All @@ -7,6 +9,11 @@ export interface Task extends ExecutionOptions {
*/
task_id: string

/**
* The status of the execution
*/
task_status: AgentExecutionStatus

/**
* The steps executed by the agent to complete the task
*/
Expand All @@ -29,6 +36,11 @@ export interface Step extends ExecutionOptions {
*/
task_id: string

/**
* The status of the execution
*/
step_status: AgentExecutionStatus

/**
* Whether this is the last step in the task.
*/
Expand All @@ -40,25 +52,7 @@ export interface Step extends ExecutionOptions {
name?: string
}

export const FIRST_STEP_NAME = 'init'
export const LAST_STEP_NAME = 'init'

export interface ExecutionOptions {
/**
* The input for the task. It can be a prompt, a question, etc
*/
input: ExecutionInput

/**
* The status of the execution
*/
status: AgentExecutionStatus

/**
* The output of the step
*/
output?: ExecutionOutput

export interface ExecutionOptions extends ExecutionInput, ExecutionOutput {
/**
* When the execution was created
*/
Expand All @@ -73,6 +67,11 @@ export interface ExecutionOptions {
* The number of retries for the task or step
*/
retries?: number

/**
* The cost in credits resulting from the execution of the task or the step
*/
cost?: number
}

/**
Expand All @@ -82,39 +81,38 @@ export interface ExecutionInput {
/**
* The input for the task. It can be a prompt, a question, etc
*/
query: string
input_query: string

/**
* Additional parameters required for the task
*/
additional_params?: { [name: string]: string }[]
input_params?: { [name: string]: string }[]

/**
* List of artifact ids that are associated with the task
*/
artifacts?: Artifact[]
input_artifacts?: Artifact[]
}

/**
* Output of the task or step execution
*/
export interface ExecutionOutput {
/**
* The main output of the task
* The main output generated by a task or step
*/

output: any

/**
* Additional output generated
*/

additional_output?: { [name: string]: any }[]
output_additional?: { [name: string]: any }[]

/**
* List of artifact generated by the task or step
*/
artifacts?: string[]
output_artifacts?: any[]
}

/**
Expand Down
10 changes: 0 additions & 10 deletions src/common/utils.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export * from './environments'
export * from './payments'
export * from './utils'
export * from './common/types'
export * from './common/payments.error'
export * from './common/utils'
export * from './common/helper'
export * from './api/query-api'
export { BackendApiOptions, BackendWebSocketOptions } from './api/nvm-backend'
Loading

0 comments on commit 66d1fa1

Please sign in to comment.