Skip to content

Commit

Permalink
v0.5.0 Release (#11)
Browse files Browse the repository at this point in the history
### Markdown enhancements

- The `Options` are now copy and all call sites take by value. There are too many cases where it's useful to modify the options within a call to a `ToMarkdown` method and it's small enough to be faster this way.
- Option for `heading_level` added.
- Option for `attrs` added. This adds a `role` attr to the header. Mostly useful for conversion from the markdown stream to HTML.

### `Key` changes and fixes

- `Key` encryption is now an optional feature. The `Key` is still always zeroized.
- Conversion from a `Vec<u8>` and array has been removed because it would allow bypassing the invariant that the inner value is utf-8, causing a panic on display.
- Use `Zeroizing` wrapper for input to make it impossible to forget to `zeroize()`.

### Add `html` feature

- Add `html` feature and module for rendering the prompt and messages to `Html`. The same options as `markdown` are used and it requires this feature.
- For the moment, base64 encoded images are not converted to HTML. Adding this is planned but requires special handling since `pulldown_cmark` does not officially support this. It *does* work in pure markdown but the HTML is escaped so the <img> tag we use in markdown to get around the limitation does not work.

### Better partial json support

- Merging deltas is easy because they're strings but appending them to content is not so easy because tool use's input type is a `serde_json::Value`. This allows such merges **so long as the delta is a complete json object**.  We do this to guarantee input is always valid json. However Anthropic does not currently guarantee this. Therefore it's recommended to merge such deltas manually or add complete json objects. Additions to `Stream` may be made to streamline this.

### Fixes
- More coverage
- Fix `Deserialize` for `Tool`. It was previously possible to deserialize an invalid `Tool` struct.
- Comprehensive CI - Some feature combinations were broken, and so we now test with no features, each feature individually, and all features together. All pairs is not currently planned.
- `prompt-caching` feature now works without the `image` feature which was a bug. With CI this shouldn't break again.
- `rustfmt` and `clippy` run on CI
  • Loading branch information
mdegans authored Nov 14, 2024
1 parent 61f782b commit e91e6cc
Show file tree
Hide file tree
Showing 15 changed files with 1,503 additions and 254 deletions.
44 changes: 43 additions & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,51 @@ jobs:
- name: Build
run: cargo build --all-features --verbose

- name: Test
- name: Check formatting
run: cargo fmt --all -- --check

- name: Clippy
run: cargo clippy --all-features

- name: Test Without Default Features
run: cargo test --all-features --verbose --no-default-features

- name: Test With all Features
run: cargo test --all-features --verbose

- name: Test With Image Feature
run: cargo test --features image --verbose

- name: Test with JPEG Feature
run: cargo test --features jpeg --verbose

- name: Test with PNG Feature
run: cargo test --features png --verbose

- name: Test with GIF Feature
run: cargo test --features gif --verbose

- name: Test with WEBP Feature
run: cargo test --features webp --verbose

- name: Test with Prompt Caching Feature
run: cargo test --features prompt-caching --verbose

- name: Test with Log Feature
run: cargo test --features log --verbose

- name: Test with Markdown Feature
run: cargo test --features markdown --verbose

- name: Test with PartialEq Feature
run: cargo test --features partial-eq --verbose

- name: Test with Langsan feature
run: cargo test --features langsan --verbose

- name: Test with Memsecurity feature
run: cargo test --features memsecurity --verbose

# This should only happen on push to main. PRs should not upload coverage.
- name: Install llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
Expand Down
38 changes: 33 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "misanthropic"
version = "0.4.2"
version = "0.5.0"
edition = "2021"
authors = ["Michael de Gans <[email protected]>"]
description = "An async, ergonomic, client for Anthropic's Messages API"
Expand All @@ -17,24 +17,34 @@ categories = [
]
license = "MIT"

[package.metadata.docs.rs]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]

[lints.rust]
unsafe_code = "forbid"

[profile.release]
lto = true
strip = true
# There are (hopefully) no panics in this library. If there are, they are bugs.
panic = "abort"

[dependencies]
base64 = "0.22"
derive_more = { version = "1", features = ["from", "is_variant", "display"] }
eventsource-stream = "0.2"
futures = "0.3"
image = { version = "0.25", optional = true }
log = { version = "0.4", optional = true }
memsecurity = "3.5"
memsecurity = { version = "3.5", optional = true }
zeroize = { version = "1", features = ["derive"] }
# rustls because I am sick of getting Dependabot alerts for OpenSSL.
reqwest = { version = "0.12", features = ["json", "stream"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1"
# markdown support
pulldown-cmark = { version = "0.12", optional = true }
pulldown-cmark = { version = "0.12", optional = true, features = ["serde"] }
pulldown-cmark-to-cmark = { version = "17", optional = true }
static_assertions = "1"
langsan = { version = "0", features = [
Expand All @@ -46,6 +56,8 @@ langsan = { version = "0", features = [
"emoji",
"verbose",
], optional = true }
# For HTML escaping
xml-rs = { version = "0.8", optional = true }

[dev-dependencies]
# for all examples
Expand Down Expand Up @@ -84,16 +96,32 @@ log = ["dep:log"]
rustls-tls = ["reqwest/rustls-tls"]
# Use `pulldown-cmark` for markdown parsing and `pulldown-cmark-to-cmark` for
# converting to CommonMark.
markdown = ["dep:pulldown-cmark", "dep:pulldown-cmark-to-cmark"]
markdown = ["pulldown-cmark/serde", "dep:pulldown-cmark-to-cmark"]
# Utilities for converting prompts and messages to HTML. Enables `markdown`.
html = ["markdown", "xml-rs"]
# Derive PartialEq for all structs and enums.
partial_eq = []
partial-eq = []
# Input and output sanitization
langsan = ["dep:langsan"]
# Encrypted key in memory. Without this the key is still zeroed on drop, but is
# not encrypted. This is a more secure option for the paranoid. Does not build
# on wasm32.
memsecurity = ["dep:memsecurity"]

[[example]]
name = "strawberry"
required-features = ["markdown"]
doc-scrape-examples = true

[[example]]
name = "python"
required-features = ["markdown", "prompt-caching"]
doc-scrape-examples = true

[[example]]
name = "website_wizard"
doc-scrape-examples = true

[[example]]
name = "neologism"
doc-scrape-examples = true
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,16 @@ println!("{}", message);
- [x] Message responses
- [x] Image support with or without the `image` crate
- [x] Markdown formatting of messages, including images
- [x] HTML formatting of messages\*.
- [x] Prompt caching support
- [x] Custom request and endpoint support
- [x] Zero-copy where possible
- [x] [Sanitization](https://crates.io/crates/langsan) of input and output to mitigate [injection attacks](https://arstechnica.com/security/2024/10/ai-chatbots-can-read-and-write-invisible-text-creating-an-ideal-covert-channel/)
- [ ] Amazon Bedrock support
- [ ] Vertex AI support

\* _Base64 encoded images are currently not implemented for HTML but this is a planned feature._

[reqwest]: https://docs.rs/reqwest

## FAQ
Expand Down
2 changes: 2 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ impl Client {
log::debug!("{} request to {}", method, url.as_str());
}

#[allow(clippy::useless_asref)]
// because with memsecurity feature it's not useless
let mut val =
reqwest::header::HeaderValue::from_bytes(self.key.read().as_ref())
.unwrap();
Expand Down
Loading

0 comments on commit e91e6cc

Please sign in to comment.