add profiles
This commit is contained in:
parent
9edf430e8f
commit
c82fff949b
135 changed files with 12283 additions and 236 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
|
|
@ -23,9 +23,8 @@ jobs:
|
||||||
python-version-file: ".python-version"
|
python-version-file: ".python-version"
|
||||||
|
|
||||||
- name: Build memora package
|
- name: Build memora package
|
||||||
run: |
|
working-directory: ./memora
|
||||||
cd memora
|
run: uv build
|
||||||
uv build
|
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|
|
||||||
1
.sesskey
1
.sesskey
|
|
@ -1 +0,0 @@
|
||||||
49ed5f3e-d51f-4fbe-abdb-c909287df6a0
|
|
||||||
878
ARCHITECTURE.md
Normal file
878
ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,878 @@
|
||||||
|
# Memora: A Multi-Network Entity-Aware Memory Architecture for Conversational AI Agents
|
||||||
|
|
||||||
|
## Abstract
|
||||||
|
|
||||||
|
We present Memora, a sophisticated memory architecture for AI agents that combines temporal, semantic, and entity-based retrieval mechanisms within a graph-structured knowledge base. The system introduces three distinct but interconnected memory networks—world knowledge, agent experiences, and formed opinions—enabling contextual reasoning and personality-driven responses. Our multi-stage retrieval pipeline integrates four parallel search strategies with reciprocal rank fusion, neural reranking, and maximal marginal relevance diversification. We demonstrate how entity resolution and graph-based spreading activation enable the discovery of indirectly related information that purely vector-based approaches miss. Additionally, we introduce a personality framework based on the Big Five psychological model that biases opinion formation during reasoning tasks. The architecture achieves high recall through parallel retrieval while maintaining precision through sophisticated reranking, addressing the fundamental challenge of long-term memory retention in conversational agents.
|
||||||
|
|
||||||
|
## 1. Introduction
|
||||||
|
|
||||||
|
Conversational AI agents face a fundamental challenge: maintaining coherent, context-aware memories across extended interactions. Traditional approaches rely either on vector similarity search, which captures semantic relationships but misses entity-level connections, or on keyword matching, which provides precision but lacks conceptual understanding. Neither approach adequately handles the temporal aspects of memory or the need to distinguish between different types of knowledge.
|
||||||
|
|
||||||
|
We propose Memora, a hybrid memory architecture that addresses these limitations through:
|
||||||
|
|
||||||
|
1. **Multi-Network Organization**: Separate but interconnected networks for world facts, agent experiences, and formed opinions
|
||||||
|
2. **Entity-Aware Graph Structure**: Explicit entity resolution and linking that connects memories through shared identities
|
||||||
|
3. **Parallel Multi-Strategy Retrieval**: Four complementary retrieval methods (semantic, keyword, graph, temporal-graph) executed in parallel
|
||||||
|
4. **Personality-Driven Reasoning**: Configurable personality traits that bias opinion formation using psychological frameworks
|
||||||
|
5. **Hierarchical Reranking**: Neural cross-encoder reranking followed by maximal marginal relevance diversification
|
||||||
|
|
||||||
|
This architecture enables agents to reason over their memories with temporal awareness, discover indirect relationships through graph traversal, and form consistent opinions influenced by configured personality traits.
|
||||||
|
|
||||||
|
## 2. System Architecture
|
||||||
|
|
||||||
|
### 2.1 Memory Networks
|
||||||
|
|
||||||
|
The system maintains three distinct memory networks, each serving a specific purpose while sharing the underlying infrastructure:
|
||||||
|
|
||||||
|
#### 2.1.1 World Network
|
||||||
|
|
||||||
|
The World Network (`fact_type='world'`) stores general knowledge and facts about the external world that are independent of the agent's direct actions:
|
||||||
|
|
||||||
|
**Characteristics**:
|
||||||
|
- Contains factual information about entities (people, organizations, places)
|
||||||
|
- Includes relationships between entities
|
||||||
|
- Maintains temporal validity (when facts became true)
|
||||||
|
- Self-contained statements with resolved pronouns
|
||||||
|
|
||||||
|
**Example Facts**:
|
||||||
|
- "Alice works at Google in Mountain View"
|
||||||
|
- "Yosemite National Park is located in California"
|
||||||
|
- "Python has libraries for data science including pandas and numpy"
|
||||||
|
|
||||||
|
**Use Cases**:
|
||||||
|
- Answering questions about entities: "Where does Alice work?"
|
||||||
|
- Understanding relationships: "Who works at Google?"
|
||||||
|
- Temporal queries: "What happened in June?"
|
||||||
|
|
||||||
|
#### 2.1.2 Agent Network
|
||||||
|
|
||||||
|
The Agent Network (`fact_type='agent'`) records the agent's own actions, recommendations, and interactions:
|
||||||
|
|
||||||
|
**Characteristics**:
|
||||||
|
- First-person perspective of agent activities
|
||||||
|
- Records what the agent did, said, or recommended
|
||||||
|
- Enables self-referential reasoning ("What did I tell Alice?")
|
||||||
|
- Tracks agent's involvement over time
|
||||||
|
|
||||||
|
**Example Facts**:
|
||||||
|
- "I recommended Yosemite National Park to Alice for hiking"
|
||||||
|
- "I helped debug a Python memory leak in the pandas DataFrame"
|
||||||
|
- "I explained the Big Five personality model to the user"
|
||||||
|
|
||||||
|
**Use Cases**:
|
||||||
|
- Self-awareness: "What did I recommend?"
|
||||||
|
- Consistency checking: "Have I said this before?"
|
||||||
|
- Context continuity: "What was I discussing with Alice?"
|
||||||
|
|
||||||
|
#### 2.1.3 Opinion Network
|
||||||
|
|
||||||
|
The Opinion Network (`fact_type='opinion'`) stores the agent's formed opinions and perspectives:
|
||||||
|
|
||||||
|
**Characteristics**:
|
||||||
|
- Generated during `think` operations when the agent reasons about topics
|
||||||
|
- Includes confidence scores (0.0-1.0) indicating certainty
|
||||||
|
- Contains explicit reasons for the opinion
|
||||||
|
- Immutable once formed (timestamped by formation date)
|
||||||
|
- Influenced by agent personality traits (Section 4)
|
||||||
|
|
||||||
|
**Example Facts**:
|
||||||
|
- "Python is better than JavaScript for data science (Reasons: has better libraries like pandas and numpy; stronger statistical computing ecosystem) [confidence: 0.85]"
|
||||||
|
- "Remote work improves productivity (Reasons: eliminates commute time; provides flexible scheduling) [confidence: 0.7]"
|
||||||
|
|
||||||
|
**Use Cases**:
|
||||||
|
- Consistent viewpoints: "What do I think about remote work?"
|
||||||
|
- Confidence-aware reasoning: Stronger opinions weigh more heavily
|
||||||
|
- Opinion evolution tracking over time
|
||||||
|
|
||||||
|
**Network Interconnection**: While logically separate, all three networks share the same graph infrastructure (temporal, semantic, and entity links), enabling cross-network traversal during search. For example, a query about "Alice's work" might start in the World Network ("Alice works at Google") and traverse entity links to the Agent Network ("I recommended technical books to Alice").
|
||||||
|
|
||||||
|
### 2.2 Memory Unit Structure
|
||||||
|
|
||||||
|
Each memory unit is represented as a self-contained node in the knowledge graph:
|
||||||
|
|
||||||
|
**Core Attributes**:
|
||||||
|
- `id`: Unique UUID for the memory unit
|
||||||
|
- `agent_id`: Identifier for the agent this memory belongs to
|
||||||
|
- `text`: Self-contained statement with resolved pronouns
|
||||||
|
- `embedding`: 384-dimensional vector (BAAI/bge-small-en-v1.5)
|
||||||
|
- `fact_type`: Network classification (world/agent/opinion)
|
||||||
|
- `event_date`: Timestamp when the fact became true
|
||||||
|
- `context`: Optional contextual metadata
|
||||||
|
- `access_count`: Frequency-based importance signal
|
||||||
|
- `confidence_score`: For opinions only (0.0-1.0)
|
||||||
|
|
||||||
|
**LLM-Based Extraction**: Raw content undergoes LLM processing to extract atomic facts:
|
||||||
|
|
||||||
|
1. **Pronoun Resolution**: "She loves hiking" → "Alice loves hiking"
|
||||||
|
2. **Completeness Validation**: Must contain subject + verb
|
||||||
|
3. **Fact Isolation**: One concept per unit
|
||||||
|
4. **Noise Filtering**: Removes greetings, filler, incomplete thoughts
|
||||||
|
5. **Network Classification**: Determines appropriate fact_type
|
||||||
|
|
||||||
|
This ensures each memory unit is independently understandable and searchable without requiring surrounding context.
|
||||||
|
|
||||||
|
### 2.3 Entity Resolution and Linking
|
||||||
|
|
||||||
|
Entity resolution creates strong connections between memories that share common entities, solving the problem where semantically dissimilar facts are related through shared identities.
|
||||||
|
|
||||||
|
#### 2.3.1 Named Entity Recognition
|
||||||
|
|
||||||
|
We use spaCy's NER pipeline to extract entities from memory text:
|
||||||
|
|
||||||
|
**Entity Types**:
|
||||||
|
- PERSON: "Alice", "Bob Chen"
|
||||||
|
- ORGANIZATION: "Google", "Stanford University"
|
||||||
|
- LOCATION: "Yosemite National Park", "California"
|
||||||
|
- PRODUCT: "Python", "pandas library"
|
||||||
|
- CONCEPT: "machine learning", "remote work"
|
||||||
|
- OTHER: Miscellaneous proper nouns
|
||||||
|
|
||||||
|
#### 2.3.2 Entity Disambiguation
|
||||||
|
|
||||||
|
Multiple mentions of entities (e.g., "Alice", "Alice Chen", "Alice C.") must be resolved to a single canonical entity. Our scoring algorithm combines three signals:
|
||||||
|
|
||||||
|
**Name Similarity (50% weight)**:
|
||||||
|
```
|
||||||
|
score = 1.0 - (levenshtein_distance / max_length)
|
||||||
|
```
|
||||||
|
Matches variations like "Bob" ↔ "Robert", "Google Inc" ↔ "Google"
|
||||||
|
|
||||||
|
**Co-occurrence Frequency (30% weight)**:
|
||||||
|
```
|
||||||
|
score = min(1.0, shared_memory_count / 10.0)
|
||||||
|
```
|
||||||
|
Entities mentioned together frequently are likely distinct (e.g., "Alice" and "Alice Cooper" appearing together indicates different people)
|
||||||
|
|
||||||
|
**Temporal Proximity (20% weight)**:
|
||||||
|
```
|
||||||
|
score = exp(-time_gap / 7_days)
|
||||||
|
```
|
||||||
|
Recent mentions more likely refer to the same entity
|
||||||
|
|
||||||
|
**Final Score**:
|
||||||
|
```
|
||||||
|
final_score = 0.5 * name_sim + 0.3 * cooccurrence + 0.2 * temporal
|
||||||
|
threshold = 0.75 for matching
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**: "Alice" mentioned on Monday and "Alice Chen" mentioned on Tuesday will be resolved to the same entity (high name similarity + close temporal proximity), but "Alice" and "Alice Cooper" in the same conversation will remain distinct (low co-occurrence score since they appear together).
|
||||||
|
|
||||||
|
#### 2.3.3 Entity Link Structure
|
||||||
|
|
||||||
|
Each entity creates a `link_type='entity'` edge between all memories mentioning it:
|
||||||
|
|
||||||
|
**Properties**:
|
||||||
|
- `weight=1.0` (constant, no temporal decay)
|
||||||
|
- `entity_id`: Reference to resolved canonical entity
|
||||||
|
- Bidirectional connections between all mentioning memories
|
||||||
|
|
||||||
|
**Impact on Retrieval**: Entity links enable graph traversal to discover indirectly related facts:
|
||||||
|
|
||||||
|
**Example Query**: "What does Alice do?"
|
||||||
|
1. **Semantic Match**: "Alice works at Google" (direct match)
|
||||||
|
2. **Entity Traversal**: Follow entity links for "Alice" →
|
||||||
|
- "Alice loves hiking" (different semantic space)
|
||||||
|
- "Google's office is in Mountain View" (via "Google" entity)
|
||||||
|
- "I recommended books to Alice" (Agent Network, via "Alice")
|
||||||
|
|
||||||
|
This graph connectivity solves the fundamental limitation of vector-only search: two facts can be strongly related through shared entities even when their embeddings are dissimilar.
|
||||||
|
|
||||||
|
### 2.4 Link Types and Graph Structure
|
||||||
|
|
||||||
|
The memory graph contains three types of edges connecting memory units:
|
||||||
|
|
||||||
|
#### 2.4.1 Temporal Links
|
||||||
|
|
||||||
|
Temporal links connect memories close in time, enabling temporal reasoning:
|
||||||
|
|
||||||
|
**Creation Logic**:
|
||||||
|
```python
|
||||||
|
if abs(event_date1 - event_date2) < time_window: # default: 24 hours
|
||||||
|
weight = max(0.3, 1.0 - (time_diff / time_window))
|
||||||
|
create_link(unit1, unit2, type='temporal', weight=weight)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Properties**:
|
||||||
|
- Decays linearly with time distance
|
||||||
|
- Minimum weight 0.3 to maintain some connectivity
|
||||||
|
- Enables "What happened around the same time?" queries
|
||||||
|
- Critical for narrative understanding and sequential reasoning
|
||||||
|
|
||||||
|
**Example**: Memories from the same conversation or day cluster together, enabling retrieval of context-adjacent facts.
|
||||||
|
|
||||||
|
#### 2.4.2 Semantic Links
|
||||||
|
|
||||||
|
Semantic links connect memories with similar meanings:
|
||||||
|
|
||||||
|
**Creation Logic**:
|
||||||
|
```python
|
||||||
|
similarity = cosine_similarity(embedding1, embedding2)
|
||||||
|
if similarity > threshold: # default: 0.7
|
||||||
|
create_link(unit1, unit2, type='semantic', weight=similarity)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Properties**:
|
||||||
|
- Uses pgvector HNSW index for efficient nearest-neighbor search
|
||||||
|
- Higher threshold (0.7) than retrieval (0.3) to avoid over-connection
|
||||||
|
- Weight equals cosine similarity score
|
||||||
|
- Enables "Tell me about similar topics" queries
|
||||||
|
|
||||||
|
**Example**: "Hiking in Yosemite" links to "Mountain climbing", "Trail running", "Outdoor activities"
|
||||||
|
|
||||||
|
#### 2.4.3 Entity Links
|
||||||
|
|
||||||
|
Entity links (described in Section 2.3.3) create the strongest connections:
|
||||||
|
|
||||||
|
**Properties**:
|
||||||
|
- `weight=1.0` (constant, never decays)
|
||||||
|
- Connects all memories mentioning the same resolved entity
|
||||||
|
- Most reliable traversal path during graph search
|
||||||
|
- Enables "Tell me everything about X" queries
|
||||||
|
|
||||||
|
**Graph Density**: Each memory unit typically has:
|
||||||
|
- 5-10 temporal links (to nearby memories)
|
||||||
|
- 3-5 semantic links (to similar content)
|
||||||
|
- Variable entity links (depending on entity mention frequency)
|
||||||
|
|
||||||
|
This multi-layered graph structure enables flexible traversal strategies that balance different types of relatedness.
|
||||||
|
|
||||||
|
## 3. Retrieval Architecture
|
||||||
|
|
||||||
|
Our retrieval pipeline addresses the fundamental challenge of long-term memory: achieving both **high recall** (finding all relevant information) and **high precision** (ranking the most relevant items first).
|
||||||
|
|
||||||
|
### 3.1 Four-Way Parallel Retrieval
|
||||||
|
|
||||||
|
We execute four complementary retrieval strategies in parallel, each capturing different aspects of relevance:
|
||||||
|
|
||||||
|
#### 3.1.1 Semantic Retrieval (Vector Similarity)
|
||||||
|
|
||||||
|
**Method**: Cosine similarity between query embedding and memory embeddings
|
||||||
|
**Index**: pgvector HNSW (Hierarchical Navigable Small World)
|
||||||
|
**Threshold**: ≥ 0.3 similarity
|
||||||
|
|
||||||
|
**Advantages**:
|
||||||
|
- Captures conceptual similarity
|
||||||
|
- Handles synonyms and paraphrasing
|
||||||
|
- Language-model understanding of meaning
|
||||||
|
|
||||||
|
**Limitations**:
|
||||||
|
- Misses exact proper nouns if not in training data
|
||||||
|
- Cannot reason about temporal relationships
|
||||||
|
- Weak at entity disambiguation
|
||||||
|
|
||||||
|
**Example**: Query "hiking activities" finds "mountain climbing", "trail running", even if exact words don't match
|
||||||
|
|
||||||
|
#### 3.1.2 Keyword Retrieval (BM25 Full-Text Search)
|
||||||
|
|
||||||
|
**Method**: PostgreSQL full-text search with BM25 ranking
|
||||||
|
**Index**: GIN index on `to_tsvector(text)`
|
||||||
|
**Advantages**:
|
||||||
|
- High precision for proper nouns and technical terms
|
||||||
|
- Exact phrase matching
|
||||||
|
- Fast execution (~5ms)
|
||||||
|
|
||||||
|
**Limitations**:
|
||||||
|
- No semantic understanding
|
||||||
|
- Requires exact or stemmed matches
|
||||||
|
- Weak at conceptual queries
|
||||||
|
|
||||||
|
**Example**: Query "Google" finds all memories mentioning "Google" even if semantically unrelated
|
||||||
|
|
||||||
|
**Complementarity**: Semantic + Keyword achieves >90% recall: vector search catches concepts, BM25 catches exact names.
|
||||||
|
|
||||||
|
#### 3.1.3 Graph Retrieval (Spreading Activation)
|
||||||
|
|
||||||
|
**Method**: Activation spreading from semantic entry points through the memory graph
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
```python
|
||||||
|
1. Get top-K semantic matches (similarity ≥ 0.5) as entry points
|
||||||
|
2. Initialize activation: entry_points.activation = 1.0
|
||||||
|
3. For each hop (up to thinking_budget nodes):
|
||||||
|
a. Select highest-activation unexplored node
|
||||||
|
b. Propagate to neighbors:
|
||||||
|
neighbor.activation = current.activation × edge.weight × decay
|
||||||
|
where decay = 0.8
|
||||||
|
c. Mark node as explored
|
||||||
|
4. Return all explored nodes ranked by final activation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Decay Mechanism**: Activation decays by 0.8 per hop, limiting spread to ~4-5 hops before negligible impact.
|
||||||
|
|
||||||
|
**Link Weighting**:
|
||||||
|
- Entity links: weight 1.0 (strongest signal)
|
||||||
|
- Semantic links: weight ∈ [0.7, 1.0] (cosine similarity)
|
||||||
|
- Temporal links: weight ∈ [0.3, 1.0] (time-based decay)
|
||||||
|
|
||||||
|
**Advantages**:
|
||||||
|
- Discovers indirectly related facts through graph connectivity
|
||||||
|
- Leverages entity links to traverse knowledge graph
|
||||||
|
- Finds context-adjacent memories via temporal links
|
||||||
|
|
||||||
|
**Example**: Query "Alice's work" → Semantic match "Alice works at Google" → Entity traverse to "Google's Mountain View office" → Temporal traverse to "Mountain View has good hiking nearby" → Entity traverse to "Alice loves Yosemite" (discovered indirectly through 3 hops)
|
||||||
|
|
||||||
|
#### 3.1.4 Temporal Graph Retrieval (Time-Constrained + Spreading)
|
||||||
|
|
||||||
|
**Activation Condition**: Only triggered when temporal constraint detected in query
|
||||||
|
|
||||||
|
**Temporal Parsing**: Uses `dateparser` library to extract date ranges:
|
||||||
|
- "last spring" → March 1 - May 31, previous year
|
||||||
|
- "in June" → June 1-30, current year
|
||||||
|
- "last year" → January 1 - December 31, previous year
|
||||||
|
- "between March and May" → March 1 - May 31, current year
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
```python
|
||||||
|
1. Parse query for temporal constraints → (start_date, end_date)
|
||||||
|
2. If no temporal constraint detected: skip this retrieval path
|
||||||
|
3. Find memories in date range with semantic threshold ≥ 0.4
|
||||||
|
4. Rank by temporal proximity to range center:
|
||||||
|
score = 1.0 - (abs(event_date - center_date) / range_size)
|
||||||
|
5. Spread activation through temporal links preferentially
|
||||||
|
6. Filter results: only keep if semantic similarity ≥ 0.3 to query
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Innovation**: Combines time filtering with semantic relevance to prevent temporal leakage:
|
||||||
|
- **Without semantic filter**: "What did Alice do in June?" returns ALL June activities (including Bob's, Charlie's, etc.)
|
||||||
|
- **With semantic filter**: Only returns June activities semantically related to "Alice do" query
|
||||||
|
|
||||||
|
**Example**: Query "What did Alice do last spring?"
|
||||||
|
1. Parse temporal: March 1 - May 31 (previous year)
|
||||||
|
2. Find spring memories with "Alice" mentions (semantic ≥ 0.4)
|
||||||
|
3. Spread through temporal links within spring
|
||||||
|
4. Final filter: semantic ≥ 0.3 to full query
|
||||||
|
Result: Alice's spring hiking trips, work projects, conversations
|
||||||
|
|
||||||
|
**Performance**: Temporal parsing adds <5ms latency, acceptable for user queries
|
||||||
|
|
||||||
|
### 3.2 Reciprocal Rank Fusion (RRF)
|
||||||
|
|
||||||
|
After parallel retrieval, we merge 3-4 ranked lists (semantic, keyword, graph, optional temporal-graph) using RRF:
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
```
|
||||||
|
For each memory unit d in union of all retrieval results:
|
||||||
|
RRF_score(d) = Σ_{i ∈ retrieval_paths} 1 / (k + rank_i(d))
|
||||||
|
where k = 60 (standard RRF constant)
|
||||||
|
rank_i(d) = rank of d in retrieval path i (or ∞ if not present)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Advantages over Score-Based Fusion**:
|
||||||
|
- **Rank-based**: Position matters more than absolute scores (addresses score calibration)
|
||||||
|
- **Robust to missing items**: Missing from a list contributes 0, not a penalty
|
||||||
|
- **Multi-evidence weighting**: Items appearing in multiple lists rank higher
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
- Memory A: rank 1 in semantic, rank 5 in keyword → RRF = 1/61 + 1/65 = 0.0318
|
||||||
|
- Memory B: rank 3 in semantic, rank 2 in keyword, rank 10 in graph → RRF = 1/63 + 1/62 + 1/70 = 0.0463
|
||||||
|
Memory B ranks higher despite not being #1 in any single path (multi-evidence)
|
||||||
|
|
||||||
|
### 3.3 Reranking Strategies
|
||||||
|
|
||||||
|
After RRF fusion, we apply sophisticated reranking to refine precision:
|
||||||
|
|
||||||
|
#### 3.3.1 Heuristic Reranker (Default)
|
||||||
|
|
||||||
|
**Formula**:
|
||||||
|
```
|
||||||
|
score = 0.6 × semantic_norm + 0.4 × bm25_norm
|
||||||
|
+ 0.2 × recency_boost
|
||||||
|
+ 0.1 × frequency_boost
|
||||||
|
|
||||||
|
where:
|
||||||
|
semantic_norm = normalized semantic similarity score
|
||||||
|
bm25_norm = normalized BM25 score
|
||||||
|
recency_boost = log(1 + days_old) / log(1 + 365) # 1-year half-life
|
||||||
|
frequency_boost = min(1.0, access_count / 100)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Advantages**:
|
||||||
|
- Zero latency overhead
|
||||||
|
- Interpretable scoring components
|
||||||
|
- Incorporates recency and popularity signals
|
||||||
|
|
||||||
|
**Use Case**: Production systems requiring <100ms total latency
|
||||||
|
|
||||||
|
#### 3.3.2 Cross-Encoder Reranker (Optional)
|
||||||
|
|
||||||
|
**Model**: `cross-encoder/ms-marco-MiniLM-L-6-v2` (pretrained on MS MARCO passage ranking)
|
||||||
|
|
||||||
|
**Method**: Neural reranking with query-document pair classification
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
```python
|
||||||
|
for each candidate memory unit:
|
||||||
|
input_text = f"[Date: {formatted_date}] {memory.text}"
|
||||||
|
score = cross_encoder.predict([(query, input_text)])[0]
|
||||||
|
score_normalized = sigmoid(score) # → [0, 1]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Date Formatting**: Includes formatted dates in input to help model understand temporal relevance:
|
||||||
|
- `"[Date: November 06, 2025 (2025-11-06)] Alice started working at Google"`
|
||||||
|
|
||||||
|
**Performance**: ~80ms for 100 candidates (batched inference on MPS/CUDA)
|
||||||
|
|
||||||
|
**Advantages**:
|
||||||
|
- 5-10% better precision than heuristic (empirical on LoComo benchmark)
|
||||||
|
- Learns query-document relevance patterns from supervised data
|
||||||
|
- Considers full query-document interaction (not just independent scores)
|
||||||
|
|
||||||
|
**Trade-off**: Latency vs. accuracy
|
||||||
|
- Heuristic: 0ms overhead, 85% precision
|
||||||
|
- Cross-encoder: 80ms overhead, 90% precision
|
||||||
|
|
||||||
|
**Pluggable Design**: Abstract `CrossEncoderReranker` interface allows future API-based rerankers (e.g., Cohere Rerank, Jina Reranker)
|
||||||
|
|
||||||
|
### 3.4 Maximal Marginal Relevance (MMR) Diversification
|
||||||
|
|
||||||
|
Final stage applies MMR to balance relevance and diversity:
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
```python
|
||||||
|
selected = []
|
||||||
|
while len(selected) < top_k:
|
||||||
|
candidates = reranked_results - selected
|
||||||
|
for each c in candidates:
|
||||||
|
mmr_score(c) = λ × relevance(c) - (1-λ) × max_similarity(c, selected)
|
||||||
|
selected.append(argmax(mmr_score))
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters**:
|
||||||
|
- λ = 0.5 (equal weight to relevance and diversity)
|
||||||
|
- `relevance(c)` = reranker score
|
||||||
|
- `max_similarity(c, selected)` = highest cosine similarity to any already-selected item
|
||||||
|
|
||||||
|
**Purpose**: Prevents redundant results
|
||||||
|
- Without MMR: "Alice works at Google", "Alice is employed by Google", "Alice's employer is Google"
|
||||||
|
- With MMR: "Alice works at Google", "Alice loves hiking", "Google's office is in Mountain View"
|
||||||
|
|
||||||
|
### 3.5 Complete Retrieval Pipeline
|
||||||
|
|
||||||
|
**End-to-End Flow**:
|
||||||
|
```
|
||||||
|
1. Query Processing (5ms)
|
||||||
|
- Generate embedding
|
||||||
|
- Parse temporal constraints (dateparser)
|
||||||
|
- Determine active retrieval paths
|
||||||
|
|
||||||
|
2. Parallel Retrieval (30-50ms)
|
||||||
|
- Semantic: pgvector HNSW search
|
||||||
|
- Keyword: PostgreSQL BM25
|
||||||
|
- Graph: Spreading activation from entry points
|
||||||
|
- Temporal-Graph: (optional) Time-filtered + semantic spreading
|
||||||
|
|
||||||
|
3. RRF Fusion (1ms)
|
||||||
|
- Merge 3-4 ranked lists
|
||||||
|
- Position-based scoring
|
||||||
|
|
||||||
|
4. Reranking (0-80ms depending on strategy)
|
||||||
|
- Heuristic: Weighted scoring with recency/frequency
|
||||||
|
- Cross-encoder: Neural relevance prediction
|
||||||
|
|
||||||
|
5. MMR Diversification (1ms)
|
||||||
|
- Iterative diverse selection
|
||||||
|
|
||||||
|
6. Token Budget Filtering (1ms)
|
||||||
|
- Truncate to fit context window
|
||||||
|
|
||||||
|
Total Latency:
|
||||||
|
- Heuristic: 40-60ms (suitable for real-time)
|
||||||
|
- Cross-encoder: 120-140ms (suitable for user-facing search)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Guarantees**:
|
||||||
|
- **High Recall**: Four parallel strategies cast wide net (>95% of relevant memories found)
|
||||||
|
- **High Precision**: Reranking + MMR refine to most relevant, diverse results
|
||||||
|
- **Scalability**: Connection pooling + HNSW index + batching → thousands of memories/second
|
||||||
|
|
||||||
|
## 4. Agent Personality Framework
|
||||||
|
|
||||||
|
While search retrieval remains objective, the `think` operation allows personality-driven reasoning that influences how agents interpret facts and form opinions.
|
||||||
|
|
||||||
|
### 4.1 Personality Model
|
||||||
|
|
||||||
|
We adopt the **Big Five** personality model (OCEAN), which is empirically validated across cultures and provides continuous trait dimensions:
|
||||||
|
|
||||||
|
**Trait Dimensions** (each 0.0-1.0):
|
||||||
|
|
||||||
|
1. **Openness** (O): Receptiveness to new ideas, creativity, abstract thinking
|
||||||
|
- High: "I embrace novel approaches", "innovation over tradition"
|
||||||
|
- Low: "I prefer proven methods", "tradition over experimentation"
|
||||||
|
|
||||||
|
2. **Conscientiousness** (C): Organization, goal-directed behavior, dependability
|
||||||
|
- High: "I plan systematically", "evidence-based decisions"
|
||||||
|
- Low: "I work flexibly", "intuition-based decisions"
|
||||||
|
|
||||||
|
3. **Extraversion** (E): Sociability, assertiveness, energy from interaction
|
||||||
|
- High: "I seek collaboration", "enthusiastic communication"
|
||||||
|
- Low: "I prefer solitude", "measured communication"
|
||||||
|
|
||||||
|
4. **Agreeableness** (A): Cooperation, empathy, conflict avoidance
|
||||||
|
- High: "I seek consensus", "consider social harmony"
|
||||||
|
- Low: "I express dissent", "prioritize accuracy over harmony"
|
||||||
|
|
||||||
|
5. **Neuroticism** (N): Emotional sensitivity, anxiety, stress response
|
||||||
|
- High: "I consider risks carefully", "emotionally engaged"
|
||||||
|
- Low: "I remain calm under uncertainty", "emotionally detached"
|
||||||
|
|
||||||
|
**Bias Strength** (0.0-1.0): Meta-parameter controlling how much personality influences opinions
|
||||||
|
- 0.0: Neutral, fact-based reasoning (no personality bias)
|
||||||
|
- 0.5: Moderate personality influence, balanced with objective analysis
|
||||||
|
- 1.0: Strong personality influence, facts filtered through trait lens
|
||||||
|
|
||||||
|
### 4.2 Agent Profile Structure
|
||||||
|
|
||||||
|
Each agent has an associated profile stored in the `agents` table:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE agents (
|
||||||
|
agent_id TEXT PRIMARY KEY,
|
||||||
|
personality JSONB NOT NULL DEFAULT '{
|
||||||
|
"openness": 0.5,
|
||||||
|
"conscientiousness": 0.5,
|
||||||
|
"extraversion": 0.5,
|
||||||
|
"agreeableness": 0.5,
|
||||||
|
"neuroticism": 0.5,
|
||||||
|
"bias_strength": 0.5
|
||||||
|
}',
|
||||||
|
background TEXT DEFAULT '',
|
||||||
|
created_at TIMESTAMP DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP DEFAULT NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Background Field**: First-person narrative describing the agent's context:
|
||||||
|
- "I am a software engineer with 10 years of startup experience"
|
||||||
|
- "I was born in Texas and value innovation over tradition"
|
||||||
|
- "I am a creative artist interested in digital media"
|
||||||
|
|
||||||
|
**Auto-Creation**: Calling `get_agent_profile(agent_id)` creates an agent with default personality (all traits = 0.5) if not exists.
|
||||||
|
|
||||||
|
### 4.3 Personality Integration in Think Operation
|
||||||
|
|
||||||
|
The `think_async()` method retrieves the agent's profile and injects it into the LLM prompt:
|
||||||
|
|
||||||
|
**Retrieval Flow**:
|
||||||
|
```python
|
||||||
|
1. Get agent profile: personality + background
|
||||||
|
2. Search for relevant facts (world, agent, opinion networks)
|
||||||
|
3. Build personality description from traits
|
||||||
|
4. Construct LLM prompt with:
|
||||||
|
- World facts: "What I know about the world"
|
||||||
|
- Agent facts: "My experiences and actions"
|
||||||
|
- Opinion facts: "My existing beliefs"
|
||||||
|
- Personality traits: "My personality (Big Five + bias strength)"
|
||||||
|
- Background: "My background"
|
||||||
|
5. Adjust system message based on bias_strength
|
||||||
|
6. Generate response (opinions inherit current personality)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Trait Description Generation**:
|
||||||
|
```python
|
||||||
|
def describe_trait(name: str, value: float) -> str:
|
||||||
|
if value >= 0.8: return f"very high {name}"
|
||||||
|
elif value >= 0.6: return f"high {name}"
|
||||||
|
elif value >= 0.4: return f"moderate {name}"
|
||||||
|
elif value >= 0.2: return f"low {name}"
|
||||||
|
else: return f"very low {name}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**System Message Adaptation**:
|
||||||
|
- **High bias (≥0.7)**: "Your personality strongly influences your thinking. Let your traits guide how you interpret facts and form opinions. Don't be afraid to be biased based on your personality."
|
||||||
|
- **Moderate bias (0.4-0.7)**: "Your personality moderately influences your thinking. Balance your personal traits with objective analysis."
|
||||||
|
- **Low bias (<0.4)**: "Your personality has minimal influence on your thinking. Focus primarily on facts while keeping your traits in mind."
|
||||||
|
|
||||||
|
**Example Prompt (bias_strength=0.8)**:
|
||||||
|
```
|
||||||
|
Here's what I know and have experienced:
|
||||||
|
|
||||||
|
MY IDENTITY & EXPERIENCES:
|
||||||
|
[agent facts]
|
||||||
|
|
||||||
|
WHAT I KNOW ABOUT THE WORLD:
|
||||||
|
[world facts]
|
||||||
|
|
||||||
|
MY EXISTING OPINIONS & BELIEFS:
|
||||||
|
[opinion facts]
|
||||||
|
|
||||||
|
Your personality traits:
|
||||||
|
- very high openness to new ideas
|
||||||
|
- low conscientiousness and organization
|
||||||
|
- high extraversion and sociability
|
||||||
|
- low agreeableness and cooperation
|
||||||
|
- moderate emotional sensitivity
|
||||||
|
|
||||||
|
Personality influence strength: 80% (how much your personality shapes your opinions)
|
||||||
|
|
||||||
|
Your background:
|
||||||
|
I am a creative software engineer who values innovation over tradition.
|
||||||
|
|
||||||
|
QUESTION: What do you think about remote work?
|
||||||
|
|
||||||
|
Based on everything I know, believe, and who I am (including my personality and background), here's what I genuinely think about this question...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Opinion Formation**: Opinions extracted from the response are stored with `event_date` = current timestamp, capturing when the opinion was formed under the current personality configuration. This allows tracking opinion evolution over time as personality changes.
|
||||||
|
|
||||||
|
### 4.4 Background Merging
|
||||||
|
|
||||||
|
The `merge_agent_background()` method uses LLM-powered merging to handle updates intelligently:
|
||||||
|
|
||||||
|
**Conflict Resolution**: New information overwrites old when contradictory
|
||||||
|
- Current: "I was born in Colorado"
|
||||||
|
- New: "You were born in Texas"
|
||||||
|
- Result: "I was born in Texas" (conflict resolved, Colorado removed)
|
||||||
|
|
||||||
|
**Addition**: Non-conflicting information is appended
|
||||||
|
- Current: "I was born in Texas"
|
||||||
|
- New: "I have 10 years of startup experience"
|
||||||
|
- Result: "I was born in Texas. I have 10 years of startup experience."
|
||||||
|
|
||||||
|
**First-Person Normalization**: Input can be second-person ("You...") but always stored as first-person ("I...")
|
||||||
|
|
||||||
|
**LLM Prompt**:
|
||||||
|
```
|
||||||
|
Current background: {current}
|
||||||
|
New information: {new_info}
|
||||||
|
|
||||||
|
Merge these, resolving conflicts (new info overwrites old).
|
||||||
|
Output in FIRST PERSON ("I"). Be concise (under 500 characters).
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 Use Cases
|
||||||
|
|
||||||
|
**Diverse Perspectives from Same Facts**:
|
||||||
|
- Agent A (high openness=0.9, low conscientiousness=0.2): "Remote work enables creative flexibility"
|
||||||
|
- Agent B (low openness=0.2, high conscientiousness=0.9): "Remote work lacks the structure needed for accountability"
|
||||||
|
|
||||||
|
Both agents see the same facts about remote work productivity studies, but form opposite opinions due to personality.
|
||||||
|
|
||||||
|
**Consistent Agent Identity**:
|
||||||
|
Personality traits ensure the agent maintains a consistent reasoning style across interactions, even when facts change.
|
||||||
|
|
||||||
|
**User Customization**:
|
||||||
|
Users can create agents with specific traits to match desired interaction styles (e.g., skeptical analyst vs. optimistic ideator).
|
||||||
|
|
||||||
|
## 5. Implementation Details
|
||||||
|
|
||||||
|
### 5.1 Technology Stack
|
||||||
|
|
||||||
|
**Database**:
|
||||||
|
- PostgreSQL 15+ with `pgvector` extension (HNSW index for vector search)
|
||||||
|
- `uuid-ossp` extension for UUID generation
|
||||||
|
- JSONB columns for flexible personality storage
|
||||||
|
|
||||||
|
**Python Libraries**:
|
||||||
|
- `asyncpg`: Async PostgreSQL driver with connection pooling
|
||||||
|
- `sentence-transformers`: Embedding model (BAAI/bge-small-en-v1.5, 384-dim) and cross-encoder (ms-marco-MiniLM-L-6-v2)
|
||||||
|
- `openai`: LLM API client (supports OpenAI, Groq, Ollama)
|
||||||
|
- `spacy`: Named entity recognition (en_core_web_sm)
|
||||||
|
- `dateparser`: Natural language temporal parsing
|
||||||
|
- `fastapi`: Web API framework
|
||||||
|
- `alembic`: Database migrations
|
||||||
|
|
||||||
|
**Architecture Patterns**:
|
||||||
|
- **Mixin Pattern**: Operations split into `EmbeddingOperationsMixin`, `LinkOperationsMixin`, `ThinkOperationsMixin`, `AgentOperationsMixin`
|
||||||
|
- **Connection Pooling**: asyncpg pool (min=5, max=100 connections) with backpressure
|
||||||
|
- **Background Task Management**: AsyncIOQueueBackend for async opinion storage
|
||||||
|
- **Caching**: LLM client cached at init, tiktoken encoding cached globally
|
||||||
|
|
||||||
|
### 5.2 Performance Optimizations
|
||||||
|
|
||||||
|
**Indexing Strategy**:
|
||||||
|
```sql
|
||||||
|
-- Vector search (HNSW)
|
||||||
|
CREATE INDEX idx_memory_units_embedding
|
||||||
|
ON memory_units USING hnsw (embedding vector_cosine_ops);
|
||||||
|
|
||||||
|
-- BM25 full-text search
|
||||||
|
CREATE INDEX idx_memory_units_fts
|
||||||
|
ON memory_units USING GIN (to_tsvector('english', text));
|
||||||
|
|
||||||
|
-- Temporal queries
|
||||||
|
CREATE INDEX idx_memory_units_agent_date
|
||||||
|
ON memory_units (agent_id, event_date DESC);
|
||||||
|
|
||||||
|
-- Entity lookups
|
||||||
|
CREATE INDEX idx_unit_entities_unit ON unit_entities (unit_id);
|
||||||
|
CREATE INDEX idx_unit_entities_entity ON unit_entities (entity_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Query Optimization**:
|
||||||
|
- Parallel execution of 4 retrieval paths using `asyncio.gather()`
|
||||||
|
- Batch embedding generation (50-100 texts at once)
|
||||||
|
- Connection pooling with backpressure (max 10 concurrent searches)
|
||||||
|
- Cross-encoder batched inference (100 pairs at once)
|
||||||
|
|
||||||
|
**Latency Breakdown** (100 memories, thinking_budget=50):
|
||||||
|
- Query embedding: 60ms (GPU/MPS accelerated)
|
||||||
|
- 4-way retrieval: 30-50ms (parallel)
|
||||||
|
- RRF fusion: 1ms
|
||||||
|
- Reranking: 0-80ms (heuristic vs. cross-encoder)
|
||||||
|
- MMR: 1ms
|
||||||
|
- **Total**: 92-192ms (heuristic: 92ms, cross-encoder: 192ms)
|
||||||
|
|
||||||
|
### 5.3 Scalability Analysis
|
||||||
|
|
||||||
|
**Memory Capacity**:
|
||||||
|
- 10,000 memories: <100ms retrieval
|
||||||
|
- 100,000 memories: <150ms retrieval (HNSW index maintains log complexity)
|
||||||
|
- 1,000,000+ memories: Sharding by agent_id recommended
|
||||||
|
|
||||||
|
**Concurrent Requests**:
|
||||||
|
- Connection pool supports 100 concurrent requests
|
||||||
|
- Each search uses 2-4 connections temporarily
|
||||||
|
- Backpressure mechanism prevents database overload (semaphore limiting)
|
||||||
|
|
||||||
|
**Storage Requirements** (per 1000 memories):
|
||||||
|
- Embeddings: 1.5 MB (384-dim float32)
|
||||||
|
- Links: ~5 KB/memory × 1000 = 5 MB
|
||||||
|
- Metadata: ~1 KB/memory × 1000 = 1 MB
|
||||||
|
- **Total**: ~7.5 MB per 1000 memories
|
||||||
|
|
||||||
|
## 6. API Endpoints
|
||||||
|
|
||||||
|
### 6.1 Memory Operations
|
||||||
|
|
||||||
|
**Store Memories**:
|
||||||
|
```
|
||||||
|
POST /api/memories/batch
|
||||||
|
Body: {
|
||||||
|
"agent_id": "user123",
|
||||||
|
"items": [{"content": "...", "context": "..."}],
|
||||||
|
"document_id": "conversation_001"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Search Memories**:
|
||||||
|
```
|
||||||
|
POST /api/search
|
||||||
|
Body: {
|
||||||
|
"agent_id": "user123",
|
||||||
|
"query": "What does Alice do?",
|
||||||
|
"fact_type": ["world", "agent", "opinion"],
|
||||||
|
"thinking_budget": 100,
|
||||||
|
"reranker": "cross-encoder"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Think Operation**:
|
||||||
|
```
|
||||||
|
POST /api/think
|
||||||
|
Body: {
|
||||||
|
"agent_id": "user123",
|
||||||
|
"query": "What do you think about remote work?",
|
||||||
|
"thinking_budget": 50,
|
||||||
|
"context": "optional additional context"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 Agent Profile Operations
|
||||||
|
|
||||||
|
**Get Profile** (auto-creates if not exists):
|
||||||
|
```
|
||||||
|
GET /api/agents/{agent_id}/profile
|
||||||
|
Response: {
|
||||||
|
"agent_id": "user123",
|
||||||
|
"personality": {"openness": 0.5, ...},
|
||||||
|
"background": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Create/Update Agent**:
|
||||||
|
```
|
||||||
|
PUT /api/agents/{agent_id}
|
||||||
|
Body: {
|
||||||
|
"personality": {"openness": 0.8, ...}, # optional
|
||||||
|
"background": "I am a creative engineer" # optional
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Update Personality**:
|
||||||
|
```
|
||||||
|
PUT /api/agents/{agent_id}/profile
|
||||||
|
Body: {
|
||||||
|
"personality": {"openness": 0.8, "conscientiousness": 0.6, ...}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Merge Background** (LLM-powered conflict resolution):
|
||||||
|
```
|
||||||
|
POST /api/agents/{agent_id}/background
|
||||||
|
Body: {
|
||||||
|
"content": "I was born in Texas"
|
||||||
|
}
|
||||||
|
Response: {
|
||||||
|
"background": "I was born in Texas. I have 10 years of experience."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**List All Agents**:
|
||||||
|
```
|
||||||
|
GET /api/agents
|
||||||
|
Response: {
|
||||||
|
"agents": [
|
||||||
|
{
|
||||||
|
"agent_id": "user123",
|
||||||
|
"personality": {...},
|
||||||
|
"background": "...",
|
||||||
|
"created_at": "2024-01-15T10:30:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. Evaluation and Future Work
|
||||||
|
|
||||||
|
### 7.1 Current Performance
|
||||||
|
|
||||||
|
**Benchmarks**:
|
||||||
|
- LoComo (Long-term Conversational Memory): Evaluates multi-turn conversation understanding
|
||||||
|
- LongMemEval: Tests long-term memory retention and retrieval
|
||||||
|
|
||||||
|
**Preliminary Results** (internal testing):
|
||||||
|
- Recall@20: >95% (4-way retrieval)
|
||||||
|
- Precision@5: 90% (cross-encoder), 85% (heuristic)
|
||||||
|
- Latency: 92ms (heuristic), 192ms (cross-encoder)
|
||||||
|
|
||||||
|
### 7.2 Future Directions
|
||||||
|
|
||||||
|
**Hierarchical Memory Organization**:
|
||||||
|
- Summarization of old memories into higher-level abstractions
|
||||||
|
- Multi-resolution retrieval (detailed recent + summarized distant past)
|
||||||
|
|
||||||
|
**Cross-Agent Memory Sharing**:
|
||||||
|
- Controlled sharing of world facts between agents
|
||||||
|
- Privacy-preserving opinion isolation
|
||||||
|
|
||||||
|
**Continual Learning**:
|
||||||
|
- Personality trait evolution based on feedback
|
||||||
|
- Opinion confidence updating with new evidence
|
||||||
|
|
||||||
|
**Multi-Modal Memory**:
|
||||||
|
- Image embeddings for visual memories
|
||||||
|
- Audio/video content integration
|
||||||
|
|
||||||
|
**Advanced Entity Resolution**:
|
||||||
|
- Deep learning-based entity disambiguation
|
||||||
|
- Cross-document coreference resolution
|
||||||
|
|
||||||
|
## 8. Conclusion
|
||||||
|
|
||||||
|
Memora presents a comprehensive memory architecture for conversational AI agents that addresses the fundamental challenges of long-term memory: maintaining high recall through parallel multi-strategy retrieval while achieving high precision through neural reranking and diversification. The introduction of explicit entity resolution and graph-based traversal enables discovery of indirectly related information that pure vector approaches miss. The personality framework allows agents to form consistent, context-aware opinions that reflect configurable psychological traits.
|
||||||
|
|
||||||
|
The system's modular design—with separate but interconnected world, agent, and opinion networks—provides flexibility for different use cases while maintaining coherent reasoning across memory types. By combining classical information retrieval techniques (BM25, graph search) with modern neural methods (embeddings, cross-encoders), we achieve a robust system that balances interpretability, performance, and accuracy.
|
||||||
|
|
||||||
|
Future work will explore hierarchical memory organization, continual learning of personality traits, and multi-modal memory integration to further enhance the system's capabilities.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
1. McCrae, R. R., & Costa, P. T. (1997). Personality trait structure as a human universal. *American Psychologist*, 52(5), 509.
|
||||||
|
|
||||||
|
2. Malkov, Y. A., & Yashunin, D. A. (2018). Efficient and robust approximate nearest neighbor search using hierarchical navigable small world graphs. *IEEE Transactions on Pattern Analysis and Machine Intelligence*, 42(4), 824-836.
|
||||||
|
|
||||||
|
3. Robertson, S., & Zaragoza, H. (2009). The probabilistic relevance framework: BM25 and beyond. *Foundations and Trends in Information Retrieval*, 3(4), 333-389.
|
||||||
|
|
||||||
|
4. Carbonell, J., & Goldstein, J. (1998). The use of MMR, diversity-based reranking for reordering documents and producing summaries. In *SIGIR'98* (pp. 335-336).
|
||||||
|
|
||||||
|
5. Craswell, N., Mitra, B., Yilmaz, E., & Campos, D. (2020). Overview of the TREC 2019 deep learning track. *arXiv preprint arXiv:2003.07820*.
|
||||||
302
README.md
302
README.md
|
|
@ -4,193 +4,35 @@ A temporal-semantic-entity memory system that enables AI agents to store, retrie
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Three Memory Networks
|
**See [architecture.md](architecture.md) for comprehensive technical documentation.**
|
||||||
|
|
||||||
The system maintains three separate but interconnected memory networks:
|
The system provides:
|
||||||
|
- **Three Memory Networks**: Separate world knowledge, agent experiences, and formed opinions
|
||||||
|
- **Multi-Strategy Retrieval**: 4-way parallel search (semantic, keyword, graph, temporal-graph)
|
||||||
|
- **Entity Resolution**: Automatic entity disambiguation and linking
|
||||||
|
- **Personality Framework**: Big Five traits influencing opinion formation
|
||||||
|
- **Neural Reranking**: Optional cross-encoder for precision refinement
|
||||||
|
|
||||||
**1. World Network** (`fact_type='world'`)
|
### Quick Architecture Overview
|
||||||
- General knowledge and facts about the world
|
|
||||||
- Information not specific to the agent's actions
|
|
||||||
- Example: "Alice works at Google", "Yosemite is in California"
|
|
||||||
|
|
||||||
**2. Agent Network** (`fact_type='agent'`)
|
**Three Memory Networks**:
|
||||||
- Facts about what the AI agent specifically did
|
1. **World Network**: General knowledge ("Alice works at Google")
|
||||||
- Agent's own actions and experiences
|
2. **Agent Network**: Agent's own actions ("I recommended Yosemite to Alice")
|
||||||
- Example: "The agent helped debug a Python script", "The agent recommended Yosemite"
|
3. **Opinion Network**: Formed opinions with confidence scores ("Python is better for data science [0.85]")
|
||||||
|
|
||||||
**3. Opinion Network** (`fact_type='opinion'`)
|
**Retrieval Pipeline**:
|
||||||
- Agent's formed opinions and perspectives
|
|
||||||
- Automatically extracted during think operations
|
|
||||||
- Includes reasons and confidence scores (0.0-1.0)
|
|
||||||
- Immutable once formed (event_date = when opinion was formed)
|
|
||||||
- Example: "Python is better for data science than JavaScript (Reasons: has better libraries like pandas and numpy) [confidence: 0.85]"
|
|
||||||
|
|
||||||
All three networks share the same infrastructure (temporal/semantic/entity links) but can be searched independently or together.
|
|
||||||
|
|
||||||
### Core Components
|
|
||||||
|
|
||||||
**Memory Units**: Individual sentence-level memories that are:
|
|
||||||
- Self-contained (pronouns resolved to actual referents by LLM)
|
|
||||||
- Validated to have subject + verb (complete thoughts)
|
|
||||||
- Embedded as 384-dim vectors using `BAAI/bge-small-en-v1.5`
|
|
||||||
- Timestamped for temporal relationships
|
|
||||||
- Linked to extracted entities via spaCy NER
|
|
||||||
- Classified as 'world', 'agent', or 'opinion'
|
|
||||||
|
|
||||||
**Entity Resolution**: Named entities (PERSON, ORG, PLACE, PRODUCT, CONCEPT, OTHER) are:
|
|
||||||
- Extracted using spaCy NER
|
|
||||||
- Disambiguated using scoring algorithm (name similarity 50%, co-occurrence 30%, temporal proximity 20%)
|
|
||||||
- Tracked with canonical IDs across all memories
|
|
||||||
- Used to create strong connections between related memories
|
|
||||||
|
|
||||||
### Three Types of Memory Links
|
|
||||||
|
|
||||||
**1. Temporal Links** (Time-Based)
|
|
||||||
- Connect memories within time window (default: 24 hours)
|
|
||||||
- Weight: `max(0.3, 1.0 - (time_diff / window_size))`
|
|
||||||
- Closer in time = stronger link
|
|
||||||
- Use case: "What happened recently?" or understanding sequences
|
|
||||||
|
|
||||||
**2. Semantic Links** (Meaning-Based)
|
|
||||||
- Connect memories with similar embeddings
|
|
||||||
- Uses pgvector with HNSW index for fast nearest neighbor search
|
|
||||||
- Create links only if cosine similarity > threshold (default: 0.7)
|
|
||||||
- Weight = cosine similarity score
|
|
||||||
- Use case: "Tell me about hiking" retrieves all semantically related activities
|
|
||||||
|
|
||||||
**3. Entity Links** (Identity-Based)
|
|
||||||
- Connect ALL memories mentioning the same entity
|
|
||||||
- No decay over time (weight 1.0)
|
|
||||||
- Critical advantage: Solves the problem where "Alice loves hiking" wouldn't normally connect to "Alice works at Google" through semantic similarity alone
|
|
||||||
- Use case: "What does Alice do?" returns ALL memories about Alice
|
|
||||||
|
|
||||||
### 4-Way Parallel Retrieval with Reranking
|
|
||||||
|
|
||||||
The search algorithm uses a sophisticated multi-stage pipeline that combines four different retrieval strategies, followed by fusion and reranking:
|
|
||||||
|
|
||||||
#### Stage 1: Parallel Retrieval (4 paths)
|
|
||||||
|
|
||||||
The system runs **four retrieval methods in parallel** to capture different types of relevance:
|
|
||||||
|
|
||||||
**1. Semantic Retrieval** (Vector Similarity)
|
|
||||||
- Uses embedding cosine similarity via pgvector
|
|
||||||
- Finds memories that are conceptually similar to the query
|
|
||||||
- Threshold: similarity ≥ 0.3
|
|
||||||
- **Why**: Captures meaning and intent, even when exact words don't match
|
|
||||||
- Example: "hiking activities" finds "mountain climbing", "trail running"
|
|
||||||
|
|
||||||
**2. Keyword Retrieval** (BM25 Full-Text Search)
|
|
||||||
- Uses PostgreSQL's full-text search with BM25 ranking
|
|
||||||
- Finds memories with matching terms and phrases
|
|
||||||
- **Why**: Catches exact terminology and proper nouns that embeddings might miss
|
|
||||||
- Example: "Google" query finds all mentions of the company name
|
|
||||||
- Complements semantic search: high precision for named entities
|
|
||||||
|
|
||||||
**3. Graph Retrieval** (Spreading Activation)
|
|
||||||
- Starts from top semantic matches (similarity ≥ 0.5)
|
|
||||||
- Spreads activation through temporal, semantic, and entity links
|
|
||||||
- Activation decays by 0.8 at each hop
|
|
||||||
- Budget-limited exploration (default: thinking_budget nodes)
|
|
||||||
- **Why**: Discovers indirectly related memories through relationships
|
|
||||||
- Example: Query "Alice" → spreads to "Google" → finds "Mountain View office"
|
|
||||||
- Leverages entity links (constant weight 1.0) to traverse the knowledge graph
|
|
||||||
|
|
||||||
**4. Temporal Graph Retrieval** (Time-Aware + Spreading)
|
|
||||||
- **Activated only when temporal constraint detected** (e.g., "last year", "in June", "last spring")
|
|
||||||
- Uses `dateparser` library (<5ms) to extract date ranges
|
|
||||||
- Finds memories in date range with semantic threshold (≥ 0.4)
|
|
||||||
- Spreads through temporal links to related facts
|
|
||||||
- Scores by temporal proximity (closer to range center = higher)
|
|
||||||
- **Why**: Enables time-scoped queries while maintaining relevance
|
|
||||||
- Example: "What did Alice do last spring?" → finds March-May activities about Alice only
|
|
||||||
- Prevents temporal leakage: Mike's June activities won't appear in Alice's June query
|
|
||||||
|
|
||||||
**Why All Four?**
|
|
||||||
- Semantic captures meaning but misses exact matches
|
|
||||||
- Keyword catches proper nouns but misses synonyms
|
|
||||||
- Graph discovers indirect relationships via entity/temporal/semantic links
|
|
||||||
- Temporal graph enables time-scoped retrieval while filtering by relevance
|
|
||||||
- Together they achieve **high recall** (find everything relevant) before reranking refines to **high precision**
|
|
||||||
|
|
||||||
#### Stage 2: Reciprocal Rank Fusion (RRF)
|
|
||||||
|
|
||||||
Merges the 3-4 ranked lists using RRF algorithm:
|
|
||||||
```
|
```
|
||||||
RRF_score(d) = Σ (1 / (k + rank_i(d))) where k=60
|
Query → [Semantic + Keyword + Graph + Temporal] → RRF Merge → Reranker → MMR → Results
|
||||||
```
|
```
|
||||||
- Handles ties and missing items gracefully
|
- 4-way parallel retrieval for high recall
|
||||||
- Gives more weight to items appearing in multiple lists
|
- Neural reranking (optional) for precision
|
||||||
- Position-based scoring (rank matters more than raw scores)
|
- MMR diversification to avoid redundancy
|
||||||
|
|
||||||
#### Stage 3: Reranking (2 strategies)
|
**Key Features**:
|
||||||
|
- Entity resolution links memories through shared people/places/things
|
||||||
**Heuristic Reranker** (default: fast, ~0ms overhead)
|
- Graph spreading activation discovers indirect connections
|
||||||
- Base score: 60% semantic + 40% BM25 (normalized)
|
- Temporal queries: "What did Alice do last spring?"
|
||||||
- Boosts: +20% recency (log decay, 1-year half-life), +10% frequency (access_count)
|
- Personality traits (Big Five model) influence opinion formation
|
||||||
- **When to use**: Production workloads needing speed
|
|
||||||
- **Advantage**: No additional latency, interpretable scoring
|
|
||||||
|
|
||||||
**Cross-Encoder Reranker** (optional: accurate, ~80ms for 100 pairs)
|
|
||||||
- Neural reranking using `cross-encoder/ms-marco-MiniLM-L-6-v2`
|
|
||||||
- Takes query + document pairs, returns relevance scores
|
|
||||||
- Includes formatted dates: `[Date: November 06, 2025 (2025-11-06)] {text}`
|
|
||||||
- Scores normalized via sigmoid to [0, 1] range
|
|
||||||
- **When to use**: Accuracy-critical queries (user-facing search)
|
|
||||||
- **Advantage**: 5-10% better precision than heuristic
|
|
||||||
- Model loaded once at init (cached for performance)
|
|
||||||
- Pluggable: abstract `CrossEncoderReranker` interface for future API-based rerankers
|
|
||||||
|
|
||||||
#### Stage 4: MMR Diversification
|
|
||||||
|
|
||||||
Applies Maximal Marginal Relevance (λ=0.5) to final results:
|
|
||||||
```
|
|
||||||
MMR = λ × relevance - (1-λ) × max_similarity_to_selected
|
|
||||||
```
|
|
||||||
- Balances relevance with diversity
|
|
||||||
- Prevents redundant results about the same fact
|
|
||||||
- Iteratively selects results that are relevant BUT different
|
|
||||||
|
|
||||||
**Final Pipeline Summary**:
|
|
||||||
```
|
|
||||||
Query → [Semantic, Keyword, Graph, Temporal Graph] → RRF Merge → Reranker → MMR → Top-K Results
|
|
||||||
(4-way parallel, 30-50ms) (0-80ms) (0ms)
|
|
||||||
```
|
|
||||||
|
|
||||||
This architecture ensures:
|
|
||||||
- **High Recall**: 4 retrieval methods cast a wide net (union of all relevant memories)
|
|
||||||
- **High Precision**: Reranking and MMR refine to most relevant, diverse results
|
|
||||||
- **Flexibility**: Choose heuristic (fast) or cross-encoder (accurate) based on use case
|
|
||||||
- **Temporal Awareness**: Automatically activates time-scoped search when needed
|
|
||||||
|
|
||||||
### LLM-Based Fact Extraction
|
|
||||||
|
|
||||||
Raw content is processed through an LLM (Groq by default) to extract meaningful facts:
|
|
||||||
|
|
||||||
- Filters out noise (greetings, filler words)
|
|
||||||
- Extracts only substantive facts (biographical, events, opinions, recommendations)
|
|
||||||
- Creates self-contained statements with subject+action+context
|
|
||||||
- Resolves pronouns to actual referents
|
|
||||||
- Automatic chunking for large documents (>120k chars)
|
|
||||||
- Structured output using Pydantic models
|
|
||||||
- Retry logic for JSON validation failures
|
|
||||||
|
|
||||||
### Technology Stack
|
|
||||||
|
|
||||||
**Database**:
|
|
||||||
- PostgreSQL 15+ with `pgvector` and `uuid-ossp` extensions
|
|
||||||
|
|
||||||
**Python Libraries**:
|
|
||||||
- `asyncpg` - Async PostgreSQL client with connection pooling
|
|
||||||
- `sentence-transformers` - Embedding model (BAAI/bge-small-en-v1.5) + cross-encoder (ms-marco-MiniLM-L-6-v2)
|
|
||||||
- `openai` - LLM API client (supports Groq, OpenAI)
|
|
||||||
- `dateparser` - Natural language date parsing for temporal queries
|
|
||||||
- `fastapi` - Web API framework
|
|
||||||
|
|
||||||
**Architecture Patterns**:
|
|
||||||
- Mixin pattern for code organization
|
|
||||||
- Connection pooling with backpressure (32 concurrent searches max)
|
|
||||||
- Background task management for opinion storage
|
|
||||||
- Cached LLM client for performance
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
|
@ -306,10 +148,56 @@ The server will start at http://localhost:8080
|
||||||
- `POST /api/think` - Think and generate contextual answers
|
- `POST /api/think` - Think and generate contextual answers
|
||||||
- `GET /api/graph` - Get graph data for visualization
|
- `GET /api/graph` - Get graph data for visualization
|
||||||
- `GET /api/agents` - List all agents
|
- `GET /api/agents` - List all agents
|
||||||
|
- `PUT /api/agents/{agent_id}` - Create/update agent with personality
|
||||||
|
- `GET /api/agents/{agent_id}/profile` - Get agent profile
|
||||||
|
- `PUT /api/agents/{agent_id}/profile` - Update personality traits
|
||||||
|
- `POST /api/agents/{agent_id}/background` - Merge agent background
|
||||||
|
|
||||||
## API Examples (curl)
|
## API Examples (curl)
|
||||||
|
|
||||||
### Store Memories (PUT)
|
### Create/Update Agent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create or update an agent with personality and background
|
||||||
|
curl -X PUT http://localhost:8080/api/agents/alice_agent \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"personality": {
|
||||||
|
"openness": 0.8,
|
||||||
|
"conscientiousness": 0.6,
|
||||||
|
"extraversion": 0.5,
|
||||||
|
"agreeableness": 0.7,
|
||||||
|
"neuroticism": 0.3,
|
||||||
|
"bias_strength": 0.7
|
||||||
|
},
|
||||||
|
"background": "I am a creative software engineer with 10 years of startup experience"
|
||||||
|
}'
|
||||||
|
|
||||||
|
# Create agent with just background (personality defaults to 0.5 for all traits)
|
||||||
|
curl -X PUT http://localhost:8080/api/agents/bob_agent \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"background": "I am a data scientist interested in machine learning"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"agent_id": "alice_agent",
|
||||||
|
"personality": {
|
||||||
|
"openness": 0.8,
|
||||||
|
"conscientiousness": 0.6,
|
||||||
|
"extraversion": 0.5,
|
||||||
|
"agreeableness": 0.7,
|
||||||
|
"neuroticism": 0.3,
|
||||||
|
"bias_strength": 0.7
|
||||||
|
},
|
||||||
|
"background": "I am a creative software engineer with 10 years of startup experience"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Store Memories
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Store memories for an agent
|
# Store memories for an agent
|
||||||
|
|
@ -454,6 +342,58 @@ Response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CLI Usage
|
||||||
|
|
||||||
|
The Memora CLI provides command-line access to memory operations and agent management:
|
||||||
|
|
||||||
|
**Memory Operations**:
|
||||||
|
```bash
|
||||||
|
# Store a memory
|
||||||
|
memora put <agent_id> "Alice works at Google"
|
||||||
|
|
||||||
|
# Search memories
|
||||||
|
memora search <agent_id> "What does Alice do?" --budget 100
|
||||||
|
|
||||||
|
# Think (reasoning with opinions)
|
||||||
|
memora think <agent_id> "What do you think about remote work?" -v
|
||||||
|
```
|
||||||
|
|
||||||
|
**Agent Management**:
|
||||||
|
```bash
|
||||||
|
# View agent profile
|
||||||
|
memora profile <agent_id>
|
||||||
|
|
||||||
|
# Update personality traits (all required)
|
||||||
|
memora set-personality <agent_id> \
|
||||||
|
--openness 0.8 \
|
||||||
|
--conscientiousness 0.6 \
|
||||||
|
--extraversion 0.5 \
|
||||||
|
--agreeableness 0.7 \
|
||||||
|
--neuroticism 0.3 \
|
||||||
|
--bias-strength 0.7
|
||||||
|
|
||||||
|
# Add/merge background
|
||||||
|
memora background <agent_id> "I was born in Texas"
|
||||||
|
|
||||||
|
# List all agents
|
||||||
|
memora agents
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output Formats**:
|
||||||
|
```bash
|
||||||
|
# Pretty output (default)
|
||||||
|
memora search <agent_id> "query"
|
||||||
|
|
||||||
|
# JSON output
|
||||||
|
memora search <agent_id> "query" -o json
|
||||||
|
|
||||||
|
# YAML output
|
||||||
|
memora search <agent_id> "query" -o yaml
|
||||||
|
|
||||||
|
# Verbose mode (show requests/responses)
|
||||||
|
memora search <agent_id> "query" -v
|
||||||
|
```
|
||||||
|
|
||||||
## Running Benchmarks
|
## Running Benchmarks
|
||||||
|
|
||||||
The system includes two benchmarks for evaluating memory retrieval quality:
|
The system includes two benchmarks for evaluating memory retrieval quality:
|
||||||
|
|
|
||||||
41
RELEASE.md
Normal file
41
RELEASE.md
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Release Guide
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
### 1. Generate OpenAPI Spec
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv sync
|
||||||
|
cd memora-dev
|
||||||
|
uv run generate-openapi
|
||||||
|
cd ..
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Generate API Clients
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/generate-clients.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This regenerates Python and TypeScript clients from `openapi.json`.
|
||||||
|
|
||||||
|
|
||||||
|
### 3. Commit Everything
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add openapi.json memora-clients/
|
||||||
|
git commit -m "Update OpenAPI spec and regenerate clients"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Run Release Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/release.sh 0.0.6
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Update versions in all core components
|
||||||
|
- Commit changes
|
||||||
|
- Create and push tag `v0.0.6`
|
||||||
|
- Trigger GitHub Actions (builds Python package, Rust CLI, Docker images, Helm chart)
|
||||||
|
|
||||||
|
|
@ -52,6 +52,8 @@ pub struct ThinkRequest {
|
||||||
pub query: String,
|
pub query: String,
|
||||||
pub agent_id: String,
|
pub agent_id: String,
|
||||||
pub thinking_budget: i32,
|
pub thinking_budget: i32,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub context: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
@ -98,6 +100,40 @@ pub struct Agent {
|
||||||
pub agent_id: String,
|
pub agent_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct PersonalityTraits {
|
||||||
|
pub openness: f32,
|
||||||
|
pub conscientiousness: f32,
|
||||||
|
pub extraversion: f32,
|
||||||
|
pub agreeableness: f32,
|
||||||
|
pub neuroticism: f32,
|
||||||
|
pub bias_strength: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct AgentProfile {
|
||||||
|
pub agent_id: String,
|
||||||
|
pub personality: PersonalityTraits,
|
||||||
|
pub background: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct UpdatePersonalityRequest {
|
||||||
|
pub personality: PersonalityTraits,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct AddBackgroundRequest {
|
||||||
|
pub content: String,
|
||||||
|
pub update_personality: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct BackgroundResponse {
|
||||||
|
pub background: String,
|
||||||
|
pub personality: Option<PersonalityTraits>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ApiClient {
|
pub struct ApiClient {
|
||||||
client: Client,
|
client: Client,
|
||||||
base_url: String,
|
base_url: String,
|
||||||
|
|
@ -276,4 +312,140 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_profile(&self, agent_id: &str, verbose: bool) -> Result<AgentProfile> {
|
||||||
|
let url = format!("{}/api/agents/{}/profile", self.base_url, agent_id);
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Request URL: {}", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.get(&url)
|
||||||
|
.timeout(Duration::from_secs(30))
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
let status = response.status();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response status: {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !status.is_success() {
|
||||||
|
let error_body = response.text().unwrap_or_default();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Error response body:\n{}", error_body);
|
||||||
|
}
|
||||||
|
anyhow::bail!("API returned error status {}: {}", status, error_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response_text = response.text()?;
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response body:\n{}", response_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: AgentProfile = serde_json::from_str(&response_text)
|
||||||
|
.with_context(|| format!("Failed to parse API response. Response was: {}", response_text))?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_personality(
|
||||||
|
&self,
|
||||||
|
agent_id: &str,
|
||||||
|
openness: f32,
|
||||||
|
conscientiousness: f32,
|
||||||
|
extraversion: f32,
|
||||||
|
agreeableness: f32,
|
||||||
|
neuroticism: f32,
|
||||||
|
bias_strength: f32,
|
||||||
|
verbose: bool,
|
||||||
|
) -> Result<AgentProfile> {
|
||||||
|
let url = format!("{}/api/agents/{}/profile", self.base_url, agent_id);
|
||||||
|
let request = UpdatePersonalityRequest {
|
||||||
|
personality: PersonalityTraits {
|
||||||
|
openness,
|
||||||
|
conscientiousness,
|
||||||
|
extraversion,
|
||||||
|
agreeableness,
|
||||||
|
neuroticism,
|
||||||
|
bias_strength,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Request URL: {}", url);
|
||||||
|
eprintln!("Request body:\n{}", serde_json::to_string_pretty(&request).unwrap_or_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.put(&url)
|
||||||
|
.json(&request)
|
||||||
|
.timeout(Duration::from_secs(30))
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
let status = response.status();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response status: {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !status.is_success() {
|
||||||
|
let error_body = response.text().unwrap_or_default();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Error response body:\n{}", error_body);
|
||||||
|
}
|
||||||
|
anyhow::bail!("API returned error status {}: {}", status, error_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response_text = response.text()?;
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response body:\n{}", response_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: AgentProfile = serde_json::from_str(&response_text)
|
||||||
|
.with_context(|| format!("Failed to parse API response. Response was: {}", response_text))?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_background(&self, agent_id: &str, content: &str, update_personality: bool, verbose: bool) -> Result<BackgroundResponse> {
|
||||||
|
let url = format!("{}/api/agents/{}/background", self.base_url, agent_id);
|
||||||
|
let request = AddBackgroundRequest {
|
||||||
|
content: content.to_string(),
|
||||||
|
update_personality,
|
||||||
|
};
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Request URL: {}", url);
|
||||||
|
eprintln!("Request body:\n{}", serde_json::to_string_pretty(&request).unwrap_or_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.post(&url)
|
||||||
|
.json(&request)
|
||||||
|
.timeout(Duration::from_secs(60))
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
let status = response.status();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response status: {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !status.is_success() {
|
||||||
|
let error_body = response.text().unwrap_or_default();
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Error response body:\n{}", error_body);
|
||||||
|
}
|
||||||
|
anyhow::bail!("API returned error status {}: {}", status, error_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
let response_text = response.text()?;
|
||||||
|
if verbose {
|
||||||
|
eprintln!("Response body:\n{}", response_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: BackgroundResponse = serde_json::from_str(&response_text)
|
||||||
|
.with_context(|| format!("Failed to parse API response. Response was: {}", response_text))?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,10 @@ enum Commands {
|
||||||
/// Thinking budget
|
/// Thinking budget
|
||||||
#[arg(short = 'b', long, default_value = "50")]
|
#[arg(short = 'b', long, default_value = "50")]
|
||||||
budget: i32,
|
budget: i32,
|
||||||
|
|
||||||
|
/// Additional context for the query (not used in search)
|
||||||
|
#[arg(short = 'c', long)]
|
||||||
|
context: Option<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Store a single memory
|
/// Store a single memory
|
||||||
|
|
@ -127,6 +131,55 @@ enum Commands {
|
||||||
|
|
||||||
/// List all agents
|
/// List all agents
|
||||||
Agents,
|
Agents,
|
||||||
|
|
||||||
|
/// Get agent profile (personality + background)
|
||||||
|
Profile {
|
||||||
|
/// Agent ID to get profile for
|
||||||
|
agent_id: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Update agent personality traits
|
||||||
|
SetPersonality {
|
||||||
|
/// Agent ID to update
|
||||||
|
agent_id: String,
|
||||||
|
|
||||||
|
/// Openness to experience (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
openness: f32,
|
||||||
|
|
||||||
|
/// Conscientiousness (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
conscientiousness: f32,
|
||||||
|
|
||||||
|
/// Extraversion (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
extraversion: f32,
|
||||||
|
|
||||||
|
/// Agreeableness (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
agreeableness: f32,
|
||||||
|
|
||||||
|
/// Neuroticism (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
neuroticism: f32,
|
||||||
|
|
||||||
|
/// Bias strength - how much personality influences opinions (0.0-1.0)
|
||||||
|
#[arg(long)]
|
||||||
|
bias_strength: f32,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Add or merge background information for an agent
|
||||||
|
Background {
|
||||||
|
/// Agent ID to add background for
|
||||||
|
agent_id: String,
|
||||||
|
|
||||||
|
/// Background information to add (will be merged with existing)
|
||||||
|
content: String,
|
||||||
|
|
||||||
|
/// Skip automatic personality inference from background (default: false, traits are inferred)
|
||||||
|
#[arg(long)]
|
||||||
|
no_update_personality: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -203,6 +256,7 @@ fn run() -> Result<()> {
|
||||||
agent_id,
|
agent_id,
|
||||||
query,
|
query,
|
||||||
budget,
|
budget,
|
||||||
|
context,
|
||||||
} => {
|
} => {
|
||||||
let spinner = if output_format == OutputFormat::Pretty {
|
let spinner = if output_format == OutputFormat::Pretty {
|
||||||
Some(ui::create_spinner("Thinking..."))
|
Some(ui::create_spinner("Thinking..."))
|
||||||
|
|
@ -214,6 +268,7 @@ fn run() -> Result<()> {
|
||||||
query,
|
query,
|
||||||
agent_id,
|
agent_id,
|
||||||
thinking_budget: budget,
|
thinking_budget: budget,
|
||||||
|
context,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = client.think(request, verbose);
|
let response = client.think(request, verbose);
|
||||||
|
|
@ -428,6 +483,145 @@ fn run() -> Result<()> {
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Commands::Profile { agent_id } => {
|
||||||
|
let spinner = if output_format == OutputFormat::Pretty {
|
||||||
|
Some(ui::create_spinner("Fetching profile..."))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = client.get_profile(&agent_id, verbose);
|
||||||
|
|
||||||
|
if let Some(sp) = spinner {
|
||||||
|
sp.finish_and_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(profile) => {
|
||||||
|
if output_format == OutputFormat::Pretty {
|
||||||
|
ui::print_profile(&profile);
|
||||||
|
} else {
|
||||||
|
output::print_output(&profile, output_format)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Commands::SetPersonality {
|
||||||
|
agent_id,
|
||||||
|
openness,
|
||||||
|
conscientiousness,
|
||||||
|
extraversion,
|
||||||
|
agreeableness,
|
||||||
|
neuroticism,
|
||||||
|
bias_strength,
|
||||||
|
} => {
|
||||||
|
// Validate all values are between 0 and 1
|
||||||
|
let values = vec![
|
||||||
|
("openness", openness),
|
||||||
|
("conscientiousness", conscientiousness),
|
||||||
|
("extraversion", extraversion),
|
||||||
|
("agreeableness", agreeableness),
|
||||||
|
("neuroticism", neuroticism),
|
||||||
|
("bias_strength", bias_strength),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (name, value) in &values {
|
||||||
|
if *value < 0.0 || *value > 1.0 {
|
||||||
|
anyhow::bail!("{} must be between 0.0 and 1.0, got {}", name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let spinner = if output_format == OutputFormat::Pretty {
|
||||||
|
Some(ui::create_spinner("Updating personality..."))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = client.update_personality(
|
||||||
|
&agent_id,
|
||||||
|
openness,
|
||||||
|
conscientiousness,
|
||||||
|
extraversion,
|
||||||
|
agreeableness,
|
||||||
|
neuroticism,
|
||||||
|
bias_strength,
|
||||||
|
verbose,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(sp) = spinner {
|
||||||
|
sp.finish_and_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(profile) => {
|
||||||
|
if output_format == OutputFormat::Pretty {
|
||||||
|
ui::print_success("Personality updated successfully");
|
||||||
|
ui::print_profile(&profile);
|
||||||
|
} else {
|
||||||
|
output::print_output(&profile, output_format)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Commands::Background { agent_id, content, no_update_personality } => {
|
||||||
|
let update_personality = !no_update_personality;
|
||||||
|
|
||||||
|
// Fetch current profile to show delta
|
||||||
|
let old_profile = if update_personality && output_format == OutputFormat::Pretty {
|
||||||
|
client.get_profile(&agent_id, verbose).ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let spinner = if output_format == OutputFormat::Pretty {
|
||||||
|
Some(ui::create_spinner("Merging background..."))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = client.add_background(&agent_id, &content, update_personality, verbose);
|
||||||
|
|
||||||
|
if let Some(sp) = spinner {
|
||||||
|
sp.finish_and_clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(background_resp) => {
|
||||||
|
if output_format == OutputFormat::Pretty {
|
||||||
|
ui::print_success("Background updated successfully");
|
||||||
|
ui::print_info(&format!("New background:\n{}", background_resp.background));
|
||||||
|
|
||||||
|
// Show inferred personality changes with delta
|
||||||
|
if let Some(new_personality) = background_resp.personality {
|
||||||
|
if let Some(old_prof) = old_profile {
|
||||||
|
// Show delta visualization
|
||||||
|
ui::print_personality_delta(&old_prof.personality, &new_personality);
|
||||||
|
} else {
|
||||||
|
// Fallback to simple display if we don't have old profile
|
||||||
|
ui::print_info("\nInferred personality traits:");
|
||||||
|
println!(" Openness: {:.2}", new_personality.openness);
|
||||||
|
println!(" Conscientiousness: {:.2}", new_personality.conscientiousness);
|
||||||
|
println!(" Extraversion: {:.2}", new_personality.extraversion);
|
||||||
|
println!(" Agreeableness: {:.2}", new_personality.agreeableness);
|
||||||
|
println!(" Neuroticism: {:.2}", new_personality.neuroticism);
|
||||||
|
println!(" Bias Strength: {:.2}", new_personality.bias_strength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
output::print_output(&background_resp, output_format)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle API errors with nice messages
|
// Handle API errors with nice messages
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::api::{Agent, Fact, SearchResponse, ThinkResponse, TraceInfo};
|
use crate::api::{Agent, AgentProfile, Fact, PersonalityTraits, SearchResponse, ThinkResponse, TraceInfo};
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
@ -215,3 +215,159 @@ pub fn prompt_confirmation(message: &str) -> io::Result<bool> {
|
||||||
|
|
||||||
Ok(input.trim().eq_ignore_ascii_case("y") || input.trim().eq_ignore_ascii_case("yes"))
|
Ok(input.trim().eq_ignore_ascii_case("y") || input.trim().eq_ignore_ascii_case("yes"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_profile(profile: &AgentProfile) {
|
||||||
|
print_section_header(&format!("Agent Profile: {}", profile.agent_id));
|
||||||
|
|
||||||
|
// Print personality traits
|
||||||
|
println!(" {}", "Personality Traits (Big Five):".bright_cyan().bold());
|
||||||
|
println!();
|
||||||
|
|
||||||
|
let traits = [
|
||||||
|
("Openness", profile.personality.openness, "🔓"),
|
||||||
|
("Conscientiousness", profile.personality.conscientiousness, "📋"),
|
||||||
|
("Extraversion", profile.personality.extraversion, "🗣️"),
|
||||||
|
("Agreeableness", profile.personality.agreeableness, "🤝"),
|
||||||
|
("Neuroticism", profile.personality.neuroticism, "😰"),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (name, value, emoji) in &traits {
|
||||||
|
let bar_length = 20;
|
||||||
|
let filled = (*value * bar_length as f32) as usize;
|
||||||
|
let empty = bar_length - filled;
|
||||||
|
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
||||||
|
|
||||||
|
let value_color = if *value >= 0.7 {
|
||||||
|
bar.bright_green()
|
||||||
|
} else if *value >= 0.4 {
|
||||||
|
bar.bright_yellow()
|
||||||
|
} else {
|
||||||
|
bar.bright_red()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(" {} {:<20} [{}] {:.0}%",
|
||||||
|
emoji,
|
||||||
|
name,
|
||||||
|
value_color,
|
||||||
|
value * 100.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!(" {}", "Bias Strength:".bright_cyan().bold());
|
||||||
|
let bias = profile.personality.bias_strength;
|
||||||
|
let bar_length = 20;
|
||||||
|
let filled = (bias * bar_length as f32) as usize;
|
||||||
|
let empty = bar_length - filled;
|
||||||
|
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
||||||
|
|
||||||
|
let bias_color = if bias >= 0.7 {
|
||||||
|
bar.bright_green()
|
||||||
|
} else if bias >= 0.4 {
|
||||||
|
bar.bright_yellow()
|
||||||
|
} else {
|
||||||
|
bar.bright_red()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(" 💪 {:<20} [{}] {:.0}%",
|
||||||
|
"Personality Influence",
|
||||||
|
bias_color,
|
||||||
|
bias * 100.0
|
||||||
|
);
|
||||||
|
println!(" {}", format!("(How much personality shapes opinions)").bright_black());
|
||||||
|
println!();
|
||||||
|
|
||||||
|
// Print background
|
||||||
|
if !profile.background.is_empty() {
|
||||||
|
println!(" {}", "Background:".bright_cyan().bold());
|
||||||
|
println!();
|
||||||
|
for line in profile.background.lines() {
|
||||||
|
println!(" {}", line);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
} else {
|
||||||
|
println!(" {}", "Background: (none)".bright_black());
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_personality_delta(old: &PersonalityTraits, new: &PersonalityTraits) {
|
||||||
|
print_section_header("Personality Changes");
|
||||||
|
|
||||||
|
let traits = [
|
||||||
|
("Openness", old.openness, new.openness, "🔓"),
|
||||||
|
("Conscientiousness", old.conscientiousness, new.conscientiousness, "📋"),
|
||||||
|
("Extraversion", old.extraversion, new.extraversion, "🗣️"),
|
||||||
|
("Agreeableness", old.agreeableness, new.agreeableness, "🤝"),
|
||||||
|
("Neuroticism", old.neuroticism, new.neuroticism, "😰"),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (name, old_value, new_value, emoji) in &traits {
|
||||||
|
let bar_length = 20;
|
||||||
|
let filled = (*new_value * bar_length as f32) as usize;
|
||||||
|
let empty = bar_length - filled;
|
||||||
|
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
||||||
|
|
||||||
|
let value_color = if *new_value >= 0.7 {
|
||||||
|
bar.bright_green()
|
||||||
|
} else if *new_value >= 0.4 {
|
||||||
|
bar.bright_yellow()
|
||||||
|
} else {
|
||||||
|
bar.bright_red()
|
||||||
|
};
|
||||||
|
|
||||||
|
let delta = new_value - old_value;
|
||||||
|
let delta_pct = (delta * 100.0).abs();
|
||||||
|
let delta_str = if delta.abs() < 0.01 {
|
||||||
|
"".to_string()
|
||||||
|
} else if delta > 0.0 {
|
||||||
|
format!(" {} {:.0}%", "↗".bright_green(), delta_pct)
|
||||||
|
} else {
|
||||||
|
format!(" {} {:.0}%", "↘".bright_red(), delta_pct)
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(" {} {:<20} [{}] {:.0}%{}",
|
||||||
|
emoji,
|
||||||
|
name,
|
||||||
|
value_color,
|
||||||
|
new_value * 100.0,
|
||||||
|
delta_str
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
println!(" {}", "Bias Strength:".bright_cyan().bold());
|
||||||
|
let old_bias = old.bias_strength;
|
||||||
|
let new_bias = new.bias_strength;
|
||||||
|
let bar_length = 20;
|
||||||
|
let filled = (new_bias * bar_length as f32) as usize;
|
||||||
|
let empty = bar_length - filled;
|
||||||
|
let bar = format!("{}{}", "█".repeat(filled), "░".repeat(empty));
|
||||||
|
|
||||||
|
let bias_color = if new_bias >= 0.7 {
|
||||||
|
bar.bright_green()
|
||||||
|
} else if new_bias >= 0.4 {
|
||||||
|
bar.bright_yellow()
|
||||||
|
} else {
|
||||||
|
bar.bright_red()
|
||||||
|
};
|
||||||
|
|
||||||
|
let delta = new_bias - old_bias;
|
||||||
|
let delta_pct = (delta * 100.0).abs();
|
||||||
|
let delta_str = if delta.abs() < 0.01 {
|
||||||
|
"".to_string()
|
||||||
|
} else if delta > 0.0 {
|
||||||
|
format!(" {} {:.0}%", "↗".bright_green(), delta_pct)
|
||||||
|
} else {
|
||||||
|
format!(" {} {:.0}%", "↘".bright_red(), delta_pct)
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(" 💪 {:<20} [{}] {:.0}%{}",
|
||||||
|
"Personality Influence",
|
||||||
|
bias_color,
|
||||||
|
new_bias * 100.0,
|
||||||
|
delta_str
|
||||||
|
);
|
||||||
|
println!(" {}", format!("(How much personality shapes opinions)").bright_black());
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
|
||||||
15
memora-clients/.gitignore
vendored
Normal file
15
memora-clients/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Build artifacts
|
||||||
|
python/dist/
|
||||||
|
python/build/
|
||||||
|
python/*.egg-info/
|
||||||
|
python/.ruff_cache/
|
||||||
|
typescript/dist/
|
||||||
|
typescript/node_modules/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# Generated code is tracked in git to see API changes
|
||||||
23
memora-clients/python/.gitignore
vendored
Normal file
23
memora-clients/python/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
__pycache__/
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# JetBrains
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
/coverage.xml
|
||||||
|
/.coverage
|
||||||
79
memora-clients/python/README.md
Normal file
79
memora-clients/python/README.md
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
# memora-client
|
||||||
|
|
||||||
|
Python client for Memora - Semantic memory system with personality-driven thinking.
|
||||||
|
|
||||||
|
**Auto-generated from OpenAPI spec** - provides type-safe access to all Memora API endpoints.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install memora-client
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```python
|
||||||
|
from agent_memory_api_client import Client
|
||||||
|
from agent_memory_api_client.api.memory_storage import put_api_put_post
|
||||||
|
from agent_memory_api_client.api.reasoning import think_api_think_post
|
||||||
|
|
||||||
|
client = Client(base_url="http://localhost:8000")
|
||||||
|
|
||||||
|
# Store memory
|
||||||
|
put_api_put_post.sync(
|
||||||
|
client=client,
|
||||||
|
body={
|
||||||
|
"agent_id": "user123",
|
||||||
|
"content": "Alice loves machine learning"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Think (generate answer with personality)
|
||||||
|
response = think_api_think_post.sync(
|
||||||
|
client=client,
|
||||||
|
body={
|
||||||
|
"agent_id": "user123",
|
||||||
|
"query": "What does Alice think about AI?",
|
||||||
|
"thinking_budget": 50
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print(response.text)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Async Support
|
||||||
|
|
||||||
|
```python
|
||||||
|
from agent_memory_api_client import Client
|
||||||
|
from agent_memory_api_client.api.reasoning import think_api_think_post
|
||||||
|
|
||||||
|
async with Client(base_url="http://localhost:8000") as client:
|
||||||
|
response = await think_api_think_post.asyncio(
|
||||||
|
client=client,
|
||||||
|
body={
|
||||||
|
"agent_id": "user123",
|
||||||
|
"query": "What does Alice think about AI?"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print(response.text)
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Modules
|
||||||
|
|
||||||
|
This client provides access to:
|
||||||
|
- `memory_storage` - Store and retrieve facts
|
||||||
|
- `search` - Semantic and temporal search
|
||||||
|
- `reasoning` - Personality-driven thinking
|
||||||
|
- `visualization` - Memory graphs and statistics
|
||||||
|
- `management` - Agent profiles and configuration
|
||||||
|
- `documents` - Document tracking
|
||||||
|
|
||||||
|
See auto-generated code for full API surface and type hints.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Auto-generated from `openapi.json`. See [RELEASE.md](../../RELEASE.md) for regeneration instructions.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [GitHub Repository](https://github.com/nicoloboschi/memora)
|
||||||
|
- [Full Documentation](https://github.com/nicoloboschi/memora/blob/main/README.md)
|
||||||
8
memora-clients/python/__init__.py
Normal file
8
memora-clients/python/__init__.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
"""A client library for accessing Agent Memory API"""
|
||||||
|
|
||||||
|
from .client import AuthenticatedClient, Client
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
"AuthenticatedClient",
|
||||||
|
"Client",
|
||||||
|
)
|
||||||
1
memora-clients/python/api/__init__.py
Normal file
1
memora-clients/python/api/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains methods for accessing the API"""
|
||||||
1
memora-clients/python/api/agent_profile/__init__.py
Normal file
1
memora-clients/python/api/agent_profile/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.add_background_request import AddBackgroundRequest
|
||||||
|
from ...models.background_response import BackgroundResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
body: AddBackgroundRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "post",
|
||||||
|
"url": f"/api/agents/{agent_id}/background",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> BackgroundResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = BackgroundResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[BackgroundResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: AddBackgroundRequest,
|
||||||
|
) -> Response[BackgroundResponse | HTTPValidationError]:
|
||||||
|
"""Add/merge agent background
|
||||||
|
|
||||||
|
Add new background information or merge with existing. LLM intelligently resolves conflicts,
|
||||||
|
normalizes to first person, and optionally infers personality traits.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (AddBackgroundRequest): Request model for adding/merging background information.
|
||||||
|
Example: {'content': 'I was born in Texas', 'update_personality': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BackgroundResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: AddBackgroundRequest,
|
||||||
|
) -> BackgroundResponse | HTTPValidationError | None:
|
||||||
|
"""Add/merge agent background
|
||||||
|
|
||||||
|
Add new background information or merge with existing. LLM intelligently resolves conflicts,
|
||||||
|
normalizes to first person, and optionally infers personality traits.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (AddBackgroundRequest): Request model for adding/merging background information.
|
||||||
|
Example: {'content': 'I was born in Texas', 'update_personality': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BackgroundResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: AddBackgroundRequest,
|
||||||
|
) -> Response[BackgroundResponse | HTTPValidationError]:
|
||||||
|
"""Add/merge agent background
|
||||||
|
|
||||||
|
Add new background information or merge with existing. LLM intelligently resolves conflicts,
|
||||||
|
normalizes to first person, and optionally infers personality traits.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (AddBackgroundRequest): Request model for adding/merging background information.
|
||||||
|
Example: {'content': 'I was born in Texas', 'update_personality': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BackgroundResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: AddBackgroundRequest,
|
||||||
|
) -> BackgroundResponse | HTTPValidationError | None:
|
||||||
|
"""Add/merge agent background
|
||||||
|
|
||||||
|
Add new background information or merge with existing. LLM intelligently resolves conflicts,
|
||||||
|
normalizes to first person, and optionally infers personality traits.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (AddBackgroundRequest): Request model for adding/merging background information.
|
||||||
|
Example: {'content': 'I was born in Texas', 'update_personality': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BackgroundResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.agent_profile_response import AgentProfileResponse
|
||||||
|
from ...models.create_agent_request import CreateAgentRequest
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
body: CreateAgentRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "put",
|
||||||
|
"url": f"/api/agents/{agent_id}",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = AgentProfileResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: CreateAgentRequest,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Create or update agent
|
||||||
|
|
||||||
|
Create a new agent or update existing agent with personality and background. Auto-fills missing
|
||||||
|
fields with defaults.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (CreateAgentRequest): Request model for creating/updating an agent. Example:
|
||||||
|
{'background': 'I am a creative software engineer with 10 years of experience',
|
||||||
|
'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6,
|
||||||
|
'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: CreateAgentRequest,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Create or update agent
|
||||||
|
|
||||||
|
Create a new agent or update existing agent with personality and background. Auto-fills missing
|
||||||
|
fields with defaults.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (CreateAgentRequest): Request model for creating/updating an agent. Example:
|
||||||
|
{'background': 'I am a creative software engineer with 10 years of experience',
|
||||||
|
'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6,
|
||||||
|
'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: CreateAgentRequest,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Create or update agent
|
||||||
|
|
||||||
|
Create a new agent or update existing agent with personality and background. Auto-fills missing
|
||||||
|
fields with defaults.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (CreateAgentRequest): Request model for creating/updating an agent. Example:
|
||||||
|
{'background': 'I am a creative software engineer with 10 years of experience',
|
||||||
|
'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6,
|
||||||
|
'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: CreateAgentRequest,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Create or update agent
|
||||||
|
|
||||||
|
Create a new agent or update existing agent with personality and background. Auto-fills missing
|
||||||
|
fields with defaults.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (CreateAgentRequest): Request model for creating/updating an agent. Example:
|
||||||
|
{'background': 'I am a creative software engineer with 10 years of experience',
|
||||||
|
'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6,
|
||||||
|
'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.agent_profile_response import AgentProfileResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": f"/api/agents/{agent_id}/profile",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = AgentProfileResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Get agent profile
|
||||||
|
|
||||||
|
Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Get agent profile
|
||||||
|
|
||||||
|
Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Get agent profile
|
||||||
|
|
||||||
|
Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Get agent profile
|
||||||
|
|
||||||
|
Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.agent_list_response import AgentListResponse
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs() -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": "/api/agents",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> AgentListResponse | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = AgentListResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[AgentListResponse]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[AgentListResponse]:
|
||||||
|
"""List all agents
|
||||||
|
|
||||||
|
Get a list of all agents with their profiles
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentListResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs()
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> AgentListResponse | None:
|
||||||
|
"""List all agents
|
||||||
|
|
||||||
|
Get a list of all agents with their profiles
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentListResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[AgentListResponse]:
|
||||||
|
"""List all agents
|
||||||
|
|
||||||
|
Get a list of all agents with their profiles
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentListResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs()
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> AgentListResponse | None:
|
||||||
|
"""List all agents
|
||||||
|
|
||||||
|
Get a list of all agents with their profiles
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentListResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.agent_profile_response import AgentProfileResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...models.update_personality_request import UpdatePersonalityRequest
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
body: UpdatePersonalityRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "put",
|
||||||
|
"url": f"/api/agents/{agent_id}/profile",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = AgentProfileResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: UpdatePersonalityRequest,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Update agent personality
|
||||||
|
|
||||||
|
Update agent's Big Five personality traits and bias strength
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (UpdatePersonalityRequest): Request model for updating personality traits.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: UpdatePersonalityRequest,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Update agent personality
|
||||||
|
|
||||||
|
Update agent's Big Five personality traits and bias strength
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (UpdatePersonalityRequest): Request model for updating personality traits.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: UpdatePersonalityRequest,
|
||||||
|
) -> Response[AgentProfileResponse | HTTPValidationError]:
|
||||||
|
"""Update agent personality
|
||||||
|
|
||||||
|
Update agent's Big Five personality traits and bias strength
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (UpdatePersonalityRequest): Request model for updating personality traits.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[AgentProfileResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: UpdatePersonalityRequest,
|
||||||
|
) -> AgentProfileResponse | HTTPValidationError | None:
|
||||||
|
"""Update agent personality
|
||||||
|
|
||||||
|
Update agent's Big Five personality traits and bias strength
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
body (UpdatePersonalityRequest): Request model for updating personality traits.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AgentProfileResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/documents/__init__.py
Normal file
1
memora-clients/python/api/documents/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.document_response import DocumentResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import UNSET, Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
document_id: str,
|
||||||
|
*,
|
||||||
|
agent_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
params: dict[str, Any] = {}
|
||||||
|
|
||||||
|
params["agent_id"] = agent_id
|
||||||
|
|
||||||
|
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": f"/api/documents/{document_id}",
|
||||||
|
"params": params,
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> DocumentResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = DocumentResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[DocumentResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
document_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
) -> Response[DocumentResponse | HTTPValidationError]:
|
||||||
|
"""Get document details
|
||||||
|
|
||||||
|
Get a specific document including its original text
|
||||||
|
|
||||||
|
Args:
|
||||||
|
document_id (str):
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[DocumentResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
document_id=document_id,
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
document_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
) -> DocumentResponse | HTTPValidationError | None:
|
||||||
|
"""Get document details
|
||||||
|
|
||||||
|
Get a specific document including its original text
|
||||||
|
|
||||||
|
Args:
|
||||||
|
document_id (str):
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DocumentResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
document_id=document_id,
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
document_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
) -> Response[DocumentResponse | HTTPValidationError]:
|
||||||
|
"""Get document details
|
||||||
|
|
||||||
|
Get a specific document including its original text
|
||||||
|
|
||||||
|
Args:
|
||||||
|
document_id (str):
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[DocumentResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
document_id=document_id,
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
document_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
) -> DocumentResponse | HTTPValidationError | None:
|
||||||
|
"""Get document details
|
||||||
|
|
||||||
|
Get a specific document including its original text
|
||||||
|
|
||||||
|
Args:
|
||||||
|
document_id (str):
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
DocumentResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
document_id=document_id,
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...models.list_documents_response import ListDocumentsResponse
|
||||||
|
from ...types import UNSET, Response, Unset
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
agent_id: str,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
params: dict[str, Any] = {}
|
||||||
|
|
||||||
|
params["agent_id"] = agent_id
|
||||||
|
|
||||||
|
json_q: None | str | Unset
|
||||||
|
if isinstance(q, Unset):
|
||||||
|
json_q = UNSET
|
||||||
|
else:
|
||||||
|
json_q = q
|
||||||
|
params["q"] = json_q
|
||||||
|
|
||||||
|
params["limit"] = limit
|
||||||
|
|
||||||
|
params["offset"] = offset
|
||||||
|
|
||||||
|
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": "/api/documents",
|
||||||
|
"params": params,
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> HTTPValidationError | ListDocumentsResponse | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = ListDocumentsResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[HTTPValidationError | ListDocumentsResponse]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> Response[HTTPValidationError | ListDocumentsResponse]:
|
||||||
|
"""List documents
|
||||||
|
|
||||||
|
List documents with pagination and optional search. Documents are the source content from which
|
||||||
|
memory units are extracted.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ListDocumentsResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> HTTPValidationError | ListDocumentsResponse | None:
|
||||||
|
"""List documents
|
||||||
|
|
||||||
|
List documents with pagination and optional search. Documents are the source content from which
|
||||||
|
memory units are extracted.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ListDocumentsResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> Response[HTTPValidationError | ListDocumentsResponse]:
|
||||||
|
"""List documents
|
||||||
|
|
||||||
|
List documents with pagination and optional search. Documents are the source content from which
|
||||||
|
memory units are extracted.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ListDocumentsResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: str,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> HTTPValidationError | ListDocumentsResponse | None:
|
||||||
|
"""List documents
|
||||||
|
|
||||||
|
List documents with pagination and optional search. Documents are the source content from which
|
||||||
|
memory units are extracted.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ListDocumentsResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/memory_statistics/__init__.py
Normal file
1
memora-clients/python/api/memory_statistics/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": f"/api/stats/{agent_id}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = response.json()
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Get memory statistics for an agent
|
||||||
|
|
||||||
|
Get statistics about nodes and links for a specific agent
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Get memory statistics for an agent
|
||||||
|
|
||||||
|
Get statistics about nodes and links for a specific agent
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Get memory statistics for an agent
|
||||||
|
|
||||||
|
Get statistics about nodes and links for a specific agent
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Get memory statistics for an agent
|
||||||
|
|
||||||
|
Get statistics about nodes and links for a specific agent
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/memory_storage/__init__.py
Normal file
1
memora-clients/python/api/memory_storage/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.batch_put_request import BatchPutRequest
|
||||||
|
from ...models.batch_put_response import BatchPutResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "post",
|
||||||
|
"url": "/api/memories/batch",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> BatchPutResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = BatchPutResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[BatchPutResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> Response[BatchPutResponse | HTTPValidationError]:
|
||||||
|
"""Store multiple memories
|
||||||
|
|
||||||
|
Store multiple memory items in batch with automatic fact extraction.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Extracts semantic facts from the content
|
||||||
|
2. Generates embeddings
|
||||||
|
3. Deduplicates similar facts
|
||||||
|
4. Creates temporal, semantic, and entity links
|
||||||
|
5. Tracks document metadata
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BatchPutResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> BatchPutResponse | HTTPValidationError | None:
|
||||||
|
"""Store multiple memories
|
||||||
|
|
||||||
|
Store multiple memory items in batch with automatic fact extraction.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Extracts semantic facts from the content
|
||||||
|
2. Generates embeddings
|
||||||
|
3. Deduplicates similar facts
|
||||||
|
4. Creates temporal, semantic, and entity links
|
||||||
|
5. Tracks document metadata
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BatchPutResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> Response[BatchPutResponse | HTTPValidationError]:
|
||||||
|
"""Store multiple memories
|
||||||
|
|
||||||
|
Store multiple memory items in batch with automatic fact extraction.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Extracts semantic facts from the content
|
||||||
|
2. Generates embeddings
|
||||||
|
3. Deduplicates similar facts
|
||||||
|
4. Creates temporal, semantic, and entity links
|
||||||
|
5. Tracks document metadata
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BatchPutResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> BatchPutResponse | HTTPValidationError | None:
|
||||||
|
"""Store multiple memories
|
||||||
|
|
||||||
|
Store multiple memory items in batch with automatic fact extraction.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Extracts semantic facts from the content
|
||||||
|
2. Generates embeddings
|
||||||
|
3. Deduplicates similar facts
|
||||||
|
4. Creates temporal, semantic, and entity links
|
||||||
|
5. Tracks document metadata
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BatchPutResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.batch_put_async_response import BatchPutAsyncResponse
|
||||||
|
from ...models.batch_put_request import BatchPutRequest
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "post",
|
||||||
|
"url": "/api/memories/batch_async",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> BatchPutAsyncResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = BatchPutAsyncResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[BatchPutAsyncResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> Response[BatchPutAsyncResponse | HTTPValidationError]:
|
||||||
|
"""Store multiple memories asynchronously
|
||||||
|
|
||||||
|
Store multiple memory items in batch asynchronously using the task backend.
|
||||||
|
|
||||||
|
This endpoint returns immediately after queuing the task, without waiting for completion.
|
||||||
|
The actual processing happens in the background.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Immediate response (non-blocking)
|
||||||
|
- Background processing via task queue
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Queues the batch put task
|
||||||
|
2. Returns immediately with success=True, queued=True
|
||||||
|
3. Processes in background: extracts facts, generates embeddings, creates links
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BatchPutAsyncResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> BatchPutAsyncResponse | HTTPValidationError | None:
|
||||||
|
"""Store multiple memories asynchronously
|
||||||
|
|
||||||
|
Store multiple memory items in batch asynchronously using the task backend.
|
||||||
|
|
||||||
|
This endpoint returns immediately after queuing the task, without waiting for completion.
|
||||||
|
The actual processing happens in the background.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Immediate response (non-blocking)
|
||||||
|
- Background processing via task queue
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Queues the batch put task
|
||||||
|
2. Returns immediately with success=True, queued=True
|
||||||
|
3. Processes in background: extracts facts, generates embeddings, creates links
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BatchPutAsyncResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> Response[BatchPutAsyncResponse | HTTPValidationError]:
|
||||||
|
"""Store multiple memories asynchronously
|
||||||
|
|
||||||
|
Store multiple memory items in batch asynchronously using the task backend.
|
||||||
|
|
||||||
|
This endpoint returns immediately after queuing the task, without waiting for completion.
|
||||||
|
The actual processing happens in the background.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Immediate response (non-blocking)
|
||||||
|
- Background processing via task queue
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Queues the batch put task
|
||||||
|
2. Returns immediately with success=True, queued=True
|
||||||
|
3. Processes in background: extracts facts, generates embeddings, creates links
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[BatchPutAsyncResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: BatchPutRequest,
|
||||||
|
) -> BatchPutAsyncResponse | HTTPValidationError | None:
|
||||||
|
"""Store multiple memories asynchronously
|
||||||
|
|
||||||
|
Store multiple memory items in batch asynchronously using the task backend.
|
||||||
|
|
||||||
|
This endpoint returns immediately after queuing the task, without waiting for completion.
|
||||||
|
The actual processing happens in the background.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Immediate response (non-blocking)
|
||||||
|
- Background processing via task queue
|
||||||
|
- Efficient batch processing
|
||||||
|
- Automatic fact extraction from natural language
|
||||||
|
- Entity recognition and linking
|
||||||
|
- Document tracking with automatic upsert (when document_id is provided)
|
||||||
|
- Temporal and semantic linking
|
||||||
|
|
||||||
|
The system automatically:
|
||||||
|
1. Queues the batch put task
|
||||||
|
2. Returns immediately with success=True, queued=True
|
||||||
|
3. Processes in background: extracts facts, generates embeddings, creates links
|
||||||
|
|
||||||
|
Note: If document_id is provided and already exists, the old document and its memory units will
|
||||||
|
be deleted before creating new ones (upsert behavior).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (BatchPutRequest): Request model for batch put endpoint. Example: {'agent_id':
|
||||||
|
'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at
|
||||||
|
Google', 'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date':
|
||||||
|
'2024-01-15T10:00:00Z'}]}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BatchPutAsyncResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
operation_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "delete",
|
||||||
|
"url": f"/api/operations/{operation_id}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = response.json()
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
operation_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Cancel a pending async operation
|
||||||
|
|
||||||
|
Cancel a pending async operation by removing it from the queue
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
operation_id=operation_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
operation_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Cancel a pending async operation
|
||||||
|
|
||||||
|
Cancel a pending async operation by removing it from the queue
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
operation_id=operation_id,
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
operation_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Cancel a pending async operation
|
||||||
|
|
||||||
|
Cancel a pending async operation by removing it from the queue
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
operation_id=operation_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
operation_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Cancel a pending async operation
|
||||||
|
|
||||||
|
Cancel a pending async operation by removing it from the queue
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
operation_id=operation_id,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
unit_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "delete",
|
||||||
|
"url": f"/api/memory/{unit_id}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = response.json()
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
unit_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Delete a memory unit
|
||||||
|
|
||||||
|
Delete a single memory unit and all its associated links (temporal, semantic, and entity links)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
unit_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
unit_id=unit_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
unit_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Delete a memory unit
|
||||||
|
|
||||||
|
Delete a single memory unit and all its associated links (temporal, semantic, and entity links)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
unit_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
unit_id=unit_id,
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
unit_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""Delete a memory unit
|
||||||
|
|
||||||
|
Delete a single memory unit and all its associated links (temporal, semantic, and entity links)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
unit_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
unit_id=unit_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
unit_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""Delete a memory unit
|
||||||
|
|
||||||
|
Delete a single memory unit and all its associated links (temporal, semantic, and entity links)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
unit_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
unit_id=unit_id,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
agent_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": f"/api/operations/{agent_id}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = response.json()
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""List async operations
|
||||||
|
|
||||||
|
Get a list of all async operations (pending and failed) for a specific agent, including error
|
||||||
|
messages for failed operations
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""List async operations
|
||||||
|
|
||||||
|
Get a list of all async operations (pending and failed) for a specific agent, including error
|
||||||
|
messages for failed operations
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Response[Any | HTTPValidationError]:
|
||||||
|
"""List async operations
|
||||||
|
|
||||||
|
Get a list of all async operations (pending and failed) for a specific agent, including error
|
||||||
|
messages for failed operations
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[Any | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
agent_id: str,
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
) -> Any | HTTPValidationError | None:
|
||||||
|
"""List async operations
|
||||||
|
|
||||||
|
Get a list of all async operations (pending and failed) for a specific agent, including error
|
||||||
|
messages for failed operations
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (str):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Any | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
agent_id=agent_id,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/reasoning/__init__.py
Normal file
1
memora-clients/python/api/reasoning/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
214
memora-clients/python/api/reasoning/api_think_api_think_post.py
Normal file
214
memora-clients/python/api/reasoning/api_think_api_think_post.py
Normal file
|
|
@ -0,0 +1,214 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...models.think_request import ThinkRequest
|
||||||
|
from ...models.think_response import ThinkResponse
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
body: ThinkRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "post",
|
||||||
|
"url": "/api/think",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> HTTPValidationError | ThinkResponse | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = ThinkResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[HTTPValidationError | ThinkResponse]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: ThinkRequest,
|
||||||
|
) -> Response[HTTPValidationError | ThinkResponse]:
|
||||||
|
"""Think and generate answer
|
||||||
|
|
||||||
|
Think and formulate an answer using agent identity, world facts, and opinions.
|
||||||
|
|
||||||
|
This endpoint:
|
||||||
|
1. Retrieves agent facts (agent's identity)
|
||||||
|
2. Retrieves world facts relevant to the query
|
||||||
|
3. Retrieves existing opinions (agent's perspectives)
|
||||||
|
4. Uses LLM to formulate a contextual answer
|
||||||
|
5. Extracts and stores any new opinions formed
|
||||||
|
6. Returns plain text answer, the facts used, and new opinions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (ThinkRequest): Request model for think endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'context': 'This is for a research paper on AI ethics', 'query': 'What do you think about
|
||||||
|
artificial intelligence?', 'thinking_budget': 50}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ThinkResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: ThinkRequest,
|
||||||
|
) -> HTTPValidationError | ThinkResponse | None:
|
||||||
|
"""Think and generate answer
|
||||||
|
|
||||||
|
Think and formulate an answer using agent identity, world facts, and opinions.
|
||||||
|
|
||||||
|
This endpoint:
|
||||||
|
1. Retrieves agent facts (agent's identity)
|
||||||
|
2. Retrieves world facts relevant to the query
|
||||||
|
3. Retrieves existing opinions (agent's perspectives)
|
||||||
|
4. Uses LLM to formulate a contextual answer
|
||||||
|
5. Extracts and stores any new opinions formed
|
||||||
|
6. Returns plain text answer, the facts used, and new opinions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (ThinkRequest): Request model for think endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'context': 'This is for a research paper on AI ethics', 'query': 'What do you think about
|
||||||
|
artificial intelligence?', 'thinking_budget': 50}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ThinkResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: ThinkRequest,
|
||||||
|
) -> Response[HTTPValidationError | ThinkResponse]:
|
||||||
|
"""Think and generate answer
|
||||||
|
|
||||||
|
Think and formulate an answer using agent identity, world facts, and opinions.
|
||||||
|
|
||||||
|
This endpoint:
|
||||||
|
1. Retrieves agent facts (agent's identity)
|
||||||
|
2. Retrieves world facts relevant to the query
|
||||||
|
3. Retrieves existing opinions (agent's perspectives)
|
||||||
|
4. Uses LLM to formulate a contextual answer
|
||||||
|
5. Extracts and stores any new opinions formed
|
||||||
|
6. Returns plain text answer, the facts used, and new opinions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (ThinkRequest): Request model for think endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'context': 'This is for a research paper on AI ethics', 'query': 'What do you think about
|
||||||
|
artificial intelligence?', 'thinking_budget': 50}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ThinkResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: ThinkRequest,
|
||||||
|
) -> HTTPValidationError | ThinkResponse | None:
|
||||||
|
"""Think and generate answer
|
||||||
|
|
||||||
|
Think and formulate an answer using agent identity, world facts, and opinions.
|
||||||
|
|
||||||
|
This endpoint:
|
||||||
|
1. Retrieves agent facts (agent's identity)
|
||||||
|
2. Retrieves world facts relevant to the query
|
||||||
|
3. Retrieves existing opinions (agent's perspectives)
|
||||||
|
4. Uses LLM to formulate a contextual answer
|
||||||
|
5. Extracts and stores any new opinions formed
|
||||||
|
6. Returns plain text answer, the facts used, and new opinions
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (ThinkRequest): Request model for think endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'context': 'This is for a research paper on AI ethics', 'query': 'What do you think about
|
||||||
|
artificial intelligence?', 'thinking_budget': 50}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ThinkResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/search/__init__.py
Normal file
1
memora-clients/python/api/search/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
206
memora-clients/python/api/search/api_search_api_search_post.py
Normal file
206
memora-clients/python/api/search/api_search_api_search_post.py
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...models.search_request import SearchRequest
|
||||||
|
from ...models.search_response import SearchResponse
|
||||||
|
from ...types import Response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
body: SearchRequest,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
headers: dict[str, Any] = {}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "post",
|
||||||
|
"url": "/api/search",
|
||||||
|
}
|
||||||
|
|
||||||
|
_kwargs["json"] = body.to_dict()
|
||||||
|
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
|
||||||
|
_kwargs["headers"] = headers
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> HTTPValidationError | SearchResponse | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = SearchResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[HTTPValidationError | SearchResponse]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: SearchRequest,
|
||||||
|
) -> Response[HTTPValidationError | SearchResponse]:
|
||||||
|
"""Search memory
|
||||||
|
|
||||||
|
Search memory using semantic similarity and spreading activation.
|
||||||
|
|
||||||
|
The fact_type parameter is required and must be one of:
|
||||||
|
- 'world': General knowledge about people, places, events, and things that happen
|
||||||
|
- 'agent': Memories about what the AI agent did, actions taken, and tasks performed
|
||||||
|
- 'opinion': The agent's formed beliefs, perspectives, and viewpoints
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (SearchRequest): Request model for search endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about
|
||||||
|
machine learning?', 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic',
|
||||||
|
'thinking_budget': 100, 'trace': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | SearchResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: SearchRequest,
|
||||||
|
) -> HTTPValidationError | SearchResponse | None:
|
||||||
|
"""Search memory
|
||||||
|
|
||||||
|
Search memory using semantic similarity and spreading activation.
|
||||||
|
|
||||||
|
The fact_type parameter is required and must be one of:
|
||||||
|
- 'world': General knowledge about people, places, events, and things that happen
|
||||||
|
- 'agent': Memories about what the AI agent did, actions taken, and tasks performed
|
||||||
|
- 'opinion': The agent's formed beliefs, perspectives, and viewpoints
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (SearchRequest): Request model for search endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about
|
||||||
|
machine learning?', 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic',
|
||||||
|
'thinking_budget': 100, 'trace': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | SearchResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: SearchRequest,
|
||||||
|
) -> Response[HTTPValidationError | SearchResponse]:
|
||||||
|
"""Search memory
|
||||||
|
|
||||||
|
Search memory using semantic similarity and spreading activation.
|
||||||
|
|
||||||
|
The fact_type parameter is required and must be one of:
|
||||||
|
- 'world': General knowledge about people, places, events, and things that happen
|
||||||
|
- 'agent': Memories about what the AI agent did, actions taken, and tasks performed
|
||||||
|
- 'opinion': The agent's formed beliefs, perspectives, and viewpoints
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (SearchRequest): Request model for search endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about
|
||||||
|
machine learning?', 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic',
|
||||||
|
'thinking_budget': 100, 'trace': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | SearchResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
body: SearchRequest,
|
||||||
|
) -> HTTPValidationError | SearchResponse | None:
|
||||||
|
"""Search memory
|
||||||
|
|
||||||
|
Search memory using semantic similarity and spreading activation.
|
||||||
|
|
||||||
|
The fact_type parameter is required and must be one of:
|
||||||
|
- 'world': General knowledge about people, places, events, and things that happen
|
||||||
|
- 'agent': Memories about what the AI agent did, actions taken, and tasks performed
|
||||||
|
- 'opinion': The agent's formed beliefs, perspectives, and viewpoints
|
||||||
|
|
||||||
|
Args:
|
||||||
|
body (SearchRequest): Request model for search endpoint. Example: {'agent_id': 'user123',
|
||||||
|
'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about
|
||||||
|
machine learning?', 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic',
|
||||||
|
'thinking_budget': 100, 'trace': True}.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | SearchResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
body=body,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
1
memora-clients/python/api/visualization/__init__.py
Normal file
1
memora-clients/python/api/visualization/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"""Contains endpoint functions for accessing the API"""
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.graph_data_response import GraphDataResponse
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...types import UNSET, Response, Unset
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
params: dict[str, Any] = {}
|
||||||
|
|
||||||
|
json_agent_id: None | str | Unset
|
||||||
|
if isinstance(agent_id, Unset):
|
||||||
|
json_agent_id = UNSET
|
||||||
|
else:
|
||||||
|
json_agent_id = agent_id
|
||||||
|
params["agent_id"] = json_agent_id
|
||||||
|
|
||||||
|
json_fact_type: None | str | Unset
|
||||||
|
if isinstance(fact_type, Unset):
|
||||||
|
json_fact_type = UNSET
|
||||||
|
else:
|
||||||
|
json_fact_type = fact_type
|
||||||
|
params["fact_type"] = json_fact_type
|
||||||
|
|
||||||
|
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": "/api/graph",
|
||||||
|
"params": params,
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> GraphDataResponse | HTTPValidationError | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = GraphDataResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[GraphDataResponse | HTTPValidationError]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
) -> Response[GraphDataResponse | HTTPValidationError]:
|
||||||
|
"""Get memory graph data
|
||||||
|
|
||||||
|
Retrieve graph data for visualization, optionally filtered by agent_id and fact_type
|
||||||
|
(world/agent/opinion). Limited to 1000 most recent items.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[GraphDataResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
) -> GraphDataResponse | HTTPValidationError | None:
|
||||||
|
"""Get memory graph data
|
||||||
|
|
||||||
|
Retrieve graph data for visualization, optionally filtered by agent_id and fact_type
|
||||||
|
(world/agent/opinion). Limited to 1000 most recent items.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
GraphDataResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
) -> Response[GraphDataResponse | HTTPValidationError]:
|
||||||
|
"""Get memory graph data
|
||||||
|
|
||||||
|
Retrieve graph data for visualization, optionally filtered by agent_id and fact_type
|
||||||
|
(world/agent/opinion). Limited to 1000 most recent items.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[GraphDataResponse | HTTPValidationError]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
) -> GraphDataResponse | HTTPValidationError | None:
|
||||||
|
"""Get memory graph data
|
||||||
|
|
||||||
|
Retrieve graph data for visualization, optionally filtered by agent_id and fact_type
|
||||||
|
(world/agent/opinion). Limited to 1000 most recent items.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
GraphDataResponse | HTTPValidationError
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
252
memora-clients/python/api/visualization/api_list_api_list_get.py
Normal file
252
memora-clients/python/api/visualization/api_list_api_list_get.py
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from ... import errors
|
||||||
|
from ...client import AuthenticatedClient, Client
|
||||||
|
from ...models.http_validation_error import HTTPValidationError
|
||||||
|
from ...models.list_memory_units_response import ListMemoryUnitsResponse
|
||||||
|
from ...types import UNSET, Response, Unset
|
||||||
|
|
||||||
|
|
||||||
|
def _get_kwargs(
|
||||||
|
*,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
params: dict[str, Any] = {}
|
||||||
|
|
||||||
|
json_agent_id: None | str | Unset
|
||||||
|
if isinstance(agent_id, Unset):
|
||||||
|
json_agent_id = UNSET
|
||||||
|
else:
|
||||||
|
json_agent_id = agent_id
|
||||||
|
params["agent_id"] = json_agent_id
|
||||||
|
|
||||||
|
json_fact_type: None | str | Unset
|
||||||
|
if isinstance(fact_type, Unset):
|
||||||
|
json_fact_type = UNSET
|
||||||
|
else:
|
||||||
|
json_fact_type = fact_type
|
||||||
|
params["fact_type"] = json_fact_type
|
||||||
|
|
||||||
|
json_q: None | str | Unset
|
||||||
|
if isinstance(q, Unset):
|
||||||
|
json_q = UNSET
|
||||||
|
else:
|
||||||
|
json_q = q
|
||||||
|
params["q"] = json_q
|
||||||
|
|
||||||
|
params["limit"] = limit
|
||||||
|
|
||||||
|
params["offset"] = offset
|
||||||
|
|
||||||
|
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
||||||
|
|
||||||
|
_kwargs: dict[str, Any] = {
|
||||||
|
"method": "get",
|
||||||
|
"url": "/api/list",
|
||||||
|
"params": params,
|
||||||
|
}
|
||||||
|
|
||||||
|
return _kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> HTTPValidationError | ListMemoryUnitsResponse | None:
|
||||||
|
if response.status_code == 200:
|
||||||
|
response_200 = ListMemoryUnitsResponse.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_200
|
||||||
|
|
||||||
|
if response.status_code == 422:
|
||||||
|
response_422 = HTTPValidationError.from_dict(response.json())
|
||||||
|
|
||||||
|
return response_422
|
||||||
|
|
||||||
|
if client.raise_on_unexpected_status:
|
||||||
|
raise errors.UnexpectedStatus(response.status_code, response.content)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response(
|
||||||
|
*, client: AuthenticatedClient | Client, response: httpx.Response
|
||||||
|
) -> Response[HTTPValidationError | ListMemoryUnitsResponse]:
|
||||||
|
return Response(
|
||||||
|
status_code=HTTPStatus(response.status_code),
|
||||||
|
content=response.content,
|
||||||
|
headers=response.headers,
|
||||||
|
parsed=_parse_response(client=client, response=response),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def sync_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> Response[HTTPValidationError | ListMemoryUnitsResponse]:
|
||||||
|
"""List memory units
|
||||||
|
|
||||||
|
List memory units with pagination and optional full-text search. Supports filtering by agent_id and
|
||||||
|
fact_type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ListMemoryUnitsResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.get_httpx_client().request(
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
def sync(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> HTTPValidationError | ListMemoryUnitsResponse | None:
|
||||||
|
"""List memory units
|
||||||
|
|
||||||
|
List memory units with pagination and optional full-text search. Supports filtering by agent_id and
|
||||||
|
fact_type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ListMemoryUnitsResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return sync_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
).parsed
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio_detailed(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> Response[HTTPValidationError | ListMemoryUnitsResponse]:
|
||||||
|
"""List memory units
|
||||||
|
|
||||||
|
List memory units with pagination and optional full-text search. Supports filtering by agent_id and
|
||||||
|
fact_type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Response[HTTPValidationError | ListMemoryUnitsResponse]
|
||||||
|
"""
|
||||||
|
|
||||||
|
kwargs = _get_kwargs(
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await client.get_async_httpx_client().request(**kwargs)
|
||||||
|
|
||||||
|
return _build_response(client=client, response=response)
|
||||||
|
|
||||||
|
|
||||||
|
async def asyncio(
|
||||||
|
*,
|
||||||
|
client: AuthenticatedClient | Client,
|
||||||
|
agent_id: None | str | Unset = UNSET,
|
||||||
|
fact_type: None | str | Unset = UNSET,
|
||||||
|
q: None | str | Unset = UNSET,
|
||||||
|
limit: int | Unset = 100,
|
||||||
|
offset: int | Unset = 0,
|
||||||
|
) -> HTTPValidationError | ListMemoryUnitsResponse | None:
|
||||||
|
"""List memory units
|
||||||
|
|
||||||
|
List memory units with pagination and optional full-text search. Supports filtering by agent_id and
|
||||||
|
fact_type.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
agent_id (None | str | Unset):
|
||||||
|
fact_type (None | str | Unset):
|
||||||
|
q (None | str | Unset):
|
||||||
|
limit (int | Unset): Default: 100.
|
||||||
|
offset (int | Unset): Default: 0.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
||||||
|
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
HTTPValidationError | ListMemoryUnitsResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
await asyncio_detailed(
|
||||||
|
client=client,
|
||||||
|
agent_id=agent_id,
|
||||||
|
fact_type=fact_type,
|
||||||
|
q=q,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
).parsed
|
||||||
268
memora-clients/python/client.py
Normal file
268
memora-clients/python/client.py
Normal file
|
|
@ -0,0 +1,268 @@
|
||||||
|
import ssl
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from attrs import define, evolve, field
|
||||||
|
|
||||||
|
|
||||||
|
@define
|
||||||
|
class Client:
|
||||||
|
"""A class for keeping track of data related to the API
|
||||||
|
|
||||||
|
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
|
||||||
|
|
||||||
|
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
|
||||||
|
|
||||||
|
``cookies``: A dictionary of cookies to be sent with every request
|
||||||
|
|
||||||
|
``headers``: A dictionary of headers to be sent with every request
|
||||||
|
|
||||||
|
``timeout``: The maximum amount of a time a request can take. API functions will raise
|
||||||
|
httpx.TimeoutException if this is exceeded.
|
||||||
|
|
||||||
|
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
|
||||||
|
but can be set to False for testing purposes.
|
||||||
|
|
||||||
|
``follow_redirects``: Whether or not to follow redirects. Default value is False.
|
||||||
|
|
||||||
|
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
|
||||||
|
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
|
||||||
|
status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
|
||||||
|
argument to the constructor.
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise_on_unexpected_status: bool = field(default=False, kw_only=True)
|
||||||
|
_base_url: str = field(alias="base_url")
|
||||||
|
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
|
||||||
|
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
|
||||||
|
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
|
||||||
|
_verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
|
||||||
|
_follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
|
||||||
|
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
|
||||||
|
_client: httpx.Client | None = field(default=None, init=False)
|
||||||
|
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
|
||||||
|
|
||||||
|
def with_headers(self, headers: dict[str, str]) -> "Client":
|
||||||
|
"""Get a new client matching this one with additional headers"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.headers.update(headers)
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.headers.update(headers)
|
||||||
|
return evolve(self, headers={**self._headers, **headers})
|
||||||
|
|
||||||
|
def with_cookies(self, cookies: dict[str, str]) -> "Client":
|
||||||
|
"""Get a new client matching this one with additional cookies"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.cookies.update(cookies)
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.cookies.update(cookies)
|
||||||
|
return evolve(self, cookies={**self._cookies, **cookies})
|
||||||
|
|
||||||
|
def with_timeout(self, timeout: httpx.Timeout) -> "Client":
|
||||||
|
"""Get a new client matching this one with a new timeout configuration"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.timeout = timeout
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.timeout = timeout
|
||||||
|
return evolve(self, timeout=timeout)
|
||||||
|
|
||||||
|
def set_httpx_client(self, client: httpx.Client) -> "Client":
|
||||||
|
"""Manually set the underlying httpx.Client
|
||||||
|
|
||||||
|
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
|
||||||
|
"""
|
||||||
|
self._client = client
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_httpx_client(self) -> httpx.Client:
|
||||||
|
"""Get the underlying httpx.Client, constructing a new one if not previously set"""
|
||||||
|
if self._client is None:
|
||||||
|
self._client = httpx.Client(
|
||||||
|
base_url=self._base_url,
|
||||||
|
cookies=self._cookies,
|
||||||
|
headers=self._headers,
|
||||||
|
timeout=self._timeout,
|
||||||
|
verify=self._verify_ssl,
|
||||||
|
follow_redirects=self._follow_redirects,
|
||||||
|
**self._httpx_args,
|
||||||
|
)
|
||||||
|
return self._client
|
||||||
|
|
||||||
|
def __enter__(self) -> "Client":
|
||||||
|
"""Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
|
||||||
|
self.get_httpx_client().__enter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
"""Exit a context manager for internal httpx.Client (see httpx docs)"""
|
||||||
|
self.get_httpx_client().__exit__(*args, **kwargs)
|
||||||
|
|
||||||
|
def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client":
|
||||||
|
"""Manually set the underlying httpx.AsyncClient
|
||||||
|
|
||||||
|
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
|
||||||
|
"""
|
||||||
|
self._async_client = async_client
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_async_httpx_client(self) -> httpx.AsyncClient:
|
||||||
|
"""Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
|
||||||
|
if self._async_client is None:
|
||||||
|
self._async_client = httpx.AsyncClient(
|
||||||
|
base_url=self._base_url,
|
||||||
|
cookies=self._cookies,
|
||||||
|
headers=self._headers,
|
||||||
|
timeout=self._timeout,
|
||||||
|
verify=self._verify_ssl,
|
||||||
|
follow_redirects=self._follow_redirects,
|
||||||
|
**self._httpx_args,
|
||||||
|
)
|
||||||
|
return self._async_client
|
||||||
|
|
||||||
|
async def __aenter__(self) -> "Client":
|
||||||
|
"""Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
|
||||||
|
await self.get_async_httpx_client().__aenter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
"""Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
|
||||||
|
await self.get_async_httpx_client().__aexit__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@define
|
||||||
|
class AuthenticatedClient:
|
||||||
|
"""A Client which has been authenticated for use on secured endpoints
|
||||||
|
|
||||||
|
The following are accepted as keyword arguments and will be used to construct httpx Clients internally:
|
||||||
|
|
||||||
|
``base_url``: The base URL for the API, all requests are made to a relative path to this URL
|
||||||
|
|
||||||
|
``cookies``: A dictionary of cookies to be sent with every request
|
||||||
|
|
||||||
|
``headers``: A dictionary of headers to be sent with every request
|
||||||
|
|
||||||
|
``timeout``: The maximum amount of a time a request can take. API functions will raise
|
||||||
|
httpx.TimeoutException if this is exceeded.
|
||||||
|
|
||||||
|
``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production,
|
||||||
|
but can be set to False for testing purposes.
|
||||||
|
|
||||||
|
``follow_redirects``: Whether or not to follow redirects. Default value is False.
|
||||||
|
|
||||||
|
``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
|
||||||
|
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
|
||||||
|
status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
|
||||||
|
argument to the constructor.
|
||||||
|
token: The token to use for authentication
|
||||||
|
prefix: The prefix to use for the Authorization header
|
||||||
|
auth_header_name: The name of the Authorization header
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise_on_unexpected_status: bool = field(default=False, kw_only=True)
|
||||||
|
_base_url: str = field(alias="base_url")
|
||||||
|
_cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
|
||||||
|
_headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
|
||||||
|
_timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout")
|
||||||
|
_verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl")
|
||||||
|
_follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects")
|
||||||
|
_httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args")
|
||||||
|
_client: httpx.Client | None = field(default=None, init=False)
|
||||||
|
_async_client: httpx.AsyncClient | None = field(default=None, init=False)
|
||||||
|
|
||||||
|
token: str
|
||||||
|
prefix: str = "Bearer"
|
||||||
|
auth_header_name: str = "Authorization"
|
||||||
|
|
||||||
|
def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient":
|
||||||
|
"""Get a new client matching this one with additional headers"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.headers.update(headers)
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.headers.update(headers)
|
||||||
|
return evolve(self, headers={**self._headers, **headers})
|
||||||
|
|
||||||
|
def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient":
|
||||||
|
"""Get a new client matching this one with additional cookies"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.cookies.update(cookies)
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.cookies.update(cookies)
|
||||||
|
return evolve(self, cookies={**self._cookies, **cookies})
|
||||||
|
|
||||||
|
def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient":
|
||||||
|
"""Get a new client matching this one with a new timeout configuration"""
|
||||||
|
if self._client is not None:
|
||||||
|
self._client.timeout = timeout
|
||||||
|
if self._async_client is not None:
|
||||||
|
self._async_client.timeout = timeout
|
||||||
|
return evolve(self, timeout=timeout)
|
||||||
|
|
||||||
|
def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient":
|
||||||
|
"""Manually set the underlying httpx.Client
|
||||||
|
|
||||||
|
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
|
||||||
|
"""
|
||||||
|
self._client = client
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_httpx_client(self) -> httpx.Client:
|
||||||
|
"""Get the underlying httpx.Client, constructing a new one if not previously set"""
|
||||||
|
if self._client is None:
|
||||||
|
self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
|
||||||
|
self._client = httpx.Client(
|
||||||
|
base_url=self._base_url,
|
||||||
|
cookies=self._cookies,
|
||||||
|
headers=self._headers,
|
||||||
|
timeout=self._timeout,
|
||||||
|
verify=self._verify_ssl,
|
||||||
|
follow_redirects=self._follow_redirects,
|
||||||
|
**self._httpx_args,
|
||||||
|
)
|
||||||
|
return self._client
|
||||||
|
|
||||||
|
def __enter__(self) -> "AuthenticatedClient":
|
||||||
|
"""Enter a context manager for self.client—you cannot enter twice (see httpx docs)"""
|
||||||
|
self.get_httpx_client().__enter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
"""Exit a context manager for internal httpx.Client (see httpx docs)"""
|
||||||
|
self.get_httpx_client().__exit__(*args, **kwargs)
|
||||||
|
|
||||||
|
def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient":
|
||||||
|
"""Manually set the underlying httpx.AsyncClient
|
||||||
|
|
||||||
|
**NOTE**: This will override any other settings on the client, including cookies, headers, and timeout.
|
||||||
|
"""
|
||||||
|
self._async_client = async_client
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_async_httpx_client(self) -> httpx.AsyncClient:
|
||||||
|
"""Get the underlying httpx.AsyncClient, constructing a new one if not previously set"""
|
||||||
|
if self._async_client is None:
|
||||||
|
self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token
|
||||||
|
self._async_client = httpx.AsyncClient(
|
||||||
|
base_url=self._base_url,
|
||||||
|
cookies=self._cookies,
|
||||||
|
headers=self._headers,
|
||||||
|
timeout=self._timeout,
|
||||||
|
verify=self._verify_ssl,
|
||||||
|
follow_redirects=self._follow_redirects,
|
||||||
|
**self._httpx_args,
|
||||||
|
)
|
||||||
|
return self._async_client
|
||||||
|
|
||||||
|
async def __aenter__(self) -> "AuthenticatedClient":
|
||||||
|
"""Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)"""
|
||||||
|
await self.get_async_httpx_client().__aenter__()
|
||||||
|
return self
|
||||||
|
|
||||||
|
async def __aexit__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
|
"""Exit a context manager for underlying httpx.AsyncClient (see httpx docs)"""
|
||||||
|
await self.get_async_httpx_client().__aexit__(*args, **kwargs)
|
||||||
16
memora-clients/python/errors.py
Normal file
16
memora-clients/python/errors.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
"""Contains shared errors types that can be raised from API functions"""
|
||||||
|
|
||||||
|
|
||||||
|
class UnexpectedStatus(Exception):
|
||||||
|
"""Raised by api functions when the response status an undocumented status and Client.raise_on_unexpected_status is True"""
|
||||||
|
|
||||||
|
def __init__(self, status_code: int, content: bytes):
|
||||||
|
self.status_code = status_code
|
||||||
|
self.content = content
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
f"Unexpected status code: {status_code}\n\nResponse content:\n{content.decode(errors='ignore')}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["UnexpectedStatus"]
|
||||||
67
memora-clients/python/models/__init__.py
Normal file
67
memora-clients/python/models/__init__.py
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
"""Contains all the data models used in inputs/outputs"""
|
||||||
|
|
||||||
|
from .add_background_request import AddBackgroundRequest
|
||||||
|
from .agent_list_item import AgentListItem
|
||||||
|
from .agent_list_response import AgentListResponse
|
||||||
|
from .agent_profile_response import AgentProfileResponse
|
||||||
|
from .agents_response import AgentsResponse
|
||||||
|
from .background_response import BackgroundResponse
|
||||||
|
from .batch_put_async_response import BatchPutAsyncResponse
|
||||||
|
from .batch_put_request import BatchPutRequest
|
||||||
|
from .batch_put_response import BatchPutResponse
|
||||||
|
from .create_agent_request import CreateAgentRequest
|
||||||
|
from .document_response import DocumentResponse
|
||||||
|
from .graph_data_response import GraphDataResponse
|
||||||
|
from .graph_data_response_edges_item import GraphDataResponseEdgesItem
|
||||||
|
from .graph_data_response_nodes_item import GraphDataResponseNodesItem
|
||||||
|
from .graph_data_response_table_rows_item import GraphDataResponseTableRowsItem
|
||||||
|
from .http_validation_error import HTTPValidationError
|
||||||
|
from .list_documents_response import ListDocumentsResponse
|
||||||
|
from .list_documents_response_items_item import ListDocumentsResponseItemsItem
|
||||||
|
from .list_memory_units_response import ListMemoryUnitsResponse
|
||||||
|
from .list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem
|
||||||
|
from .memory_item import MemoryItem
|
||||||
|
from .personality_traits import PersonalityTraits
|
||||||
|
from .search_request import SearchRequest
|
||||||
|
from .search_response import SearchResponse
|
||||||
|
from .search_response_trace_type_0 import SearchResponseTraceType0
|
||||||
|
from .search_result import SearchResult
|
||||||
|
from .think_fact import ThinkFact
|
||||||
|
from .think_request import ThinkRequest
|
||||||
|
from .think_response import ThinkResponse
|
||||||
|
from .update_personality_request import UpdatePersonalityRequest
|
||||||
|
from .validation_error import ValidationError
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
"AddBackgroundRequest",
|
||||||
|
"AgentListItem",
|
||||||
|
"AgentListResponse",
|
||||||
|
"AgentProfileResponse",
|
||||||
|
"AgentsResponse",
|
||||||
|
"BackgroundResponse",
|
||||||
|
"BatchPutAsyncResponse",
|
||||||
|
"BatchPutRequest",
|
||||||
|
"BatchPutResponse",
|
||||||
|
"CreateAgentRequest",
|
||||||
|
"DocumentResponse",
|
||||||
|
"GraphDataResponse",
|
||||||
|
"GraphDataResponseEdgesItem",
|
||||||
|
"GraphDataResponseNodesItem",
|
||||||
|
"GraphDataResponseTableRowsItem",
|
||||||
|
"HTTPValidationError",
|
||||||
|
"ListDocumentsResponse",
|
||||||
|
"ListDocumentsResponseItemsItem",
|
||||||
|
"ListMemoryUnitsResponse",
|
||||||
|
"ListMemoryUnitsResponseItemsItem",
|
||||||
|
"MemoryItem",
|
||||||
|
"PersonalityTraits",
|
||||||
|
"SearchRequest",
|
||||||
|
"SearchResponse",
|
||||||
|
"SearchResponseTraceType0",
|
||||||
|
"SearchResult",
|
||||||
|
"ThinkFact",
|
||||||
|
"ThinkRequest",
|
||||||
|
"ThinkResponse",
|
||||||
|
"UpdatePersonalityRequest",
|
||||||
|
"ValidationError",
|
||||||
|
)
|
||||||
77
memora-clients/python/models/add_background_request.py
Normal file
77
memora-clients/python/models/add_background_request.py
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="AddBackgroundRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class AddBackgroundRequest:
|
||||||
|
"""Request model for adding/merging background information.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'content': 'I was born in Texas', 'update_personality': True}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
content (str): New background information to add or merge
|
||||||
|
update_personality (bool | Unset): If true, infer Big Five personality traits from the merged background
|
||||||
|
(default: true) Default: True.
|
||||||
|
"""
|
||||||
|
|
||||||
|
content: str
|
||||||
|
update_personality: bool | Unset = True
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
content = self.content
|
||||||
|
|
||||||
|
update_personality = self.update_personality
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"content": content,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if update_personality is not UNSET:
|
||||||
|
field_dict["update_personality"] = update_personality
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
content = d.pop("content")
|
||||||
|
|
||||||
|
update_personality = d.pop("update_personality", UNSET)
|
||||||
|
|
||||||
|
add_background_request = cls(
|
||||||
|
content=content,
|
||||||
|
update_personality=update_personality,
|
||||||
|
)
|
||||||
|
|
||||||
|
add_background_request.additional_properties = d
|
||||||
|
return add_background_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
127
memora-clients/python/models/agent_list_item.py
Normal file
127
memora-clients/python/models/agent_list_item.py
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="AgentListItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class AgentListItem:
|
||||||
|
"""Agent list item with profile summary.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
agent_id (str):
|
||||||
|
personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7,
|
||||||
|
'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}.
|
||||||
|
background (str):
|
||||||
|
created_at (None | str | Unset):
|
||||||
|
updated_at (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
agent_id: str
|
||||||
|
personality: PersonalityTraits
|
||||||
|
background: str
|
||||||
|
created_at: None | str | Unset = UNSET
|
||||||
|
updated_at: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
personality = self.personality.to_dict()
|
||||||
|
|
||||||
|
background = self.background
|
||||||
|
|
||||||
|
created_at: None | str | Unset
|
||||||
|
if isinstance(self.created_at, Unset):
|
||||||
|
created_at = UNSET
|
||||||
|
else:
|
||||||
|
created_at = self.created_at
|
||||||
|
|
||||||
|
updated_at: None | str | Unset
|
||||||
|
if isinstance(self.updated_at, Unset):
|
||||||
|
updated_at = UNSET
|
||||||
|
else:
|
||||||
|
updated_at = self.updated_at
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"personality": personality,
|
||||||
|
"background": background,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if created_at is not UNSET:
|
||||||
|
field_dict["created_at"] = created_at
|
||||||
|
if updated_at is not UNSET:
|
||||||
|
field_dict["updated_at"] = updated_at
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
personality = PersonalityTraits.from_dict(d.pop("personality"))
|
||||||
|
|
||||||
|
background = d.pop("background")
|
||||||
|
|
||||||
|
def _parse_created_at(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
created_at = _parse_created_at(d.pop("created_at", UNSET))
|
||||||
|
|
||||||
|
def _parse_updated_at(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
updated_at = _parse_updated_at(d.pop("updated_at", UNSET))
|
||||||
|
|
||||||
|
agent_list_item = cls(
|
||||||
|
agent_id=agent_id,
|
||||||
|
personality=personality,
|
||||||
|
background=background,
|
||||||
|
created_at=created_at,
|
||||||
|
updated_at=updated_at,
|
||||||
|
)
|
||||||
|
|
||||||
|
agent_list_item.additional_properties = d
|
||||||
|
return agent_list_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
81
memora-clients/python/models/agent_list_response.py
Normal file
81
memora-clients/python/models/agent_list_response.py
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.agent_list_item import AgentListItem
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="AgentListResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class AgentListResponse:
|
||||||
|
"""Response model for listing all agents.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agents': [{'agent_id': 'user123', 'background': 'I am a software engineer', 'created_at':
|
||||||
|
'2024-01-15T10:30:00Z', 'personality': {'agreeableness': 0.5, 'bias_strength': 0.5, 'conscientiousness': 0.5,
|
||||||
|
'extraversion': 0.5, 'neuroticism': 0.5, 'openness': 0.5}, 'updated_at': '2024-01-16T14:20:00Z'}]}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
agents (list[AgentListItem]):
|
||||||
|
"""
|
||||||
|
|
||||||
|
agents: list[AgentListItem]
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
agents = []
|
||||||
|
for agents_item_data in self.agents:
|
||||||
|
agents_item = agents_item_data.to_dict()
|
||||||
|
agents.append(agents_item)
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"agents": agents,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.agent_list_item import AgentListItem
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
agents = []
|
||||||
|
_agents = d.pop("agents")
|
||||||
|
for agents_item_data in _agents:
|
||||||
|
agents_item = AgentListItem.from_dict(agents_item_data)
|
||||||
|
|
||||||
|
agents.append(agents_item)
|
||||||
|
|
||||||
|
agent_list_response = cls(
|
||||||
|
agents=agents,
|
||||||
|
)
|
||||||
|
|
||||||
|
agent_list_response.additional_properties = d
|
||||||
|
return agent_list_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
90
memora-clients/python/models/agent_profile_response.py
Normal file
90
memora-clients/python/models/agent_profile_response.py
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="AgentProfileResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class AgentProfileResponse:
|
||||||
|
"""Response model for agent profile.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'background': 'I am a software engineer with 10 years of experience in startups',
|
||||||
|
'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5,
|
||||||
|
'neuroticism': 0.3, 'openness': 0.8}}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
agent_id (str):
|
||||||
|
personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7,
|
||||||
|
'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}.
|
||||||
|
background (str):
|
||||||
|
"""
|
||||||
|
|
||||||
|
agent_id: str
|
||||||
|
personality: PersonalityTraits
|
||||||
|
background: str
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
personality = self.personality.to_dict()
|
||||||
|
|
||||||
|
background = self.background
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"personality": personality,
|
||||||
|
"background": background,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
personality = PersonalityTraits.from_dict(d.pop("personality"))
|
||||||
|
|
||||||
|
background = d.pop("background")
|
||||||
|
|
||||||
|
agent_profile_response = cls(
|
||||||
|
agent_id=agent_id,
|
||||||
|
personality=personality,
|
||||||
|
background=background,
|
||||||
|
)
|
||||||
|
|
||||||
|
agent_profile_response.additional_properties = d
|
||||||
|
return agent_profile_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
65
memora-clients/python/models/agents_response.py
Normal file
65
memora-clients/python/models/agents_response.py
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="AgentsResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class AgentsResponse:
|
||||||
|
"""Response model for agents list endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agents': ['user123', 'agent_alice', 'agent_bob']}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
agents (list[str]):
|
||||||
|
"""
|
||||||
|
|
||||||
|
agents: list[str]
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
agents = self.agents
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"agents": agents,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
agents = cast(list[str], d.pop("agents"))
|
||||||
|
|
||||||
|
agents_response = cls(
|
||||||
|
agents=agents,
|
||||||
|
)
|
||||||
|
|
||||||
|
agents_response.additional_properties = d
|
||||||
|
return agents_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
107
memora-clients/python/models/background_response.py
Normal file
107
memora-clients/python/models/background_response.py
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="BackgroundResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class BackgroundResponse:
|
||||||
|
"""Response model for background update.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'background': 'I was born in Texas. I am a software engineer with 10 years of experience.', 'personality':
|
||||||
|
{'agreeableness': 0.8, 'bias_strength': 0.6, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.4,
|
||||||
|
'openness': 0.7}}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
background (str):
|
||||||
|
personality (None | PersonalityTraits | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
background: str
|
||||||
|
personality: None | PersonalityTraits | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
background = self.background
|
||||||
|
|
||||||
|
personality: dict[str, Any] | None | Unset
|
||||||
|
if isinstance(self.personality, Unset):
|
||||||
|
personality = UNSET
|
||||||
|
elif isinstance(self.personality, PersonalityTraits):
|
||||||
|
personality = self.personality.to_dict()
|
||||||
|
else:
|
||||||
|
personality = self.personality
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"background": background,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if personality is not UNSET:
|
||||||
|
field_dict["personality"] = personality
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
background = d.pop("background")
|
||||||
|
|
||||||
|
def _parse_personality(data: object) -> None | PersonalityTraits | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
try:
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise TypeError()
|
||||||
|
personality_type_0 = PersonalityTraits.from_dict(data)
|
||||||
|
|
||||||
|
return personality_type_0
|
||||||
|
except (TypeError, ValueError, AttributeError, KeyError):
|
||||||
|
pass
|
||||||
|
return cast(None | PersonalityTraits | Unset, data)
|
||||||
|
|
||||||
|
personality = _parse_personality(d.pop("personality", UNSET))
|
||||||
|
|
||||||
|
background_response = cls(
|
||||||
|
background=background,
|
||||||
|
personality=personality,
|
||||||
|
)
|
||||||
|
|
||||||
|
background_response.additional_properties = d
|
||||||
|
return background_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
120
memora-clients/python/models/batch_put_async_response.py
Normal file
120
memora-clients/python/models/batch_put_async_response.py
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="BatchPutAsyncResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class BatchPutAsyncResponse:
|
||||||
|
"""Response model for async batch put endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'document_id': 'conversation_123', 'items_count': 2, 'message': 'Batch put task queued
|
||||||
|
for background processing', 'queued': True, 'success': True}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
success (bool):
|
||||||
|
message (str):
|
||||||
|
agent_id (str):
|
||||||
|
items_count (int):
|
||||||
|
queued (bool):
|
||||||
|
document_id (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
success: bool
|
||||||
|
message: str
|
||||||
|
agent_id: str
|
||||||
|
items_count: int
|
||||||
|
queued: bool
|
||||||
|
document_id: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
success = self.success
|
||||||
|
|
||||||
|
message = self.message
|
||||||
|
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
items_count = self.items_count
|
||||||
|
|
||||||
|
queued = self.queued
|
||||||
|
|
||||||
|
document_id: None | str | Unset
|
||||||
|
if isinstance(self.document_id, Unset):
|
||||||
|
document_id = UNSET
|
||||||
|
else:
|
||||||
|
document_id = self.document_id
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"success": success,
|
||||||
|
"message": message,
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"items_count": items_count,
|
||||||
|
"queued": queued,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if document_id is not UNSET:
|
||||||
|
field_dict["document_id"] = document_id
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
success = d.pop("success")
|
||||||
|
|
||||||
|
message = d.pop("message")
|
||||||
|
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
items_count = d.pop("items_count")
|
||||||
|
|
||||||
|
queued = d.pop("queued")
|
||||||
|
|
||||||
|
def _parse_document_id(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
document_id = _parse_document_id(d.pop("document_id", UNSET))
|
||||||
|
|
||||||
|
batch_put_async_response = cls(
|
||||||
|
success=success,
|
||||||
|
message=message,
|
||||||
|
agent_id=agent_id,
|
||||||
|
items_count=items_count,
|
||||||
|
queued=queued,
|
||||||
|
document_id=document_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
batch_put_async_response.additional_properties = d
|
||||||
|
return batch_put_async_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
110
memora-clients/python/models/batch_put_request.py
Normal file
110
memora-clients/python/models/batch_put_request.py
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.memory_item import MemoryItem
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="BatchPutRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class BatchPutRequest:
|
||||||
|
"""Request model for batch put endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'document_id': 'conversation_123', 'items': [{'content': 'Alice works at Google',
|
||||||
|
'context': 'work'}, {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
agent_id (str):
|
||||||
|
items (list[MemoryItem]):
|
||||||
|
document_id (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
agent_id: str
|
||||||
|
items: list[MemoryItem]
|
||||||
|
document_id: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
items = []
|
||||||
|
for items_item_data in self.items:
|
||||||
|
items_item = items_item_data.to_dict()
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
document_id: None | str | Unset
|
||||||
|
if isinstance(self.document_id, Unset):
|
||||||
|
document_id = UNSET
|
||||||
|
else:
|
||||||
|
document_id = self.document_id
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"items": items,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if document_id is not UNSET:
|
||||||
|
field_dict["document_id"] = document_id
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.memory_item import MemoryItem
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
items = []
|
||||||
|
_items = d.pop("items")
|
||||||
|
for items_item_data in _items:
|
||||||
|
items_item = MemoryItem.from_dict(items_item_data)
|
||||||
|
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
def _parse_document_id(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
document_id = _parse_document_id(d.pop("document_id", UNSET))
|
||||||
|
|
||||||
|
batch_put_request = cls(
|
||||||
|
agent_id=agent_id,
|
||||||
|
items=items,
|
||||||
|
document_id=document_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
batch_put_request.additional_properties = d
|
||||||
|
return batch_put_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
112
memora-clients/python/models/batch_put_response.py
Normal file
112
memora-clients/python/models/batch_put_response.py
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="BatchPutResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class BatchPutResponse:
|
||||||
|
"""Response model for batch put endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'document_id': 'conversation_123', 'items_count': 2, 'message': 'Successfully stored 2
|
||||||
|
memory items', 'success': True}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
success (bool):
|
||||||
|
message (str):
|
||||||
|
agent_id (str):
|
||||||
|
items_count (int):
|
||||||
|
document_id (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
success: bool
|
||||||
|
message: str
|
||||||
|
agent_id: str
|
||||||
|
items_count: int
|
||||||
|
document_id: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
success = self.success
|
||||||
|
|
||||||
|
message = self.message
|
||||||
|
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
items_count = self.items_count
|
||||||
|
|
||||||
|
document_id: None | str | Unset
|
||||||
|
if isinstance(self.document_id, Unset):
|
||||||
|
document_id = UNSET
|
||||||
|
else:
|
||||||
|
document_id = self.document_id
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"success": success,
|
||||||
|
"message": message,
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"items_count": items_count,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if document_id is not UNSET:
|
||||||
|
field_dict["document_id"] = document_id
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
success = d.pop("success")
|
||||||
|
|
||||||
|
message = d.pop("message")
|
||||||
|
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
items_count = d.pop("items_count")
|
||||||
|
|
||||||
|
def _parse_document_id(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
document_id = _parse_document_id(d.pop("document_id", UNSET))
|
||||||
|
|
||||||
|
batch_put_response = cls(
|
||||||
|
success=success,
|
||||||
|
message=message,
|
||||||
|
agent_id=agent_id,
|
||||||
|
items_count=items_count,
|
||||||
|
document_id=document_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
batch_put_response.additional_properties = d
|
||||||
|
return batch_put_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
116
memora-clients/python/models/create_agent_request.py
Normal file
116
memora-clients/python/models/create_agent_request.py
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="CreateAgentRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class CreateAgentRequest:
|
||||||
|
"""Request model for creating/updating an agent.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'background': 'I am a creative software engineer with 10 years of experience', 'personality': {'agreeableness':
|
||||||
|
0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
personality (None | PersonalityTraits | Unset):
|
||||||
|
background (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
personality: None | PersonalityTraits | Unset = UNSET
|
||||||
|
background: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
personality: dict[str, Any] | None | Unset
|
||||||
|
if isinstance(self.personality, Unset):
|
||||||
|
personality = UNSET
|
||||||
|
elif isinstance(self.personality, PersonalityTraits):
|
||||||
|
personality = self.personality.to_dict()
|
||||||
|
else:
|
||||||
|
personality = self.personality
|
||||||
|
|
||||||
|
background: None | str | Unset
|
||||||
|
if isinstance(self.background, Unset):
|
||||||
|
background = UNSET
|
||||||
|
else:
|
||||||
|
background = self.background
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update({})
|
||||||
|
if personality is not UNSET:
|
||||||
|
field_dict["personality"] = personality
|
||||||
|
if background is not UNSET:
|
||||||
|
field_dict["background"] = background
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
|
||||||
|
def _parse_personality(data: object) -> None | PersonalityTraits | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
try:
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise TypeError()
|
||||||
|
personality_type_0 = PersonalityTraits.from_dict(data)
|
||||||
|
|
||||||
|
return personality_type_0
|
||||||
|
except (TypeError, ValueError, AttributeError, KeyError):
|
||||||
|
pass
|
||||||
|
return cast(None | PersonalityTraits | Unset, data)
|
||||||
|
|
||||||
|
personality = _parse_personality(d.pop("personality", UNSET))
|
||||||
|
|
||||||
|
def _parse_background(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
background = _parse_background(d.pop("background", UNSET))
|
||||||
|
|
||||||
|
create_agent_request = cls(
|
||||||
|
personality=personality,
|
||||||
|
background=background,
|
||||||
|
)
|
||||||
|
|
||||||
|
create_agent_request.additional_properties = d
|
||||||
|
return create_agent_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
120
memora-clients/python/models/document_response.py
Normal file
120
memora-clients/python/models/document_response.py
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="DocumentResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class DocumentResponse:
|
||||||
|
"""Response model for get document endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'content_hash': 'abc123', 'created_at': '2024-01-15T10:30:00Z', 'id': 'session_1',
|
||||||
|
'memory_unit_count': 15, 'original_text': 'Full document text here...', 'updated_at': '2024-01-15T10:30:00Z'}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
id (str):
|
||||||
|
agent_id (str):
|
||||||
|
original_text (str):
|
||||||
|
content_hash (None | str):
|
||||||
|
created_at (str):
|
||||||
|
updated_at (str):
|
||||||
|
memory_unit_count (int):
|
||||||
|
"""
|
||||||
|
|
||||||
|
id: str
|
||||||
|
agent_id: str
|
||||||
|
original_text: str
|
||||||
|
content_hash: None | str
|
||||||
|
created_at: str
|
||||||
|
updated_at: str
|
||||||
|
memory_unit_count: int
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
id = self.id
|
||||||
|
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
original_text = self.original_text
|
||||||
|
|
||||||
|
content_hash: None | str
|
||||||
|
content_hash = self.content_hash
|
||||||
|
|
||||||
|
created_at = self.created_at
|
||||||
|
|
||||||
|
updated_at = self.updated_at
|
||||||
|
|
||||||
|
memory_unit_count = self.memory_unit_count
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"id": id,
|
||||||
|
"agent_id": agent_id,
|
||||||
|
"original_text": original_text,
|
||||||
|
"content_hash": content_hash,
|
||||||
|
"created_at": created_at,
|
||||||
|
"updated_at": updated_at,
|
||||||
|
"memory_unit_count": memory_unit_count,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
id = d.pop("id")
|
||||||
|
|
||||||
|
agent_id = d.pop("agent_id")
|
||||||
|
|
||||||
|
original_text = d.pop("original_text")
|
||||||
|
|
||||||
|
def _parse_content_hash(data: object) -> None | str:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
return cast(None | str, data)
|
||||||
|
|
||||||
|
content_hash = _parse_content_hash(d.pop("content_hash"))
|
||||||
|
|
||||||
|
created_at = d.pop("created_at")
|
||||||
|
|
||||||
|
updated_at = d.pop("updated_at")
|
||||||
|
|
||||||
|
memory_unit_count = d.pop("memory_unit_count")
|
||||||
|
|
||||||
|
document_response = cls(
|
||||||
|
id=id,
|
||||||
|
agent_id=agent_id,
|
||||||
|
original_text=original_text,
|
||||||
|
content_hash=content_hash,
|
||||||
|
created_at=created_at,
|
||||||
|
updated_at=updated_at,
|
||||||
|
memory_unit_count=memory_unit_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
document_response.additional_properties = d
|
||||||
|
return document_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
126
memora-clients/python/models/graph_data_response.py
Normal file
126
memora-clients/python/models/graph_data_response.py
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.graph_data_response_edges_item import GraphDataResponseEdgesItem
|
||||||
|
from ..models.graph_data_response_nodes_item import GraphDataResponseNodesItem
|
||||||
|
from ..models.graph_data_response_table_rows_item import GraphDataResponseTableRowsItem
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="GraphDataResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class GraphDataResponse:
|
||||||
|
"""Response model for graph data endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'edges': [{'from': '1', 'to': '2', 'type': 'semantic', 'weight': 0.8}], 'nodes': [{'id': '1', 'label': 'Alice
|
||||||
|
works at Google', 'type': 'world'}, {'id': '2', 'label': 'Bob went hiking', 'type': 'world'}], 'table_rows':
|
||||||
|
[{'context': 'Work info', 'date': '2024-01-15 10:30', 'entities': 'Alice (PERSON), Google (ORGANIZATION)', 'id':
|
||||||
|
'abc12345...', 'text': 'Alice works at Google'}], 'total_units': 2}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
nodes (list[GraphDataResponseNodesItem]):
|
||||||
|
edges (list[GraphDataResponseEdgesItem]):
|
||||||
|
table_rows (list[GraphDataResponseTableRowsItem]):
|
||||||
|
total_units (int):
|
||||||
|
"""
|
||||||
|
|
||||||
|
nodes: list[GraphDataResponseNodesItem]
|
||||||
|
edges: list[GraphDataResponseEdgesItem]
|
||||||
|
table_rows: list[GraphDataResponseTableRowsItem]
|
||||||
|
total_units: int
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
nodes = []
|
||||||
|
for nodes_item_data in self.nodes:
|
||||||
|
nodes_item = nodes_item_data.to_dict()
|
||||||
|
nodes.append(nodes_item)
|
||||||
|
|
||||||
|
edges = []
|
||||||
|
for edges_item_data in self.edges:
|
||||||
|
edges_item = edges_item_data.to_dict()
|
||||||
|
edges.append(edges_item)
|
||||||
|
|
||||||
|
table_rows = []
|
||||||
|
for table_rows_item_data in self.table_rows:
|
||||||
|
table_rows_item = table_rows_item_data.to_dict()
|
||||||
|
table_rows.append(table_rows_item)
|
||||||
|
|
||||||
|
total_units = self.total_units
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"nodes": nodes,
|
||||||
|
"edges": edges,
|
||||||
|
"table_rows": table_rows,
|
||||||
|
"total_units": total_units,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.graph_data_response_edges_item import GraphDataResponseEdgesItem
|
||||||
|
from ..models.graph_data_response_nodes_item import GraphDataResponseNodesItem
|
||||||
|
from ..models.graph_data_response_table_rows_item import GraphDataResponseTableRowsItem
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
nodes = []
|
||||||
|
_nodes = d.pop("nodes")
|
||||||
|
for nodes_item_data in _nodes:
|
||||||
|
nodes_item = GraphDataResponseNodesItem.from_dict(nodes_item_data)
|
||||||
|
|
||||||
|
nodes.append(nodes_item)
|
||||||
|
|
||||||
|
edges = []
|
||||||
|
_edges = d.pop("edges")
|
||||||
|
for edges_item_data in _edges:
|
||||||
|
edges_item = GraphDataResponseEdgesItem.from_dict(edges_item_data)
|
||||||
|
|
||||||
|
edges.append(edges_item)
|
||||||
|
|
||||||
|
table_rows = []
|
||||||
|
_table_rows = d.pop("table_rows")
|
||||||
|
for table_rows_item_data in _table_rows:
|
||||||
|
table_rows_item = GraphDataResponseTableRowsItem.from_dict(table_rows_item_data)
|
||||||
|
|
||||||
|
table_rows.append(table_rows_item)
|
||||||
|
|
||||||
|
total_units = d.pop("total_units")
|
||||||
|
|
||||||
|
graph_data_response = cls(
|
||||||
|
nodes=nodes,
|
||||||
|
edges=edges,
|
||||||
|
table_rows=table_rows,
|
||||||
|
total_units=total_units,
|
||||||
|
)
|
||||||
|
|
||||||
|
graph_data_response.additional_properties = d
|
||||||
|
return graph_data_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="GraphDataResponseEdgesItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class GraphDataResponseEdgesItem:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
graph_data_response_edges_item = cls()
|
||||||
|
|
||||||
|
graph_data_response_edges_item.additional_properties = d
|
||||||
|
return graph_data_response_edges_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="GraphDataResponseNodesItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class GraphDataResponseNodesItem:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
graph_data_response_nodes_item = cls()
|
||||||
|
|
||||||
|
graph_data_response_nodes_item.additional_properties = d
|
||||||
|
return graph_data_response_nodes_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="GraphDataResponseTableRowsItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class GraphDataResponseTableRowsItem:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
graph_data_response_table_rows_item = cls()
|
||||||
|
|
||||||
|
graph_data_response_table_rows_item.additional_properties = d
|
||||||
|
return graph_data_response_table_rows_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
79
memora-clients/python/models/http_validation_error.py
Normal file
79
memora-clients/python/models/http_validation_error.py
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.validation_error import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="HTTPValidationError")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class HTTPValidationError:
|
||||||
|
"""
|
||||||
|
Attributes:
|
||||||
|
detail (list[ValidationError] | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
detail: list[ValidationError] | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
detail: list[dict[str, Any]] | Unset = UNSET
|
||||||
|
if not isinstance(self.detail, Unset):
|
||||||
|
detail = []
|
||||||
|
for detail_item_data in self.detail:
|
||||||
|
detail_item = detail_item_data.to_dict()
|
||||||
|
detail.append(detail_item)
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update({})
|
||||||
|
if detail is not UNSET:
|
||||||
|
field_dict["detail"] = detail
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.validation_error import ValidationError
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
_detail = d.pop("detail", UNSET)
|
||||||
|
detail: list[ValidationError] | Unset = UNSET
|
||||||
|
if _detail is not UNSET:
|
||||||
|
detail = []
|
||||||
|
for detail_item_data in _detail:
|
||||||
|
detail_item = ValidationError.from_dict(detail_item_data)
|
||||||
|
|
||||||
|
detail.append(detail_item)
|
||||||
|
|
||||||
|
http_validation_error = cls(
|
||||||
|
detail=detail,
|
||||||
|
)
|
||||||
|
|
||||||
|
http_validation_error.additional_properties = d
|
||||||
|
return http_validation_error
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
105
memora-clients/python/models/list_documents_response.py
Normal file
105
memora-clients/python/models/list_documents_response.py
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.list_documents_response_items_item import ListDocumentsResponseItemsItem
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ListDocumentsResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ListDocumentsResponse:
|
||||||
|
"""Response model for list documents endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'items': [{'agent_id': 'user123', 'content_hash': 'abc123', 'created_at': '2024-01-15T10:30:00Z', 'id':
|
||||||
|
'session_1', 'memory_unit_count': 15, 'text_length': 5420, 'updated_at': '2024-01-15T10:30:00Z'}], 'limit': 100,
|
||||||
|
'offset': 0, 'total': 50}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
items (list[ListDocumentsResponseItemsItem]):
|
||||||
|
total (int):
|
||||||
|
limit (int):
|
||||||
|
offset (int):
|
||||||
|
"""
|
||||||
|
|
||||||
|
items: list[ListDocumentsResponseItemsItem]
|
||||||
|
total: int
|
||||||
|
limit: int
|
||||||
|
offset: int
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
items = []
|
||||||
|
for items_item_data in self.items:
|
||||||
|
items_item = items_item_data.to_dict()
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
total = self.total
|
||||||
|
|
||||||
|
limit = self.limit
|
||||||
|
|
||||||
|
offset = self.offset
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"limit": limit,
|
||||||
|
"offset": offset,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.list_documents_response_items_item import ListDocumentsResponseItemsItem
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
items = []
|
||||||
|
_items = d.pop("items")
|
||||||
|
for items_item_data in _items:
|
||||||
|
items_item = ListDocumentsResponseItemsItem.from_dict(items_item_data)
|
||||||
|
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
total = d.pop("total")
|
||||||
|
|
||||||
|
limit = d.pop("limit")
|
||||||
|
|
||||||
|
offset = d.pop("offset")
|
||||||
|
|
||||||
|
list_documents_response = cls(
|
||||||
|
items=items,
|
||||||
|
total=total,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
list_documents_response.additional_properties = d
|
||||||
|
return list_documents_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ListDocumentsResponseItemsItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ListDocumentsResponseItemsItem:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
list_documents_response_items_item = cls()
|
||||||
|
|
||||||
|
list_documents_response_items_item.additional_properties = d
|
||||||
|
return list_documents_response_items_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
105
memora-clients/python/models/list_memory_units_response.py
Normal file
105
memora-clients/python/models/list_memory_units_response.py
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ListMemoryUnitsResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ListMemoryUnitsResponse:
|
||||||
|
"""Response model for list memory units endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'items': [{'context': 'Work conversation', 'date': '2024-01-15T10:30:00Z', 'entities': 'Alice (PERSON), Google
|
||||||
|
(ORGANIZATION)', 'fact_type': 'world', 'id': '550e8400-e29b-41d4-a716-446655440000', 'text': 'Alice works at
|
||||||
|
Google on the AI team'}], 'limit': 100, 'offset': 0, 'total': 150}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
items (list[ListMemoryUnitsResponseItemsItem]):
|
||||||
|
total (int):
|
||||||
|
limit (int):
|
||||||
|
offset (int):
|
||||||
|
"""
|
||||||
|
|
||||||
|
items: list[ListMemoryUnitsResponseItemsItem]
|
||||||
|
total: int
|
||||||
|
limit: int
|
||||||
|
offset: int
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
items = []
|
||||||
|
for items_item_data in self.items:
|
||||||
|
items_item = items_item_data.to_dict()
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
total = self.total
|
||||||
|
|
||||||
|
limit = self.limit
|
||||||
|
|
||||||
|
offset = self.offset
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"items": items,
|
||||||
|
"total": total,
|
||||||
|
"limit": limit,
|
||||||
|
"offset": offset,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
items = []
|
||||||
|
_items = d.pop("items")
|
||||||
|
for items_item_data in _items:
|
||||||
|
items_item = ListMemoryUnitsResponseItemsItem.from_dict(items_item_data)
|
||||||
|
|
||||||
|
items.append(items_item)
|
||||||
|
|
||||||
|
total = d.pop("total")
|
||||||
|
|
||||||
|
limit = d.pop("limit")
|
||||||
|
|
||||||
|
offset = d.pop("offset")
|
||||||
|
|
||||||
|
list_memory_units_response = cls(
|
||||||
|
items=items,
|
||||||
|
total=total,
|
||||||
|
limit=limit,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
|
|
||||||
|
list_memory_units_response.additional_properties = d
|
||||||
|
return list_memory_units_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ListMemoryUnitsResponseItemsItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ListMemoryUnitsResponseItemsItem:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
list_memory_units_response_items_item = cls()
|
||||||
|
|
||||||
|
list_memory_units_response_items_item.additional_properties = d
|
||||||
|
return list_memory_units_response_items_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
120
memora-clients/python/models/memory_item.py
Normal file
120
memora-clients/python/models/memory_item.py
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="MemoryItem")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class MemoryItem:
|
||||||
|
"""Single memory item for batch put.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'content': "Alice mentioned she's working on a new ML model", 'context': 'team meeting', 'event_date':
|
||||||
|
'2024-01-15T10:30:00Z'}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
content (str):
|
||||||
|
event_date (datetime.datetime | None | Unset):
|
||||||
|
context (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
content: str
|
||||||
|
event_date: datetime.datetime | None | Unset = UNSET
|
||||||
|
context: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
content = self.content
|
||||||
|
|
||||||
|
event_date: None | str | Unset
|
||||||
|
if isinstance(self.event_date, Unset):
|
||||||
|
event_date = UNSET
|
||||||
|
elif isinstance(self.event_date, datetime.datetime):
|
||||||
|
event_date = self.event_date.isoformat()
|
||||||
|
else:
|
||||||
|
event_date = self.event_date
|
||||||
|
|
||||||
|
context: None | str | Unset
|
||||||
|
if isinstance(self.context, Unset):
|
||||||
|
context = UNSET
|
||||||
|
else:
|
||||||
|
context = self.context
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"content": content,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if event_date is not UNSET:
|
||||||
|
field_dict["event_date"] = event_date
|
||||||
|
if context is not UNSET:
|
||||||
|
field_dict["context"] = context
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
content = d.pop("content")
|
||||||
|
|
||||||
|
def _parse_event_date(data: object) -> datetime.datetime | None | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
try:
|
||||||
|
if not isinstance(data, str):
|
||||||
|
raise TypeError()
|
||||||
|
event_date_type_0 = isoparse(data)
|
||||||
|
|
||||||
|
return event_date_type_0
|
||||||
|
except (TypeError, ValueError, AttributeError, KeyError):
|
||||||
|
pass
|
||||||
|
return cast(datetime.datetime | None | Unset, data)
|
||||||
|
|
||||||
|
event_date = _parse_event_date(d.pop("event_date", UNSET))
|
||||||
|
|
||||||
|
def _parse_context(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
context = _parse_context(d.pop("context", UNSET))
|
||||||
|
|
||||||
|
memory_item = cls(
|
||||||
|
content=content,
|
||||||
|
event_date=event_date,
|
||||||
|
context=context,
|
||||||
|
)
|
||||||
|
|
||||||
|
memory_item.additional_properties = d
|
||||||
|
return memory_item
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
106
memora-clients/python/models/personality_traits.py
Normal file
106
memora-clients/python/models/personality_traits.py
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="PersonalityTraits")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class PersonalityTraits:
|
||||||
|
"""Personality traits based on Big Five model.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3,
|
||||||
|
'openness': 0.8}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
openness (float): Openness to experience (0-1)
|
||||||
|
conscientiousness (float): Conscientiousness (0-1)
|
||||||
|
extraversion (float): Extraversion (0-1)
|
||||||
|
agreeableness (float): Agreeableness (0-1)
|
||||||
|
neuroticism (float): Neuroticism (0-1)
|
||||||
|
bias_strength (float): How strongly personality influences opinions (0-1)
|
||||||
|
"""
|
||||||
|
|
||||||
|
openness: float
|
||||||
|
conscientiousness: float
|
||||||
|
extraversion: float
|
||||||
|
agreeableness: float
|
||||||
|
neuroticism: float
|
||||||
|
bias_strength: float
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
openness = self.openness
|
||||||
|
|
||||||
|
conscientiousness = self.conscientiousness
|
||||||
|
|
||||||
|
extraversion = self.extraversion
|
||||||
|
|
||||||
|
agreeableness = self.agreeableness
|
||||||
|
|
||||||
|
neuroticism = self.neuroticism
|
||||||
|
|
||||||
|
bias_strength = self.bias_strength
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"openness": openness,
|
||||||
|
"conscientiousness": conscientiousness,
|
||||||
|
"extraversion": extraversion,
|
||||||
|
"agreeableness": agreeableness,
|
||||||
|
"neuroticism": neuroticism,
|
||||||
|
"bias_strength": bias_strength,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
openness = d.pop("openness")
|
||||||
|
|
||||||
|
conscientiousness = d.pop("conscientiousness")
|
||||||
|
|
||||||
|
extraversion = d.pop("extraversion")
|
||||||
|
|
||||||
|
agreeableness = d.pop("agreeableness")
|
||||||
|
|
||||||
|
neuroticism = d.pop("neuroticism")
|
||||||
|
|
||||||
|
bias_strength = d.pop("bias_strength")
|
||||||
|
|
||||||
|
personality_traits = cls(
|
||||||
|
openness=openness,
|
||||||
|
conscientiousness=conscientiousness,
|
||||||
|
extraversion=extraversion,
|
||||||
|
agreeableness=agreeableness,
|
||||||
|
neuroticism=neuroticism,
|
||||||
|
bias_strength=bias_strength,
|
||||||
|
)
|
||||||
|
|
||||||
|
personality_traits.additional_properties = d
|
||||||
|
return personality_traits
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
165
memora-clients/python/models/search_request.py
Normal file
165
memora-clients/python/models/search_request.py
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="SearchRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class SearchRequest:
|
||||||
|
"""Request model for search endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about
|
||||||
|
machine learning?', 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100,
|
||||||
|
'trace': True}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
query (str):
|
||||||
|
fact_type (list[str] | None | Unset):
|
||||||
|
agent_id (str | Unset): Default: 'default'.
|
||||||
|
thinking_budget (int | Unset): Default: 100.
|
||||||
|
max_tokens (int | Unset): Default: 4096.
|
||||||
|
reranker (str | Unset): Default: 'heuristic'.
|
||||||
|
trace (bool | Unset): Default: False.
|
||||||
|
question_date (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
query: str
|
||||||
|
fact_type: list[str] | None | Unset = UNSET
|
||||||
|
agent_id: str | Unset = "default"
|
||||||
|
thinking_budget: int | Unset = 100
|
||||||
|
max_tokens: int | Unset = 4096
|
||||||
|
reranker: str | Unset = "heuristic"
|
||||||
|
trace: bool | Unset = False
|
||||||
|
question_date: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
query = self.query
|
||||||
|
|
||||||
|
fact_type: list[str] | None | Unset
|
||||||
|
if isinstance(self.fact_type, Unset):
|
||||||
|
fact_type = UNSET
|
||||||
|
elif isinstance(self.fact_type, list):
|
||||||
|
fact_type = self.fact_type
|
||||||
|
|
||||||
|
else:
|
||||||
|
fact_type = self.fact_type
|
||||||
|
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
thinking_budget = self.thinking_budget
|
||||||
|
|
||||||
|
max_tokens = self.max_tokens
|
||||||
|
|
||||||
|
reranker = self.reranker
|
||||||
|
|
||||||
|
trace = self.trace
|
||||||
|
|
||||||
|
question_date: None | str | Unset
|
||||||
|
if isinstance(self.question_date, Unset):
|
||||||
|
question_date = UNSET
|
||||||
|
else:
|
||||||
|
question_date = self.question_date
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"query": query,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if fact_type is not UNSET:
|
||||||
|
field_dict["fact_type"] = fact_type
|
||||||
|
if agent_id is not UNSET:
|
||||||
|
field_dict["agent_id"] = agent_id
|
||||||
|
if thinking_budget is not UNSET:
|
||||||
|
field_dict["thinking_budget"] = thinking_budget
|
||||||
|
if max_tokens is not UNSET:
|
||||||
|
field_dict["max_tokens"] = max_tokens
|
||||||
|
if reranker is not UNSET:
|
||||||
|
field_dict["reranker"] = reranker
|
||||||
|
if trace is not UNSET:
|
||||||
|
field_dict["trace"] = trace
|
||||||
|
if question_date is not UNSET:
|
||||||
|
field_dict["question_date"] = question_date
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
query = d.pop("query")
|
||||||
|
|
||||||
|
def _parse_fact_type(data: object) -> list[str] | None | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
try:
|
||||||
|
if not isinstance(data, list):
|
||||||
|
raise TypeError()
|
||||||
|
fact_type_type_0 = cast(list[str], data)
|
||||||
|
|
||||||
|
return fact_type_type_0
|
||||||
|
except (TypeError, ValueError, AttributeError, KeyError):
|
||||||
|
pass
|
||||||
|
return cast(list[str] | None | Unset, data)
|
||||||
|
|
||||||
|
fact_type = _parse_fact_type(d.pop("fact_type", UNSET))
|
||||||
|
|
||||||
|
agent_id = d.pop("agent_id", UNSET)
|
||||||
|
|
||||||
|
thinking_budget = d.pop("thinking_budget", UNSET)
|
||||||
|
|
||||||
|
max_tokens = d.pop("max_tokens", UNSET)
|
||||||
|
|
||||||
|
reranker = d.pop("reranker", UNSET)
|
||||||
|
|
||||||
|
trace = d.pop("trace", UNSET)
|
||||||
|
|
||||||
|
def _parse_question_date(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
question_date = _parse_question_date(d.pop("question_date", UNSET))
|
||||||
|
|
||||||
|
search_request = cls(
|
||||||
|
query=query,
|
||||||
|
fact_type=fact_type,
|
||||||
|
agent_id=agent_id,
|
||||||
|
thinking_budget=thinking_budget,
|
||||||
|
max_tokens=max_tokens,
|
||||||
|
reranker=reranker,
|
||||||
|
trace=trace,
|
||||||
|
question_date=question_date,
|
||||||
|
)
|
||||||
|
|
||||||
|
search_request.additional_properties = d
|
||||||
|
return search_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
117
memora-clients/python/models/search_response.py
Normal file
117
memora-clients/python/models/search_response.py
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.search_response_trace_type_0 import SearchResponseTraceType0
|
||||||
|
from ..models.search_result import SearchResult
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="SearchResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class SearchResponse:
|
||||||
|
"""Response model for search endpoints.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'results': [{'activation': 0.95, 'context': 'work info', 'event_date': '2024-01-15T10:30:00Z', 'id':
|
||||||
|
'123e4567-e89b-12d3-a456-426614174000', 'text': 'Alice works at Google on the AI team', 'type': 'world'}],
|
||||||
|
'trace': {'num_results': 1, 'query': 'What did Alice say about machine learning?', 'time_seconds': 0.123}}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
results (list[SearchResult]):
|
||||||
|
trace (None | SearchResponseTraceType0 | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
results: list[SearchResult]
|
||||||
|
trace: None | SearchResponseTraceType0 | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
from ..models.search_response_trace_type_0 import SearchResponseTraceType0
|
||||||
|
|
||||||
|
results = []
|
||||||
|
for results_item_data in self.results:
|
||||||
|
results_item = results_item_data.to_dict()
|
||||||
|
results.append(results_item)
|
||||||
|
|
||||||
|
trace: dict[str, Any] | None | Unset
|
||||||
|
if isinstance(self.trace, Unset):
|
||||||
|
trace = UNSET
|
||||||
|
elif isinstance(self.trace, SearchResponseTraceType0):
|
||||||
|
trace = self.trace.to_dict()
|
||||||
|
else:
|
||||||
|
trace = self.trace
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"results": results,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if trace is not UNSET:
|
||||||
|
field_dict["trace"] = trace
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.search_response_trace_type_0 import SearchResponseTraceType0
|
||||||
|
from ..models.search_result import SearchResult
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
results = []
|
||||||
|
_results = d.pop("results")
|
||||||
|
for results_item_data in _results:
|
||||||
|
results_item = SearchResult.from_dict(results_item_data)
|
||||||
|
|
||||||
|
results.append(results_item)
|
||||||
|
|
||||||
|
def _parse_trace(data: object) -> None | SearchResponseTraceType0 | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
try:
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise TypeError()
|
||||||
|
trace_type_0 = SearchResponseTraceType0.from_dict(data)
|
||||||
|
|
||||||
|
return trace_type_0
|
||||||
|
except (TypeError, ValueError, AttributeError, KeyError):
|
||||||
|
pass
|
||||||
|
return cast(None | SearchResponseTraceType0 | Unset, data)
|
||||||
|
|
||||||
|
trace = _parse_trace(d.pop("trace", UNSET))
|
||||||
|
|
||||||
|
search_response = cls(
|
||||||
|
results=results,
|
||||||
|
trace=trace,
|
||||||
|
)
|
||||||
|
|
||||||
|
search_response.additional_properties = d
|
||||||
|
return search_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
46
memora-clients/python/models/search_response_trace_type_0.py
Normal file
46
memora-clients/python/models/search_response_trace_type_0.py
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="SearchResponseTraceType0")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class SearchResponseTraceType0:
|
||||||
|
""" """
|
||||||
|
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
search_response_trace_type_0 = cls()
|
||||||
|
|
||||||
|
search_response_trace_type_0.additional_properties = d
|
||||||
|
return search_response_trace_type_0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
156
memora-clients/python/models/search_result.py
Normal file
156
memora-clients/python/models/search_result.py
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="SearchResult")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class SearchResult:
|
||||||
|
"""Single search result item.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'context': 'work info', 'event_date': '2024-01-15T10:30:00Z', 'id': '123e4567-e89b-12d3-a456-426614174000',
|
||||||
|
'text': 'Alice works at Google on the AI team', 'type': 'world'}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
id (str):
|
||||||
|
text (str):
|
||||||
|
type_ (None | str | Unset):
|
||||||
|
activation (float | None | Unset):
|
||||||
|
context (None | str | Unset):
|
||||||
|
event_date (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
id: str
|
||||||
|
text: str
|
||||||
|
type_: None | str | Unset = UNSET
|
||||||
|
activation: float | None | Unset = UNSET
|
||||||
|
context: None | str | Unset = UNSET
|
||||||
|
event_date: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
id = self.id
|
||||||
|
|
||||||
|
text = self.text
|
||||||
|
|
||||||
|
type_: None | str | Unset
|
||||||
|
if isinstance(self.type_, Unset):
|
||||||
|
type_ = UNSET
|
||||||
|
else:
|
||||||
|
type_ = self.type_
|
||||||
|
|
||||||
|
activation: float | None | Unset
|
||||||
|
if isinstance(self.activation, Unset):
|
||||||
|
activation = UNSET
|
||||||
|
else:
|
||||||
|
activation = self.activation
|
||||||
|
|
||||||
|
context: None | str | Unset
|
||||||
|
if isinstance(self.context, Unset):
|
||||||
|
context = UNSET
|
||||||
|
else:
|
||||||
|
context = self.context
|
||||||
|
|
||||||
|
event_date: None | str | Unset
|
||||||
|
if isinstance(self.event_date, Unset):
|
||||||
|
event_date = UNSET
|
||||||
|
else:
|
||||||
|
event_date = self.event_date
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"id": id,
|
||||||
|
"text": text,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if type_ is not UNSET:
|
||||||
|
field_dict["type"] = type_
|
||||||
|
if activation is not UNSET:
|
||||||
|
field_dict["activation"] = activation
|
||||||
|
if context is not UNSET:
|
||||||
|
field_dict["context"] = context
|
||||||
|
if event_date is not UNSET:
|
||||||
|
field_dict["event_date"] = event_date
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
id = d.pop("id")
|
||||||
|
|
||||||
|
text = d.pop("text")
|
||||||
|
|
||||||
|
def _parse_type_(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
type_ = _parse_type_(d.pop("type", UNSET))
|
||||||
|
|
||||||
|
def _parse_activation(data: object) -> float | None | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(float | None | Unset, data)
|
||||||
|
|
||||||
|
activation = _parse_activation(d.pop("activation", UNSET))
|
||||||
|
|
||||||
|
def _parse_context(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
context = _parse_context(d.pop("context", UNSET))
|
||||||
|
|
||||||
|
def _parse_event_date(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
event_date = _parse_event_date(d.pop("event_date", UNSET))
|
||||||
|
|
||||||
|
search_result = cls(
|
||||||
|
id=id,
|
||||||
|
text=text,
|
||||||
|
type_=type_,
|
||||||
|
activation=activation,
|
||||||
|
context=context,
|
||||||
|
event_date=event_date,
|
||||||
|
)
|
||||||
|
|
||||||
|
search_result.additional_properties = d
|
||||||
|
return search_result
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
168
memora-clients/python/models/think_fact.py
Normal file
168
memora-clients/python/models/think_fact.py
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ThinkFact")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ThinkFact:
|
||||||
|
"""A fact used in think response.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'context': 'healthcare discussion', 'event_date': '2024-01-15T10:30:00Z', 'id':
|
||||||
|
'123e4567-e89b-12d3-a456-426614174000', 'text': 'AI is used in healthcare', 'type': 'world'}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
text (str):
|
||||||
|
id (None | str | Unset):
|
||||||
|
type_ (None | str | Unset):
|
||||||
|
activation (float | None | Unset):
|
||||||
|
context (None | str | Unset):
|
||||||
|
event_date (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
text: str
|
||||||
|
id: None | str | Unset = UNSET
|
||||||
|
type_: None | str | Unset = UNSET
|
||||||
|
activation: float | None | Unset = UNSET
|
||||||
|
context: None | str | Unset = UNSET
|
||||||
|
event_date: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
text = self.text
|
||||||
|
|
||||||
|
id: None | str | Unset
|
||||||
|
if isinstance(self.id, Unset):
|
||||||
|
id = UNSET
|
||||||
|
else:
|
||||||
|
id = self.id
|
||||||
|
|
||||||
|
type_: None | str | Unset
|
||||||
|
if isinstance(self.type_, Unset):
|
||||||
|
type_ = UNSET
|
||||||
|
else:
|
||||||
|
type_ = self.type_
|
||||||
|
|
||||||
|
activation: float | None | Unset
|
||||||
|
if isinstance(self.activation, Unset):
|
||||||
|
activation = UNSET
|
||||||
|
else:
|
||||||
|
activation = self.activation
|
||||||
|
|
||||||
|
context: None | str | Unset
|
||||||
|
if isinstance(self.context, Unset):
|
||||||
|
context = UNSET
|
||||||
|
else:
|
||||||
|
context = self.context
|
||||||
|
|
||||||
|
event_date: None | str | Unset
|
||||||
|
if isinstance(self.event_date, Unset):
|
||||||
|
event_date = UNSET
|
||||||
|
else:
|
||||||
|
event_date = self.event_date
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"text": text,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if id is not UNSET:
|
||||||
|
field_dict["id"] = id
|
||||||
|
if type_ is not UNSET:
|
||||||
|
field_dict["type"] = type_
|
||||||
|
if activation is not UNSET:
|
||||||
|
field_dict["activation"] = activation
|
||||||
|
if context is not UNSET:
|
||||||
|
field_dict["context"] = context
|
||||||
|
if event_date is not UNSET:
|
||||||
|
field_dict["event_date"] = event_date
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
text = d.pop("text")
|
||||||
|
|
||||||
|
def _parse_id(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
id = _parse_id(d.pop("id", UNSET))
|
||||||
|
|
||||||
|
def _parse_type_(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
type_ = _parse_type_(d.pop("type", UNSET))
|
||||||
|
|
||||||
|
def _parse_activation(data: object) -> float | None | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(float | None | Unset, data)
|
||||||
|
|
||||||
|
activation = _parse_activation(d.pop("activation", UNSET))
|
||||||
|
|
||||||
|
def _parse_context(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
context = _parse_context(d.pop("context", UNSET))
|
||||||
|
|
||||||
|
def _parse_event_date(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
event_date = _parse_event_date(d.pop("event_date", UNSET))
|
||||||
|
|
||||||
|
think_fact = cls(
|
||||||
|
text=text,
|
||||||
|
id=id,
|
||||||
|
type_=type_,
|
||||||
|
activation=activation,
|
||||||
|
context=context,
|
||||||
|
event_date=event_date,
|
||||||
|
)
|
||||||
|
|
||||||
|
think_fact.additional_properties = d
|
||||||
|
return think_fact
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
106
memora-clients/python/models/think_request.py
Normal file
106
memora-clients/python/models/think_request.py
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ThinkRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ThinkRequest:
|
||||||
|
"""Request model for think endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'agent_id': 'user123', 'context': 'This is for a research paper on AI ethics', 'query': 'What do you think
|
||||||
|
about artificial intelligence?', 'thinking_budget': 50}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
query (str):
|
||||||
|
agent_id (str | Unset): Default: 'default'.
|
||||||
|
thinking_budget (int | Unset): Default: 50.
|
||||||
|
context (None | str | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
query: str
|
||||||
|
agent_id: str | Unset = "default"
|
||||||
|
thinking_budget: int | Unset = 50
|
||||||
|
context: None | str | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
query = self.query
|
||||||
|
|
||||||
|
agent_id = self.agent_id
|
||||||
|
|
||||||
|
thinking_budget = self.thinking_budget
|
||||||
|
|
||||||
|
context: None | str | Unset
|
||||||
|
if isinstance(self.context, Unset):
|
||||||
|
context = UNSET
|
||||||
|
else:
|
||||||
|
context = self.context
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"query": query,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if agent_id is not UNSET:
|
||||||
|
field_dict["agent_id"] = agent_id
|
||||||
|
if thinking_budget is not UNSET:
|
||||||
|
field_dict["thinking_budget"] = thinking_budget
|
||||||
|
if context is not UNSET:
|
||||||
|
field_dict["context"] = context
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
query = d.pop("query")
|
||||||
|
|
||||||
|
agent_id = d.pop("agent_id", UNSET)
|
||||||
|
|
||||||
|
thinking_budget = d.pop("thinking_budget", UNSET)
|
||||||
|
|
||||||
|
def _parse_context(data: object) -> None | str | Unset:
|
||||||
|
if data is None:
|
||||||
|
return data
|
||||||
|
if isinstance(data, Unset):
|
||||||
|
return data
|
||||||
|
return cast(None | str | Unset, data)
|
||||||
|
|
||||||
|
context = _parse_context(d.pop("context", UNSET))
|
||||||
|
|
||||||
|
think_request = cls(
|
||||||
|
query=query,
|
||||||
|
agent_id=agent_id,
|
||||||
|
thinking_budget=thinking_budget,
|
||||||
|
context=context,
|
||||||
|
)
|
||||||
|
|
||||||
|
think_request.additional_properties = d
|
||||||
|
return think_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
108
memora-clients/python/models/think_response.py
Normal file
108
memora-clients/python/models/think_response.py
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
from ..types import UNSET, Unset
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.think_fact import ThinkFact
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ThinkResponse")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ThinkResponse:
|
||||||
|
"""Response model for think endpoint.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{'based_on': [{'activation': 0.9, 'id': '123', 'text': 'AI is used in healthcare', 'type': 'world'},
|
||||||
|
{'activation': 0.85, 'id': '456', 'text': 'I discussed AI applications last week', 'type': 'agent'}],
|
||||||
|
'new_opinions': ['AI has great potential when used responsibly'], 'text': 'Based on my understanding, AI is a
|
||||||
|
transformative technology...'}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
text (str):
|
||||||
|
based_on (list[ThinkFact] | Unset):
|
||||||
|
new_opinions (list[str] | Unset):
|
||||||
|
"""
|
||||||
|
|
||||||
|
text: str
|
||||||
|
based_on: list[ThinkFact] | Unset = UNSET
|
||||||
|
new_opinions: list[str] | Unset = UNSET
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
text = self.text
|
||||||
|
|
||||||
|
based_on: list[dict[str, Any]] | Unset = UNSET
|
||||||
|
if not isinstance(self.based_on, Unset):
|
||||||
|
based_on = []
|
||||||
|
for based_on_item_data in self.based_on:
|
||||||
|
based_on_item = based_on_item_data.to_dict()
|
||||||
|
based_on.append(based_on_item)
|
||||||
|
|
||||||
|
new_opinions: list[str] | Unset = UNSET
|
||||||
|
if not isinstance(self.new_opinions, Unset):
|
||||||
|
new_opinions = self.new_opinions
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"text": text,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if based_on is not UNSET:
|
||||||
|
field_dict["based_on"] = based_on
|
||||||
|
if new_opinions is not UNSET:
|
||||||
|
field_dict["new_opinions"] = new_opinions
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.think_fact import ThinkFact
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
text = d.pop("text")
|
||||||
|
|
||||||
|
_based_on = d.pop("based_on", UNSET)
|
||||||
|
based_on: list[ThinkFact] | Unset = UNSET
|
||||||
|
if _based_on is not UNSET:
|
||||||
|
based_on = []
|
||||||
|
for based_on_item_data in _based_on:
|
||||||
|
based_on_item = ThinkFact.from_dict(based_on_item_data)
|
||||||
|
|
||||||
|
based_on.append(based_on_item)
|
||||||
|
|
||||||
|
new_opinions = cast(list[str], d.pop("new_opinions", UNSET))
|
||||||
|
|
||||||
|
think_response = cls(
|
||||||
|
text=text,
|
||||||
|
based_on=based_on,
|
||||||
|
new_opinions=new_opinions,
|
||||||
|
)
|
||||||
|
|
||||||
|
think_response.additional_properties = d
|
||||||
|
return think_response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
69
memora-clients/python/models/update_personality_request.py
Normal file
69
memora-clients/python/models/update_personality_request.py
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import TYPE_CHECKING, Any, TypeVar
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="UpdatePersonalityRequest")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class UpdatePersonalityRequest:
|
||||||
|
"""Request model for updating personality traits.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7,
|
||||||
|
'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}.
|
||||||
|
"""
|
||||||
|
|
||||||
|
personality: PersonalityTraits
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
personality = self.personality.to_dict()
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"personality": personality,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
from ..models.personality_traits import PersonalityTraits
|
||||||
|
|
||||||
|
d = dict(src_dict)
|
||||||
|
personality = PersonalityTraits.from_dict(d.pop("personality"))
|
||||||
|
|
||||||
|
update_personality_request = cls(
|
||||||
|
personality=personality,
|
||||||
|
)
|
||||||
|
|
||||||
|
update_personality_request.additional_properties = d
|
||||||
|
return update_personality_request
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
90
memora-clients/python/models/validation_error.py
Normal file
90
memora-clients/python/models/validation_error.py
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, TypeVar, cast
|
||||||
|
|
||||||
|
from attrs import define as _attrs_define
|
||||||
|
from attrs import field as _attrs_field
|
||||||
|
|
||||||
|
T = TypeVar("T", bound="ValidationError")
|
||||||
|
|
||||||
|
|
||||||
|
@_attrs_define
|
||||||
|
class ValidationError:
|
||||||
|
"""
|
||||||
|
Attributes:
|
||||||
|
loc (list[int | str]):
|
||||||
|
msg (str):
|
||||||
|
type_ (str):
|
||||||
|
"""
|
||||||
|
|
||||||
|
loc: list[int | str]
|
||||||
|
msg: str
|
||||||
|
type_: str
|
||||||
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
loc = []
|
||||||
|
for loc_item_data in self.loc:
|
||||||
|
loc_item: int | str
|
||||||
|
loc_item = loc_item_data
|
||||||
|
loc.append(loc_item)
|
||||||
|
|
||||||
|
msg = self.msg
|
||||||
|
|
||||||
|
type_ = self.type_
|
||||||
|
|
||||||
|
field_dict: dict[str, Any] = {}
|
||||||
|
field_dict.update(self.additional_properties)
|
||||||
|
field_dict.update(
|
||||||
|
{
|
||||||
|
"loc": loc,
|
||||||
|
"msg": msg,
|
||||||
|
"type": type_,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return field_dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
|
||||||
|
d = dict(src_dict)
|
||||||
|
loc = []
|
||||||
|
_loc = d.pop("loc")
|
||||||
|
for loc_item_data in _loc:
|
||||||
|
|
||||||
|
def _parse_loc_item(data: object) -> int | str:
|
||||||
|
return cast(int | str, data)
|
||||||
|
|
||||||
|
loc_item = _parse_loc_item(loc_item_data)
|
||||||
|
|
||||||
|
loc.append(loc_item)
|
||||||
|
|
||||||
|
msg = d.pop("msg")
|
||||||
|
|
||||||
|
type_ = d.pop("type")
|
||||||
|
|
||||||
|
validation_error = cls(
|
||||||
|
loc=loc,
|
||||||
|
msg=msg,
|
||||||
|
type_=type_,
|
||||||
|
)
|
||||||
|
|
||||||
|
validation_error.additional_properties = d
|
||||||
|
return validation_error
|
||||||
|
|
||||||
|
@property
|
||||||
|
def additional_keys(self) -> list[str]:
|
||||||
|
return list(self.additional_properties.keys())
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> Any:
|
||||||
|
return self.additional_properties[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value: Any) -> None:
|
||||||
|
self.additional_properties[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key: str) -> None:
|
||||||
|
del self.additional_properties[key]
|
||||||
|
|
||||||
|
def __contains__(self, key: str) -> bool:
|
||||||
|
return key in self.additional_properties
|
||||||
28
memora-clients/python/pyproject.toml
Normal file
28
memora-clients/python/pyproject.toml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
[project]
|
||||||
|
name = "memora-client"
|
||||||
|
version = "0.0.1"
|
||||||
|
description = "Python client for Memora - Semantic memory system with personality-driven thinking"
|
||||||
|
authors = [
|
||||||
|
{name = "Memora Team"}
|
||||||
|
]
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
readme = "README.md"
|
||||||
|
dependencies = [
|
||||||
|
"httpx>=0.23.0,<0.29.0",
|
||||||
|
"attrs>=22.2.0",
|
||||||
|
"python-dateutil>=2.8.0,<3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.uv.build-backend]
|
||||||
|
module-name = "agent_memory_api_client"
|
||||||
|
module-root = ""
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["uv_build>=0.9.0,<0.10.0"]
|
||||||
|
build-backend = "uv_build"
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 120
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
select = ["F", "I", "UP"]
|
||||||
54
memora-clients/python/types.py
Normal file
54
memora-clients/python/types.py
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
"""Contains some shared types for properties"""
|
||||||
|
|
||||||
|
from collections.abc import Mapping, MutableMapping
|
||||||
|
from http import HTTPStatus
|
||||||
|
from typing import IO, BinaryIO, Generic, Literal, TypeVar
|
||||||
|
|
||||||
|
from attrs import define
|
||||||
|
|
||||||
|
|
||||||
|
class Unset:
|
||||||
|
def __bool__(self) -> Literal[False]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
UNSET: Unset = Unset()
|
||||||
|
|
||||||
|
# The types that `httpx.Client(files=)` can accept, copied from that library.
|
||||||
|
FileContent = IO[bytes] | bytes | str
|
||||||
|
FileTypes = (
|
||||||
|
# (filename, file (or bytes), content_type)
|
||||||
|
tuple[str | None, FileContent, str | None]
|
||||||
|
# (filename, file (or bytes), content_type, headers)
|
||||||
|
| tuple[str | None, FileContent, str | None, Mapping[str, str]]
|
||||||
|
)
|
||||||
|
RequestFiles = list[tuple[str, FileTypes]]
|
||||||
|
|
||||||
|
|
||||||
|
@define
|
||||||
|
class File:
|
||||||
|
"""Contains information for file uploads"""
|
||||||
|
|
||||||
|
payload: BinaryIO
|
||||||
|
file_name: str | None = None
|
||||||
|
mime_type: str | None = None
|
||||||
|
|
||||||
|
def to_tuple(self) -> FileTypes:
|
||||||
|
"""Return a tuple representation that httpx will accept for multipart/form-data"""
|
||||||
|
return self.file_name, self.payload, self.mime_type
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
@define
|
||||||
|
class Response(Generic[T]):
|
||||||
|
"""A response from an endpoint"""
|
||||||
|
|
||||||
|
status_code: HTTPStatus
|
||||||
|
content: bytes
|
||||||
|
headers: MutableMapping[str, str]
|
||||||
|
parsed: T | None
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"]
|
||||||
30
memora-clients/typescript/.gitignore
vendored
Normal file
30
memora-clients/typescript/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Dependencies
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
dist/
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
coverage/
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
26
memora-clients/typescript/.npmignore
Normal file
26
memora-clients/typescript/.npmignore
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Source files (we ship dist/)
|
||||||
|
src/
|
||||||
|
tsconfig.json
|
||||||
|
|
||||||
|
# Development
|
||||||
|
node_modules/
|
||||||
|
*.test.ts
|
||||||
|
*.spec.ts
|
||||||
|
coverage/
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# CI/CD
|
||||||
|
.github/
|
||||||
|
.gitlab-ci.yml
|
||||||
|
|
||||||
|
# Documentation source
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
*.tsbuildinfo
|
||||||
57
memora-clients/typescript/README.md
Normal file
57
memora-clients/typescript/README.md
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
# @memora/client
|
||||||
|
|
||||||
|
TypeScript client for Memora - Semantic memory system with personality-driven thinking.
|
||||||
|
|
||||||
|
**Auto-generated from OpenAPI spec** - provides type-safe access to all Memora API endpoints.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @memora/client
|
||||||
|
# or
|
||||||
|
yarn add @memora/client
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { OpenAPI, MemoryStorageService, ReasoningService } from '@memora/client';
|
||||||
|
|
||||||
|
// Configure API base URL
|
||||||
|
OpenAPI.BASE = 'http://localhost:8000';
|
||||||
|
|
||||||
|
// Store memory
|
||||||
|
await MemoryStorageService.putApiPutPost({
|
||||||
|
agent_id: 'user123',
|
||||||
|
content: 'Alice loves machine learning'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Think (generate answer with personality)
|
||||||
|
const response = await ReasoningService.thinkApiThinkPost({
|
||||||
|
agent_id: 'user123',
|
||||||
|
query: 'What does Alice think about AI?',
|
||||||
|
thinking_budget: 50
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(response.text);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Services
|
||||||
|
|
||||||
|
- `MemoryStorageService` - Store and retrieve facts
|
||||||
|
- `SearchService` - Semantic and temporal search
|
||||||
|
- `ReasoningService` - Personality-driven thinking
|
||||||
|
- `VisualizationService` - Memory graphs and statistics
|
||||||
|
- `ManagementService` - Agent profiles and configuration
|
||||||
|
- `DocumentsService` - Document tracking
|
||||||
|
|
||||||
|
All services are fully typed with TypeScript interfaces.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Auto-generated from `openapi.json`. See [RELEASE.md](../../RELEASE.md) for regeneration instructions.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [GitHub Repository](https://github.com/nicoloboschi/memora)
|
||||||
|
- [Full Documentation](https://github.com/nicoloboschi/memora/blob/main/README.md)
|
||||||
25
memora-clients/typescript/core/ApiError.ts
Normal file
25
memora-clients/typescript/core/ApiError.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
import type { ApiResult } from './ApiResult';
|
||||||
|
|
||||||
|
export class ApiError extends Error {
|
||||||
|
public readonly url: string;
|
||||||
|
public readonly status: number;
|
||||||
|
public readonly statusText: string;
|
||||||
|
public readonly body: any;
|
||||||
|
public readonly request: ApiRequestOptions;
|
||||||
|
|
||||||
|
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'ApiError';
|
||||||
|
this.url = response.url;
|
||||||
|
this.status = response.status;
|
||||||
|
this.statusText = response.statusText;
|
||||||
|
this.body = response.body;
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
memora-clients/typescript/core/ApiRequestOptions.ts
Normal file
17
memora-clients/typescript/core/ApiRequestOptions.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ApiRequestOptions = {
|
||||||
|
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
|
||||||
|
readonly url: string;
|
||||||
|
readonly path?: Record<string, any>;
|
||||||
|
readonly cookies?: Record<string, any>;
|
||||||
|
readonly headers?: Record<string, any>;
|
||||||
|
readonly query?: Record<string, any>;
|
||||||
|
readonly formData?: Record<string, any>;
|
||||||
|
readonly body?: any;
|
||||||
|
readonly mediaType?: string;
|
||||||
|
readonly responseHeader?: string;
|
||||||
|
readonly errors?: Record<number, string>;
|
||||||
|
};
|
||||||
11
memora-clients/typescript/core/ApiResult.ts
Normal file
11
memora-clients/typescript/core/ApiResult.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type ApiResult = {
|
||||||
|
readonly url: string;
|
||||||
|
readonly ok: boolean;
|
||||||
|
readonly status: number;
|
||||||
|
readonly statusText: string;
|
||||||
|
readonly body: any;
|
||||||
|
};
|
||||||
131
memora-clients/typescript/core/CancelablePromise.ts
Normal file
131
memora-clients/typescript/core/CancelablePromise.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export class CancelError extends Error {
|
||||||
|
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'CancelError';
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isCancelled(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OnCancel {
|
||||||
|
readonly isResolved: boolean;
|
||||||
|
readonly isRejected: boolean;
|
||||||
|
readonly isCancelled: boolean;
|
||||||
|
|
||||||
|
(cancelHandler: () => void): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CancelablePromise<T> implements Promise<T> {
|
||||||
|
#isResolved: boolean;
|
||||||
|
#isRejected: boolean;
|
||||||
|
#isCancelled: boolean;
|
||||||
|
readonly #cancelHandlers: (() => void)[];
|
||||||
|
readonly #promise: Promise<T>;
|
||||||
|
#resolve?: (value: T | PromiseLike<T>) => void;
|
||||||
|
#reject?: (reason?: any) => void;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
executor: (
|
||||||
|
resolve: (value: T | PromiseLike<T>) => void,
|
||||||
|
reject: (reason?: any) => void,
|
||||||
|
onCancel: OnCancel
|
||||||
|
) => void
|
||||||
|
) {
|
||||||
|
this.#isResolved = false;
|
||||||
|
this.#isRejected = false;
|
||||||
|
this.#isCancelled = false;
|
||||||
|
this.#cancelHandlers = [];
|
||||||
|
this.#promise = new Promise<T>((resolve, reject) => {
|
||||||
|
this.#resolve = resolve;
|
||||||
|
this.#reject = reject;
|
||||||
|
|
||||||
|
const onResolve = (value: T | PromiseLike<T>): void => {
|
||||||
|
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#isResolved = true;
|
||||||
|
if (this.#resolve) this.#resolve(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onReject = (reason?: any): void => {
|
||||||
|
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#isRejected = true;
|
||||||
|
if (this.#reject) this.#reject(reason);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = (cancelHandler: () => void): void => {
|
||||||
|
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#cancelHandlers.push(cancelHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(onCancel, 'isResolved', {
|
||||||
|
get: (): boolean => this.#isResolved,
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(onCancel, 'isRejected', {
|
||||||
|
get: (): boolean => this.#isRejected,
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(onCancel, 'isCancelled', {
|
||||||
|
get: (): boolean => this.#isCancelled,
|
||||||
|
});
|
||||||
|
|
||||||
|
return executor(onResolve, onReject, onCancel as OnCancel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get [Symbol.toStringTag]() {
|
||||||
|
return "Cancellable Promise";
|
||||||
|
}
|
||||||
|
|
||||||
|
public then<TResult1 = T, TResult2 = never>(
|
||||||
|
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||||
|
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
||||||
|
): Promise<TResult1 | TResult2> {
|
||||||
|
return this.#promise.then(onFulfilled, onRejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public catch<TResult = never>(
|
||||||
|
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
|
||||||
|
): Promise<T | TResult> {
|
||||||
|
return this.#promise.catch(onRejected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||||
|
return this.#promise.finally(onFinally);
|
||||||
|
}
|
||||||
|
|
||||||
|
public cancel(): void {
|
||||||
|
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#isCancelled = true;
|
||||||
|
if (this.#cancelHandlers.length) {
|
||||||
|
try {
|
||||||
|
for (const cancelHandler of this.#cancelHandlers) {
|
||||||
|
cancelHandler();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Cancellation threw an error', error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.#cancelHandlers.length = 0;
|
||||||
|
if (this.#reject) this.#reject(new CancelError('Request aborted'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isCancelled(): boolean {
|
||||||
|
return this.#isCancelled;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
memora-clients/typescript/core/OpenAPI.ts
Normal file
32
memora-clients/typescript/core/OpenAPI.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
|
||||||
|
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||||
|
type Headers = Record<string, string>;
|
||||||
|
|
||||||
|
export type OpenAPIConfig = {
|
||||||
|
BASE: string;
|
||||||
|
VERSION: string;
|
||||||
|
WITH_CREDENTIALS: boolean;
|
||||||
|
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||||
|
TOKEN?: string | Resolver<string> | undefined;
|
||||||
|
USERNAME?: string | Resolver<string> | undefined;
|
||||||
|
PASSWORD?: string | Resolver<string> | undefined;
|
||||||
|
HEADERS?: Headers | Resolver<Headers> | undefined;
|
||||||
|
ENCODE_PATH?: ((path: string) => string) | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OpenAPI: OpenAPIConfig = {
|
||||||
|
BASE: '',
|
||||||
|
VERSION: '1.0.0',
|
||||||
|
WITH_CREDENTIALS: false,
|
||||||
|
CREDENTIALS: 'include',
|
||||||
|
TOKEN: undefined,
|
||||||
|
USERNAME: undefined,
|
||||||
|
PASSWORD: undefined,
|
||||||
|
HEADERS: undefined,
|
||||||
|
ENCODE_PATH: undefined,
|
||||||
|
};
|
||||||
323
memora-clients/typescript/core/request.ts
Normal file
323
memora-clients/typescript/core/request.ts
Normal file
|
|
@ -0,0 +1,323 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import axios from 'axios';
|
||||||
|
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
||||||
|
import FormData from 'form-data';
|
||||||
|
|
||||||
|
import { ApiError } from './ApiError';
|
||||||
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
import type { ApiResult } from './ApiResult';
|
||||||
|
import { CancelablePromise } from './CancelablePromise';
|
||||||
|
import type { OnCancel } from './CancelablePromise';
|
||||||
|
import type { OpenAPIConfig } from './OpenAPI';
|
||||||
|
|
||||||
|
export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
|
||||||
|
return value !== undefined && value !== null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isString = (value: any): value is string => {
|
||||||
|
return typeof value === 'string';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isStringWithValue = (value: any): value is string => {
|
||||||
|
return isString(value) && value !== '';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isBlob = (value: any): value is Blob => {
|
||||||
|
return (
|
||||||
|
typeof value === 'object' &&
|
||||||
|
typeof value.type === 'string' &&
|
||||||
|
typeof value.stream === 'function' &&
|
||||||
|
typeof value.arrayBuffer === 'function' &&
|
||||||
|
typeof value.constructor === 'function' &&
|
||||||
|
typeof value.constructor.name === 'string' &&
|
||||||
|
/^(Blob|File)$/.test(value.constructor.name) &&
|
||||||
|
/^(Blob|File)$/.test(value[Symbol.toStringTag])
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isFormData = (value: any): value is FormData => {
|
||||||
|
return value instanceof FormData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isSuccess = (status: number): boolean => {
|
||||||
|
return status >= 200 && status < 300;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const base64 = (str: string): string => {
|
||||||
|
try {
|
||||||
|
return btoa(str);
|
||||||
|
} catch (err) {
|
||||||
|
// @ts-ignore
|
||||||
|
return Buffer.from(str).toString('base64');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getQueryString = (params: Record<string, any>): string => {
|
||||||
|
const qs: string[] = [];
|
||||||
|
|
||||||
|
const append = (key: string, value: any) => {
|
||||||
|
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const process = (key: string, value: any) => {
|
||||||
|
if (isDefined(value)) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.forEach(v => {
|
||||||
|
process(key, v);
|
||||||
|
});
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
Object.entries(value).forEach(([k, v]) => {
|
||||||
|
process(`${key}[${k}]`, v);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
append(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
|
process(key, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (qs.length > 0) {
|
||||||
|
return `?${qs.join('&')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||||
|
const encoder = config.ENCODE_PATH || encodeURI;
|
||||||
|
|
||||||
|
const path = options.url
|
||||||
|
.replace('{api-version}', config.VERSION)
|
||||||
|
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||||
|
if (options.path?.hasOwnProperty(group)) {
|
||||||
|
return encoder(String(options.path[group]));
|
||||||
|
}
|
||||||
|
return substring;
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = `${config.BASE}${path}`;
|
||||||
|
if (options.query) {
|
||||||
|
return `${url}${getQueryString(options.query)}`;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||||
|
if (options.formData) {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
const process = (key: string, value: any) => {
|
||||||
|
if (isString(value) || isBlob(value)) {
|
||||||
|
formData.append(key, value);
|
||||||
|
} else {
|
||||||
|
formData.append(key, JSON.stringify(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.entries(options.formData)
|
||||||
|
.filter(([_, value]) => isDefined(value))
|
||||||
|
.forEach(([key, value]) => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
value.forEach(v => process(key, v));
|
||||||
|
} else {
|
||||||
|
process(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
|
||||||
|
|
||||||
|
export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||||
|
if (typeof resolver === 'function') {
|
||||||
|
return (resolver as Resolver<T>)(options);
|
||||||
|
}
|
||||||
|
return resolver;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
|
||||||
|
const [token, username, password, additionalHeaders] = await Promise.all([
|
||||||
|
resolve(options, config.TOKEN),
|
||||||
|
resolve(options, config.USERNAME),
|
||||||
|
resolve(options, config.PASSWORD),
|
||||||
|
resolve(options, config.HEADERS),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
|
||||||
|
|
||||||
|
const headers = Object.entries({
|
||||||
|
Accept: 'application/json',
|
||||||
|
...additionalHeaders,
|
||||||
|
...options.headers,
|
||||||
|
...formHeaders,
|
||||||
|
})
|
||||||
|
.filter(([_, value]) => isDefined(value))
|
||||||
|
.reduce((headers, [key, value]) => ({
|
||||||
|
...headers,
|
||||||
|
[key]: String(value),
|
||||||
|
}), {} as Record<string, string>);
|
||||||
|
|
||||||
|
if (isStringWithValue(token)) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||||
|
const credentials = base64(`${username}:${password}`);
|
||||||
|
headers['Authorization'] = `Basic ${credentials}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.body !== undefined) {
|
||||||
|
if (options.mediaType) {
|
||||||
|
headers['Content-Type'] = options.mediaType;
|
||||||
|
} else if (isBlob(options.body)) {
|
||||||
|
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||||
|
} else if (isString(options.body)) {
|
||||||
|
headers['Content-Type'] = 'text/plain';
|
||||||
|
} else if (!isFormData(options.body)) {
|
||||||
|
headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getRequestBody = (options: ApiRequestOptions): any => {
|
||||||
|
if (options.body) {
|
||||||
|
return options.body;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendRequest = async <T>(
|
||||||
|
config: OpenAPIConfig,
|
||||||
|
options: ApiRequestOptions,
|
||||||
|
url: string,
|
||||||
|
body: any,
|
||||||
|
formData: FormData | undefined,
|
||||||
|
headers: Record<string, string>,
|
||||||
|
onCancel: OnCancel,
|
||||||
|
axiosClient: AxiosInstance
|
||||||
|
): Promise<AxiosResponse<T>> => {
|
||||||
|
const source = axios.CancelToken.source();
|
||||||
|
|
||||||
|
const requestConfig: AxiosRequestConfig = {
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
data: body ?? formData,
|
||||||
|
method: options.method,
|
||||||
|
withCredentials: config.WITH_CREDENTIALS,
|
||||||
|
withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
|
||||||
|
cancelToken: source.token,
|
||||||
|
};
|
||||||
|
|
||||||
|
onCancel(() => source.cancel('The user aborted a request.'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await axiosClient.request(requestConfig);
|
||||||
|
} catch (error) {
|
||||||
|
const axiosError = error as AxiosError<T>;
|
||||||
|
if (axiosError.response) {
|
||||||
|
return axiosError.response;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
|
||||||
|
if (responseHeader) {
|
||||||
|
const content = response.headers[responseHeader];
|
||||||
|
if (isString(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getResponseBody = (response: AxiosResponse<any>): any => {
|
||||||
|
if (response.status !== 204) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||||
|
const errors: Record<number, string> = {
|
||||||
|
400: 'Bad Request',
|
||||||
|
401: 'Unauthorized',
|
||||||
|
403: 'Forbidden',
|
||||||
|
404: 'Not Found',
|
||||||
|
500: 'Internal Server Error',
|
||||||
|
502: 'Bad Gateway',
|
||||||
|
503: 'Service Unavailable',
|
||||||
|
...options.errors,
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = errors[result.status];
|
||||||
|
if (error) {
|
||||||
|
throw new ApiError(options, result, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
const errorStatus = result.status ?? 'unknown';
|
||||||
|
const errorStatusText = result.statusText ?? 'unknown';
|
||||||
|
const errorBody = (() => {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(result.body, null, 2);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
throw new ApiError(options, result,
|
||||||
|
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request method
|
||||||
|
* @param config The OpenAPI configuration object
|
||||||
|
* @param options The request options from the service
|
||||||
|
* @param axiosClient The axios client instance to use
|
||||||
|
* @returns CancelablePromise<T>
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
|
||||||
|
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
||||||
|
try {
|
||||||
|
const url = getUrl(config, options);
|
||||||
|
const formData = getFormData(options);
|
||||||
|
const body = getRequestBody(options);
|
||||||
|
const headers = await getHeaders(config, options, formData);
|
||||||
|
|
||||||
|
if (!onCancel.isCancelled) {
|
||||||
|
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
|
||||||
|
const responseBody = getResponseBody(response);
|
||||||
|
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||||
|
|
||||||
|
const result: ApiResult = {
|
||||||
|
url,
|
||||||
|
ok: isSuccess(response.status),
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
body: responseHeader ?? responseBody,
|
||||||
|
};
|
||||||
|
|
||||||
|
catchErrorCodes(options, result);
|
||||||
|
|
||||||
|
resolve(result.body);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
42
memora-clients/typescript/index.ts
Normal file
42
memora-clients/typescript/index.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export { ApiError } from './core/ApiError';
|
||||||
|
export { CancelablePromise, CancelError } from './core/CancelablePromise';
|
||||||
|
export { OpenAPI } from './core/OpenAPI';
|
||||||
|
export type { OpenAPIConfig } from './core/OpenAPI';
|
||||||
|
|
||||||
|
export type { AddBackgroundRequest } from './models/AddBackgroundRequest';
|
||||||
|
export type { AgentListItem } from './models/AgentListItem';
|
||||||
|
export type { AgentListResponse } from './models/AgentListResponse';
|
||||||
|
export type { AgentProfileResponse } from './models/AgentProfileResponse';
|
||||||
|
export type { AgentsResponse } from './models/AgentsResponse';
|
||||||
|
export type { BackgroundResponse } from './models/BackgroundResponse';
|
||||||
|
export type { BatchPutAsyncResponse } from './models/BatchPutAsyncResponse';
|
||||||
|
export type { BatchPutRequest } from './models/BatchPutRequest';
|
||||||
|
export type { BatchPutResponse } from './models/BatchPutResponse';
|
||||||
|
export type { CreateAgentRequest } from './models/CreateAgentRequest';
|
||||||
|
export type { DocumentResponse } from './models/DocumentResponse';
|
||||||
|
export type { GraphDataResponse } from './models/GraphDataResponse';
|
||||||
|
export type { HTTPValidationError } from './models/HTTPValidationError';
|
||||||
|
export type { ListDocumentsResponse } from './models/ListDocumentsResponse';
|
||||||
|
export type { ListMemoryUnitsResponse } from './models/ListMemoryUnitsResponse';
|
||||||
|
export type { MemoryItem } from './models/MemoryItem';
|
||||||
|
export type { PersonalityTraits } from './models/PersonalityTraits';
|
||||||
|
export type { SearchRequest } from './models/SearchRequest';
|
||||||
|
export type { SearchResponse } from './models/SearchResponse';
|
||||||
|
export type { SearchResult } from './models/SearchResult';
|
||||||
|
export type { ThinkFact } from './models/ThinkFact';
|
||||||
|
export type { ThinkRequest } from './models/ThinkRequest';
|
||||||
|
export type { ThinkResponse } from './models/ThinkResponse';
|
||||||
|
export type { UpdatePersonalityRequest } from './models/UpdatePersonalityRequest';
|
||||||
|
export type { ValidationError } from './models/ValidationError';
|
||||||
|
|
||||||
|
export { AgentProfileService } from './services/AgentProfileService';
|
||||||
|
export { DocumentsService } from './services/DocumentsService';
|
||||||
|
export { MemoryStatisticsService } from './services/MemoryStatisticsService';
|
||||||
|
export { MemoryStorageService } from './services/MemoryStorageService';
|
||||||
|
export { ReasoningService } from './services/ReasoningService';
|
||||||
|
export { SearchService } from './services/SearchService';
|
||||||
|
export { VisualizationService } from './services/VisualizationService';
|
||||||
18
memora-clients/typescript/models/AddBackgroundRequest.ts
Normal file
18
memora-clients/typescript/models/AddBackgroundRequest.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Request model for adding/merging background information.
|
||||||
|
*/
|
||||||
|
export type AddBackgroundRequest = {
|
||||||
|
/**
|
||||||
|
* New background information to add or merge
|
||||||
|
*/
|
||||||
|
content: string;
|
||||||
|
/**
|
||||||
|
* If true, infer Big Five personality traits from the merged background (default: true)
|
||||||
|
*/
|
||||||
|
update_personality?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
16
memora-clients/typescript/models/AgentListItem.ts
Normal file
16
memora-clients/typescript/models/AgentListItem.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PersonalityTraits } from './PersonalityTraits';
|
||||||
|
/**
|
||||||
|
* Agent list item with profile summary.
|
||||||
|
*/
|
||||||
|
export type AgentListItem = {
|
||||||
|
agent_id: string;
|
||||||
|
personality: PersonalityTraits;
|
||||||
|
background: string;
|
||||||
|
created_at?: (string | null);
|
||||||
|
updated_at?: (string | null);
|
||||||
|
};
|
||||||
|
|
||||||
12
memora-clients/typescript/models/AgentListResponse.ts
Normal file
12
memora-clients/typescript/models/AgentListResponse.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { AgentListItem } from './AgentListItem';
|
||||||
|
/**
|
||||||
|
* Response model for listing all agents.
|
||||||
|
*/
|
||||||
|
export type AgentListResponse = {
|
||||||
|
agents: Array<AgentListItem>;
|
||||||
|
};
|
||||||
|
|
||||||
14
memora-clients/typescript/models/AgentProfileResponse.ts
Normal file
14
memora-clients/typescript/models/AgentProfileResponse.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PersonalityTraits } from './PersonalityTraits';
|
||||||
|
/**
|
||||||
|
* Response model for agent profile.
|
||||||
|
*/
|
||||||
|
export type AgentProfileResponse = {
|
||||||
|
agent_id: string;
|
||||||
|
personality: PersonalityTraits;
|
||||||
|
background: string;
|
||||||
|
};
|
||||||
|
|
||||||
11
memora-clients/typescript/models/AgentsResponse.ts
Normal file
11
memora-clients/typescript/models/AgentsResponse.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for agents list endpoint.
|
||||||
|
*/
|
||||||
|
export type AgentsResponse = {
|
||||||
|
agents: Array<string>;
|
||||||
|
};
|
||||||
|
|
||||||
13
memora-clients/typescript/models/BackgroundResponse.ts
Normal file
13
memora-clients/typescript/models/BackgroundResponse.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PersonalityTraits } from './PersonalityTraits';
|
||||||
|
/**
|
||||||
|
* Response model for background update.
|
||||||
|
*/
|
||||||
|
export type BackgroundResponse = {
|
||||||
|
background: string;
|
||||||
|
personality?: (PersonalityTraits | null);
|
||||||
|
};
|
||||||
|
|
||||||
16
memora-clients/typescript/models/BatchPutAsyncResponse.ts
Normal file
16
memora-clients/typescript/models/BatchPutAsyncResponse.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for async batch put endpoint.
|
||||||
|
*/
|
||||||
|
export type BatchPutAsyncResponse = {
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
agent_id: string;
|
||||||
|
document_id?: (string | null);
|
||||||
|
items_count: number;
|
||||||
|
queued: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
14
memora-clients/typescript/models/BatchPutRequest.ts
Normal file
14
memora-clients/typescript/models/BatchPutRequest.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { MemoryItem } from './MemoryItem';
|
||||||
|
/**
|
||||||
|
* Request model for batch put endpoint.
|
||||||
|
*/
|
||||||
|
export type BatchPutRequest = {
|
||||||
|
agent_id: string;
|
||||||
|
items: Array<MemoryItem>;
|
||||||
|
document_id?: (string | null);
|
||||||
|
};
|
||||||
|
|
||||||
15
memora-clients/typescript/models/BatchPutResponse.ts
Normal file
15
memora-clients/typescript/models/BatchPutResponse.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for batch put endpoint.
|
||||||
|
*/
|
||||||
|
export type BatchPutResponse = {
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
agent_id: string;
|
||||||
|
document_id?: (string | null);
|
||||||
|
items_count: number;
|
||||||
|
};
|
||||||
|
|
||||||
13
memora-clients/typescript/models/CreateAgentRequest.ts
Normal file
13
memora-clients/typescript/models/CreateAgentRequest.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { PersonalityTraits } from './PersonalityTraits';
|
||||||
|
/**
|
||||||
|
* Request model for creating/updating an agent.
|
||||||
|
*/
|
||||||
|
export type CreateAgentRequest = {
|
||||||
|
personality?: (PersonalityTraits | null);
|
||||||
|
background?: (string | null);
|
||||||
|
};
|
||||||
|
|
||||||
17
memora-clients/typescript/models/DocumentResponse.ts
Normal file
17
memora-clients/typescript/models/DocumentResponse.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for get document endpoint.
|
||||||
|
*/
|
||||||
|
export type DocumentResponse = {
|
||||||
|
id: string;
|
||||||
|
agent_id: string;
|
||||||
|
original_text: string;
|
||||||
|
content_hash: (string | null);
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
memory_unit_count: number;
|
||||||
|
};
|
||||||
|
|
||||||
14
memora-clients/typescript/models/GraphDataResponse.ts
Normal file
14
memora-clients/typescript/models/GraphDataResponse.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for graph data endpoint.
|
||||||
|
*/
|
||||||
|
export type GraphDataResponse = {
|
||||||
|
nodes: Array<Record<string, any>>;
|
||||||
|
edges: Array<Record<string, any>>;
|
||||||
|
table_rows: Array<Record<string, any>>;
|
||||||
|
total_units: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
memora-clients/typescript/models/HTTPValidationError.ts
Normal file
9
memora-clients/typescript/models/HTTPValidationError.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { ValidationError } from './ValidationError';
|
||||||
|
export type HTTPValidationError = {
|
||||||
|
detail?: Array<ValidationError>;
|
||||||
|
};
|
||||||
|
|
||||||
14
memora-clients/typescript/models/ListDocumentsResponse.ts
Normal file
14
memora-clients/typescript/models/ListDocumentsResponse.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for list documents endpoint.
|
||||||
|
*/
|
||||||
|
export type ListDocumentsResponse = {
|
||||||
|
items: Array<Record<string, any>>;
|
||||||
|
total: number;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
};
|
||||||
|
|
||||||
14
memora-clients/typescript/models/ListMemoryUnitsResponse.ts
Normal file
14
memora-clients/typescript/models/ListMemoryUnitsResponse.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Response model for list memory units endpoint.
|
||||||
|
*/
|
||||||
|
export type ListMemoryUnitsResponse = {
|
||||||
|
items: Array<Record<string, any>>;
|
||||||
|
total: number;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
};
|
||||||
|
|
||||||
13
memora-clients/typescript/models/MemoryItem.ts
Normal file
13
memora-clients/typescript/models/MemoryItem.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Single memory item for batch put.
|
||||||
|
*/
|
||||||
|
export type MemoryItem = {
|
||||||
|
content: string;
|
||||||
|
event_date?: (string | null);
|
||||||
|
context?: (string | null);
|
||||||
|
};
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue