Matrix bridge scaffold: test harness with texting E2E
- src/matrix.zig: minimal Matrix client (conduwuit @ matrix.chaosmith.systems) via curl subprocess transport (native TLS swap later): login, createRoom (trusted_private_chat, unencrypted — no olm), sendText, sync polling with window-scan event extraction reusing letta.jsonStr - src/matrix_harness.zig: standalone entrypoint (independent of tray daemon): login -> DM with peer -> sync loop -> peer messages routed through letta CLI (chaos-prime) -> replies sent back to the room - build.zig: second exe matrix_harness; use_llvm fix promoted into build.zig for both executables (native lld vs GCC16 .sframe relocations) - calling/Element Call (livekit SFU already deployed on ass-host) layers on top of this harness next 👾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta Code <noreply@letta.com>
This commit is contained in:
1 parent
187bac9aa4
commit
da50dea0d1
3 files changed
+274
No files matched your search
@@ -0,0 +1,102 @@
|
||||
//! matrix_harness — standalone Matrix bridge test harness.
|
||||
//!
|
||||
//! Logs in as the inferon Matrix account, opens/creates a DM with MATRIX_PEER
|
||||
//! (default @pierre:chaosmith.systems), and loops: incoming peer messages →
|
||||
//! letta CLI (chaos-prime) → text reply. Independent of the tray daemon so
|
||||
//! calling/voice work can be layered on top without touching it.
|
||||
//!
|
||||
//! Env: MATRIX_USER, MATRIX_PASSWORD, MATRIX_PEER, LETTA_MATRIX_AGENT.
|
||||
|
||||
const std = @import("std");
|
||||
const matrix = @import("matrix.zig");
|
||||
const letta = @import("letta.zig");
|
||||
|
||||
fn envOr(name: [:0]const u8, default: []const u8) []const u8 {
|
||||
if (std.c.getenv(name)) |v| {
|
||||
var len: usize = 0;
|
||||
while (v[len] != 0) len += 1;
|
||||
if (len > 0) return v[0..len];
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const alloc = init.gpa;
|
||||
const io = init.io;
|
||||
letta.initConversationsDir();
|
||||
|
||||
const user = envOr("MATRIX_USER", "@chaos-prime:chaosmith.systems");
|
||||
const password = envOr("MATRIX_PASSWORD", "");
|
||||
const peer = envOr("MATRIX_PEER", "@pierre:chaosmith.systems");
|
||||
const agent = envOr("LETTA_MATRIX_AGENT", "agent-local-273c95cf-82a0-4711-bcd5-6139661e8488");
|
||||
|
||||
if (password.len == 0) {
|
||||
std.debug.print("matrix_harness: MATRIX_PASSWORD not set\n", .{});
|
||||
return error.NoCredentials;
|
||||
}
|
||||
|
||||
std.debug.print("matrix_harness: logging in as {s}...\n", .{user});
|
||||
const session = matrix.login(alloc, io, user, password) catch |e| {
|
||||
std.debug.print("matrix_harness: login failed: {s}\n", .{@errorName(e)});
|
||||
return e;
|
||||
};
|
||||
defer alloc.free(session.token);
|
||||
defer alloc.free(session.user_id);
|
||||
std.debug.print("matrix_harness: logged in ({s})\n", .{session.user_id});
|
||||
|
||||
// Create (or reuse) the DM. For scaffold simplicity we create fresh each
|
||||
// run — Element dedupes DMs and the invite lands in Pierre's inbox.
|
||||
const room = matrix.createDirect(alloc, io, session.token, peer) catch |e| {
|
||||
std.debug.print("matrix_harness: createDirect failed: {s}\n", .{@errorName(e)});
|
||||
return e;
|
||||
};
|
||||
defer alloc.free(room);
|
||||
std.debug.print("matrix_harness: DM room {s}\n", .{room});
|
||||
|
||||
_ = try matrix.sendText(alloc, io, session.token, room, "matrix_harness online. Talk to me — messages go to the agent, replies come back here.");
|
||||
|
||||
// Establish a sync point (drop history before now).
|
||||
const first = try matrix.sync(alloc, io, session.token, "", 0);
|
||||
for (first.events) |ev| {
|
||||
alloc.free(ev.sender);
|
||||
alloc.free(ev.body);
|
||||
}
|
||||
alloc.free(first.events);
|
||||
var since = first.next;
|
||||
|
||||
std.debug.print("matrix_harness: polling sync (peer {s}, agent {s})\n", .{ peer, agent });
|
||||
|
||||
while (true) {
|
||||
const result = matrix.sync(alloc, io, session.token, since, 15000) catch |e| {
|
||||
std.debug.print("matrix_harness: sync error: {s}, retrying\n", .{@errorName(e)});
|
||||
io.sleep(.{ .nanoseconds = 3 * std.time.ns_per_s }, .real) catch {};
|
||||
continue;
|
||||
};
|
||||
alloc.free(since);
|
||||
since = result.next;
|
||||
|
||||
for (result.events) |ev| {
|
||||
defer alloc.free(ev.sender);
|
||||
defer alloc.free(ev.body);
|
||||
// Only peer messages (skip own sends and server noise).
|
||||
if (!std.mem.eql(u8, ev.sender, peer)) continue;
|
||||
if (ev.body.len == 0) continue;
|
||||
|
||||
std.debug.print("matrix_harness: [{s}] {s}\n", .{ ev.sender, ev.body });
|
||||
|
||||
const reply = letta.infer(io, alloc, agent, ev.body) catch |e| {
|
||||
std.debug.print("matrix_harness: letta failed: {s}\n", .{@errorName(e)});
|
||||
const err_txt = "agent failed — see harness logs";
|
||||
if (matrix.sendText(alloc, io, session.token, room, err_txt)) |ev_id| alloc.free(ev_id) else |_| {}
|
||||
continue;
|
||||
};
|
||||
defer alloc.free(reply);
|
||||
|
||||
std.debug.print("matrix_harness: reply: {s}\n", .{reply});
|
||||
if (matrix.sendText(alloc, io, session.token, room, reply)) |ev_id| alloc.free(ev_id) else |e| {
|
||||
std.debug.print("matrix_harness: send failed: {s}\n", .{@errorName(e)});
|
||||
}
|
||||
}
|
||||
alloc.free(result.events);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user