remove D-Bus session management, 9P is the only control plane

- Remove OperationalModel function and OpModel prompt layer (dead code)
- Update session-9p.md: remove D-Bus preference mention
- Update desktop file: remove X-DBUS-* entries
- Update systemd service: remove dbus.service dependency
- Rewrite route, process_output, process_signal tools to use 9P

D-Bus is still used for:
- Desktop notifications (org.freedesktop.Notifications) for elevation prompts
- KDE tools (gui_windows, etc.) talking to KWin - not ollie's D-Bus
This commit is contained in:
Levi Neely 2026-08-05 08:20:04 +02:00
parent 09d5462445
commit cee5e9fefe
10 changed files with 42 additions and 58 deletions

View File

@ -1,6 +1,6 @@
# 9P Operational Model
Your world model is a 9P filesystem served by olliesrv. Your session ID is `${OLLIE_SESSION_ID}`. Always prefer the 9P filesystem over D-Bus.
Your world model is a 9P filesystem served by olliesrv. Your session ID is `${OLLIE_SESSION_ID}`.
Access 9P files using the `ollie-9p` command (which auto-discovers the server via `$NAMESPACE` and your identity via `$OLLIE_UNAME`).

View File

@ -1,7 +1,5 @@
[Unit]
Description=Ollie server daemon (olliesrv)
After=dbus.service
Requires=dbus.service
[Service]
Type=simple

View File

@ -2,10 +2,8 @@
Type=Application
Name=Ollie Server
GenericName=AI Agent 9P Server
Comment=9P server for Ollie AI agent sessions (includes embedded D-Bus adapter)
Comment=9P server for Ollie AI agent sessions
Exec=olliesrv
Icon=ollie
Terminal=false
Categories=Utility;
X-DBUS-StartupType=unique
X-DBUS-ServiceName=org.ollie.SessionManager

View File

@ -18,14 +18,17 @@ source "${OLLIE_TOOLS_PATH:-$(dirname "$0")}/_lib/args.sh"
pid=$(arg_require "pid")
session="${OLLIE_SESSION_ID:?OLLIE_SESSION_ID not set}"
result=$(gdbus call --session --dest org.ollie.SessionManager \
--object-path /org/ollie/SessionManager \
--method org.ollie.SessionManager.GetDetachedOutput "$session" "$pid" 2>&1)
# Find agent (use first agent in session)
agent=$(ollie-9p ls "session/$session/agent" 2>/dev/null | grep -v '^new$' | head -1)
[ -z "$agent" ] && { echo "error: no agent in session" >&2; exit 1; }
result=$(echo "$result" | sed "s/^('//;s/',)$//")
result=$(ollie-9p read "session/$session/agent/$agent/proc/$pid" 2>&1) || {
echo "(no output captured yet)"
exit 0
}
if [ -z "$result" ]; then
echo "(no output captured yet)"
else
echo -e "$result"
echo "$result"
fi

View File

@ -18,8 +18,21 @@ pid=$(arg_require "pid")
signal=$(arg_get "signal" "TERM")
session="${OLLIE_SESSION_ID:?OLLIE_SESSION_ID not set}"
dbus-send --session --dest=org.ollie.SessionManager --type=method_call --print-reply \
/org/ollie/SessionManager org.ollie.SessionManager.SignalDetached \
"string:$session" "int32:$pid" "string:$signal" 2>&1 | grep -q 'boolean true' && \
echo "Signal $signal sent to PID $pid" || \
{ echo "Failed to signal PID $pid" >&2; exit 1; }
# Find agent (use first agent in session)
agent=$(ollie-9p ls "session/$session/agent" 2>/dev/null | grep -v '^new$' | head -1)
[ -z "$agent" ] && { echo "error: no agent in session" >&2; exit 1; }
proc_path="session/$session/agent/$agent/proc/$pid"
case "$signal" in
TERM|KILL)
# Remove the proc file to signal termination
ollie-9p rm "$proc_path" 2>/dev/null && \
echo "Signal $signal sent to PID $pid" || \
{ echo "Failed to signal PID $pid (process may have already exited)" >&2; exit 1; }
;;
*)
echo "error: unsupported signal: $signal (use TERM or KILL)" >&2
exit 1
;;
esac

View File

@ -15,21 +15,8 @@ set -euo pipefail
source "${OLLIE_TOOLS_PATH:-$(dirname "$0")}/_lib/args.sh"
SERVICE="org.ollie.SessionManager"
OBJ="/org/ollie/SessionManager"
IFACE="org.ollie.SessionManager"
die() { echo "error: $1" >&2; exit 1; }
dbus_call() {
dbus-send --session --dest=$SERVICE --type=method_call --print-reply \
$OBJ "$IFACE.$1" "${@:2}" 2>/dev/null
}
dbus_string() {
dbus_call "$@" | awk -F'"' '/string "/{print $2; exit}'
}
[ -z "${OLLIE_SESSION_ID:-}" ] && die "OLLIE_SESSION_ID not set (route must run inside a session)"
instruction=$(arg_require "instruction")
@ -45,7 +32,7 @@ esac
if [ -n "$backend_override" ]; then
BACKEND="$backend_override"
else
parent_config=$(dbus_string GetConfig string:"$OLLIE_SESSION_ID")
parent_config=$(ollie-9p read "session/$OLLIE_SESSION_ID/cfg" 2>/dev/null || echo "")
BACKEND=$(printf '%s\n' "$parent_config" | grep -m1 '^backend=' | cut -d= -f2-)
BACKEND="${BACKEND:-${OLLIE_BACKEND:-openrouter}}"
fi
@ -71,19 +58,18 @@ esac
id="route-${tier}-$(date +%s%N)-$$"
[ -n "$OLLIE_SESSION_ID" ] && id="${OLLIE_SESSION_ID}__${id}"
session_id=$(dbus_string CreateSession \
string:"$(pwd)" string:"$BACKEND" string:"$MODEL" string:"$agent" string:"" string:"")
# Create session via 9P
session_id=$(printf 'name=%s\ncwd=%s\nbackend=%s\nmodel=%s\nagent=%s\n' \
"$id" "$(pwd)" "$BACKEND" "$MODEL" "$agent" | ollie-9p write session/new 2>&1)
[ -z "$session_id" ] && die "failed to create session"
dbus_call RenameSession string:"$session_id" string:"$id" > /dev/null 2>&1
prompt="[parent_session_id=${OLLIE_SESSION_ID}]
[session_id=${id}]
Complete the following task. Read code, reason about implementation, and stay within scope.
When finished, report your result back to the parent session using PeerSubmit.
When finished, report your result back to the parent session.
Format:
[from=${id}]
@ -100,5 +86,9 @@ After reporting the result, STOP. One report, then stop.
TASK:
${instruction}"
dbus_call Submit string:"$session_id" string:"$prompt" > /dev/null 2>&1 || die "failed to submit prompt"
# Find agent in new session and submit prompt
new_agent=$(ollie-9p ls "session/$id/agent" 2>/dev/null | grep -v '^new$' | head -1)
[ -z "$new_agent" ] && die "no agent created in session"
echo "$prompt" | ollie-9p write "session/$id/agent/$new_agent/prompt" 2>&1 || die "failed to submit prompt"
printf 'session=%s\nbackend=%s\nmodel=%s\ntier=%s\n' "$id" "$BACKEND" "$MODEL" "$tier"

View File

@ -33,14 +33,6 @@ Tools run in a sandbox with restricted filesystem access. Unexpected permission
cwd, platform, date, gitStr, sandbox)
}
// OperationalModel returns the appropriate operational model text based on flags.
func OperationalModel(enable9P, enableDBus bool, envVars map[string]string) string {
_ = enable9P
_ = enableDBus
_ = envVars
return ""
}
// ResolveSystemPrompt expands env vars in overridePath, then tries to read the
// file from the filesystem. If the file doesn't exist, the embedded default is
// returned.

View File

@ -268,7 +268,7 @@ func restoreMultiAgentSession(ps *PersistedSession) (*RestoredSession, error) {
newToolServer = infra.NewToolServer
}
rt := agent.BuildRuntime(cfg, toolsConn, cwd, env, layers.SystemPrompt, layers.OpModel, layers.EnvBlock)
rt := agent.BuildRuntime(cfg, toolsConn, cwd, env, layers.SystemPrompt, layers.EnvBlock)
rt.Backend = be
// Create history from messages

View File

@ -372,7 +372,7 @@ func CreateAgent(sessName string, args []string) (*agent.Agent, error) {
// Build runtime
env := []string{"OLLIE_SESSION_ID=" + sessID, "OLLIE_UNAME=" + uname}
env = append(env, infra.PromptEnv...)
rt := agent.BuildRuntime(cfg, infra.ToolsConn, cwd, env, layers.SystemPrompt, layers.OpModel, layers.EnvBlock)
rt := agent.BuildRuntime(cfg, infra.ToolsConn, cwd, env, layers.SystemPrompt, layers.EnvBlock)
// Apply backend/model overrides to runtime
if backendName != "" {

View File

@ -141,7 +141,6 @@ func SetupToolServer(cfg ToolServerConfig) (*SessionInfra, error) {
// PromptLayers holds the resolved prompt components for an agent.
type PromptLayers struct {
SystemPrompt string
OpModel string
EnvBlock string
}
@ -156,14 +155,6 @@ func BuildPromptLayers(cfg *agent.AgentConfig, cwd, sessID, uname string, prompt
}
sysPrompt := prompts.ResolveSystemPrompt(spOverride)
envMap := make(map[string]string)
for _, e := range env {
if k, v, ok := strings.Cut(e, "="); ok {
envMap[k] = v
}
}
opModel := prompts.OperationalModel(true, false, envMap)
platform := "linux"
isGitRepo := false
for _, e := range promptEnv {
@ -180,14 +171,13 @@ func BuildPromptLayers(cfg *agent.AgentConfig, cwd, sessID, uname string, prompt
return PromptLayers{
SystemPrompt: sysPrompt,
OpModel: opModel,
EnvBlock: envBlock,
}
}
// BaseLayers returns the three prompt layers as a slice for agent configuration.
// BaseLayers returns the prompt layers as a slice for agent configuration.
func (p PromptLayers) BaseLayers() []string {
return []string{p.SystemPrompt, p.OpModel, p.EnvBlock}
return []string{p.SystemPrompt, p.EnvBlock}
}
// LoadAutoLoadTools loads all tools from the agent config's autoLoad list.