fix: resolve startup issues and JSONL parsing bugs

- Add PYTHONPATH/DJANGO_SETTINGS_MODULE for Docker environment
- Fix gunicorn bind port (8000 instead of 8765)
- Add whitenoise for static file serving
- Fix JSONL parser: read role/content from event.message.* (nested structure)
- Fix session counts (message_count/tool_call_count/error_count were all 0)
- Increase DATA_UPLOAD_MAX_MEMORY_SIZE to 50MB for large batch syncs
- Add STATIC_ROOT and WhiteNoise middleware for admin CSS
- Fix index name length (>30 chars issue)
- Replace unique_together with indexes (Django 5.x compatible)
- Add graceful degradation for TimescaleDB hypertable creation
- Add static_volume/ to .gitignore
This commit is contained in:
ishenwei
2026-04-06 20:51:51 +08:00
parent 0653c26523
commit f205c42714
9 changed files with 54 additions and 32 deletions

View File

@@ -183,13 +183,15 @@ def parse_jsonl(file_path):
current_thinking_level = event.get("thinkingLevel", "")
elif event_type == "message":
role = event.get("role", "")
# Nested structure: message data is inside "message" object
message_obj = event.get("message", {})
role = message_obj.get("role", "")
msg_id = event.get("id", "")
parent_id = event.get("parentId", "")
msg_timestamp = event.get("timestamp", "")
# Extract text content (skip thinking)
content_items = event.get("content", [])
# Extract text content (skip thinking) from nested content
content_items = message_obj.get("content", [])
text_parts = []
tc_list = []
for item in content_items:
@@ -210,16 +212,16 @@ def parse_jsonl(file_path):
"role": role or "",
"content_text": content_text,
"raw_content": content_items if content_items else [],
"raw_message": event.get("content", []),
"raw_message": message_obj.get("content", []),
"timestamp": msg_timestamp,
}
if role == "assistant":
usage = event.get("usage", {})
usage = message_obj.get("usage", {})
msg_data.update({
"model": current_model_id,
"provider": current_model_provider,
"stop_reason": event.get("stopReason", ""),
"stop_reason": message_obj.get("stopReason", ""),
"tokens_input": usage.get("inputTokens", 0),
"tokens_output": usage.get("outputTokens", 0),
"tokens_cache_read": usage.get("cacheReadInputTokens", 0),
@@ -228,8 +230,8 @@ def parse_jsonl(file_path):
})
total_tokens += usage.get("totalTokens", 0)
if event.get("cost"):
cost_val = event["cost"].get("total", 0.0)
if message_obj.get("cost"):
cost_val = message_obj["cost"].get("total", 0.0)
msg_data["cost_total"] = cost_val
total_cost += cost_val
@@ -237,21 +239,20 @@ def parse_jsonl(file_path):
elif role == "toolResult":
msg_data.update({
"tool_call_id": event.get("toolCallId", ""),
"tool_name": event.get("toolName", ""),
"is_error": event.get("isError", False),
"exit_code": event.get("exitCode"),
"duration_ms": event.get("durationMs"),
"tool_call_id": message_obj.get("toolCallId", ""),
"tool_name": message_obj.get("toolName", ""),
"is_error": message_obj.get("isError", False),
"exit_code": message_obj.get("exitCode"),
"duration_ms": message_obj.get("durationMs"),
})
if event.get("isError"):
if message_obj.get("isError"):
error_count += 1
# Store for tool call association
if event.get("toolCallId"):
tool_results[event["toolCallId"]] = {
if message_obj.get("toolCallId"):
tool_results[message_obj["toolCallId"]] = {
"result_text": content_text,
"is_error": event.get("isError", False),
"exit_code": event.get("exitCode"),
"duration_ms": event.get("durationMs"),
"is_error": message_obj.get("isError", False),
"exit_code": message_obj.get("exitCode"),
"duration_ms": message_obj.get("durationMs"),
}
messages.append(msg_data)