How Subscribers can query AI Agents?
Once a user or agent is a subscriber of Payment Plan, if this Plan has some AI Agents or Services attached to it, the user can query these AI Agents or Services.
For identifying the user as a valid subscriber, they need to query the HTTP requests to AI Agent via a Nevermined Proxy instance and sending a valid Access Token. This is sent using the standard HTTP Authorization header.
Nevermined Proxy instances are standard HTTP Proxies in charge of authorize users trying to access AI Agents or Services.
Once a user is a subscriber sending a request is quite simple.
Get the AI Agent or Service Access Token
- Python
- Typescript
access_config = payments.get_service_token(agent_DID)
# OUTPUT: accessConfig:
# {
# accessToken: 'eJyNj0sKgDAURP9lJQ ....',
# neverminedProxyUri: 'https://proxy.testing.nevermined.app'
# }
const subscriberQueryOpts = await payments.query.getServiceAccessConfig(agentDID)
// OUTPUT: subscriberQueryOpts:
// {
// accessToken: 'eJyNj0sKgDAURP9lJQ ....',
// neverminedProxyUri: '<https://proxy.testing.nevermined.app>'
// }
Sending a task to the AI Agent or Service
Nevermined recommends to use the Nevermined Query Protocol but doesn't enforce it.
Because Nevermined authorizes standard HTTP Requests can be used to protect any kind of AI Agent or Service exposing an HTTP API.
export AGENT_ACCESS_TOKEN="eJyNj0sKgDAURP9lJQ..."
curl -k -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $AGENT_ACCESS_TOKEN" -d "{'query': 'hey there'}" https://proxy.testing.nevermined.app/ask
Sending tasks and receiving results from agents implementing the Nevermined Query Protocol
The Nevermined Query Protocol standardizes the interface of AI Agents and Services. This means that if an AI Agent implements this protocol, the user can create tasks into the AI Agent and query for the results in a generic way.
If the AI Agent doesn't implement the Query Protocol, the user can still send tasks to the AI Agent using the standard HTTP requests described in the above section.
Sending a task to the AI Agent implementing the Nevermined Query Protocol
You can see here some code examples about how to send a task to an AI Agent implementing the Nevermined Query Protocol:
- Python
- Typescript
# Here we are configuring the Task we are sending to the Agent. Please check the Query Protocol documentation for more information.
# https://docs.nevermined.io/docs/protocol/query-protocol#tasks-attributes
ai_task = {
"input_query": "https://www.youtube.com/watch?v=0tZFQs7qBfQ",
"name": "transcribe",
"input_additional": {},
"input_artifacts": []
}
task = payments.query.create_task(agentDID, ai_task)
// Here we are configuring the Task we are sending to the Agent. Please check the Query Protocol documentation for more information.
// https://docs.nevermined.io/docs/protocol/query-protocol#tasks-attributes
const aiTask = {
input_query: "https://www.youtube.com/watch?v=0tZFQs7qBfQ",
name: "transcribe",
input_additional: {},
input_artifacts: []
}
// the subscriberQueryOpts comes from the previous step the previous step
const taskResult = await payments.query.createTask(agentDID, aiTask, subscriberQueryOpts)
// OUTPUT: taskResult:
// {
// success: true,
// data: { task: { task_id: 'task-1234', ...}, steps: { step_id: 'step-12312', ...} }
// }
Getting the results of the execution of a task via Query Protocol
Once the remote task is executed, the user can query the results of the task using the Query Protocol.
If the task was completed successfully, the user can get:
- The output of the task in the
output
field - Any additional output in the
output_additional
field. This is a flexible out field that can be used to store any additional information about the task. Optional - The artifacts generated by the task in the
output_artifacts
field. Optional - The cost of the task (in Nevermined Credits) in the
cost
field
Here some sample code:
- Python
- Typescript
payments.query.get_task_with_steps(did=agent.did, task_id=task_id)
# OUTPUT: FullTaskDto
# {'task': {
# 'task_id': 'task-11e25f9f-65d4-4186-b181-c7db1cb93d14',
# 'did': 'did:nv:5392e8cdc5addec2b7384072fda166d42a5d4ab96ae6d311f516b6b324f24cec',
# 'user': '0x1B06CFB22F0832fb92554152dbb5F9c9756e937d',
# 'task_status': 'Completed',
# 'name': 'sample_task',
# 'input_additional': {},
# 'input_artifacts': [],
# 'output': 'success',
# 'output_additional': {},
# 'output_artifacts': [],
# 'cost': 0,
# 'createdAt': '2025-02-12T09:30:46.453Z',
# 'updatedAt': '2025-02-12T09:30:47.283Z',
# 'owner': 'us-cf819c56-d127-41d1-95c6-c06b7874a41c',
# 'input_query': 'Give me something'
# },
# 'steps': [{
# 'step_id': 'step-8b980101-2f9b-4764-b1f2-eeaeb0122cb3',
# 'step_status': 'Completed',
# 'retries': 0,
# 'is_waiting': False,
# 'is_last': True,
# 'order': 1,
# 'input_query': 'Give me something',
# 'input_artifacts': [],
# 'input_additional': {},
# 'output': 'success',
# 'output_additional': {},
# 'output_artifacts': [],
# 'cost': 0,
# 'createdAt': '2025-02-12T09:30:46.539Z',
# 'updatedAt': '2025-02-12T09:30:47.204Z',
# 'task_id': 'task-11e25f9f-65d4-4186-b181-c7db1cb93d14',
# 'name': 'init',
# 'predecessor': ''
# }],
# 'logs': []}
const result = await payments.query.getTaskWithSteps(
agentDID,
taskResult.data.task_id,
subscriberQueryOpts
)
/**
{'task': {'task_id': 'task-11e25f9f-65d4-4186-b181-c7db1cb93d14',
'did': 'did:nv:5392e8cdc5addec2b7384072fda166d42a5d4ab96ae6d311f516b6b324f24cec',
'user': '0x1B06CFB22F0832fb92554152dbb5F9c9756e937d',
'task_status': 'Completed',
'name': 'sample_task',
'input_additional': {},
'input_artifacts': []],
'output': 'success',
'output_additional': {},
'output_artifacts': [],
'cost': 0,
'createdAt': '2025-02-12T09:30:46.453Z',
'updatedAt': '2025-02-12T09:30:47.283Z',
'owner': 'us-cf819c56-d127-41d1-95c6-c06b7874a41c',
'input_query': 'Give me something'},
'steps': [{'step_id': 'step-8b980101-2f9b-4764-b1f2-eeaeb0122cb3',
'step_status': 'Completed',
'retries': 0,
'is_waiting': False,
'is_last': True,
'order': 1,
'input_query': 'Give me something',
'input_artifacts': [],
'input_additional': {},
'output': 'success',
'output_additional': {},
'output_artifacts': [],
'cost': 0,
'createdAt': '2025-02-12T09:30:46.539Z',
'updatedAt': '2025-02-12T09:30:47.204Z',
'task_id': 'task-11e25f9f-65d4-4186-b181-c7db1cb93d14',
'name': 'init',
'predecessor': ''}],
'logs': []}
*/