> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gp.scale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Agent Service Endpoints

> How to interact with agents built in Agent Service.

## Overview

Clients call through the SGP API to Agent Service in order to CRUD agent configs and execute agents.
Agent configs are stored in Agents DB, together with the internal run states of the agents. The service also talks to secrets vault (e.g. AWS secrets manager) and blob store (e.g. AWS S3). For SGP native assets like knowledge bases and LLMs the service also talks back to the SGP API.

<img height="663" width="2048" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXehlGBNOa7LUNHPqpQRcxClvyNkLPFQIpssgjmYWYHZ0X6ottG3_nMos3wBnLliszV8oV-znkkm6QlP380mGu4A-Vzk5CzC43v8aSPk8WI8HUKYLMoNmzhIR7vXBX4IBxvF59_p?key=4UQ2rxZFcFiohhkK9_YjC7dy" />

## Creating Agent Configurations

1. **Create an Application Specification**
   * Generates a timestamp.
   * Sends a `POST` request to create an application spec (`/v4/application-specs`).
   * Extracts the `application_spec_id` from the response.

```python theme={null}
# Create application spec
timestamp = int(time.time())

response = await c.post(
    "/v4/application-specs",
    **TEST_USER_AUTH,
    json={
        "name": f"Loop {timestamp}",
        "description": "Agentic Application",
        "account_id": ACCOUNT_ID,
    },
)
application_spec_id = response.json()["id"]
```

2. **Load YAML Configuration**
   * Reads a YAML config file (`loop_with_list_demo.yaml`).
   * Assigns a unique ID (`uuid4()`) and associates an `account_id`.
   * Determines the **agent type** (`STATE_MACHINE`, `PLAN`, or `WORKFLOW`) based on YAML contents.

```python theme={null}
# Load agent yaml config
filepath = "../../examples/tutorial/05-loops/loop_with_list_demo.yaml"
filename = Path(filepath).name

with open(filepath) as f:
    config = yaml.safe_load(f)
    config["id"] = str(uuid4())
    config["account_id"] = ACCOUNT_ID
    agent_type = (
        "STATE_MACHINE" if "machine" in config else "PLAN" if "plan" in config else "WORKFLOW"
    )
```

3. **Construct and Send Application Variant Request**
   * Builds a JSON payload with the application variant details.
   * Sends a `POST` request to `/v4/application-variants` to create a variant.
   * Extracts the `variant_id` from the response.

```python theme={null}
# Construct application variant config payload
json_data = {
    "name": f"{filename} variant",
    "description": f"{filename} app variant description",
    "configuration": {
        "params": config,
        "type": agent_type,
    },
    "version": "AGENTS_SERVICE",
    "application_spec_id": application_spec_id,
    "account_id": ACCOUNT_ID,
}

print(json_data)

# Create agentic application variant
response = await c.post(
    "/v4/application-variants",
    **TEST_USER_AUTH,
    json=json_data,
)

variant_id = response.json()["id"]
```

## Executing an Agent

You can send a POST request to an agent variant as a standard request or stream the response line by line.

1. **Process a Variant (Standard Request)**
   * Sends a `POST` request to process a specific application variant.
   * Provides input parameters (`object: "tree"`) for processing.
   * Returns a JSON response containing the processed result.

```python theme={null}
# Process variant
response = await c.post(
    f"/v4/applications/{variant_id}/process",
    **TEST_USER_AUTH,
    json={
        "inputs": {
            "object": "tree",
        },
    },
)

response.json()
```

2. **Stream Responses from the Variant**
   * Sends a `POST` request with `stream=True` to enable real-time streaming.
   * Asynchronously processes and prints incoming data as it arrives.

```python theme={null}
# Stream variant
async with c.stream(
    "POST",
    f"/v4/applications/{variant_id}/process",
    **TEST_USER_AUTH,
    json={
        "inputs": {
            "object": "tree",
        },
        "stream": True,
    },
) as response:
    # Ensure the response is OK
    response.raise_for_status()

    # Stream the response line by line
    async for line in response.aiter_text():
        if line.startswith("data:"):
            data = line.lstrip("data: ").strip()
            print(f"Received data: {data}")
        elif line.startswith("event:"):
            event = line.lstrip("event: ").strip()
            print(f"Received event: {event}")
```
