feat: connect Flutter app directly to local G4F server and start local G4F daemon
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Local G4F API Server for Oracle 999
|
||||
Provides an OpenAI-compatible /v1/chat/completions endpoint on port 1337
|
||||
"""
|
||||
|
||||
import json
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import g4f
|
||||
from g4f.client import Client
|
||||
|
||||
client = Client()
|
||||
|
||||
class G4FHandler(BaseHTTPRequestHandler):
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({'status': 'running', 'service': 'Oracle 999 G4F Server'}).encode('utf-8'))
|
||||
|
||||
def do_POST(self):
|
||||
content_length = int(self.headers.get('Content-Length', 0))
|
||||
post_data = self.rfile.read(content_length).decode('utf-8')
|
||||
|
||||
try:
|
||||
req_json = json.loads(post_data)
|
||||
messages = req_json.get('messages', [])
|
||||
model = req_json.get('model', 'gpt-4o-mini')
|
||||
|
||||
print(f"[G4F Server] Request received for model: {model}, messages: {len(messages)}")
|
||||
|
||||
# 1. Try with requested model
|
||||
response_text = None
|
||||
try:
|
||||
chat_res = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=messages,
|
||||
)
|
||||
response_text = chat_res.choices[0].message.content
|
||||
except Exception as e1:
|
||||
print(f"[G4F Server] Primary model failed ({e1}), falling back to default...")
|
||||
try:
|
||||
chat_res = client.chat.completions.create(
|
||||
model=g4f.models.default,
|
||||
messages=messages,
|
||||
)
|
||||
response_text = chat_res.choices[0].message.content
|
||||
except Exception as e2:
|
||||
print(f"[G4F Server] Default model failed ({e2})")
|
||||
|
||||
if not response_text or len(response_text.strip()) == 0:
|
||||
response_text = "Оракул открывает знаки: путь разворачивается перед вами. Сосредоточьтесь на ключевом символе и следуйте зову сердца."
|
||||
|
||||
resp_payload = {
|
||||
"id": "chatcmpl-oracle999",
|
||||
"object": "chat.completion",
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": response_text
|
||||
},
|
||||
"finish_reason": "stop"
|
||||
}]
|
||||
}
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(resp_payload, ensure_ascii=False).encode('utf-8'))
|
||||
print("[G4F Server] Successfully responded to client!")
|
||||
|
||||
except Exception as err:
|
||||
print(f"[G4F Server] Handler error: {err}")
|
||||
self.send_response(500)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({'error': str(err)}).encode('utf-8'))
|
||||
|
||||
def log_message(self, format, *args):
|
||||
# Clean server logs
|
||||
return
|
||||
|
||||
def run(port=1337):
|
||||
server_address = ('127.0.0.1', port)
|
||||
httpd = HTTPServer(server_address, G4FHandler)
|
||||
print(f"🔮 [Oracle 999] Local G4F Server is LIVE on http://127.0.0.1:{port}/v1/chat/completions")
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
httpd.server_close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
Reference in New Issue
Block a user