@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.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,138 @@ 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
+ }));
3951
+ }
3952
+ async listMemories(params) {
3953
+ const projectRef = this.getRequiredProject(params.project);
3954
+ return this.withProjectRefFallback(projectRef, async (project) => {
3955
+ const query = new URLSearchParams({
3956
+ project,
3957
+ ...params.user_id ? { user_id: params.user_id } : {},
3958
+ ...params.session_id ? { session_id: params.session_id } : {},
3959
+ ...params.agent_id ? { agent_id: params.agent_id } : {},
3960
+ limit: String(Math.min(Math.max(params.limit ?? 200, 1), 200))
3961
+ });
3962
+ return this.request(`/v1/memories?${query.toString()}`, { method: "GET" });
3963
+ });
3853
3964
  }
3854
3965
  async addMemory(params) {
3855
3966
  const projectRef = this.getRequiredProject(params.project);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usewhisper/sdk",
3
- "version": "3.7.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 .",