clanka 0.0.28 → 0.1.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.
- package/dist/Agent.d.ts +87 -40
- package/dist/Agent.d.ts.map +1 -1
- package/dist/Agent.js +154 -94
- package/dist/Agent.js.map +1 -1
- package/dist/AgentExecutor.d.ts +165 -0
- package/dist/AgentExecutor.d.ts.map +1 -0
- package/dist/AgentExecutor.js +121 -0
- package/dist/AgentExecutor.js.map +1 -0
- package/dist/AgentTools.d.ts +14 -132
- package/dist/AgentTools.d.ts.map +1 -1
- package/dist/AgentTools.js +10 -12
- package/dist/AgentTools.js.map +1 -1
- package/dist/OutputFormatter.d.ts.map +1 -1
- package/dist/OutputFormatter.js +18 -0
- package/dist/OutputFormatter.js.map +1 -1
- package/dist/WebToMarkdown.d.ts.map +1 -1
- package/dist/WebToMarkdown.js +1 -1
- package/dist/WebToMarkdown.js.map +1 -1
- package/dist/WebToMarkdown.test.d.ts +2 -0
- package/dist/WebToMarkdown.test.d.ts.map +1 -0
- package/dist/WebToMarkdown.test.js +37 -0
- package/dist/WebToMarkdown.test.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Agent.ts +290 -215
- package/src/AgentExecutor.ts +245 -0
- package/src/AgentTools.ts +25 -22
- package/src/OutputFormatter.ts +18 -0
- package/src/WebToMarkdown.test.ts +65 -0
- package/src/WebToMarkdown.ts +1 -0
- package/src/index.ts +4 -4
- package/dist/Agent.test.d.ts +0 -2
- package/dist/Agent.test.d.ts.map +0 -1
- package/dist/Agent.test.js +0 -111
- package/dist/Agent.test.js.map +0 -1
- package/dist/AgentTools.test.d.ts +0 -2
- package/dist/AgentTools.test.d.ts.map +0 -1
- package/dist/AgentTools.test.js +0 -714
- package/dist/AgentTools.test.js.map +0 -1
- package/dist/DuckDuckGo.d.ts +0 -28
- package/dist/DuckDuckGo.d.ts.map +0 -1
- package/dist/DuckDuckGo.js +0 -131
- package/dist/DuckDuckGo.js.map +0 -1
- package/dist/Executor.d.ts +0 -20
- package/dist/Executor.d.ts.map +0 -1
- package/dist/Executor.js +0 -98
- package/dist/Executor.js.map +0 -1
- package/dist/GithubCopilot.d.ts +0 -11
- package/dist/GithubCopilot.d.ts.map +0 -1
- package/dist/GithubCopilot.js +0 -14
- package/dist/GithubCopilot.js.map +0 -1
- package/dist/GithubCopilotAuth.d.ts +0 -57
- package/dist/GithubCopilotAuth.d.ts.map +0 -1
- package/dist/GithubCopilotAuth.js +0 -218
- package/dist/GithubCopilotAuth.js.map +0 -1
- package/dist/GithubCopilotAuth.test.d.ts +0 -2
- package/dist/GithubCopilotAuth.test.d.ts.map +0 -1
- package/dist/GithubCopilotAuth.test.js +0 -267
- package/dist/GithubCopilotAuth.test.js.map +0 -1
- package/dist/MockSearch.d.ts +0 -12
- package/dist/MockSearch.d.ts.map +0 -1
- package/dist/MockSearch.js +0 -4
- package/dist/MockSearch.js.map +0 -1
- package/dist/ai.d.ts +0 -2
- package/dist/ai.d.ts.map +0 -1
- package/dist/ai.js +0 -29
- package/dist/ai.js.map +0 -1
- package/dist/examples/cli.mjs +0 -68514
- package/src/Agent.test.ts +0 -159
- package/src/Executor.ts +0 -151
package/src/Agent.test.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { NodeServices } from "@effect/platform-node"
|
|
2
|
-
import { Effect, Layer, Stream } from "effect"
|
|
3
|
-
import { describe, it } from "@effect/vitest"
|
|
4
|
-
import { expect } from "vitest"
|
|
5
|
-
import { AgentModelConfig, make } from "./Agent.ts"
|
|
6
|
-
import { pretty } from "./OutputFormatter.ts"
|
|
7
|
-
import { LanguageModel, Prompt } from "effect/unstable/ai"
|
|
8
|
-
import * as Model from "effect/unstable/ai/Model"
|
|
9
|
-
import { Executor } from "./Executor.ts"
|
|
10
|
-
import { ToolkitRenderer } from "./ToolkitRenderer.ts"
|
|
11
|
-
import { AgentToolHandlersTest } from "./AgentTools.ts"
|
|
12
|
-
|
|
13
|
-
const usage = {
|
|
14
|
-
inputTokens: {
|
|
15
|
-
uncached: undefined,
|
|
16
|
-
total: undefined,
|
|
17
|
-
cacheRead: undefined,
|
|
18
|
-
cacheWrite: undefined,
|
|
19
|
-
},
|
|
20
|
-
outputTokens: {
|
|
21
|
-
total: undefined,
|
|
22
|
-
text: undefined,
|
|
23
|
-
reasoning: undefined,
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const promptText = (prompt: Prompt.Prompt) =>
|
|
28
|
-
prompt.content
|
|
29
|
-
.flatMap((message) => {
|
|
30
|
-
if (typeof message.content === "string") {
|
|
31
|
-
return [message.content]
|
|
32
|
-
}
|
|
33
|
-
return message.content.flatMap((part) => {
|
|
34
|
-
switch (part.type) {
|
|
35
|
-
case "text":
|
|
36
|
-
case "reasoning":
|
|
37
|
-
return [part.text]
|
|
38
|
-
|
|
39
|
-
default:
|
|
40
|
-
return []
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
.join("\n")
|
|
45
|
-
|
|
46
|
-
const scriptResponse = (script: string) =>
|
|
47
|
-
Stream.fromIterable([
|
|
48
|
-
{ type: "text-start", id: "script" } as const,
|
|
49
|
-
{ type: "text-delta", id: "script", delta: script } as const,
|
|
50
|
-
{ type: "text-end", id: "script" } as const,
|
|
51
|
-
{
|
|
52
|
-
type: "finish",
|
|
53
|
-
reason: "stop",
|
|
54
|
-
usage,
|
|
55
|
-
response: undefined,
|
|
56
|
-
} as const,
|
|
57
|
-
])
|
|
58
|
-
|
|
59
|
-
const TestModel = Model.make(
|
|
60
|
-
"test-provider",
|
|
61
|
-
"test-model",
|
|
62
|
-
Layer.effect(
|
|
63
|
-
LanguageModel.LanguageModel,
|
|
64
|
-
LanguageModel.make({
|
|
65
|
-
generateText: () => Effect.succeed([]),
|
|
66
|
-
streamText: ({ prompt }) => {
|
|
67
|
-
const text = promptText(prompt)
|
|
68
|
-
|
|
69
|
-
if (text.includes("grandchild task")) {
|
|
70
|
-
return scriptResponse(
|
|
71
|
-
[
|
|
72
|
-
'console.log("grandchild output")',
|
|
73
|
-
'await taskComplete("grandchild summary")',
|
|
74
|
-
].join("\n"),
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (text.includes("child task")) {
|
|
79
|
-
return scriptResponse(
|
|
80
|
-
[
|
|
81
|
-
'const result = await delegate("grandchild task")',
|
|
82
|
-
"await taskComplete(`child summary: ${result}`)",
|
|
83
|
-
].join("\n"),
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return scriptResponse(
|
|
88
|
-
[
|
|
89
|
-
'const result = await delegate("child task")',
|
|
90
|
-
"await taskComplete(`root summary: ${result}`)",
|
|
91
|
-
].join("\n"),
|
|
92
|
-
)
|
|
93
|
-
},
|
|
94
|
-
}),
|
|
95
|
-
),
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
describe("Agent", () => {
|
|
99
|
-
it.effect("forwards nested subagent output", () =>
|
|
100
|
-
Effect.gen(function* () {
|
|
101
|
-
const seen = [] as Array<string>
|
|
102
|
-
const agent = yield* make({
|
|
103
|
-
directory: process.cwd(),
|
|
104
|
-
prompt: "root task",
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
const output = yield* agent.output.pipe(
|
|
108
|
-
Stream.tap((part) =>
|
|
109
|
-
Effect.sync(() => {
|
|
110
|
-
switch (part._tag) {
|
|
111
|
-
case "SubagentStart":
|
|
112
|
-
case "SubagentComplete":
|
|
113
|
-
seen.push(`${part._tag}:${part.id}`)
|
|
114
|
-
break
|
|
115
|
-
|
|
116
|
-
case "SubagentPart":
|
|
117
|
-
seen.push(`${part._tag}:${part.id}:${part.part._tag}`)
|
|
118
|
-
break
|
|
119
|
-
|
|
120
|
-
default:
|
|
121
|
-
seen.push(part._tag)
|
|
122
|
-
break
|
|
123
|
-
}
|
|
124
|
-
}),
|
|
125
|
-
),
|
|
126
|
-
pretty,
|
|
127
|
-
Stream.mkString,
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
expect(seen).toContain("SubagentStart:1")
|
|
131
|
-
expect(seen).toContain("SubagentStart:2")
|
|
132
|
-
expect(seen).toContain("SubagentPart:2:ScriptStart")
|
|
133
|
-
expect(seen).toContain("SubagentPart:2:ScriptOutput")
|
|
134
|
-
expect(seen).toContain("SubagentComplete:2")
|
|
135
|
-
expect(seen).toContain("SubagentComplete:1")
|
|
136
|
-
|
|
137
|
-
expect(output).toContain("Subagent #1 starting")
|
|
138
|
-
expect(output).toContain("Subagent #2 starting")
|
|
139
|
-
expect(output).toContain("grandchild output")
|
|
140
|
-
expect(output).toContain("Subagent #2 complete")
|
|
141
|
-
expect(output).toContain("Task complete:")
|
|
142
|
-
expect(output).toContain(
|
|
143
|
-
"root summary: child summary: grandchild summary",
|
|
144
|
-
)
|
|
145
|
-
}).pipe(
|
|
146
|
-
Effect.provide(
|
|
147
|
-
Layer.mergeAll(
|
|
148
|
-
AgentToolHandlersTest,
|
|
149
|
-
TestModel,
|
|
150
|
-
AgentModelConfig.layer({
|
|
151
|
-
supportsNoTools: true,
|
|
152
|
-
}),
|
|
153
|
-
Executor.layer,
|
|
154
|
-
ToolkitRenderer.layer,
|
|
155
|
-
).pipe(Layer.provideMerge(NodeServices.layer)),
|
|
156
|
-
),
|
|
157
|
-
),
|
|
158
|
-
)
|
|
159
|
-
})
|
package/src/Executor.ts
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since 1.0.0
|
|
3
|
-
*/
|
|
4
|
-
import {
|
|
5
|
-
Cause,
|
|
6
|
-
Console,
|
|
7
|
-
Effect,
|
|
8
|
-
Exit,
|
|
9
|
-
Fiber,
|
|
10
|
-
Layer,
|
|
11
|
-
Queue,
|
|
12
|
-
Scope,
|
|
13
|
-
ServiceMap,
|
|
14
|
-
Stream,
|
|
15
|
-
} from "effect"
|
|
16
|
-
import { Tool, Toolkit } from "effect/unstable/ai"
|
|
17
|
-
import * as NodeConsole from "node:console"
|
|
18
|
-
import * as NodeVm from "node:vm"
|
|
19
|
-
import { Writable } from "node:stream"
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @since 1.0.0
|
|
23
|
-
* @category Services
|
|
24
|
-
*/
|
|
25
|
-
export class Executor extends ServiceMap.Service<
|
|
26
|
-
Executor,
|
|
27
|
-
{
|
|
28
|
-
execute<Tools extends Record<string, Tool.Any>>(options: {
|
|
29
|
-
readonly tools: Toolkit.WithHandler<Tools>
|
|
30
|
-
readonly script: string
|
|
31
|
-
}): Stream.Stream<string, never, Tool.HandlerServices<Tools[keyof Tools]>>
|
|
32
|
-
}
|
|
33
|
-
>()("clanka/Executor") {
|
|
34
|
-
static readonly layer = Layer.effect(
|
|
35
|
-
Executor,
|
|
36
|
-
// oxlint-disable-next-line require-yield
|
|
37
|
-
Effect.gen(function* () {
|
|
38
|
-
const execute = Effect.fnUntraced(function* <
|
|
39
|
-
Tools extends Record<string, Tool.Any>,
|
|
40
|
-
>(options: {
|
|
41
|
-
readonly tools: Toolkit.WithHandler<Tools>
|
|
42
|
-
readonly script: string
|
|
43
|
-
}) {
|
|
44
|
-
const output = yield* Queue.unbounded<string, Cause.Done>()
|
|
45
|
-
const console = yield* makeConsole(output)
|
|
46
|
-
const handlerScope = Scope.makeUnsafe("parallel")
|
|
47
|
-
const trackFiber = Fiber.runIn(handlerScope)
|
|
48
|
-
|
|
49
|
-
yield* Effect.gen(function* () {
|
|
50
|
-
const console = yield* Console.Console
|
|
51
|
-
const services = yield* Effect.services()
|
|
52
|
-
let running = 0
|
|
53
|
-
|
|
54
|
-
const script = new NodeVm.Script(`async function main() {
|
|
55
|
-
${options.script}
|
|
56
|
-
}`)
|
|
57
|
-
const sandbox: ScriptSandbox = {
|
|
58
|
-
main: defaultMain,
|
|
59
|
-
console,
|
|
60
|
-
fetch,
|
|
61
|
-
process: undefined,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for (const [name, tool] of Object.entries(options.tools.tools)) {
|
|
65
|
-
const handler = services.mapUnsafe.get(
|
|
66
|
-
tool.id,
|
|
67
|
-
) as Tool.Handler<string>
|
|
68
|
-
|
|
69
|
-
const handlerServices = ServiceMap.merge(services, handler.services)
|
|
70
|
-
const runFork = Effect.runForkWith(handlerServices)
|
|
71
|
-
|
|
72
|
-
// oxlint-disable-next-line typescript/no-explicit-any
|
|
73
|
-
sandbox[name] = function (params: any) {
|
|
74
|
-
running++
|
|
75
|
-
const fiber = trackFiber(runFork(handler.handler(params, {})))
|
|
76
|
-
return new Promise((resolve, reject) => {
|
|
77
|
-
fiber.addObserver((exit) => {
|
|
78
|
-
running--
|
|
79
|
-
if (exit._tag === "Success") {
|
|
80
|
-
resolve(exit.value)
|
|
81
|
-
} else {
|
|
82
|
-
if (Cause.hasInterruptsOnly(exit.cause)) return
|
|
83
|
-
reject(Cause.squash(exit.cause))
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
script.runInNewContext(sandbox, {
|
|
91
|
-
timeout: 1000,
|
|
92
|
-
})
|
|
93
|
-
yield* Effect.promise(sandbox.main)
|
|
94
|
-
while (true) {
|
|
95
|
-
yield* Effect.yieldNow
|
|
96
|
-
if (running === 0) break
|
|
97
|
-
}
|
|
98
|
-
}).pipe(
|
|
99
|
-
Effect.ensuring(Scope.close(handlerScope, Exit.void)),
|
|
100
|
-
Effect.catchCause(Effect.logFatal),
|
|
101
|
-
Effect.provideService(Console.Console, console),
|
|
102
|
-
Effect.ensuring(Queue.end(output)),
|
|
103
|
-
Effect.forkScoped,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
return Stream.fromQueue(output)
|
|
107
|
-
}, Stream.unwrap)
|
|
108
|
-
|
|
109
|
-
return Executor.of({
|
|
110
|
-
execute,
|
|
111
|
-
})
|
|
112
|
-
}),
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
interface ScriptSandbox {
|
|
117
|
-
main: () => Promise<void>
|
|
118
|
-
console: Console.Console
|
|
119
|
-
[toolName: string]: unknown
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const defaultMain = () => Promise.resolve()
|
|
123
|
-
|
|
124
|
-
const makeConsole = Effect.fn(function* (
|
|
125
|
-
queue: Queue.Queue<string, Cause.Done>,
|
|
126
|
-
) {
|
|
127
|
-
const writable = new QueueWriteStream(queue)
|
|
128
|
-
const newConsole = new NodeConsole.Console(writable)
|
|
129
|
-
yield* Effect.addFinalizer(() => {
|
|
130
|
-
writable.end()
|
|
131
|
-
return Effect.void
|
|
132
|
-
})
|
|
133
|
-
return newConsole
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
class QueueWriteStream extends Writable {
|
|
137
|
-
readonly queue: Queue.Enqueue<string, Cause.Done>
|
|
138
|
-
constructor(queue: Queue.Enqueue<string, Cause.Done>) {
|
|
139
|
-
super()
|
|
140
|
-
this.queue = queue
|
|
141
|
-
}
|
|
142
|
-
_write(
|
|
143
|
-
// oxlint-disable-next-line typescript/no-explicit-any
|
|
144
|
-
chunk: any,
|
|
145
|
-
_encoding: BufferEncoding,
|
|
146
|
-
callback: (error?: Error | null) => void,
|
|
147
|
-
): void {
|
|
148
|
-
Queue.offerUnsafe(this.queue, chunk.toString())
|
|
149
|
-
callback()
|
|
150
|
-
}
|
|
151
|
-
}
|