saeeol 1.2.1 → 1.2.3
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/bin/saeeol.cjs +187 -0
- package/npm/bin/saeeol +0 -0
- package/package.json +12 -12
- package/src/cli/cmd/tui/component/dialog/dialog-agent.tsx +32 -0
- package/src/cli/cmd/tui/component/dialog/dialog-command.tsx +190 -0
- package/src/cli/cmd/tui/component/dialog/dialog-console-org.tsx +103 -0
- package/src/cli/cmd/tui/component/dialog/dialog-go-upsell.tsx +159 -0
- package/src/cli/cmd/tui/component/dialog/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog/dialog-model.tsx +238 -0
- package/src/cli/cmd/tui/component/dialog/dialog-provider.tsx +343 -0
- package/src/cli/cmd/tui/component/dialog/dialog-session-delete-failed.tsx +103 -0
- package/src/cli/cmd/tui/component/dialog/dialog-session-list.tsx +301 -0
- package/src/cli/cmd/tui/component/dialog/dialog-session-rename.tsx +35 -0
- package/src/cli/cmd/tui/component/dialog/dialog-skill.tsx +37 -0
- package/src/cli/cmd/tui/component/dialog/dialog-stash.tsx +87 -0
- package/src/cli/cmd/tui/component/dialog/dialog-status.tsx +190 -0
- package/src/cli/cmd/tui/component/dialog/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog/dialog-theme-list.tsx +50 -0
- package/src/cli/cmd/tui/component/dialog/dialog-variant.tsx +39 -0
- package/src/cli/cmd/tui/component/dialog/dialog-workspace-create.tsx +200 -0
- package/src/cli/cmd/tui/component/dialog/dialog-workspace-unavailable.tsx +81 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +1 -32
- package/src/cli/cmd/tui/component/dialog-command.tsx +1 -190
- package/src/cli/cmd/tui/component/dialog-console-org.tsx +1 -103
- package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +1 -159
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +1 -86
- package/src/cli/cmd/tui/component/dialog-model.tsx +1 -238
- package/src/cli/cmd/tui/component/dialog-provider.tsx +1 -343
- package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +1 -103
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +1 -301
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +1 -35
- package/src/cli/cmd/tui/component/dialog-skill.tsx +1 -37
- package/src/cli/cmd/tui/component/dialog-stash.tsx +1 -87
- package/src/cli/cmd/tui/component/dialog-status.tsx +1 -190
- package/src/cli/cmd/tui/component/dialog-tag.tsx +1 -44
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +1 -50
- package/src/cli/cmd/tui/component/dialog-variant.tsx +1 -39
- package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +1 -200
- package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +1 -81
- package/src/cli/cmd/tui/context/app/args.tsx +15 -0
- package/src/cli/cmd/tui/context/app/directory.ts +15 -0
- package/src/cli/cmd/tui/context/app/editor-zed.ts +281 -0
- package/src/cli/cmd/tui/context/app/editor.ts +425 -0
- package/src/cli/cmd/tui/context/app/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/app/project.tsx +109 -0
- package/src/cli/cmd/tui/context/app/route.tsx +67 -0
- package/src/cli/cmd/tui/context/app/sdk.tsx +142 -0
- package/src/cli/cmd/tui/context/app/sync.tsx +713 -0
- package/src/cli/cmd/tui/context/app/theme.tsx +307 -0
- package/src/cli/cmd/tui/context/app/tui-config.tsx +9 -0
- package/src/cli/cmd/tui/context/args.tsx +1 -15
- package/src/cli/cmd/tui/context/directory.ts +1 -15
- package/src/cli/cmd/tui/context/editor-zed.ts +1 -281
- package/src/cli/cmd/tui/context/editor.ts +1 -425
- package/src/cli/cmd/tui/context/event.ts +1 -45
- package/src/cli/cmd/tui/context/exit.tsx +1 -67
- package/src/cli/cmd/tui/context/helper.tsx +1 -25
- package/src/cli/cmd/tui/context/keybind.tsx +1 -105
- package/src/cli/cmd/tui/context/kv.tsx +1 -76
- package/src/cli/cmd/tui/context/local.tsx +1 -478
- package/src/cli/cmd/tui/context/plugin-keybinds.ts +1 -41
- package/src/cli/cmd/tui/context/project.tsx +1 -109
- package/src/cli/cmd/tui/context/prompt.tsx +1 -18
- package/src/cli/cmd/tui/context/route.tsx +1 -67
- package/src/cli/cmd/tui/context/runtime/event.ts +45 -0
- package/src/cli/cmd/tui/context/runtime/exit.tsx +67 -0
- package/src/cli/cmd/tui/context/runtime/keybind.tsx +105 -0
- package/src/cli/cmd/tui/context/runtime/kv.tsx +76 -0
- package/src/cli/cmd/tui/context/runtime/local.tsx +478 -0
- package/src/cli/cmd/tui/context/runtime/plugin-keybinds.ts +41 -0
- package/src/cli/cmd/tui/context/sdk.tsx +1 -142
- package/src/cli/cmd/tui/context/session/prompt.tsx +18 -0
- package/src/cli/cmd/tui/context/sync.tsx +1 -713
- package/src/cli/cmd/tui/context/theme.tsx +1 -307
- package/src/cli/cmd/tui/context/tui-config.tsx +1 -9
- package/src/tool/apply_patch.ts +1 -334
- package/src/tool/bash.ts +1 -656
- package/src/tool/core/external-directory.ts +55 -0
- package/src/tool/core/invalid.ts +21 -0
- package/src/tool/core/recall.ts +164 -0
- package/src/tool/core/recall.txt +12 -0
- package/src/tool/core/schema.ts +16 -0
- package/src/tool/core/tool.ts +162 -0
- package/src/tool/core/truncate.ts +160 -0
- package/src/tool/core/truncation-dir.ts +4 -0
- package/src/tool/diagnostics.ts +1 -20
- package/src/tool/edit-replacers.ts +1 -288
- package/src/tool/edit-utils.ts +1 -86
- package/src/tool/edit.ts +1 -262
- package/src/tool/external-directory.ts +1 -55
- package/src/tool/file/apply_patch.ts +334 -0
- package/src/tool/file/apply_patch.txt +33 -0
- package/src/tool/file/bash.ts +656 -0
- package/src/tool/file/bash.txt +119 -0
- package/src/tool/file/edit-replacers.ts +288 -0
- package/src/tool/file/edit-utils.ts +86 -0
- package/src/tool/file/edit.ts +262 -0
- package/src/tool/file/edit.txt +10 -0
- package/src/tool/file/read.ts +389 -0
- package/src/tool/file/read.txt +14 -0
- package/src/tool/file/write.ts +114 -0
- package/src/tool/file/write.txt +8 -0
- package/src/tool/glob.ts +1 -115
- package/src/tool/grep.ts +1 -151
- package/src/tool/integration/diagnostics.ts +20 -0
- package/src/tool/integration/lsp.ts +113 -0
- package/src/tool/integration/lsp.txt +24 -0
- package/src/tool/integration/mcp-exa.ts +73 -0
- package/src/tool/integration/package.ts +168 -0
- package/src/tool/integration/registry.ts +375 -0
- package/src/tool/invalid.ts +1 -21
- package/src/tool/lsp.ts +1 -113
- package/src/tool/mcp-exa.ts +1 -73
- package/src/tool/package.ts +1 -168
- package/src/tool/plan.ts +1 -30
- package/src/tool/question.ts +1 -52
- package/src/tool/read.ts +1 -389
- package/src/tool/recall.ts +1 -164
- package/src/tool/registry.ts +1 -375
- package/src/tool/schema.ts +1 -16
- package/src/tool/search/glob.ts +115 -0
- package/src/tool/search/glob.txt +6 -0
- package/src/tool/search/grep.ts +151 -0
- package/src/tool/search/grep.txt +8 -0
- package/src/tool/search/warpgrep.ts +107 -0
- package/src/tool/search/warpgrep.txt +10 -0
- package/src/tool/search/webfetch.ts +202 -0
- package/src/tool/search/webfetch.txt +13 -0
- package/src/tool/search/websearch.ts +71 -0
- package/src/tool/search/websearch.txt +14 -0
- package/src/tool/skill.ts +1 -91
- package/src/tool/task.ts +1 -197
- package/src/tool/todo.ts +1 -62
- package/src/tool/tool.ts +1 -162
- package/src/tool/truncate.ts +1 -160
- package/src/tool/truncation-dir.ts +1 -4
- package/src/tool/warpgrep.ts +1 -107
- package/src/tool/webfetch.ts +1 -202
- package/src/tool/websearch.ts +1 -71
- package/src/tool/workflow/plan-enter.txt +14 -0
- package/src/tool/workflow/plan-exit.txt +13 -0
- package/src/tool/workflow/plan.ts +30 -0
- package/src/tool/workflow/question.ts +52 -0
- package/src/tool/workflow/question.txt +11 -0
- package/src/tool/workflow/skill.ts +91 -0
- package/src/tool/workflow/skill.txt +5 -0
- package/src/tool/workflow/task.ts +197 -0
- package/src/tool/workflow/task.txt +57 -0
- package/src/tool/workflow/todo.ts +62 -0
- package/src/tool/workflow/todowrite.txt +167 -0
- package/src/tool/write.ts +1 -114
package/src/tool/mcp-exa.ts
CHANGED
|
@@ -1,73 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { HttpClient, HttpClientRequest } from "effect/unstable/http"
|
|
3
|
-
|
|
4
|
-
const URL = process.env.EXA_API_KEY
|
|
5
|
-
? `https://mcp.exa.ai/mcp?exaApiKey=${encodeURIComponent(process.env.EXA_API_KEY)}`
|
|
6
|
-
: "https://mcp.exa.ai/mcp"
|
|
7
|
-
|
|
8
|
-
const McpResult = Schema.Struct({
|
|
9
|
-
result: Schema.Struct({
|
|
10
|
-
content: Schema.Array(
|
|
11
|
-
Schema.Struct({
|
|
12
|
-
type: Schema.String,
|
|
13
|
-
text: Schema.String,
|
|
14
|
-
}),
|
|
15
|
-
),
|
|
16
|
-
}),
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const decode = Schema.decodeUnknownEffect(Schema.fromJsonString(McpResult))
|
|
20
|
-
|
|
21
|
-
const parseSse = Effect.fn("McpExa.parseSse")(function* (body: string) {
|
|
22
|
-
for (const line of body.split("\n")) {
|
|
23
|
-
if (!line.startsWith("data: ")) continue
|
|
24
|
-
const data = yield* decode(line.substring(6))
|
|
25
|
-
if (data.result.content[0]?.text) return data.result.content[0].text
|
|
26
|
-
}
|
|
27
|
-
return undefined
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
export const SearchArgs = Schema.Struct({
|
|
31
|
-
query: Schema.String,
|
|
32
|
-
type: Schema.String,
|
|
33
|
-
numResults: Schema.Number,
|
|
34
|
-
livecrawl: Schema.String,
|
|
35
|
-
contextMaxCharacters: Schema.optional(Schema.Number),
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const McpRequest = <F extends Schema.Struct.Fields>(args: Schema.Struct<F>) =>
|
|
39
|
-
Schema.Struct({
|
|
40
|
-
jsonrpc: Schema.Literal("2.0"),
|
|
41
|
-
id: Schema.Literal(1),
|
|
42
|
-
method: Schema.Literal("tools/call"),
|
|
43
|
-
params: Schema.Struct({
|
|
44
|
-
name: Schema.String,
|
|
45
|
-
arguments: args,
|
|
46
|
-
}),
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
export const call = <F extends Schema.Struct.Fields>(
|
|
50
|
-
http: HttpClient.HttpClient,
|
|
51
|
-
tool: string,
|
|
52
|
-
args: Schema.Struct<F>,
|
|
53
|
-
value: Schema.Struct.Type<F>,
|
|
54
|
-
timeout: Duration.Input,
|
|
55
|
-
) =>
|
|
56
|
-
Effect.gen(function* () {
|
|
57
|
-
const request = yield* HttpClientRequest.post(URL).pipe(
|
|
58
|
-
HttpClientRequest.accept("application/json, text/event-stream"),
|
|
59
|
-
HttpClientRequest.schemaBodyJson(McpRequest(args))({
|
|
60
|
-
jsonrpc: "2.0" as const,
|
|
61
|
-
id: 1 as const,
|
|
62
|
-
method: "tools/call" as const,
|
|
63
|
-
params: { name: tool, arguments: value },
|
|
64
|
-
}),
|
|
65
|
-
)
|
|
66
|
-
const response = yield* HttpClient.filterStatusOk(http)
|
|
67
|
-
.execute(request)
|
|
68
|
-
.pipe(
|
|
69
|
-
Effect.timeoutOrElse({ duration: timeout, orElse: () => Effect.die(new Error(`${tool} request timed out`)) }),
|
|
70
|
-
)
|
|
71
|
-
const body = yield* response.text
|
|
72
|
-
return yield* parseSse(body)
|
|
73
|
-
})
|
|
1
|
+
export * from "./integration/mcp-exa"
|
package/src/tool/package.ts
CHANGED
|
@@ -1,168 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { Npm } from "@saeeol/core/npm"
|
|
3
|
-
import * as Bus from "@/bus"
|
|
4
|
-
import * as Tool from "./tool"
|
|
5
|
-
import { ProviderInstallEvent } from "@/provider/provider-events"
|
|
6
|
-
|
|
7
|
-
const Parameters = Schema.Struct({
|
|
8
|
-
action: Schema.Literals(["install", "list"]).annotate({
|
|
9
|
-
description: '"install" to install provider packages, "list" to show available providers',
|
|
10
|
-
}),
|
|
11
|
-
packages: Schema.optional(Schema.Array(Schema.String)).annotate({
|
|
12
|
-
description:
|
|
13
|
-
'Package names to install. npm names like "@ai-sdk/anthropic" or short names like "anthropic".',
|
|
14
|
-
}),
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
type Params = Schema.Schema.Type<typeof Parameters>
|
|
18
|
-
|
|
19
|
-
const SHORT_NAME_MAP: Record<string, string> = {
|
|
20
|
-
anthropic: "@ai-sdk/anthropic",
|
|
21
|
-
openai: "@ai-sdk/openai",
|
|
22
|
-
"openai-compatible": "@ai-sdk/openai-compatible",
|
|
23
|
-
google: "@ai-sdk/google",
|
|
24
|
-
"google-vertex": "@ai-sdk/google-vertex",
|
|
25
|
-
bedrock: "@ai-sdk/amazon-bedrock",
|
|
26
|
-
"amazon-bedrock": "@ai-sdk/amazon-bedrock",
|
|
27
|
-
azure: "@ai-sdk/azure",
|
|
28
|
-
openrouter: "@openrouter/ai-sdk-provider",
|
|
29
|
-
groq: "@ai-sdk/groq",
|
|
30
|
-
deepinfra: "@ai-sdk/deepinfra",
|
|
31
|
-
gateway: "@ai-sdk/gateway",
|
|
32
|
-
alibaba: "@ai-sdk/alibaba",
|
|
33
|
-
cerebras: "@ai-sdk/cerebras",
|
|
34
|
-
xai: "@ai-sdk/xai",
|
|
35
|
-
mistral: "@ai-sdk/mistral",
|
|
36
|
-
cohere: "@ai-sdk/cohere",
|
|
37
|
-
togetherai: "@ai-sdk/togetherai",
|
|
38
|
-
perplexity: "@ai-sdk/perplexity",
|
|
39
|
-
vercel: "@ai-sdk/vercel",
|
|
40
|
-
gitlab: "gitlab-ai-provider",
|
|
41
|
-
venice: "venice-ai-sdk-provider",
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const KNOWN_PROVIDERS = [
|
|
45
|
-
{ npm: "@saeeol/gateway", label: "Saeeol Gateway (bundled)" },
|
|
46
|
-
{ npm: "@ai-sdk/anthropic", label: "Anthropic (Claude)" },
|
|
47
|
-
{ npm: "@ai-sdk/openai", label: "OpenAI (GPT)" },
|
|
48
|
-
{ npm: "@ai-sdk/openai-compatible", label: "OpenAI Compatible" },
|
|
49
|
-
{ npm: "@ai-sdk/google", label: "Google (Gemini)" },
|
|
50
|
-
{ npm: "@ai-sdk/github-copilot", label: "GitHub Copilot" },
|
|
51
|
-
{ npm: "@ai-sdk/amazon-bedrock", label: "Amazon Bedrock" },
|
|
52
|
-
{ npm: "@ai-sdk/azure", label: "Azure OpenAI" },
|
|
53
|
-
{ npm: "@ai-sdk/google-vertex", label: "Google Vertex AI" },
|
|
54
|
-
{ npm: "@openrouter/ai-sdk-provider", label: "OpenRouter" },
|
|
55
|
-
{ npm: "@ai-sdk/groq", label: "Groq" },
|
|
56
|
-
{ npm: "@ai-sdk/deepinfra", label: "DeepInfra" },
|
|
57
|
-
{ npm: "@ai-sdk/gateway", label: "Vercel AI Gateway" },
|
|
58
|
-
{ npm: "@ai-sdk/alibaba", label: "Alibaba (Qwen)" },
|
|
59
|
-
{ npm: "@ai-sdk/cerebras", label: "Cerebras" },
|
|
60
|
-
{ npm: "@ai-sdk/xai", label: "xAI (Grok)" },
|
|
61
|
-
{ npm: "@ai-sdk/mistral", label: "Mistral" },
|
|
62
|
-
{ npm: "@ai-sdk/cohere", label: "Cohere" },
|
|
63
|
-
{ npm: "@ai-sdk/togetherai", label: "Together AI" },
|
|
64
|
-
{ npm: "@ai-sdk/perplexity", label: "Perplexity" },
|
|
65
|
-
{ npm: "@ai-sdk/vercel", label: "Vercel" },
|
|
66
|
-
]
|
|
67
|
-
|
|
68
|
-
function resolve(pkg: string) {
|
|
69
|
-
if (pkg.startsWith("@") || pkg.startsWith("file://")) return pkg
|
|
70
|
-
return SHORT_NAME_MAP[pkg] ?? pkg
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const PackageTool = Tool.define(
|
|
74
|
-
"package",
|
|
75
|
-
Effect.gen(function* () {
|
|
76
|
-
return {
|
|
77
|
-
description: [
|
|
78
|
-
"Manage saeeol provider SDK packages.",
|
|
79
|
-
"",
|
|
80
|
-
"Use this tool when the user asks to install additional AI providers,",
|
|
81
|
-
"or when you detect that a required provider is not available.",
|
|
82
|
-
"",
|
|
83
|
-
'Actions: "install" — install provider packages, "list" — show available providers',
|
|
84
|
-
"",
|
|
85
|
-
"Short names: anthropic, openai, google, bedrock, azure, openrouter, groq,",
|
|
86
|
-
"deepinfra, cerebras, xai, mistral, cohere, togetherai, perplexity, vercel",
|
|
87
|
-
].join("\n"),
|
|
88
|
-
parameters: Parameters,
|
|
89
|
-
execute: (params: Params, ctx: Tool.Context) =>
|
|
90
|
-
Effect.gen(function* () {
|
|
91
|
-
if (params.action === "list") {
|
|
92
|
-
const lines = [
|
|
93
|
-
"Available provider SDKs:",
|
|
94
|
-
"",
|
|
95
|
-
...KNOWN_PROVIDERS.map((p) => ` ${p.label}\n npm: ${p.npm}`),
|
|
96
|
-
"",
|
|
97
|
-
'Install: { action: "install", packages: ["anthropic"] }',
|
|
98
|
-
]
|
|
99
|
-
return { title: "Available Providers", output: lines.join("\n"), metadata: {} }
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// action === "install"
|
|
103
|
-
const packages = params.packages
|
|
104
|
-
if (!packages || packages.length === 0) {
|
|
105
|
-
return {
|
|
106
|
-
title: "Package Install",
|
|
107
|
-
output: "No packages specified. Provide package names in the 'packages' array.",
|
|
108
|
-
metadata: {},
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const resolved = packages.map(resolve)
|
|
113
|
-
|
|
114
|
-
yield* ctx.ask({
|
|
115
|
-
permission: "package",
|
|
116
|
-
patterns: resolved,
|
|
117
|
-
always: resolved,
|
|
118
|
-
metadata: {},
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
const results: string[] = []
|
|
122
|
-
for (const pkg of resolved) {
|
|
123
|
-
void Bus.publish(ProviderInstallEvent.Started, {
|
|
124
|
-
providerID: pkg,
|
|
125
|
-
pkg,
|
|
126
|
-
})
|
|
127
|
-
try {
|
|
128
|
-
const entry = yield* Effect.promise(() => Npm.add(pkg))
|
|
129
|
-
if (!entry.entrypoint) {
|
|
130
|
-
void Bus.publish(ProviderInstallEvent.Failed, {
|
|
131
|
-
providerID: pkg,
|
|
132
|
-
pkg,
|
|
133
|
-
error: "No import entrypoint found",
|
|
134
|
-
})
|
|
135
|
-
results.push(`X ${pkg}: no import entrypoint`)
|
|
136
|
-
continue
|
|
137
|
-
}
|
|
138
|
-
void Bus.publish(ProviderInstallEvent.Completed, {
|
|
139
|
-
providerID: pkg,
|
|
140
|
-
pkg,
|
|
141
|
-
})
|
|
142
|
-
results.push(`OK ${pkg}`)
|
|
143
|
-
} catch (err) {
|
|
144
|
-
const msg = err instanceof Error ? err.message : String(err)
|
|
145
|
-
void Bus.publish(ProviderInstallEvent.Failed, {
|
|
146
|
-
providerID: pkg,
|
|
147
|
-
pkg,
|
|
148
|
-
error: msg,
|
|
149
|
-
})
|
|
150
|
-
results.push(`X ${pkg}: ${msg}`)
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
title: "Package Install",
|
|
156
|
-
output: [
|
|
157
|
-
`${resolved.length} package(s) processed:`,
|
|
158
|
-
"",
|
|
159
|
-
...results,
|
|
160
|
-
"",
|
|
161
|
-
"Installed providers are now available.",
|
|
162
|
-
].join("\n"),
|
|
163
|
-
metadata: {},
|
|
164
|
-
}
|
|
165
|
-
}),
|
|
166
|
-
}
|
|
167
|
-
}),
|
|
168
|
-
)
|
|
1
|
+
export * from "./integration/package"
|
package/src/tool/plan.ts
CHANGED
|
@@ -1,30 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { Effect, Schema } from "effect"
|
|
3
|
-
import * as Tool from "./tool"
|
|
4
|
-
import { Session } from "@/session/session"
|
|
5
|
-
import { InstanceState } from "@/effect/instance-state"
|
|
6
|
-
import EXIT_DESCRIPTION from "./plan-exit.txt"
|
|
7
|
-
|
|
8
|
-
export const Parameters = Schema.Struct({})
|
|
9
|
-
export const PlanExitTool = Tool.define(
|
|
10
|
-
"plan_exit",
|
|
11
|
-
Effect.gen(function* () {
|
|
12
|
-
const session = yield* Session.Service
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
description: EXIT_DESCRIPTION,
|
|
16
|
-
parameters: Parameters,
|
|
17
|
-
execute: (_params: {}, ctx: Tool.Context) =>
|
|
18
|
-
Effect.gen(function* () {
|
|
19
|
-
const instance = yield* InstanceState.context
|
|
20
|
-
const info = yield* session.get(ctx.sessionID)
|
|
21
|
-
const plan = path.relative(instance.worktree, Session.plan(info, instance))
|
|
22
|
-
return {
|
|
23
|
-
title: "Planning complete",
|
|
24
|
-
output: `Plan is ready at ${plan}. Ending planning turn.`,
|
|
25
|
-
metadata: { plan },
|
|
26
|
-
}
|
|
27
|
-
}).pipe(Effect.orDie),
|
|
28
|
-
}
|
|
29
|
-
}),
|
|
30
|
-
)
|
|
1
|
+
export * from "./workflow/plan"
|
package/src/tool/question.ts
CHANGED
|
@@ -1,52 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { plural } from "@saeeol/boxes/plural"
|
|
3
|
-
import * as Tool from "./tool"
|
|
4
|
-
import { Question } from "../question"
|
|
5
|
-
import DESCRIPTION from "./question.txt"
|
|
6
|
-
import { SaeeolQuestionTool } from "@/saeeol/tool/question"
|
|
7
|
-
|
|
8
|
-
export const Parameters = Schema.Struct({
|
|
9
|
-
questions: Schema.mutable(Schema.Array(Question.Prompt)).annotate({ description: "Questions to ask" }),
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
type Metadata = {
|
|
13
|
-
answers: ReadonlyArray<Question.Answer>
|
|
14
|
-
dismissed?: boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const QuestionTool = Tool.define<typeof Parameters, Metadata, Question.Service>(
|
|
18
|
-
"question",
|
|
19
|
-
Effect.gen(function* () {
|
|
20
|
-
const question = yield* Question.Service
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
description: DESCRIPTION,
|
|
24
|
-
parameters: Parameters,
|
|
25
|
-
execute: (params: Schema.Schema.Type<typeof Parameters>, ctx: Tool.Context<Metadata>) =>
|
|
26
|
-
Effect.gen(function* () {
|
|
27
|
-
// tool result via SaeeolQuestionTool helpers, so Effect.orDie below does not turn
|
|
28
|
-
// it into a defect and kill the in-flight stream.
|
|
29
|
-
const answers = yield* question
|
|
30
|
-
.ask({
|
|
31
|
-
sessionID: ctx.sessionID,
|
|
32
|
-
questions: params.questions,
|
|
33
|
-
tool: ctx.callID ? { messageID: ctx.messageID, callID: ctx.callID } : undefined,
|
|
34
|
-
})
|
|
35
|
-
.pipe(SaeeolQuestionTool.catchDismissed)
|
|
36
|
-
if (SaeeolQuestionTool.isDismissed(answers)) return SaeeolQuestionTool.dismissedResult()
|
|
37
|
-
|
|
38
|
-
const formatted = params.questions
|
|
39
|
-
.map((q, i) => `"${q.question}"="${answers[i]?.length ? answers[i].join(", ") : "Unanswered"}"`)
|
|
40
|
-
.join(", ")
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
title: plural(params.questions.length, `Asked {} question`, `Asked {} questions`),
|
|
44
|
-
output: `User has answered your questions: ${formatted}. You can now continue with the user's answers in mind.`,
|
|
45
|
-
metadata: {
|
|
46
|
-
answers,
|
|
47
|
-
},
|
|
48
|
-
}
|
|
49
|
-
}).pipe(Effect.orDie),
|
|
50
|
-
}
|
|
51
|
-
}),
|
|
52
|
-
)
|
|
1
|
+
export * from "./workflow/question"
|