diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..adfa40c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: '[BUG] ' +labels: bug +assignees: '' +--- + +## Describe the bug +A clear and concise description of what the bug is. + +## To Reproduce +Steps to reproduce the behavior: +1. Run '...' +2. Use tool '...' +3. See error + +## Expected behavior +A clear and concise description of what you expected to happen. + +## Actual behavior +What actually happened. + +## Error output +``` +Paste any error messages or stack traces here +``` + +## Environment +- **OS**: [e.g., Ubuntu 22.04, macOS 14.0, Windows 11] +- **Rust version**: [e.g., 1.80.0] +- **Selfware version**: [e.g., 0.1.0] +- **Installation method**: [e.g., cargo install, built from source] + +## Additional context +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..f7e9f93 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,22 @@ +--- +name: Feature Request +about: Suggest an idea for selfware +title: '[FEATURE] ' +labels: enhancement +assignees: '' +--- + +## Is your feature request related to a problem? +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Describe the solution you'd like +A clear and concise description of what you want to happen. + +## Describe alternatives you've considered +A clear and concise description of any alternative solutions or features you've considered. + +## Use case +Describe how this feature would be used in practice. + +## Additional context +Add any other context, mockups, or examples about the feature request here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ab6e169 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,39 @@ +## Summary + +Brief description of the changes in this PR. + +## Changes + +- [ ] Change 1 +- [ ] Change 2 +- [ ] Change 3 + +## Type of change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Refactoring (no functional changes) +- [ ] Performance improvement +- [ ] Test coverage improvement + +## Testing + +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] I have run `cargo test --all-features` +- [ ] I have run `cargo clippy --all-features` + +## Checklist + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] Any dependent changes have been merged and published + +## Related Issues + +Fixes #(issue number) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..fbbd085 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,45 @@ +# Pre-commit hooks for selfware +# Install: pip install pre-commit && pre-commit install + +repos: + - repo: local + hooks: + - id: cargo-fmt + name: cargo fmt + entry: cargo fmt -- --check + language: system + types: [rust] + pass_filenames: false + + - id: cargo-clippy + name: cargo clippy + entry: cargo clippy --all-targets --all-features -- -D warnings + language: system + types: [rust] + pass_filenames: false + + - id: cargo-test + name: cargo test + entry: cargo test --all-features + language: system + types: [rust] + pass_filenames: false + stages: [push] + + - id: cargo-check + name: cargo check + entry: cargo check --all-features + language: system + types: [rust] + pass_filenames: false + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-toml + - id: check-merge-conflict + - id: check-added-large-files + args: ['--maxkb=500'] diff --git a/Cargo.lock b/Cargo.lock index de4b0c0..d151e10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anndists" version = "0.1.3" @@ -213,6 +219,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "castaway" version = "0.2.4" @@ -266,6 +278,33 @@ dependencies = [ "windows-link", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" version = "4.5.58" @@ -416,6 +455,42 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -485,6 +560,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.7" @@ -924,6 +1005,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.15.5" @@ -1258,12 +1350,32 @@ dependencies = [ "serde", ] +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -1709,6 +1821,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "openssl-probe" version = "0.1.6" @@ -1805,6 +1923,34 @@ dependencies = [ "time", ] +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -2356,6 +2502,7 @@ dependencies = [ "chrono", "clap", "colored", + "criterion", "crossterm 0.27.0", "dirs", "futures", @@ -2822,6 +2969,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.10.0" diff --git a/Cargo.toml b/Cargo.toml index b30710e..f484f09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ extras = [] [dev-dependencies] tokio-test = "0.4" +criterion = { version = "0.5", features = ["html_reports"] } [lib] name = "selfware" @@ -98,3 +99,8 @@ path = "examples/multi_agent.rs" [[example]] name = "custom_config" path = "examples/custom_config.rs" + +# Benchmarks +[[bench]] +name = "token_processing" +harness = false diff --git a/README.md b/README.md index 28e9268..dfe4313 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Selfware +[![CI](https://github.com/architehc/selfware/actions/workflows/ci.yml/badge.svg)](https://github.com/architehc/selfware/actions/workflows/ci.yml) +[![Crates.io](https://img.shields.io/crates/v/selfware)](https://crates.io/crates/selfware) +[![Docs.rs](https://docs.rs/selfware/badge.svg)](https://docs.rs/selfware) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![codecov](https://codecov.io/gh/architehc/selfware/branch/main/graph/badge.svg)](https://codecov.io/gh/architehc/selfware) + ``` 🦊 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Your Personal AI Workshop diff --git a/benches/token_processing.rs b/benches/token_processing.rs new file mode 100644 index 0000000..497fbf0 --- /dev/null +++ b/benches/token_processing.rs @@ -0,0 +1,76 @@ +//! Token processing benchmarks +//! +//! Measures performance of token counting and streaming operations. + +use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId}; + +/// Simulate token counting for a string +fn count_tokens(text: &str) -> usize { + // Simple whitespace tokenization for benchmarking + // Real implementation would use tiktoken or similar + text.split_whitespace().count() +} + +/// Simulate processing a batch of tokens +fn process_token_batch(tokens: &[&str]) -> Vec { + tokens.iter().map(|t| t.to_uppercase()).collect() +} + +fn token_counting_benchmark(c: &mut Criterion) { + let short_text = "Hello, world! This is a test."; + let medium_text = "The quick brown fox jumps over the lazy dog. ".repeat(100); + let long_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ".repeat(1000); + + let mut group = c.benchmark_group("token_counting"); + + group.bench_with_input( + BenchmarkId::new("short", short_text.len()), + &short_text, + |b, text| b.iter(|| count_tokens(black_box(text))), + ); + + group.bench_with_input( + BenchmarkId::new("medium", medium_text.len()), + &medium_text, + |b, text| b.iter(|| count_tokens(black_box(text))), + ); + + group.bench_with_input( + BenchmarkId::new("long", long_text.len()), + &long_text, + |b, text| b.iter(|| count_tokens(black_box(text))), + ); + + group.finish(); +} + +fn token_batch_benchmark(c: &mut Criterion) { + let small_batch: Vec<&str> = (0..10).map(|_| "token").collect(); + let medium_batch: Vec<&str> = (0..100).map(|_| "token").collect(); + let large_batch: Vec<&str> = (0..1000).map(|_| "token").collect(); + + let mut group = c.benchmark_group("token_batch"); + + group.bench_with_input( + BenchmarkId::new("small", small_batch.len()), + &small_batch, + |b, batch| b.iter(|| process_token_batch(black_box(batch))), + ); + + group.bench_with_input( + BenchmarkId::new("medium", medium_batch.len()), + &medium_batch, + |b, batch| b.iter(|| process_token_batch(black_box(batch))), + ); + + group.bench_with_input( + BenchmarkId::new("large", large_batch.len()), + &large_batch, + |b, batch| b.iter(|| process_token_batch(black_box(batch))), + ); + + group.finish(); +} + +criterion_group!(benches, token_counting_benchmark, token_batch_benchmark); +criterion_main!(benches); diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..1e91731 --- /dev/null +++ b/deny.toml @@ -0,0 +1,68 @@ +# cargo-deny configuration +# https://embarkstudios.github.io/cargo-deny/ + +[graph] +# Only check these targets +targets = [ + "x86_64-unknown-linux-gnu", + "x86_64-apple-darwin", + "aarch64-apple-darwin", + "x86_64-pc-windows-msvc", +] + +[advisories] +# The database of advisories +db-path = "~/.cargo/advisory-db" +# URL(s) of the advisory database to fetch +db-urls = ["https://github.com/rustsec/advisory-db"] +# Ignore these advisories (add specific IDs if needed) +ignore = [] +# Treat unmaintained crates as warnings +unmaintained = "warn" +# Yanked crates are errors +yanked = "deny" + +[licenses] +# List of allowed licenses +allow = [ + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Zlib", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "Unlicense", +] +# Confidence threshold for detecting license from text +confidence-threshold = 0.8 +# Allow exceptions for specific crates +exceptions = [] + +[bans] +# Lint level for multiple versions of the same crate +multiple-versions = "warn" +# Lint level for when a crate is detected as a build-time dependency +wildcards = "allow" +# Allow dependencies with git sources +allow-build-scripts = ["*"] + +# Specific crate denials +deny = [] + +# Skip specific versions (for version conflicts) +skip = [] + +# Skip entire dependency trees +skip-tree = [] + +[sources] +# Allowed registries +unknown-registry = "warn" +# Allowed git sources +unknown-git = "warn" +# List of allowed registries +allow-registry = ["https://github.com/rust-lang/crates.io-index"]