Outhad_ContextKit: Intelligent Memory Layer for AI Applications
Long-term memory for AI agents: graph, timeline and personalised recall in one library
Quick Start • Features • Cloud • API Reference • Examples • Docs
Why Outhad_ContextKit?
Traditional AI applications send the entire conversation history to the LLM on every request. The result:
- Growing cost: every turn re-sends every previous turn
- Slow responses: the model re-reads the whole history each time
- Privacy risk: sensitive details are repeatedly sent to the LLM provider
Outhad_ContextKit solves this by storing facts once and retrieving only what matters:
# ❌ Traditional approach: sends ALL messages, every time
response = openai.chat.completions.create(
model="gpt-4o",
messages=conversation_history, # grows with every turn
)
# ✅ Outhad_ContextKit: sends ONLY relevant memories
relevant_memories = memory.search(query=message, user_id="alice", limit=3)
response = openai.chat.completions.create(
model="gpt-4o",
messages=[system_prompt_with_memories, user_message], # a handful of facts
)
What's inside
| Feature | What it does | Default |
|---|---|---|
| TCMGM | Temporal + causal graph reasoning ("when?" and "why?") | Auto when a graph store is set |
| Context-Graph Layer | Memories linked as a graph; graph-first retrieval | Off |
| MSPR | Ranking that adapts to intent, usage and feedback | Off |
| Tenants | Isolated memory per customer, department or project | Off |
| Decay & Versioning | Memories age, version, roll back and archive | Off |
| Adaptive Chunking | Chunks long documents, keeps short ones whole | Off |
| PPMF | Detect, redact and encrypt sensitive data | Off |
| Multimodal | Images, audio and text in one memory | Off |
Every opt-in layer is a guarded no-op when disabled: turning a feature off leaves existing behaviour exactly as it was.
Quick Start
New to Outhad_ContextKit? Choose your path:
- 🚀 5-Minute Quick Start: no infrastructure needed
- 🔧 Full Setup Guide: production-ready with all features
- 📚 Troubleshooting: common issues and solutions
Installation
pip install outhad_contextkitai
Optional dependencies:
pip install "outhad_contextkitai[graph]" # Neo4j / Neptune graph memory (TCMGM)
pip install "outhad_contextkitai[vector_stores]" # Pinecone, Weaviate, Chroma, FAISS, ...
pip install "outhad_contextkitai[llms]" # Groq, Together, Ollama, Gemini, ...
pip install "outhad_contextkitai[multimodal]" # Image + audio embeddings (CLIP, CLAP)
pip install "outhad_contextkitai[extras]" # Bedrock, S3, Elasticsearch, OpenSearch, Memgraph
pip install networkx scipy # Context-Graph Layer (scipy powers PageRank retrieval)
pip install tiktoken # Token-based adaptive chunking
Prerequisites
- Python 3.9+
- An LLM API key: OpenAI by default (
export OPENAI_API_KEY="sk-..."); Anthropic, Gemini, Groq and more work via config - Neo4j (optional): only for TCMGM and the CGL
neo4jbackend
docker run --name neo4j -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:latest
Without Neo4j: ✅ vector memory · ✅ Context-Graph Layer · ✅ MSPR · ✅ Tenants · ✅ Decay & Versioning · ✅ Chunking · ✅ PPMF
With Neo4j: all of the above, ✅ plus temporal reasoning · ✅ causal analysis · ✅ entity graphs · ✅ fused retrieval
60-Second Setup
from openai import OpenAI
from outhad_contextkit import Memory
openai_client = OpenAI()
memory = Memory()
# Add memories from conversations
memory.add([
{"role": "user", "content": "I'm allergic to peanuts"},
{"role": "assistant", "content": "I'll remember that!"},
], user_id="alice")
# Search relevant memories
relevant_memories = memory.search("What are my dietary restrictions?", user_id="alice", limit=3)
# Use memories in LLM context
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"User memories: {relevant_memories['results']}"},
{"role": "user", "content": "What should I avoid eating?"},
],
)
print(response.choices[0].message.content)
# "Based on your allergy, you should avoid peanuts and foods containing them."
Core Features
1. TCMGM (Temporal-Causal-Multimodal Graph Memory)
Temporal and causal reasoning over memory: ask when and why, not just what.
Automatically builds a knowledge graph with timeline events and cause → effect links whenever a graph store is configured:
from outhad_contextkit import Memory
memory = Memory.from_config({
"graph_store": {
"provider": "neo4j", # or "memgraph", "neptune"
"config": {"url": "bolt://localhost:7687", "username": "neo4j", "password": "password"},
}
})
# Add conversations - TCMGM automatically extracts:
# - Entities and relationships
# - Temporal events with timestamps
# - Causal dependencies
memory.add([
{"role": "user", "content": "I deployed the new API yesterday"},
{"role": "assistant", "content": "How did it go?"},
{"role": "user", "content": "Response times doubled - something broke"},
], user_id="dev_team")
# Query with temporal + causal reasoning
results = memory.search(
"When did the performance issue start?",
user_id="dev_team",
use_tcmgm=True, # fused vector + graph + timeline retrieval
)
# Adds: timeline_results, causal_chains, fused_ranking
What makes TCMGM unique:
- Temporal Queries: "What changed before the bug appeared?"
- Causal Analysis: "Why is the API slow?" → finds the root cause in the memory graph
- Multimodal Support: connects text, images and audio in one graph
- Fused Retrieval: combines vector search + graph traversal + timeline analysis
Complete TCMGM Documentation →
2. Context-Graph Layer (CGL)
Every memory becomes a node: memories link to each other, not just to entities.
Connects memories with typed edges and retrieves through the graph, so related context arrives with the best match:
from outhad_contextkit import Memory
memory = Memory.from_config({
"context_graph": {"enabled": True, "backend": "networkx"}, # or "neo4j" for > 100k memories
})
memory.add("I love pizza", user_id="u1", run_id="r1")
memory.add("Italian food is my favourite", user_id="u1", run_id="r1")
# Graph-first retrieval: seed → expand along edges → re-rank
results = memory.search("what should I eat?", user_id="u1", use_context_graph=True)
print(results["results"], results["subgraph"])
# Already have memories? Build the graph in one idempotent call
memory.backfill_context_graph(user_id="u1") # {"nodes": 42, "edges": 117}
What makes CGL powerful:
- Typed Edges: replies, timeline order, topic similarity, document links, updates and causes are linked automatically; opt-in LLM edges add
SUPPORTS/CONTRADICTS/REFINES/ELABORATES - Graph-First Retrieval: BFS or Personalised PageRank, re-ranked by dense + keyword + graph scores
- Natural Forgetting: edges and nodes decay over time; steer them with
mark_relevant()/mark_irrelevant() - Time Travel & Audit: every change is logged. Snapshot it, replay to any point in time, or stream it to webhooks, SSE or Kafka
3. Multi-Stage Personalized Retrieval (MSPR)
Search that learns from each user: ranking adapts to intent, usage and feedback.
Layers personal signals on top of CGL, each behind its own switch so you can roll them out one at a time:
from outhad_contextkit import Memory
memory = Memory.from_config({
"context_graph": {"enabled": True, "retrieval": {"delta_personal": 0.3, "zeta_success": 0.2}},
"mspr": {"enabled": True, "feedback": {"enabled": True}, "success": {"enabled": True}},
})
memory.add("Q4 revenue forecast: $4.2M", user_id="u1")
results = memory.search("revenue forecast", user_id="u1", use_context_graph=True)
# Tell it what helped - future searches for this query rank it higher
memory.record_feedback(results["results"][0]["id"], helpful=True,
user_id="u1", query="revenue forecast")
What makes MSPR powerful:
- Intent-Aware: classifies each query and re-weights the ranking for that intent
- Feedback & Frequency: helpful / unhelpful verdicts and real usage feed a personal boost
- Learns What Worked: memories that answered the same query before get lifted
- Role-Aware: a
RolePolicyfilters what each caller may see (tenant isolation, role scopes)
New ranking weights default to 0.0, so nothing changes until you opt in.
4. Tenant + Sub-Tenant Architecture
Multi-tenant memory in one config line: isolated per customer, department or project.
from outhad_contextkit import Memory
memory = Memory.from_config({
"tenant": {"enabled": True, "isolation": {"mode": "collection"}}, # one collection per tenant
})
# Admin API
memory.tenant.create_tenant(id="acme", name="Acme Corp")
memory.tenant.create_sub_tenant(tenant_id="acme", name="finance", kind="department")
memory.tenant.assign_role(tenant_id="acme", principal="alice@acme.com", role="member")
# Tenant-scoped memory
memory.add("Q4 forecast: $4.2M", user_id="alice",
metadata={"tenant_id": "acme", "sub_tenant_id": "finance"})
results = memory.search("revenue forecast", user_id="alice", filters={"tenant_id": "acme"})
What makes Tenants powerful:
- Three Isolation Modes: shared collection + filter, one collection per tenant, or one database per tenant (reserved)
- Sub-Tenants & RBAC: departments, projects or users under each tenant, with role bindings
- Lifecycle Ops:
export_tenant,import_tenant,migrate_tenant, and GDPR-style hard delete - Zero New Infrastructure: SQLite registry + your existing vector store;
backfill_tenant()upgrades old data
Complete Tenant Documentation →
5. Time-Aware Decay & Versioning
Memories that age, version and archive themselves: built for long-lived production stores.
from outhad_contextkit import Memory
memory = Memory.from_config({
"context_graph": {"enabled": True},
"decay_v2": {
"enabled": True,
"versioning": {"mode": "immutable"}, # updates keep old versions
"schedule": {"enabled": True, "interval_seconds": 1800}, # decay every 30 min
},
})
memory.decay_score(memory_id) # 0.0 (stale) → 1.0 (fresh)
memory.archive_low(threshold=0.05) # archive what has gone stale
memory.versions(memory_id) # full version chain
memory.rollback(memory_id, to_version=2) # restore an earlier version
What makes Decay & Versioning powerful:
- Decay Score: blends recency, access frequency and feedback into one number
- Background Scheduler: decays, archives and prunes old versions on an interval
- Immutable History: diff any two versions; a rollback is itself a new version
- Cold Storage: move stale memories to local disk or S3 and bring them back on demand
Complete Decay & Versioning Documentation →
6. Adaptive Chunking
Smart document processing: only chunks when needed.
from outhad_contextkit import Memory
memory = Memory.from_config({
"chunking": {
"enabled": True,
"strategy": "token", # or "character", "semantic", "hierarchical"
"chunk_size": 512,
"chunk_overlap": 50,
"min_document_size": 1500, # don't chunk short docs
"merge_chunks_on_retrieval": True,
}
})
# Short documents (< 1500 chars) → stored as a single memory
memory.add("Alice loves Italian food", user_id="alice")
# Long documents (≥ 1500 chars) → chunked into 512-token segments
memory.add(research_paper_text, user_id="researcher")
# Retrieval merges related chunks back together
results = memory.search("methodology section", user_id="researcher")
Adaptive Chunking Benefits:
- Prevents Over-Fragmentation: short texts keep their meaning intact
- Context Preservation: configurable overlap between chunks
- Coherent Retrieval: neighbouring chunks are merged back at search time
- Four Strategies: character, token, semantic, or hierarchical (structure-aware)
Complete Chunking Documentation →
7. PPMF (Privacy-Preserving Memory Firewall)
Privacy building blocks: detect, redact and encrypt sensitive data.
from outhad_contextkit.memory.privacy import (
EncryptionAlgorithm, EncryptionManager, MemorySanitizer, PPMFConfig, RedactionMode, redact_text,
)
config = PPMFConfig(enabled=True, encryption_algorithm=EncryptionAlgorithm.AES_256_GCM)
# Detect + redact
text = "Email me at john@example.com or call 555-123-4567"
result = MemorySanitizer(config).classify(text)
print(redact_text(text, result.sensitive_spans, RedactionMode.REPLACE))
# "Email me at [PII_EMAIL] or call [PII_PHONE]"
# Encrypt at rest
encryption = EncryptionManager(config=config)
ciphertext, meta = encryption.encrypt("john@example.com")
encryption.decrypt(ciphertext, meta) # "john@example.com"
PPMF Features:
- ✅ PII / PHI / financial / secret detection (fast rules + optional LLM classifier)
- ✅ Five redaction modes: mask, replace, encrypt, remove, hash
- ✅ Fernet / AES-256-GCM / NaCl encryption
- ✅ Telemetry sanitising + MEXTRA-style adversarial testing
Note:
ppmf.enabled=Truedoes not yet run these automatically insideMemory.add()/search(). Call them directly as shown above.
8. Multimodal Memory
Images alongside text: a vision LLM turns pictures into searchable facts.
from outhad_contextkit import Memory
memory = Memory.from_config({
"llm": {"provider": "openai", "config": {"model": "gpt-4o", "enable_vision": True}},
})
memory.add([
{"role": "user", "content": "This is our new product design"},
{"role": "user", "content": {"type": "image_url", "image_url": {"url": "https://example.com/product.jpg"}}},
], user_id="design_team")
results = memory.search("product design with blue accents", user_id="design_team")
Multimodal Features:
- Vision Ingest: images are described by the LLM and stored as regular memories
- Cross-Modal Search: CLIP / SigLIP / CLAP embeddings link images, text and audio inside TCMGM
- Opt-In Weight: install
[multimodal]only when you need it; nothing heavy loads otherwise
Complete Multimodal Documentation →
9. Multi-Provider Support
Flexible infrastructure: use your preferred tools.
| Component | Supported Providers |
|---|---|
| LLMs | OpenAI, Anthropic, Gemini, Azure OpenAI, AWS Bedrock, Groq, Together, Ollama, LiteLLM, DeepSeek, xAI, Sarvam, LM Studio, vLLM, LangChain |
| Embedders (10) | OpenAI, Azure OpenAI, Gemini, Vertex AI, HuggingFace, Ollama, Together, LM Studio, AWS Bedrock, LangChain |
| Vector Stores (16) | Qdrant (default), Chroma, pgvector, Milvus, Pinecone, Weaviate, FAISS, MongoDB, Redis, Elasticsearch, OpenSearch, Supabase, Upstash, Azure AI Search, Vertex AI, LangChain |
| Graph Stores (3) | Neo4j, Memgraph, AWS Neptune |
# Example: Anthropic Claude + Qdrant + Neo4j
memory = Memory.from_config({
"llm": {"provider": "anthropic", "config": {"model": "claude-haiku-4-5-20251001"}},
"embedder": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
"vector_store": {"provider": "qdrant", "config": {"host": "localhost", "port": 6333}},
"graph_store": {"provider": "neo4j", "config": {
"url": "bolt://localhost:7687", "username": "neo4j", "password": "password"}},
})
Hosted Cloud
Managed memory over HTTP: the same engine with no infrastructure to run.
pip install outhad-contextkit-sdk
from outhad_contextkit_sdk import MemoryClient # AsyncMemoryClient has the same API
client = MemoryClient(api_key="ock_live_...") # or set OUTHAD_CONTEXTKIT_API_KEY
client.add(messages=[{"role": "user", "content": "I love sushi."}], user_id="alice")
hits = client.search(query="What food do I like?", user_id="alice")
# Switch the LLM for a single call
client.search(query="What food do I like?", user_id="alice",
llm={"provider": "anthropic", "model": "claude-haiku-4-5-20251001"})
What the cloud adds:
- Every Engine Feature over HTTP: TCMGM, CGL, MSPR, versioning, decay, feedback, pin / unpin
- Projects & Teams: projects, members, webhooks, environments, per-project model settings
- Security: scoped API keys, key rotation, IP allowlists, audit log
- Observability: usage, request log, top users, graph snapshot
Self-host it: the FastAPI control plane lives in server/cloud and the Next.js dashboard in web/:
cd server && cp .env.example .env # fill in DATABASE_URL, CLERK_*, OPENAI_API_KEY
make cloud-migrate && make cloud-up # API on http://localhost:8000
cd ../web && npm install && npm run dev
Architecture
Your application / agent framework
│ │
in-process│ │ HTTPS + API key
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ Memory / AsyncMemory │◄──│ Cloud control plane │
│ add · search · update · ... │ │ server/cloud (FastAPI) │
└───────────────┬───────────────┘ │ keys · projects · usage · │
│ │ audit log · webhooks │
│ └───────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────────┐
│ Opt-in layers (all off by default) │
│ Retrieval TCMGM · CGL (BFS / PPR) · MSPR │
│ Governance Tenants · Decay & versioning · PPMF │
│ Ingest Adaptive chunking · Multimodal │
└───────────────────────────────┬───────────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────────┐
│ Storage │
│ Vector store (16 providers) Graph store (Neo4j / Memgraph / │
│ History (SQLite / Postgres) Neptune) │
│ CGL graph (networkx / Neo4j) Cold storage (local disk / S3) │
│ SQLite sidecars: CGL changelog · feedback · query success · │
│ tenant registry │
└───────────────────────────────────────────────────────────────────┘
Complete Architecture Documentation →
Memory API Reference
All methods are available on both Memory and AsyncMemory. Click a group to expand it.
Core: add, search, get, update, delete, history
| Method | Purpose |
|---|---|
add(messages, *, user_id, agent_id, run_id, metadata, infer=True) |
Extract facts with the LLM (or store raw with infer=False) |
search(query, *, user_id, limit, filters, threshold, ...) |
Semantic search; flags: use_tcmgm, time_window, include_causal, use_context_graph, merge_chunks, include_archived |
get(memory_id) / get_all(*, user_id, agent_id, run_id, filters, limit) |
Retrieve memories |
update(memory_id, data) / delete(memory_id) / delete_all(...) |
Modify with automatic history tracking |
history(memory_id, *, tenant_id, sub_tenant_id) |
Change history for a memory |
reset() |
Wipe the memory store |
Context-Graph Layer: backfill, decay, snapshot, replay, change feed
| Method | Purpose |
|---|---|
backfill_context_graph(*, batch_size, user_id, agent_id, run_id) |
Idempotent graph build from existing memories |
tick_decay() / reset_context_graph() |
One decay round / drop all graph nodes and edges |
mark_relevant(id, delta) / mark_irrelevant(id, delta) |
Manually adjust relevance |
snapshot_context_graph(path) / replay_context_graph(*, until) |
Snapshot and point-in-time replay |
subscribe_context_graph_changes(callback) / unsubscribe_context_graph_changes(token) |
Live change feed |
MSPR: feedback, role policies, backfill
| Method | Purpose |
|---|---|
record_feedback(memory_id, *, helpful, user_id, query) / reset_feedback(*, user_id) |
Capture or wipe user verdicts |
set_role_policy(policy) / get_role_policy() |
Install or read the active RolePolicy |
backfill_mspr() |
Rebuild the success store from existing feedback |
Tenants: admin, RBAC, export / import / migrate
| Method | Purpose |
|---|---|
tenant.create_tenant / list_tenants / get_tenant / update_tenant / delete_tenant(hard=) |
Tenant admin |
tenant.create_sub_tenant / list_sub_tenants / delete_sub_tenant |
Sub-tenant admin |
tenant.assign_role / revoke_role / list_roles_for / has_role |
RBAC |
backfill_tenant() / export_tenant() / import_tenant() / migrate_tenant() |
Upgrade and lifecycle |
Decay & Versioning: scoring, scheduler, versions, cold storage
| Method | Purpose |
|---|---|
decay_score(id) / archive_low(*, threshold, dry_run) |
Score and archive stale memories |
start_decay_scheduler() / stop_decay_scheduler() / close() |
Background scheduler control |
versions(id) / latest_version(id) / diff_versions(old, new) / rollback(id, *, to_version) |
Version chain |
record_reference(id, *, strength) |
Mark a memory as actually used by the agent |
demote_to_cold(id) / promote_from_cold(id) |
Cold storage |
backfill_decay_v2() |
Recompute decay scores for existing data |
Examples
Chatbot with Persistent Memory
from openai import OpenAI
from outhad_contextkit import Memory
openai_client = OpenAI()
memory = Memory()
def chat_with_memory(message: str, user_id: str) -> str:
# Retrieve relevant memories
memories = memory.search(query=message, user_id=user_id, limit=3)
context = "\n".join(m["memory"] for m in memories["results"])
# Generate response with memory context
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"User context: {context}"},
{"role": "user", "content": message},
],
)
answer = response.choices[0].message.content
# Store new conversation
memory.add([
{"role": "user", "content": message},
{"role": "assistant", "content": answer},
], user_id=user_id)
return answer
print(chat_with_memory("I love pizza", user_id="alice"))
print(chat_with_memory("What food do I like?", user_id="alice"))
# "You mentioned you love pizza!"
Multi-Agent Shared Memory
from outhad_contextkit import Memory
memory = Memory()
# Research agent stores findings
memory.add("Found 3 security vulnerabilities in the authentication module",
agent_id="research_agent", run_id="audit_2026")
# Development agent retrieves findings
findings = memory.search("security issues", agent_id="research_agent", run_id="audit_2026")
# Both agents share knowledge
memory.add("Fixed SQL injection in login endpoint", agent_id="dev_agent", run_id="audit_2026")
More runnable examples:
- Context-Graph Layer: basics, backfill, decay, LLM edges, snapshot / replay, webhook audit
- MSPR: end-to-end personalised retrieval
- Versioning & decay: versions, cold storage, references
- Cloud SDK: quickstart, provider switching, TCMGM over HTTP
- Multi-agent • Multimodal • Graph DB • Chunking
Benchmarks & Evaluation
Benchmark harnesses live in evaluation/. Run them against your own data and models; the JSON results there are the source of truth.
python evaluation/run_locomo_eval.py # long-term conversational QA (LoCoMo)
python evaluation/run_coqa_eval.py # CoQA, with / without adaptive chunking
python evaluation/run_context_graph_eval.py --algorithm both # graph-first vs vector; BFS vs PPR
python tools/cost_calculator.py --users 1000 --messages 50 --model gpt-4 # estimate your savings
Documentation
| Topic | Guides |
|---|---|
| Getting started | Quick start • Setup • Neo4j • Troubleshooting |
| Core operations | add • search • update • delete • Memory types |
| TCMGM | Retrieval • Causal • Temporal • Timeline • Multimodal |
| Advanced layers | CGL • MSPR • Tenants • Decay & versioning |
| Ingest & privacy | Chunking • PPMF • Flexible embedder • Multimodal install |
| Cloud | SDK reference |
| Project | Architecture • Changelog • Contributing |
Contributing
Quick Development Setup:
git clone https://github.com/tanzil7890/Outhad_ContextKit.git
cd Outhad_ContextKit
hatch env create && make install # install development dependencies
make test # run tests
make format && make lint # format + lint with ruff
See CONTRIBUTING.md for details.
Citation
If you use Outhad_ContextKit in your research, please cite:
@software{outhad_contextkit2025,
title = {Outhad_ContextKit: Intelligent Memory Layer for AI Applications},
author = {Outhad Team},
year = {2025},
url = {https://github.com/tanzil7890/Outhad_ContextKit}
}
License
Apache 2.0. See LICENSE.
Metadata
Release files for outhad-contextkitai 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| outhad_contextkitai-0.1.3.tar.gz | 302.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| outhad_contextkitai-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 719.1 kB
Release files / outhad_contextkitai-0.1.3.tar.gz
| Download URL | outhad_contextkitai-0.1.3.tar.gz |
|---|---|
| Size | 302.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
81a57472ea6627b0fe1700983fa59514650ff5e429721c3e11c783e0d9031dee
|
|
BLAKE2b-256 checksum How to use checksums |
a52ab33b2e8e38408444494e2ce6a597d51b42fbf8162754dd3209c76ac6bb03
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / outhad_contextkitai-0.1.3-py3-none-any.whl
| Download URL | outhad_contextkitai-0.1.3-py3-none-any.whl |
|---|---|
| Size | 416.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2d235184a1c193d0907eefab99c30fb1ef20c6204affa07aa87baab5fc80daa3
|
|
BLAKE2b-256 checksum How to use checksums |
eb8470db0a15f6ba2118d90f39dde771c23ee6ffbd2bdec6f0f5a951649c9e25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for outhad-contextkitai 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.