Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions skills/_shared/references/api-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ $TFY_API_SH GET /api/svc/v1/workspaces
| GET | `/api/svc/v1/teams` | List teams |
| POST | `/api/svc/v1/teams` | Create a team |
| GET | `/api/svc/v1/teams/{id}` | Get team |
| POST | `/api/svc/v1/teams/{id}/members` | Add member to team |
| DELETE | `/api/svc/v1/teams/{id}` | Delete team |

---
Expand All @@ -361,6 +362,8 @@ $TFY_API_SH GET /api/svc/v1/workspaces
| GET | `/api/svc/v1/users/{id}` | Get user |
| POST | `/api/svc/v1/users/invite` | Invite user |

Invite and access grants are separate: invite with `/users/invite`, then add collaborators to resources after confirming role/resource.

---

## Personal Access Tokens
Expand All @@ -384,6 +387,8 @@ $TFY_API_SH GET /api/svc/v1/workspaces
| POST | `/api/svc/v1/virtual-accounts/{id}/regenerate-token` | Regenerate token |
| DELETE | `/api/svc/v1/virtual-accounts/{id}` | Delete virtual account |

Service accounts are valid collaborator subjects as `serviceaccount:name`, but this reference does not currently include a verified service-account creation endpoint.

---

## Agents
Expand Down
11 changes: 10 additions & 1 deletion skills/gateway/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Supported providers reference: [references/guardrail-providers.md](references/gu

## AI Monitoring

Query gateway request traces via the spans API. Requires either `tracingProjectFqn` or `dataRoutingDestination` (suggest `"default"` as starting point).
Query gateway request traces via the spans API and aggregate usage via the metrics API. Requires either `tracingProjectFqn` or `dataRoutingDestination` for trace queries; suggest `"default"` as a starting point when the user does not know the destination.

### Recent Requests

Expand All @@ -183,6 +183,13 @@ For all monitoring use cases (cost analysis, errors, model usage, user filtering

### Aggregated Metrics

Use this path for aggregate questions such as:

- "Show cost incurred for the last 3 months."
- "Break cost down by model, user, team, or virtual account."
- "Show total tokens and latency by model."
- "Which virtual account generated the most cost?"

```bash
$TFY_API_SH POST /api/svc/v1/llm-gateway/metrics/query '{
"startTs": "...", "endTs": "...",
Expand All @@ -193,6 +200,8 @@ $TFY_API_SH POST /api/svc/v1/llm-gateway/metrics/query '{
}'
```

When answering a time-range question, calculate exact `startTs` and `endTs`, state the range used, and present totals in a compact table. If the user asks for monthly breakdowns, run one query per month unless the API exposes a time-bucket field.

---

## Generating Manifests
Expand Down
107 changes: 97 additions & 10 deletions skills/gateway/references/monitoring.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AI Monitoring & Traces
# AI Monitoring & Metrics

Query gateway request traces, costs, latency, errors, and token usage via the spans query API.
Query gateway request traces, costs, latency, errors, and token usage. Use the spans API for request-level investigations and the metrics API for aggregate questions such as "show cost for the last 3 months."

### Required Parameter

Expand Down Expand Up @@ -28,6 +28,38 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
}'
```

### Metrics API

**Endpoint:** `POST /api/svc/v1/llm-gateway/metrics/query`

Use this API for aggregate gateway questions. Calculate `startTs` and `endTs` from the user's requested time range. If the user says "last 3 months", use the exact three-month window ending now unless they ask for calendar months.

```bash
$TFY_API_SH POST '/api/svc/v1/llm-gateway/metrics/query' '{
"startTs": "2026-02-20T00:00:00.000Z",
"endTs": "2026-05-20T00:00:00.000Z",
"datasource": "modelMetrics",
"type": "distribution",
"aggregations": [
{"type": "count", "column": "costInUSD"},
{"type": "sum", "column": "costInUSD"},
{"type": "sum", "column": "inputTokens"},
{"type": "sum", "column": "outputTokens"},
{"type": "p50", "column": "latencyMs"},
{"type": "p90", "column": "latencyMs"}
],
"groupBy": ["modelName"]
}'
```

Available aggregation columns: `costInUSD`, `inputTokens`, `outputTokens`, `latencyMs`, `interTokenLatencyMs`, `timeToFirstTokenMs`, `timePerOutputTokenLatencyMs`

Aggregation types: `count`, `sum`, `p50`, `p75`, `p90`, `p99`

Group-by dimensions: `modelName`, `userEmail`, `virtualaccount`, `team`, `virtualModel`, `errorCode`, `requestType`, `providerAccountType`, `providerModelName`, `metadata.<key>`

For calendar-month cost breakdowns, run one metrics query per month. Do not invent a month group-by unless the API response or product docs expose one.

### Common Monitoring Use Cases

#### 1. Show Recent Requests
Expand All @@ -41,7 +73,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
}'
```

#### 2. Cost Analysis (LLM Spans)
#### 2. Cost Analysis (Request-Level LLM Spans)

Filter for LLM spans and extract cost attributes:

Expand All @@ -50,7 +82,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"spanAttributeKey": "tfy.span_type", "operator": "eq", "value": "LLM"}
{"spanAttributeKey": "tfy.span_type", "operator": "EQUAL", "value": "LLM"}
],
"limit": 200,
"sortDirection": "desc"
Expand All @@ -69,7 +101,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"spanFieldName": "statusCode", "operator": "eq", "value": "ERROR"}
{"spanFieldName": "statusCode", "operator": "EQUAL", "value": "ERROR"}
],
"limit": 50,
"sortDirection": "desc"
Expand All @@ -85,7 +117,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"spanAttributeKey": "tfy.span_type", "operator": "eq", "value": "LLM"}
{"spanAttributeKey": "tfy.span_type", "operator": "EQUAL", "value": "LLM"}
],
"limit": 200,
"sortDirection": "desc"
Expand Down Expand Up @@ -125,7 +157,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"spanAttributeKey": "tfy.span_type", "operator": "eq", "value": "MCP"}
{"spanAttributeKey": "tfy.span_type", "operator": "EQUAL", "value": "MCP"}
],
"limit": 50,
"sortDirection": "desc"
Expand Down Expand Up @@ -153,7 +185,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"spanFieldName": "spanName", "operator": "contains", "value": "completions"}
{"spanFieldName": "spanName", "operator": "STRING_CONTAINS", "value": "completions"}
],
"limit": 50,
"sortDirection": "desc"
Expand All @@ -167,7 +199,7 @@ $TFY_API_SH POST '/api/svc/v1/spans/query' '{
"startTime": "2026-03-26T00:00:00.000Z",
"dataRoutingDestination": "default",
"filters": [
{"gatewayRequestMetadataKey": "tfy_gateway_region", "operator": "eq", "value": "US"}
{"gatewayRequestMetadataKey": "tfy_gateway_region", "operator": "EQUAL", "value": "US"}
],
"limit": 50,
"sortDirection": "desc"
Expand Down Expand Up @@ -222,7 +254,62 @@ Custom metadata keys set via `X-TFY-LOGGING-CONFIG` headers.

#### Filter Operators

`eq`, `neq`, `contains`, `not_contains`, `starts_with`, `ends_with`
`EQUAL`, `IN`, `NOT_IN`, `STRING_CONTAINS`, `STRING_STARTS_WITH`, `STRING_ENDS_WITH`, `GREATER_THAN`, `LESS_THAN`

### Aggregate Cost Recipes

#### Total Cost for a Time Range

```bash
$TFY_API_SH POST '/api/svc/v1/llm-gateway/metrics/query' '{
"startTs": "2026-02-20T00:00:00.000Z",
"endTs": "2026-05-20T00:00:00.000Z",
"datasource": "modelMetrics",
"type": "distribution",
"aggregations": [
{"type": "count", "column": "costInUSD"},
{"type": "sum", "column": "costInUSD"},
{"type": "sum", "column": "inputTokens"},
{"type": "sum", "column": "outputTokens"}
]
}'
```

#### Cost by Model

Use the same body and add:

```json
"groupBy": ["modelName"]
```

#### Cost by User, Team, or Virtual Account

Use one of these groupings:

```json
"groupBy": ["userEmail"]
"groupBy": ["team"]
"groupBy": ["virtualaccount"]
```

#### Error or Latency Summary

```bash
$TFY_API_SH POST '/api/svc/v1/llm-gateway/metrics/query' '{
"startTs": "2026-02-20T00:00:00.000Z",
"endTs": "2026-05-20T00:00:00.000Z",
"datasource": "modelMetrics",
"type": "distribution",
"aggregations": [
{"type": "count", "column": "costInUSD"},
{"type": "p50", "column": "latencyMs"},
{"type": "p90", "column": "latencyMs"},
{"type": "p99", "column": "latencyMs"}
],
"groupBy": ["errorCode"]
}'
```

### Response Structure

Expand Down
25 changes: 23 additions & 2 deletions skills/platform/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ Platform setup and access management: verify credentials, discover workspaces an
- Verify TrueFoundry credentials and connectivity (preflight check)
- List clusters, workspaces, GPU types, or base domains
- Find workspace FQNs for deployment targets
- Invite users by email
- List or create roles, teams, or collaborators
- Manage secret groups and secret references (`tfy-secret://`)
- List and create personal access tokens (PATs)
- List and create personal access tokens (PATs) and virtual accounts (VATs)

## When NOT to Use

Expand Down Expand Up @@ -96,6 +97,7 @@ Manage roles, teams, and collaborators. For full API calls, tool call syntax, pr

| Action | API Call |
|--------|---------|
| Invite user | `$TFY_API_SH POST /api/svc/v1/users/invite '{...}'` |
| List roles | `$TFY_API_SH GET /api/svc/v1/roles` |
| List teams | `$TFY_API_SH GET /api/svc/v1/teams` |
| List collaborators | `$TFY_API_SH GET '/api/svc/v1/collaborators?resourceType=TYPE&resourceId=ID'` |
Expand All @@ -109,6 +111,19 @@ Subject format: `user:email`, `team:slug`, `serviceaccount:name`, `virtualaccoun

Destructive operations (delete roles, teams, collaborators): direct to dashboard.

### Invite Users

Use this for "invite new users by email" requests.

1. Collect email addresses.
2. Confirm target tenant.
3. Ask whether to only invite or also grant access to a resource.
4. If granting access, list roles/resources first and ask for explicit confirmation.

```bash
$TFY_API_SH POST /api/svc/v1/users/invite '{"emails":["alice@example.com"]}'
```

## Secrets

Manage secret groups and `tfy-secret://` references. Never ask user to paste secret values in chat.
Expand All @@ -129,19 +144,25 @@ For full create/update flows, API patterns, and security policies, see [referenc

## Access Tokens

List and create PATs. Token values are shown only once at creation.
List and create PATs and manage virtual accounts/VATs. Token values are shown only once at creation or retrieval/regeneration time.

| Action | API Call |
|--------|---------|
| List PATs | `$TFY_API_SH GET /api/svc/v1/personal-access-tokens` |
| Create PAT | `$TFY_API_SH POST /api/svc/v1/personal-access-tokens '{"name":"..."}'` |
| List virtual accounts | `$TFY_API_SH GET /api/svc/v1/virtual-accounts` |
| Create/update virtual account | `$TFY_API_SH POST /api/svc/v1/virtual-accounts '{...}'` |
| Get VAT token | `$TFY_API_SH GET /api/svc/v1/virtual-accounts/ID/token` |
| Regenerate VAT token | `$TFY_API_SH POST /api/svc/v1/virtual-accounts/ID/regenerate-token` |

> **Security:** Never repeat, store, or log token values. Show masked preview by default; full value only on explicit confirmation.

For full token display policy and security rules, see [references/secrets-and-tokens.md](references/secrets-and-tokens.md).

Deletion: direct to dashboard.

Service accounts: this skill can grant roles to existing service account subjects using `serviceaccount:name`. Do not claim service-account creation is supported until the create endpoint or dashboard flow is verified.

</instructions>

<success_criteria>
Expand Down
61 changes: 54 additions & 7 deletions skills/platform/references/access-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@ Manage roles, teams, and collaborators. Roles define permission sets, teams grou

When using direct API, set `TFY_API_SH` to the full path of this skill's `scripts/tfy-api.sh`. See `references/tfy-api-setup.md` for paths per agent.

### Users

Use user workflows for listing existing users and inviting new users by email. Inviting a user and granting access are separate steps.

#### List Users

```bash
$TFY_API_SH GET /api/svc/v1/users
```

#### Invite Users by Email

Before inviting, collect the email addresses and confirm the target tenant. If the user also wants workspace or resource access, complete the invite first, then use the collaborator workflow after confirming the role and resource.

```bash
$TFY_API_SH POST /api/svc/v1/users/invite '{"emails":["alice@example.com","bob@example.com"]}'
```

Present:

```text
Invites:
| Email | Status |
|-------|--------|
| alice@example.com | invited |
```

### Roles

Roles are named permission sets scoped to a resource type. Built-in roles vary by resource type (for example, `workspace-admin`, `workspace-member`).
Expand Down Expand Up @@ -217,22 +244,29 @@ To remove this collaborator, open the TrueFoundry dashboard, go to the resource

#### Grant a User Access to a Workspace

1. List roles to find the appropriate role ID (e.g., `workspace-admin` or `workspace-member`)
2. Add the user as a collaborator on the workspace with that role
1. Invite the user first if they do not already exist in the tenant.
2. List roles to find the appropriate role ID (e.g., `workspace-admin` or `workspace-member`).
3. Confirm the email, workspace, and role with the user.
4. Add the user as a collaborator on the workspace with that role.

```bash
# Optional: invite the user
$TFY_API_SH POST /api/svc/v1/users/invite '{"emails":["alice@example.com"]}'

# 1. Find the role ID
$TFY_API_SH GET /api/svc/v1/roles

# 2. Add collaborator
# 2. Add collaborator after confirmation
$TFY_API_SH POST /api/svc/v1/collaborators '{"resourceType":"workspace","resourceId":"WORKSPACE_ID","subject":"user:alice@company.com","roleId":"ROLE_ID"}'
```

#### Create a Team and Grant Access

1. Create the team
2. Add members to the team
3. Add the team as a collaborator on the target resource
1. Create the team.
2. Add members to the team.
3. List roles and select the role ID.
4. Confirm the team, resource, and role with the user.
5. Add the team as a collaborator on the target resource.

```bash
# 1. Create team
Expand All @@ -241,10 +275,23 @@ $TFY_API_SH POST /api/svc/v1/teams '{"name":"ml-engineers","description":"ML eng
# 2. Add members (use team ID from response)
$TFY_API_SH POST /api/svc/v1/teams/TEAM_ID/members '{"subject":"user:alice@company.com","role":"member"}'

# 3. Grant team access to a workspace
# 3. Grant team access to a workspace after confirmation
$TFY_API_SH POST /api/svc/v1/collaborators '{"resourceType":"workspace","resourceId":"WORKSPACE_ID","subject":"team:ml-engineers","roleId":"ROLE_ID"}'
```

#### Create a Custom Role and Grant It to a Team

1. Define the role name, resource type, and permission list.
2. Create the role.
3. Create or select the team.
4. Confirm the final subject/resource/role binding.
5. Add the team as a collaborator.

```bash
$TFY_API_SH POST /api/svc/v1/roles '{"name":"custom-deployer","displayName":"Custom Deployer","description":"Can deploy apps","resourceType":"workspace","permissions":["deploy:create","deploy:read"]}'
$TFY_API_SH POST /api/svc/v1/collaborators '{"resourceType":"workspace","resourceId":"WORKSPACE_ID","subject":"team:ml-engineers","roleId":"ROLE_ID_FROM_RESPONSE"}'
```

#### Audit Access on a Resource

List all collaborators to see who has access and with what role:
Expand Down
Loading
Loading