- Added EveAI Client to project

- Improvements to EntitlementsDomain & Services
- Prechecks in Document domain
- Add audit information to LicenseUsage
This commit is contained in:
Josako
2025-05-17 15:56:14 +02:00
parent b4f7b210e0
commit 5c982fcc2c
260 changed files with 48683 additions and 43 deletions

View File

@@ -0,0 +1,17 @@
from flask import Blueprint, render_template, current_app
from eveai_client.platform.extensions import config_manager
main_bp = Blueprint('main', __name__)
@main_bp.route('/')
def index():
"""Main page - shows specialist selection."""
specialists = config_manager.get_available_specialists()
return render_template('specialist_list.html', specialists=specialists)
@main_bp.route('/test')
def test():
"""Test route to verify the Flask app is working."""
return "EveAI Client is running!"

View File

@@ -0,0 +1,112 @@
from flask import Blueprint, render_template, request, jsonify, Response, current_app, stream_with_context
import json
from datetime import datetime as dt
from eveai_client.platform.extensions import config_manager
from eveai_client.platform.services.specialist_service import process_stream_updates
from eveai_client.platform.extensions import api_client, ui
specialist_bp = Blueprint('specialist', __name__, url_prefix='/specialist')
@specialist_bp.route('/<int:specialist_id>')
def get_specialist_form(specialist_id: int):
"""Get and render specialist form with chat interface."""
try:
specialist = next(
(s for s in current_app.config['SPECIALISTS'] if s['id'] == specialist_id),
{'name': f'Specialist {specialist_id}', 'description': ''}
)
config = config_manager.get_specialist_config(specialist_id)
if not config:
config = api_client.get_specialist_config(specialist_id)
config_manager.save_specialist_config(specialist_id, config)
return ui.render_specialist_form(specialist_id, specialist, config)
except Exception as e:
return render_template('error.html', error=str(e))
@specialist_bp.route('/start_session')
def start_session():
"""Start a new session and return the session ID as JSON."""
try:
session_id = api_client.start_session()
return jsonify({'session_id': session_id})
except Exception as e:
return jsonify({'error': str(e)}), 500
@specialist_bp.route('/execute', methods=['POST'])
def execute_specialist():
"""Execute specialist with query and return chat message HTML."""
try:
specialist_id = int(request.form['specialist_id'])
query = request.form.get('query', '')
session_id = request.form.get('session_id', '')
# If no session ID provided, get a new one
if not session_id:
session_id = api_client.start_session()
# Extract all arguments from the form
arguments = {}
for key, value in request.form.items():
if key not in ['specialist_id', 'session_id']:
arguments[key] = value
# Execute specialist
execution_data = api_client.execute_specialist(
specialist_id=specialist_id,
arguments=arguments,
session_id=session_id
)
task_id = execution_data['task_id']
stream_url = api_client.base_url + execution_data['stream_url']
# Store the stream URL for later use
if not hasattr(current_app, 'stream_urls'):
current_app.stream_urls = {}
current_app.stream_urls[task_id] = stream_url
# Return HTML for user message and AI response placeholder
return ui.render_message_exchange(query, task_id)
except Exception as e:
return ui.render_error(str(e))
@specialist_bp.route('/process/<task_id>')
def process_specialist_stream(task_id: str):
"""Process the SSE stream in the backend and update UI accordingly."""
if not hasattr(current_app, 'stream_urls'):
print('No stream URLs registered')
return jsonify({'error': 'No stream URLs registered'}), 400
if task_id not in current_app.stream_urls:
print(f'No stream URL found for task {task_id}')
return jsonify({'error': f'No stream URL found for task {task_id}'}), 400
stream_url = current_app.stream_urls[task_id]
print(f'Processing stream {stream_url}')
def generate():
try:
for update in process_stream_updates(api_client, stream_url, task_id):
# Format as proper SSE data
if isinstance(update, dict):
yield f"data: {json.dumps(update)}\n\n"
else:
yield f"data: {json.dumps({'message': update})}\n\n"
except Exception as e:
current_app.logger.error(f"Stream error: {str(e)}")
yield f"data: {json.dumps({'type': 'error', 'message': str(e)})}\n\n"
return Response(
stream_with_context(generate()),
mimetype='text/event-stream',
headers={
'Cache-Control': 'no-cache',
'X-Accel-Buffering': 'no'
}
)