Files
pi_harness/packages/agent/julia_implementation/src/session/jsonl_repo.jl
T
2026-07-28 07:12:13 +07:00

149 lines
4.5 KiB
Julia

"""
session/jsonl_repo.jl - JSONL session repository
This module provides a JSONL-based session repository implementation.
"""
module JsonlRepo
using ..Types: *
using ..SessionStorage: SessionStorage, SessionMetadata
using ..JsonlStorage: JsonlSessionStorage, headerToSessionMetadata
using ..MemoryRepo: createSessionId, createTimestamp, getEntriesToFork, toSession
using ..HarnessTypes: SessionRepo, SessionForkOptions
# ============================================================================
# JSONL session repository
# ============================================================================
mutable struct JsonlSessionRepo <: SessionRepo{
JsonlSessionMetadata,
JsonlSessionCreateOptions,
JsonlSessionListOptions
}
fs::Any
sessions_root_input::String
sessions_root::Union{String, Nothing}
function JsonlSessionRepo(; sessions_root::String, fs::Any)
new(fs, sessions_root, nothing)
end
end
# ============================================================================
# Session repo methods
# ============================================================================
function create(repo::JsonlSessionRepo, options::JsonlSessionCreateOptions)::Session
id = if haskey(options, :id) && !isnothing(options[:id])
options[:id]
else
createSessionId()
end
created_at = createTimestamp()
session_dir = getSessionDir(repo, options.cwd)
file_path = createSessionFilePath(repo, options.cwd, id, created_at)
storage = JsonlSessionStorage(
file_path,
SessionHeader(
"session",
3,
id,
created_at,
options.cwd,
get(options, :parentSessionPath, nothing),
get(options, :metadata, nothing),
),
SessionTreeEntry[],
nothing,
)
return toSession(storage)
end
function open(repo::JsonlSessionRepo, metadata::JsonlSessionMetadata)::Session
# TODO: Open existing file
return toSession(JsonlSessionStorage(
metadata.path,
SessionHeader(
"session",
3,
metadata.id,
metadata.created_at,
metadata.cwd,
metadata.parent_session_path,
metadata.metadata,
),
SessionTreeEntry[],
nothing,
))
end
function list(repo::JsonlSessionRepo, options::JsonlSessionListOptions=JsonlSessionListOptions())::Vector{JsonlSessionMetadata}
# TODO: List sessions
return JsonlSessionMetadata[]
end
function delete(repo::JsonlSessionRepo, metadata::JsonlSessionMetadata)::Nothing
# TODO: Delete session file
return nothing
end
function fork(repo::JsonlSessionRepo, source::JsonlSessionMetadata, options::Dict{String, Any})::Session
# TODO: Fork session
return create(repo, JsonlSessionCreateOptions(
cwd=get(options, "cwd", ""),
id=get(options, "id", createSessionId()),
))
end
# ============================================================================
# Helper functions
# ============================================================================
function getSessionsRoot(repo::JsonlSessionRepo)::String
if isnothing(repo.sessions_root)
repo.sessions_root = getFileSystemResultOrThrow(
absolutePath(repo.fs, repo.sessions_root_input),
"Failed to resolve sessions root $(repo.sessions_root_input)",
)
end
return repo.sessions_root
end
function getSessionDir(repo::JsonlSessionRepo, cwd::String)::String
return getFileSystemResultOrThrow(
joinPath(repo.fs, [getSessionsRoot(repo), encodeCwd(cwd)]),
"Failed to resolve session directory for $(cwd)",
)
end
function encodeCwd(cwd::String)::String
result = replace(cwd, r"^[/\\]" => "")
result = replace(result, r"[/\\:]" => "-")
return "--$(result)--"
end
function createSessionFilePath(repo::JsonlSessionRepo, cwd::String, session_id::String, timestamp::String)::String
return getFileSystemResultOrThrow(
joinPath(repo.fs, [
getSessionDir(repo, cwd),
"$(replace(timestamp, r"[:.]" => "-"))_$(session_id).jsonl",
]),
"Failed to resolve session file path for $(session_id)",
)
end
function getFileSystemResultOrThrow(result::Result, message::String)
if !result.ok
code = result.error.code == "not_found" ? "not_found" : "storage"
throw(SessionError(code, "$(message): $(result.error.message)", result.error))
end
return result.value
end
end