Skip to content

Commit 940c8ae

Browse files
authored
docs: solves partially #1617 - basic structure for TS SDK docs (#1722)
* docs: solves partially #1617 - basic structure for TS SDK docs Signed-off-by: Tomas Weiss <[email protected]> * chore: basic structure for TS docs Signed-off-by: Tomas Weiss <[email protected]> * chore: extensions page Signed-off-by: Tomas Weiss <[email protected]> * docs: api client Signed-off-by: Tomas Weiss <[email protected]> --------- Signed-off-by: Tomas Weiss <[email protected]>
1 parent 5017241 commit 940c8ae

File tree

5 files changed

+455
-13
lines changed

5 files changed

+455
-13
lines changed

docs/development/custom-ui/client-sdk.mdx

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
---
2+
title: Agent Stack API Client
3+
description: Complete reference for the AgentStack platform API client and context management
4+
---
5+
6+
The `buildApiClient` function creates a type-safe HTTP client for interacting with the AgentStack platform API. This client enables you to manage contexts, generate tokens with permissions, match model providers, and list connectors.
7+
8+
## Initialization
9+
10+
Create an API client by calling `buildApiClient` with configuration options:
11+
12+
```typescript
13+
import { buildApiClient } from 'agentstack-sdk';
14+
15+
const api = buildApiClient({
16+
baseUrl: 'https://your-agentstack-instance.com',
17+
fetch: customFetch, // Optional: provide custom fetch implementation
18+
});
19+
```
20+
21+
### Configuration Options
22+
23+
- **`baseUrl`** (required): The base URL of your AgentStack server instance
24+
- **`fetch`** (optional): Custom fetch implementation. Required in Node.js < 18 or environments without global fetch support. Useful for adding authentication headers or custom request handling.
25+
26+
### Example: Authenticated Client
27+
28+
In many applications, you'll want to add authentication headers to requests:
29+
30+
```typescript
31+
const authenticatedFetch: typeof fetch = async (url, init) => {
32+
const request = new Request(url, init);
33+
34+
// Add your authentication token
35+
const token = await getAuthToken();
36+
request.headers.set('Authorization', `Bearer ${token}`);
37+
38+
return fetch(request);
39+
};
40+
41+
const api = buildApiClient({
42+
baseUrl: 'https://your-agentstack-instance.com',
43+
fetch: authenticatedFetch,
44+
});
45+
```
46+
47+
## API Methods
48+
49+
### `createContext(providerId: string)`
50+
51+
Creates a new agent context. Contexts are isolated workspaces where agents can store files, vector stores, and other context-specific data.
52+
53+
**Parameters:**
54+
- `providerId`: The ID of the provider to associate with this context
55+
56+
**Returns:** `Promise<CreateContextResponse>`
57+
58+
```typescript
59+
const context = await api.createContext('my-provider-id');
60+
console.log(context.id); // Use this ID for subsequent operations
61+
```
62+
63+
**Response Type:**
64+
```typescript
65+
interface CreateContextResponse {
66+
id: string;
67+
created_at: string;
68+
updated_at: string;
69+
last_active_at: string;
70+
created_by: string;
71+
provider_id: string | null;
72+
metadata: Record<string, unknown> | null;
73+
}
74+
```
75+
76+
### `createContextToken(params: CreateContextTokenParams)`
77+
78+
Generates a context token with specific permissions. Context tokens are used to grant agents access to platform resources through the [Platform API extension](/development/custom-ui/client-sdk/extensions#dependency-injection-service-extensions).
79+
80+
**Parameters:**
81+
- `contextId`: The ID of the context to create a token for
82+
- `globalPermissions`: Permissions that apply across all contexts
83+
- `contextPermissions`: Permissions specific to this context
84+
85+
**Returns:** `Promise<{ token: ContextToken; contextId: string }>`
86+
87+
```typescript
88+
const { token, contextId } = await api.createContextToken({
89+
contextId: context.id,
90+
globalPermissions: {
91+
llm: ['*'], // Grant access to all LLM providers
92+
embeddings: ['*'], // Grant access to all embedding providers
93+
a2a_proxy: ['*'], // Allow A2A proxy access
94+
},
95+
contextPermissions: {
96+
files: ['*'], // Full file access in this context
97+
vector_stores: ['*'], // Full vector store access
98+
context_data: ['*'], // Full context data access
99+
},
100+
});
101+
102+
// Use token.token to pass to agents via Platform API extension
103+
```
104+
105+
**Token Type:**
106+
```typescript
107+
interface ContextToken {
108+
token: string;
109+
expires_at: string | null;
110+
}
111+
```
112+
113+
### Permissions
114+
115+
Permissions control what resources agents can access. There are two types:
116+
117+
#### Global Permissions
118+
119+
Apply across all contexts and control access to platform-wide resources:
120+
121+
- **`llm`**: Access to LLM providers. Can be `['*']` for all providers or an array of specific provider IDs
122+
- **`embeddings`**: Access to embedding providers. Same format as `llm`
123+
- **`model_providers`**: Read/write access to model provider configurations
124+
- **`a2a_proxy`**: Access to A2A proxy services
125+
- **`providers`**: Access to provider management
126+
- **`provider_variables`**: Access to provider environment variables
127+
- **`contexts`**: Access to context management
128+
- **`mcp_providers`**: Access to MCP providers
129+
- **`mcp_tools`**: Access to MCP tools
130+
- **`mcp_proxy`**: Access to MCP proxy
131+
- **`connectors`**: Access to connector management
132+
- **`feedback`**: Ability to submit feedback
133+
134+
#### Context Permissions
135+
136+
Apply only to the specific context:
137+
138+
- **`files`**: File operations (`read`, `write`, `extract`, or `*` for all)
139+
- **`vector_stores`**: Vector store operations (`read`, `write`, or `*` for all)
140+
- **`context_data`**: Context metadata operations (`read`, `write`, or `*` for all)
141+
142+
### `matchProviders(params: MatchProvidersParams)`
143+
144+
Finds model providers that match specified criteria. This is typically used when fulfilling LLM or embedding service extension demands.
145+
146+
**Parameters:**
147+
- `suggestedModels`: Array of preferred model IDs, or `null` to match any model
148+
- `capability`: Either `ModelCapability.Llm` or `ModelCapability.Embedding`
149+
- `scoreCutoff`: Minimum match score (0.0 to 1.0). Higher values require better matches.
150+
151+
**Returns:** `Promise<ModelProviderMatch>`
152+
153+
```typescript
154+
import { ModelCapability } from 'agentstack-sdk';
155+
156+
const matches = await api.matchProviders({
157+
suggestedModels: ['gpt-4', 'gpt-3.5-turbo'],
158+
capability: ModelCapability.Llm,
159+
scoreCutoff: 0.4,
160+
});
161+
162+
if (matches.items.length > 0) {
163+
const bestMatch = matches.items[0];
164+
console.log(`Best match: ${bestMatch.model_id} (score: ${bestMatch.score})`);
165+
}
166+
```
167+
168+
**Response Type:**
169+
```typescript
170+
interface ModelProviderMatch {
171+
items: Array<{
172+
model_id: string;
173+
score: number;
174+
}>;
175+
total_count: number;
176+
has_more: boolean;
177+
next_page_token: string | null;
178+
}
179+
```
180+
181+
### `listConnectors()`
182+
183+
Lists all available connectors in the platform. Connectors enable agents to integrate with external services and APIs.
184+
185+
**Returns:** `Promise<ListConnectorsResponse>`
186+
187+
```typescript
188+
const connectors = await api.listConnectors();
189+
190+
for (const connector of connectors.items) {
191+
console.log(`${connector.id}: ${connector.state}`);
192+
193+
if (connector.state === ConnectorState.AuthRequired) {
194+
// Handle OAuth flow using connector.auth_request
195+
}
196+
}
197+
```
198+
199+
**Response Type:**
200+
```typescript
201+
interface ListConnectorsResponse {
202+
items: Connector[];
203+
total_count: number;
204+
has_more: boolean;
205+
next_page_token: string | null;
206+
}
207+
208+
interface Connector {
209+
id: string;
210+
url: string;
211+
state: ConnectorState;
212+
auth_request: {
213+
type: 'code';
214+
authorization_endpoint: string;
215+
} | null;
216+
disconnect_reason: string | null;
217+
metadata: Record<string, string> | null;
218+
}
219+
220+
enum ConnectorState {
221+
Created = 'created',
222+
AuthRequired = 'auth_required',
223+
Connected = 'connected',
224+
Disconnected = 'disconnected',
225+
}
226+
```
227+
228+
## Common Usage Patterns
229+
230+
### Creating a Context and Token for an Agent
231+
232+
The most common pattern is creating a context and generating a token with appropriate permissions:
233+
234+
```typescript
235+
// 1. Create a context
236+
const context = await api.createContext('my-provider-id');
237+
238+
// 2. Generate a token with permissions
239+
const { token } = await api.createContextToken({
240+
contextId: context.id,
241+
globalPermissions: {
242+
llm: ['*'],
243+
embeddings: ['*'],
244+
a2a_proxy: ['*'],
245+
},
246+
contextPermissions: {
247+
files: ['*'],
248+
vector_stores: ['*'],
249+
context_data: ['*'],
250+
},
251+
});
252+
253+
// 3. Use the token in your Platform API extension fulfillment
254+
// The token.token value is passed as the api_key in the fulfillment
255+
```
256+
257+
### Fulfilling LLM Demands
258+
259+
When an agent requests LLM access, use `matchProviders` to find suitable models:
260+
261+
```typescript
262+
import { buildLLMExtensionFulfillmentResolver } from 'agentstack-sdk';
263+
264+
// Create context and token first
265+
const context = await api.createContext('my-provider-id');
266+
const { token } = await api.createContextToken({
267+
contextId: context.id,
268+
globalPermissions: { llm: ['*'], a2a_proxy: ['*'] },
269+
contextPermissions: { files: ['*'] },
270+
});
271+
272+
// Build the LLM fulfillment resolver
273+
const llmResolver = buildLLMExtensionFulfillmentResolver(api, token);
274+
275+
// Use in your fulfillments when calling resolveMetadata
276+
const { resolveMetadata } = handleAgentCard(agentCard);
277+
const metadata = resolveMetadata({
278+
llm: llmResolver,
279+
// ... other fulfillments
280+
});
281+
```
282+
283+
284+
## Type Safety
285+
286+
All API methods are fully typed with TypeScript and use Zod schemas for runtime validation. Response data is automatically validated against these schemas, ensuring type safety and catching API contract changes at runtime.
287+
288+
## Next Steps
289+
290+
- **[Extensions](/development/custom-ui/client-sdk/extensions)** - Learn how to use the API client with extension fulfillments
291+
- **[Examples](/development/custom-ui/client-sdk/examples)** - See complete integration examples
292+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: Extensions
3+
description: Service and UI extensions for agent communication and capabilities
4+
---
5+
6+
Built on top of the [Agent2Agent Protocol (A2A)](https://a2a-protocol.org/), Agent Stack extends the protocol with Agent Stack-specific capabilities through [A2A extensions](https://a2a-protocol.org/latest/topics/extensions/). These extensions enable agents to access platform services and enhance the user interface beyond what the base A2A protocol provides.
7+
8+
There are two types of extensions:
9+
10+
## Dependency Injection Service Extensions
11+
12+
Service extensions use a dependency injection pattern where agents declare **demands** that must be fulfilled by the client (your application). The client provides configured access to external services based on these demands.
13+
14+
When an agent card is received, `handleAgentCard` extracts the service extension demands. You then provide fulfillment functions that resolve these demands with actual service configurations:
15+
16+
- **LLM Service**: Language model access with automatic provider selection
17+
- **Embedding Service**: Text embedding generation for RAG
18+
- **MCP**: Integrating pre-defined connectors
19+
- **OAuth Provider**: OAuth authentication services
20+
- **Secrets**: Secure credential management
21+
- **Settings**: Runtime configuration access
22+
- **Form**: Form service for structured data collection
23+
24+
The fulfillment process works like dependency injection: the agent declares what it needs, and your client provides the configured services.
25+
26+
## UI Extensions
27+
28+
UI extensions add extra metadata to messages, enabling your custom UI to render advanced interactive components beyond standard text responses:
29+
30+
- **Forms**: Collect structured user input through interactive forms
31+
- **Citations**: Display source references with clickable inline links
32+
- **Trajectory**: Visualize agent reasoning steps with execution traces
33+
- **Canvas**: Handle visual editing and canvas-based interactions
34+
- **Agent Detail**: Display agent-specific information and metadata
35+
- **Error**: Render structured error messages
36+
- **OAuth**: Handle OAuth authentication flows
37+
- **Settings**: Display and manage agent settings
38+
39+
These extensions enhance messages with metadata that your UI interprets to create rich, interactive experiences. The SDK provides type-safe parsers to extract this metadata from agent messages and task status updates.
40+
41+
42+
### Providing metadata
43+
44+
A2A extensions travel in message metadata. When you receive an agent card, call `handleAgentCard(agentCard)` to:
45+
46+
- Extract extension demands
47+
- Get a `resolveMetadata(fulfillments)` helper that builds the metadata the agent expects
48+
49+
You provide the `fulfillments` object with functions that resolve demands (dependency injection). Many fulfillments can be powered by the Platform API client—for example, using platform-provided LLM or embedding services.
50+
51+
### Common fulfilment resolvers
52+
53+
The SDK ships an LLM fulfillment resolver you can wire up quickly:
54+
55+
- Use `buildLLMExtensionFulfillmentResolver(api, contextToken)` to return a resolver for `LLM` demands. It matches suggested models via the Platform API and returns the fulfillment payload automatically.
56+
- Feed this resolver into your `fulfillments.llm` callback when calling `resolveMetadata(fulfillments)`.
57+
58+
Other fulfillments (embeddings, MCP, secrets, settings, forms, OAuth) are client-specific; use the Platform API client and your own UI flows (forms, OAuth prompts, secret capture) to build those resolvers.

0 commit comments

Comments
 (0)