@tyvm/knowhow 0.0.48 → 0.0.50

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 (42) hide show
  1. package/package.json +1 -1
  2. package/src/agents/base/base.ts +9 -1
  3. package/src/auth/browserLogin.ts +4 -4
  4. package/src/chat/modules/AgentModule.ts +22 -3
  5. package/src/embeddings.ts +2 -4
  6. package/src/login.ts +27 -20
  7. package/src/plugins/GitPlugin.ts +10 -5
  8. package/src/processors/CustomVariables.ts +48 -70
  9. package/src/processors/TokenCompressor.ts +5 -4
  10. package/src/processors/ToolResponseCache.ts +6 -9
  11. package/src/services/KnowhowClient.ts +43 -16
  12. package/tests/processors/CustomVariables.test.ts +110 -55
  13. package/tests/processors/TokenCompressor.test.ts +48 -49
  14. package/tests/processors/ToolResponseCache.test.ts +309 -261
  15. package/ts_build/package.json +1 -1
  16. package/ts_build/src/agents/base/base.d.ts +5 -0
  17. package/ts_build/src/agents/base/base.js +3 -1
  18. package/ts_build/src/agents/base/base.js.map +1 -1
  19. package/ts_build/src/chat/modules/AgentModule.js +9 -1
  20. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  21. package/ts_build/src/embeddings.js +2 -4
  22. package/ts_build/src/embeddings.js.map +1 -1
  23. package/ts_build/src/login.d.ts +4 -0
  24. package/ts_build/src/login.js +21 -16
  25. package/ts_build/src/login.js.map +1 -1
  26. package/ts_build/src/plugins/GitPlugin.js +5 -5
  27. package/ts_build/src/plugins/GitPlugin.js.map +1 -1
  28. package/ts_build/src/processors/CustomVariables.js +36 -47
  29. package/ts_build/src/processors/CustomVariables.js.map +1 -1
  30. package/ts_build/src/processors/TokenCompressor.js +2 -2
  31. package/ts_build/src/processors/TokenCompressor.js.map +1 -1
  32. package/ts_build/src/processors/ToolResponseCache.js +6 -8
  33. package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
  34. package/ts_build/src/services/KnowhowClient.d.ts +2 -1
  35. package/ts_build/src/services/KnowhowClient.js +36 -16
  36. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  37. package/ts_build/tests/processors/CustomVariables.test.js +41 -38
  38. package/ts_build/tests/processors/CustomVariables.test.js.map +1 -1
  39. package/ts_build/tests/processors/TokenCompressor.test.js +4 -5
  40. package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -1
  41. package/ts_build/tests/processors/ToolResponseCache.test.js +89 -78
  42. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyvm/knowhow",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "description": "ai cli with plugins and agents",
5
5
  "main": "ts_build/src/index.js",
6
6
  "bin": {
@@ -31,6 +31,11 @@ export interface AgentContext {
31
31
  Clients?: AIClient;
32
32
  }
33
33
 
34
+ export interface ToolCallEvent {
35
+ toolCall: ToolCall;
36
+ functionResp: any;
37
+ }
38
+
34
39
  export abstract class BaseAgent implements IAgent {
35
40
  abstract name: string;
36
41
  abstract description: string;
@@ -62,7 +67,8 @@ export abstract class BaseAgent implements IAgent {
62
67
  newThread: "new_thread",
63
68
  threadUpdate: "thread_update",
64
69
  costUpdate: "cost_update",
65
- toolUsed: "tool_used",
70
+ toolCall: "tool:pre_call",
71
+ toolUsed: "tool:post_call",
66
72
  done: "done",
67
73
  pause: "pause",
68
74
  kill: "kill",
@@ -294,6 +300,8 @@ export abstract class BaseAgent implements IAgent {
294
300
  abstract getInitialMessages(userInput: string): Promise<Message[]>;
295
301
 
296
302
  async processToolMessages(toolCall: ToolCall) {
303
+ this.agentEvents.emit(this.eventTypes.toolCall, { toolCall });
304
+
297
305
  const { functionResp, toolMessages } = await this.tools.callTool(
298
306
  toolCall,
299
307
  this.getEnabledToolNames()
@@ -253,17 +253,17 @@ export function validateJwt(jwt: string): boolean {
253
253
 
254
254
  // If this looks like a real JWT (contains base64-like characters), validate it strictly
255
255
  const looksLikeRealJwt = parts.every(part => /^[A-Za-z0-9+/\-_]+={0,2}$/.test(part));
256
-
256
+
257
257
  if (looksLikeRealJwt) {
258
258
  // Strict validation for real JWTs
259
259
  try {
260
260
  // Try to decode header and payload as valid JSON
261
261
  JSON.parse(Buffer.from(parts[0], "base64").toString());
262
262
  JSON.parse(Buffer.from(parts[1], "base64").toString());
263
-
263
+
264
264
  // Try to decode signature - should be valid base64 with reasonable length
265
265
  const signature = Buffer.from(parts[2], "base64");
266
-
266
+
267
267
  // JWT signatures are typically at least 32 bytes (256 bits)
268
268
  if (signature.length < 32) {
269
269
  return false;
@@ -273,7 +273,7 @@ export function validateJwt(jwt: string): boolean {
273
273
  return false;
274
274
  }
275
275
  }
276
-
276
+
277
277
  // For simple test cases like 'part1.part2.part3', just check basic structure
278
278
  try {
279
279
  return true;
@@ -20,6 +20,7 @@ import {
20
20
  } from "../../processors/index";
21
21
  import { TaskInfo, ChatSession } from "../types";
22
22
  import { agents } from "../../agents";
23
+ import { ToolCallEvent } from "src/agents/base/base";
23
24
 
24
25
  export class AgentModule extends BaseChatModule {
25
26
  name = "agent";
@@ -719,10 +720,28 @@ ${reason}
719
720
  ]);
720
721
 
721
722
  // Set up event listeners
723
+ if (!agent.agentEvents.listenerCount(agent.eventTypes.toolCall)) {
724
+ agent.agentEvents.on(
725
+ agent.eventTypes.toolCall,
726
+ (responseMsg: ToolCallEvent) => {
727
+ console.time(JSON.stringify(responseMsg.toolCall.function.name));
728
+ console.log(
729
+ ` 🔨 Tool: ${responseMsg.toolCall.function.name}\n Args: ${responseMsg.toolCall.function.arguments}\n`
730
+ );
731
+ }
732
+ );
733
+ }
722
734
  if (!agent.agentEvents.listenerCount(agent.eventTypes.toolUsed)) {
723
- agent.agentEvents.on(agent.eventTypes.toolUsed, (responseMsg) => {
724
- console.log(` 🔨 Tool used: ${JSON.stringify(responseMsg, null, 2)}`);
725
- });
735
+ agent.agentEvents.on(
736
+ agent.eventTypes.toolUsed,
737
+ (responseMsg: ToolCallEvent) => {
738
+ console.timeEnd(JSON.stringify(responseMsg.toolCall.function.name));
739
+ console.log(
740
+ ` 🔨 Tool Response:
741
+ ${JSON.stringify(responseMsg.functionResp, null, 2)}`
742
+ );
743
+ }
744
+ );
726
745
  }
727
746
 
728
747
  const taskCompleted = new Promise<string>((resolve) => {
package/src/embeddings.ts CHANGED
@@ -136,11 +136,10 @@ export async function embedSource(
136
136
  inputs = [source.input];
137
137
  }
138
138
 
139
- console.log(`Found ${inputs.length} files`);
139
+ console.log(`Checking ${inputs.length} files`);
140
140
  if (inputs.length > 1000) {
141
141
  console.error("Large number of files detected. This may take a while");
142
142
  }
143
- console.log(inputs);
144
143
  const embeddings: Embeddable[] = await loadEmbedding(source.output);
145
144
  let batch = [];
146
145
  let index = 0;
@@ -231,7 +230,6 @@ export async function embed(
231
230
  }
232
231
 
233
232
  if (alreadyEmbedded) {
234
- console.log("Skipping", chunkId);
235
233
  continue;
236
234
  }
237
235
 
@@ -468,7 +466,7 @@ export async function queryEmbedding<E>(
468
466
  model = EmbeddingModels.openai.EmbeddingAda2
469
467
  ) {
470
468
  const providerEmbeddings = await Clients.createEmbedding("", {
471
- input: takeFirstNWords(query, 5000),
469
+ input: takeFirstNWords(query, 5000).slice(0, 16000),
472
470
  model,
473
471
  });
474
472
  const queryVector = providerEmbeddings.data[0].embedding;
package/src/login.ts CHANGED
@@ -42,33 +42,19 @@ export async function login(jwtFlag?: boolean): Promise<void> {
42
42
  // Get current user/org information
43
43
  try {
44
44
  const storedJwt = await loadJwt();
45
- const response = await axios.get(`${KNOWHOW_API_URL}/api/users/me`, {
46
- headers: {
47
- Authorization: `Bearer ${storedJwt}`,
48
- },
49
- });
50
- const user = response.data.user;
51
- const orgs = user.orgs;
52
- const orgId = response.data.orgId;
53
-
54
- const currentOrg = orgs.find((org) => {
55
- return org.organizationId === orgId;
56
- });
57
-
58
- console.log(
59
- `Current user: ${user.email}, \nOrganization: ${currentOrg?.organization?.name} - ${orgId}`
60
- );
45
+ await checkJwt(storedJwt);
61
46
 
62
47
  const config = await getConfig();
63
48
  const proxyUrl = KNOWHOW_API_URL + "/api/proxy";
49
+
50
+ if (!config.modelProviders) {
51
+ config.modelProviders = [];
52
+ }
53
+
64
54
  const hasProvider = config.modelProviders.find(
65
55
  (provider) => provider.provider === "knowhow" && provider.url === proxyUrl
66
56
  );
67
57
  if (!hasProvider) {
68
- if (!config.modelProviders) {
69
- config.modelProviders = [];
70
- }
71
-
72
58
  config.modelProviders.push({
73
59
  provider: "knowhow",
74
60
  url: proxyUrl,
@@ -106,3 +92,24 @@ export async function loadJwt(): Promise<string> {
106
92
 
107
93
  return jwt;
108
94
  }
95
+
96
+ export async function checkJwt(storedJwt: string) {
97
+ const response = await axios.get(`${KNOWHOW_API_URL}/api/users/me`, {
98
+ headers: {
99
+ Authorization: `Bearer ${storedJwt}`,
100
+ },
101
+ });
102
+ const user = response.data.user;
103
+ const orgs = user.orgs;
104
+ const orgId = response.data.orgId;
105
+
106
+ const currentOrg = orgs.find((org) => {
107
+ return org.organizationId === orgId;
108
+ });
109
+
110
+ console.log(
111
+ `Current user: ${user.email}, \nOrganization: ${currentOrg?.organization?.name} - ${orgId}`
112
+ );
113
+
114
+ return { user, currentOrg };
115
+ }
@@ -92,12 +92,17 @@ Your modifications are automatically tracked separately and won't affect the use
92
92
  "# Knowhow agent tracking repository\n"
93
93
  );
94
94
 
95
- const hasChanges = await this.hasChanges();
96
- if (hasChanges) {
97
- this.commit("Initial commit for agent tracking, with changes");
98
- } else {
95
+ // For initial commit, we need to add files and commit directly
96
+ // since HEAD doesn't exist yet
97
+ try {
98
+ this.gitCommand("add -A");
99
+ this.gitCommand(
100
+ 'commit -m "Initial commit for agent tracking"'
101
+ );
102
+ } catch (error) {
103
+ // If there's nothing to commit, create an empty commit
99
104
  this.gitCommand(
100
- 'commit --allow-empty -m "Initial commit for agent tracking, no changes"'
105
+ 'commit --allow-empty -m "Initial commit for agent tracking"'
101
106
  );
102
107
  }
103
108
  }
@@ -101,18 +101,24 @@ export class CustomVariables {
101
101
  */
102
102
  private listVariables(): string {
103
103
  const variableNames = Object.keys(this.variables);
104
-
104
+
105
105
  if (variableNames.length === 0) {
106
106
  return "No variables are currently stored.";
107
107
  }
108
108
 
109
- const variableList = variableNames.map(name => {
110
- const value = this.variables[name];
111
- const preview = typeof value === "string"
112
- ? (value.length > 50 ? value.substring(0, 50) + "..." : value)
113
- : JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? "..." : "");
114
- return `- ${name}: ${preview}`;
115
- }).join("\n");
109
+ const variableList = variableNames
110
+ .map((name) => {
111
+ const value = this.variables[name];
112
+ const preview =
113
+ typeof value === "string"
114
+ ? value.length > 50
115
+ ? value.substring(0, 50) + "..."
116
+ : value
117
+ : JSON.stringify(value).substring(0, 50) +
118
+ (JSON.stringify(value).length > 50 ? "..." : "");
119
+ return `- ${name}: ${preview}`;
120
+ })
121
+ .join("\n");
116
122
 
117
123
  return `Currently stored variables (${variableNames.length}):\n${variableList}`;
118
124
  }
@@ -146,17 +152,17 @@ export class CustomVariables {
146
152
  // Check if ALL variables are undefined - if so, return just the error message for the first one
147
153
  const variableMatches = value.match(/\{\{([a-zA-Z0-9_]+)\}\}/g);
148
154
  if (variableMatches) {
149
- const allUndefined = variableMatches.every(match => {
150
- const varName = match.replace(/[{}]/g, '');
155
+ const allUndefined = variableMatches.every((match) => {
156
+ const varName = match.replace(/[{}]/g, "");
151
157
  return !(varName in this.variables);
152
158
  });
153
-
159
+
154
160
  if (allUndefined && variableMatches.length > 0) {
155
- const firstUndefinedVar = variableMatches[0].replace(/[{}]/g, '');
161
+ const firstUndefinedVar = variableMatches[0].replace(/[{}]/g, "");
156
162
  return `{{ERROR: Variable "${firstUndefinedVar}" is not defined}}`;
157
163
  }
158
164
  }
159
-
165
+
160
166
  // Otherwise, proceed with partial substitution
161
167
  return value.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g, (match, varName) => {
162
168
  // Prevent infinite recursion
@@ -251,62 +257,34 @@ export class CustomVariables {
251
257
  */
252
258
  private registerTools(toolsService: ToolsService): void {
253
259
  // Register setVariable tool
254
- if (!toolsService.getTool(this.setVariableToolName)) {
255
- toolsService.addTool(setVariableToolDefinition);
256
- toolsService.addFunctions({
257
- [this.setVariableToolName]: (name: string, contents: any) => {
258
- return this.setVariable(name, contents);
259
- },
260
- });
261
- }
262
-
263
- // Register getVariable tool
264
- if (!toolsService.getTool(this.getVariableToolName)) {
265
- toolsService.addTool(getVariableToolDefinition);
266
- toolsService.addFunctions({
267
- [this.getVariableToolName]: (varName: string) => {
268
- return this.getVariable(varName);
269
- },
270
- });
271
- }
272
-
273
- // Register storeToolCallToVariable tool
274
- if (!toolsService.getTool(this.storeToolCallToolName)) {
275
- toolsService.addTool(storeToolCallToVariableDefinition);
276
- toolsService.addFunctions({
277
- [this.storeToolCallToolName]: async (
278
- varName: string,
279
- toolName: string,
280
- toolArgs: string
281
- ) => {
282
- return await this.storeToolCallToVariable(
283
- varName,
284
- toolName,
285
- toolArgs
286
- );
287
- },
288
- });
289
- }
290
-
291
- // Register listVariables tool
292
- if (!toolsService.getTool(this.listVariablesToolName)) {
293
- toolsService.addTool(listVariablesToolDefinition);
294
- toolsService.addFunctions({
295
- [this.listVariablesToolName]: () => {
296
- return this.listVariables();
297
- },
298
- });
299
- }
300
-
301
- // Register deleteVariable tool
302
- if (!toolsService.getTool(this.deleteVariableToolName)) {
303
- toolsService.addTool(deleteVariableToolDefinition);
304
- toolsService.addFunctions({
305
- [this.deleteVariableToolName]: (varName: string) => {
306
- return this.deleteVariable(varName);
307
- },
308
- });
309
- }
260
+ toolsService.addTools([
261
+ setVariableToolDefinition,
262
+ getVariableToolDefinition,
263
+ storeToolCallToVariableDefinition,
264
+ listVariablesToolDefinition,
265
+ deleteVariableToolDefinition,
266
+ ]);
267
+ toolsService.addFunctions({
268
+ [this.setVariableToolName]: (name: string, contents: any) => {
269
+ return this.setVariable(name, contents);
270
+ },
271
+ [this.getVariableToolName]: (varName: string) => {
272
+ return this.getVariable(varName);
273
+ },
274
+ [this.storeToolCallToolName]: async (
275
+ varName: string,
276
+ toolName: string,
277
+ toolArgs: string
278
+ ) => {
279
+ return await this.storeToolCallToVariable(varName, toolName, toolArgs);
280
+ },
281
+ [this.listVariablesToolName]: () => {
282
+ return this.listVariables();
283
+ },
284
+ [this.deleteVariableToolName]: (varName: string) => {
285
+ return this.deleteVariable(varName);
286
+ },
287
+ });
310
288
  }
311
289
 
312
290
  /**
@@ -434,4 +412,4 @@ export const deleteVariableToolDefinition: Tool = {
434
412
  required: ["varName"],
435
413
  },
436
414
  },
437
- };
415
+ };
@@ -116,8 +116,9 @@ export class TokenCompressor {
116
116
 
117
117
  // For nested properties (path !== ""), use maxTokens to avoid recompressing stored data
118
118
  // For top-level content (path === ""), use compressionThreshold to determine compression
119
- const thresholdToUse = path === "" ? this.compressionThreshold : this.maxTokens;
120
-
119
+ const thresholdToUse =
120
+ path === "" ? this.compressionThreshold : this.maxTokens;
121
+
121
122
  if (tokens <= thresholdToUse) {
122
123
  return content;
123
124
  }
@@ -320,8 +321,8 @@ export class TokenCompressor {
320
321
  }
321
322
 
322
323
  registerTool(toolsService?: ToolsService): void {
323
- if (toolsService && !toolsService.getTool(this.toolName)) {
324
- toolsService.addTool(expandTokensDefinition);
324
+ if (toolsService) {
325
+ toolsService.addTools([expandTokensDefinition]);
325
326
  toolsService.addFunctions({
326
327
  [this.toolName]: (key: string) => {
327
328
  const data = this.retrieveString(key);
@@ -130,7 +130,6 @@ export class ToolResponseCache {
130
130
  }
131
131
 
132
132
  try {
133
-
134
133
  // First parse the stored string as JSON, then handle nested JSON strings
135
134
  const jsonData = this.tryParseJson(data);
136
135
  if (!jsonData) {
@@ -207,14 +206,12 @@ export class ToolResponseCache {
207
206
  * Registers the jqToolResponse tool with the ToolsService
208
207
  */
209
208
  registerTool(toolsService: ToolsService): void {
210
- if (!toolsService.getTool(this.toolName)) {
211
- toolsService.addTool(jqToolResponseDefinition);
212
- toolsService.addFunctions({
213
- [this.toolName]: async (toolCallId: string, jqQuery: string) => {
214
- return await this.queryToolResponse(toolCallId, jqQuery);
215
- },
216
- });
217
- }
209
+ toolsService.addTools([jqToolResponseDefinition]);
210
+ toolsService.addFunctions({
211
+ [this.toolName]: async (toolCallId: string, jqQuery: string) => {
212
+ return await this.queryToolResponse(toolCallId, jqQuery);
213
+ },
214
+ });
218
215
  }
219
216
  }
220
217
 
@@ -38,7 +38,9 @@ export function loadKnowhowJwt(): string {
38
38
  if (!fs.existsSync(jwtFile)) {
39
39
  return "";
40
40
  }
41
- return fs.readFileSync(jwtFile, "utf-8").trim();
41
+ const jwt = fs.readFileSync(jwtFile, "utf-8").trim();
42
+
43
+ return jwt;
42
44
  }
43
45
 
44
46
  export const KNOWHOW_API_URL =
@@ -46,6 +48,7 @@ export const KNOWHOW_API_URL =
46
48
 
47
49
  export class KnowhowSimpleClient {
48
50
  headers = {};
51
+ jwtValidated = false;
49
52
 
50
53
  constructor(private baseUrl, private jwt = loadKnowhowJwt()) {
51
54
  this.setJwt(jwt);
@@ -58,21 +61,45 @@ export class KnowhowSimpleClient {
58
61
  };
59
62
  }
60
63
 
61
- checkJwt() {
64
+ async checkJwt() {
62
65
  if (!this.jwt) {
63
66
  throw new Error("No JWT found. Please login first.");
64
67
  }
68
+
69
+ if (!this.jwtValidated) {
70
+ try {
71
+ this.jwtValidated = true;
72
+ const response = await this.me();
73
+
74
+ const user = response.data.user;
75
+ const orgs = user.orgs;
76
+ const orgId = response.data.orgId;
77
+
78
+ const currentOrg = orgs.find((org) => {
79
+ return org.organizationId === orgId;
80
+ });
81
+
82
+ console.log(
83
+ `Current user: ${user.email}, \nOrganization: ${currentOrg?.organization?.name} - ${orgId}`
84
+ );
85
+ } catch (error) {
86
+ throw new Error("Invalid JWT. Please login again.");
87
+ }
88
+ }
65
89
  }
66
90
 
67
- me() {
68
- this.checkJwt();
91
+ async me() {
92
+ if (!this.jwt) {
93
+ throw new Error("No JWT found. Please login first.");
94
+ }
95
+
69
96
  return axios.get(`${this.baseUrl}/api/users/me`, {
70
97
  headers: this.headers,
71
98
  });
72
99
  }
73
100
 
74
101
  async getPresignedUploadUrl(source: Config["embedSources"][0]) {
75
- this.checkJwt();
102
+ await this.checkJwt();
76
103
  const id = source.remoteId;
77
104
  const presignedUrlResp = await axios.post(
78
105
  `${this.baseUrl}/api/org-embeddings/${id}/upload`,
@@ -89,7 +116,7 @@ export class KnowhowSimpleClient {
89
116
  }
90
117
 
91
118
  async getPresignedDownloadUrl(source: Config["embedSources"][0]) {
92
- this.checkJwt();
119
+ await this.checkJwt();
93
120
  const id = source.remoteId;
94
121
  const presignedUrlResp = await axios.post(
95
122
  `${this.baseUrl}/api/org-embeddings/${id}/download`,
@@ -103,8 +130,8 @@ export class KnowhowSimpleClient {
103
130
  return presignedUrl;
104
131
  }
105
132
 
106
- createChatCompletion(options: CompletionOptions) {
107
- this.checkJwt();
133
+ async createChatCompletion(options: CompletionOptions) {
134
+ await this.checkJwt();
108
135
  return axios.post<CompletionResponse>(
109
136
  `${this.baseUrl}/api/proxy/v1/chat/completions`,
110
137
  options,
@@ -114,8 +141,8 @@ export class KnowhowSimpleClient {
114
141
  );
115
142
  }
116
143
 
117
- createEmbedding(options: EmbeddingOptions) {
118
- this.checkJwt();
144
+ async createEmbedding(options: EmbeddingOptions) {
145
+ await this.checkJwt();
119
146
  return axios.post<EmbeddingResponse>(
120
147
  `${this.baseUrl}/api/proxy/v1/embeddings`,
121
148
  options,
@@ -125,15 +152,15 @@ export class KnowhowSimpleClient {
125
152
  );
126
153
  }
127
154
 
128
- getModels() {
129
- this.checkJwt();
155
+ async getModels() {
156
+ await this.checkJwt();
130
157
  return axios.get(`${this.baseUrl}/api/proxy/v1/models?type=all`, {
131
158
  headers: this.headers,
132
159
  });
133
160
  }
134
161
 
135
- createChatTask(request: CreateMessageTaskRequest) {
136
- this.checkJwt();
162
+ async createChatTask(request: CreateMessageTaskRequest) {
163
+ await this.checkJwt();
137
164
  return axios.post<CreateMessageTaskResponse>(
138
165
  `${this.baseUrl}/api/chat/tasks`,
139
166
  request,
@@ -143,8 +170,8 @@ export class KnowhowSimpleClient {
143
170
  );
144
171
  }
145
172
 
146
- updateChatTask(taskId: string, updates: UpdateOrgTaskRequest) {
147
- this.checkJwt();
173
+ async updateChatTask(taskId: string, updates: UpdateOrgTaskRequest) {
174
+ await this.checkJwt();
148
175
  return axios.put<UpdateOrgTaskResponse>(
149
176
  `${this.baseUrl}/api/chat/tasks/${taskId}`,
150
177
  updates,