@dakera-ai/dakera 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +145 -5
- package/dist/index.d.ts +145 -5
- package/dist/index.js +127 -24
- package/dist/index.mjs +127 -24
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -226,16 +226,33 @@ interface BatchQuerySpec {
|
|
|
226
226
|
/** Staleness configuration for bounded staleness reads */
|
|
227
227
|
stalenessConfig?: StalenessConfig;
|
|
228
228
|
}
|
|
229
|
+
/** Exponential backoff configuration for retries */
|
|
230
|
+
interface RetryConfig {
|
|
231
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
232
|
+
maxRetries?: number;
|
|
233
|
+
/** Base delay in milliseconds before the first retry (default: 100) */
|
|
234
|
+
baseDelay?: number;
|
|
235
|
+
/** Maximum delay in milliseconds between retries (default: 60000) */
|
|
236
|
+
maxDelay?: number;
|
|
237
|
+
/** Whether to add random jitter to backoff delay (default: true) */
|
|
238
|
+
jitter?: boolean;
|
|
239
|
+
}
|
|
229
240
|
/** Client configuration options */
|
|
230
241
|
interface ClientOptions {
|
|
231
242
|
/** Base URL of the Dakera server */
|
|
232
243
|
baseUrl: string;
|
|
233
244
|
/** API key for authentication */
|
|
234
245
|
apiKey?: string;
|
|
235
|
-
/**
|
|
246
|
+
/** Per-request timeout in milliseconds (default: 30000) */
|
|
236
247
|
timeout?: number;
|
|
237
|
-
/**
|
|
248
|
+
/** Connection establishment timeout in milliseconds. Defaults to `timeout`. */
|
|
249
|
+
connectTimeout?: number;
|
|
250
|
+
/** Maximum number of retries for transient errors (default: 3).
|
|
251
|
+
* Ignored when `retryBackoff` is provided. */
|
|
238
252
|
maxRetries?: number;
|
|
253
|
+
/** Fine-grained retry and backoff configuration.
|
|
254
|
+
* When provided, `maxRetries` is ignored in favour of `retryBackoff.maxRetries`. */
|
|
255
|
+
retryBackoff?: RetryConfig;
|
|
239
256
|
/** Additional headers */
|
|
240
257
|
headers?: Record<string, string>;
|
|
241
258
|
}
|
|
@@ -966,6 +983,8 @@ interface CrossAgentNetworkResponse {
|
|
|
966
983
|
nodes: AgentNetworkNode[];
|
|
967
984
|
edges: AgentNetworkEdge[];
|
|
968
985
|
stats: AgentNetworkStats;
|
|
986
|
+
/** Total number of memory nodes in the network (added in server v0.6.2). */
|
|
987
|
+
node_count: number;
|
|
969
988
|
}
|
|
970
989
|
/** Request body for POST /v1/knowledge/network/cross-agent */
|
|
971
990
|
interface CrossAgentNetworkRequest {
|
|
@@ -1044,6 +1063,74 @@ interface KeyUsage {
|
|
|
1044
1063
|
last_used?: string;
|
|
1045
1064
|
requests_by_endpoint?: Record<string, number>;
|
|
1046
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Rate-limit and quota headers present on every API response (OPS-1).
|
|
1068
|
+
*
|
|
1069
|
+
* Fields are `undefined` when the server does not include the header
|
|
1070
|
+
* (e.g. non-namespaced endpoints where quota does not apply).
|
|
1071
|
+
*/
|
|
1072
|
+
interface RateLimitHeaders {
|
|
1073
|
+
/** `X-RateLimit-Limit` — max requests allowed in the current window. */
|
|
1074
|
+
limit?: number;
|
|
1075
|
+
/** `X-RateLimit-Remaining` — requests left in the current window. */
|
|
1076
|
+
remaining?: number;
|
|
1077
|
+
/** `X-RateLimit-Reset` — Unix timestamp (seconds) when the window resets. */
|
|
1078
|
+
reset?: number;
|
|
1079
|
+
/** `X-Quota-Used` — namespace vectors / storage consumed. */
|
|
1080
|
+
quotaUsed?: number;
|
|
1081
|
+
/** `X-Quota-Limit` — namespace quota ceiling. */
|
|
1082
|
+
quotaLimit?: number;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Filter predicates for batch memory operations (CE-2).
|
|
1086
|
+
*
|
|
1087
|
+
* All fields are optional. For `batchForget` at least one must be set
|
|
1088
|
+
* (server-side safety guard).
|
|
1089
|
+
*/
|
|
1090
|
+
interface BatchMemoryFilter {
|
|
1091
|
+
/** Restrict to memories that carry **all** listed tags. */
|
|
1092
|
+
tags?: string[];
|
|
1093
|
+
/** Minimum importance (inclusive). */
|
|
1094
|
+
min_importance?: number;
|
|
1095
|
+
/** Maximum importance (inclusive). */
|
|
1096
|
+
max_importance?: number;
|
|
1097
|
+
/** Only memories created at or after this Unix timestamp (seconds). */
|
|
1098
|
+
created_after?: number;
|
|
1099
|
+
/** Only memories created before or at this Unix timestamp (seconds). */
|
|
1100
|
+
created_before?: number;
|
|
1101
|
+
/** Restrict to a specific memory type. */
|
|
1102
|
+
memory_type?: MemoryType;
|
|
1103
|
+
/** Restrict to memories from a specific session. */
|
|
1104
|
+
session_id?: string;
|
|
1105
|
+
}
|
|
1106
|
+
/** Request body for `POST /v1/memories/recall/batch`. */
|
|
1107
|
+
interface BatchRecallRequest {
|
|
1108
|
+
/** Agent whose memory namespace to search. */
|
|
1109
|
+
agent_id: string;
|
|
1110
|
+
/** Filter predicates to apply. An empty object returns all memories up to `limit`. */
|
|
1111
|
+
filter?: BatchMemoryFilter;
|
|
1112
|
+
/** Maximum number of results to return (default: 100). */
|
|
1113
|
+
limit?: number;
|
|
1114
|
+
}
|
|
1115
|
+
/** Response from `POST /v1/memories/recall/batch`. */
|
|
1116
|
+
interface BatchRecallResponse {
|
|
1117
|
+
memories: Memory[];
|
|
1118
|
+
/** Total memories in the agent namespace. */
|
|
1119
|
+
total: number;
|
|
1120
|
+
/** Number of memories that passed the filter. */
|
|
1121
|
+
filtered: number;
|
|
1122
|
+
}
|
|
1123
|
+
/** Request body for `DELETE /v1/memories/forget/batch`. */
|
|
1124
|
+
interface BatchForgetRequest {
|
|
1125
|
+
/** Agent whose memory namespace to purge from. */
|
|
1126
|
+
agent_id: string;
|
|
1127
|
+
/** Filter predicates — **at least one must be set** (server safety guard). */
|
|
1128
|
+
filter: BatchMemoryFilter;
|
|
1129
|
+
}
|
|
1130
|
+
/** Response from `DELETE /v1/memories/forget/batch`. */
|
|
1131
|
+
interface BatchForgetResponse {
|
|
1132
|
+
deleted_count: number;
|
|
1133
|
+
}
|
|
1047
1134
|
|
|
1048
1135
|
/**
|
|
1049
1136
|
* Dakera Client
|
|
@@ -1072,17 +1159,28 @@ declare class DakeraClient {
|
|
|
1072
1159
|
private readonly baseUrl;
|
|
1073
1160
|
private readonly apiKey?;
|
|
1074
1161
|
private readonly timeout;
|
|
1075
|
-
private readonly
|
|
1162
|
+
private readonly connectTimeout;
|
|
1163
|
+
private readonly retryConfig;
|
|
1076
1164
|
private readonly headers;
|
|
1165
|
+
/** OPS-1: rate-limit headers from the most recent API response. */
|
|
1166
|
+
private _lastRateLimitHeaders;
|
|
1077
1167
|
constructor(options: ClientOptions | string);
|
|
1078
1168
|
/**
|
|
1079
|
-
*
|
|
1169
|
+
* Rate-limit headers from the most recent API response (OPS-1).
|
|
1170
|
+
*
|
|
1171
|
+
* Returns `null` until the first successful request has been made.
|
|
1172
|
+
*/
|
|
1173
|
+
get lastRateLimitHeaders(): RateLimitHeaders | null;
|
|
1174
|
+
private computeBackoff;
|
|
1175
|
+
/**
|
|
1176
|
+
* Make an HTTP request with retry logic and exponential backoff.
|
|
1080
1177
|
*/
|
|
1081
1178
|
private request;
|
|
1082
1179
|
/**
|
|
1083
1180
|
* Handle HTTP response and throw appropriate errors.
|
|
1084
1181
|
*/
|
|
1085
1182
|
private handleResponse;
|
|
1183
|
+
private _parseHeaderInt;
|
|
1086
1184
|
private sleep;
|
|
1087
1185
|
/**
|
|
1088
1186
|
* Upsert vectors into a namespace.
|
|
@@ -1555,6 +1653,38 @@ declare class DakeraClient {
|
|
|
1555
1653
|
forget(agentId: string, memoryId: string): Promise<{
|
|
1556
1654
|
status: string;
|
|
1557
1655
|
}>;
|
|
1656
|
+
/**
|
|
1657
|
+
* Bulk-recall memories using filter predicates (CE-2).
|
|
1658
|
+
*
|
|
1659
|
+
* Uses `POST /v1/memories/recall/batch` — no embedding required.
|
|
1660
|
+
*
|
|
1661
|
+
* @example
|
|
1662
|
+
* ```typescript
|
|
1663
|
+
* const resp = await client.batchRecall({
|
|
1664
|
+
* agent_id: 'agent-1',
|
|
1665
|
+
* filter: { tags: ['preferences'], min_importance: 0.7 },
|
|
1666
|
+
* limit: 50,
|
|
1667
|
+
* });
|
|
1668
|
+
* console.log(`Found ${resp.filtered} memories`);
|
|
1669
|
+
* ```
|
|
1670
|
+
*/
|
|
1671
|
+
batchRecall(request: BatchRecallRequest): Promise<BatchRecallResponse>;
|
|
1672
|
+
/**
|
|
1673
|
+
* Bulk-delete memories using filter predicates (CE-2).
|
|
1674
|
+
*
|
|
1675
|
+
* Uses `DELETE /v1/memories/forget/batch`. At least one filter predicate
|
|
1676
|
+
* must be set (server safety guard).
|
|
1677
|
+
*
|
|
1678
|
+
* @example
|
|
1679
|
+
* ```typescript
|
|
1680
|
+
* const resp = await client.batchForget({
|
|
1681
|
+
* agent_id: 'agent-1',
|
|
1682
|
+
* filter: { created_before: Math.floor(Date.now() / 1000) - 86400 },
|
|
1683
|
+
* });
|
|
1684
|
+
* console.log(`Deleted ${resp.deleted_count} memories`);
|
|
1685
|
+
* ```
|
|
1686
|
+
*/
|
|
1687
|
+
batchForget(request: BatchForgetRequest): Promise<BatchForgetResponse>;
|
|
1558
1688
|
/** Search memories for an agent */
|
|
1559
1689
|
searchMemories(agentId: string, query: string, options?: {
|
|
1560
1690
|
top_k?: number;
|
|
@@ -1744,6 +1874,16 @@ declare class DakeraClient {
|
|
|
1744
1874
|
* ```
|
|
1745
1875
|
*/
|
|
1746
1876
|
streamMemoryEvents(): AsyncGenerator<MemoryEvent>;
|
|
1877
|
+
/**
|
|
1878
|
+
* Return a URL with `?api_key=<key>` appended for use with browser-native
|
|
1879
|
+
* `EventSource`, which cannot send custom request headers.
|
|
1880
|
+
*
|
|
1881
|
+
* @example
|
|
1882
|
+
* ```ts
|
|
1883
|
+
* const src = new EventSource(client.sseUrl('/v1/namespaces/my-ns/events'));
|
|
1884
|
+
* ```
|
|
1885
|
+
*/
|
|
1886
|
+
sseUrl(path: string): string;
|
|
1747
1887
|
/** Low-level SSE streaming helper — parses the SSE wire format. */
|
|
1748
1888
|
private _streamSse;
|
|
1749
1889
|
/** Parse a single SSE event block into a {@link DakeraEvent}. */
|
|
@@ -1822,4 +1962,4 @@ declare class TimeoutError extends DakeraError {
|
|
|
1822
1962
|
constructor(message: string);
|
|
1823
1963
|
}
|
|
1824
1964
|
|
|
1825
|
-
export { type AccessPatternHint, type AgentId, type AgentNetworkEdge, type AgentNetworkInfo, type AgentNetworkNode, type AgentNetworkStats, type AgentStats, type AgentSummary, type AggregationGroup, type AggregationRequest, type AggregationResponse, type AnalyticsOptions, type AnalyticsOverview, type ApiKey, AuthenticationError, AuthorizationError, type BackupInfo, type BatchQuerySpec, type BatchTextQueryOptions, type BatchTextQueryResponse, type Branded, type CacheStats, type ClientOptions, type ClusterNode, type ClusterStatus, type ColumnUpsertRequest, type ConfigureNamespaceRequest, type ConfigureNamespaceResponse, ConnectionError, type ConsolidateRequest, type ConsolidateResponse, type CreateKeyRequest, type CrossAgentNetworkRequest, type CrossAgentNetworkResponse, DakeraClient, DakeraError, type DakeraEvent, type DeduplicateRequest, type DeduplicateResponse, type DeleteOptions, type DeleteResponse, type DistanceMetric, type Document, type DocumentInput, type EmbeddingModel, ErrorCode, type ExportRequest, type ExportResponse, type ExportedVector, type FilterExpression, type FilterOperators, type FullKnowledgeGraphRequest, type FullTextSearchResult, type HealthResponse, type HybridSearchResult, type IndexStats, type JobProgressEvent, type KeyUsage, type KnowledgeEdge, type KnowledgeGraphRequest, type KnowledgeGraphResponse, type KnowledgeNode, type LatencyAnalytics, type ListSessionsOptions, type Memory, type MemoryEvent, type MemoryFeedbackRequest, type MemoryFeedbackResponse, type MemoryId, type MemoryType, type MultiVectorSearchRequest, type MultiVectorSearchResponse, type MultiVectorSearchResult, type NamespaceCreatedEvent, type NamespaceDeletedEvent, type NamespaceInfo, NotFoundError, type OpStatus, type OperationProgressEvent, type QueryExplainRequest, type QueryExplainResponse, type QueryOptions, type QueryResult, RateLimitError, type ReadConsistency, type RecallRequest, type RecalledMemory, type SearchResult, ServerError, type Session, type SessionId, type SlowQuery, type StalenessConfig, type StartSessionRequest, type StorageAnalytics, type StoreMemoryRequest, type StoreMemoryResponse, type StreamLaggedEvent, type SummarizeRequest, type SummarizeResponse, type TextDocument, type TextQueryOptions, type TextQueryResponse, type TextSearchResult, type TextUpsertOptions, type TextUpsertResponse, type ThroughputAnalytics, TimeoutError, type TtlConfig, type UnifiedQueryRequest, type UnifiedQueryResponse, type UnifiedSearchResult, type UpdateImportanceRequest, type UpdateMemoryRequest, type UpsertOptions, type UpsertResponse, ValidationError, type Vector, type VectorId, type VectorInput, type VectorMutationOp, type VectorsMutatedEvent, type WarmCacheRequest, type WarmCacheResponse, type WarmingPriority, type WarmingTargetTier, agentId, memoryId, sessionId, vectorId };
|
|
1965
|
+
export { type AccessPatternHint, type AgentId, type AgentNetworkEdge, type AgentNetworkInfo, type AgentNetworkNode, type AgentNetworkStats, type AgentStats, type AgentSummary, type AggregationGroup, type AggregationRequest, type AggregationResponse, type AnalyticsOptions, type AnalyticsOverview, type ApiKey, AuthenticationError, AuthorizationError, type BackupInfo, type BatchForgetRequest, type BatchForgetResponse, type BatchMemoryFilter, type BatchQuerySpec, type BatchRecallRequest, type BatchRecallResponse, type BatchTextQueryOptions, type BatchTextQueryResponse, type Branded, type CacheStats, type ClientOptions, type ClusterNode, type ClusterStatus, type ColumnUpsertRequest, type ConfigureNamespaceRequest, type ConfigureNamespaceResponse, ConnectionError, type ConsolidateRequest, type ConsolidateResponse, type CreateKeyRequest, type CrossAgentNetworkRequest, type CrossAgentNetworkResponse, DakeraClient, DakeraError, type DakeraEvent, type DeduplicateRequest, type DeduplicateResponse, type DeleteOptions, type DeleteResponse, type DistanceMetric, type Document, type DocumentInput, type EmbeddingModel, ErrorCode, type ExportRequest, type ExportResponse, type ExportedVector, type FilterExpression, type FilterOperators, type FullKnowledgeGraphRequest, type FullTextSearchResult, type HealthResponse, type HybridSearchResult, type IndexStats, type JobProgressEvent, type KeyUsage, type KnowledgeEdge, type KnowledgeGraphRequest, type KnowledgeGraphResponse, type KnowledgeNode, type LatencyAnalytics, type ListSessionsOptions, type Memory, type MemoryEvent, type MemoryFeedbackRequest, type MemoryFeedbackResponse, type MemoryId, type MemoryType, type MultiVectorSearchRequest, type MultiVectorSearchResponse, type MultiVectorSearchResult, type NamespaceCreatedEvent, type NamespaceDeletedEvent, type NamespaceInfo, NotFoundError, type OpStatus, type OperationProgressEvent, type QueryExplainRequest, type QueryExplainResponse, type QueryOptions, type QueryResult, RateLimitError, type RateLimitHeaders, type ReadConsistency, type RecallRequest, type RecalledMemory, type RetryConfig, type SearchResult, ServerError, type Session, type SessionId, type SlowQuery, type StalenessConfig, type StartSessionRequest, type StorageAnalytics, type StoreMemoryRequest, type StoreMemoryResponse, type StreamLaggedEvent, type SummarizeRequest, type SummarizeResponse, type TextDocument, type TextQueryOptions, type TextQueryResponse, type TextSearchResult, type TextUpsertOptions, type TextUpsertResponse, type ThroughputAnalytics, TimeoutError, type TtlConfig, type UnifiedQueryRequest, type UnifiedQueryResponse, type UnifiedSearchResult, type UpdateImportanceRequest, type UpdateMemoryRequest, type UpsertOptions, type UpsertResponse, ValidationError, type Vector, type VectorId, type VectorInput, type VectorMutationOp, type VectorsMutatedEvent, type WarmCacheRequest, type WarmCacheResponse, type WarmingPriority, type WarmingTargetTier, agentId, memoryId, sessionId, vectorId };
|
package/dist/index.d.ts
CHANGED
|
@@ -226,16 +226,33 @@ interface BatchQuerySpec {
|
|
|
226
226
|
/** Staleness configuration for bounded staleness reads */
|
|
227
227
|
stalenessConfig?: StalenessConfig;
|
|
228
228
|
}
|
|
229
|
+
/** Exponential backoff configuration for retries */
|
|
230
|
+
interface RetryConfig {
|
|
231
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
232
|
+
maxRetries?: number;
|
|
233
|
+
/** Base delay in milliseconds before the first retry (default: 100) */
|
|
234
|
+
baseDelay?: number;
|
|
235
|
+
/** Maximum delay in milliseconds between retries (default: 60000) */
|
|
236
|
+
maxDelay?: number;
|
|
237
|
+
/** Whether to add random jitter to backoff delay (default: true) */
|
|
238
|
+
jitter?: boolean;
|
|
239
|
+
}
|
|
229
240
|
/** Client configuration options */
|
|
230
241
|
interface ClientOptions {
|
|
231
242
|
/** Base URL of the Dakera server */
|
|
232
243
|
baseUrl: string;
|
|
233
244
|
/** API key for authentication */
|
|
234
245
|
apiKey?: string;
|
|
235
|
-
/**
|
|
246
|
+
/** Per-request timeout in milliseconds (default: 30000) */
|
|
236
247
|
timeout?: number;
|
|
237
|
-
/**
|
|
248
|
+
/** Connection establishment timeout in milliseconds. Defaults to `timeout`. */
|
|
249
|
+
connectTimeout?: number;
|
|
250
|
+
/** Maximum number of retries for transient errors (default: 3).
|
|
251
|
+
* Ignored when `retryBackoff` is provided. */
|
|
238
252
|
maxRetries?: number;
|
|
253
|
+
/** Fine-grained retry and backoff configuration.
|
|
254
|
+
* When provided, `maxRetries` is ignored in favour of `retryBackoff.maxRetries`. */
|
|
255
|
+
retryBackoff?: RetryConfig;
|
|
239
256
|
/** Additional headers */
|
|
240
257
|
headers?: Record<string, string>;
|
|
241
258
|
}
|
|
@@ -966,6 +983,8 @@ interface CrossAgentNetworkResponse {
|
|
|
966
983
|
nodes: AgentNetworkNode[];
|
|
967
984
|
edges: AgentNetworkEdge[];
|
|
968
985
|
stats: AgentNetworkStats;
|
|
986
|
+
/** Total number of memory nodes in the network (added in server v0.6.2). */
|
|
987
|
+
node_count: number;
|
|
969
988
|
}
|
|
970
989
|
/** Request body for POST /v1/knowledge/network/cross-agent */
|
|
971
990
|
interface CrossAgentNetworkRequest {
|
|
@@ -1044,6 +1063,74 @@ interface KeyUsage {
|
|
|
1044
1063
|
last_used?: string;
|
|
1045
1064
|
requests_by_endpoint?: Record<string, number>;
|
|
1046
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Rate-limit and quota headers present on every API response (OPS-1).
|
|
1068
|
+
*
|
|
1069
|
+
* Fields are `undefined` when the server does not include the header
|
|
1070
|
+
* (e.g. non-namespaced endpoints where quota does not apply).
|
|
1071
|
+
*/
|
|
1072
|
+
interface RateLimitHeaders {
|
|
1073
|
+
/** `X-RateLimit-Limit` — max requests allowed in the current window. */
|
|
1074
|
+
limit?: number;
|
|
1075
|
+
/** `X-RateLimit-Remaining` — requests left in the current window. */
|
|
1076
|
+
remaining?: number;
|
|
1077
|
+
/** `X-RateLimit-Reset` — Unix timestamp (seconds) when the window resets. */
|
|
1078
|
+
reset?: number;
|
|
1079
|
+
/** `X-Quota-Used` — namespace vectors / storage consumed. */
|
|
1080
|
+
quotaUsed?: number;
|
|
1081
|
+
/** `X-Quota-Limit` — namespace quota ceiling. */
|
|
1082
|
+
quotaLimit?: number;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Filter predicates for batch memory operations (CE-2).
|
|
1086
|
+
*
|
|
1087
|
+
* All fields are optional. For `batchForget` at least one must be set
|
|
1088
|
+
* (server-side safety guard).
|
|
1089
|
+
*/
|
|
1090
|
+
interface BatchMemoryFilter {
|
|
1091
|
+
/** Restrict to memories that carry **all** listed tags. */
|
|
1092
|
+
tags?: string[];
|
|
1093
|
+
/** Minimum importance (inclusive). */
|
|
1094
|
+
min_importance?: number;
|
|
1095
|
+
/** Maximum importance (inclusive). */
|
|
1096
|
+
max_importance?: number;
|
|
1097
|
+
/** Only memories created at or after this Unix timestamp (seconds). */
|
|
1098
|
+
created_after?: number;
|
|
1099
|
+
/** Only memories created before or at this Unix timestamp (seconds). */
|
|
1100
|
+
created_before?: number;
|
|
1101
|
+
/** Restrict to a specific memory type. */
|
|
1102
|
+
memory_type?: MemoryType;
|
|
1103
|
+
/** Restrict to memories from a specific session. */
|
|
1104
|
+
session_id?: string;
|
|
1105
|
+
}
|
|
1106
|
+
/** Request body for `POST /v1/memories/recall/batch`. */
|
|
1107
|
+
interface BatchRecallRequest {
|
|
1108
|
+
/** Agent whose memory namespace to search. */
|
|
1109
|
+
agent_id: string;
|
|
1110
|
+
/** Filter predicates to apply. An empty object returns all memories up to `limit`. */
|
|
1111
|
+
filter?: BatchMemoryFilter;
|
|
1112
|
+
/** Maximum number of results to return (default: 100). */
|
|
1113
|
+
limit?: number;
|
|
1114
|
+
}
|
|
1115
|
+
/** Response from `POST /v1/memories/recall/batch`. */
|
|
1116
|
+
interface BatchRecallResponse {
|
|
1117
|
+
memories: Memory[];
|
|
1118
|
+
/** Total memories in the agent namespace. */
|
|
1119
|
+
total: number;
|
|
1120
|
+
/** Number of memories that passed the filter. */
|
|
1121
|
+
filtered: number;
|
|
1122
|
+
}
|
|
1123
|
+
/** Request body for `DELETE /v1/memories/forget/batch`. */
|
|
1124
|
+
interface BatchForgetRequest {
|
|
1125
|
+
/** Agent whose memory namespace to purge from. */
|
|
1126
|
+
agent_id: string;
|
|
1127
|
+
/** Filter predicates — **at least one must be set** (server safety guard). */
|
|
1128
|
+
filter: BatchMemoryFilter;
|
|
1129
|
+
}
|
|
1130
|
+
/** Response from `DELETE /v1/memories/forget/batch`. */
|
|
1131
|
+
interface BatchForgetResponse {
|
|
1132
|
+
deleted_count: number;
|
|
1133
|
+
}
|
|
1047
1134
|
|
|
1048
1135
|
/**
|
|
1049
1136
|
* Dakera Client
|
|
@@ -1072,17 +1159,28 @@ declare class DakeraClient {
|
|
|
1072
1159
|
private readonly baseUrl;
|
|
1073
1160
|
private readonly apiKey?;
|
|
1074
1161
|
private readonly timeout;
|
|
1075
|
-
private readonly
|
|
1162
|
+
private readonly connectTimeout;
|
|
1163
|
+
private readonly retryConfig;
|
|
1076
1164
|
private readonly headers;
|
|
1165
|
+
/** OPS-1: rate-limit headers from the most recent API response. */
|
|
1166
|
+
private _lastRateLimitHeaders;
|
|
1077
1167
|
constructor(options: ClientOptions | string);
|
|
1078
1168
|
/**
|
|
1079
|
-
*
|
|
1169
|
+
* Rate-limit headers from the most recent API response (OPS-1).
|
|
1170
|
+
*
|
|
1171
|
+
* Returns `null` until the first successful request has been made.
|
|
1172
|
+
*/
|
|
1173
|
+
get lastRateLimitHeaders(): RateLimitHeaders | null;
|
|
1174
|
+
private computeBackoff;
|
|
1175
|
+
/**
|
|
1176
|
+
* Make an HTTP request with retry logic and exponential backoff.
|
|
1080
1177
|
*/
|
|
1081
1178
|
private request;
|
|
1082
1179
|
/**
|
|
1083
1180
|
* Handle HTTP response and throw appropriate errors.
|
|
1084
1181
|
*/
|
|
1085
1182
|
private handleResponse;
|
|
1183
|
+
private _parseHeaderInt;
|
|
1086
1184
|
private sleep;
|
|
1087
1185
|
/**
|
|
1088
1186
|
* Upsert vectors into a namespace.
|
|
@@ -1555,6 +1653,38 @@ declare class DakeraClient {
|
|
|
1555
1653
|
forget(agentId: string, memoryId: string): Promise<{
|
|
1556
1654
|
status: string;
|
|
1557
1655
|
}>;
|
|
1656
|
+
/**
|
|
1657
|
+
* Bulk-recall memories using filter predicates (CE-2).
|
|
1658
|
+
*
|
|
1659
|
+
* Uses `POST /v1/memories/recall/batch` — no embedding required.
|
|
1660
|
+
*
|
|
1661
|
+
* @example
|
|
1662
|
+
* ```typescript
|
|
1663
|
+
* const resp = await client.batchRecall({
|
|
1664
|
+
* agent_id: 'agent-1',
|
|
1665
|
+
* filter: { tags: ['preferences'], min_importance: 0.7 },
|
|
1666
|
+
* limit: 50,
|
|
1667
|
+
* });
|
|
1668
|
+
* console.log(`Found ${resp.filtered} memories`);
|
|
1669
|
+
* ```
|
|
1670
|
+
*/
|
|
1671
|
+
batchRecall(request: BatchRecallRequest): Promise<BatchRecallResponse>;
|
|
1672
|
+
/**
|
|
1673
|
+
* Bulk-delete memories using filter predicates (CE-2).
|
|
1674
|
+
*
|
|
1675
|
+
* Uses `DELETE /v1/memories/forget/batch`. At least one filter predicate
|
|
1676
|
+
* must be set (server safety guard).
|
|
1677
|
+
*
|
|
1678
|
+
* @example
|
|
1679
|
+
* ```typescript
|
|
1680
|
+
* const resp = await client.batchForget({
|
|
1681
|
+
* agent_id: 'agent-1',
|
|
1682
|
+
* filter: { created_before: Math.floor(Date.now() / 1000) - 86400 },
|
|
1683
|
+
* });
|
|
1684
|
+
* console.log(`Deleted ${resp.deleted_count} memories`);
|
|
1685
|
+
* ```
|
|
1686
|
+
*/
|
|
1687
|
+
batchForget(request: BatchForgetRequest): Promise<BatchForgetResponse>;
|
|
1558
1688
|
/** Search memories for an agent */
|
|
1559
1689
|
searchMemories(agentId: string, query: string, options?: {
|
|
1560
1690
|
top_k?: number;
|
|
@@ -1744,6 +1874,16 @@ declare class DakeraClient {
|
|
|
1744
1874
|
* ```
|
|
1745
1875
|
*/
|
|
1746
1876
|
streamMemoryEvents(): AsyncGenerator<MemoryEvent>;
|
|
1877
|
+
/**
|
|
1878
|
+
* Return a URL with `?api_key=<key>` appended for use with browser-native
|
|
1879
|
+
* `EventSource`, which cannot send custom request headers.
|
|
1880
|
+
*
|
|
1881
|
+
* @example
|
|
1882
|
+
* ```ts
|
|
1883
|
+
* const src = new EventSource(client.sseUrl('/v1/namespaces/my-ns/events'));
|
|
1884
|
+
* ```
|
|
1885
|
+
*/
|
|
1886
|
+
sseUrl(path: string): string;
|
|
1747
1887
|
/** Low-level SSE streaming helper — parses the SSE wire format. */
|
|
1748
1888
|
private _streamSse;
|
|
1749
1889
|
/** Parse a single SSE event block into a {@link DakeraEvent}. */
|
|
@@ -1822,4 +1962,4 @@ declare class TimeoutError extends DakeraError {
|
|
|
1822
1962
|
constructor(message: string);
|
|
1823
1963
|
}
|
|
1824
1964
|
|
|
1825
|
-
export { type AccessPatternHint, type AgentId, type AgentNetworkEdge, type AgentNetworkInfo, type AgentNetworkNode, type AgentNetworkStats, type AgentStats, type AgentSummary, type AggregationGroup, type AggregationRequest, type AggregationResponse, type AnalyticsOptions, type AnalyticsOverview, type ApiKey, AuthenticationError, AuthorizationError, type BackupInfo, type BatchQuerySpec, type BatchTextQueryOptions, type BatchTextQueryResponse, type Branded, type CacheStats, type ClientOptions, type ClusterNode, type ClusterStatus, type ColumnUpsertRequest, type ConfigureNamespaceRequest, type ConfigureNamespaceResponse, ConnectionError, type ConsolidateRequest, type ConsolidateResponse, type CreateKeyRequest, type CrossAgentNetworkRequest, type CrossAgentNetworkResponse, DakeraClient, DakeraError, type DakeraEvent, type DeduplicateRequest, type DeduplicateResponse, type DeleteOptions, type DeleteResponse, type DistanceMetric, type Document, type DocumentInput, type EmbeddingModel, ErrorCode, type ExportRequest, type ExportResponse, type ExportedVector, type FilterExpression, type FilterOperators, type FullKnowledgeGraphRequest, type FullTextSearchResult, type HealthResponse, type HybridSearchResult, type IndexStats, type JobProgressEvent, type KeyUsage, type KnowledgeEdge, type KnowledgeGraphRequest, type KnowledgeGraphResponse, type KnowledgeNode, type LatencyAnalytics, type ListSessionsOptions, type Memory, type MemoryEvent, type MemoryFeedbackRequest, type MemoryFeedbackResponse, type MemoryId, type MemoryType, type MultiVectorSearchRequest, type MultiVectorSearchResponse, type MultiVectorSearchResult, type NamespaceCreatedEvent, type NamespaceDeletedEvent, type NamespaceInfo, NotFoundError, type OpStatus, type OperationProgressEvent, type QueryExplainRequest, type QueryExplainResponse, type QueryOptions, type QueryResult, RateLimitError, type ReadConsistency, type RecallRequest, type RecalledMemory, type SearchResult, ServerError, type Session, type SessionId, type SlowQuery, type StalenessConfig, type StartSessionRequest, type StorageAnalytics, type StoreMemoryRequest, type StoreMemoryResponse, type StreamLaggedEvent, type SummarizeRequest, type SummarizeResponse, type TextDocument, type TextQueryOptions, type TextQueryResponse, type TextSearchResult, type TextUpsertOptions, type TextUpsertResponse, type ThroughputAnalytics, TimeoutError, type TtlConfig, type UnifiedQueryRequest, type UnifiedQueryResponse, type UnifiedSearchResult, type UpdateImportanceRequest, type UpdateMemoryRequest, type UpsertOptions, type UpsertResponse, ValidationError, type Vector, type VectorId, type VectorInput, type VectorMutationOp, type VectorsMutatedEvent, type WarmCacheRequest, type WarmCacheResponse, type WarmingPriority, type WarmingTargetTier, agentId, memoryId, sessionId, vectorId };
|
|
1965
|
+
export { type AccessPatternHint, type AgentId, type AgentNetworkEdge, type AgentNetworkInfo, type AgentNetworkNode, type AgentNetworkStats, type AgentStats, type AgentSummary, type AggregationGroup, type AggregationRequest, type AggregationResponse, type AnalyticsOptions, type AnalyticsOverview, type ApiKey, AuthenticationError, AuthorizationError, type BackupInfo, type BatchForgetRequest, type BatchForgetResponse, type BatchMemoryFilter, type BatchQuerySpec, type BatchRecallRequest, type BatchRecallResponse, type BatchTextQueryOptions, type BatchTextQueryResponse, type Branded, type CacheStats, type ClientOptions, type ClusterNode, type ClusterStatus, type ColumnUpsertRequest, type ConfigureNamespaceRequest, type ConfigureNamespaceResponse, ConnectionError, type ConsolidateRequest, type ConsolidateResponse, type CreateKeyRequest, type CrossAgentNetworkRequest, type CrossAgentNetworkResponse, DakeraClient, DakeraError, type DakeraEvent, type DeduplicateRequest, type DeduplicateResponse, type DeleteOptions, type DeleteResponse, type DistanceMetric, type Document, type DocumentInput, type EmbeddingModel, ErrorCode, type ExportRequest, type ExportResponse, type ExportedVector, type FilterExpression, type FilterOperators, type FullKnowledgeGraphRequest, type FullTextSearchResult, type HealthResponse, type HybridSearchResult, type IndexStats, type JobProgressEvent, type KeyUsage, type KnowledgeEdge, type KnowledgeGraphRequest, type KnowledgeGraphResponse, type KnowledgeNode, type LatencyAnalytics, type ListSessionsOptions, type Memory, type MemoryEvent, type MemoryFeedbackRequest, type MemoryFeedbackResponse, type MemoryId, type MemoryType, type MultiVectorSearchRequest, type MultiVectorSearchResponse, type MultiVectorSearchResult, type NamespaceCreatedEvent, type NamespaceDeletedEvent, type NamespaceInfo, NotFoundError, type OpStatus, type OperationProgressEvent, type QueryExplainRequest, type QueryExplainResponse, type QueryOptions, type QueryResult, RateLimitError, type RateLimitHeaders, type ReadConsistency, type RecallRequest, type RecalledMemory, type RetryConfig, type SearchResult, ServerError, type Session, type SessionId, type SlowQuery, type StalenessConfig, type StartSessionRequest, type StorageAnalytics, type StoreMemoryRequest, type StoreMemoryResponse, type StreamLaggedEvent, type SummarizeRequest, type SummarizeResponse, type TextDocument, type TextQueryOptions, type TextQueryResponse, type TextSearchResult, type TextUpsertOptions, type TextUpsertResponse, type ThroughputAnalytics, TimeoutError, type TtlConfig, type UnifiedQueryRequest, type UnifiedQueryResponse, type UnifiedSearchResult, type UpdateImportanceRequest, type UpdateMemoryRequest, type UpsertOptions, type UpsertResponse, ValidationError, type Vector, type VectorId, type VectorInput, type VectorMutationOp, type VectorsMutatedEvent, type WarmCacheRequest, type WarmCacheResponse, type WarmingPriority, type WarmingTargetTier, agentId, memoryId, sessionId, vectorId };
|
package/dist/index.js
CHANGED
|
@@ -136,25 +136,34 @@ function parseErrorCode(raw) {
|
|
|
136
136
|
}
|
|
137
137
|
return "UNKNOWN" /* UNKNOWN */;
|
|
138
138
|
}
|
|
139
|
-
var
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
};
|
|
139
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
140
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
141
|
+
var DEFAULT_BASE_DELAY = 100;
|
|
142
|
+
var DEFAULT_MAX_DELAY = 6e4;
|
|
144
143
|
var DakeraClient = class {
|
|
145
144
|
baseUrl;
|
|
146
145
|
apiKey;
|
|
147
146
|
timeout;
|
|
148
|
-
|
|
147
|
+
connectTimeout;
|
|
148
|
+
retryConfig;
|
|
149
149
|
headers;
|
|
150
|
+
/** OPS-1: rate-limit headers from the most recent API response. */
|
|
151
|
+
_lastRateLimitHeaders = null;
|
|
150
152
|
constructor(options) {
|
|
151
153
|
if (typeof options === "string") {
|
|
152
154
|
options = { baseUrl: options };
|
|
153
155
|
}
|
|
154
156
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
155
157
|
this.apiKey = options.apiKey;
|
|
156
|
-
this.timeout = options.timeout ??
|
|
157
|
-
this.
|
|
158
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
159
|
+
this.connectTimeout = options.connectTimeout ?? this.timeout;
|
|
160
|
+
const rb = options.retryBackoff ?? {};
|
|
161
|
+
this.retryConfig = {
|
|
162
|
+
maxRetries: rb.maxRetries ?? options.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
163
|
+
baseDelay: rb.baseDelay ?? DEFAULT_BASE_DELAY,
|
|
164
|
+
maxDelay: rb.maxDelay ?? DEFAULT_MAX_DELAY,
|
|
165
|
+
jitter: rb.jitter ?? true
|
|
166
|
+
};
|
|
158
167
|
this.headers = {
|
|
159
168
|
"Content-Type": "application/json",
|
|
160
169
|
...options.headers
|
|
@@ -164,41 +173,73 @@ var DakeraClient = class {
|
|
|
164
173
|
}
|
|
165
174
|
}
|
|
166
175
|
/**
|
|
167
|
-
*
|
|
176
|
+
* Rate-limit headers from the most recent API response (OPS-1).
|
|
177
|
+
*
|
|
178
|
+
* Returns `null` until the first successful request has been made.
|
|
179
|
+
*/
|
|
180
|
+
get lastRateLimitHeaders() {
|
|
181
|
+
return this._lastRateLimitHeaders;
|
|
182
|
+
}
|
|
183
|
+
computeBackoff(attempt) {
|
|
184
|
+
const { baseDelay, maxDelay, jitter } = this.retryConfig;
|
|
185
|
+
let delay = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
|
|
186
|
+
if (jitter) {
|
|
187
|
+
delay *= 0.5 + Math.random();
|
|
188
|
+
}
|
|
189
|
+
return delay;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Make an HTTP request with retry logic and exponential backoff.
|
|
168
193
|
*/
|
|
169
194
|
async request(method, path, body) {
|
|
170
195
|
const url = `${this.baseUrl}${path}`;
|
|
196
|
+
const { maxRetries } = this.retryConfig;
|
|
197
|
+
const connectMs = Math.min(this.connectTimeout, this.timeout);
|
|
171
198
|
let lastError;
|
|
172
|
-
for (let attempt = 0; attempt <
|
|
199
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
173
200
|
try {
|
|
174
201
|
const controller = new AbortController();
|
|
175
|
-
const
|
|
202
|
+
const timerId = setTimeout(() => controller.abort(), connectMs);
|
|
176
203
|
const response = await fetch(url, {
|
|
177
204
|
method,
|
|
178
205
|
headers: this.headers,
|
|
179
206
|
body: body ? JSON.stringify(body) : void 0,
|
|
180
207
|
signal: controller.signal
|
|
181
208
|
});
|
|
182
|
-
clearTimeout(
|
|
209
|
+
clearTimeout(timerId);
|
|
183
210
|
return await this.handleResponse(response);
|
|
184
211
|
} catch (error) {
|
|
212
|
+
if (error instanceof RateLimitError) {
|
|
213
|
+
if (attempt === maxRetries - 1) throw error;
|
|
214
|
+
const wait = error.retryAfter != null ? error.retryAfter * 1e3 : this.computeBackoff(attempt);
|
|
215
|
+
await this.sleep(wait);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
185
218
|
if (error instanceof DakeraError) {
|
|
186
|
-
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500
|
|
219
|
+
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
if (attempt === maxRetries - 1) throw error;
|
|
223
|
+
lastError = error;
|
|
224
|
+
} else if (error instanceof Error) {
|
|
225
|
+
if (attempt === maxRetries - 1) {
|
|
226
|
+
if (error.name === "AbortError") {
|
|
227
|
+
throw new TimeoutError(`Request timed out after ${connectMs}ms`);
|
|
228
|
+
}
|
|
229
|
+
if (error.message.includes("fetch")) {
|
|
230
|
+
throw new ConnectionError(`Failed to connect to ${url}: ${error.message}`);
|
|
231
|
+
}
|
|
187
232
|
throw error;
|
|
188
233
|
}
|
|
189
|
-
}
|
|
190
|
-
if (error instanceof Error) {
|
|
191
234
|
if (error.name === "AbortError") {
|
|
192
|
-
lastError = new TimeoutError(`Request timed out after ${
|
|
235
|
+
lastError = new TimeoutError(`Request timed out after ${connectMs}ms`);
|
|
193
236
|
} else if (error.message.includes("fetch")) {
|
|
194
237
|
lastError = new ConnectionError(`Failed to connect to ${url}: ${error.message}`);
|
|
195
238
|
} else {
|
|
196
239
|
lastError = error;
|
|
197
240
|
}
|
|
198
241
|
}
|
|
199
|
-
|
|
200
|
-
await this.sleep(Math.pow(2, attempt) * 100);
|
|
201
|
-
}
|
|
242
|
+
await this.sleep(this.computeBackoff(attempt));
|
|
202
243
|
}
|
|
203
244
|
}
|
|
204
245
|
throw lastError ?? new DakeraError("Request failed after retries");
|
|
@@ -207,6 +248,13 @@ var DakeraClient = class {
|
|
|
207
248
|
* Handle HTTP response and throw appropriate errors.
|
|
208
249
|
*/
|
|
209
250
|
async handleResponse(response) {
|
|
251
|
+
this._lastRateLimitHeaders = {
|
|
252
|
+
limit: this._parseHeaderInt(response.headers.get("X-RateLimit-Limit")),
|
|
253
|
+
remaining: this._parseHeaderInt(response.headers.get("X-RateLimit-Remaining")),
|
|
254
|
+
reset: this._parseHeaderInt(response.headers.get("X-RateLimit-Reset")),
|
|
255
|
+
quotaUsed: this._parseHeaderInt(response.headers.get("X-Quota-Used")),
|
|
256
|
+
quotaLimit: this._parseHeaderInt(response.headers.get("X-Quota-Limit"))
|
|
257
|
+
};
|
|
210
258
|
let body;
|
|
211
259
|
const contentType = response.headers.get("content-type");
|
|
212
260
|
if (contentType?.includes("application/json")) {
|
|
@@ -247,6 +295,11 @@ var DakeraClient = class {
|
|
|
247
295
|
throw new DakeraError(errorMessage, response.status, body, code);
|
|
248
296
|
}
|
|
249
297
|
}
|
|
298
|
+
_parseHeaderInt(value) {
|
|
299
|
+
if (value === null) return void 0;
|
|
300
|
+
const n = parseInt(value, 10);
|
|
301
|
+
return isNaN(n) ? void 0 : n;
|
|
302
|
+
}
|
|
250
303
|
sleep(ms) {
|
|
251
304
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
252
305
|
}
|
|
@@ -1017,6 +1070,42 @@ var DakeraClient = class {
|
|
|
1017
1070
|
async forget(agentId2, memoryId2) {
|
|
1018
1071
|
return this.request("DELETE", `/v1/agents/${agentId2}/memories/${memoryId2}`);
|
|
1019
1072
|
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Bulk-recall memories using filter predicates (CE-2).
|
|
1075
|
+
*
|
|
1076
|
+
* Uses `POST /v1/memories/recall/batch` — no embedding required.
|
|
1077
|
+
*
|
|
1078
|
+
* @example
|
|
1079
|
+
* ```typescript
|
|
1080
|
+
* const resp = await client.batchRecall({
|
|
1081
|
+
* agent_id: 'agent-1',
|
|
1082
|
+
* filter: { tags: ['preferences'], min_importance: 0.7 },
|
|
1083
|
+
* limit: 50,
|
|
1084
|
+
* });
|
|
1085
|
+
* console.log(`Found ${resp.filtered} memories`);
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
async batchRecall(request) {
|
|
1089
|
+
return this.request("POST", "/v1/memories/recall/batch", request);
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Bulk-delete memories using filter predicates (CE-2).
|
|
1093
|
+
*
|
|
1094
|
+
* Uses `DELETE /v1/memories/forget/batch`. At least one filter predicate
|
|
1095
|
+
* must be set (server safety guard).
|
|
1096
|
+
*
|
|
1097
|
+
* @example
|
|
1098
|
+
* ```typescript
|
|
1099
|
+
* const resp = await client.batchForget({
|
|
1100
|
+
* agent_id: 'agent-1',
|
|
1101
|
+
* filter: { created_before: Math.floor(Date.now() / 1000) - 86400 },
|
|
1102
|
+
* });
|
|
1103
|
+
* console.log(`Deleted ${resp.deleted_count} memories`);
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
1106
|
+
async batchForget(request) {
|
|
1107
|
+
return this.request("DELETE", "/v1/memories/forget/batch", request);
|
|
1108
|
+
}
|
|
1020
1109
|
/** Search memories for an agent */
|
|
1021
1110
|
async searchMemories(agentId2, query, options) {
|
|
1022
1111
|
const body = { query, ...options };
|
|
@@ -1341,15 +1430,29 @@ var DakeraClient = class {
|
|
|
1341
1430
|
const url = `${this.baseUrl}/v1/events/stream`;
|
|
1342
1431
|
yield* this._streamSseMemory(url);
|
|
1343
1432
|
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Return a URL with `?api_key=<key>` appended for use with browser-native
|
|
1435
|
+
* `EventSource`, which cannot send custom request headers.
|
|
1436
|
+
*
|
|
1437
|
+
* @example
|
|
1438
|
+
* ```ts
|
|
1439
|
+
* const src = new EventSource(client.sseUrl('/v1/namespaces/my-ns/events'));
|
|
1440
|
+
* ```
|
|
1441
|
+
*/
|
|
1442
|
+
sseUrl(path) {
|
|
1443
|
+
const base = `${this.baseUrl}${path}`;
|
|
1444
|
+
if (!this.apiKey) return base;
|
|
1445
|
+
const sep = base.includes("?") ? "&" : "?";
|
|
1446
|
+
return `${base}${sep}api_key=${encodeURIComponent(this.apiKey)}`;
|
|
1447
|
+
}
|
|
1344
1448
|
/** Low-level SSE streaming helper — parses the SSE wire format. */
|
|
1345
1449
|
async *_streamSse(url) {
|
|
1450
|
+
const sseUrl = this.apiKey ? `${url}${url.includes("?") ? "&" : "?"}api_key=${encodeURIComponent(this.apiKey)}` : url;
|
|
1346
1451
|
const headers = {
|
|
1347
|
-
...this.headers,
|
|
1348
|
-
// includes Authorization and any custom headers
|
|
1349
1452
|
Accept: "text/event-stream",
|
|
1350
1453
|
"Cache-Control": "no-cache"
|
|
1351
1454
|
};
|
|
1352
|
-
const response = await fetch(
|
|
1455
|
+
const response = await fetch(sseUrl, { headers });
|
|
1353
1456
|
if (!response.ok || !response.body) {
|
|
1354
1457
|
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
1355
1458
|
}
|
|
@@ -1395,12 +1498,12 @@ var DakeraClient = class {
|
|
|
1395
1498
|
* so callers receive a fully-populated {@link MemoryEvent}.
|
|
1396
1499
|
*/
|
|
1397
1500
|
async *_streamSseMemory(url) {
|
|
1501
|
+
const sseUrl = this.apiKey ? `${url}${url.includes("?") ? "&" : "?"}api_key=${encodeURIComponent(this.apiKey)}` : url;
|
|
1398
1502
|
const headers = {
|
|
1399
|
-
...this.headers,
|
|
1400
1503
|
Accept: "text/event-stream",
|
|
1401
1504
|
"Cache-Control": "no-cache"
|
|
1402
1505
|
};
|
|
1403
|
-
const response = await fetch(
|
|
1506
|
+
const response = await fetch(sseUrl, { headers });
|
|
1404
1507
|
if (!response.ok || !response.body) {
|
|
1405
1508
|
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
1406
1509
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -96,25 +96,34 @@ function parseErrorCode(raw) {
|
|
|
96
96
|
}
|
|
97
97
|
return "UNKNOWN" /* UNKNOWN */;
|
|
98
98
|
}
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
};
|
|
99
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
100
|
+
var DEFAULT_MAX_RETRIES = 3;
|
|
101
|
+
var DEFAULT_BASE_DELAY = 100;
|
|
102
|
+
var DEFAULT_MAX_DELAY = 6e4;
|
|
104
103
|
var DakeraClient = class {
|
|
105
104
|
baseUrl;
|
|
106
105
|
apiKey;
|
|
107
106
|
timeout;
|
|
108
|
-
|
|
107
|
+
connectTimeout;
|
|
108
|
+
retryConfig;
|
|
109
109
|
headers;
|
|
110
|
+
/** OPS-1: rate-limit headers from the most recent API response. */
|
|
111
|
+
_lastRateLimitHeaders = null;
|
|
110
112
|
constructor(options) {
|
|
111
113
|
if (typeof options === "string") {
|
|
112
114
|
options = { baseUrl: options };
|
|
113
115
|
}
|
|
114
116
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
115
117
|
this.apiKey = options.apiKey;
|
|
116
|
-
this.timeout = options.timeout ??
|
|
117
|
-
this.
|
|
118
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
119
|
+
this.connectTimeout = options.connectTimeout ?? this.timeout;
|
|
120
|
+
const rb = options.retryBackoff ?? {};
|
|
121
|
+
this.retryConfig = {
|
|
122
|
+
maxRetries: rb.maxRetries ?? options.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
123
|
+
baseDelay: rb.baseDelay ?? DEFAULT_BASE_DELAY,
|
|
124
|
+
maxDelay: rb.maxDelay ?? DEFAULT_MAX_DELAY,
|
|
125
|
+
jitter: rb.jitter ?? true
|
|
126
|
+
};
|
|
118
127
|
this.headers = {
|
|
119
128
|
"Content-Type": "application/json",
|
|
120
129
|
...options.headers
|
|
@@ -124,41 +133,73 @@ var DakeraClient = class {
|
|
|
124
133
|
}
|
|
125
134
|
}
|
|
126
135
|
/**
|
|
127
|
-
*
|
|
136
|
+
* Rate-limit headers from the most recent API response (OPS-1).
|
|
137
|
+
*
|
|
138
|
+
* Returns `null` until the first successful request has been made.
|
|
139
|
+
*/
|
|
140
|
+
get lastRateLimitHeaders() {
|
|
141
|
+
return this._lastRateLimitHeaders;
|
|
142
|
+
}
|
|
143
|
+
computeBackoff(attempt) {
|
|
144
|
+
const { baseDelay, maxDelay, jitter } = this.retryConfig;
|
|
145
|
+
let delay = Math.min(maxDelay, baseDelay * Math.pow(2, attempt));
|
|
146
|
+
if (jitter) {
|
|
147
|
+
delay *= 0.5 + Math.random();
|
|
148
|
+
}
|
|
149
|
+
return delay;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Make an HTTP request with retry logic and exponential backoff.
|
|
128
153
|
*/
|
|
129
154
|
async request(method, path, body) {
|
|
130
155
|
const url = `${this.baseUrl}${path}`;
|
|
156
|
+
const { maxRetries } = this.retryConfig;
|
|
157
|
+
const connectMs = Math.min(this.connectTimeout, this.timeout);
|
|
131
158
|
let lastError;
|
|
132
|
-
for (let attempt = 0; attempt <
|
|
159
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
133
160
|
try {
|
|
134
161
|
const controller = new AbortController();
|
|
135
|
-
const
|
|
162
|
+
const timerId = setTimeout(() => controller.abort(), connectMs);
|
|
136
163
|
const response = await fetch(url, {
|
|
137
164
|
method,
|
|
138
165
|
headers: this.headers,
|
|
139
166
|
body: body ? JSON.stringify(body) : void 0,
|
|
140
167
|
signal: controller.signal
|
|
141
168
|
});
|
|
142
|
-
clearTimeout(
|
|
169
|
+
clearTimeout(timerId);
|
|
143
170
|
return await this.handleResponse(response);
|
|
144
171
|
} catch (error) {
|
|
172
|
+
if (error instanceof RateLimitError) {
|
|
173
|
+
if (attempt === maxRetries - 1) throw error;
|
|
174
|
+
const wait = error.retryAfter != null ? error.retryAfter * 1e3 : this.computeBackoff(attempt);
|
|
175
|
+
await this.sleep(wait);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
145
178
|
if (error instanceof DakeraError) {
|
|
146
|
-
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500
|
|
179
|
+
if (error.statusCode && error.statusCode >= 400 && error.statusCode < 500) {
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
if (attempt === maxRetries - 1) throw error;
|
|
183
|
+
lastError = error;
|
|
184
|
+
} else if (error instanceof Error) {
|
|
185
|
+
if (attempt === maxRetries - 1) {
|
|
186
|
+
if (error.name === "AbortError") {
|
|
187
|
+
throw new TimeoutError(`Request timed out after ${connectMs}ms`);
|
|
188
|
+
}
|
|
189
|
+
if (error.message.includes("fetch")) {
|
|
190
|
+
throw new ConnectionError(`Failed to connect to ${url}: ${error.message}`);
|
|
191
|
+
}
|
|
147
192
|
throw error;
|
|
148
193
|
}
|
|
149
|
-
}
|
|
150
|
-
if (error instanceof Error) {
|
|
151
194
|
if (error.name === "AbortError") {
|
|
152
|
-
lastError = new TimeoutError(`Request timed out after ${
|
|
195
|
+
lastError = new TimeoutError(`Request timed out after ${connectMs}ms`);
|
|
153
196
|
} else if (error.message.includes("fetch")) {
|
|
154
197
|
lastError = new ConnectionError(`Failed to connect to ${url}: ${error.message}`);
|
|
155
198
|
} else {
|
|
156
199
|
lastError = error;
|
|
157
200
|
}
|
|
158
201
|
}
|
|
159
|
-
|
|
160
|
-
await this.sleep(Math.pow(2, attempt) * 100);
|
|
161
|
-
}
|
|
202
|
+
await this.sleep(this.computeBackoff(attempt));
|
|
162
203
|
}
|
|
163
204
|
}
|
|
164
205
|
throw lastError ?? new DakeraError("Request failed after retries");
|
|
@@ -167,6 +208,13 @@ var DakeraClient = class {
|
|
|
167
208
|
* Handle HTTP response and throw appropriate errors.
|
|
168
209
|
*/
|
|
169
210
|
async handleResponse(response) {
|
|
211
|
+
this._lastRateLimitHeaders = {
|
|
212
|
+
limit: this._parseHeaderInt(response.headers.get("X-RateLimit-Limit")),
|
|
213
|
+
remaining: this._parseHeaderInt(response.headers.get("X-RateLimit-Remaining")),
|
|
214
|
+
reset: this._parseHeaderInt(response.headers.get("X-RateLimit-Reset")),
|
|
215
|
+
quotaUsed: this._parseHeaderInt(response.headers.get("X-Quota-Used")),
|
|
216
|
+
quotaLimit: this._parseHeaderInt(response.headers.get("X-Quota-Limit"))
|
|
217
|
+
};
|
|
170
218
|
let body;
|
|
171
219
|
const contentType = response.headers.get("content-type");
|
|
172
220
|
if (contentType?.includes("application/json")) {
|
|
@@ -207,6 +255,11 @@ var DakeraClient = class {
|
|
|
207
255
|
throw new DakeraError(errorMessage, response.status, body, code);
|
|
208
256
|
}
|
|
209
257
|
}
|
|
258
|
+
_parseHeaderInt(value) {
|
|
259
|
+
if (value === null) return void 0;
|
|
260
|
+
const n = parseInt(value, 10);
|
|
261
|
+
return isNaN(n) ? void 0 : n;
|
|
262
|
+
}
|
|
210
263
|
sleep(ms) {
|
|
211
264
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
212
265
|
}
|
|
@@ -977,6 +1030,42 @@ var DakeraClient = class {
|
|
|
977
1030
|
async forget(agentId2, memoryId2) {
|
|
978
1031
|
return this.request("DELETE", `/v1/agents/${agentId2}/memories/${memoryId2}`);
|
|
979
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Bulk-recall memories using filter predicates (CE-2).
|
|
1035
|
+
*
|
|
1036
|
+
* Uses `POST /v1/memories/recall/batch` — no embedding required.
|
|
1037
|
+
*
|
|
1038
|
+
* @example
|
|
1039
|
+
* ```typescript
|
|
1040
|
+
* const resp = await client.batchRecall({
|
|
1041
|
+
* agent_id: 'agent-1',
|
|
1042
|
+
* filter: { tags: ['preferences'], min_importance: 0.7 },
|
|
1043
|
+
* limit: 50,
|
|
1044
|
+
* });
|
|
1045
|
+
* console.log(`Found ${resp.filtered} memories`);
|
|
1046
|
+
* ```
|
|
1047
|
+
*/
|
|
1048
|
+
async batchRecall(request) {
|
|
1049
|
+
return this.request("POST", "/v1/memories/recall/batch", request);
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Bulk-delete memories using filter predicates (CE-2).
|
|
1053
|
+
*
|
|
1054
|
+
* Uses `DELETE /v1/memories/forget/batch`. At least one filter predicate
|
|
1055
|
+
* must be set (server safety guard).
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```typescript
|
|
1059
|
+
* const resp = await client.batchForget({
|
|
1060
|
+
* agent_id: 'agent-1',
|
|
1061
|
+
* filter: { created_before: Math.floor(Date.now() / 1000) - 86400 },
|
|
1062
|
+
* });
|
|
1063
|
+
* console.log(`Deleted ${resp.deleted_count} memories`);
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
async batchForget(request) {
|
|
1067
|
+
return this.request("DELETE", "/v1/memories/forget/batch", request);
|
|
1068
|
+
}
|
|
980
1069
|
/** Search memories for an agent */
|
|
981
1070
|
async searchMemories(agentId2, query, options) {
|
|
982
1071
|
const body = { query, ...options };
|
|
@@ -1301,15 +1390,29 @@ var DakeraClient = class {
|
|
|
1301
1390
|
const url = `${this.baseUrl}/v1/events/stream`;
|
|
1302
1391
|
yield* this._streamSseMemory(url);
|
|
1303
1392
|
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Return a URL with `?api_key=<key>` appended for use with browser-native
|
|
1395
|
+
* `EventSource`, which cannot send custom request headers.
|
|
1396
|
+
*
|
|
1397
|
+
* @example
|
|
1398
|
+
* ```ts
|
|
1399
|
+
* const src = new EventSource(client.sseUrl('/v1/namespaces/my-ns/events'));
|
|
1400
|
+
* ```
|
|
1401
|
+
*/
|
|
1402
|
+
sseUrl(path) {
|
|
1403
|
+
const base = `${this.baseUrl}${path}`;
|
|
1404
|
+
if (!this.apiKey) return base;
|
|
1405
|
+
const sep = base.includes("?") ? "&" : "?";
|
|
1406
|
+
return `${base}${sep}api_key=${encodeURIComponent(this.apiKey)}`;
|
|
1407
|
+
}
|
|
1304
1408
|
/** Low-level SSE streaming helper — parses the SSE wire format. */
|
|
1305
1409
|
async *_streamSse(url) {
|
|
1410
|
+
const sseUrl = this.apiKey ? `${url}${url.includes("?") ? "&" : "?"}api_key=${encodeURIComponent(this.apiKey)}` : url;
|
|
1306
1411
|
const headers = {
|
|
1307
|
-
...this.headers,
|
|
1308
|
-
// includes Authorization and any custom headers
|
|
1309
1412
|
Accept: "text/event-stream",
|
|
1310
1413
|
"Cache-Control": "no-cache"
|
|
1311
1414
|
};
|
|
1312
|
-
const response = await fetch(
|
|
1415
|
+
const response = await fetch(sseUrl, { headers });
|
|
1313
1416
|
if (!response.ok || !response.body) {
|
|
1314
1417
|
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
1315
1418
|
}
|
|
@@ -1355,12 +1458,12 @@ var DakeraClient = class {
|
|
|
1355
1458
|
* so callers receive a fully-populated {@link MemoryEvent}.
|
|
1356
1459
|
*/
|
|
1357
1460
|
async *_streamSseMemory(url) {
|
|
1461
|
+
const sseUrl = this.apiKey ? `${url}${url.includes("?") ? "&" : "?"}api_key=${encodeURIComponent(this.apiKey)}` : url;
|
|
1358
1462
|
const headers = {
|
|
1359
|
-
...this.headers,
|
|
1360
1463
|
Accept: "text/event-stream",
|
|
1361
1464
|
"Cache-Control": "no-cache"
|
|
1362
1465
|
};
|
|
1363
|
-
const response = await fetch(
|
|
1466
|
+
const response = await fetch(sseUrl, { headers });
|
|
1364
1467
|
if (!response.ok || !response.body) {
|
|
1365
1468
|
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
1366
1469
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dakera-ai/dakera",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "TypeScript/JavaScript SDK for Dakera AI memory platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -57,3 +57,4 @@
|
|
|
57
57
|
"vitest": "^4.1.0"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
|