@agent-spaces/server 0.3.65 → 0.4.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/adapters/agent-runtime.js +8 -0
- package/dist/adapters/codex-function-tool-bridge.js +152 -0
- package/dist/adapters/codex-runtime.js +23 -4
- package/dist/adapters/git.js +25 -3
- package/dist/adapters/hermes-runtime.js +813 -0
- package/dist/adapters/langchain-runtime.js +384 -21
- package/dist/adapters/oh-my-pi-runtime.js +858 -0
- package/dist/adapters/open-agent-sdk-runtime.js +202 -5
- package/dist/adapters/open-agent-sdk-runtime.test.js +35 -0
- package/dist/agents/agent-message-parts.js +52 -2
- package/dist/agents/issue-task-controller.js +71 -2
- package/dist/agents/pull-request-agent.js +115 -0
- package/dist/agents/scheduler-agent.js +1 -1
- package/dist/agents/title-generator-agent.js +120 -0
- package/dist/app.js +61 -4
- package/dist/middleware/auth.js +1 -1
- package/dist/package.json +2 -1
- package/dist/routes/agent-sse.js +70 -6
- package/dist/routes/channel.js +23 -2
- package/dist/routes/chat-run.js +191 -0
- package/dist/routes/chat.js +142 -0
- package/dist/routes/command.js +16 -0
- package/dist/routes/data.js +189 -0
- package/dist/routes/git.js +10 -1
- package/dist/routes/import.js +199 -0
- package/dist/routes/issue.js +17 -5
- package/dist/routes/notification.js +10 -0
- package/dist/routes/plugin.js +69 -0
- package/dist/routes/version.js +95 -0
- package/dist/routes/workflow-hook.js +71 -0
- package/dist/routes/workflow.js +282 -7
- package/dist/routes/workspace.js +13 -4
- package/dist/routes/worktree.js +93 -0
- package/dist/services/agent.js +123 -36
- package/dist/services/ai-text.js +185 -0
- package/dist/services/builtin-tools/index.js +1 -0
- package/dist/services/builtin-tools/workflow-editor-tools.js +509 -0
- package/dist/services/builtin-tools/workflow-exec-tools.js +320 -0
- package/dist/services/chat.js +134 -0
- package/dist/services/command-process-manager.js +16 -0
- package/dist/services/execution-manager.js +1346 -0
- package/dist/services/generated-title.js +59 -0
- package/dist/services/gitignore.js +22 -18
- package/dist/services/interaction-manager.js +114 -0
- package/dist/services/issue-retry.js +25 -0
- package/dist/services/notification-center.js +9 -0
- package/dist/services/output-style.js +8 -1
- package/dist/services/plugin.js +257 -0
- package/dist/services/prompt-template.js +8 -1
- package/dist/services/pty.js +20 -0
- package/dist/services/search.js +16 -6
- package/dist/services/skill.js +2 -0
- package/dist/services/version.js +69 -0
- package/dist/services/workflow-command-runner.js +24 -0
- package/dist/services/workflow-trigger-service.js +137 -0
- package/dist/services/workflow.js +219 -39
- package/dist/services/workspace.js +23 -1
- package/dist/services/worktree.js +207 -0
- package/dist/storage/agent-store.js +8 -0
- package/dist/storage/chat-store.js +151 -0
- package/dist/storage/database-store.js +6 -0
- package/dist/storage/json-store.js +2 -1
- package/dist/storage/kanban-store.js +6 -0
- package/dist/storage/workflow-store.js +386 -22
- package/dist/storage/worktree-store.js +33 -0
- package/dist/web/404.html +1 -1
- package/dist/web/__next.__PAGE__.txt +4 -4
- package/dist/web/__next._full.txt +21 -21
- package/dist/web/__next._head.txt +4 -4
- package/dist/web/__next._index.txt +13 -13
- package/dist/web/__next._tree.txt +2 -2
- package/dist/web/_next/static/chunks/{08x85faoz58i7.js → 0-92u-tiuy40a.js} +4 -4
- package/dist/web/_next/static/chunks/{0db14450oqzhg.js → 0-yizd8osmas2.js} +1 -1
- package/dist/web/_next/static/chunks/0.ln~3mnv8.69.js +1 -0
- package/dist/web/_next/static/chunks/{11cchuwoupmbf.js → 01y3e9pemva7b.js} +10 -10
- package/dist/web/_next/static/chunks/02l~tmzrgny.~.js +1 -0
- package/dist/web/_next/static/chunks/03f1bwuynjdmk.js +1 -0
- package/dist/web/_next/static/chunks/04cb4kc9r2pd1.js +1 -0
- package/dist/web/_next/static/chunks/04de6ha5_e3pp.js +1 -0
- package/dist/web/_next/static/chunks/09he0p79ov1rn.js +1 -0
- package/dist/web/_next/static/chunks/09vpocs4zuc8h.js +1 -0
- package/dist/web/_next/static/chunks/0_o2exgr0e_nh.js +1 -0
- package/dist/web/_next/static/chunks/{0xbaakj0dfc0..js → 0_y9nskc-xt2k.js} +1 -1
- package/dist/web/_next/static/chunks/0clnj-1fi6u8j.js +3 -0
- package/dist/web/_next/static/chunks/0gv40by0zzxs_.js +1 -0
- package/dist/web/_next/static/chunks/0iusr8y88.kjg.js +1 -0
- package/dist/web/_next/static/chunks/{0-a.-hl3wv99k.js → 0j-8418fxvkd1.js} +1 -1
- package/dist/web/_next/static/chunks/0j.wxxyoclma5.js +1 -0
- package/dist/web/_next/static/chunks/{0.6b64sy0g5.3.js → 0jq.16sozqik..js} +1 -1
- package/dist/web/_next/static/chunks/0jw8xdk_fpnp0.css +1 -0
- package/dist/web/_next/static/chunks/0l1lkd-wcotma.js +1 -0
- package/dist/web/_next/static/chunks/{0u6h-hqc_i52e.js → 0ncxf_zr4n839.js} +1 -1
- package/dist/web/_next/static/chunks/0ndo7um~v7vco.js +1 -0
- package/dist/web/_next/static/chunks/0ngk.~kan8wq_.js +1 -0
- package/dist/web/_next/static/chunks/0ppr271hz0xoq.js +1 -0
- package/dist/web/_next/static/chunks/0rt9bofnn6qvn.js +1 -0
- package/dist/web/_next/static/chunks/0t64.9jd00hio.js +3 -0
- package/dist/web/_next/static/chunks/0taui9--5n6-5.js +1 -0
- package/dist/web/_next/static/chunks/0ty39169lh~z3.js +1 -0
- package/dist/web/_next/static/chunks/0v8nof~waedlu.js +1 -0
- package/dist/web/_next/static/chunks/{0-pi.67w.ymsr.js → 0vcfoagnpf.aw.js} +1 -1
- package/dist/web/_next/static/chunks/{0vis~lx0nxgn-.js → 0wwwq.gyyz0vg.js} +3 -3
- package/dist/web/_next/static/chunks/0x5lak8yz7pm7.js +1 -0
- package/dist/web/_next/static/chunks/0xon_.4-o0_zq.js +7 -0
- package/dist/web/_next/static/chunks/0zjnrbt7inime.js +1 -0
- package/dist/web/_next/static/chunks/0zwebpitvpuv1.js +1 -0
- package/dist/web/_next/static/chunks/0~02o4g-o6n~m.js +1 -0
- package/dist/web/_next/static/chunks/{0w7.tb29958zj.js → 0~fjezp.k4qk3.js} +1 -1
- package/dist/web/_next/static/chunks/0~sh93re1-_rp.js +1 -0
- package/dist/web/_next/static/chunks/10_niiq0k6o-p.js +5 -0
- package/dist/web/_next/static/chunks/12tjr0_2ccrtq.js +2 -0
- package/dist/web/_next/static/chunks/12x5.go_x9mfk.js +1 -0
- package/dist/web/_next/static/chunks/{0l2w0qz1ea7ql.js → 12~5dk9i9d16t.js} +2 -2
- package/dist/web/_next/static/chunks/13iye4rv5p31b.js +1 -0
- package/dist/web/_next/static/chunks/{01~quun6sefgl.js → 13~y-b.b9rrw4.js} +1 -1
- package/dist/web/_next/static/chunks/151wzhb5q0lo5.js +1 -0
- package/dist/web/_not-found/__next._full.txt +19 -19
- package/dist/web/_not-found/__next._head.txt +4 -4
- package/dist/web/_not-found/__next._index.txt +13 -13
- package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
- package/dist/web/_not-found/__next._not-found.txt +3 -3
- package/dist/web/_not-found/__next._tree.txt +2 -2
- package/dist/web/_not-found.html +1 -1
- package/dist/web/_not-found.txt +19 -19
- package/dist/web/index.html +1 -1
- package/dist/web/index.txt +21 -21
- package/dist/web/login/__next._full.txt +21 -21
- package/dist/web/login/__next._head.txt +4 -4
- package/dist/web/login/__next._index.txt +13 -13
- package/dist/web/login/__next._tree.txt +2 -2
- package/dist/web/login/__next.login.__PAGE__.txt +4 -4
- package/dist/web/login/__next.login.txt +3 -3
- package/dist/web/login.html +1 -1
- package/dist/web/login.txt +21 -21
- package/dist/web/settings/__next._full.txt +23 -23
- package/dist/web/settings/__next._head.txt +4 -4
- package/dist/web/settings/__next._index.txt +13 -13
- package/dist/web/settings/__next._tree.txt +2 -2
- package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
- package/dist/web/settings/__next.settings.txt +5 -5
- package/dist/web/settings/agents/__next._full.txt +23 -23
- package/dist/web/settings/agents/__next._head.txt +4 -4
- package/dist/web/settings/agents/__next._index.txt +13 -13
- package/dist/web/settings/agents/__next._tree.txt +2 -2
- package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
- package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
- package/dist/web/settings/agents/__next.settings.txt +5 -5
- package/dist/web/settings/agents.html +1 -1
- package/dist/web/settings/agents.txt +23 -23
- package/dist/web/settings/mcps/__next._full.txt +23 -23
- package/dist/web/settings/mcps/__next._head.txt +4 -4
- package/dist/web/settings/mcps/__next._index.txt +13 -13
- package/dist/web/settings/mcps/__next._tree.txt +2 -2
- package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
- package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
- package/dist/web/settings/mcps/__next.settings.txt +5 -5
- package/dist/web/settings/mcps.html +1 -1
- package/dist/web/settings/mcps.txt +23 -23
- package/dist/web/settings/models/__next._full.txt +23 -23
- package/dist/web/settings/models/__next._head.txt +4 -4
- package/dist/web/settings/models/__next._index.txt +13 -13
- package/dist/web/settings/models/__next._tree.txt +2 -2
- package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
- package/dist/web/settings/models/__next.settings.models.txt +3 -3
- package/dist/web/settings/models/__next.settings.txt +5 -5
- package/dist/web/settings/models.html +1 -1
- package/dist/web/settings/models.txt +23 -23
- package/dist/web/settings/output-styles/__next._full.txt +23 -23
- package/dist/web/settings/output-styles/__next._head.txt +4 -4
- package/dist/web/settings/output-styles/__next._index.txt +13 -13
- package/dist/web/settings/output-styles/__next._tree.txt +2 -2
- package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
- package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
- package/dist/web/settings/output-styles/__next.settings.txt +5 -5
- package/dist/web/settings/output-styles.html +1 -1
- package/dist/web/settings/output-styles.txt +23 -23
- package/dist/web/settings/prompts/__next._full.txt +23 -23
- package/dist/web/settings/prompts/__next._head.txt +4 -4
- package/dist/web/settings/prompts/__next._index.txt +13 -13
- package/dist/web/settings/prompts/__next._tree.txt +2 -2
- package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
- package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
- package/dist/web/settings/prompts/__next.settings.txt +5 -5
- package/dist/web/settings/prompts.html +1 -1
- package/dist/web/settings/prompts.txt +23 -23
- package/dist/web/settings/providers/__next._full.txt +23 -23
- package/dist/web/settings/providers/__next._head.txt +4 -4
- package/dist/web/settings/providers/__next._index.txt +13 -13
- package/dist/web/settings/providers/__next._tree.txt +2 -2
- package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
- package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
- package/dist/web/settings/providers/__next.settings.txt +5 -5
- package/dist/web/settings/providers.html +1 -1
- package/dist/web/settings/providers.txt +23 -23
- package/dist/web/settings/skills/__next._full.txt +23 -23
- package/dist/web/settings/skills/__next._head.txt +4 -4
- package/dist/web/settings/skills/__next._index.txt +13 -13
- package/dist/web/settings/skills/__next._tree.txt +2 -2
- package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
- package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
- package/dist/web/settings/skills/__next.settings.txt +5 -5
- package/dist/web/settings/skills.html +1 -1
- package/dist/web/settings/skills.txt +23 -23
- package/dist/web/settings/tools/__next._full.txt +23 -23
- package/dist/web/settings/tools/__next._head.txt +4 -4
- package/dist/web/settings/tools/__next._index.txt +13 -13
- package/dist/web/settings/tools/__next._tree.txt +2 -2
- package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +4 -4
- package/dist/web/settings/tools/__next.settings.tools.txt +3 -3
- package/dist/web/settings/tools/__next.settings.txt +5 -5
- package/dist/web/settings/tools.html +1 -1
- package/dist/web/settings/tools.txt +23 -23
- package/dist/web/settings.html +1 -1
- package/dist/web/settings.txt +23 -23
- package/dist/web/workflows/__next._full.txt +22 -22
- package/dist/web/workflows/__next._head.txt +4 -4
- package/dist/web/workflows/__next._index.txt +13 -13
- package/dist/web/workflows/__next._tree.txt +2 -2
- package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
- package/dist/web/workflows/__next.workflows.txt +3 -3
- package/dist/web/workflows.html +1 -1
- package/dist/web/workflows.txt +22 -22
- package/dist/web/workspace/_/__next._full.txt +20 -20
- package/dist/web/workspace/_/__next._head.txt +4 -4
- package/dist/web/workspace/_/__next._index.txt +13 -13
- package/dist/web/workspace/_/__next._tree.txt +2 -2
- package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
- package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
- package/dist/web/workspace/_/__next.workspace.txt +3 -3
- package/dist/web/workspace/_.html +1 -1
- package/dist/web/workspace/_.txt +20 -20
- package/dist/web/workspaces/__next._full.txt +21 -21
- package/dist/web/workspaces/__next._head.txt +4 -4
- package/dist/web/workspaces/__next._index.txt +13 -13
- package/dist/web/workspaces/__next._tree.txt +2 -2
- package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
- package/dist/web/workspaces/__next.workspaces.txt +3 -3
- package/dist/web/workspaces.html +1 -1
- package/dist/web/workspaces.txt +21 -21
- package/dist/ws/agent-prompt.js +36 -3
- package/dist/ws/agent-runner.js +30 -18
- package/dist/ws/chat-handler.js +89 -0
- package/dist/ws/connection-manager.js +49 -2
- package/dist/ws/execution-channels.js +88 -0
- package/dist/ws/handler.js +32 -5
- package/dist/ws/message-parts.js +130 -12
- package/dist/ws/terminal-handler.js +26 -0
- package/package.json +13 -1
- package/public/avatars/user.jpg +0 -0
- package/dist/web/_next/static/chunks/0-v_p6j5u3_9l.js +0 -1
- package/dist/web/_next/static/chunks/0.-x29t-8gk0r.js +0 -1
- package/dist/web/_next/static/chunks/0.l5e8~r7_0~p.js +0 -1
- package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +0 -1
- package/dist/web/_next/static/chunks/00-syqzi-6zxr.js +0 -1
- package/dist/web/_next/static/chunks/02j4sr9psucf-.js +0 -1
- package/dist/web/_next/static/chunks/06si8l0doqe8p.js +0 -1
- package/dist/web/_next/static/chunks/08kfx8on9oty~.js +0 -1
- package/dist/web/_next/static/chunks/08ugbvzr20drp.js +0 -2
- package/dist/web/_next/static/chunks/0_cqojbge48kq.js +0 -5
- package/dist/web/_next/static/chunks/0d6~~lv0-6kex.js +0 -3
- package/dist/web/_next/static/chunks/0gdwop9cnpmtu.js +0 -1
- package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +0 -1
- package/dist/web/_next/static/chunks/0kbvoxla7f751.js +0 -1
- package/dist/web/_next/static/chunks/0paaat8y96ayc.js +0 -7
- package/dist/web/_next/static/chunks/0pq318f8xgafg.js +0 -1
- package/dist/web/_next/static/chunks/0t6s8of0qr6nc.js +0 -1
- package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +0 -1
- package/dist/web/_next/static/chunks/0yd.m1afqg.2t.js +0 -3
- package/dist/web/_next/static/chunks/0yhbr8hl09b-5.js +0 -1
- package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +0 -1
- package/dist/web/_next/static/chunks/0~~_ltu6dx_ch.js +0 -1
- package/dist/web/_next/static/chunks/12oxcgyhpaxw~.js +0 -1
- package/dist/web/_next/static/chunks/1452eibz62gs6.css +0 -1
- package/dist/web/_next/static/chunks/16zlreiems5cn.js +0 -1
- package/dist/web/_next/static/chunks/18awqjk9-o5m0.js +0 -1
- /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_buildManifest.js +0 -0
- /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_ssgManifest.js +0 -0
package/dist/services/agent.js
CHANGED
|
@@ -11,7 +11,13 @@ import { extractUsageFromOutput } from '../storage/usage.js';
|
|
|
11
11
|
const DEFAULT_AGENT_ROLE = 'agent';
|
|
12
12
|
export const AGENT_GENERATOR_PRESET_ID = 'agent-generator';
|
|
13
13
|
export const AGENT_COMMIT_PRESET_ID = 'commit-agent';
|
|
14
|
-
const
|
|
14
|
+
export const AGENT_TITLE_GENERATOR_PRESET_ID = 'title-generator';
|
|
15
|
+
const BUILT_IN_AGENT_IDS = [
|
|
16
|
+
AGENT_GENERATOR_PRESET_ID,
|
|
17
|
+
AGENT_COMMIT_PRESET_ID,
|
|
18
|
+
AGENT_TITLE_GENERATOR_PRESET_ID,
|
|
19
|
+
];
|
|
20
|
+
const VALID_RUNTIME_KINDS = ['open-agent-sdk', 'claude-code', 'codex', 'langchain', 'hermes', 'oh-my-pi'];
|
|
15
21
|
const VALID_TOOL_NAMES = new Set(BUILT_IN_AGENT_TOOLS.map((tool) => tool.name));
|
|
16
22
|
const CLAUDE_BUILT_IN_DIRS = ['agents', 'commands'];
|
|
17
23
|
const ANTHROPIC_BRIDGE_PROVIDERS = [
|
|
@@ -27,18 +33,12 @@ export function isValidRole(role) {
|
|
|
27
33
|
export function listTemplates() {
|
|
28
34
|
const root = getGlobalAgentTemplatesDir();
|
|
29
35
|
if (!existsSync(root))
|
|
30
|
-
return
|
|
36
|
+
return getDefaultBuiltInAgentPresets();
|
|
31
37
|
const templates = readdirSync(root, { withFileTypes: true })
|
|
32
38
|
.filter((entry) => entry.isDirectory())
|
|
33
39
|
.map((entry) => readAgentTemplate(entry.name))
|
|
34
40
|
.filter((template) => Boolean(template));
|
|
35
|
-
|
|
36
|
-
templates.unshift(getDefaultAgentGeneratorPreset());
|
|
37
|
-
}
|
|
38
|
-
if (!templates.some((template) => template.id === AGENT_COMMIT_PRESET_ID)) {
|
|
39
|
-
templates.unshift(getDefaultCommitAgentPreset());
|
|
40
|
-
}
|
|
41
|
-
return templates;
|
|
41
|
+
return withBuiltInTemplatesFirst(templates);
|
|
42
42
|
}
|
|
43
43
|
export async function testConnection(workspaceId, data) {
|
|
44
44
|
if (workspaceId) {
|
|
@@ -279,8 +279,11 @@ export function createPreset(_workspaceId, data) {
|
|
|
279
279
|
skills: normalizeSkillNames(data.skills),
|
|
280
280
|
tools: normalizeToolNames(data.tools ?? BUILT_IN_AGENT_TOOLS.map((tool) => tool.name)),
|
|
281
281
|
systemPrompt: data.systemPrompt || '',
|
|
282
|
+
outputStyle: data.outputStyle,
|
|
282
283
|
temperature: data.temperature ?? 0.3,
|
|
283
284
|
maxTokens: data.maxTokens ?? 4096,
|
|
285
|
+
avatarUrl: data.avatarUrl,
|
|
286
|
+
icon: data.icon,
|
|
284
287
|
sandboxDirs: data.sandboxDirs,
|
|
285
288
|
maxRetries: data.maxRetries,
|
|
286
289
|
templateId: data.templateId,
|
|
@@ -316,12 +319,8 @@ export function updatePreset(_workspaceId, presetId, data) {
|
|
|
316
319
|
return updated;
|
|
317
320
|
}
|
|
318
321
|
export function getAllowedTools(mcps) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
const servers = mcps.mcpServers;
|
|
322
|
-
if (!servers || typeof servers !== 'object' || Array.isArray(servers))
|
|
323
|
-
return undefined;
|
|
324
|
-
return Object.keys(servers);
|
|
322
|
+
const servers = getMcpServers(mcps);
|
|
323
|
+
return servers ? Object.keys(servers) : undefined;
|
|
325
324
|
}
|
|
326
325
|
export function getMcpServers(mcps) {
|
|
327
326
|
if (!mcps)
|
|
@@ -329,7 +328,11 @@ export function getMcpServers(mcps) {
|
|
|
329
328
|
const servers = mcps.mcpServers;
|
|
330
329
|
if (!servers || typeof servers !== 'object' || Array.isArray(servers))
|
|
331
330
|
return undefined;
|
|
332
|
-
|
|
331
|
+
const resolved = Object.fromEntries(Object.entries(servers).flatMap(([name, server]) => {
|
|
332
|
+
const config = getRunnableMcpServerConfig(server) ?? readStoredMcpServerConfig(name);
|
|
333
|
+
return config ? [[name, config]] : [];
|
|
334
|
+
}));
|
|
335
|
+
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
333
336
|
}
|
|
334
337
|
export function getAgentConfigDir(workspaceId, preset) {
|
|
335
338
|
const ws = getWorkspace(workspaceId);
|
|
@@ -362,13 +365,13 @@ export function getAvailableSkillNames(agentDir, skills) {
|
|
|
362
365
|
if (!skill)
|
|
363
366
|
return false;
|
|
364
367
|
const skillsBase = join(agentDir, 'skills');
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
return existsSync(
|
|
368
|
+
if (hasReadableSkillSource(skillsBase, skill))
|
|
369
|
+
return true;
|
|
370
|
+
const globalSkillFile = join(getDataDir(), 'skills', skill, 'SKILL.md');
|
|
371
|
+
if (existsSync(globalSkillFile) && statSync(globalSkillFile).size > 0)
|
|
372
|
+
return true;
|
|
373
|
+
const globalLegacySkillFile = join(getDataDir(), 'skills', `${skill}.md`);
|
|
374
|
+
return existsSync(globalLegacySkillFile) && statSync(globalLegacySkillFile).size > 0;
|
|
372
375
|
});
|
|
373
376
|
}
|
|
374
377
|
export function resolveWorkingDir(workspaceId, preset) {
|
|
@@ -423,6 +426,31 @@ function normalizeMcpConfig(mcps) {
|
|
|
423
426
|
return {};
|
|
424
427
|
return mcps;
|
|
425
428
|
}
|
|
429
|
+
function getRunnableMcpServerConfig(server) {
|
|
430
|
+
if (!server || typeof server !== 'object' || Array.isArray(server))
|
|
431
|
+
return null;
|
|
432
|
+
const record = server;
|
|
433
|
+
if (typeof record.command === 'string' && record.command.trim())
|
|
434
|
+
return record;
|
|
435
|
+
if (typeof record.url === 'string' && record.url.trim())
|
|
436
|
+
return record;
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
function readStoredMcpServerConfig(name) {
|
|
440
|
+
const filePath = join(getDataDir(), 'mcps', `${sanitizeMcpName(name)}.json`);
|
|
441
|
+
if (!existsSync(filePath))
|
|
442
|
+
return null;
|
|
443
|
+
try {
|
|
444
|
+
const parsed = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
445
|
+
return getRunnableMcpServerConfig(parsed.config);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function sanitizeMcpName(name) {
|
|
452
|
+
return name.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'mcp-server';
|
|
453
|
+
}
|
|
426
454
|
function normalizeModelProvider(provider) {
|
|
427
455
|
return provider || undefined;
|
|
428
456
|
}
|
|
@@ -565,10 +593,24 @@ function ensureWorkspaceAgentCopy(preset, agentspaceDir) {
|
|
|
565
593
|
&& statSync(sourceBuiltInDir).isDirectory()
|
|
566
594
|
&& countFiles(sourceBuiltInDir) > countFiles(targetBuiltInDir);
|
|
567
595
|
});
|
|
568
|
-
|
|
596
|
+
const missingSkill = (preset.skills ?? []).some((skill) => {
|
|
597
|
+
const skillName = skill.replace(/\.md$/i, '');
|
|
598
|
+
const targetSkillsDir = join(workspaceAgentDir, 'skills');
|
|
599
|
+
return !hasReadableSkillSource(targetSkillsDir, skillName);
|
|
600
|
+
});
|
|
601
|
+
if (!missingRequiredFile && !missingBuiltInDir && !missingSkill)
|
|
569
602
|
return;
|
|
570
603
|
writeWorkspaceAgentCopy(preset, agentspaceDir);
|
|
571
604
|
}
|
|
605
|
+
function hasReadableSkillSource(skillsDir, skillName) {
|
|
606
|
+
const skillDir = join(skillsDir, skillName);
|
|
607
|
+
const skillFile = join(skillDir, 'SKILL.md');
|
|
608
|
+
if (existsSync(skillDir) && statSync(skillDir).isDirectory()) {
|
|
609
|
+
return existsSync(skillFile) && statSync(skillFile).size > 0;
|
|
610
|
+
}
|
|
611
|
+
const legacySkillFile = join(skillsDir, `${skillName}.md`);
|
|
612
|
+
return existsSync(legacySkillFile) && statSync(legacySkillFile).size > 0;
|
|
613
|
+
}
|
|
572
614
|
function countFiles(dir) {
|
|
573
615
|
if (!existsSync(dir) || !statSync(dir).isDirectory())
|
|
574
616
|
return 0;
|
|
@@ -582,19 +624,37 @@ function countFiles(dir) {
|
|
|
582
624
|
export function readAgentTemplate(agentId) {
|
|
583
625
|
const filePath = join(getGlobalAgentTemplateDir(agentId), 'agent.json');
|
|
584
626
|
if (!existsSync(filePath)) {
|
|
585
|
-
return agentId
|
|
586
|
-
: agentId === AGENT_COMMIT_PRESET_ID ? getDefaultCommitAgentPreset()
|
|
587
|
-
: null;
|
|
627
|
+
return getDefaultBuiltInAgentPreset(agentId);
|
|
588
628
|
}
|
|
589
629
|
try {
|
|
590
630
|
return JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
591
631
|
}
|
|
592
632
|
catch {
|
|
593
|
-
return agentId
|
|
594
|
-
: agentId === AGENT_COMMIT_PRESET_ID ? getDefaultCommitAgentPreset()
|
|
595
|
-
: null;
|
|
633
|
+
return getDefaultBuiltInAgentPreset(agentId);
|
|
596
634
|
}
|
|
597
635
|
}
|
|
636
|
+
function getDefaultBuiltInAgentPresets() {
|
|
637
|
+
return [
|
|
638
|
+
getDefaultAgentGeneratorPreset(),
|
|
639
|
+
getDefaultCommitAgentPreset(),
|
|
640
|
+
getDefaultTitleGeneratorPreset(),
|
|
641
|
+
];
|
|
642
|
+
}
|
|
643
|
+
function getDefaultBuiltInAgentPreset(agentId) {
|
|
644
|
+
if (agentId === AGENT_GENERATOR_PRESET_ID)
|
|
645
|
+
return getDefaultAgentGeneratorPreset();
|
|
646
|
+
if (agentId === AGENT_COMMIT_PRESET_ID)
|
|
647
|
+
return getDefaultCommitAgentPreset();
|
|
648
|
+
if (agentId === AGENT_TITLE_GENERATOR_PRESET_ID)
|
|
649
|
+
return getDefaultTitleGeneratorPreset();
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
function withBuiltInTemplatesFirst(templates) {
|
|
653
|
+
const byId = new Map(templates.map((template) => [template.id, template]));
|
|
654
|
+
const builtIns = getDefaultBuiltInAgentPresets().map((preset) => byId.get(preset.id) ?? preset);
|
|
655
|
+
const custom = templates.filter((template) => !BUILT_IN_AGENT_IDS.includes(template.id));
|
|
656
|
+
return [...builtIns, ...custom];
|
|
657
|
+
}
|
|
598
658
|
function getDefaultAgentGeneratorPreset() {
|
|
599
659
|
return {
|
|
600
660
|
id: AGENT_GENERATOR_PRESET_ID,
|
|
@@ -658,15 +718,44 @@ export function getDefaultCommitAgentPreset() {
|
|
|
658
718
|
enabled: true,
|
|
659
719
|
};
|
|
660
720
|
}
|
|
721
|
+
export function getDefaultTitleGeneratorPreset() {
|
|
722
|
+
return {
|
|
723
|
+
id: AGENT_TITLE_GENERATOR_PRESET_ID,
|
|
724
|
+
name: 'Title Generator',
|
|
725
|
+
role: 'agent',
|
|
726
|
+
description: 'Generate short titles for channels and issues from user requirements.',
|
|
727
|
+
runtimeKind: 'claude-code',
|
|
728
|
+
modelProvider: undefined,
|
|
729
|
+
modelId: '',
|
|
730
|
+
apiBase: '',
|
|
731
|
+
apiKey: '',
|
|
732
|
+
workingDir: '',
|
|
733
|
+
mcps: {},
|
|
734
|
+
skills: [],
|
|
735
|
+
tools: [],
|
|
736
|
+
systemPrompt: [
|
|
737
|
+
'You generate objective scene titles for Agent Spaces channels and issues.',
|
|
738
|
+
'Return exactly one title and nothing else.',
|
|
739
|
+
'The title must describe the scenario, task, or intent objectively.',
|
|
740
|
+
'Do not include a speaking subject, assistant identity, user identity, first-person wording, second-person wording, greetings, replies, questions, or conversational text.',
|
|
741
|
+
'For Chinese, prefer a short noun phrase ending with 场景, 任务, 问题, 需求, 讨论, or 分析 when appropriate.',
|
|
742
|
+
'Examples: user says "你好" -> "打招呼场景"; user says "帮我修复登录报错" -> "登录报错修复"; user says "分析这段代码" -> "代码分析任务".',
|
|
743
|
+
'Use the same language as the user request when it is clear.',
|
|
744
|
+
'Keep the title under 20 Chinese characters or under 8 English words.',
|
|
745
|
+
'Do not use quotes, markdown, punctuation-only endings, prefixes, explanations, or multiple options.',
|
|
746
|
+
].join(' '),
|
|
747
|
+
temperature: 0.2,
|
|
748
|
+
maxTokens: 64,
|
|
749
|
+
enabled: true,
|
|
750
|
+
};
|
|
751
|
+
}
|
|
661
752
|
function sanitizeMarkdownFilename(name) {
|
|
662
753
|
const raw = basename(name).replace(/\.md$/i, '');
|
|
663
754
|
const safe = raw.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'skill';
|
|
664
755
|
return `${safe}.md`;
|
|
665
756
|
}
|
|
666
757
|
export function deletePreset(workspaceId, presetId) {
|
|
667
|
-
if (presetId
|
|
668
|
-
return false;
|
|
669
|
-
if (presetId === AGENT_COMMIT_PRESET_ID)
|
|
758
|
+
if (BUILT_IN_AGENT_IDS.includes(presetId))
|
|
670
759
|
return false;
|
|
671
760
|
const ws = getWorkspace(workspaceId);
|
|
672
761
|
if (!ws)
|
|
@@ -755,9 +844,7 @@ export function updateGlobalPreset(presetId, data) {
|
|
|
755
844
|
return updated;
|
|
756
845
|
}
|
|
757
846
|
export function deleteGlobalPreset(presetId) {
|
|
758
|
-
if (presetId
|
|
759
|
-
return false;
|
|
760
|
-
if (presetId === AGENT_COMMIT_PRESET_ID)
|
|
847
|
+
if (BUILT_IN_AGENT_IDS.includes(presetId))
|
|
761
848
|
return false;
|
|
762
849
|
const templateDir = getGlobalAgentTemplateDir(presetId);
|
|
763
850
|
if (!existsSync(templateDir))
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
export async function requestAiText(config, input) {
|
|
2
|
+
const provider = config.modelProvider ?? inferProvider(config.apiBase);
|
|
3
|
+
if (provider === 'anthropic-messages')
|
|
4
|
+
return requestAnthropic(config, input.systemPrompt, input.userPrompt);
|
|
5
|
+
if (provider === 'gemini-generate-content')
|
|
6
|
+
return requestGemini(config, input.systemPrompt, input.userPrompt);
|
|
7
|
+
return requestOpenAICompatible(config, input.systemPrompt, input.userPrompt, provider === 'openai-responses' || provider === 'openai-responses-to-anthropic-messages');
|
|
8
|
+
}
|
|
9
|
+
export function maskAiTextUrl(url) {
|
|
10
|
+
if (!url)
|
|
11
|
+
return undefined;
|
|
12
|
+
try {
|
|
13
|
+
const parsed = new URL(url);
|
|
14
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return url.slice(0, 80);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function requestOpenAICompatible(config, systemPrompt, userPrompt, useResponsesApi) {
|
|
21
|
+
const response = await fetch(joinUrl(config.apiBase, useResponsesApi ? '/responses' : '/chat/completions'), {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(useResponsesApi
|
|
28
|
+
? {
|
|
29
|
+
model: config.modelId,
|
|
30
|
+
input: `${systemPrompt}\n\n${userPrompt}`,
|
|
31
|
+
temperature: config.temperature ?? 0.2,
|
|
32
|
+
max_output_tokens: config.maxTokens ?? 1024,
|
|
33
|
+
}
|
|
34
|
+
: {
|
|
35
|
+
model: config.modelId,
|
|
36
|
+
messages: [
|
|
37
|
+
{ role: 'system', content: systemPrompt },
|
|
38
|
+
{ role: 'user', content: userPrompt },
|
|
39
|
+
],
|
|
40
|
+
temperature: config.temperature ?? 0.2,
|
|
41
|
+
max_tokens: config.maxTokens ?? 1024,
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
const body = await readResponseBody(response);
|
|
45
|
+
if (!response.ok || body.error)
|
|
46
|
+
throw new Error(body.error || `AI text request failed with status ${response.status}`);
|
|
47
|
+
return body.text;
|
|
48
|
+
}
|
|
49
|
+
async function requestAnthropic(config, systemPrompt, userPrompt) {
|
|
50
|
+
const response = await fetch(getAnthropicMessagesUrl(config.apiBase), {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: {
|
|
53
|
+
'x-api-key': config.apiKey,
|
|
54
|
+
'anthropic-version': '2023-06-01',
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
model: config.modelId,
|
|
59
|
+
system: systemPrompt,
|
|
60
|
+
messages: [{ role: 'user', content: userPrompt }],
|
|
61
|
+
max_tokens: config.maxTokens ?? 1024,
|
|
62
|
+
temperature: config.temperature ?? 0.2,
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
const body = await readResponseBody(response);
|
|
66
|
+
if (!response.ok || body.error)
|
|
67
|
+
throw new Error(body.error || `AI text request failed with status ${response.status}`);
|
|
68
|
+
return body.text;
|
|
69
|
+
}
|
|
70
|
+
async function requestGemini(config, systemPrompt, userPrompt) {
|
|
71
|
+
const response = await fetch(joinUrl(config.apiBase, `/models/${encodeURIComponent(config.modelId)}:generateContent`), {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'x-goog-api-key': config.apiKey,
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
systemInstruction: { parts: [{ text: systemPrompt }] },
|
|
79
|
+
contents: [{ role: 'user', parts: [{ text: userPrompt }] }],
|
|
80
|
+
generationConfig: {
|
|
81
|
+
temperature: config.temperature ?? 0.2,
|
|
82
|
+
maxOutputTokens: config.maxTokens ?? 1024,
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
const body = await readResponseBody(response);
|
|
87
|
+
if (!response.ok || body.error)
|
|
88
|
+
throw new Error(body.error || `AI text request failed with status ${response.status}`);
|
|
89
|
+
return body.text;
|
|
90
|
+
}
|
|
91
|
+
async function readResponseBody(response) {
|
|
92
|
+
const raw = await response.text();
|
|
93
|
+
if (!raw)
|
|
94
|
+
return { text: '' };
|
|
95
|
+
try {
|
|
96
|
+
const json = JSON.parse(raw);
|
|
97
|
+
return {
|
|
98
|
+
text: extractText(json),
|
|
99
|
+
error: extractError(json),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return { text: raw };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function extractText(json) {
|
|
107
|
+
const outputText = json.output_text;
|
|
108
|
+
if (typeof outputText === 'string')
|
|
109
|
+
return outputText;
|
|
110
|
+
const output = Array.isArray(json.output) ? json.output : [];
|
|
111
|
+
const responseOutputText = output
|
|
112
|
+
.flatMap((item) => Array.isArray(item.content) ? item.content : [])
|
|
113
|
+
.map((part) => typeof part.text === 'string' ? part.text : '')
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.join('\n');
|
|
116
|
+
if (responseOutputText)
|
|
117
|
+
return responseOutputText;
|
|
118
|
+
const choices = Array.isArray(json.choices) ? json.choices : [];
|
|
119
|
+
const firstChoice = choices[0];
|
|
120
|
+
if (typeof firstChoice?.text === 'string')
|
|
121
|
+
return firstChoice.text;
|
|
122
|
+
const message = firstChoice?.message;
|
|
123
|
+
if (typeof message?.content === 'string')
|
|
124
|
+
return message.content;
|
|
125
|
+
if (Array.isArray(message?.content)) {
|
|
126
|
+
const messageText = message.content
|
|
127
|
+
.map((part) => typeof part.text === 'string' ? part.text : '')
|
|
128
|
+
.filter(Boolean)
|
|
129
|
+
.join('\n');
|
|
130
|
+
if (messageText)
|
|
131
|
+
return messageText;
|
|
132
|
+
}
|
|
133
|
+
const content = Array.isArray(json.content) ? json.content : [];
|
|
134
|
+
const anthropicText = content
|
|
135
|
+
.map((part) => typeof part.text === 'string' ? part.text : '')
|
|
136
|
+
.filter(Boolean)
|
|
137
|
+
.join('\n');
|
|
138
|
+
if (anthropicText)
|
|
139
|
+
return anthropicText;
|
|
140
|
+
const candidates = Array.isArray(json.candidates) ? json.candidates : [];
|
|
141
|
+
const firstCandidate = candidates[0];
|
|
142
|
+
const parts = (firstCandidate?.content?.parts ?? []);
|
|
143
|
+
return parts
|
|
144
|
+
.map((part) => typeof part.text === 'string' ? part.text : '')
|
|
145
|
+
.filter(Boolean)
|
|
146
|
+
.join('\n');
|
|
147
|
+
}
|
|
148
|
+
function extractError(json) {
|
|
149
|
+
if (json.success === false) {
|
|
150
|
+
return typeof json.msg === 'string' ? json.msg : 'Provider returned success=false';
|
|
151
|
+
}
|
|
152
|
+
const error = json.error;
|
|
153
|
+
if (typeof error === 'string')
|
|
154
|
+
return error;
|
|
155
|
+
if (error && typeof error === 'object') {
|
|
156
|
+
const message = error.message;
|
|
157
|
+
if (typeof message === 'string')
|
|
158
|
+
return message;
|
|
159
|
+
}
|
|
160
|
+
return typeof json.message === 'string' ? json.message : undefined;
|
|
161
|
+
}
|
|
162
|
+
function inferProvider(apiBase) {
|
|
163
|
+
if (apiBase?.includes('anthropic.com'))
|
|
164
|
+
return 'anthropic-messages';
|
|
165
|
+
if (apiBase?.includes('generativelanguage.googleapis.com'))
|
|
166
|
+
return 'gemini-generate-content';
|
|
167
|
+
return 'openai-chat-completions';
|
|
168
|
+
}
|
|
169
|
+
function joinUrl(base, path) {
|
|
170
|
+
return `${base.replace(/\/+$/, '')}${path}`;
|
|
171
|
+
}
|
|
172
|
+
function getAnthropicMessagesUrl(apiBase) {
|
|
173
|
+
try {
|
|
174
|
+
const url = new URL(apiBase);
|
|
175
|
+
if (url.pathname.endsWith('/messages'))
|
|
176
|
+
return apiBase;
|
|
177
|
+
if (url.hostname === 'api.anthropic.com')
|
|
178
|
+
return joinUrl(apiBase, '/messages');
|
|
179
|
+
return joinUrl(apiBase, '/v1/messages');
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return apiBase;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=ai-text.js.map
|
|
@@ -2,4 +2,5 @@ export { createIssueFunctionTools, isBuiltInIssueToolName } from './issue-tools.
|
|
|
2
2
|
export { createCommandFunctionTools } from './command-tools.js';
|
|
3
3
|
export { createDatabaseFunctionTools } from './database-tools.js';
|
|
4
4
|
export { createKanbanFunctionTools } from './kanban-tools.js';
|
|
5
|
+
export { createWorkflowExecutionFunctionTools, setWorkflowExecutionManager } from './workflow-exec-tools.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|