Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e31fc25
chore(deps): make pdf-extract unconditional, drop rag-pdf feature (#2…
oxoxDev May 29, 2026
976c35d
feat(config): add MultimodalFileConfig for file attachments (#2777)
oxoxDev May 29, 2026
4bef1af
feat(agent/multimodal): support [FILE:…] markers with text extraction…
oxoxDev May 29, 2026
213ec2c
test(agent/multimodal): cover file-marker parser, extraction, rejecti…
oxoxDev May 29, 2026
61321f7
feat(agent/multimodal): bump entry + resolve traces from debug to inf…
oxoxDev May 29, 2026
2bd32be
feat(agent/session): wire multimodal marker pipeline into Agent::turn…
oxoxDev May 29, 2026
ac92428
fix(agent/multimodal): count markers per-turn, not across history (#2…
oxoxDev May 29, 2026
48ca642
chore(deps,fmt): pdf-extract transitive deps + rustfmt on turn.rs (#2…
oxoxDev May 29, 2026
523c641
fix(agent/triage): block file-marker resolution for triage payloads (…
oxoxDev May 29, 2026
a0fafd9
fix(agent/multimodal): truncation suffix reservation + revert log lev…
oxoxDev May 29, 2026
e758538
fix(agent/session): re-trim context-window after multimodal expansion…
oxoxDev May 29, 2026
4964de7
Merge remote-tracking branch 'upstream/main' into pr/2954
senamakel May 30, 2026
b2818d1
Merge remote-tracking branch 'upstream/main' into feat/2777-multimoda…
oxoxDev May 30, 2026
25c7984
test(playwright): install MutationObserver to scrub re-mounted joyrid…
oxoxDev May 30, 2026
e8702a3
feat(channels): harden multimodal file ingress on channel-sourced turns
oxoxDev Jun 1, 2026
af8b7cc
test(channels): cover [FILE:...] marker rejection on channel ingress
oxoxDev Jun 1, 2026
de546c0
Merge remote-tracking branch 'upstream/main' into feat/2777-multimoda…
oxoxDev Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ curve25519-dalek = { version = "4", default-features = false, features = ["alloc
matrix-sdk = { version = "0.16", optional = true, default-features = false, features = ["e2e-encryption", "rustls-tls", "markdown"] }
fantoccini = { version = "0.22.0", optional = true, default-features = false, features = ["rustls-tls"] }
serde-big-array = { version = "0.5", optional = true }
pdf-extract = { version = "0.10", optional = true }
pdf-extract = "0.10"
# WhatsApp Web — upstream `whatsapp-rust` 0.5. Replaces the previous `wa-rs`
# 0.2 fork: upstream now ships its own SqliteStore (so we no longer need the
# 1.3K-line custom RusqliteStore) and dispatches `Event::Message` for
Expand Down Expand Up @@ -254,7 +254,6 @@ peripheral-rpi = ["dep:rppal"]
browser-native = ["dep:fantoccini"]
fantoccini = ["browser-native"]
landlock = ["sandbox-landlock"]
rag-pdf = ["dep:pdf-extract"]
whatsapp-web = ["dep:whatsapp-rust", "dep:whatsapp-rust-tokio-transport", "dep:whatsapp-rust-ureq-http-client", "dep:wacore", "serde-big-array"]
# Exposes the destructive `openhuman.test_reset` RPC. Off by default; the E2E
# build (app/scripts/e2e-build.sh) flips it on. Shipped binaries never have
Expand Down
156 changes: 154 additions & 2 deletions app/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions app/test/playwright/helpers/core-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,36 @@ export async function dismissWalkthroughIfPresent(page: Page): Promise<void> {
}

await markCompleted();
// Last-resort: a lingering #react-joyride-portal node will keep
// intercepting clicks on the page even after we've persisted the
// completion flag, AND React may re-mount one later (e.g. after a
// hash-route navigation that runs the walkthrough effect again).
// Strip every portal node now AND install a MutationObserver that
// keeps stripping any future mount for the rest of the page
// lifetime. The observer install is idempotent — re-runs of this
// helper on the same page no-op.
await page.evaluate(() => {
document.querySelectorAll('#react-joyride-portal').forEach(node => node.remove());
const win = window as unknown as { __openhumanJoyrideScrubInstalled?: boolean };
if (win.__openhumanJoyrideScrubInstalled) return;
win.__openhumanJoyrideScrubInstalled = true;
const scrub = (root: ParentNode) => {
root.querySelectorAll('#react-joyride-portal').forEach(node => node.remove());
};
const obs = new MutationObserver(mutations => {
for (const m of mutations) {
m.addedNodes.forEach(node => {
if (!(node instanceof Element)) return;
if (node.id === 'react-joyride-portal') {
node.remove();
} else {
scrub(node);
}
});
}
});
obs.observe(document.body, { childList: true, subtree: true });
});
}

async function waitForAuthenticatedSnapshot(page: Page): Promise<void> {
Expand Down
7 changes: 7 additions & 0 deletions src/openhuman/agent/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ pub struct AgentTurnRequest {
/// size caps).
pub multimodal: MultimodalConfig,

/// File-attachment feature configuration (file marker count caps,
/// per-file size budget, extracted-text limits, MIME allowlist).
pub multimodal_files: crate::openhuman::config::MultimodalFileConfig,

/// Maximum number of LLM↔tool round-trips before bailing out.
/// Prevents infinite loops if a model gets "stuck" calling the same tool.
pub max_tool_iterations: usize,
Expand Down Expand Up @@ -152,6 +156,7 @@ pub fn register_agent_handlers() {
silent,
channel_name,
multimodal,
multimodal_files,
max_tool_iterations,
on_delta,
target_agent_id,
Expand Down Expand Up @@ -245,6 +250,7 @@ pub fn register_agent_handlers() {
silent,
&channel_name,
&multimodal,
&multimodal_files,
max_tool_iterations,
on_delta,
visible_tool_names.as_ref(),
Expand Down Expand Up @@ -402,6 +408,7 @@ mod tests {
silent: true,
channel_name: "test-channel".into(),
multimodal: MultimodalConfig::default(),
multimodal_files: crate::openhuman::config::MultimodalFileConfig::default(),
max_tool_iterations: 1,
on_delta: None,
target_agent_id: None,
Expand Down
Loading
Loading