harnessed_agent/wwwroot/v1/chat/completions.dspy
yumoqing 608413a5d5 feat: implement OpenAI-compatible LLM API
- Add /v1/chat/completions endpoint (POST) with streaming support
- Add /v1/models endpoint (GET) listing available models
- Add /v1/completions endpoint (POST) legacy compatibility
- Add llm_api.py module with OpenAI API proxy via aiohttp
- Add llm_service_url, llm_api_key, available_models to config model
- Update harnessed_agent_config_view CRUD to protect API key field
- Register new functions in init.py (harnessed_llm_chat_completions etc.)
- Add .gitignore for pycache files

Endpoints available under module path:
  POST /harnessed_agent/v1/chat/completions
  GET  /harnessed_agent/v1/models
  POST /harnessed_agent/v1/completions
2026-05-07 11:36:35 +08:00

47 lines
1.3 KiB
Plaintext

"""
OpenAI-compatible /v1/chat/completions endpoint
Accepts POST with JSON body matching OpenAI API format.
"""
import json
async def main():
# Read request body
body = {}
try:
raw_body = await request.read()
if raw_body:
body = json.loads(raw_body)
except Exception as e:
result = {
'error': {
'message': f'Invalid JSON body: {str(e)}',
'type': 'invalid_request_error',
'code': 400,
}
}
return json.dumps(result, ensure_ascii=False)
# Pass the request object for streaming support
body['_request'] = request
# Call the LLM API handler
result = await harnessed_llm_chat_completions(body)
# Handle streaming response (StreamResponse)
from aiohttp.web_response import StreamResponse
if isinstance(result, StreamResponse):
return result
# Handle error response
if 'error' in result:
status_code = result.get('error', {}).get('code', 500)
resp = web.Response(
status=status_code,
body=json.dumps(result, ensure_ascii=False),
content_type='application/json'
)
return resp
# Return successful response
return json.dumps(result, ensure_ascii=False)