@usewhisper/sdk 3.8.0 → 3.9.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.
Files changed (5) hide show
  1. package/index.d.mts +179 -65
  2. package/index.d.ts +179 -65
  3. package/index.js +173 -75
  4. package/index.mjs +173 -75
  5. package/package.json +1 -1
package/index.d.mts CHANGED
@@ -1,3 +1,163 @@
1
+ type MemoryKind$1 = "factual" | "preference" | "event" | "relationship" | "opinion" | "goal" | "instruction" | "episodic" | "semantic" | "procedural";
2
+ interface MemoryLatencyBreakdown$1 {
3
+ cache_ms: number;
4
+ embed_ms: number;
5
+ vector_ms: number;
6
+ lexical_ms: number;
7
+ merge_ms: number;
8
+ total_ms: number;
9
+ }
10
+ interface MemorySearchResult {
11
+ memory: {
12
+ id: string;
13
+ content: string;
14
+ type: string;
15
+ entities?: string[];
16
+ confidence?: number;
17
+ version?: number;
18
+ temporal?: {
19
+ document_date?: string | null;
20
+ event_date?: string | null;
21
+ valid_from?: string | null;
22
+ valid_until?: string | null;
23
+ };
24
+ };
25
+ similarity: number;
26
+ relations?: Array<Record<string, unknown>>;
27
+ chunk?: {
28
+ id: string;
29
+ content: string;
30
+ metadata?: Record<string, unknown>;
31
+ };
32
+ }
33
+ interface MemorySearchResponse$1 {
34
+ results: MemorySearchResult[];
35
+ count: number;
36
+ query: string;
37
+ trace_id?: string;
38
+ latency_ms?: number;
39
+ latency_breakdown?: MemoryLatencyBreakdown$1;
40
+ fallback?: "vector" | "lexical";
41
+ mode?: "fast" | "balanced" | "quality";
42
+ profile?: "fast" | "balanced" | "quality";
43
+ include_pending?: boolean;
44
+ pending_overlay_count?: number;
45
+ cache_hit?: boolean;
46
+ }
47
+ interface MemoryWriteAck$1 {
48
+ success: boolean;
49
+ mode?: "async" | "sync";
50
+ trace_id?: string;
51
+ memory_id?: string;
52
+ job_id?: string;
53
+ status_url?: string;
54
+ accepted_at?: string;
55
+ visibility_sla_ms?: number;
56
+ pending_visibility?: boolean;
57
+ semantic_status?: "pending" | "ready";
58
+ queued?: boolean;
59
+ event_id?: string;
60
+ created?: number;
61
+ errors?: string[];
62
+ }
63
+ type LearnIngestionProfile = "auto" | "repo" | "web_docs" | "pdf_layout" | "video_transcript" | "plain_text";
64
+ type LearnStrategyOverride = "fixed" | "recursive" | "semantic" | "hierarchical" | "adaptive";
65
+ type LearnSourceType = "github" | "web" | "playwright" | "pdf" | "local" | "slack" | "video";
66
+ interface LearnConversationInput {
67
+ mode: "conversation";
68
+ project?: string;
69
+ user_id?: string;
70
+ session_id: string;
71
+ messages: Array<{
72
+ role: string;
73
+ content: string;
74
+ timestamp?: string;
75
+ }>;
76
+ }
77
+ interface LearnTextInput {
78
+ mode: "text";
79
+ project?: string;
80
+ title: string;
81
+ content: string;
82
+ metadata?: Record<string, unknown>;
83
+ tags?: string[];
84
+ namespace?: string;
85
+ options?: {
86
+ async?: boolean;
87
+ ingestion_profile?: LearnIngestionProfile;
88
+ strategy_override?: LearnStrategyOverride;
89
+ profile_config?: Record<string, unknown>;
90
+ };
91
+ }
92
+ interface LearnSourceInput {
93
+ mode: "source";
94
+ project?: string;
95
+ type: LearnSourceType;
96
+ name?: string;
97
+ metadata?: Record<string, string>;
98
+ owner?: string;
99
+ repo?: string;
100
+ branch?: string;
101
+ paths?: string[];
102
+ url?: string;
103
+ file_path?: string;
104
+ path?: string;
105
+ channel_ids?: string[];
106
+ since?: string;
107
+ token?: string;
108
+ auth_ref?: string;
109
+ platform?: "youtube" | "loom" | "generic";
110
+ language?: string;
111
+ options?: {
112
+ async?: boolean;
113
+ auto_index?: boolean;
114
+ ingestion_profile?: LearnIngestionProfile;
115
+ strategy_override?: LearnStrategyOverride;
116
+ profile_config?: Record<string, unknown>;
117
+ crawl_depth?: number;
118
+ include_paths?: string[];
119
+ exclude_paths?: string[];
120
+ glob?: string;
121
+ max_files?: number;
122
+ max_pages?: number;
123
+ extract_mode?: "text" | "structured" | "markdown";
124
+ workspace_id?: string;
125
+ allow_stt_fallback?: boolean;
126
+ max_duration_minutes?: number;
127
+ max_chunks?: number;
128
+ };
129
+ }
130
+ type LearnInput = LearnConversationInput | LearnTextInput | LearnSourceInput;
131
+ interface LearnConversationResult {
132
+ success: true;
133
+ mode: "conversation";
134
+ project: string;
135
+ scope_mode: "user_session" | "session_only";
136
+ memories_created: number;
137
+ relations_created: number;
138
+ memories_invalidated: number;
139
+ errors?: string[];
140
+ }
141
+ interface LearnTextResult {
142
+ success: true;
143
+ mode: "text";
144
+ project: string;
145
+ status: "processing" | "completed";
146
+ job_id?: string | null;
147
+ chunks_indexed?: number;
148
+ source_id?: string | null;
149
+ }
150
+ interface LearnSourceResult {
151
+ success: true;
152
+ mode: "source";
153
+ project: string;
154
+ source_id: string;
155
+ status: string;
156
+ job_id?: string | null;
157
+ index_started: boolean;
158
+ }
159
+ type LearnResult = LearnConversationResult | LearnTextResult | LearnSourceResult;
160
+
1
161
  /**
2
162
  * Whisper - Simple Memory Layer for AI Agents
3
163
  *
@@ -155,6 +315,7 @@ declare class Whisper {
155
315
  userId?: string;
156
316
  sessionId?: string;
157
317
  project?: string;
318
+ auto_learn?: boolean;
158
319
  }): Promise<{
159
320
  success: boolean;
160
321
  extracted: number;
@@ -169,12 +330,14 @@ declare class Whisper {
169
330
  sessionId?: string;
170
331
  project?: string;
171
332
  limit?: number;
333
+ auto_learn?: boolean;
172
334
  }): Promise<{
173
335
  response: string;
174
336
  context: string;
175
337
  count: number;
176
338
  extracted: number;
177
339
  }>;
340
+ learn(input: LearnInput): Promise<LearnResult>;
178
341
  /**
179
342
  * Direct access to WhisperContext for advanced usage
180
343
  */
@@ -367,69 +530,6 @@ declare class SearchResponseCache<T = unknown> {
367
530
  private deleteByKey;
368
531
  }
369
532
 
370
- type MemoryKind$1 = "factual" | "preference" | "event" | "relationship" | "opinion" | "goal" | "instruction" | "episodic" | "semantic" | "procedural";
371
- interface MemoryLatencyBreakdown$1 {
372
- cache_ms: number;
373
- embed_ms: number;
374
- vector_ms: number;
375
- lexical_ms: number;
376
- merge_ms: number;
377
- total_ms: number;
378
- }
379
- interface MemorySearchResult {
380
- memory: {
381
- id: string;
382
- content: string;
383
- type: string;
384
- entities?: string[];
385
- confidence?: number;
386
- version?: number;
387
- temporal?: {
388
- document_date?: string | null;
389
- event_date?: string | null;
390
- valid_from?: string | null;
391
- valid_until?: string | null;
392
- };
393
- };
394
- similarity: number;
395
- relations?: Array<Record<string, unknown>>;
396
- chunk?: {
397
- id: string;
398
- content: string;
399
- metadata?: Record<string, unknown>;
400
- };
401
- }
402
- interface MemorySearchResponse$1 {
403
- results: MemorySearchResult[];
404
- count: number;
405
- query: string;
406
- trace_id?: string;
407
- latency_ms?: number;
408
- latency_breakdown?: MemoryLatencyBreakdown$1;
409
- fallback?: "vector" | "lexical";
410
- mode?: "fast" | "balanced" | "quality";
411
- profile?: "fast" | "balanced" | "quality";
412
- include_pending?: boolean;
413
- pending_overlay_count?: number;
414
- cache_hit?: boolean;
415
- }
416
- interface MemoryWriteAck$1 {
417
- success: boolean;
418
- mode?: "async" | "sync";
419
- trace_id?: string;
420
- memory_id?: string;
421
- job_id?: string;
422
- status_url?: string;
423
- accepted_at?: string;
424
- visibility_sla_ms?: number;
425
- pending_visibility?: boolean;
426
- semantic_status?: "pending" | "ready";
427
- queued?: boolean;
428
- event_id?: string;
429
- created?: number;
430
- errors?: string[];
431
- }
432
-
433
533
  interface MemoryModuleOptions {
434
534
  defaultProject?: string;
435
535
  cacheEnabled?: boolean;
@@ -896,8 +996,10 @@ declare class WhisperAgentRuntime {
896
996
  success: true;
897
997
  buffered: true;
898
998
  }>;
999
+ private resolveLearningScope;
899
1000
  afterTurn(input: TurnInput & {
900
1001
  assistantMessage: string;
1002
+ auto_learn?: boolean;
901
1003
  }, context?: Partial<AgentRunContext>): Promise<TurnCaptureResult>;
902
1004
  flush(reason?: string, context?: Partial<AgentRunContext>): Promise<AgentRuntimeStatus>;
903
1005
  status(): AgentRuntimeStatus;
@@ -1027,6 +1129,7 @@ declare class WhisperClient {
1027
1129
  memories_invalidated: number;
1028
1130
  errors?: string[];
1029
1131
  } & MemoryWriteAck$1>;
1132
+ learn(params: LearnInput): Promise<LearnResult>;
1030
1133
  createAgentRuntime(options?: AgentRuntimeOptions): WhisperAgentRuntime;
1031
1134
  withRunContext(context: RunContext): {
1032
1135
  memory: {
@@ -1051,6 +1154,7 @@ declare class WhisperClient {
1051
1154
  sequence: number;
1052
1155
  }>;
1053
1156
  };
1157
+ learn: (params: LearnInput) => Promise<LearnResult>;
1054
1158
  queue: {
1055
1159
  flush: () => Promise<void>;
1056
1160
  status: () => ReturnType<WriteQueue["status"]>;
@@ -1079,6 +1183,7 @@ interface AgentTurnParams {
1079
1183
  sessionId?: string;
1080
1184
  project?: string;
1081
1185
  contextLimit?: number;
1186
+ auto_learn?: boolean;
1082
1187
  }
1083
1188
  interface AgentTurnResult {
1084
1189
  prompt: string;
@@ -1111,6 +1216,7 @@ declare class WhisperAgentMiddleware {
1111
1216
  userId?: string;
1112
1217
  sessionId?: string;
1113
1218
  project?: string;
1219
+ auto_learn?: boolean;
1114
1220
  }): Promise<{
1115
1221
  success: boolean;
1116
1222
  extracted: number;
@@ -1357,7 +1463,7 @@ interface VideoIngestionStatus {
1357
1463
  last_error?: string | null;
1358
1464
  updated_at?: string;
1359
1465
  }
1360
- type CanonicalSourceType = "github" | "web" | "pdf" | "local" | "slack";
1466
+ type CanonicalSourceType = "github" | "web" | "playwright" | "pdf" | "local" | "slack" | "video";
1361
1467
  interface CanonicalSourceCreateParams {
1362
1468
  type: CanonicalSourceType;
1363
1469
  name?: string;
@@ -1378,11 +1484,18 @@ interface CanonicalSourceCreateParams {
1378
1484
  path?: string;
1379
1485
  glob?: string;
1380
1486
  max_files?: number;
1487
+ max_pages?: number;
1488
+ extract_mode?: "text" | "structured" | "markdown";
1381
1489
  workspace_id?: string;
1382
1490
  channel_ids?: string[];
1383
1491
  since?: string;
1384
1492
  token?: string;
1385
1493
  auth_ref?: string;
1494
+ platform?: "youtube" | "loom" | "generic";
1495
+ language?: string;
1496
+ allow_stt_fallback?: boolean;
1497
+ max_duration_minutes?: number;
1498
+ max_chunks?: number;
1386
1499
  }
1387
1500
  interface CanonicalSourceCreateResult {
1388
1501
  source_id: string;
@@ -1600,6 +1713,7 @@ declare class WhisperContext {
1600
1713
  }): Promise<{
1601
1714
  ingested: number;
1602
1715
  }>;
1716
+ learn(params: LearnInput): Promise<LearnResult>;
1603
1717
  listMemories(params: {
1604
1718
  project?: string;
1605
1719
  user_id?: string;
@@ -2145,4 +2259,4 @@ declare class WhisperContext {
2145
2259
  };
2146
2260
  }
2147
2261
 
2148
- export { type AgentRunContext, type AgentRuntimeOptions, type AgentRuntimeRankWeights, type AgentRuntimeRetrievalOptions, type AgentRuntimeSourceActivityOptions, type AgentRuntimeStatus, type CanonicalSourceCreateParams, type CanonicalSourceCreateResult, type CanonicalSourceType, type ExtractedMemory, LangChainMemoryAdapter, LangGraphCheckpointAdapter, type Memory, type MemoryExtractionResult, type MemoryKind, type MemoryLatencyBreakdown, type MemorySearchResponse, type MemoryWriteAck, type MemoryWriteResult, type PreparedTurn, type Project, type QueryParams, type QueryResult, type Source, type TurnCaptureResult, type TurnInput, type VideoIngestionStatus, type VideoSourceMetadata, Whisper, WhisperAgentMiddleware, WhisperClient, type WhisperConfig, WhisperContext, Whisper as WhisperDefault, WhisperError, type WhisperErrorCode, WhisperClient as WhisperRuntimeClient, type WorkEvent, type WorkEventKind, type WorkEventSalience, createAgentMiddleware, createLangChainMemoryAdapter, createLangGraphCheckpointAdapter, WhisperContext as default, memoryGraphToMermaid };
2262
+ export { type AgentRunContext, type AgentRuntimeOptions, type AgentRuntimeRankWeights, type AgentRuntimeRetrievalOptions, type AgentRuntimeSourceActivityOptions, type AgentRuntimeStatus, type CanonicalSourceCreateParams, type CanonicalSourceCreateResult, type CanonicalSourceType, type ExtractedMemory, LangChainMemoryAdapter, LangGraphCheckpointAdapter, type LearnConversationInput, type LearnConversationResult, type LearnInput, type LearnResult, type LearnSourceInput, type LearnSourceResult, type LearnSourceType, type LearnTextInput, type LearnTextResult, type Memory, type MemoryExtractionResult, type MemoryKind, type MemoryLatencyBreakdown, type MemorySearchResponse, type MemoryWriteAck, type MemoryWriteResult, type PreparedTurn, type Project, type QueryParams, type QueryResult, type Source, type TurnCaptureResult, type TurnInput, type VideoIngestionStatus, type VideoSourceMetadata, Whisper, WhisperAgentMiddleware, WhisperClient, type WhisperConfig, WhisperContext, Whisper as WhisperDefault, WhisperError, type WhisperErrorCode, WhisperClient as WhisperRuntimeClient, type WorkEvent, type WorkEventKind, type WorkEventSalience, createAgentMiddleware, createLangChainMemoryAdapter, createLangGraphCheckpointAdapter, WhisperContext as default, memoryGraphToMermaid };
package/index.d.ts CHANGED
@@ -1,3 +1,163 @@
1
+ type MemoryKind$1 = "factual" | "preference" | "event" | "relationship" | "opinion" | "goal" | "instruction" | "episodic" | "semantic" | "procedural";
2
+ interface MemoryLatencyBreakdown$1 {
3
+ cache_ms: number;
4
+ embed_ms: number;
5
+ vector_ms: number;
6
+ lexical_ms: number;
7
+ merge_ms: number;
8
+ total_ms: number;
9
+ }
10
+ interface MemorySearchResult {
11
+ memory: {
12
+ id: string;
13
+ content: string;
14
+ type: string;
15
+ entities?: string[];
16
+ confidence?: number;
17
+ version?: number;
18
+ temporal?: {
19
+ document_date?: string | null;
20
+ event_date?: string | null;
21
+ valid_from?: string | null;
22
+ valid_until?: string | null;
23
+ };
24
+ };
25
+ similarity: number;
26
+ relations?: Array<Record<string, unknown>>;
27
+ chunk?: {
28
+ id: string;
29
+ content: string;
30
+ metadata?: Record<string, unknown>;
31
+ };
32
+ }
33
+ interface MemorySearchResponse$1 {
34
+ results: MemorySearchResult[];
35
+ count: number;
36
+ query: string;
37
+ trace_id?: string;
38
+ latency_ms?: number;
39
+ latency_breakdown?: MemoryLatencyBreakdown$1;
40
+ fallback?: "vector" | "lexical";
41
+ mode?: "fast" | "balanced" | "quality";
42
+ profile?: "fast" | "balanced" | "quality";
43
+ include_pending?: boolean;
44
+ pending_overlay_count?: number;
45
+ cache_hit?: boolean;
46
+ }
47
+ interface MemoryWriteAck$1 {
48
+ success: boolean;
49
+ mode?: "async" | "sync";
50
+ trace_id?: string;
51
+ memory_id?: string;
52
+ job_id?: string;
53
+ status_url?: string;
54
+ accepted_at?: string;
55
+ visibility_sla_ms?: number;
56
+ pending_visibility?: boolean;
57
+ semantic_status?: "pending" | "ready";
58
+ queued?: boolean;
59
+ event_id?: string;
60
+ created?: number;
61
+ errors?: string[];
62
+ }
63
+ type LearnIngestionProfile = "auto" | "repo" | "web_docs" | "pdf_layout" | "video_transcript" | "plain_text";
64
+ type LearnStrategyOverride = "fixed" | "recursive" | "semantic" | "hierarchical" | "adaptive";
65
+ type LearnSourceType = "github" | "web" | "playwright" | "pdf" | "local" | "slack" | "video";
66
+ interface LearnConversationInput {
67
+ mode: "conversation";
68
+ project?: string;
69
+ user_id?: string;
70
+ session_id: string;
71
+ messages: Array<{
72
+ role: string;
73
+ content: string;
74
+ timestamp?: string;
75
+ }>;
76
+ }
77
+ interface LearnTextInput {
78
+ mode: "text";
79
+ project?: string;
80
+ title: string;
81
+ content: string;
82
+ metadata?: Record<string, unknown>;
83
+ tags?: string[];
84
+ namespace?: string;
85
+ options?: {
86
+ async?: boolean;
87
+ ingestion_profile?: LearnIngestionProfile;
88
+ strategy_override?: LearnStrategyOverride;
89
+ profile_config?: Record<string, unknown>;
90
+ };
91
+ }
92
+ interface LearnSourceInput {
93
+ mode: "source";
94
+ project?: string;
95
+ type: LearnSourceType;
96
+ name?: string;
97
+ metadata?: Record<string, string>;
98
+ owner?: string;
99
+ repo?: string;
100
+ branch?: string;
101
+ paths?: string[];
102
+ url?: string;
103
+ file_path?: string;
104
+ path?: string;
105
+ channel_ids?: string[];
106
+ since?: string;
107
+ token?: string;
108
+ auth_ref?: string;
109
+ platform?: "youtube" | "loom" | "generic";
110
+ language?: string;
111
+ options?: {
112
+ async?: boolean;
113
+ auto_index?: boolean;
114
+ ingestion_profile?: LearnIngestionProfile;
115
+ strategy_override?: LearnStrategyOverride;
116
+ profile_config?: Record<string, unknown>;
117
+ crawl_depth?: number;
118
+ include_paths?: string[];
119
+ exclude_paths?: string[];
120
+ glob?: string;
121
+ max_files?: number;
122
+ max_pages?: number;
123
+ extract_mode?: "text" | "structured" | "markdown";
124
+ workspace_id?: string;
125
+ allow_stt_fallback?: boolean;
126
+ max_duration_minutes?: number;
127
+ max_chunks?: number;
128
+ };
129
+ }
130
+ type LearnInput = LearnConversationInput | LearnTextInput | LearnSourceInput;
131
+ interface LearnConversationResult {
132
+ success: true;
133
+ mode: "conversation";
134
+ project: string;
135
+ scope_mode: "user_session" | "session_only";
136
+ memories_created: number;
137
+ relations_created: number;
138
+ memories_invalidated: number;
139
+ errors?: string[];
140
+ }
141
+ interface LearnTextResult {
142
+ success: true;
143
+ mode: "text";
144
+ project: string;
145
+ status: "processing" | "completed";
146
+ job_id?: string | null;
147
+ chunks_indexed?: number;
148
+ source_id?: string | null;
149
+ }
150
+ interface LearnSourceResult {
151
+ success: true;
152
+ mode: "source";
153
+ project: string;
154
+ source_id: string;
155
+ status: string;
156
+ job_id?: string | null;
157
+ index_started: boolean;
158
+ }
159
+ type LearnResult = LearnConversationResult | LearnTextResult | LearnSourceResult;
160
+
1
161
  /**
2
162
  * Whisper - Simple Memory Layer for AI Agents
3
163
  *
@@ -155,6 +315,7 @@ declare class Whisper {
155
315
  userId?: string;
156
316
  sessionId?: string;
157
317
  project?: string;
318
+ auto_learn?: boolean;
158
319
  }): Promise<{
159
320
  success: boolean;
160
321
  extracted: number;
@@ -169,12 +330,14 @@ declare class Whisper {
169
330
  sessionId?: string;
170
331
  project?: string;
171
332
  limit?: number;
333
+ auto_learn?: boolean;
172
334
  }): Promise<{
173
335
  response: string;
174
336
  context: string;
175
337
  count: number;
176
338
  extracted: number;
177
339
  }>;
340
+ learn(input: LearnInput): Promise<LearnResult>;
178
341
  /**
179
342
  * Direct access to WhisperContext for advanced usage
180
343
  */
@@ -367,69 +530,6 @@ declare class SearchResponseCache<T = unknown> {
367
530
  private deleteByKey;
368
531
  }
369
532
 
370
- type MemoryKind$1 = "factual" | "preference" | "event" | "relationship" | "opinion" | "goal" | "instruction" | "episodic" | "semantic" | "procedural";
371
- interface MemoryLatencyBreakdown$1 {
372
- cache_ms: number;
373
- embed_ms: number;
374
- vector_ms: number;
375
- lexical_ms: number;
376
- merge_ms: number;
377
- total_ms: number;
378
- }
379
- interface MemorySearchResult {
380
- memory: {
381
- id: string;
382
- content: string;
383
- type: string;
384
- entities?: string[];
385
- confidence?: number;
386
- version?: number;
387
- temporal?: {
388
- document_date?: string | null;
389
- event_date?: string | null;
390
- valid_from?: string | null;
391
- valid_until?: string | null;
392
- };
393
- };
394
- similarity: number;
395
- relations?: Array<Record<string, unknown>>;
396
- chunk?: {
397
- id: string;
398
- content: string;
399
- metadata?: Record<string, unknown>;
400
- };
401
- }
402
- interface MemorySearchResponse$1 {
403
- results: MemorySearchResult[];
404
- count: number;
405
- query: string;
406
- trace_id?: string;
407
- latency_ms?: number;
408
- latency_breakdown?: MemoryLatencyBreakdown$1;
409
- fallback?: "vector" | "lexical";
410
- mode?: "fast" | "balanced" | "quality";
411
- profile?: "fast" | "balanced" | "quality";
412
- include_pending?: boolean;
413
- pending_overlay_count?: number;
414
- cache_hit?: boolean;
415
- }
416
- interface MemoryWriteAck$1 {
417
- success: boolean;
418
- mode?: "async" | "sync";
419
- trace_id?: string;
420
- memory_id?: string;
421
- job_id?: string;
422
- status_url?: string;
423
- accepted_at?: string;
424
- visibility_sla_ms?: number;
425
- pending_visibility?: boolean;
426
- semantic_status?: "pending" | "ready";
427
- queued?: boolean;
428
- event_id?: string;
429
- created?: number;
430
- errors?: string[];
431
- }
432
-
433
533
  interface MemoryModuleOptions {
434
534
  defaultProject?: string;
435
535
  cacheEnabled?: boolean;
@@ -896,8 +996,10 @@ declare class WhisperAgentRuntime {
896
996
  success: true;
897
997
  buffered: true;
898
998
  }>;
999
+ private resolveLearningScope;
899
1000
  afterTurn(input: TurnInput & {
900
1001
  assistantMessage: string;
1002
+ auto_learn?: boolean;
901
1003
  }, context?: Partial<AgentRunContext>): Promise<TurnCaptureResult>;
902
1004
  flush(reason?: string, context?: Partial<AgentRunContext>): Promise<AgentRuntimeStatus>;
903
1005
  status(): AgentRuntimeStatus;
@@ -1027,6 +1129,7 @@ declare class WhisperClient {
1027
1129
  memories_invalidated: number;
1028
1130
  errors?: string[];
1029
1131
  } & MemoryWriteAck$1>;
1132
+ learn(params: LearnInput): Promise<LearnResult>;
1030
1133
  createAgentRuntime(options?: AgentRuntimeOptions): WhisperAgentRuntime;
1031
1134
  withRunContext(context: RunContext): {
1032
1135
  memory: {
@@ -1051,6 +1154,7 @@ declare class WhisperClient {
1051
1154
  sequence: number;
1052
1155
  }>;
1053
1156
  };
1157
+ learn: (params: LearnInput) => Promise<LearnResult>;
1054
1158
  queue: {
1055
1159
  flush: () => Promise<void>;
1056
1160
  status: () => ReturnType<WriteQueue["status"]>;
@@ -1079,6 +1183,7 @@ interface AgentTurnParams {
1079
1183
  sessionId?: string;
1080
1184
  project?: string;
1081
1185
  contextLimit?: number;
1186
+ auto_learn?: boolean;
1082
1187
  }
1083
1188
  interface AgentTurnResult {
1084
1189
  prompt: string;
@@ -1111,6 +1216,7 @@ declare class WhisperAgentMiddleware {
1111
1216
  userId?: string;
1112
1217
  sessionId?: string;
1113
1218
  project?: string;
1219
+ auto_learn?: boolean;
1114
1220
  }): Promise<{
1115
1221
  success: boolean;
1116
1222
  extracted: number;
@@ -1357,7 +1463,7 @@ interface VideoIngestionStatus {
1357
1463
  last_error?: string | null;
1358
1464
  updated_at?: string;
1359
1465
  }
1360
- type CanonicalSourceType = "github" | "web" | "pdf" | "local" | "slack";
1466
+ type CanonicalSourceType = "github" | "web" | "playwright" | "pdf" | "local" | "slack" | "video";
1361
1467
  interface CanonicalSourceCreateParams {
1362
1468
  type: CanonicalSourceType;
1363
1469
  name?: string;
@@ -1378,11 +1484,18 @@ interface CanonicalSourceCreateParams {
1378
1484
  path?: string;
1379
1485
  glob?: string;
1380
1486
  max_files?: number;
1487
+ max_pages?: number;
1488
+ extract_mode?: "text" | "structured" | "markdown";
1381
1489
  workspace_id?: string;
1382
1490
  channel_ids?: string[];
1383
1491
  since?: string;
1384
1492
  token?: string;
1385
1493
  auth_ref?: string;
1494
+ platform?: "youtube" | "loom" | "generic";
1495
+ language?: string;
1496
+ allow_stt_fallback?: boolean;
1497
+ max_duration_minutes?: number;
1498
+ max_chunks?: number;
1386
1499
  }
1387
1500
  interface CanonicalSourceCreateResult {
1388
1501
  source_id: string;
@@ -1600,6 +1713,7 @@ declare class WhisperContext {
1600
1713
  }): Promise<{
1601
1714
  ingested: number;
1602
1715
  }>;
1716
+ learn(params: LearnInput): Promise<LearnResult>;
1603
1717
  listMemories(params: {
1604
1718
  project?: string;
1605
1719
  user_id?: string;
@@ -2145,4 +2259,4 @@ declare class WhisperContext {
2145
2259
  };
2146
2260
  }
2147
2261
 
2148
- export { type AgentRunContext, type AgentRuntimeOptions, type AgentRuntimeRankWeights, type AgentRuntimeRetrievalOptions, type AgentRuntimeSourceActivityOptions, type AgentRuntimeStatus, type CanonicalSourceCreateParams, type CanonicalSourceCreateResult, type CanonicalSourceType, type ExtractedMemory, LangChainMemoryAdapter, LangGraphCheckpointAdapter, type Memory, type MemoryExtractionResult, type MemoryKind, type MemoryLatencyBreakdown, type MemorySearchResponse, type MemoryWriteAck, type MemoryWriteResult, type PreparedTurn, type Project, type QueryParams, type QueryResult, type Source, type TurnCaptureResult, type TurnInput, type VideoIngestionStatus, type VideoSourceMetadata, Whisper, WhisperAgentMiddleware, WhisperClient, type WhisperConfig, WhisperContext, Whisper as WhisperDefault, WhisperError, type WhisperErrorCode, WhisperClient as WhisperRuntimeClient, type WorkEvent, type WorkEventKind, type WorkEventSalience, createAgentMiddleware, createLangChainMemoryAdapter, createLangGraphCheckpointAdapter, WhisperContext as default, memoryGraphToMermaid };
2262
+ export { type AgentRunContext, type AgentRuntimeOptions, type AgentRuntimeRankWeights, type AgentRuntimeRetrievalOptions, type AgentRuntimeSourceActivityOptions, type AgentRuntimeStatus, type CanonicalSourceCreateParams, type CanonicalSourceCreateResult, type CanonicalSourceType, type ExtractedMemory, LangChainMemoryAdapter, LangGraphCheckpointAdapter, type LearnConversationInput, type LearnConversationResult, type LearnInput, type LearnResult, type LearnSourceInput, type LearnSourceResult, type LearnSourceType, type LearnTextInput, type LearnTextResult, type Memory, type MemoryExtractionResult, type MemoryKind, type MemoryLatencyBreakdown, type MemorySearchResponse, type MemoryWriteAck, type MemoryWriteResult, type PreparedTurn, type Project, type QueryParams, type QueryResult, type Source, type TurnCaptureResult, type TurnInput, type VideoIngestionStatus, type VideoSourceMetadata, Whisper, WhisperAgentMiddleware, WhisperClient, type WhisperConfig, WhisperContext, Whisper as WhisperDefault, WhisperError, type WhisperErrorCode, WhisperClient as WhisperRuntimeClient, type WorkEvent, type WorkEventKind, type WorkEventSalience, createAgentMiddleware, createLangChainMemoryAdapter, createLangGraphCheckpointAdapter, WhisperContext as default, memoryGraphToMermaid };
package/index.js CHANGED
@@ -2126,9 +2126,33 @@ ${lines.join("\n")}`;
2126
2126
  }
2127
2127
  });
2128
2128
  }
2129
+ async resolveLearningScope(overrides) {
2130
+ const merged = {
2131
+ ...this.baseContext,
2132
+ ...overrides
2133
+ };
2134
+ const { scope } = await this.resolveScope(overrides);
2135
+ return {
2136
+ project: scope.project,
2137
+ sessionId: merged.sessionId || scope.sessionId,
2138
+ userId: merged.userId
2139
+ };
2140
+ }
2129
2141
  async afterTurn(input, context = {}) {
2130
2142
  this.pushTouchedFiles(input.touchedFiles);
2131
- const { scope } = await this.resolveScope(context);
2143
+ if (input.auto_learn === false) {
2144
+ return {
2145
+ success: true,
2146
+ sessionIngested: false,
2147
+ memoriesCreated: 0,
2148
+ relationsCreated: 0,
2149
+ invalidatedCount: 0,
2150
+ mergedCount: 0,
2151
+ droppedCount: 0,
2152
+ warnings: []
2153
+ };
2154
+ }
2155
+ const scope = await this.resolveLearningScope(context);
2132
2156
  const result = await this.args.adapter.ingestSession({
2133
2157
  project: scope.project,
2134
2158
  session_id: scope.sessionId,
@@ -2511,6 +2535,19 @@ var WhisperClient = class _WhisperClient {
2511
2535
  });
2512
2536
  return response.data;
2513
2537
  }
2538
+ async learn(params) {
2539
+ const project = (await this.resolveProject(params.project)).id;
2540
+ const response = await this.runtimeClient.request({
2541
+ endpoint: "/v1/learn",
2542
+ method: "POST",
2543
+ operation: params.mode === "conversation" ? "session" : "bulk",
2544
+ body: {
2545
+ ...params,
2546
+ project
2547
+ }
2548
+ });
2549
+ return response.data;
2550
+ }
2514
2551
  createAgentRuntime(options = {}) {
2515
2552
  const baseContext = {
2516
2553
  workspacePath: options.workspacePath,
@@ -2559,6 +2596,14 @@ var WhisperClient = class _WhisperClient {
2559
2596
  sessionId: params.sessionId || context.sessionId || ""
2560
2597
  })
2561
2598
  },
2599
+ learn: (params) => base.learn({
2600
+ ...params,
2601
+ project: params.project || context.project || base.config.project,
2602
+ ...params.mode === "conversation" ? {
2603
+ user_id: params.user_id ?? context.userId,
2604
+ session_id: params.session_id || context.sessionId || ""
2605
+ } : {}
2606
+ }),
2562
2607
  queue: base.queue,
2563
2608
  diagnostics: base.diagnostics
2564
2609
  };
@@ -2770,6 +2815,9 @@ ${context}` : "",
2770
2815
  * Capture from multiple messages (e.g., full conversation)
2771
2816
  */
2772
2817
  async captureSession(messages, options) {
2818
+ if (options?.auto_learn === false) {
2819
+ return { success: true, extracted: 0 };
2820
+ }
2773
2821
  try {
2774
2822
  const filteredMessages = messages.filter((m) => m.role !== "system");
2775
2823
  const runtime = this.runtimeClient.createAgentRuntime({
@@ -2780,7 +2828,8 @@ ${context}` : "",
2780
2828
  });
2781
2829
  const result = await runtime.afterTurn({
2782
2830
  userMessage: [...filteredMessages].reverse().find((m) => m.role === "user")?.content || "",
2783
- assistantMessage: [...filteredMessages].reverse().find((m) => m.role === "assistant")?.content || ""
2831
+ assistantMessage: [...filteredMessages].reverse().find((m) => m.role === "assistant")?.content || "",
2832
+ auto_learn: options?.auto_learn
2784
2833
  });
2785
2834
  return {
2786
2835
  success: true,
@@ -2817,7 +2866,8 @@ User: ${params.userMessage}` : params.userMessage;
2817
2866
  {
2818
2867
  userId: params.userId,
2819
2868
  sessionId: params.sessionId,
2820
- project: params.project
2869
+ project: params.project,
2870
+ auto_learn: params.auto_learn
2821
2871
  }
2822
2872
  );
2823
2873
  return {
@@ -2827,6 +2877,18 @@ User: ${params.userMessage}` : params.userMessage;
2827
2877
  extracted: captureResult.extracted
2828
2878
  };
2829
2879
  }
2880
+ async learn(input) {
2881
+ const params = input.mode === "conversation" ? {
2882
+ ...input,
2883
+ project: input.project ?? this.options.project,
2884
+ user_id: input.user_id ?? this.userId,
2885
+ session_id: input.session_id || this.sessionId || "default"
2886
+ } : {
2887
+ ...input,
2888
+ project: input.project ?? this.options.project
2889
+ };
2890
+ return this.runtimeClient.learn(params);
2891
+ }
2830
2892
  /**
2831
2893
  * Direct access to WhisperContext for advanced usage
2832
2894
  */
@@ -2912,7 +2974,8 @@ User: ${userMessage}`;
2912
2974
  {
2913
2975
  userId: params.userId,
2914
2976
  sessionId: params.sessionId,
2915
- project: params.project
2977
+ project: params.project,
2978
+ auto_learn: params.auto_learn
2916
2979
  }
2917
2980
  );
2918
2981
  }
@@ -2924,7 +2987,8 @@ User: ${userMessage}`;
2924
2987
  assistantMessage: response,
2925
2988
  userId: params.userId,
2926
2989
  sessionId: params.sessionId,
2927
- project: params.project
2990
+ project: params.project,
2991
+ auto_learn: params.auto_learn
2928
2992
  });
2929
2993
  return {
2930
2994
  response,
@@ -3814,91 +3878,125 @@ var WhisperContext = class _WhisperContext {
3814
3878
  return this.request(`/v1/sources/${sourceId}/sync`, { method: "POST" });
3815
3879
  }
3816
3880
  async addSourceByType(projectId, params) {
3817
- return this.withProjectPathFallback(
3818
- this.getRequiredProject(projectId),
3819
- (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/add_source`, {
3820
- method: "POST",
3821
- body: JSON.stringify(params)
3822
- })
3823
- );
3881
+ const result = await this.learn({
3882
+ mode: "source",
3883
+ project: projectId,
3884
+ type: "video",
3885
+ name: params.name,
3886
+ url: params.url,
3887
+ platform: params.platform,
3888
+ language: params.language,
3889
+ options: {
3890
+ async: true,
3891
+ auto_index: params.auto_sync ?? true,
3892
+ ingestion_profile: params.ingestion_profile,
3893
+ strategy_override: params.strategy_override,
3894
+ profile_config: params.profile_config,
3895
+ allow_stt_fallback: params.allow_stt_fallback,
3896
+ max_duration_minutes: params.max_duration_minutes
3897
+ }
3898
+ });
3899
+ return {
3900
+ source_id: result.source_id,
3901
+ sync_job_id: result.job_id ?? null,
3902
+ status: result.status === "processing" || result.status === "queued" ? result.status : "created"
3903
+ };
3824
3904
  }
3825
3905
  async getSourceStatus(sourceId) {
3826
3906
  return this.request(`/v1/sources/${sourceId}/status`, { method: "GET" });
3827
3907
  }
3828
3908
  async createCanonicalSource(project, params) {
3829
- const connector_type = params.type === "github" ? "github" : params.type === "web" ? "website" : params.type === "pdf" ? "pdf" : params.type === "local" ? "local-folder" : "slack";
3830
- const config = {};
3831
- if (params.type === "github") {
3832
- if (!params.owner || !params.repo) throw new WhisperError({ code: "REQUEST_FAILED", message: "github source requires owner and repo" });
3833
- config.owner = params.owner;
3834
- config.repo = params.repo;
3835
- if (params.branch) config.branch = params.branch;
3836
- if (params.paths) config.paths = params.paths;
3837
- } else if (params.type === "web") {
3838
- if (!params.url) throw new WhisperError({ code: "REQUEST_FAILED", message: "web source requires url" });
3839
- config.url = params.url;
3840
- if (params.crawl_depth !== void 0) config.crawl_depth = params.crawl_depth;
3841
- if (params.include_paths) config.include_paths = params.include_paths;
3842
- if (params.exclude_paths) config.exclude_paths = params.exclude_paths;
3843
- } else if (params.type === "pdf") {
3844
- if (!params.url && !params.file_path) throw new WhisperError({ code: "REQUEST_FAILED", message: "pdf source requires url or file_path" });
3845
- if (params.url) config.url = params.url;
3846
- if (params.file_path) config.file_path = params.file_path;
3847
- } else if (params.type === "local") {
3848
- if (!params.path) throw new WhisperError({ code: "REQUEST_FAILED", message: "local source requires path" });
3849
- config.path = params.path;
3850
- if (params.glob) config.glob = params.glob;
3851
- if (params.max_files !== void 0) config.max_files = params.max_files;
3852
- } else {
3853
- config.channel_ids = params.channel_ids || [];
3854
- if (params.since) config.since = params.since;
3855
- if (params.workspace_id) config.workspace_id = params.workspace_id;
3856
- if (params.token) config.token = params.token;
3857
- if (params.auth_ref) config.auth_ref = params.auth_ref;
3858
- }
3859
- if (params.metadata) config.metadata = params.metadata;
3860
- if (params.ingestion_profile) config.ingestion_profile = params.ingestion_profile;
3861
- if (params.strategy_override) config.strategy_override = params.strategy_override;
3862
- if (params.profile_config) config.profile_config = params.profile_config;
3863
- config.auto_index = params.auto_index ?? true;
3864
- const created = await this.addSource(project, {
3865
- name: params.name || `${params.type}-source-${Date.now()}`,
3866
- connector_type,
3867
- config
3909
+ const result = await this.learn({
3910
+ mode: "source",
3911
+ project,
3912
+ type: params.type,
3913
+ name: params.name,
3914
+ metadata: params.metadata,
3915
+ owner: params.owner,
3916
+ repo: params.repo,
3917
+ branch: params.branch,
3918
+ paths: params.paths,
3919
+ url: params.url,
3920
+ file_path: params.file_path,
3921
+ path: params.path,
3922
+ channel_ids: params.channel_ids,
3923
+ since: params.since,
3924
+ token: params.token,
3925
+ auth_ref: params.auth_ref,
3926
+ platform: params.platform,
3927
+ language: params.language,
3928
+ options: {
3929
+ async: true,
3930
+ auto_index: params.auto_index ?? true,
3931
+ ingestion_profile: params.ingestion_profile,
3932
+ strategy_override: params.strategy_override,
3933
+ profile_config: params.profile_config,
3934
+ crawl_depth: params.crawl_depth,
3935
+ include_paths: params.include_paths,
3936
+ exclude_paths: params.exclude_paths,
3937
+ glob: params.glob,
3938
+ max_files: params.max_files,
3939
+ max_pages: params.max_pages,
3940
+ extract_mode: params.extract_mode,
3941
+ workspace_id: params.workspace_id,
3942
+ allow_stt_fallback: params.allow_stt_fallback,
3943
+ max_duration_minutes: params.max_duration_minutes,
3944
+ max_chunks: params.max_chunks
3945
+ }
3868
3946
  });
3869
- let status = "queued";
3870
- let jobId = null;
3871
- if (params.auto_index ?? true) {
3872
- const syncRes = await this.syncSource(created.id);
3873
- status = "indexing";
3874
- jobId = String(syncRes?.id || syncRes?.job_id || "");
3875
- }
3876
3947
  return {
3877
- source_id: created.id,
3878
- status,
3879
- job_id: jobId,
3880
- index_started: params.auto_index ?? true,
3948
+ source_id: result.source_id,
3949
+ status: result.status === "processing" ? "indexing" : result.status === "created" ? "queued" : result.status,
3950
+ job_id: result.job_id ?? null,
3951
+ index_started: result.index_started,
3881
3952
  warnings: []
3882
3953
  };
3883
3954
  }
3884
3955
  async ingest(projectId, documents) {
3885
- return this.withProjectPathFallback(
3886
- this.getRequiredProject(projectId),
3887
- (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/ingest`, {
3888
- method: "POST",
3889
- body: JSON.stringify({ documents })
3890
- })
3956
+ await Promise.all(
3957
+ documents.map(
3958
+ (doc) => this.learn({
3959
+ mode: "text",
3960
+ project: projectId,
3961
+ title: doc.title,
3962
+ content: doc.content,
3963
+ metadata: {
3964
+ ...doc.metadata || {},
3965
+ ...doc.file_path ? { file_path: doc.file_path } : {}
3966
+ },
3967
+ options: {
3968
+ async: true,
3969
+ ingestion_profile: doc.ingestion_profile,
3970
+ strategy_override: doc.strategy_override,
3971
+ profile_config: doc.profile_config
3972
+ }
3973
+ })
3974
+ )
3891
3975
  );
3976
+ return { ingested: documents.length };
3892
3977
  }
3893
3978
  async addContext(params) {
3894
- const projectId = (await this.resolveProject(this.getRequiredProject(params.project))).id;
3895
- return this.ingest(projectId, [
3896
- {
3897
- title: params.title || "Context",
3898
- content: params.content,
3899
- metadata: params.metadata || { source: "addContext" }
3979
+ await this.learn({
3980
+ mode: "text",
3981
+ project: this.getRequiredProject(params.project),
3982
+ title: params.title || "Context",
3983
+ content: params.content,
3984
+ metadata: params.metadata || { source: "addContext" },
3985
+ options: {
3986
+ async: true
3900
3987
  }
3901
- ]);
3988
+ });
3989
+ return { ingested: 1 };
3990
+ }
3991
+ async learn(params) {
3992
+ const projectRef = this.getRequiredProject(params.project);
3993
+ return this.withProjectRefFallback(projectRef, (project) => this.request("/v1/learn", {
3994
+ method: "POST",
3995
+ body: JSON.stringify({
3996
+ ...params,
3997
+ project
3998
+ })
3999
+ }));
3902
4000
  }
3903
4001
  async listMemories(params) {
3904
4002
  const projectRef = this.getRequiredProject(params.project);
package/index.mjs CHANGED
@@ -2077,9 +2077,33 @@ ${lines.join("\n")}`;
2077
2077
  }
2078
2078
  });
2079
2079
  }
2080
+ async resolveLearningScope(overrides) {
2081
+ const merged = {
2082
+ ...this.baseContext,
2083
+ ...overrides
2084
+ };
2085
+ const { scope } = await this.resolveScope(overrides);
2086
+ return {
2087
+ project: scope.project,
2088
+ sessionId: merged.sessionId || scope.sessionId,
2089
+ userId: merged.userId
2090
+ };
2091
+ }
2080
2092
  async afterTurn(input, context = {}) {
2081
2093
  this.pushTouchedFiles(input.touchedFiles);
2082
- const { scope } = await this.resolveScope(context);
2094
+ if (input.auto_learn === false) {
2095
+ return {
2096
+ success: true,
2097
+ sessionIngested: false,
2098
+ memoriesCreated: 0,
2099
+ relationsCreated: 0,
2100
+ invalidatedCount: 0,
2101
+ mergedCount: 0,
2102
+ droppedCount: 0,
2103
+ warnings: []
2104
+ };
2105
+ }
2106
+ const scope = await this.resolveLearningScope(context);
2083
2107
  const result = await this.args.adapter.ingestSession({
2084
2108
  project: scope.project,
2085
2109
  session_id: scope.sessionId,
@@ -2462,6 +2486,19 @@ var WhisperClient = class _WhisperClient {
2462
2486
  });
2463
2487
  return response.data;
2464
2488
  }
2489
+ async learn(params) {
2490
+ const project = (await this.resolveProject(params.project)).id;
2491
+ const response = await this.runtimeClient.request({
2492
+ endpoint: "/v1/learn",
2493
+ method: "POST",
2494
+ operation: params.mode === "conversation" ? "session" : "bulk",
2495
+ body: {
2496
+ ...params,
2497
+ project
2498
+ }
2499
+ });
2500
+ return response.data;
2501
+ }
2465
2502
  createAgentRuntime(options = {}) {
2466
2503
  const baseContext = {
2467
2504
  workspacePath: options.workspacePath,
@@ -2510,6 +2547,14 @@ var WhisperClient = class _WhisperClient {
2510
2547
  sessionId: params.sessionId || context.sessionId || ""
2511
2548
  })
2512
2549
  },
2550
+ learn: (params) => base.learn({
2551
+ ...params,
2552
+ project: params.project || context.project || base.config.project,
2553
+ ...params.mode === "conversation" ? {
2554
+ user_id: params.user_id ?? context.userId,
2555
+ session_id: params.session_id || context.sessionId || ""
2556
+ } : {}
2557
+ }),
2513
2558
  queue: base.queue,
2514
2559
  diagnostics: base.diagnostics
2515
2560
  };
@@ -2721,6 +2766,9 @@ ${context}` : "",
2721
2766
  * Capture from multiple messages (e.g., full conversation)
2722
2767
  */
2723
2768
  async captureSession(messages, options) {
2769
+ if (options?.auto_learn === false) {
2770
+ return { success: true, extracted: 0 };
2771
+ }
2724
2772
  try {
2725
2773
  const filteredMessages = messages.filter((m) => m.role !== "system");
2726
2774
  const runtime = this.runtimeClient.createAgentRuntime({
@@ -2731,7 +2779,8 @@ ${context}` : "",
2731
2779
  });
2732
2780
  const result = await runtime.afterTurn({
2733
2781
  userMessage: [...filteredMessages].reverse().find((m) => m.role === "user")?.content || "",
2734
- assistantMessage: [...filteredMessages].reverse().find((m) => m.role === "assistant")?.content || ""
2782
+ assistantMessage: [...filteredMessages].reverse().find((m) => m.role === "assistant")?.content || "",
2783
+ auto_learn: options?.auto_learn
2735
2784
  });
2736
2785
  return {
2737
2786
  success: true,
@@ -2768,7 +2817,8 @@ User: ${params.userMessage}` : params.userMessage;
2768
2817
  {
2769
2818
  userId: params.userId,
2770
2819
  sessionId: params.sessionId,
2771
- project: params.project
2820
+ project: params.project,
2821
+ auto_learn: params.auto_learn
2772
2822
  }
2773
2823
  );
2774
2824
  return {
@@ -2778,6 +2828,18 @@ User: ${params.userMessage}` : params.userMessage;
2778
2828
  extracted: captureResult.extracted
2779
2829
  };
2780
2830
  }
2831
+ async learn(input) {
2832
+ const params = input.mode === "conversation" ? {
2833
+ ...input,
2834
+ project: input.project ?? this.options.project,
2835
+ user_id: input.user_id ?? this.userId,
2836
+ session_id: input.session_id || this.sessionId || "default"
2837
+ } : {
2838
+ ...input,
2839
+ project: input.project ?? this.options.project
2840
+ };
2841
+ return this.runtimeClient.learn(params);
2842
+ }
2781
2843
  /**
2782
2844
  * Direct access to WhisperContext for advanced usage
2783
2845
  */
@@ -2863,7 +2925,8 @@ User: ${userMessage}`;
2863
2925
  {
2864
2926
  userId: params.userId,
2865
2927
  sessionId: params.sessionId,
2866
- project: params.project
2928
+ project: params.project,
2929
+ auto_learn: params.auto_learn
2867
2930
  }
2868
2931
  );
2869
2932
  }
@@ -2875,7 +2938,8 @@ User: ${userMessage}`;
2875
2938
  assistantMessage: response,
2876
2939
  userId: params.userId,
2877
2940
  sessionId: params.sessionId,
2878
- project: params.project
2941
+ project: params.project,
2942
+ auto_learn: params.auto_learn
2879
2943
  });
2880
2944
  return {
2881
2945
  response,
@@ -3765,91 +3829,125 @@ var WhisperContext = class _WhisperContext {
3765
3829
  return this.request(`/v1/sources/${sourceId}/sync`, { method: "POST" });
3766
3830
  }
3767
3831
  async addSourceByType(projectId, params) {
3768
- return this.withProjectPathFallback(
3769
- this.getRequiredProject(projectId),
3770
- (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/add_source`, {
3771
- method: "POST",
3772
- body: JSON.stringify(params)
3773
- })
3774
- );
3832
+ const result = await this.learn({
3833
+ mode: "source",
3834
+ project: projectId,
3835
+ type: "video",
3836
+ name: params.name,
3837
+ url: params.url,
3838
+ platform: params.platform,
3839
+ language: params.language,
3840
+ options: {
3841
+ async: true,
3842
+ auto_index: params.auto_sync ?? true,
3843
+ ingestion_profile: params.ingestion_profile,
3844
+ strategy_override: params.strategy_override,
3845
+ profile_config: params.profile_config,
3846
+ allow_stt_fallback: params.allow_stt_fallback,
3847
+ max_duration_minutes: params.max_duration_minutes
3848
+ }
3849
+ });
3850
+ return {
3851
+ source_id: result.source_id,
3852
+ sync_job_id: result.job_id ?? null,
3853
+ status: result.status === "processing" || result.status === "queued" ? result.status : "created"
3854
+ };
3775
3855
  }
3776
3856
  async getSourceStatus(sourceId) {
3777
3857
  return this.request(`/v1/sources/${sourceId}/status`, { method: "GET" });
3778
3858
  }
3779
3859
  async createCanonicalSource(project, params) {
3780
- const connector_type = params.type === "github" ? "github" : params.type === "web" ? "website" : params.type === "pdf" ? "pdf" : params.type === "local" ? "local-folder" : "slack";
3781
- const config = {};
3782
- if (params.type === "github") {
3783
- if (!params.owner || !params.repo) throw new WhisperError({ code: "REQUEST_FAILED", message: "github source requires owner and repo" });
3784
- config.owner = params.owner;
3785
- config.repo = params.repo;
3786
- if (params.branch) config.branch = params.branch;
3787
- if (params.paths) config.paths = params.paths;
3788
- } else if (params.type === "web") {
3789
- if (!params.url) throw new WhisperError({ code: "REQUEST_FAILED", message: "web source requires url" });
3790
- config.url = params.url;
3791
- if (params.crawl_depth !== void 0) config.crawl_depth = params.crawl_depth;
3792
- if (params.include_paths) config.include_paths = params.include_paths;
3793
- if (params.exclude_paths) config.exclude_paths = params.exclude_paths;
3794
- } else if (params.type === "pdf") {
3795
- if (!params.url && !params.file_path) throw new WhisperError({ code: "REQUEST_FAILED", message: "pdf source requires url or file_path" });
3796
- if (params.url) config.url = params.url;
3797
- if (params.file_path) config.file_path = params.file_path;
3798
- } else if (params.type === "local") {
3799
- if (!params.path) throw new WhisperError({ code: "REQUEST_FAILED", message: "local source requires path" });
3800
- config.path = params.path;
3801
- if (params.glob) config.glob = params.glob;
3802
- if (params.max_files !== void 0) config.max_files = params.max_files;
3803
- } else {
3804
- config.channel_ids = params.channel_ids || [];
3805
- if (params.since) config.since = params.since;
3806
- if (params.workspace_id) config.workspace_id = params.workspace_id;
3807
- if (params.token) config.token = params.token;
3808
- if (params.auth_ref) config.auth_ref = params.auth_ref;
3809
- }
3810
- if (params.metadata) config.metadata = params.metadata;
3811
- if (params.ingestion_profile) config.ingestion_profile = params.ingestion_profile;
3812
- if (params.strategy_override) config.strategy_override = params.strategy_override;
3813
- if (params.profile_config) config.profile_config = params.profile_config;
3814
- config.auto_index = params.auto_index ?? true;
3815
- const created = await this.addSource(project, {
3816
- name: params.name || `${params.type}-source-${Date.now()}`,
3817
- connector_type,
3818
- config
3860
+ const result = await this.learn({
3861
+ mode: "source",
3862
+ project,
3863
+ type: params.type,
3864
+ name: params.name,
3865
+ metadata: params.metadata,
3866
+ owner: params.owner,
3867
+ repo: params.repo,
3868
+ branch: params.branch,
3869
+ paths: params.paths,
3870
+ url: params.url,
3871
+ file_path: params.file_path,
3872
+ path: params.path,
3873
+ channel_ids: params.channel_ids,
3874
+ since: params.since,
3875
+ token: params.token,
3876
+ auth_ref: params.auth_ref,
3877
+ platform: params.platform,
3878
+ language: params.language,
3879
+ options: {
3880
+ async: true,
3881
+ auto_index: params.auto_index ?? true,
3882
+ ingestion_profile: params.ingestion_profile,
3883
+ strategy_override: params.strategy_override,
3884
+ profile_config: params.profile_config,
3885
+ crawl_depth: params.crawl_depth,
3886
+ include_paths: params.include_paths,
3887
+ exclude_paths: params.exclude_paths,
3888
+ glob: params.glob,
3889
+ max_files: params.max_files,
3890
+ max_pages: params.max_pages,
3891
+ extract_mode: params.extract_mode,
3892
+ workspace_id: params.workspace_id,
3893
+ allow_stt_fallback: params.allow_stt_fallback,
3894
+ max_duration_minutes: params.max_duration_minutes,
3895
+ max_chunks: params.max_chunks
3896
+ }
3819
3897
  });
3820
- let status = "queued";
3821
- let jobId = null;
3822
- if (params.auto_index ?? true) {
3823
- const syncRes = await this.syncSource(created.id);
3824
- status = "indexing";
3825
- jobId = String(syncRes?.id || syncRes?.job_id || "");
3826
- }
3827
3898
  return {
3828
- source_id: created.id,
3829
- status,
3830
- job_id: jobId,
3831
- index_started: params.auto_index ?? true,
3899
+ source_id: result.source_id,
3900
+ status: result.status === "processing" ? "indexing" : result.status === "created" ? "queued" : result.status,
3901
+ job_id: result.job_id ?? null,
3902
+ index_started: result.index_started,
3832
3903
  warnings: []
3833
3904
  };
3834
3905
  }
3835
3906
  async ingest(projectId, documents) {
3836
- return this.withProjectPathFallback(
3837
- this.getRequiredProject(projectId),
3838
- (projectPathRef) => this.request(`/v1/projects/${encodeURIComponent(projectPathRef)}/ingest`, {
3839
- method: "POST",
3840
- body: JSON.stringify({ documents })
3841
- })
3907
+ await Promise.all(
3908
+ documents.map(
3909
+ (doc) => this.learn({
3910
+ mode: "text",
3911
+ project: projectId,
3912
+ title: doc.title,
3913
+ content: doc.content,
3914
+ metadata: {
3915
+ ...doc.metadata || {},
3916
+ ...doc.file_path ? { file_path: doc.file_path } : {}
3917
+ },
3918
+ options: {
3919
+ async: true,
3920
+ ingestion_profile: doc.ingestion_profile,
3921
+ strategy_override: doc.strategy_override,
3922
+ profile_config: doc.profile_config
3923
+ }
3924
+ })
3925
+ )
3842
3926
  );
3927
+ return { ingested: documents.length };
3843
3928
  }
3844
3929
  async addContext(params) {
3845
- const projectId = (await this.resolveProject(this.getRequiredProject(params.project))).id;
3846
- return this.ingest(projectId, [
3847
- {
3848
- title: params.title || "Context",
3849
- content: params.content,
3850
- metadata: params.metadata || { source: "addContext" }
3930
+ await this.learn({
3931
+ mode: "text",
3932
+ project: this.getRequiredProject(params.project),
3933
+ title: params.title || "Context",
3934
+ content: params.content,
3935
+ metadata: params.metadata || { source: "addContext" },
3936
+ options: {
3937
+ async: true
3851
3938
  }
3852
- ]);
3939
+ });
3940
+ return { ingested: 1 };
3941
+ }
3942
+ async learn(params) {
3943
+ const projectRef = this.getRequiredProject(params.project);
3944
+ return this.withProjectRefFallback(projectRef, (project) => this.request("/v1/learn", {
3945
+ method: "POST",
3946
+ body: JSON.stringify({
3947
+ ...params,
3948
+ project
3949
+ })
3950
+ }));
3853
3951
  }
3854
3952
  async listMemories(params) {
3855
3953
  const projectRef = this.getRequiredProject(params.project);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usewhisper/sdk",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "whisperContractVersion": "2026.03.10",
5
5
  "scripts": {
6
6
  "build": "tsup ../src/sdk/index.ts --format esm,cjs --dts --out-dir .",