-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathCargo.toml
More file actions
239 lines (218 loc) · 11.2 KB
/
Copy pathCargo.toml
File metadata and controls
239 lines (218 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# This package is also the workspace root so the reusable secrets core can stay
# independently consumable. The `[patch.crates-io]` below applies workspace-wide.
[workspace]
members = ["faculties-migrations", "faculties-secrets"]
resolver = "2"
[package]
name = "faculties"
version = "0.20.2"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "An office suite for AI agents: kanban, wiki, files, messaging, and a GORBIE-backed viewer — all persisted in a TribleSpace pile."
authors = ["Jan-Paul Bultmann <jp@bultmann.eu>"]
homepage = "https://github.com/erlkonig-ai/faculties"
repository = "https://github.com/erlkonig-ai/faculties"
readme = "README.md"
keywords = ["triblespace", "ai-agent", "kanban", "wiki", "notebook"]
categories = ["command-line-utilities", "data-structures"]
# docs.rs should render all public API, including the optional
# `widgets` module (WikiViewer / CompassBoard / etc.) that depends
# on egui/GORBIE/cubecl.
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lib]
path = "src/lib.rs"
# GORBIE-backed viewer binary. Requires the `widgets` feature.
[[bin]]
name = "viewer"
path = "src/bin/viewer.rs"
required-features = ["widgets"]
# Minimal headless capture target for iterating on planner-widget
# visuals in isolation — avoids spinning up the wiki widget (cubecl
# GPU context) which collides with the headless wgpu renderer on
# some platforms.
[[bin]]
name = "planner-capture"
path = "src/bin/planner-capture.rs"
required-features = ["widgets"]
# Same idea for the headspace widget — minimal capture target that
# skips the wiki widget's GPU init so headless captures of the
# agent-config card don't get truncated.
[[bin]]
name = "headspace-capture"
path = "src/bin/headspace-capture.rs"
required-features = ["widgets"]
# Memory chunks viewer — recent compacted-context summaries.
[[bin]]
name = "memory-capture"
path = "src/bin/memory-capture.rs"
required-features = ["widgets"]
# Gauge research-health dashboard.
[[bin]]
name = "gauge-capture"
path = "src/bin/gauge-capture.rs"
required-features = ["widgets"]
# Messages-only viewer.
[[bin]]
name = "messages-capture"
path = "src/bin/messages-capture.rs"
required-features = ["widgets"]
# Files import-history viewer.
[[bin]]
name = "files-capture"
path = "src/bin/files-capture.rs"
required-features = ["widgets"]
# Triage diagnostic viewer.
[[bin]]
name = "triage-capture"
path = "src/bin/triage-capture.rs"
required-features = ["widgets"]
# Atlas schema-catalog browser.
[[bin]]
name = "atlas-capture"
path = "src/bin/atlas-capture.rs"
required-features = ["widgets"]
# Discord recent-messages viewer.
[[bin]]
name = "discord-capture"
path = "src/bin/discord-capture.rs"
required-features = ["widgets"]
# Teams recent-messages viewer.
[[bin]]
name = "teams-capture"
path = "src/bin/teams-capture.rs"
required-features = ["widgets"]
# Window-status board viewer.
[[bin]]
name = "status-capture"
path = "src/bin/status-capture.rs"
required-features = ["widgets"]
[features]
# `local-embed` and `widgets` are default: semantic recall is core to knowledge
# workflows, and the GORBIE viewer is part of the normal office surface.
# A stock workspace cohort build (`cargo build --release --workspace --bins`)
# must ship both.
default = ["local-embed", "widgets", "audio", "hear"]
# GORBIE-backed viewers for faculty branches. Enables the `widgets` module.
widgets = [
"dep:GORBIE",
"dep:egui",
"dep:cubecl",
]
# Consumed by GORBIE's `#[notebook]` expansion to gate its export branch.
web-export = []
# Semantic similarity in `files` + `wiki similar` / `memory similar` (image+text
# embeddings via mary's embedder). Default (see above).
local-embed = ["dep:mary", "mary/embed", "mary/gemma"]
# Text-to-image generation via mary's ported FLUX.2 pipeline (Burn/Metal).
imagine = ["dep:mary", "mary/flux", "dep:image"]
# In-process Qwen3-TTS in the `voice` faculty (`voice say`/
# `voice shout`) via mary's ported Burn/Metal pipeline. Calls
# `mary::speak::synthesize_stream` directly — no separately-built binary that can
# drift stale against the pile format (the staleness class that truncated memory
# on 2026-06-30). Four explicit roots are selected from one frozen native
# model-collection pile (`QWEN3TTS_PILE`): exact base, shared codec, filtered
# f16 talker, and folded f16 talker.
# Native audio device enumeration + playback sink (rodio/cpal). Default so
# stock installs keep `voice devices`/routing; excluded on audio-less servers
# (FreeBSD build class, 2026-07-21) via --no-default-features.
audio = ["dep:rodio"]
voice = ["dep:mary", "mary/speak", "audio"]
# The `hear` faculty: Soma's framed microphone -> energy VAD -> Gemma-4 audio
# tower + multimodal embedder, handing over EMBEDDINGS (not text). `mary/gemma`
# brings the parity-gated audio path; `tokenizers` is the decoder's BPE, needed
# to build the `Hearing` handle even when only `embed` is called. DEFAULT: it
# replaces `converse` as the shipping ear surface, and `local-embed` (also
# default) already pays for `mary/gemma`, so the marginal cost is the
# tokenizer. Capture itself is `soma-client`, which is unconditional and tiny.
hear = ["dep:mary", "mary/gemma", "dep:tokenizers"]
# The `duplex` faculty: a continuously running spoken channel on mary's
# streaming full-duplex speech model. `mary/personaplex` brings the LM layers
# (it rides the same layer stack as `speak`), `mary/q4` the 4-bit temporal
# stack and the streaming codec. `audio` supplies the named-device PLAYBACK
# plumbing only — the microphone is Soma's, reached through `soma-client`
# (unconditional and tiny), which is what lets `hear` and `duplex` run at the
# same time off one device. Off by default: the model runtime is heavy and only
# this one binary needs it. NOT YET REALTIME on the measured hardware — see the
# frame-budget section of the binary's module docs before relying on it.
duplex = ["dep:mary", "mary/personaplex", "mary/q4", "audio"]
[dependencies]
# Core: every CLI faculty depends on these.
anyhow = "1.0"
clap = { version = "4.5.4", features = ["derive", "env"] }
ed25519-dalek = "2.1.1"
hifitime = "4.2.3"
rand_core = "0.6.4"
triblespace = { version = "0.47", path = "../triblespace-rs" }
triblespace-paths = { version = "0.47.0", path = "../triblespace-rs/triblespace-paths" }
triblespace-search = { version = "0.47.0", path = "../triblespace-rs/triblespace-search" }
faculties-secrets = { version = "0.1.0", path = "faculties-secrets" } # secrets faculty logic
# Per-faculty deps (kept here so faculties stay single-file in src/bin/).
anybytes = "0.20" # files
base64 = "0.22" # teams
blake3 = "1" # mail (deterministic entity id from Message-Id)
chrono = { version = "0.4.39", features = ["clock"] } # orient
comemo = "0.5.1" # wiki
ctrlc = "3.5" # body (graceful close for kept touch loops)
dirs = "5" # wiki
hex = "0.4" # gauge
zeroize = "1.9" # secrets CLI plaintext lifetime
humantime = "2.3.0" # orient, patience
ical = "0.11" # planner
itertools = "0.14" # wiki
kamadak-exif = "0.6" # posture (EXIF/TIFF tags on images)
lettre = { version = "0.11", default-features = false, features = ["smtp-transport", "rustls-tls", "builder"] } # mail (SMTP send)
libc = "0.2" # teams
lopdf = { version = "0.44", default-features = false } # posture (PDF objects + content streams)
mailparse = "0.16" # mail (RFC 5322 parser)
memchr = "2" # archive (bounded streaming rollout prefilter)
mime = "0.3" # shared canonical file media-type parsing
zmij = "1" # archive (canonical JSON float spelling)
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] } # mail POP transport
rustls-native-certs = "0.8" # mail POP transport (platform trust roots)
quick-xml = "0.37" # posture (OOXML part parsing)
rayon = "1.10" # archive
regex = "1" # wiki
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls", "json", "multipart"] } # discord, files, teams, web, body, voice
rodio = { version = "0.22", default-features = false, features = ["playback"], optional = true } # audio feature (NATIVE cpal device enumeration + playback sink; no afplay/ffplay/SwitchAudioSource subprocesses)
soma-client = { version = "0.1.0", path = "../soma/soma-client" } # hear + duplex (Soma's framed 80 ms capture contract; anyhow + the reqwest already here). Unconditional: the capture seam is not a feature, it is how the body is reached.
tokenizers = { version = "0.21", optional = true } # hear (Gemma-4 BPE, needed to build the Hearing handle)
rrule = "0.14" # planner
serde = { version = "1", features = ["derive"] } # discord, teams, triage, web
serde_json = "1" # discord, teams, triage, web
tracing = "0.1" # archive
tracing-subscriber = { version = "0.3", features = ["env-filter"] } # archive
typst = "0.14" # wiki
typst-syntax = "0.14" # wiki
zip = { version = "2", default-features = false, features = ["deflate"] } # posture (OOXML is a zip of XML)
# Widgets-only (optional): GORBIE viewer stack.
GORBIE = { version = "0.18.1", default-features = false, features = ["typst", "markdown"], optional = true }
egui = { version = "0.34", optional = true }
cubecl = { version = "0.10.0", default-features = false, features = ["wgpu", "std"], optional = true }
# Optional, heavy: mary's Burn/Metal model ports. Activated as a bare optional
# dep (no default features); the *consuming* faculties feature turns on exactly
# the mary features it needs, so each build stays as lean as its job allows:
# local-embed → mary[embed,gemma]: CLIP/SigLIP multi-modal embedder (CLIP
# image+text shared space) + nomic-embed-multimodal-7b (3584-d
# dense image/text space; Qwen2.5-VL port + Metal/wgpu backend).
# imagine → mary[flux]: the ported FLUX.2 text→image pipeline.
mary = { path = "../mary", default-features = false, optional = true }
# imagine-only: the `image` crate, matching mary's flux feature, so the
# RgbImage the pipeline returns can be `.save()`d to a PNG here.
image = { version = "0.25", default-features = false, features = ["png"], optional = true }
[dev-dependencies]
tempfile = "3"
# ── patches ────────────────────────────────────────────────────────────────
# `[patch]` only takes effect from the *root* crate of a build, so mary's own
# patch section is ignored when mary is consumed as a path dep here. We mirror
# it: the nomic-mm7b zero-copy aliasing path (`local-embed`) needs the cubecl
# fork (adds `register_external_aliased`) and the V3 256-byte-aligned local
# triblespace-core. The whole suite is on one cubecl lineage (0.10): the
# widgets GPU graph layout, mary's model ports, and these fork patches all
# resolve to the same cubecl — widgets, local-embed, imagine, and voice are
# co-buildable in a single `cargo install`.
[patch.crates-io]
cubecl-runtime = { path = "../cubecl-fork/cubecl-runtime" }
cubecl-wgpu = { path = "../cubecl-fork/cubecl-wgpu" }
triblespace-core = { path = "../triblespace-rs/triblespace-core" }