@usewhisper/sdk 3.7.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 +188 -65
  2. package/index.d.ts +188 -65
  3. package/index.js +186 -75
  4. package/index.mjs +186 -75
  5. package/package.json +1 -1
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,138 @@ 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
+ }));
4000
+ }
4001
+ async listMemories(params) {
4002
+ const projectRef = this.getRequiredProject(params.project);
4003
+ return this.withProjectRefFallback(projectRef, async (project) => {
4004
+ const query = new URLSearchParams({
4005
+ project,
4006
+ ...params.user_id ? { user_id: params.user_id } : {},
4007
+ ...params.session_id ? { session_id: params.session_id } : {},
4008
+ ...params.agent_id ? { agent_id: params.agent_id } : {},
4009
+ limit: String(Math.min(Math.max(params.limit ?? 200, 1), 200))
4010
+ });
4011
+ return this.request(`/v1/memories?${query.toString()}`, { method: "GET" });
4012
+ });
3902
4013
  }
3903
4014
  async addMemory(params) {
3904
4015
  const projectRef = this.getRequiredProject(params.project);