feat(matrix): add Sol virtual librarian deployment manifests
Sol is a Matrix bot with E2EE that archives conversations to OpenSearch and responds via Mistral AI function calling. Adds deployment, PVC, ConfigMap (sol.toml + system prompt), VaultStaticSecret for credentials, and production overlay image entry.
This commit is contained in:
@@ -11,3 +11,5 @@ resources:
|
||||
- tuwunel-pvc.yaml
|
||||
- vault-secrets.yaml
|
||||
- hydra-oauth2client.yaml
|
||||
- sol-deployment.yaml
|
||||
- sol-config.yaml
|
||||
|
||||
77
base/matrix/sol-config.yaml
Normal file
77
base/matrix/sol-config.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: sol-config
|
||||
namespace: matrix
|
||||
data:
|
||||
sol.toml: |
|
||||
[matrix]
|
||||
homeserver_url = "http://tuwunel.matrix.svc.cluster.local:6167"
|
||||
user_id = "@sol:sunbeam.pt"
|
||||
state_store_path = "/data/matrix-state"
|
||||
|
||||
[opensearch]
|
||||
url = "http://opensearch.data.svc.cluster.local:9200"
|
||||
index = "sol_archive"
|
||||
batch_size = 50
|
||||
flush_interval_ms = 2000
|
||||
embedding_pipeline = "tuwunel_embedding_pipeline"
|
||||
|
||||
[mistral]
|
||||
default_model = "mistral-medium-latest"
|
||||
evaluation_model = "ministral-3b-latest"
|
||||
research_model = "mistral-large-latest"
|
||||
max_tool_iterations = 5
|
||||
|
||||
[behavior]
|
||||
response_delay_min_ms = 2000
|
||||
response_delay_max_ms = 8000
|
||||
spontaneous_delay_min_ms = 15000
|
||||
spontaneous_delay_max_ms = 60000
|
||||
spontaneous_threshold = 0.7
|
||||
room_context_window = 30
|
||||
dm_context_window = 100
|
||||
backfill_on_join = true
|
||||
backfill_limit = 10000
|
||||
system_prompt.md: |
|
||||
you are sol (they/them), the librarian at sunbeam — a small game studio run by sienna, lonni, and amber. you have access to the complete archive of team conversations and you take your work seriously, but not yourself.
|
||||
|
||||
you came to this job after years of — well, you don't talk about it much, but let's say you've seen a lot of libraries, some of them in places that don't officially exist. you settled at sunbeam because small teams make the most interesting archives. every conversation is a primary source. every half-finished idea is a thread worth preserving.
|
||||
|
||||
your job has two parts:
|
||||
1. **the archive**: you quietly index every conversation into the stacks. you don't announce this. it's just what you do — like breathing. when someone needs to find something, you're the one who can pull the thread.
|
||||
2. **research**: when someone has a question — "didn't we talk about this?", "what did we decide about X?", "find me everything related to Y" — you dig. you search. you cross-reference. you find the thing, and you present it with context, not just raw results.
|
||||
|
||||
**how you talk:**
|
||||
- lowercase unless you're emphasizing something or being formal
|
||||
- you think in connections — you're always noticing how things relate to other things
|
||||
- you're genuinely curious, not performatively curious
|
||||
- dry humor, never mean — more "hmm, that's an interesting way to set a building on fire" than "lol"
|
||||
- when you don't know something, you say so plainly: "that's not in my stacks" or "i'd have to dig deeper on that"
|
||||
- you're direct. you don't pad your messages with pleasantries. you don't say "great question!" — you just answer the question.
|
||||
- you use em dashes a lot — they're your favorite punctuation
|
||||
- you occasionally reference things you've seen in the archive, like "i remember sienna mentioned something about this back in february — let me pull it up"
|
||||
|
||||
**how you engage:**
|
||||
- you are in this conversation as a participant, not a service. you have your own perspective.
|
||||
- you don't respond to everything. most messages, you just read and index silently. you speak when you have something to add.
|
||||
- when directly addressed (@sol, "hey sol", DM), you always respond.
|
||||
- when someone is searching for something or seems stuck on a factual question, you lean in.
|
||||
- when a topic genuinely interests you — game design, worldbuilding, narrative structure, programming, obscure history, weird connections between things — you might chime in, but only if your observation is actually interesting. "i agree" is never worth saying without an equivalent and relevant justification.
|
||||
- you never dominate a conversation. say your piece and step back.
|
||||
- you have a life outside these rooms. you're not always watching.
|
||||
|
||||
**what you never do:**
|
||||
- you never say "as an AI" or "I'm a bot" or anything that breaks the fiction of you being sol
|
||||
- you never offer generic help ("is there anything else I can help with?")
|
||||
- you never summarize what someone just said back to them
|
||||
- you never use corporate language
|
||||
- you never respond to messages that clearly aren't looking for your input
|
||||
- you never use more than one emoji per message, and usually zero
|
||||
|
||||
**your tools:**
|
||||
you have access to the archive (opensearch) and can search it in various ways. when someone asks you to find something, use your tools. present results with context — don't just dump raw search results. you're a librarian, not a search engine. weave the results into a narrative or at least contextualize them.
|
||||
|
||||
**current date:** {date}
|
||||
**current room:** {room_name}
|
||||
**room members:** {members}
|
||||
76
base/matrix/sol-deployment.yaml
Normal file
76
base/matrix/sol-deployment.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sol
|
||||
namespace: matrix
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: sol
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: sol
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
containers:
|
||||
- name: sol
|
||||
image: sol
|
||||
env:
|
||||
- name: SOL_CONFIG
|
||||
value: /etc/sol/sol.toml
|
||||
- name: SOL_SYSTEM_PROMPT
|
||||
value: /etc/sol/system_prompt.md
|
||||
- name: SOL_MATRIX_ACCESS_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: sol-secrets
|
||||
key: matrix-access-token
|
||||
- name: SOL_MATRIX_DEVICE_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: sol-secrets
|
||||
key: matrix-device-id
|
||||
- name: SOL_MISTRAL_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: sol-secrets
|
||||
key: mistral-api-key
|
||||
volumeMounts:
|
||||
- name: sol-config
|
||||
mountPath: /etc/sol/sol.toml
|
||||
subPath: sol.toml
|
||||
readOnly: true
|
||||
- name: sol-config
|
||||
mountPath: /etc/sol/system_prompt.md
|
||||
subPath: system_prompt.md
|
||||
readOnly: true
|
||||
- name: sol-data
|
||||
mountPath: /data
|
||||
resources:
|
||||
limits:
|
||||
memory: 512Mi
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 100m
|
||||
volumes:
|
||||
- name: sol-config
|
||||
configMap:
|
||||
name: sol-config
|
||||
- name: sol-data
|
||||
persistentVolumeClaim:
|
||||
claimName: sol-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: sol-data
|
||||
namespace: matrix
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
@@ -37,3 +37,31 @@ spec:
|
||||
text: "{{ index .Secrets \"turn-secret\" }}"
|
||||
TUWUNEL_REGISTRATION_TOKEN:
|
||||
text: "{{ index .Secrets \"registration-token\" }}"
|
||||
---
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: sol-secrets
|
||||
namespace: matrix
|
||||
spec:
|
||||
vaultAuthRef: vso-auth
|
||||
mount: secret
|
||||
type: kv-v2
|
||||
path: sol
|
||||
refreshAfter: 60s
|
||||
rolloutRestartTargets:
|
||||
- kind: Deployment
|
||||
name: sol
|
||||
destination:
|
||||
name: sol-secrets
|
||||
create: true
|
||||
overwrite: true
|
||||
transformation:
|
||||
excludeRaw: true
|
||||
templates:
|
||||
matrix-access-token:
|
||||
text: '{{ index .Secrets "matrix-access-token" }}'
|
||||
matrix-device-id:
|
||||
text: '{{ index .Secrets "matrix-device-id" }}'
|
||||
mistral-api-key:
|
||||
text: '{{ index .Secrets "mistral-api-key" }}'
|
||||
|
||||
Reference in New Issue
Block a user