kernl 0.1.1
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/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +53 -0
- package/LICENSE +201 -0
- package/dist/agent.d.ts +43 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +130 -0
- package/dist/context.d.ts +70 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +111 -0
- package/dist/env.d.ts +45 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +31 -0
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +1 -0
- package/dist/guardrail.d.ts +178 -0
- package/dist/guardrail.d.ts.map +1 -0
- package/dist/guardrail.js +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/kernel.d.ts +7 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +7 -0
- package/dist/kernl.d.ts +18 -0
- package/dist/kernl.d.ts.map +1 -0
- package/dist/kernl.js +16 -0
- package/dist/lib/env.d.ts +43 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +29 -0
- package/dist/lib/error.d.ts +88 -0
- package/dist/lib/error.d.ts.map +1 -0
- package/dist/lib/error.js +117 -0
- package/dist/lib/logger.d.ts +36 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +43 -0
- package/dist/lib/serde/__tests__/codec.test.d.ts +2 -0
- package/dist/lib/serde/__tests__/codec.test.d.ts.map +1 -0
- package/dist/lib/serde/__tests__/codec.test.js +75 -0
- package/dist/lib/serde/codec.d.ts +12 -0
- package/dist/lib/serde/codec.d.ts.map +1 -0
- package/dist/lib/serde/codec.js +54 -0
- package/dist/lib/serde/json.d.ts +8 -0
- package/dist/lib/serde/json.d.ts.map +1 -0
- package/dist/lib/serde/json.js +13 -0
- package/dist/lib/serde/thread.d.ts +1 -0
- package/dist/lib/serde/thread.d.ts.map +1 -0
- package/dist/lib/serde/thread.js +172 -0
- package/dist/lib/serde/tool.d.ts +36 -0
- package/dist/lib/serde/tool.d.ts.map +1 -0
- package/dist/lib/serde/tool.js +1 -0
- package/dist/lib/utils.d.ts +19 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +41 -0
- package/dist/lifecycle.d.ts +133 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +29 -0
- package/dist/logger.d.ts +36 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +43 -0
- package/dist/mcp/__tests__/base.test.d.ts +2 -0
- package/dist/mcp/__tests__/base.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/base.test.js +268 -0
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/echo-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/echo-server.js +92 -0
- package/dist/mcp/__tests__/fixtures/math-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/math-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/math-server.js +98 -0
- package/dist/mcp/__tests__/fixtures/server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/server.js +162 -0
- package/dist/mcp/__tests__/fixtures/test-server.d.ts +3 -0
- package/dist/mcp/__tests__/fixtures/test-server.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/test-server.js +163 -0
- package/dist/mcp/__tests__/fixtures/utils.d.ts +17 -0
- package/dist/mcp/__tests__/fixtures/utils.d.ts.map +1 -0
- package/dist/mcp/__tests__/fixtures/utils.js +42 -0
- package/dist/mcp/__tests__/integration.test.d.ts +2 -0
- package/dist/mcp/__tests__/integration.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/integration.test.js +360 -0
- package/dist/mcp/__tests__/stdio.test.d.ts +2 -0
- package/dist/mcp/__tests__/stdio.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/stdio.test.js +180 -0
- package/dist/mcp/__tests__/test-utils.d.ts +17 -0
- package/dist/mcp/__tests__/test-utils.d.ts.map +1 -0
- package/dist/mcp/__tests__/test-utils.js +42 -0
- package/dist/mcp/__tests__/utils.test.d.ts +2 -0
- package/dist/mcp/__tests__/utils.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/utils.test.js +300 -0
- package/dist/mcp/base.d.ts +88 -0
- package/dist/mcp/base.d.ts.map +1 -0
- package/dist/mcp/base.js +68 -0
- package/dist/mcp/http.d.ts +34 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +100 -0
- package/dist/mcp/node.d.ts +60 -0
- package/dist/mcp/node.d.ts.map +1 -0
- package/dist/mcp/node.js +297 -0
- package/dist/mcp/sse.d.ts +34 -0
- package/dist/mcp/sse.d.ts.map +1 -0
- package/dist/mcp/sse.js +97 -0
- package/dist/mcp/stdio.d.ts +32 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +96 -0
- package/dist/mcp/types.d.ts +172 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +16 -0
- package/dist/mcp/utils.d.ts +23 -0
- package/dist/mcp/utils.d.ts.map +1 -0
- package/dist/mcp/utils.js +44 -0
- package/dist/model.d.ts +175 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +1 -0
- package/dist/providers/ai.d.ts +1 -0
- package/dist/providers/ai.d.ts.map +1 -0
- package/dist/providers/ai.js +1 -0
- package/dist/providers/default.d.ts +16 -0
- package/dist/providers/default.d.ts.map +1 -0
- package/dist/providers/default.js +17 -0
- package/dist/providers/registry.d.ts +1 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +1 -0
- package/dist/sched/scheduler.d.ts +20 -0
- package/dist/sched/scheduler.d.ts.map +1 -0
- package/dist/sched/scheduler.js +1 -0
- package/dist/sched/task.d.ts +92 -0
- package/dist/sched/task.d.ts.map +1 -0
- package/dist/sched/task.js +102 -0
- package/dist/serde/__tests__/codec.test.d.ts +2 -0
- package/dist/serde/__tests__/codec.test.d.ts.map +1 -0
- package/dist/serde/__tests__/codec.test.js +75 -0
- package/dist/serde/codec.d.ts +12 -0
- package/dist/serde/codec.d.ts.map +1 -0
- package/dist/serde/codec.js +54 -0
- package/dist/serde/json.d.ts +8 -0
- package/dist/serde/json.d.ts.map +1 -0
- package/dist/serde/json.js +13 -0
- package/dist/serde/thread.d.ts +687 -0
- package/dist/serde/thread.d.ts.map +1 -0
- package/dist/serde/thread.js +158 -0
- package/dist/serde/tool.d.ts +36 -0
- package/dist/serde/tool.d.ts.map +1 -0
- package/dist/serde/tool.js +1 -0
- package/dist/session.d.ts +1 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +1 -0
- package/dist/task.d.ts +87 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +97 -0
- package/dist/thread/__tests__/mock.d.ts +28 -0
- package/dist/thread/__tests__/mock.d.ts.map +1 -0
- package/dist/thread/__tests__/mock.js +74 -0
- package/dist/thread/__tests__/thread.test.d.ts +2 -0
- package/dist/thread/__tests__/thread.test.d.ts.map +1 -0
- package/dist/thread/__tests__/thread.test.js +1412 -0
- package/dist/thread/index.d.ts +2 -0
- package/dist/thread/index.d.ts.map +1 -0
- package/dist/thread/index.js +1 -0
- package/dist/thread/thread.d.ts +66 -0
- package/dist/thread/thread.d.ts.map +1 -0
- package/dist/thread/thread.js +472 -0
- package/dist/thread/utils.d.ts +19 -0
- package/dist/thread/utils.d.ts.map +1 -0
- package/dist/thread/utils.js +50 -0
- package/dist/tool/__tests__/fixtures.d.ts +45 -0
- package/dist/tool/__tests__/fixtures.d.ts.map +1 -0
- package/dist/tool/__tests__/fixtures.js +97 -0
- package/dist/tool/__tests__/tool.test.d.ts +2 -0
- package/dist/tool/__tests__/tool.test.d.ts.map +1 -0
- package/dist/tool/__tests__/tool.test.js +172 -0
- package/dist/tool/__tests__/toolkit.test.d.ts +2 -0
- package/dist/tool/__tests__/toolkit.test.d.ts.map +1 -0
- package/dist/tool/__tests__/toolkit.test.js +134 -0
- package/dist/tool/index.d.ts +4 -0
- package/dist/tool/index.d.ts.map +1 -0
- package/dist/tool/index.js +2 -0
- package/dist/tool/mcp.d.ts +75 -0
- package/dist/tool/mcp.d.ts.map +1 -0
- package/dist/tool/mcp.js +111 -0
- package/dist/tool/tool.d.ts +95 -0
- package/dist/tool/tool.d.ts.map +1 -0
- package/dist/tool/tool.js +176 -0
- package/dist/tool/toolkit.d.ts +121 -0
- package/dist/tool/toolkit.d.ts.map +1 -0
- package/dist/tool/toolkit.js +180 -0
- package/dist/tool/types.d.ts +187 -0
- package/dist/tool/types.d.ts.map +1 -0
- package/dist/tool/types.js +1 -0
- package/dist/tools.d.ts +362 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +220 -0
- package/dist/trace/processor.d.ts +1 -0
- package/dist/trace/processor.d.ts.map +1 -0
- package/dist/trace/processor.js +1 -0
- package/dist/trace/traces.d.ts +1 -0
- package/dist/trace/traces.d.ts.map +1 -0
- package/dist/trace/traces.js +73 -0
- package/dist/trace/utils.d.ts +22 -0
- package/dist/trace/utils.d.ts.map +1 -0
- package/dist/trace/utils.js +30 -0
- package/dist/types/agent.d.ts +91 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +1 -0
- package/dist/types/proto.d.ts +1551 -0
- package/dist/types/proto.d.ts.map +1 -0
- package/dist/types/proto.js +531 -0
- package/dist/types/thread.d.ts +71 -0
- package/dist/types/thread.d.ts.map +1 -0
- package/dist/types/thread.js +5 -0
- package/dist/usage.d.ts +43 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +61 -0
- package/package.json +52 -0
- package/src/agent.ts +203 -0
- package/src/context.ts +265 -0
- package/src/guardrail.ts +277 -0
- package/src/index.ts +3 -0
- package/src/kernl.ts +22 -0
- package/src/lib/env.ts +36 -0
- package/src/lib/error.ts +158 -0
- package/src/lib/logger.ts +78 -0
- package/src/lib/serde/json.ts +18 -0
- package/src/lib/serde/thread.ts +188 -0
- package/src/lifecycle.ts +181 -0
- package/src/mcp/__tests__/base.test.ts +344 -0
- package/src/mcp/__tests__/fixtures/server.ts +179 -0
- package/src/mcp/__tests__/fixtures/utils.ts +58 -0
- package/src/mcp/__tests__/integration.test.ts +447 -0
- package/src/mcp/__tests__/stdio.test.ts +236 -0
- package/src/mcp/__tests__/utils.test.ts +360 -0
- package/src/mcp/base.ts +162 -0
- package/src/mcp/http.ts +147 -0
- package/src/mcp/sse.ts +137 -0
- package/src/mcp/stdio.ts +136 -0
- package/src/mcp/types.ts +202 -0
- package/src/mcp/utils.ts +62 -0
- package/src/task.ts +119 -0
- package/src/thread/__tests__/mock.ts +95 -0
- package/src/thread/__tests__/thread.test.ts +1574 -0
- package/src/thread/index.ts +1 -0
- package/src/thread/thread.ts +611 -0
- package/src/thread/utils.ts +67 -0
- package/src/tool/__tests__/fixtures.ts +106 -0
- package/src/tool/__tests__/tool.test.ts +235 -0
- package/src/tool/__tests__/toolkit.test.ts +174 -0
- package/src/tool/index.ts +10 -0
- package/src/tool/tool.ts +264 -0
- package/src/tool/toolkit.ts +234 -0
- package/src/tool/types.ts +243 -0
- package/src/trace/processor.ts +0 -0
- package/src/trace/traces.ts +86 -0
- package/src/trace/utils.ts +38 -0
- package/src/types/agent.ts +145 -0
- package/src/types/thread.ts +86 -0
- package/tsconfig.json +13 -0
- package/vitest.config.ts +14 -0
package/dist/usage.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { UsageData } from "./types/thread";
|
|
2
|
+
/**
|
|
3
|
+
* Tracks token usage and request counts for an agent run.
|
|
4
|
+
*/
|
|
5
|
+
export class Usage {
|
|
6
|
+
/**
|
|
7
|
+
* The number of requests made to the LLM API.
|
|
8
|
+
*/
|
|
9
|
+
requests;
|
|
10
|
+
/**
|
|
11
|
+
* The number of input tokens used across all requests.
|
|
12
|
+
*/
|
|
13
|
+
inputTokens;
|
|
14
|
+
/**
|
|
15
|
+
* The number of output tokens used across all requests.
|
|
16
|
+
*/
|
|
17
|
+
outputTokens;
|
|
18
|
+
/**
|
|
19
|
+
* The total number of tokens sent and received, across all requests.
|
|
20
|
+
*/
|
|
21
|
+
totalTokens;
|
|
22
|
+
/**
|
|
23
|
+
* Details about the input tokens used across all requests.
|
|
24
|
+
*/
|
|
25
|
+
inputTokensDetails = [];
|
|
26
|
+
/**
|
|
27
|
+
* Details about the output tokens used across all requests.
|
|
28
|
+
*/
|
|
29
|
+
outputTokensDetails = [];
|
|
30
|
+
constructor(input) {
|
|
31
|
+
if (typeof input === "undefined") {
|
|
32
|
+
this.requests = 0;
|
|
33
|
+
this.inputTokens = 0;
|
|
34
|
+
this.outputTokens = 0;
|
|
35
|
+
this.totalTokens = 0;
|
|
36
|
+
this.inputTokensDetails = [];
|
|
37
|
+
this.outputTokensDetails = [];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.requests = input?.requests ?? 1;
|
|
41
|
+
this.inputTokens = input?.inputTokens ?? input?.input_tokens ?? 0;
|
|
42
|
+
this.outputTokens = input?.outputTokens ?? input?.output_tokens ?? 0;
|
|
43
|
+
this.totalTokens = input?.totalTokens ?? input?.total_tokens ?? 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
add(newUsage) {
|
|
47
|
+
this.requests += newUsage.requests;
|
|
48
|
+
this.inputTokens += newUsage.inputTokens;
|
|
49
|
+
this.outputTokens += newUsage.outputTokens;
|
|
50
|
+
this.totalTokens += newUsage.totalTokens;
|
|
51
|
+
if (newUsage.inputTokensDetails) {
|
|
52
|
+
// The type does not allow undefined, but it could happen runtime
|
|
53
|
+
this.inputTokensDetails.push(...newUsage.inputTokensDetails);
|
|
54
|
+
}
|
|
55
|
+
if (newUsage.outputTokensDetails) {
|
|
56
|
+
// The type does not allow undefined, but it could happen runtime
|
|
57
|
+
this.outputTokensDetails.push(...newUsage.outputTokensDetails);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export { UsageData };
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kernl",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A modern AI agent framework with MCP integration",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"kernl",
|
|
7
|
+
"ai",
|
|
8
|
+
"agent",
|
|
9
|
+
"framework",
|
|
10
|
+
"mcp"
|
|
11
|
+
],
|
|
12
|
+
"author": "dremnik",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/dremnik/kernl.git",
|
|
17
|
+
"directory": "packages/kernl"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/dremnik/kernl#readme",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/dremnik/kernl/issues"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.20.2",
|
|
32
|
+
"pino": "^9.6.0",
|
|
33
|
+
"zod": "^4.1.12",
|
|
34
|
+
"@kernl/protocol": "0.1.1",
|
|
35
|
+
"@kernl/shared": "^0.1.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^24.10.0",
|
|
39
|
+
"tsc-alias": "^1.8.10",
|
|
40
|
+
"typescript": "5.9.2",
|
|
41
|
+
"vitest": "^4.0.8"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc && tsc-alias",
|
|
45
|
+
"dev": "tsc --watch",
|
|
46
|
+
"lint": "eslint src/",
|
|
47
|
+
"check-types": "tsc --noEmit",
|
|
48
|
+
"test": "vitest",
|
|
49
|
+
"test:watch": "vitest --watch",
|
|
50
|
+
"test:run": "vitest run"
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/agent.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { LanguageModel, LanguageModelRequestSettings } from "@kernl/protocol";
|
|
2
|
+
|
|
3
|
+
import type { Context, UnknownContext } from "./context";
|
|
4
|
+
import { InputGuardrail, OutputGuardrail } from "./guardrail";
|
|
5
|
+
import { AgentHooks } from "./lifecycle";
|
|
6
|
+
import { Toolkit } from "./tool/toolkit";
|
|
7
|
+
import { Tool } from "./tool";
|
|
8
|
+
// import { DEFAULT_LANGUAGE_MODEL } from "@/providers/default";
|
|
9
|
+
|
|
10
|
+
import { MisconfiguredError } from "./lib/error";
|
|
11
|
+
|
|
12
|
+
import type { AgentConfig, AgentResponseType } from "./types/agent";
|
|
13
|
+
import { TextResponse } from "./types/thread";
|
|
14
|
+
|
|
15
|
+
export class Agent<
|
|
16
|
+
TContext = UnknownContext,
|
|
17
|
+
TResponse extends AgentResponseType = TextResponse,
|
|
18
|
+
>
|
|
19
|
+
extends AgentHooks<TContext, TResponse>
|
|
20
|
+
implements AgentConfig<TContext, TResponse>
|
|
21
|
+
{
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
instructions: (context: Context<TContext>) => Promise<string> | string;
|
|
25
|
+
|
|
26
|
+
model: LanguageModel;
|
|
27
|
+
modelSettings: LanguageModelRequestSettings;
|
|
28
|
+
toolkits: Toolkit<TContext>[];
|
|
29
|
+
|
|
30
|
+
// --- (TODO) ---
|
|
31
|
+
// handoffDescription: string; // ??
|
|
32
|
+
// handoffs: (Agent<any, TResponse> | Handoff<any, TResponse>)[];
|
|
33
|
+
// ----------
|
|
34
|
+
|
|
35
|
+
// /* Process/thread-group–wide signal state shared by all threads in the group: shared pending signals, job control
|
|
36
|
+
// (stops/cont, group exit), rlimits, etc. */
|
|
37
|
+
// signal: *struct signal_struct;
|
|
38
|
+
// /* Table of signal handlers (sa_handler, sa_mask, flags) shared by threads (CLONE_SIGHAND). RCU-protected so readers can access it locklessly. */
|
|
39
|
+
// sighand: *struct sighand_struct __rcu;
|
|
40
|
+
|
|
41
|
+
guardrails: {
|
|
42
|
+
input: InputGuardrail[];
|
|
43
|
+
output: OutputGuardrail<AgentResponseType>[];
|
|
44
|
+
};
|
|
45
|
+
responseType: TResponse = "text" as TResponse;
|
|
46
|
+
resetToolChoice: boolean;
|
|
47
|
+
// toolUseBehavior: ToolUseBehavior; (TODO)
|
|
48
|
+
|
|
49
|
+
// /**
|
|
50
|
+
// * Create an Agent with handoffs and automatically infer the union type for TResponse from the handoff agents' response types.
|
|
51
|
+
// */
|
|
52
|
+
// static create<
|
|
53
|
+
// TResponse extends AgentResponseType = TextResponse,
|
|
54
|
+
// Handoffs extends readonly (Agent<any, any> | Handoff<any, any>)[] = [],
|
|
55
|
+
// >(
|
|
56
|
+
// config: AgentConfigWithHandoffs<TResponse, Handoffs>,
|
|
57
|
+
// ): Agent<UnknownContext, TResponse | HandoffsOutputUnion<Handoffs>> {
|
|
58
|
+
// return new Agent<UnknownContext, TResponse | HandoffsOutputUnion<Handoffs>>(
|
|
59
|
+
// {
|
|
60
|
+
// ...config,
|
|
61
|
+
// handoffs: config.handoffs as any,
|
|
62
|
+
// responseType: config.responseType,
|
|
63
|
+
// handoffresponseTypeWarningEnabled: false,
|
|
64
|
+
// },
|
|
65
|
+
// );
|
|
66
|
+
// }
|
|
67
|
+
|
|
68
|
+
constructor(config: AgentConfig<TContext, TResponse>) {
|
|
69
|
+
super();
|
|
70
|
+
if (config.id.trim() === "") {
|
|
71
|
+
throw new MisconfiguredError("Agent must have an id.");
|
|
72
|
+
}
|
|
73
|
+
this.id = config.id;
|
|
74
|
+
this.name = config.name;
|
|
75
|
+
this.instructions =
|
|
76
|
+
typeof config.instructions === "function"
|
|
77
|
+
? config.instructions
|
|
78
|
+
: () => config.instructions as string;
|
|
79
|
+
this.model = config.model as LanguageModel; // TODO: Add default model
|
|
80
|
+
this.modelSettings = config.modelSettings ?? {};
|
|
81
|
+
|
|
82
|
+
this.toolkits = config.toolkits ?? [];
|
|
83
|
+
for (const toolkit of this.toolkits) {
|
|
84
|
+
toolkit.bind(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.guardrails = config.guardrails ?? { input: [], output: [] };
|
|
88
|
+
if (config.responseType) {
|
|
89
|
+
this.responseType = config.responseType;
|
|
90
|
+
}
|
|
91
|
+
this.resetToolChoice = config.resetToolChoice ?? true;
|
|
92
|
+
// this.toolUseBehavior = config.toolUseBehavior ?? "run_llm_again";
|
|
93
|
+
|
|
94
|
+
// this.handoffDescription = config.handoffDescription ?? "";
|
|
95
|
+
// this.handoffs = config.handoffs ?? [];
|
|
96
|
+
|
|
97
|
+
// --- Runtime warning for handoff response type compatibility ---
|
|
98
|
+
// if (
|
|
99
|
+
// config.handoffresponseTypeWarningEnabled === undefined ||
|
|
100
|
+
// config.handoffresponseTypeWarningEnabled
|
|
101
|
+
// ) {
|
|
102
|
+
// if (this.handoffs && this.responseType) {
|
|
103
|
+
// const responseTypes = new Set<string>([
|
|
104
|
+
// JSON.stringify(this.responseType),
|
|
105
|
+
// ]);
|
|
106
|
+
// for (const h of this.handoffs) {
|
|
107
|
+
// if ("responseType" in h && h.responseType) {
|
|
108
|
+
// responseTypes.add(JSON.stringify(h.responseType));
|
|
109
|
+
// } else if ("agent" in h && h.agent.responseType) {
|
|
110
|
+
// responseTypes.add(JSON.stringify(h.agent.responseType));
|
|
111
|
+
// }
|
|
112
|
+
// }
|
|
113
|
+
// if (responseTypes.size > 1) {
|
|
114
|
+
// logger.warn(
|
|
115
|
+
// `[Agent] Warning: Handoff agents have different response types: ${Array.from(responseTypes).join(", ")}. You can make it type-safe by using Agent.create({ ... }) method instead.`,
|
|
116
|
+
// );
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
// }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get a specific tool by ID from all toolkits.
|
|
124
|
+
*
|
|
125
|
+
* @param id The tool ID to look up
|
|
126
|
+
* @returns The tool if found, undefined otherwise
|
|
127
|
+
*/
|
|
128
|
+
tool(id: string): Tool<TContext> | undefined {
|
|
129
|
+
for (const toolkit of this.toolkits) {
|
|
130
|
+
const tool = toolkit.get(id);
|
|
131
|
+
if (tool) return tool;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get all tools available from all toolkits for the given context.
|
|
138
|
+
* Checks for duplicate tool IDs across toolkits and throws an error if found.
|
|
139
|
+
*
|
|
140
|
+
* (TODO): Consider returning toolkits alongside tools so we can serialize them
|
|
141
|
+
* together and give agents more options for dealing with tool groups.
|
|
142
|
+
*
|
|
143
|
+
* @param context The context to use for filtering tools
|
|
144
|
+
* @returns Array of all available tools
|
|
145
|
+
* @throws {MisconfiguredError} If duplicate tool IDs are found across toolkits
|
|
146
|
+
*/
|
|
147
|
+
async tools(context: Context<TContext>): Promise<Tool<TContext>[]> {
|
|
148
|
+
const allTools: Tool<TContext>[] = [];
|
|
149
|
+
const toolIds = new Set<string>();
|
|
150
|
+
|
|
151
|
+
for (const toolkit of this.toolkits) {
|
|
152
|
+
const tools = await toolkit.list(context);
|
|
153
|
+
|
|
154
|
+
const duplicates = tools.map((t) => t.id).filter((id) => toolIds.has(id));
|
|
155
|
+
if (duplicates.length > 0) {
|
|
156
|
+
throw new MisconfiguredError(
|
|
157
|
+
`Duplicate tool IDs found across toolkits: ${duplicates.join(", ")}`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
tools.forEach((t) => toolIds.add(t.id));
|
|
162
|
+
allTools.push(...tools);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return allTools;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// async run<TContext>(
|
|
169
|
+
// input: string,
|
|
170
|
+
// options: SharedRunOptions<TContext>,
|
|
171
|
+
// ): Promise<RunResult<TContext>> {
|
|
172
|
+
// // TODO
|
|
173
|
+
// // ...
|
|
174
|
+
// }
|
|
175
|
+
|
|
176
|
+
// async stream<TContext>(
|
|
177
|
+
// input: string,
|
|
178
|
+
// options: StreamOptions<TContext>,
|
|
179
|
+
// ): Promise<StreamedRunResult<TContext>> {
|
|
180
|
+
// // TODO
|
|
181
|
+
// // ...
|
|
182
|
+
// }
|
|
183
|
+
//
|
|
184
|
+
|
|
185
|
+
// ----------------------
|
|
186
|
+
// Events
|
|
187
|
+
// ----------------------
|
|
188
|
+
|
|
189
|
+
// on(event: any, handler: Function): void {
|
|
190
|
+
// // TODO
|
|
191
|
+
// // ...
|
|
192
|
+
// }
|
|
193
|
+
|
|
194
|
+
// once(event: any, handler: Function): void {
|
|
195
|
+
// // TODO
|
|
196
|
+
// // ...
|
|
197
|
+
// }
|
|
198
|
+
|
|
199
|
+
// off(event: any, handler: Function): void {
|
|
200
|
+
// // TODO
|
|
201
|
+
// // ...
|
|
202
|
+
// }
|
|
203
|
+
}
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status of a tool call approval.
|
|
3
|
+
*/
|
|
4
|
+
export type ApprovalStatus = "approved" | "rejected" | "pending";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A propagation mechanism which carries execution-scoped values across API boundaries and between logically associated
|
|
8
|
+
* execution units.
|
|
9
|
+
*/
|
|
10
|
+
export class Context<TContext = UnknownContext> {
|
|
11
|
+
/**
|
|
12
|
+
* The inner context object.
|
|
13
|
+
*/
|
|
14
|
+
context: TContext;
|
|
15
|
+
|
|
16
|
+
// ----------------------
|
|
17
|
+
// TEMPORARY: Tool approval tracking until actions system is refined
|
|
18
|
+
// ----------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Map of tool call IDs to their approval status.
|
|
22
|
+
* (TEMPORARY) Used until the actions system is refined.
|
|
23
|
+
*/
|
|
24
|
+
approvals: Map<string, ApprovalStatus>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Approve a tool call by its call ID.
|
|
28
|
+
* (TEMPORARY) Used until the actions system is refined.
|
|
29
|
+
*/
|
|
30
|
+
approve(callId: string): void {
|
|
31
|
+
this.approvals.set(callId, "approved");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Reject a tool call by its call ID.
|
|
36
|
+
* (TEMPORARY) Used until the actions system is refined.
|
|
37
|
+
*/
|
|
38
|
+
reject(callId: string): void {
|
|
39
|
+
this.approvals.set(callId, "rejected");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ----------------------
|
|
43
|
+
// End temporary approval tracking
|
|
44
|
+
// ----------------------
|
|
45
|
+
|
|
46
|
+
// /**
|
|
47
|
+
// * Serialization format in which to render the context to the agent
|
|
48
|
+
// */
|
|
49
|
+
// private format: "md" | "yaml" | "json" | "html" | "xml";
|
|
50
|
+
|
|
51
|
+
// /**
|
|
52
|
+
// * The usage of the agent run so far. For streamed responses, the usage will be stale until the
|
|
53
|
+
// * last chunk of the stream is processed.
|
|
54
|
+
// */
|
|
55
|
+
// usage: Usage;
|
|
56
|
+
|
|
57
|
+
// /**
|
|
58
|
+
// * A map of tool names to whether they have been approved.
|
|
59
|
+
// */
|
|
60
|
+
// #approvals: Map<string, ApprovalRecord>;
|
|
61
|
+
|
|
62
|
+
constructor(context: TContext = {} as TContext) {
|
|
63
|
+
this.context = context;
|
|
64
|
+
this.approvals = new Map();
|
|
65
|
+
// this.format = format; // (TODO): configure()
|
|
66
|
+
// this.usage = new Usage();
|
|
67
|
+
// this.#approvals = new Map();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Renders the context as a prompt using the default format selected. Kernel would inject this info automatically, but exposed in case of control
|
|
72
|
+
*/
|
|
73
|
+
render(self: Context<TContext>): string {
|
|
74
|
+
throw new Error("UNIMPLEMENTED");
|
|
75
|
+
// switch (self.format) {
|
|
76
|
+
// case "yaml":
|
|
77
|
+
// return self.yaml();
|
|
78
|
+
// // case "json":
|
|
79
|
+
// // return self.json();
|
|
80
|
+
// // case "xml":
|
|
81
|
+
// // return self.xml();
|
|
82
|
+
// case "md":
|
|
83
|
+
// default:
|
|
84
|
+
// return self.md();
|
|
85
|
+
// }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Render the context object as a markdown string:
|
|
90
|
+
*
|
|
91
|
+
* <context>
|
|
92
|
+
* <user>
|
|
93
|
+
* <name>John</name>
|
|
94
|
+
* <email>john@gmail.com</email>
|
|
95
|
+
* </user>
|
|
96
|
+
* <org>
|
|
97
|
+
* <id>org_235234523</id>
|
|
98
|
+
* <name>Acme Corp.<name>
|
|
99
|
+
* </org>
|
|
100
|
+
* </context>
|
|
101
|
+
*
|
|
102
|
+
*/
|
|
103
|
+
md(): string {
|
|
104
|
+
throw new Error("UNIMPLEMENTED");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Render the context object as a yaml string:
|
|
109
|
+
*
|
|
110
|
+
* context:
|
|
111
|
+
* user:
|
|
112
|
+
* name: John
|
|
113
|
+
* email: john@gmail.com
|
|
114
|
+
* org:
|
|
115
|
+
* id: org_235234523
|
|
116
|
+
* name: Acme Corp.
|
|
117
|
+
*/
|
|
118
|
+
yaml(): string {
|
|
119
|
+
throw new Error("UNIMPLEMENTED");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
toJSON(): {
|
|
123
|
+
context: any;
|
|
124
|
+
// usage: Usage;
|
|
125
|
+
// approvals: Record<string, ApprovalRecord>;
|
|
126
|
+
} {
|
|
127
|
+
return {
|
|
128
|
+
context: this.context,
|
|
129
|
+
// usage: this.usage,
|
|
130
|
+
// approvals: Object.fromEntries(this.#approvals.entries()),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// /**
|
|
135
|
+
// * Rebuild the approvals map from a serialized state.
|
|
136
|
+
// * @internal
|
|
137
|
+
// *
|
|
138
|
+
// * @param approvals - The approvals map to rebuild.
|
|
139
|
+
// */
|
|
140
|
+
// _rebuildApprovals(approvals: Record<string, ApprovalRecord>) {
|
|
141
|
+
// this.#approvals = new Map(Object.entries(approvals));
|
|
142
|
+
// }
|
|
143
|
+
|
|
144
|
+
// /**
|
|
145
|
+
// * Check if a tool call has been approved.
|
|
146
|
+
// *
|
|
147
|
+
// * @param approval - Details about the tool call being evaluated.
|
|
148
|
+
// * @returns `true` if the tool call has been approved, `false` if blocked and `undefined` if not yet approved or rejected.
|
|
149
|
+
// */
|
|
150
|
+
// isToolApproved(approval: { toolName: string; callId: string }) {
|
|
151
|
+
// const { toolName, callId } = approval;
|
|
152
|
+
// const approvalEntry = this.#approvals.get(toolName);
|
|
153
|
+
// if (approvalEntry?.approved === true && approvalEntry.rejected === true) {
|
|
154
|
+
// logger.warn(
|
|
155
|
+
// "Tool is permanently approved and rejected at the same time. Approval takes precedence",
|
|
156
|
+
// );
|
|
157
|
+
// return true;
|
|
158
|
+
// }
|
|
159
|
+
|
|
160
|
+
// if (approvalEntry?.approved === true) {
|
|
161
|
+
// return true;
|
|
162
|
+
// }
|
|
163
|
+
|
|
164
|
+
// if (approvalEntry?.rejected === true) {
|
|
165
|
+
// return false;
|
|
166
|
+
// }
|
|
167
|
+
|
|
168
|
+
// const individualCallApproval = Array.isArray(approvalEntry?.approved)
|
|
169
|
+
// ? approvalEntry.approved.includes(callId)
|
|
170
|
+
// : false;
|
|
171
|
+
// const individualCallRejection = Array.isArray(approvalEntry?.rejected)
|
|
172
|
+
// ? approvalEntry.rejected.includes(callId)
|
|
173
|
+
// : false;
|
|
174
|
+
|
|
175
|
+
// if (individualCallApproval && individualCallRejection) {
|
|
176
|
+
// logger.warn(
|
|
177
|
+
// `Tool call ${callId} is both approved and rejected at the same time. Approval takes precedence`,
|
|
178
|
+
// );
|
|
179
|
+
// return true;
|
|
180
|
+
// }
|
|
181
|
+
|
|
182
|
+
// if (individualCallApproval) {
|
|
183
|
+
// return true;
|
|
184
|
+
// }
|
|
185
|
+
|
|
186
|
+
// if (individualCallRejection) {
|
|
187
|
+
// return false;
|
|
188
|
+
// }
|
|
189
|
+
|
|
190
|
+
// return undefined;
|
|
191
|
+
// }
|
|
192
|
+
|
|
193
|
+
// /**
|
|
194
|
+
// * Approve a tool call.
|
|
195
|
+
// *
|
|
196
|
+
// * @param approvalItem - The tool approval item to approve.
|
|
197
|
+
// * @param options - Additional approval behavior options.
|
|
198
|
+
// */
|
|
199
|
+
// approveTool(
|
|
200
|
+
// approvalItem: RunToolApprovalItem,
|
|
201
|
+
// { alwaysApprove = false }: { alwaysApprove?: boolean } = {},
|
|
202
|
+
// ) {
|
|
203
|
+
// const toolName = approvalItem.rawItem.name;
|
|
204
|
+
// if (alwaysApprove) {
|
|
205
|
+
// this.#approvals.set(toolName, {
|
|
206
|
+
// approved: true,
|
|
207
|
+
// rejected: [],
|
|
208
|
+
// });
|
|
209
|
+
// return;
|
|
210
|
+
// }
|
|
211
|
+
|
|
212
|
+
// const approvalEntry = this.#approvals.get(toolName) ?? {
|
|
213
|
+
// approved: [],
|
|
214
|
+
// rejected: [],
|
|
215
|
+
// };
|
|
216
|
+
// if (Array.isArray(approvalEntry.approved)) {
|
|
217
|
+
// // function tool has call_id, hosted tool call has id
|
|
218
|
+
// const callId =
|
|
219
|
+
// "callId" in approvalItem.rawItem
|
|
220
|
+
// ? approvalItem.rawItem.callId // function tools
|
|
221
|
+
// : approvalItem.rawItem.id!; // hosted tools
|
|
222
|
+
// approvalEntry.approved.push(callId);
|
|
223
|
+
// }
|
|
224
|
+
// this.#approvals.set(toolName, approvalEntry);
|
|
225
|
+
// }
|
|
226
|
+
|
|
227
|
+
// /**
|
|
228
|
+
// * Reject a tool call.
|
|
229
|
+
// *
|
|
230
|
+
// * @param approvalItem - The tool approval item to reject.
|
|
231
|
+
// */
|
|
232
|
+
// rejectTool(
|
|
233
|
+
// approvalItem: RunToolApprovalItem,
|
|
234
|
+
// { alwaysReject = false }: { alwaysReject?: boolean } = {},
|
|
235
|
+
// ) {
|
|
236
|
+
// const toolName = approvalItem.rawItem.name;
|
|
237
|
+
// if (alwaysReject) {
|
|
238
|
+
// this.#approvals.set(toolName, {
|
|
239
|
+
// approved: false,
|
|
240
|
+
// rejected: true,
|
|
241
|
+
// });
|
|
242
|
+
// return;
|
|
243
|
+
// }
|
|
244
|
+
|
|
245
|
+
// const approvalEntry = this.#approvals.get(toolName) ?? {
|
|
246
|
+
// approved: [] as string[],
|
|
247
|
+
// rejected: [] as string[],
|
|
248
|
+
// };
|
|
249
|
+
|
|
250
|
+
// if (Array.isArray(approvalEntry.rejected)) {
|
|
251
|
+
// // function tool has call_id, hosted tool call has id
|
|
252
|
+
// const callId =
|
|
253
|
+
// "callId" in approvalItem.rawItem
|
|
254
|
+
// ? approvalItem.rawItem.callId // function tools
|
|
255
|
+
// : approvalItem.rawItem.id!; // hosted tools
|
|
256
|
+
// approvalEntry.rejected.push(callId);
|
|
257
|
+
// }
|
|
258
|
+
// this.#approvals.set(toolName, approvalEntry);
|
|
259
|
+
// }
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Context that is being passed around as part of the session is unknown
|
|
264
|
+
*/
|
|
265
|
+
export type UnknownContext = unknown;
|