tensorfs 0.3.22__tar.gz → 0.3.23__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tensorfs-0.3.22 → tensorfs-0.3.23}/Cargo.lock +2 -2
- {tensorfs-0.3.22 → tensorfs-0.3.23}/Cargo.toml +1 -1
- {tensorfs-0.3.22 → tensorfs-0.3.23}/PKG-INFO +1 -1
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/providers.rs +117 -8
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/source_artifact.rs +1 -1
- {tensorfs-0.3.22 → tensorfs-0.3.23}/pyproject.toml +1 -1
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/Cargo.toml +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/build.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/h3-swiglu-layout.md +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/optional-cache-backfill.md +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/resident-conversion.md +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/resident_conversion_profile.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/b64.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/ckpt.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/conform.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/fetch.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/ingest.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/main.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/rd.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/repo.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/snap.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/bin/tfs/watch.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/canon.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/capability.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/catalog.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/cbor.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/checkpoint.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/corpus.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/adoption.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/graft_tests.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/progress.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/resume_tests.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/retention.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived/roots.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/derived.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/dtype.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/durability.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/err.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/fetch.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/fill.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/fit.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/gc.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/header.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/home.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ids.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/carrier.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/convert.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/fingerprint.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/gguf.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/journal.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/mod.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/preflight.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/source.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/stamp.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/ingest/transaction.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/jcs.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/lib.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/limits.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/machine.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/manifest.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/meta.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/project.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/read.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/receipt.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/reclaim.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/registry.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/relation.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/repo_cache.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/repository.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/sha256.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/spec.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/staging.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/storage.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/store.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/api.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/http.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/hub.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/ledger.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/mod.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/policy.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/prefix.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/pull.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/push.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/ranged.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/transport/tests.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/src/vectors.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fetch_url_progress.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fit.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/h3_swiglu.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/home.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/liveness.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/read_plan.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/reclaim.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/reclaim_run.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/repo_cache.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/repo_store.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/resident_admission.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/sha256_backends.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/sharded_cas.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/source_artifacts.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/source_plan.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/source_prefixes.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/source_preflight.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/staging.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/store_boundaries.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/tensor_schema.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/version.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/write_through.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-py/Cargo.toml +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-py/src/docs.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-py/src/errors.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-py/src/lib.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-py/src/store.rs +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/python/tensorfs/__init__.py +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/python/tensorfs/_ext.pyi +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/python/tensorfs/errors.py +0 -0
- {tensorfs-0.3.22 → tensorfs-0.3.23}/python/tensorfs/py.typed +0 -0
|
@@ -392,7 +392,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
|
392
392
|
|
|
393
393
|
[[package]]
|
|
394
394
|
name = "tensorfs-core"
|
|
395
|
-
version = "0.3.
|
|
395
|
+
version = "0.3.23"
|
|
396
396
|
dependencies = [
|
|
397
397
|
"fs2",
|
|
398
398
|
"minicbor",
|
|
@@ -404,7 +404,7 @@ dependencies = [
|
|
|
404
404
|
|
|
405
405
|
[[package]]
|
|
406
406
|
name = "tensorfs-py"
|
|
407
|
-
version = "0.3.
|
|
407
|
+
version = "0.3.23"
|
|
408
408
|
dependencies = [
|
|
409
409
|
"pyo3",
|
|
410
410
|
"tensorfs-core",
|
|
@@ -392,12 +392,18 @@ fn list_observed(
|
|
|
392
392
|
format!("member name {name:?} is outside the grammar"),
|
|
393
393
|
);
|
|
394
394
|
}
|
|
395
|
+
let file_id = json_u64(file, "id")
|
|
396
|
+
.filter(|id| *id > 0 && *id < (1u64 << 53))
|
|
397
|
+
.ok_or_else(|| Refusal {
|
|
398
|
+
code: Code::KEY_GRAMMAR,
|
|
399
|
+
detail: "a Civitai file requires a positive exact integer id".into(),
|
|
400
|
+
})?;
|
|
395
401
|
let sha256 = json_get(file, "hashes")
|
|
396
402
|
.and_then(|hashes| json_str(hashes, "SHA256"))
|
|
397
403
|
.and_then(digest64);
|
|
398
404
|
let url = match json_str(file, "downloadUrl") {
|
|
399
405
|
Some(explicit) => explicit.to_string(),
|
|
400
|
-
None => format!("{base}/api/download/models/{version}"),
|
|
406
|
+
None => format!("{base}/api/download/models/{version}?fileId={file_id}"),
|
|
401
407
|
};
|
|
402
408
|
// A Civitai version is a bag of files (weights, a VAE, a config); the
|
|
403
409
|
// one to take is the `primary` SafeTensors file, exactly as the Go
|
|
@@ -413,7 +419,9 @@ fn list_observed(
|
|
|
413
419
|
// sizeKB is kilobytes as a float — an approximation, not a length.
|
|
414
420
|
// The exact length is probed from the origin at pull time.
|
|
415
421
|
members.push(SourceMember {
|
|
416
|
-
|
|
422
|
+
// Display filenames may change; the provider file ID is the reviewed
|
|
423
|
+
// profile member identity, shared with Creator and retained source trees.
|
|
424
|
+
member: format!("civitai/files/{file_id}"),
|
|
417
425
|
length: None,
|
|
418
426
|
sha256,
|
|
419
427
|
url,
|
|
@@ -1040,6 +1048,14 @@ fn is_safetensors(member: &str) -> bool {
|
|
|
1040
1048
|
lower_ends_with(member, ".safetensors")
|
|
1041
1049
|
}
|
|
1042
1050
|
|
|
1051
|
+
/// Civitai carrier members have provider IDs rather than filename extensions.
|
|
1052
|
+
pub(crate) fn is_civitai_member(member: &str) -> bool {
|
|
1053
|
+
member.strip_prefix("civitai/files/").is_some_and(|id| {
|
|
1054
|
+
id.parse::<u64>()
|
|
1055
|
+
.is_ok_and(|value| value > 0 && value < (1u64 << 53) && value.to_string() == id)
|
|
1056
|
+
})
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1043
1059
|
/// Resolve `relative` against the directory of `member`, the way the Go resolver's
|
|
1044
1060
|
/// `path.Clean(path.Join(path.Dir(member), shard))` does. `None` when the reference walks
|
|
1045
1061
|
/// above the repository root — an index may not name its way out of its own tree.
|
|
@@ -1970,12 +1986,16 @@ mod tests {
|
|
|
1970
1986
|
/// so the exact length comes from a ranged probe through the same fence.
|
|
1971
1987
|
#[test]
|
|
1972
1988
|
fn resolve_takes_the_one_primary_civitai_safetensors() {
|
|
1973
|
-
let
|
|
1989
|
+
let header =
|
|
1990
|
+
br#"{"model.diffusion_model.weight":{"dtype":"F32","shape":[1],"data_offsets":[0,4]}}"#;
|
|
1991
|
+
let mut body = (header.len() as u64).to_le_bytes().to_vec();
|
|
1992
|
+
body.extend_from_slice(header);
|
|
1993
|
+
body.extend_from_slice(&1f32.to_le_bytes());
|
|
1974
1994
|
let object = ObjectRef::of(&body);
|
|
1975
1995
|
let listing = format!(
|
|
1976
1996
|
r#"{{"id":777,"files":[
|
|
1977
|
-
{{"name":"model.safetensors","primary":true,"sizeKB":35.15,"hashes":{{"SHA256":"{}"}},"metadata":{{"format":"SafeTensor"}}}},
|
|
1978
|
-
{{"name":"extra.safetensors","primary":false,"sizeKB":1.0,"hashes":{{"SHA256":"{}"}}}}
|
|
1997
|
+
{{"id":92696,"name":"model.safetensors","primary":true,"sizeKB":35.15,"hashes":{{"SHA256":"{}"}},"metadata":{{"format":"SafeTensor"}}}},
|
|
1998
|
+
{{"id":92697,"name":"extra.safetensors","primary":false,"sizeKB":1.0,"hashes":{{"SHA256":"{}"}}}}
|
|
1979
1999
|
]}}"#,
|
|
1980
2000
|
object.sha256.to_ascii_uppercase(),
|
|
1981
2001
|
"11".repeat(32)
|
|
@@ -1999,12 +2019,101 @@ mod tests {
|
|
|
1999
2019
|
};
|
|
2000
2020
|
let resolved = resolve(&uri, &endpoints, &Anonymous, Deadline::none()).unwrap();
|
|
2001
2021
|
assert_eq!(resolved.members.len(), 1);
|
|
2002
|
-
assert_eq!(resolved.members[0].member, "
|
|
2022
|
+
assert_eq!(resolved.members[0].member, "civitai/files/92696");
|
|
2003
2023
|
assert_eq!(resolved.members[0].object, object);
|
|
2004
2024
|
assert_eq!(resolved.members[0].provenance, Provenance::Declared);
|
|
2005
2025
|
assert!(resolved.members[0].carrier);
|
|
2006
2026
|
assert_eq!(resolved.canonical, "civitai://777");
|
|
2007
2027
|
handle.join().unwrap();
|
|
2028
|
+
|
|
2029
|
+
// The real source tree must keep the carrier visible to conversion despite its
|
|
2030
|
+
// lack of a filename extension, under the member the reviewed profile selects.
|
|
2031
|
+
let root = temporary("civitai-member");
|
|
2032
|
+
let store = Store::init(&root).unwrap();
|
|
2033
|
+
store
|
|
2034
|
+
.put_stream(&mut body.as_slice(), Some(&object), &Fault::default())
|
|
2035
|
+
.unwrap();
|
|
2036
|
+
let tree = content_manifest(&resolved).unwrap();
|
|
2037
|
+
let owner = ObjectRef::of(b"civitai-member-owner").id();
|
|
2038
|
+
crate::source_artifact::create(&store, &owner, &tree).unwrap();
|
|
2039
|
+
let (_, roster, landed) =
|
|
2040
|
+
crate::source_artifact::conversion_roster(&store, &owner).unwrap();
|
|
2041
|
+
assert_eq!(roster.len(), 1);
|
|
2042
|
+
assert_eq!(roster[0].member, "civitai/files/92696");
|
|
2043
|
+
assert_eq!(roster[0].header, body[..8 + header.len()]);
|
|
2044
|
+
assert_eq!(landed, vec!["civitai/files/92696"]);
|
|
2045
|
+
let registry = crate::ingest::fingerprint::FingerprintRegistry::parse(
|
|
2046
|
+
crate::ingest::source::BUILTIN_REGISTRY_BYTES,
|
|
2047
|
+
)
|
|
2048
|
+
.unwrap();
|
|
2049
|
+
let profile = registry
|
|
2050
|
+
.source_profiles
|
|
2051
|
+
.iter()
|
|
2052
|
+
.find(|profile| profile.name == "civitai/101055/128078/single-file-fp16")
|
|
2053
|
+
.unwrap();
|
|
2054
|
+
assert!(
|
|
2055
|
+
profile
|
|
2056
|
+
.components
|
|
2057
|
+
.iter()
|
|
2058
|
+
.all(|component| component.source_member.as_deref()
|
|
2059
|
+
== Some(roster[0].member.as_str()))
|
|
2060
|
+
);
|
|
2061
|
+
std::fs::remove_dir_all(root).unwrap();
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
#[test]
|
|
2065
|
+
fn civitai_refuses_missing_invalid_and_duplicate_file_ids() {
|
|
2066
|
+
for id in ["null", "0", "-1", "1.5", "9007199254740992", "\"92696\""] {
|
|
2067
|
+
let listing = format!(r#"{{"files":[{{"id":{id},"name":"model.safetensors"}}]}}"#);
|
|
2068
|
+
let (base, _, handle) =
|
|
2069
|
+
origin(1, move |_| ok_body(listing.as_bytes(), "application/json"));
|
|
2070
|
+
let endpoints = Endpoints {
|
|
2071
|
+
civitai: base,
|
|
2072
|
+
allow_local: true,
|
|
2073
|
+
..Endpoints::default()
|
|
2074
|
+
};
|
|
2075
|
+
let refusal = list(
|
|
2076
|
+
&SourceUri::Civitai { version: 777 },
|
|
2077
|
+
&endpoints,
|
|
2078
|
+
&Anonymous,
|
|
2079
|
+
Deadline::none(),
|
|
2080
|
+
)
|
|
2081
|
+
.unwrap_err();
|
|
2082
|
+
let expected = if id == "9007199254740992" {
|
|
2083
|
+
Code::NUMBER_RANGE // The shared JSON decoder refuses before provider parsing.
|
|
2084
|
+
} else {
|
|
2085
|
+
Code::KEY_GRAMMAR
|
|
2086
|
+
};
|
|
2087
|
+
assert_eq!(refusal.code, expected, "{id}");
|
|
2088
|
+
handle.join().unwrap();
|
|
2089
|
+
}
|
|
2090
|
+
for (listing, code) in [
|
|
2091
|
+
(
|
|
2092
|
+
r#"{"files":[{"name":"missing-id.safetensors"}]}"#,
|
|
2093
|
+
Code::KEY_GRAMMAR,
|
|
2094
|
+
),
|
|
2095
|
+
(
|
|
2096
|
+
r#"{"files":[{"id":92696,"name":"a.safetensors"},{"id":92696,"name":"b.safetensors"}]}"#,
|
|
2097
|
+
Code::DUPLICATE_KEY,
|
|
2098
|
+
),
|
|
2099
|
+
] {
|
|
2100
|
+
let (base, _, handle) =
|
|
2101
|
+
origin(1, move |_| ok_body(listing.as_bytes(), "application/json"));
|
|
2102
|
+
let endpoints = Endpoints {
|
|
2103
|
+
civitai: base,
|
|
2104
|
+
allow_local: true,
|
|
2105
|
+
..Endpoints::default()
|
|
2106
|
+
};
|
|
2107
|
+
let refusal = list(
|
|
2108
|
+
&SourceUri::Civitai { version: 777 },
|
|
2109
|
+
&endpoints,
|
|
2110
|
+
&Anonymous,
|
|
2111
|
+
Deadline::none(),
|
|
2112
|
+
)
|
|
2113
|
+
.unwrap_err();
|
|
2114
|
+
assert_eq!(refusal.code, code);
|
|
2115
|
+
handle.join().unwrap();
|
|
2116
|
+
}
|
|
2008
2117
|
}
|
|
2009
2118
|
|
|
2010
2119
|
/// The credential is scoped to the host that holds it. A relative redirect stays on
|
|
@@ -2065,7 +2174,7 @@ mod tests {
|
|
|
2065
2174
|
// No downloadUrl in the fixture: the handler must fall back to the provider's
|
|
2066
2175
|
// canonical download route under the configured base.
|
|
2067
2176
|
let listing = format!(
|
|
2068
|
-
r#"{{"id":777,"files":[{{"name":"model.safetensors","sizeKB":273.4,"hashes":{{"SHA256":"{}"}}}}]}}"#,
|
|
2177
|
+
r#"{{"id":777,"files":[{{"id":92696,"name":"model.safetensors","sizeKB":273.4,"hashes":{{"SHA256":"{}"}}}}]}}"#,
|
|
2069
2178
|
object.sha256.to_ascii_uppercase()
|
|
2070
2179
|
);
|
|
2071
2180
|
let payload = body.clone();
|
|
@@ -2074,7 +2183,7 @@ mod tests {
|
|
|
2074
2183
|
let (base, _, handle) = origin(5, move |request| {
|
|
2075
2184
|
if request.path == "/api/v1/model-versions/777" {
|
|
2076
2185
|
ok_body(listing.as_bytes(), "application/json")
|
|
2077
|
-
} else if request.path == "/api/download/models/777" {
|
|
2186
|
+
} else if request.path == "/api/download/models/777?fileId=92696" {
|
|
2078
2187
|
if request.range.as_deref() == Some("bytes=0-0") {
|
|
2079
2188
|
format!(
|
|
2080
2189
|
"HTTP/1.1 206 Partial Content\r\nContent-Length: 1\r\nContent-Range: bytes 0-0/{length}\r\nETag: \"tag\"\r\nConnection: close\r\n\r\n\0"
|
|
@@ -459,7 +459,7 @@ pub fn conversion_roster(
|
|
|
459
459
|
.read_to_end(&mut bytes)
|
|
460
460
|
.map_err(io)?;
|
|
461
461
|
bytes
|
|
462
|
-
} else if member.ends_with(".safetensors") {
|
|
462
|
+
} else if member.ends_with(".safetensors") || crate::providers::is_civitai_member(member) {
|
|
463
463
|
let mut prefix = [0u8; 8];
|
|
464
464
|
file.read_exact(&mut prefix).map_err(io)?;
|
|
465
465
|
let length = u64::from_le_bytes(prefix);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/optional-cache-backfill.md
RENAMED
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/examples/resident_conversion_profile.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor
RENAMED
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json
RENAMED
|
File without changes
|
{tensorfs-0.3.22 → tensorfs-0.3.23}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|