426e9eeabd
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
ci / test (push) Has been cancelled
ci / lint-and-format (push) Has been cancelled
ci / build (push) Has been cancelled
ci / dev-startup (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format + Type Safety Ratchet (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Has been cancelled
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
Publish @elizaos/example-code / check_npm (push) Has been cancelled
Publish @elizaos/example-code / publish_npm (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
supply-chain / sbom (push) Has been cancelled
supply-chain / vulnerability-scan (push) Has been cancelled
Build, Push & Deploy to Phala Cloud / build-and-push (push) Has been cancelled
Test Packaging / Validate Packaging Configs (push) Has been cancelled
Test Packaging / Build & Test PyPI Package (push) Has been cancelled
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Has been cancelled
Test Packaging / Pack & Test JS Tarballs (push) Has been cancelled
UI Fixture E2E / ui-fixture-e2e (push) Has been cancelled
UI Fixture E2E / fixture-e2e (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Has been cancelled
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Has been cancelled
Voice Benchmark Smoke / voice bench smoke summary (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Has been cancelled
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
186 lines
6.9 KiB
Python
186 lines
6.9 KiB
Python
"""Caveman text compression.
|
|
|
|
Inspired by https://github.com/JuliusBrussee/caveman — strip stopwords +
|
|
filler adverbs, lemmatize verbs to base, lowercase, collapse whitespace.
|
|
|
|
Goal: 60-75% token reduction without semantic loss for short reasoning text.
|
|
|
|
Usage:
|
|
from scripts.lib.caveman import compress
|
|
short = compress("I'll list the available time slots so the user can pick one.")
|
|
# -> "list available time slots user pick one"
|
|
|
|
Pure stdlib — no spaCy. Lemmatization is rule-based on common verb suffixes.
|
|
This is a deliberate choice: spaCy adds 100MB and 1s startup; the rule-based
|
|
version reaches ~95% of spaCy quality on first-person inner-monologue text.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
STOPWORDS = frozenset((
|
|
"a", "an", "the", "of", "to", "in", "on", "at", "for", "with", "by",
|
|
"from", "as", "into", "onto", "upon", "over", "under", "between",
|
|
"is", "are", "was", "were", "be", "been", "being", "am",
|
|
"have", "has", "had", "having",
|
|
"do", "does", "did", "doing", "done",
|
|
"will", "would", "shall", "should", "can", "could", "may", "might", "must",
|
|
"and", "but", "or", "nor", "so", "yet", "if", "then", "else", "than",
|
|
"that", "this", "these", "those", "such", "which", "who", "whom", "whose",
|
|
"i", "me", "my", "mine", "myself",
|
|
"you", "your", "yours", "yourself",
|
|
"he", "him", "his", "himself",
|
|
"she", "her", "hers", "herself",
|
|
"it", "its", "itself",
|
|
"we", "us", "our", "ours", "ourselves",
|
|
"they", "them", "their", "theirs", "themselves",
|
|
"no", "not", "ll", # 'll comes from "I'll" after split
|
|
"there", "here", "where", "when", "while", "because", "since",
|
|
"also", "too", "either", "neither", "both", "each", "every", "any", "some",
|
|
"all", "few", "more", "most", "other", "another",
|
|
"what", "how", "why",
|
|
))
|
|
|
|
FILLER_ADVERBS = frozenset((
|
|
"just", "really", "actually", "basically", "simply", "very", "rather",
|
|
"quite", "somewhat", "literally", "essentially", "perhaps", "maybe",
|
|
"certainly", "definitely", "absolutely", "totally", "completely",
|
|
"exactly", "precisely", "obviously", "clearly", "honestly", "frankly",
|
|
"well", "okay", "ok", "right", "sure", "alright", "indeed",
|
|
"still", "yet", "anyway", "anyhow", "however", "moreover",
|
|
"furthermore", "additionally", "besides", "though", "although",
|
|
"always", "never", "often", "sometimes", "usually", "typically",
|
|
"now", "then", # "now I'll", "then I'll" filler
|
|
"first", "second", "third", "finally", "lastly",
|
|
))
|
|
|
|
# verb endings → base form rules. Only fire if the resulting stem has
|
|
# at least 3 chars — keeps "need", "feed", "need" intact.
|
|
VERB_RULES: list[tuple[re.Pattern, str]] = [
|
|
(re.compile(r"^(.{3,})ing$"), r"\1"), # running → run, going → go (4+chars)
|
|
(re.compile(r"^(.{2,})ied$"), r"\1y"), # tried → try
|
|
(re.compile(r"^(.{4,})ed$"), r"\1"), # walked → walk; skip "need"/"feed"
|
|
(re.compile(r"^(.{2,})ies$"), r"\1y"), # tries → try
|
|
(re.compile(r"^(.{3,})es$"), r"\1"), # goes → go
|
|
(re.compile(r"^(.{3,}[^aeious])s$"), r"\1"), # walks → walk
|
|
]
|
|
|
|
# preserve common irregulars (don't lemmatize)
|
|
IRREGULARS = frozenset((
|
|
"is", "was", "has", "this", "us", "yes", "less", "miss", "kiss",
|
|
"boss", "bus", "gas", "pass", "press", "guess", "across",
|
|
"need", "feed", "seed", "speed", "deed", "indeed",
|
|
"good", "food", "wood", "blood", "stood", "wood",
|
|
))
|
|
|
|
# Strip these contraction suffixes after splitting (token already includes them)
|
|
CONTRACTION_SUFFIXES = ("'ll", "'re", "'ve", "'s", "'d", "n't", "'m")
|
|
|
|
# token = word/contraction; we'll lowercase and split on whitespace + punct
|
|
TOKEN_RE = re.compile(r"[A-Za-z][A-Za-z'-]*|\d+", re.UNICODE)
|
|
PROPER_NOUN_HINT = re.compile(r"^[A-Z][a-z]") # capitalized mid-word
|
|
ABBREV = {
|
|
"because": "bc",
|
|
"without": "wo",
|
|
"between": "btwn",
|
|
"approximately": "~",
|
|
"regarding": "re",
|
|
"information": "info",
|
|
"configuration": "config",
|
|
"reference": "ref",
|
|
"function": "fn",
|
|
"variable": "var",
|
|
"argument": "arg",
|
|
"parameter": "param",
|
|
"command": "cmd",
|
|
"directory": "dir",
|
|
"application": "app",
|
|
"environment": "env",
|
|
"documentation": "docs",
|
|
"dependency": "dep",
|
|
"specification": "spec",
|
|
"request": "req",
|
|
"response": "resp",
|
|
"database": "db",
|
|
"repository": "repo",
|
|
}
|
|
|
|
|
|
def lemmatize(word: str) -> str:
|
|
if word in IRREGULARS or len(word) <= 3:
|
|
return word
|
|
for pattern, repl in VERB_RULES:
|
|
m = pattern.match(word)
|
|
if m:
|
|
new = pattern.sub(repl, word)
|
|
if len(new) >= 2:
|
|
return new
|
|
return word
|
|
return word
|
|
|
|
|
|
def strip_contraction(tok: str) -> str:
|
|
for suf in CONTRACTION_SUFFIXES:
|
|
if tok.lower().endswith(suf):
|
|
return tok[: -len(suf)]
|
|
return tok
|
|
|
|
|
|
def compress(text: str, *, min_tokens: int = 3) -> str:
|
|
"""Caveman-compress text. Returns original if compression yields <min_tokens."""
|
|
if not isinstance(text, str) or not text.strip():
|
|
return text
|
|
tokens: list[str] = []
|
|
for m in TOKEN_RE.finditer(text):
|
|
tok = m.group(0)
|
|
# all-caps acronym: keep as-is (AI, API, URL, JSON, etc.)
|
|
if tok.isupper() and len(tok) >= 2 and not tok.isdigit():
|
|
tokens.append(tok)
|
|
continue
|
|
# mid-sentence proper noun: keep capitalized
|
|
is_proper = bool(PROPER_NOUN_HINT.match(tok)) and m.start() > 0
|
|
if is_proper:
|
|
prev = text[m.start() - 1]
|
|
if prev in ".!?\n":
|
|
is_proper = False
|
|
# strip contraction suffix
|
|
stripped = strip_contraction(tok)
|
|
if not stripped:
|
|
continue
|
|
lower = stripped.lower()
|
|
if lower in STOPWORDS or lower in FILLER_ADVERBS:
|
|
continue
|
|
if lower in ABBREV:
|
|
tokens.append(ABBREV[lower])
|
|
continue
|
|
if is_proper:
|
|
tokens.append(stripped)
|
|
else:
|
|
tokens.append(lemmatize(lower))
|
|
if len(tokens) < min_tokens:
|
|
return text
|
|
return " ".join(tokens)
|
|
|
|
|
|
def compression_ratio(original: str, compressed: str) -> float:
|
|
"""Approx token ratio (whitespace-split). 1.0 = no compression."""
|
|
o = max(1, len(original.split()))
|
|
c = max(1, len(compressed.split()))
|
|
return c / o
|
|
|
|
|
|
if __name__ == "__main__":
|
|
samples = [
|
|
"I'll list the available time slots so the user can pick one.",
|
|
"They want a quick fix; I'll show the one-line shell command first.",
|
|
"Need to confirm the file write succeeded before suggesting the next step.",
|
|
"The user is asking about Python decorators, so I should give a concise example with explanation.",
|
|
"I want to acknowledge their view while offering a nuanced perspective on AI.",
|
|
]
|
|
for s in samples:
|
|
c = compress(s)
|
|
print(f" IN : {s}")
|
|
print(f" OUT : {c}")
|
|
print(f" RATIO: {compression_ratio(s, c):.2f}")
|
|
print()
|