@cremini/skillpack 1.1.8 → 1.1.9
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/README.md +5 -1
- package/dist/cli.js +126 -40
- package/package.json +1 -1
- package/templates/builtin-skills/skill-creator/LICENSE.txt +202 -0
- package/templates/builtin-skills/skill-creator/SKILL.md +171 -0
- package/templates/builtin-skills/skill-creator/agents/analyzer.md +274 -0
- package/templates/builtin-skills/skill-creator/agents/comparator.md +202 -0
- package/templates/builtin-skills/skill-creator/agents/grader.md +223 -0
- package/templates/builtin-skills/skill-creator/assets/eval_review.html +146 -0
- package/templates/builtin-skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/templates/builtin-skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/templates/builtin-skills/skill-creator/references/schemas.md +430 -0
- package/templates/builtin-skills/skill-creator/scripts/__init__.py +0 -0
- package/templates/builtin-skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/templates/builtin-skills/skill-creator/scripts/generate_report.py +326 -0
- package/templates/builtin-skills/skill-creator/scripts/improve_description.py +247 -0
- package/templates/builtin-skills/skill-creator/scripts/package_skill.py +136 -0
- package/templates/builtin-skills/skill-creator/scripts/quick_validate.py +103 -0
- package/templates/builtin-skills/skill-creator/scripts/run_eval.py +310 -0
- package/templates/builtin-skills/skill-creator/scripts/run_loop.py +328 -0
- package/templates/builtin-skills/skill-creator/scripts/utils.py +47 -0
- package/web/js/chat.js +8 -8
package/README.md
CHANGED
|
@@ -20,7 +20,9 @@ Skillpack is built for teams that want AI Agents to be deployable, trusted, and
|
|
|
20
20
|
|
|
21
21
|
### 1. Run a skillpack
|
|
22
22
|
|
|
23
|
-
1. Download the example
|
|
23
|
+
1. Download the example
|
|
24
|
+
- [Garry Tan SkillPack](https://github.com/CreminiAI/skillpack-examples/releases/download/v.0.0.3/garry-tan.zip)
|
|
25
|
+
- [Company Deep Research SkillPack](https://github.com/FinpeakInc/downloads/releases/download/v.0.0.1/Company-Deep-Research.zip)
|
|
24
26
|
2. Unzip it and Run ./start.sh on Mac OS, and double click start.bat on Windows (see below), the server starts and opens http://127.0.0.1:26313 in your browser
|
|
25
27
|
|
|
26
28
|
```bash
|
|
@@ -108,6 +110,7 @@ The start scripts use `npx @cremini/skillpack run .` so Node.js is the only prer
|
|
|
108
110
|
**Telegram configuration**: requires `Bot Token`
|
|
109
111
|
|
|
110
112
|
### Slack App Setup and how to get `App Token` and `Bot Token`
|
|
113
|
+
https://skillpack.gitbook.io/skillpack-docs/getting-started/slack-integration
|
|
111
114
|
|
|
112
115
|
1. Create a new Slack app at https://api.slack.com/apps
|
|
113
116
|
2. Enable Socket Mode (Settings → Socket Mode → Enable)
|
|
@@ -144,6 +147,7 @@ The start scripts use `npx @cremini/skillpack run .` so Node.js is the only prer
|
|
|
144
147
|
9. On the SkillPack buit-in UI http://127.0.0.1:26313, Tap "Connect to Chat App" button and Enter the **`Bot Token`** and **`App Token`**, Save
|
|
145
148
|
|
|
146
149
|
### Telegram Setup and how to get `Bot Token`
|
|
150
|
+
https://skillpack.gitbook.io/skillpack-docs/getting-started/telegram-integration
|
|
147
151
|
|
|
148
152
|
1. **Open Telegram** and search for the official account **`@BotFather`** (it will have a blue verified checkmark).
|
|
149
153
|
2. **Start a chat** by tapping "Start" or sending the `/start` command.
|
package/dist/cli.js
CHANGED
|
@@ -114,7 +114,7 @@ var init_config = __esm({
|
|
|
114
114
|
console.warn(" Warning: Failed to parse data/config.json:", err);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
let { apiKey = "", provider = "openai" } = this.configData;
|
|
117
|
+
let { apiKey = "", provider = "openai", baseUrl = "" } = this.configData;
|
|
118
118
|
if (!apiKey) {
|
|
119
119
|
if (process.env.OPENAI_API_KEY) {
|
|
120
120
|
apiKey = process.env.OPENAI_API_KEY;
|
|
@@ -126,6 +126,7 @@ var init_config = __esm({
|
|
|
126
126
|
}
|
|
127
127
|
this.configData.apiKey = apiKey;
|
|
128
128
|
this.configData.provider = provider;
|
|
129
|
+
this.configData.baseUrl = baseUrl?.trim() || void 0;
|
|
129
130
|
return this.configData;
|
|
130
131
|
}
|
|
131
132
|
getConfig() {
|
|
@@ -141,6 +142,9 @@ var init_config = __esm({
|
|
|
141
142
|
}
|
|
142
143
|
if (updates.apiKey !== void 0) this.configData.apiKey = updates.apiKey;
|
|
143
144
|
if (updates.provider !== void 0) this.configData.provider = updates.provider;
|
|
145
|
+
if (updates.baseUrl !== void 0) {
|
|
146
|
+
this.configData.baseUrl = updates.baseUrl?.trim() || void 0;
|
|
147
|
+
}
|
|
144
148
|
if (updates.adapters !== void 0) {
|
|
145
149
|
const merged = { ...this.configData.adapters || {} };
|
|
146
150
|
for (const [adapterKey, adapterVal] of Object.entries(updates.adapters)) {
|
|
@@ -397,6 +401,7 @@ var init_telegram = __esm({
|
|
|
397
401
|
try {
|
|
398
402
|
const userText = text || "(User sent an attachment)";
|
|
399
403
|
const result = await this.agent.handleMessage(
|
|
404
|
+
"telegram",
|
|
400
405
|
channelId,
|
|
401
406
|
userText,
|
|
402
407
|
onEvent,
|
|
@@ -830,6 +835,7 @@ var init_slack = __esm({
|
|
|
830
835
|
};
|
|
831
836
|
try {
|
|
832
837
|
const result = await this.agent.handleMessage(
|
|
838
|
+
"slack",
|
|
833
839
|
channelId,
|
|
834
840
|
text,
|
|
835
841
|
onEvent,
|
|
@@ -1274,6 +1280,7 @@ var init_scheduler = __esm({
|
|
|
1274
1280
|
};
|
|
1275
1281
|
try {
|
|
1276
1282
|
const result = await this.agent.handleMessage(
|
|
1283
|
+
"scheduler",
|
|
1277
1284
|
channelId,
|
|
1278
1285
|
jobConfig.prompt,
|
|
1279
1286
|
onEvent
|
|
@@ -2045,7 +2052,7 @@ import chalk4 from "chalk";
|
|
|
2045
2052
|
import express from "express";
|
|
2046
2053
|
import path11 from "path";
|
|
2047
2054
|
import fs12 from "fs";
|
|
2048
|
-
import { fileURLToPath } from "url";
|
|
2055
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2049
2056
|
import { createServer } from "http";
|
|
2050
2057
|
import { exec } from "child_process";
|
|
2051
2058
|
|
|
@@ -2053,6 +2060,7 @@ import { exec } from "child_process";
|
|
|
2053
2060
|
init_attachment_utils();
|
|
2054
2061
|
import path7 from "path";
|
|
2055
2062
|
import fs7 from "fs";
|
|
2063
|
+
import { fileURLToPath } from "url";
|
|
2056
2064
|
import {
|
|
2057
2065
|
AuthStorage,
|
|
2058
2066
|
createAgentSession,
|
|
@@ -4785,16 +4793,6 @@ var ManageScheduleParams = Type.Object({
|
|
|
4785
4793
|
description: "The work prompt to execute when the task triggers. Required for add. Describe only what to do each run; do not repeat timing, cron, or 'every N minutes' instructions here."
|
|
4786
4794
|
})
|
|
4787
4795
|
),
|
|
4788
|
-
notifyAdapter: Type.Optional(
|
|
4789
|
-
Type.String({
|
|
4790
|
-
description: "Target adapter name for result notification: 'telegram' or 'slack'. Required for add."
|
|
4791
|
-
})
|
|
4792
|
-
),
|
|
4793
|
-
notifyChannelId: Type.Optional(
|
|
4794
|
-
Type.String({
|
|
4795
|
-
description: "Target channelId for result notification (e.g. 'telegram-123456'). Required for add."
|
|
4796
|
-
})
|
|
4797
|
-
),
|
|
4798
4796
|
timezone: Type.Optional(
|
|
4799
4797
|
Type.String({
|
|
4800
4798
|
description: "Optional timezone for the cron schedule, e.g. 'Asia/Shanghai', 'America/New_York'."
|
|
@@ -4804,7 +4802,7 @@ var ManageScheduleParams = Type.Object({
|
|
|
4804
4802
|
function textResult(text) {
|
|
4805
4803
|
return { content: [{ type: "text", text }], details: void 0 };
|
|
4806
4804
|
}
|
|
4807
|
-
function createManageScheduleTool(schedulerRef,
|
|
4805
|
+
function createManageScheduleTool(schedulerRef, adapter, channelId) {
|
|
4808
4806
|
return {
|
|
4809
4807
|
name: "manage_scheduled_task",
|
|
4810
4808
|
label: "Manage Scheduled Task",
|
|
@@ -4812,7 +4810,7 @@ function createManageScheduleTool(schedulerRef, _rootDirRef) {
|
|
|
4812
4810
|
"Manage scheduled tasks (cron jobs) that automatically execute prompts and push results to IM channels.",
|
|
4813
4811
|
"",
|
|
4814
4812
|
"Actions:",
|
|
4815
|
-
"- add: Create a new scheduled task. Requires: name, cron, prompt
|
|
4813
|
+
"- add: Create a new scheduled task. Requires: name, cron, prompt. The notification target always uses the current Telegram or Slack chat. The prompt must describe only the work for each run, not the schedule itself.",
|
|
4816
4814
|
"- list: List all scheduled tasks with their status.",
|
|
4817
4815
|
"- remove: Remove a scheduled task by name.",
|
|
4818
4816
|
"- trigger: Manually trigger a scheduled task by name (runs immediately).",
|
|
@@ -4823,10 +4821,7 @@ function createManageScheduleTool(schedulerRef, _rootDirRef) {
|
|
|
4823
4821
|
"Examples:",
|
|
4824
4822
|
" '0 9 * * 1-5' = every weekday at 9:00 AM",
|
|
4825
4823
|
" '0 18 * * 5' = every Friday at 6:00 PM",
|
|
4826
|
-
" '*/30 * * * *' = every 30 minutes"
|
|
4827
|
-
"",
|
|
4828
|
-
"notifyAdapter: 'telegram' or 'slack'",
|
|
4829
|
-
"notifyChannelId: the channel ID where result will be sent (e.g. 'telegram-123456')"
|
|
4824
|
+
" '*/30 * * * *' = every 30 minutes"
|
|
4830
4825
|
].join("\n"),
|
|
4831
4826
|
parameters: ManageScheduleParams,
|
|
4832
4827
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
@@ -4856,9 +4851,9 @@ ${lines.join("\n")}`
|
|
|
4856
4851
|
"Error: 'name', 'cron', and 'prompt' are required for adding a task."
|
|
4857
4852
|
);
|
|
4858
4853
|
}
|
|
4859
|
-
if (
|
|
4854
|
+
if (adapter !== "telegram" && adapter !== "slack") {
|
|
4860
4855
|
return textResult(
|
|
4861
|
-
"Error:
|
|
4856
|
+
"Error: Scheduled tasks can only be created from a Telegram or Slack."
|
|
4862
4857
|
);
|
|
4863
4858
|
}
|
|
4864
4859
|
const jobConfig = {
|
|
@@ -4866,8 +4861,8 @@ ${lines.join("\n")}`
|
|
|
4866
4861
|
cron: params.cron,
|
|
4867
4862
|
prompt: params.prompt,
|
|
4868
4863
|
notify: {
|
|
4869
|
-
adapter
|
|
4870
|
-
channelId
|
|
4864
|
+
adapter,
|
|
4865
|
+
channelId
|
|
4871
4866
|
},
|
|
4872
4867
|
enabled: true,
|
|
4873
4868
|
timezone: params.timezone
|
|
@@ -4924,6 +4919,75 @@ ${lines.join("\n")}`
|
|
|
4924
4919
|
var DEBUG = true;
|
|
4925
4920
|
var log = (...args) => DEBUG && console.log(...args);
|
|
4926
4921
|
var write = (data) => DEBUG && process.stdout.write(data);
|
|
4922
|
+
var BUILTIN_SKILL_CREATOR_NAME = "skill-creator";
|
|
4923
|
+
var BUILTIN_SKILL_CREATOR_DESCRIPTION = "Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.";
|
|
4924
|
+
var BUILTIN_SKILL_CREATOR_TEMPLATE_DIR = fileURLToPath(
|
|
4925
|
+
new URL("../templates/builtin-skills/skill-creator", import.meta.url)
|
|
4926
|
+
);
|
|
4927
|
+
function materializeBuiltinSkillCreator(rootDir, skillsPath) {
|
|
4928
|
+
if (!fs7.existsSync(BUILTIN_SKILL_CREATOR_TEMPLATE_DIR)) {
|
|
4929
|
+
log(
|
|
4930
|
+
`[PackAgent] Built-in skill-creator template missing: ${BUILTIN_SKILL_CREATOR_TEMPLATE_DIR}`
|
|
4931
|
+
);
|
|
4932
|
+
return null;
|
|
4933
|
+
}
|
|
4934
|
+
const packConfigPath = path7.resolve(rootDir, "skillpack.json");
|
|
4935
|
+
const skillDir = path7.resolve(skillsPath, BUILTIN_SKILL_CREATOR_NAME);
|
|
4936
|
+
const skillPath = path7.join(skillDir, "SKILL.md");
|
|
4937
|
+
const renderTemplate = (content) => content.replaceAll("{{SKILLS_PATH}}", skillsPath).replaceAll("{{PACK_CONFIG_PATH}}", packConfigPath);
|
|
4938
|
+
const copyDir = (srcDir, destDir) => {
|
|
4939
|
+
fs7.mkdirSync(destDir, { recursive: true });
|
|
4940
|
+
for (const entry of fs7.readdirSync(srcDir, { withFileTypes: true })) {
|
|
4941
|
+
if (entry.name === ".DS_Store") {
|
|
4942
|
+
continue;
|
|
4943
|
+
}
|
|
4944
|
+
const srcPath = path7.join(srcDir, entry.name);
|
|
4945
|
+
const destPath = path7.join(destDir, entry.name);
|
|
4946
|
+
if (entry.isDirectory()) {
|
|
4947
|
+
copyDir(srcPath, destPath);
|
|
4948
|
+
continue;
|
|
4949
|
+
}
|
|
4950
|
+
if (!entry.isFile()) {
|
|
4951
|
+
continue;
|
|
4952
|
+
}
|
|
4953
|
+
if (entry.name.endsWith(".md") || entry.name.endsWith(".py")) {
|
|
4954
|
+
const content = fs7.readFileSync(srcPath, "utf-8");
|
|
4955
|
+
fs7.writeFileSync(destPath, renderTemplate(content), "utf-8");
|
|
4956
|
+
continue;
|
|
4957
|
+
}
|
|
4958
|
+
fs7.copyFileSync(srcPath, destPath);
|
|
4959
|
+
}
|
|
4960
|
+
};
|
|
4961
|
+
if (!fs7.existsSync(skillDir)) {
|
|
4962
|
+
copyDir(BUILTIN_SKILL_CREATOR_TEMPLATE_DIR, skillDir);
|
|
4963
|
+
}
|
|
4964
|
+
if (!fs7.existsSync(skillPath)) {
|
|
4965
|
+
log(
|
|
4966
|
+
`[PackAgent] Materialized built-in skill-creator but SKILL.md is missing: ${skillPath}`
|
|
4967
|
+
);
|
|
4968
|
+
return null;
|
|
4969
|
+
}
|
|
4970
|
+
return {
|
|
4971
|
+
name: BUILTIN_SKILL_CREATOR_NAME,
|
|
4972
|
+
description: BUILTIN_SKILL_CREATOR_DESCRIPTION,
|
|
4973
|
+
filePath: skillPath,
|
|
4974
|
+
baseDir: skillDir,
|
|
4975
|
+
source: "path",
|
|
4976
|
+
disableModelInvocation: false
|
|
4977
|
+
};
|
|
4978
|
+
}
|
|
4979
|
+
function overrideBuiltinSkillCreator(base, materializedSkill) {
|
|
4980
|
+
if (!materializedSkill) {
|
|
4981
|
+
return base;
|
|
4982
|
+
}
|
|
4983
|
+
const filtered = base.skills.filter(
|
|
4984
|
+
(skill) => skill.name !== BUILTIN_SKILL_CREATOR_NAME
|
|
4985
|
+
);
|
|
4986
|
+
return {
|
|
4987
|
+
skills: [materializedSkill, ...filtered],
|
|
4988
|
+
diagnostics: base.diagnostics
|
|
4989
|
+
};
|
|
4990
|
+
}
|
|
4927
4991
|
function getAssistantDiagnostics(message) {
|
|
4928
4992
|
if (!message || message.role !== "assistant") {
|
|
4929
4993
|
return null;
|
|
@@ -4949,17 +5013,9 @@ var PackAgent = class {
|
|
|
4949
5013
|
fileOutputCallbackRef = {
|
|
4950
5014
|
current: null
|
|
4951
5015
|
};
|
|
4952
|
-
sendFileToolDef = createSendFileTool(this.fileOutputCallbackRef);
|
|
4953
5016
|
schedulerRef = { current: null };
|
|
4954
|
-
rootDirRef;
|
|
4955
|
-
scheduleToolDef;
|
|
4956
5017
|
constructor(options) {
|
|
4957
5018
|
this.options = options;
|
|
4958
|
-
this.rootDirRef = { current: options.rootDir };
|
|
4959
|
-
this.scheduleToolDef = createManageScheduleTool(
|
|
4960
|
-
this.schedulerRef,
|
|
4961
|
-
this.rootDirRef
|
|
4962
|
-
);
|
|
4963
5019
|
}
|
|
4964
5020
|
/**
|
|
4965
5021
|
* Inject scheduler reference (called by server.ts after adapter init).
|
|
@@ -4967,22 +5023,33 @@ var PackAgent = class {
|
|
|
4967
5023
|
setScheduler(scheduler) {
|
|
4968
5024
|
this.schedulerRef.current = scheduler;
|
|
4969
5025
|
}
|
|
5026
|
+
createCustomTools(adapter, channelId) {
|
|
5027
|
+
const tools = [createSendFileTool(this.fileOutputCallbackRef)];
|
|
5028
|
+
if (adapter === "telegram" || adapter === "slack") {
|
|
5029
|
+
tools.push(createManageScheduleTool(this.schedulerRef, adapter, channelId));
|
|
5030
|
+
}
|
|
5031
|
+
return tools;
|
|
5032
|
+
}
|
|
4970
5033
|
/**
|
|
4971
5034
|
* Lazily create (or return existing) session for a channel.
|
|
4972
5035
|
*/
|
|
4973
|
-
async getOrCreateSession(channelId) {
|
|
5036
|
+
async getOrCreateSession(adapter, channelId) {
|
|
4974
5037
|
const existing = this.channels.get(channelId);
|
|
4975
5038
|
if (existing) return existing;
|
|
4976
5039
|
const pendingCreation = this.pendingSessionCreations.get(channelId);
|
|
4977
5040
|
if (pendingCreation) return pendingCreation;
|
|
4978
5041
|
const createSessionPromise = (async () => {
|
|
4979
|
-
const { apiKey, rootDir, provider, modelId } = this.options;
|
|
5042
|
+
const { apiKey, rootDir, provider, modelId, baseUrl } = this.options;
|
|
4980
5043
|
const authStorage = AuthStorage.inMemory({
|
|
4981
5044
|
[provider]: { type: "api_key", key: apiKey }
|
|
4982
5045
|
});
|
|
4983
5046
|
authStorage.setRuntimeApiKey(provider, apiKey);
|
|
4984
5047
|
const modelRegistry = new ModelRegistry(authStorage);
|
|
4985
|
-
const
|
|
5048
|
+
const resolvedModel = modelRegistry.find(provider, modelId);
|
|
5049
|
+
const model = resolvedModel && baseUrl ? { ...resolvedModel, baseUrl } : resolvedModel;
|
|
5050
|
+
if (resolvedModel && baseUrl) {
|
|
5051
|
+
log(`[PackAgent] Overriding ${provider}/${modelId} baseUrl -> ${baseUrl}`);
|
|
5052
|
+
}
|
|
4986
5053
|
const sessionDir = path7.resolve(
|
|
4987
5054
|
rootDir,
|
|
4988
5055
|
"data",
|
|
@@ -5002,12 +5069,23 @@ var PackAgent = class {
|
|
|
5002
5069
|
log(`[PackAgent] Workspace dir: ${workspaceDir}`);
|
|
5003
5070
|
const skillsPath = path7.resolve(rootDir, "skills");
|
|
5004
5071
|
log(`[PackAgent] Loading skills from: ${skillsPath}`);
|
|
5072
|
+
const materializedSkillCreator = materializeBuiltinSkillCreator(
|
|
5073
|
+
rootDir,
|
|
5074
|
+
skillsPath
|
|
5075
|
+
);
|
|
5076
|
+
if (materializedSkillCreator) {
|
|
5077
|
+
log(
|
|
5078
|
+
`[PackAgent] Materialized built-in skill-creator to: ${materializedSkillCreator.filePath}`
|
|
5079
|
+
);
|
|
5080
|
+
}
|
|
5005
5081
|
const resourceLoader = new DefaultResourceLoader({
|
|
5006
5082
|
cwd: rootDir,
|
|
5007
|
-
additionalSkillPaths: [skillsPath]
|
|
5083
|
+
additionalSkillPaths: [skillsPath],
|
|
5084
|
+
skillsOverride: (base) => overrideBuiltinSkillCreator(base, materializedSkillCreator)
|
|
5008
5085
|
});
|
|
5009
5086
|
await resourceLoader.reload();
|
|
5010
5087
|
const tools = createCodingTools(workspaceDir);
|
|
5088
|
+
const customTools = this.createCustomTools(adapter, channelId);
|
|
5011
5089
|
const { session } = await createAgentSession({
|
|
5012
5090
|
cwd: workspaceDir,
|
|
5013
5091
|
authStorage,
|
|
@@ -5016,7 +5094,7 @@ var PackAgent = class {
|
|
|
5016
5094
|
resourceLoader,
|
|
5017
5095
|
model,
|
|
5018
5096
|
tools,
|
|
5019
|
-
customTools
|
|
5097
|
+
customTools
|
|
5020
5098
|
});
|
|
5021
5099
|
const channelSession = {
|
|
5022
5100
|
session,
|
|
@@ -5033,8 +5111,8 @@ var PackAgent = class {
|
|
|
5033
5111
|
this.pendingSessionCreations.delete(channelId);
|
|
5034
5112
|
}
|
|
5035
5113
|
}
|
|
5036
|
-
async handleMessage(channelId, text, onEvent, attachments) {
|
|
5037
|
-
const cs = await this.getOrCreateSession(channelId);
|
|
5114
|
+
async handleMessage(adapter, channelId, text, onEvent, attachments) {
|
|
5115
|
+
const cs = await this.getOrCreateSession(adapter, channelId);
|
|
5038
5116
|
const run = async () => {
|
|
5039
5117
|
cs.running = true;
|
|
5040
5118
|
let turnHadVisibleOutput = false;
|
|
@@ -5243,6 +5321,7 @@ function getRuntimeConfigSignature(config) {
|
|
|
5243
5321
|
return JSON.stringify({
|
|
5244
5322
|
apiKey: config.apiKey || "",
|
|
5245
5323
|
provider: config.provider || "openai",
|
|
5324
|
+
baseUrl: config.baseUrl || "",
|
|
5246
5325
|
telegramToken: config.adapters?.telegram?.token || "",
|
|
5247
5326
|
slackBotToken: config.adapters?.slack?.botToken || "",
|
|
5248
5327
|
slackAppToken: config.adapters?.slack?.appToken || ""
|
|
@@ -5269,6 +5348,7 @@ var WebAdapter = class {
|
|
|
5269
5348
|
hasApiKey: !!conf.apiKey,
|
|
5270
5349
|
apiKey: conf.apiKey || "",
|
|
5271
5350
|
provider: conf.provider || "openai",
|
|
5351
|
+
baseUrl: conf.baseUrl || "",
|
|
5272
5352
|
adapters: conf.adapters || {},
|
|
5273
5353
|
runtimeControl: lifecycle.getRuntimeControl()
|
|
5274
5354
|
});
|
|
@@ -5278,7 +5358,7 @@ var WebAdapter = class {
|
|
|
5278
5358
|
res.json(config.skills || []);
|
|
5279
5359
|
});
|
|
5280
5360
|
app.post("/api/config/update", (req, res) => {
|
|
5281
|
-
const { key, provider, adapters } = req.body;
|
|
5361
|
+
const { key, provider, baseUrl, adapters } = req.body;
|
|
5282
5362
|
const updates = {};
|
|
5283
5363
|
const beforeConfig = JSON.parse(JSON.stringify(configManager.getConfig()));
|
|
5284
5364
|
if (key !== void 0) {
|
|
@@ -5289,6 +5369,9 @@ var WebAdapter = class {
|
|
|
5289
5369
|
updates.provider = provider;
|
|
5290
5370
|
currentProvider = provider;
|
|
5291
5371
|
}
|
|
5372
|
+
if (baseUrl !== void 0) {
|
|
5373
|
+
updates.baseUrl = baseUrl;
|
|
5374
|
+
}
|
|
5292
5375
|
if (adapters !== void 0) {
|
|
5293
5376
|
updates.adapters = adapters;
|
|
5294
5377
|
}
|
|
@@ -5298,6 +5381,7 @@ var WebAdapter = class {
|
|
|
5298
5381
|
res.json({
|
|
5299
5382
|
success: true,
|
|
5300
5383
|
provider: newConf.provider,
|
|
5384
|
+
baseUrl: newConf.baseUrl || "",
|
|
5301
5385
|
adapters: newConf.adapters,
|
|
5302
5386
|
requiresRestart,
|
|
5303
5387
|
runtimeControl: lifecycle.getRuntimeControl()
|
|
@@ -5483,7 +5567,7 @@ var WebAdapter = class {
|
|
|
5483
5567
|
if (ws.readyState !== ws.OPEN) return;
|
|
5484
5568
|
ws.send(JSON.stringify(event));
|
|
5485
5569
|
};
|
|
5486
|
-
const result = await agent.handleMessage(channelId, text, onEvent);
|
|
5570
|
+
const result = await agent.handleMessage("web", channelId, text, onEvent);
|
|
5487
5571
|
if (result.errorMessage) {
|
|
5488
5572
|
ws.send(JSON.stringify({ error: result.errorMessage }));
|
|
5489
5573
|
return;
|
|
@@ -5585,7 +5669,7 @@ var Lifecycle = class {
|
|
|
5585
5669
|
};
|
|
5586
5670
|
|
|
5587
5671
|
// src/runtime/server.ts
|
|
5588
|
-
var __dirname = path11.dirname(
|
|
5672
|
+
var __dirname = path11.dirname(fileURLToPath2(import.meta.url));
|
|
5589
5673
|
async function startServer(options) {
|
|
5590
5674
|
const {
|
|
5591
5675
|
rootDir,
|
|
@@ -5596,6 +5680,7 @@ async function startServer(options) {
|
|
|
5596
5680
|
const dataConfig = configManager.load(rootDir);
|
|
5597
5681
|
const apiKey = dataConfig.apiKey || "";
|
|
5598
5682
|
const provider = dataConfig.provider || "openai";
|
|
5683
|
+
const baseUrl = dataConfig.baseUrl?.trim() || void 0;
|
|
5599
5684
|
const modelId = provider === "anthropic" ? "claude-opus-4-6" : "gpt-5.4";
|
|
5600
5685
|
const packageRoot = path11.resolve(__dirname, "..");
|
|
5601
5686
|
const webDir = fs12.existsSync(path11.join(rootDir, "web")) ? path11.join(rootDir, "web") : path11.join(packageRoot, "web");
|
|
@@ -5609,6 +5694,7 @@ async function startServer(options) {
|
|
|
5609
5694
|
rootDir,
|
|
5610
5695
|
provider,
|
|
5611
5696
|
modelId,
|
|
5697
|
+
baseUrl,
|
|
5612
5698
|
lifecycleHandler: lifecycle
|
|
5613
5699
|
});
|
|
5614
5700
|
const adapters = [];
|
package/package.json
CHANGED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|