Repository: ErikBjare/gptme
File: gptme/server/api.py (Python)

Code before:
                        break

                # Store the complete message
                msg = Message("assistant", output)
                msg = msg.replace(quiet=True)
                manager.append(msg)
                yield f"data: {flask.json.dumps({'role': 'assistant', 'content': output, 'stored': True})}\n\n"

                # Recursively handle any new tool uses
                if any(
                    tooluse.is_runnable for tooluse in ToolUse.iter_from_content(output)
                ):
                    yield from generate()

        except GeneratorExit:
            logger.info("Client disconnected during generation, interrupting")
            if output:
                output += "\n\n[interrupted]"
                msg = Message("assistant", output)
                msg = msg.replace(quiet=True)
                manager.append(msg)
            raise
        except Exception as e:
            logger.exception("Error during generation")
            yield f"data: {flask.json.dumps({'error': str(e)})}\n\n"
        finally:
            logger.info("Generation completed")

    return flask.Response(
        generate(),
        mimetype="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "X-Accel-Buffering": "no",  # Disable buffering in nginx
        },
    )


gptme_path_ctx = resources.as_file(resources.files("gptme"))
root_path = gptme_path_ctx.__enter__()
static_path = root_path / "server" / "static"
media_path = root_path.parent / "media"
atexit.register(gptme_path_ctx.__exit__, None, None, None)


# serve index.html from the root
@api.route("/")
def root():
    return current_app.send_static_file("index.html")



Review comment (suggestion):
This is fine, but in dev mode/staging/CI we actually want to see the errors. Consider adding some kind of flag which includes more details when not running "prod" (or when a dev-mode env variable is given, so it can be enabled).

Code after:
                    if tooluses and any(tooluse.is_runnable for tooluse in tooluses):
                        break

                # Store the complete message
                msg = Message("assistant", output)
                msg = msg.replace(quiet=True)
                manager.append(msg)
                yield f"data: {flask.json.dumps({'role': 'assistant', 'content': output, 'stored': True})}\n\n"

                # Recursively handle any new tool uses
                if any(
                    tooluse.is_runnable for tooluse in ToolUse.iter_from_content(output)
                ):
                    yield from generate()

        except GeneratorExit:
            logger.info("Client disconnected during generation, interrupting")
            if output:
                output += "\n\n[interrupted]"
                msg = Message("assistant", output)
                msg = msg.replace(quiet=True)
                manager.append(msg)
            raise
        except Exception:
            logger.exception("Error during generation")
            yield f"data: {flask.json.dumps({'error': 'An internal error occurred during generation'})}\n\n"
        finally:
            logger.info("Generation completed")

    return flask.Response(
        generate(),
        mimetype="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "X-Accel-Buffering": "no",  # Disable buffering in nginx
        },
    )


gptme_path_ctx = resources.as_file(resources.files("gptme"))
root_path = gptme_path_ctx.__enter__()
static_path = root_path / "server" / "static"
media_path = root_path.parent / "media"
atexit.register(gptme_path_ctx.__exit__, None, None, None)


# serve index.html from the root
@api.route("/")
def root():
    return current_app.send_static_file("index.html")