@@ -4,28 +4,35 @@ The OSA REST API provides programmatic access to the assistant.
44
55## Base URL
66
7- `` `
8- http://localhost:38528
9- `` `
7+ - ** Production ** : ` https://api.osc.earth/osa `
8+ - ** Development ** : ` https://api.osc.earth/osa-dev `
9+ - ** Local ** : ` http://localhost:38528 `
1010
1111## Authentication
1212
1313OSA supports two authentication modes:
1414
1515### Server API Key
1616
17+ For server-to-server access using an admin key:
18+
1719``` bash
18- curl -H " X-API-Key: your-server-key" http ://localhost:38528/chat
20+ curl -H " X-API-Key: your-server-key" https ://api.osc.earth/osa/health
1921```
2022
2123### BYOK (Bring Your Own Key)
2224
23- Pass your OpenRouter API key directly:
25+ Pass your OpenRouter API key directly. This is the primary method for CLI and widget users :
2426
2527``` bash
26- curl -H " X-OpenRouter-Key: your-openrouter-key" http://localhost:38528/chat
28+ curl -H " X-OpenRouter-Key: your-openrouter-key" \
29+ https://api.osc.earth/osa/hed/ask \
30+ -H " Content-Type: application/json" \
31+ -d ' {"question": "What is HED?"}'
2732```
2833
34+ When using BYOK, no server API key is required. The user's key is forwarded to the LLM provider.
35+
2936## Endpoints
3037
3138### Health Check
@@ -40,25 +47,8 @@ Response:
4047``` json
4148{
4249 "status" : " healthy" ,
43- "version" : " 0.1.0"
44- }
45- ```
46-
47- ### API Info
48-
49- Get API information.
50-
51- ```
52- GET /info
53- ```
54-
55- Response:
56- ``` json
57- {
58- "name" : " Open Science Assistant" ,
59- "version" : " 0.1.0" ,
60- "assistants" : [" hed" , " bids" , " eeglab" ],
61- "models" : [" openai/gpt-4.1-mini" , " anthropic/claude-3-5-haiku" ]
50+ "version" : " 0.7.0" ,
51+ "environment" : " production"
6252}
6353```
6454
@@ -91,116 +81,213 @@ Response:
9181]
9282```
9383
94- This endpoint is public (no authentication required) and is used by the widget to load display configuration from the community YAML configs.
84+ This endpoint is public (no authentication required).
85+
86+ ### Ask
87+
88+ Ask a single question to a community assistant.
89+
90+ ```
91+ POST /{community}/ask
92+ Content-Type: application/json
93+ X-OpenRouter-Key: your-key
94+
95+ {
96+ "question": "How do I annotate a button press in HED?",
97+ "stream": true
98+ }
99+ ```
100+
101+ #### Non-streaming Response
102+
103+ When ` stream: false ` :
104+
105+ ``` json
106+ {
107+ "answer" : " To annotate a button press in HED..." ,
108+ "tool_calls" : []
109+ }
110+ ```
111+
112+ #### Streaming Response (SSE)
113+
114+ When ` stream: true ` (default):
115+
116+ ```
117+ data: {"event": "content", "content": "To"}
118+
119+ data: {"event": "content", "content": " annotate"}
120+
121+ data: {"event": "tool_start", "name": "retrieve_hed_docs", "params": {...}}
122+
123+ data: {"event": "tool_end", "name": "retrieve_hed_docs", "result": "..."}
124+
125+ data: {"event": "content", "content": "..."}
126+
127+ data: {"event": "done"}
128+ ```
95129
96130### Chat
97131
98- Send a message and receive a streaming response .
132+ Multi-turn chat with conversation history .
99133
100134```
101- POST /chat
135+ POST /{community}/ chat
102136Content-Type: application/json
137+ X-OpenRouter-Key: your-key
103138
104139{
105140 "message": "How do I annotate a button press in HED?",
106141 "session_id": "optional-session-id",
107- "assistant": "hed",
108- "model": "openai/gpt-4.1-mini"
142+ "stream": true
109143}
110144```
111145
112- Response (Server-Sent Events):
146+ #### Non-streaming Response
147+
148+ ``` json
149+ {
150+ "session_id" : " abc123" ,
151+ "message" : {
152+ "role" : " assistant" ,
153+ "content" : " To annotate a button press..."
154+ },
155+ "tool_calls" : []
156+ }
113157```
114- data: {"type": "start", "session_id": "abc123"}
115158
116- data: {"type": "token", "content": "To"}
159+ #### Streaming Response (SSE)
117160
118- data: {"type": "token", "content": " annotate"}
161+ ```
162+ data: {"event": "session", "session_id": "abc123"}
119163
120- data: {"type ": "tool_call ", "tool ": "retrieve_hed_docs", "params": {...} }
164+ data: {"event ": "content ", "content ": "To" }
121165
122- data: {"type ": "tool_result ", "tool ": "retrieve_hed_docs", "result": {...} }
166+ data: {"event ": "tool_start ", "name ": "retrieve_hed_docs"}
123167
124- data: {"type ": "token ", "content": "... "}
168+ data: {"event ": "content ", "content": " annotate "}
125169
126- data: {"type ": "end ", "usage ": {"prompt_tokens": 1234, "completion_tokens": 567} }
170+ data: {"event ": "done ", "session_id ": "abc123" }
127171```
128172
129173## Request Parameters
130174
175+ ### Ask Request
176+
177+ | Parameter | Type | Required | Description |
178+ | -----------| ------| ----------| -------------|
179+ | ` question ` | string | Yes | Question to ask |
180+ | ` stream ` | boolean | No | Enable SSE streaming (default: true) |
181+ | ` model ` | string | No | Custom LLM model (requires BYOK) |
182+
131183### Chat Request
132184
133185| Parameter | Type | Required | Description |
134186| -----------| ------| ----------| -------------|
135187| ` message ` | string | Yes | User message |
136188| ` session_id ` | string | No | Session ID for multi-turn chat |
137- | ` assistant ` | string | No | Assistant to use (hed, bids, eeglab) |
138- | ` model ` | string | No | LLM model to use |
189+ | ` stream ` | boolean | No | Enable SSE streaming (default: true) |
190+ | ` model ` | string | No | Custom LLM model (requires BYOK) |
191+
192+ ## Headers
193+
194+ | Header | Description | Required |
195+ | --------| -------------| ----------|
196+ | ` X-OpenRouter-Key ` | OpenRouter API key (BYOK) | Yes (or X-API-Key) |
197+ | ` X-API-Key ` | Server admin API key | Yes (or BYOK) |
198+ | ` X-User-ID ` | User ID for cache optimization | No |
199+ | ` Content-Type ` | Must be ` application/json ` | Yes |
139200
140201## Error Responses
141202
142- ### 400 Bad Request
203+ ### 401 Unauthorized
143204
144205``` json
145206{
146- "error" : " Invalid request" ,
147- "detail" : " Message is required"
207+ "detail" : " API key required (or provide your own LLM key via BYOK headers)"
148208}
149209```
150210
151- ### 401 Unauthorized
211+ ### 403 Forbidden
152212
153213``` json
154214{
155- "error" : " Unauthorized" ,
156- "detail" : " API key required"
215+ "detail" : " Invalid API key"
157216}
158217```
159218
160219### 500 Internal Server Error
161220
162221``` json
163222{
164- "error" : " Internal error" ,
165223 "detail" : " LLM provider error"
166224}
167225```
168226
169- ## Python Client
227+ ## Python Client Example
170228
171229``` python
172230import httpx
173231
174- async with httpx.AsyncClient() as client:
175- async with client.stream(
232+ # Non-streaming
233+ response = httpx.post(
234+ " https://api.osc.earth/osa/hed/ask" ,
235+ json = {" question" : " What is HED?" , " stream" : False },
236+ headers = {" X-OpenRouter-Key" : " your-key" },
237+ )
238+ print (response.json()[" answer" ])
239+ ```
240+
241+ ``` python
242+ import json
243+ import httpx
244+
245+ # Streaming
246+ with httpx.Client() as client:
247+ with client.stream(
176248 " POST" ,
177- " http ://localhost:38528/chat " ,
178- json = {" message " : " What is HED?" },
249+ " https ://api.osc.earth/osa/hed/ask " ,
250+ json = {" question " : " What is HED?" , " stream " : True },
179251 headers = {" X-OpenRouter-Key" : " your-key" },
180252 ) as response:
181- async for line in response.aiter_lines ():
253+ for line in response.iter_lines ():
182254 if line.startswith(" data: " ):
183255 data = json.loads(line[6 :])
184- if data[" type " ] == " token " :
256+ if data[" event " ] == " content " :
185257 print (data[" content" ], end = " " , flush = True )
186258```
187259
188260## cURL Examples
189261
190- ### Basic Query
262+ ### Ask (Non-streaming)
191263
192264``` bash
193- curl -X POST http ://localhost:38528/chat \
265+ curl -X POST https ://api.osc.earth/osa/hed/ask \
194266 -H " Content-Type: application/json" \
195267 -H " X-OpenRouter-Key: your-key" \
196- -d ' {"message ": "What is HED?"}'
268+ -d ' {"question ": "What is HED?", "stream": false }'
197269```
198270
199- ### With Session
271+ ### Ask (Streaming)
200272
201273``` bash
202- curl -X POST http://localhost:38528/chat \
274+ curl -N -X POST https://api.osc.earth/osa/hed/ask \
275+ -H " Content-Type: application/json" \
276+ -H " X-OpenRouter-Key: your-key" \
277+ -d ' {"question": "What is HED?"}'
278+ ```
279+
280+ ### Chat with Session
281+
282+ ``` bash
283+ curl -X POST https://api.osc.earth/osa/hed/chat \
284+ -H " Content-Type: application/json" \
285+ -H " X-OpenRouter-Key: your-key" \
286+ -d ' {"message": "What is HED?", "stream": false}'
287+
288+ # Continue conversation with session_id from response
289+ curl -X POST https://api.osc.earth/osa/hed/chat \
203290 -H " Content-Type: application/json" \
204291 -H " X-OpenRouter-Key: your-key" \
205- -d ' {"message": "Tell me more", "session_id": "my-session" }'
292+ -d ' {"message": "Tell me more", "session_id": "abc123", "stream": false }'
206293```
0 commit comments