@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.
- package/package.json +1 -1
- package/src/agents/base/base.ts +9 -1
- package/src/auth/browserLogin.ts +4 -4
- package/src/chat/modules/AgentModule.ts +22 -3
- package/src/embeddings.ts +2 -4
- package/src/login.ts +27 -20
- package/src/plugins/GitPlugin.ts +10 -5
- package/src/processors/CustomVariables.ts +48 -70
- package/src/processors/TokenCompressor.ts +5 -4
- package/src/processors/ToolResponseCache.ts +6 -9
- package/src/services/KnowhowClient.ts +43 -16
- package/tests/processors/CustomVariables.test.ts +110 -55
- package/tests/processors/TokenCompressor.test.ts +48 -49
- package/tests/processors/ToolResponseCache.test.ts +309 -261
- package/ts_build/package.json +1 -1
- package/ts_build/src/agents/base/base.d.ts +5 -0
- package/ts_build/src/agents/base/base.js +3 -1
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/chat/modules/AgentModule.js +9 -1
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
- package/ts_build/src/embeddings.js +2 -4
- package/ts_build/src/embeddings.js.map +1 -1
- package/ts_build/src/login.d.ts +4 -0
- package/ts_build/src/login.js +21 -16
- package/ts_build/src/login.js.map +1 -1
- package/ts_build/src/plugins/GitPlugin.js +5 -5
- package/ts_build/src/plugins/GitPlugin.js.map +1 -1
- package/ts_build/src/processors/CustomVariables.js +36 -47
- package/ts_build/src/processors/CustomVariables.js.map +1 -1
- package/ts_build/src/processors/TokenCompressor.js +2 -2
- package/ts_build/src/processors/TokenCompressor.js.map +1 -1
- package/ts_build/src/processors/ToolResponseCache.js +6 -8
- package/ts_build/src/processors/ToolResponseCache.js.map +1 -1
- package/ts_build/src/services/KnowhowClient.d.ts +2 -1
- package/ts_build/src/services/KnowhowClient.js +36 -16
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/tests/processors/CustomVariables.test.js +41 -38
- package/ts_build/tests/processors/CustomVariables.test.js.map +1 -1
- package/ts_build/tests/processors/TokenCompressor.test.js +4 -5
- package/ts_build/tests/processors/TokenCompressor.test.js.map +1 -1
- package/ts_build/tests/processors/ToolResponseCache.test.js +89 -78
- package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
package/package.json
CHANGED
package/src/agents/base/base.ts
CHANGED
|
@@ -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
|
-
|
|
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()
|
package/src/auth/browserLogin.ts
CHANGED
|
@@ -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(
|
|
724
|
-
|
|
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(`
|
|
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
|
-
|
|
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
|
+
}
|
package/src/plugins/GitPlugin.ts
CHANGED
|
@@ -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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
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
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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 =
|
|
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
|
|
324
|
-
toolsService.
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
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.
|
|
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,
|