Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
feat: adding nvm cost
Browse files Browse the repository at this point in the history
  • Loading branch information
aaitor committed Jun 27, 2024
1 parent 343d9de commit 23867c0
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .env.local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@ export API_AUTH_TOKEN="12345"
export NVM_ENVIRONMENT="appStaging"
export NVM_AGENT_DID="did:nv:1234"
export NVM_SUBSCRIPTION_DID="did:nv:aabb"

export DATABASE_NAME="/tmp/agent-youtube.db"

export IPFS_GATEWAY="https://ipfs.infura.io:5001"
export IPFS_PROJECT_ID=""
export IPFS_PROJECT_SECRET=""
34 changes: 30 additions & 4 deletions src/api/agent/agent.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Get,
Param,
Post,
Res,
UseGuards,
UsePipes,
ValidationPipe
Expand All @@ -17,13 +18,21 @@ import {
} from '@nestjs/swagger'
import { CreateTaskDto } from './dto/create-task-dto'
import { AuthorizationGuard } from '../../common/guards/auth.guard'
import { ConfigService } from '@nestjs/config'
import { Response } from 'express'

@ApiTags('Agent')
@Controller()
@UseGuards(AuthorizationGuard)
@ApiBearerAuth('Authorization')
export class AgentController {
constructor(private readonly agentService: AgentService) {}
static readonly DEFAULT_COST_CREDITS = '1'
static readonly NVM_COST_HEADER = 'NVMCreditsConsumed'

constructor(
private readonly agentService: AgentService,
private readonly configService: ConfigService
) {}

@Post()
@ApiOperation({
Expand All @@ -43,8 +52,19 @@ export class AgentController {
description: 'Unauthorized'
})
@UsePipes(new ValidationPipe())
async createAgentTask(@Body() agentTaskDto: CreateTaskDto) {
return this.agentService.createAgentTask(agentTaskDto)
async createAgentTask(
@Body() agentTaskDto: CreateTaskDto,
@Res({ passthrough: true }) response: Response
) {
const task = await this.agentService.createAgentTask(agentTaskDto)
const createTaskCost = this.configService.get('nvm.credits.createTask')
if (createTaskCost > 0) {
response.setHeader(
this.configService.get('nvm.credits.header'),
createTaskCost
)
}
return task
}

@Get(':task_id')
Expand All @@ -56,8 +76,14 @@ export class AgentController {
status: 200,
description: 'Return the task details'
})
async getAgentTask(@Param('task_id') taskId: string) {
async getAgentTask(
@Param('task_id') taskId: string,
@Res({ passthrough: true }) response: Response
) {
const fullTask = await this.agentService.getTaskById(taskId)
const taskCost =
fullTask.task.cost || this.configService.get('nvm.credits.getTask')
response.setHeader(this.configService.get('nvm.credits.header'), taskCost)
return {
task: fullTask.task,
steps: fullTask.steps
Expand Down
11 changes: 10 additions & 1 deletion src/api/agent/agent.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,20 @@ export class AgentService {
}

updateStep(stepId: string, stepUpdated: Partial<StepEntity>) {
Logger.log(`Updating step ${stepId}, with ${JSON.stringify(stepUpdated)}`)
Logger.log(`Updating step ${stepId}, with ${stepUpdated.step_status}`)
return this.stepEntity.update(
{ step_id: stepId },
{ ...stepUpdated, updated_at: new Date() }
)
}

async getTotalCostForTask(taskId: string) {
const totalCost = await AppDataSource.query(
`SELECT SUM(steps.cost) as total_cost FROM steps WHERE steps.task_id = \'${taskId}\'`
)
return totalCost[0].total_cost
}

async completeTasksWhenStepsAreDone() {
const tasks = await AppDataSource.query(
`SELECT tasks.task_id as task_id, steps.output as output, steps.output_artifacts as output_artifacts, steps.output_additional as output_additional FROM tasks, steps WHERE tasks.task_id = steps.task_id AND steps.is_last = true AND steps.step_status = \'COMPLETED\' AND tasks.task_status = \'PENDING\' `
Expand All @@ -76,6 +83,7 @@ export class AgentService {
{ task_id: task.task_id },
{
task_status: ExecutionStatus.COMPLETED,
cost: await this.getTotalCostForTask(task.task_id),
output: task.output,
output_artifacts: task.output_artifacts,
output_additional: task.output_additional,
Expand All @@ -100,6 +108,7 @@ export class AgentService {
{ task_id: task.task_id },
{
task_status: ExecutionStatus.FAILED,
cost: await this.getTotalCostForTask(task.task_id),
output: task.output,
output_artifacts: task.output_artifacts,
output_additional: task.output_additional,
Expand Down
3 changes: 2 additions & 1 deletion src/common/utils/ipfs-helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import IpfsHttpClientLite from 'ipfs-http-client-lite'
/* eslint-disable @typescript-eslint/no-var-requires */
const IpfsHttpClientLite = require('ipfs-http-client-lite')

export interface IpfsConnectionParameters {
gatewayUrl: string
Expand Down
7 changes: 6 additions & 1 deletion src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ export const appConfig = {
nvm: {
environment: process.env.NVM_ENVIRONMENT,
agentDid: process.env.NVM_AGENT_DID,
subscriptionDid: process.env.NVM_SUBSCRIPTION_DID
subscriptionDid: process.env.NVM_SUBSCRIPTION_DID,
credits: {
header: process.env.NVM_CREDITS_HEADER || 'NVMCreditsConsumed',
createTask: Number(process.env.NVM_CREDITS_CREATE_TASK) || 1,
getTask: Number(process.env.NVM_CREDITS_GET_TASK) || 1
}
},
logger: {
level: process.env.LOG_LEVEL || ['error', 'log', 'warn']
Expand Down
12 changes: 12 additions & 0 deletions src/database/1718898482722-AgentBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export class AgentBase1718898482722 implements MigrationInterface {
type: 'text',
isNullable: true
},
{
name: 'cost',
type: 'integer',
default: 0,
isNullable: true
},
...baseSchema
]
}),
Expand Down Expand Up @@ -137,6 +143,12 @@ export class AgentBase1718898482722 implements MigrationInterface {
type: 'text',
isNullable: true
},
{
name: 'cost',
type: 'integer',
default: 0,
isNullable: true
},
...baseSchema
]
}),
Expand Down
3 changes: 3 additions & 0 deletions src/database/entities/step.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export class StepEntity extends BaseEntity {
@Column('integer')
retries: number

@Column('integer')
cost: number

@Column('boolean')
is_last: boolean

Expand Down
3 changes: 3 additions & 0 deletions src/database/entities/task.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export class TaskEntity extends BaseEntity {
@Column('varchar')
name: string

@Column('integer')
cost: number

@Column('text')
input_query: string

Expand Down
9 changes: 6 additions & 3 deletions src/processor/processor.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,24 @@ export class ProcessorController implements OnModuleInit {
Logger.log(`[${task.task_id}] Simulate a step that is still in progress`)
await this.agentService.updateStep(step.step_id, {
step_status: ExecutionStatus.IN_PROGRESS,
retries: step.retries + 1
retries: step.retries + 1,
cost: 0
})
} else if (randomIndex === 1) {
Logger.log(`[${task.task_id}] Simulate a step that is failing`)
await this.agentService.updateStep(step.step_id, {
step_status: ExecutionStatus.FAILED,
output: `{"result": 500, "message": "Failed because ${randomIndex} is 1"}`
output: `{"result": 500, "message": "Failed because ${randomIndex} is 1"}`,
cost: 0
})
} else {
// Simulate a successful step
Logger.log(`[${task.task_id}] Simulate a step that is completed`)
await this.agentService.updateStep(step.step_id, {
step_status: ExecutionStatus.COMPLETED,
is_last: true,
output: `{"result": 200, "message": "${randomIndex}"}`
output: `{"result": 200, "message": "${randomIndex}"}`,
cost: randomIndex + 1
})
}
}
Expand Down

0 comments on commit 23867c0

Please sign in to comment.