@wingman-ai/gateway 0.1.1 → 0.1.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/dist/agent/tests/uiRegistryTools.test.cjs +25 -1
- package/dist/agent/tests/uiRegistryTools.test.js +25 -1
- package/dist/cli/config/loader.cjs +14 -3
- package/dist/cli/config/loader.d.ts +1 -0
- package/dist/cli/config/loader.js +14 -3
- package/dist/cli/config/warnings.cjs +104 -0
- package/dist/cli/config/warnings.d.ts +6 -0
- package/dist/cli/config/warnings.js +70 -0
- package/dist/cli/core/agentInvoker.cjs +1 -3
- package/dist/cli/core/agentInvoker.js +1 -3
- package/dist/gateway/index.cjs +2 -2
- package/dist/tests/cli-config-warnings.test.cjs +53 -0
- package/dist/tests/cli-config-warnings.test.d.ts +1 -0
- package/dist/tests/cli-config-warnings.test.js +47 -0
- package/dist/types/agents.d.ts +13 -2
- package/dist/webui/assets/index-CZt-NLM_.js +178 -0
- package/dist/webui/assets/index-DTK8ignm.css +1 -0
- package/dist/webui/index.html +2 -2
- package/package.json +4 -3
- package/skills/ui-registry/SKILL.md +7 -1
- package/skills/ui-registry/examples/area_chart.md +45 -0
- package/skills/ui-registry/examples/bar_chart.md +27 -0
- package/skills/ui-registry/examples/data_table.md +32 -0
- package/skills/ui-registry/examples/line_chart.md +44 -0
- package/skills/ui-registry/examples/status_list.md +26 -0
- package/skills/ui-registry/examples/timeline.md +41 -0
- package/skills/ui-registry/registry.json +238 -0
- package/.wingman/agents/lm-studio/agent.md +0 -8
- package/dist/webui/assets/index-DFyOC2sB.js +0 -112
- package/dist/webui/assets/index-RjFyKzVw.css +0 -1
|
@@ -21,7 +21,14 @@ const skillsDir = "skills";
|
|
|
21
21
|
(0, external_vitest_namespaceObject.it)("lists registry components", async ()=>{
|
|
22
22
|
const tool = (0, ui_registry_cjs_namespaceObject.createUiRegistryListTool)(workspace, skillsDir);
|
|
23
23
|
const result = await tool.invoke({});
|
|
24
|
-
|
|
24
|
+
const ids = result.components.map((component)=>component.id);
|
|
25
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("stat_grid")).toBe(true);
|
|
26
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("line_chart")).toBe(true);
|
|
27
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("area_chart")).toBe(true);
|
|
28
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("bar_chart")).toBe(true);
|
|
29
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("data_table")).toBe(true);
|
|
30
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("timeline")).toBe(true);
|
|
31
|
+
(0, external_vitest_namespaceObject.expect)(ids.includes("status_list")).toBe(true);
|
|
25
32
|
});
|
|
26
33
|
(0, external_vitest_namespaceObject.it)("returns schema details for a registry component", async ()=>{
|
|
27
34
|
const tool = (0, ui_registry_cjs_namespaceObject.createUiRegistryGetTool)(workspace, skillsDir);
|
|
@@ -31,6 +38,23 @@ const skillsDir = "skills";
|
|
|
31
38
|
(0, external_vitest_namespaceObject.expect)(result.componentId).toBe("stat_grid");
|
|
32
39
|
(0, external_vitest_namespaceObject.expect)(result.propsSchema).toBeTruthy();
|
|
33
40
|
});
|
|
41
|
+
(0, external_vitest_namespaceObject.it)("returns schema details for new registry components", async ()=>{
|
|
42
|
+
const tool = (0, ui_registry_cjs_namespaceObject.createUiRegistryGetTool)(workspace, skillsDir);
|
|
43
|
+
for (const componentId of [
|
|
44
|
+
"line_chart",
|
|
45
|
+
"area_chart",
|
|
46
|
+
"bar_chart",
|
|
47
|
+
"data_table",
|
|
48
|
+
"timeline",
|
|
49
|
+
"status_list"
|
|
50
|
+
]){
|
|
51
|
+
const result = await tool.invoke({
|
|
52
|
+
componentId
|
|
53
|
+
});
|
|
54
|
+
(0, external_vitest_namespaceObject.expect)(result.componentId).toBe(componentId);
|
|
55
|
+
(0, external_vitest_namespaceObject.expect)(result.propsSchema).toBeTruthy();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
34
58
|
(0, external_vitest_namespaceObject.it)("renders UI payload when enabled", async ()=>{
|
|
35
59
|
const tool = (0, ui_registry_cjs_namespaceObject.createUiPresentTool)(workspace, skillsDir, true);
|
|
36
60
|
const result = await tool.invoke({
|
|
@@ -16,7 +16,14 @@ describe("UI Registry Tools", ()=>{
|
|
|
16
16
|
it("lists registry components", async ()=>{
|
|
17
17
|
const tool = createUiRegistryListTool(workspace, skillsDir);
|
|
18
18
|
const result = await tool.invoke({});
|
|
19
|
-
|
|
19
|
+
const ids = result.components.map((component)=>component.id);
|
|
20
|
+
expect(ids.includes("stat_grid")).toBe(true);
|
|
21
|
+
expect(ids.includes("line_chart")).toBe(true);
|
|
22
|
+
expect(ids.includes("area_chart")).toBe(true);
|
|
23
|
+
expect(ids.includes("bar_chart")).toBe(true);
|
|
24
|
+
expect(ids.includes("data_table")).toBe(true);
|
|
25
|
+
expect(ids.includes("timeline")).toBe(true);
|
|
26
|
+
expect(ids.includes("status_list")).toBe(true);
|
|
20
27
|
});
|
|
21
28
|
it("returns schema details for a registry component", async ()=>{
|
|
22
29
|
const tool = createUiRegistryGetTool(workspace, skillsDir);
|
|
@@ -26,6 +33,23 @@ describe("UI Registry Tools", ()=>{
|
|
|
26
33
|
expect(result.componentId).toBe("stat_grid");
|
|
27
34
|
expect(result.propsSchema).toBeTruthy();
|
|
28
35
|
});
|
|
36
|
+
it("returns schema details for new registry components", async ()=>{
|
|
37
|
+
const tool = createUiRegistryGetTool(workspace, skillsDir);
|
|
38
|
+
for (const componentId of [
|
|
39
|
+
"line_chart",
|
|
40
|
+
"area_chart",
|
|
41
|
+
"bar_chart",
|
|
42
|
+
"data_table",
|
|
43
|
+
"timeline",
|
|
44
|
+
"status_list"
|
|
45
|
+
]){
|
|
46
|
+
const result = await tool.invoke({
|
|
47
|
+
componentId
|
|
48
|
+
});
|
|
49
|
+
expect(result.componentId).toBe(componentId);
|
|
50
|
+
expect(result.propsSchema).toBeTruthy();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
29
53
|
it("renders UI payload when enabled", async ()=>{
|
|
30
54
|
const tool = createUiPresentTool(workspace, skillsDir, true);
|
|
31
55
|
const result = await tool.invoke({
|
|
@@ -29,6 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
30
30
|
const external_node_path_namespaceObject = require("node:path");
|
|
31
31
|
const external_schema_cjs_namespaceObject = require("./schema.cjs");
|
|
32
|
+
const external_warnings_cjs_namespaceObject = require("./warnings.cjs");
|
|
32
33
|
const env_cjs_namespaceObject = require("../../gateway/env.cjs");
|
|
33
34
|
const external_logger_cjs_namespaceObject = require("../../logger.cjs");
|
|
34
35
|
function _define_property(obj, key, value) {
|
|
@@ -46,7 +47,9 @@ class WingmanConfigLoader {
|
|
|
46
47
|
const configPath = (0, external_node_path_namespaceObject.join)(this.workspace, this.configDir, "wingman.config.json");
|
|
47
48
|
if (!(0, external_node_fs_namespaceObject.existsSync)(configPath)) {
|
|
48
49
|
this.logger.info(`Config file not found at ${configPath}, using default configuration`);
|
|
49
|
-
|
|
50
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(this.getDefaultConfig());
|
|
51
|
+
this.logConfigWarnings(finalConfig);
|
|
52
|
+
return finalConfig;
|
|
50
53
|
}
|
|
51
54
|
try {
|
|
52
55
|
const content = (0, external_node_fs_namespaceObject.readFileSync)(configPath, "utf-8");
|
|
@@ -58,12 +61,16 @@ class WingmanConfigLoader {
|
|
|
58
61
|
return this.getDefaultConfig();
|
|
59
62
|
}
|
|
60
63
|
this.logger.debug(`Loaded configuration from ${configPath} with values: ${JSON.stringify(validation.data)}`);
|
|
61
|
-
|
|
64
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(validation.data);
|
|
65
|
+
this.logConfigWarnings(finalConfig);
|
|
66
|
+
return finalConfig;
|
|
62
67
|
} catch (error) {
|
|
63
68
|
if (error instanceof SyntaxError) this.logger.error(`Warning: Invalid JSON in ${configPath}: ${error.message}`);
|
|
64
69
|
else this.logger.error(`Warning: Failed to load config: ${error}`);
|
|
65
70
|
this.logger.error("Using default configuration");
|
|
66
|
-
|
|
71
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(this.getDefaultConfig());
|
|
72
|
+
this.logConfigWarnings(finalConfig);
|
|
73
|
+
return finalConfig;
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
applyGatewayAuthEnvOverrides(config) {
|
|
@@ -126,6 +133,10 @@ class WingmanConfigLoader {
|
|
|
126
133
|
}
|
|
127
134
|
};
|
|
128
135
|
}
|
|
136
|
+
logConfigWarnings(config) {
|
|
137
|
+
const warnings = (0, external_warnings_cjs_namespaceObject.collectConfigWarnings)(config);
|
|
138
|
+
for (const warning of warnings)this.logger.warn(`Config warning: ${warning.message}`);
|
|
139
|
+
}
|
|
129
140
|
constructor(configDir = ".wingman", workspace = process.cwd()){
|
|
130
141
|
_define_property(this, "configDir", void 0);
|
|
131
142
|
_define_property(this, "workspace", void 0);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { validateConfig } from "./schema.js";
|
|
4
|
+
import { collectConfigWarnings } from "./warnings.js";
|
|
4
5
|
import { getGatewayTokenFromEnv } from "../../gateway/env.js";
|
|
5
6
|
import { createLogger } from "../../logger.js";
|
|
6
7
|
function _define_property(obj, key, value) {
|
|
@@ -18,7 +19,9 @@ class WingmanConfigLoader {
|
|
|
18
19
|
const configPath = join(this.workspace, this.configDir, "wingman.config.json");
|
|
19
20
|
if (!existsSync(configPath)) {
|
|
20
21
|
this.logger.info(`Config file not found at ${configPath}, using default configuration`);
|
|
21
|
-
|
|
22
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(this.getDefaultConfig());
|
|
23
|
+
this.logConfigWarnings(finalConfig);
|
|
24
|
+
return finalConfig;
|
|
22
25
|
}
|
|
23
26
|
try {
|
|
24
27
|
const content = readFileSync(configPath, "utf-8");
|
|
@@ -30,12 +33,16 @@ class WingmanConfigLoader {
|
|
|
30
33
|
return this.getDefaultConfig();
|
|
31
34
|
}
|
|
32
35
|
this.logger.debug(`Loaded configuration from ${configPath} with values: ${JSON.stringify(validation.data)}`);
|
|
33
|
-
|
|
36
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(validation.data);
|
|
37
|
+
this.logConfigWarnings(finalConfig);
|
|
38
|
+
return finalConfig;
|
|
34
39
|
} catch (error) {
|
|
35
40
|
if (error instanceof SyntaxError) this.logger.error(`Warning: Invalid JSON in ${configPath}: ${error.message}`);
|
|
36
41
|
else this.logger.error(`Warning: Failed to load config: ${error}`);
|
|
37
42
|
this.logger.error("Using default configuration");
|
|
38
|
-
|
|
43
|
+
const finalConfig = this.applyGatewayAuthEnvOverrides(this.getDefaultConfig());
|
|
44
|
+
this.logConfigWarnings(finalConfig);
|
|
45
|
+
return finalConfig;
|
|
39
46
|
}
|
|
40
47
|
}
|
|
41
48
|
applyGatewayAuthEnvOverrides(config) {
|
|
@@ -98,6 +105,10 @@ class WingmanConfigLoader {
|
|
|
98
105
|
}
|
|
99
106
|
};
|
|
100
107
|
}
|
|
108
|
+
logConfigWarnings(config) {
|
|
109
|
+
const warnings = collectConfigWarnings(config);
|
|
110
|
+
for (const warning of warnings)this.logger.warn(`Config warning: ${warning.message}`);
|
|
111
|
+
}
|
|
101
112
|
constructor(configDir = ".wingman", workspace = process.cwd()){
|
|
102
113
|
_define_property(this, "configDir", void 0);
|
|
103
114
|
_define_property(this, "workspace", void 0);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
collectConfigWarnings: ()=>collectConfigWarnings
|
|
28
|
+
});
|
|
29
|
+
const AGENT_PREFIX = /^agent:[^:]+:/;
|
|
30
|
+
const hasLeadingOrTrailingWhitespace = (value)=>value.trim() !== value;
|
|
31
|
+
const isBlank = (value)=>0 === value.trim().length;
|
|
32
|
+
function collectConfigWarnings(config) {
|
|
33
|
+
const warnings = [];
|
|
34
|
+
const discord = config.gateway?.adapters?.discord;
|
|
35
|
+
if (!discord?.enabled) return warnings;
|
|
36
|
+
if (!discord.token) warnings.push({
|
|
37
|
+
code: "discord-token-missing",
|
|
38
|
+
message: "gateway.adapters.discord.enabled is true but gateway.adapters.discord.token is not set; the adapter will not start."
|
|
39
|
+
});
|
|
40
|
+
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
41
|
+
code: "discord-session-command-blank",
|
|
42
|
+
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
43
|
+
});
|
|
44
|
+
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
45
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
46
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
47
|
+
const valueLabel = JSON.stringify(value);
|
|
48
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
49
|
+
code: "discord-channel-sessions-key-whitespace",
|
|
50
|
+
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
51
|
+
});
|
|
52
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
53
|
+
code: "discord-channel-sessions-value-whitespace",
|
|
54
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
55
|
+
});
|
|
56
|
+
if (isBlank(value)) {
|
|
57
|
+
warnings.push({
|
|
58
|
+
code: "discord-channel-sessions-value-blank",
|
|
59
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
60
|
+
});
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
64
|
+
code: "discord-channel-sessions-missing-agent",
|
|
65
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
for (const entry of discord.allowedChannels ?? []){
|
|
69
|
+
const label = JSON.stringify(entry);
|
|
70
|
+
if (isBlank(entry)) {
|
|
71
|
+
warnings.push({
|
|
72
|
+
code: "discord-allowed-channels-blank",
|
|
73
|
+
message: "gateway.adapters.discord.allowedChannels contains a blank entry; remove empty strings."
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
78
|
+
code: "discord-allowed-channels-whitespace",
|
|
79
|
+
message: `gateway.adapters.discord.allowedChannels contains ${label} with leading/trailing whitespace.`
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
for (const entry of discord.allowedGuilds ?? []){
|
|
83
|
+
const label = JSON.stringify(entry);
|
|
84
|
+
if (isBlank(entry)) {
|
|
85
|
+
warnings.push({
|
|
86
|
+
code: "discord-allowed-guilds-blank",
|
|
87
|
+
message: "gateway.adapters.discord.allowedGuilds contains a blank entry; remove empty strings."
|
|
88
|
+
});
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
92
|
+
code: "discord-allowed-guilds-whitespace",
|
|
93
|
+
message: `gateway.adapters.discord.allowedGuilds contains ${label} with leading/trailing whitespace.`
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return warnings;
|
|
97
|
+
}
|
|
98
|
+
exports.collectConfigWarnings = __webpack_exports__.collectConfigWarnings;
|
|
99
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
100
|
+
"collectConfigWarnings"
|
|
101
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
102
|
+
Object.defineProperty(exports, '__esModule', {
|
|
103
|
+
value: true
|
|
104
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const AGENT_PREFIX = /^agent:[^:]+:/;
|
|
2
|
+
const hasLeadingOrTrailingWhitespace = (value)=>value.trim() !== value;
|
|
3
|
+
const isBlank = (value)=>0 === value.trim().length;
|
|
4
|
+
function collectConfigWarnings(config) {
|
|
5
|
+
const warnings = [];
|
|
6
|
+
const discord = config.gateway?.adapters?.discord;
|
|
7
|
+
if (!discord?.enabled) return warnings;
|
|
8
|
+
if (!discord.token) warnings.push({
|
|
9
|
+
code: "discord-token-missing",
|
|
10
|
+
message: "gateway.adapters.discord.enabled is true but gateway.adapters.discord.token is not set; the adapter will not start."
|
|
11
|
+
});
|
|
12
|
+
if (isBlank(discord.sessionCommand || "")) warnings.push({
|
|
13
|
+
code: "discord-session-command-blank",
|
|
14
|
+
message: 'gateway.adapters.discord.sessionCommand is blank; it will fall back to "!session".'
|
|
15
|
+
});
|
|
16
|
+
for (const [rawKey, rawValue] of Object.entries(discord.channelSessions ?? {})){
|
|
17
|
+
const keyLabel = JSON.stringify(rawKey);
|
|
18
|
+
const value = "string" == typeof rawValue ? rawValue : "";
|
|
19
|
+
const valueLabel = JSON.stringify(value);
|
|
20
|
+
if (hasLeadingOrTrailingWhitespace(rawKey)) warnings.push({
|
|
21
|
+
code: "discord-channel-sessions-key-whitespace",
|
|
22
|
+
message: `gateway.adapters.discord.channelSessions key ${keyLabel} has leading/trailing whitespace.`
|
|
23
|
+
});
|
|
24
|
+
if (hasLeadingOrTrailingWhitespace(value)) warnings.push({
|
|
25
|
+
code: "discord-channel-sessions-value-whitespace",
|
|
26
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] value ${valueLabel} has leading/trailing whitespace.`
|
|
27
|
+
});
|
|
28
|
+
if (isBlank(value)) {
|
|
29
|
+
warnings.push({
|
|
30
|
+
code: "discord-channel-sessions-value-blank",
|
|
31
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] is empty; mapping will fall back to derived session keys.`
|
|
32
|
+
});
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!AGENT_PREFIX.test(value.trim())) warnings.push({
|
|
36
|
+
code: "discord-channel-sessions-missing-agent",
|
|
37
|
+
message: `gateway.adapters.discord.channelSessions[${keyLabel}] does not include an agent prefix (agent:<id>:...); agent selection will use bindings/default.`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
for (const entry of discord.allowedChannels ?? []){
|
|
41
|
+
const label = JSON.stringify(entry);
|
|
42
|
+
if (isBlank(entry)) {
|
|
43
|
+
warnings.push({
|
|
44
|
+
code: "discord-allowed-channels-blank",
|
|
45
|
+
message: "gateway.adapters.discord.allowedChannels contains a blank entry; remove empty strings."
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
50
|
+
code: "discord-allowed-channels-whitespace",
|
|
51
|
+
message: `gateway.adapters.discord.allowedChannels contains ${label} with leading/trailing whitespace.`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
for (const entry of discord.allowedGuilds ?? []){
|
|
55
|
+
const label = JSON.stringify(entry);
|
|
56
|
+
if (isBlank(entry)) {
|
|
57
|
+
warnings.push({
|
|
58
|
+
code: "discord-allowed-guilds-blank",
|
|
59
|
+
message: "gateway.adapters.discord.allowedGuilds contains a blank entry; remove empty strings."
|
|
60
|
+
});
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (hasLeadingOrTrailingWhitespace(entry)) warnings.push({
|
|
64
|
+
code: "discord-allowed-guilds-whitespace",
|
|
65
|
+
message: `gateway.adapters.discord.allowedGuilds contains ${label} with leading/trailing whitespace.`
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return warnings;
|
|
69
|
+
}
|
|
70
|
+
export { collectConfigWarnings };
|
|
@@ -128,9 +128,7 @@ class AgentInvoker {
|
|
|
128
128
|
}), backendOverrides),
|
|
129
129
|
middleware: middleware,
|
|
130
130
|
skills: skillsSources,
|
|
131
|
-
subagents: [
|
|
132
|
-
...targetAgent.subagents || []
|
|
133
|
-
],
|
|
131
|
+
subagents: targetAgent.subagents || [],
|
|
134
132
|
checkpointer: checkpointer
|
|
135
133
|
});
|
|
136
134
|
this.logger.debug("Agent created, sending message");
|
|
@@ -99,9 +99,7 @@ class AgentInvoker {
|
|
|
99
99
|
}), backendOverrides),
|
|
100
100
|
middleware: middleware,
|
|
101
101
|
skills: skillsSources,
|
|
102
|
-
subagents: [
|
|
103
|
-
...targetAgent.subagents || []
|
|
104
|
-
],
|
|
102
|
+
subagents: targetAgent.subagents || [],
|
|
105
103
|
checkpointer: checkpointer
|
|
106
104
|
});
|
|
107
105
|
this.logger.debug("Agent created, sending message");
|
package/dist/gateway/index.cjs
CHANGED
|
@@ -91,9 +91,9 @@ var __webpack_exports__ = {};
|
|
|
91
91
|
"GatewayDaemon",
|
|
92
92
|
"default",
|
|
93
93
|
"NodeManager",
|
|
94
|
-
"GatewayRpcClient",
|
|
95
|
-
"BroadcastGroupManager",
|
|
96
94
|
"GatewayAuth",
|
|
95
|
+
"BroadcastGroupManager",
|
|
96
|
+
"GatewayRpcClient",
|
|
97
97
|
"GatewayServer"
|
|
98
98
|
].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_types_js__rspack_import_7[__rspack_import_key];
|
|
99
99
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const schema_cjs_namespaceObject = require("../cli/config/schema.cjs");
|
|
5
|
+
const warnings_cjs_namespaceObject = require("../cli/config/warnings.cjs");
|
|
6
|
+
(0, external_vitest_namespaceObject.describe)("Config warnings", ()=>{
|
|
7
|
+
(0, external_vitest_namespaceObject.it)("returns warnings for common Discord config issues", ()=>{
|
|
8
|
+
const base = (0, schema_cjs_namespaceObject.validateConfig)({}).data;
|
|
9
|
+
const config = {
|
|
10
|
+
...base,
|
|
11
|
+
gateway: {
|
|
12
|
+
...base.gateway,
|
|
13
|
+
adapters: {
|
|
14
|
+
...base.gateway.adapters,
|
|
15
|
+
discord: {
|
|
16
|
+
enabled: true,
|
|
17
|
+
token: void 0,
|
|
18
|
+
mentionOnly: true,
|
|
19
|
+
allowBots: false,
|
|
20
|
+
allowedGuilds: [
|
|
21
|
+
" "
|
|
22
|
+
],
|
|
23
|
+
allowedChannels: [
|
|
24
|
+
"",
|
|
25
|
+
" 123 "
|
|
26
|
+
],
|
|
27
|
+
channelSessions: {
|
|
28
|
+
" 123 ": " session-plain ",
|
|
29
|
+
456: "session-plain"
|
|
30
|
+
},
|
|
31
|
+
sessionCommand: " ",
|
|
32
|
+
responseChunkSize: 1900
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const warnings = (0, warnings_cjs_namespaceObject.collectConfigWarnings)(config).map((warning)=>warning.message);
|
|
38
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("token"))).toBe(true);
|
|
39
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("sessionCommand"))).toBe(true);
|
|
40
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("channelSessions"))).toBe(true);
|
|
41
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("agent prefix"))).toBe(true);
|
|
42
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("allowedChannels"))).toBe(true);
|
|
43
|
+
(0, external_vitest_namespaceObject.expect)(warnings.some((msg)=>msg.includes("allowedGuilds"))).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
(0, external_vitest_namespaceObject.it)("returns no warnings when Discord adapter is disabled", ()=>{
|
|
46
|
+
const base = (0, schema_cjs_namespaceObject.validateConfig)({}).data;
|
|
47
|
+
(0, external_vitest_namespaceObject.expect)((0, warnings_cjs_namespaceObject.collectConfigWarnings)(base)).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
51
|
+
Object.defineProperty(exports, '__esModule', {
|
|
52
|
+
value: true
|
|
53
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { validateConfig } from "../cli/config/schema.js";
|
|
3
|
+
import { collectConfigWarnings } from "../cli/config/warnings.js";
|
|
4
|
+
describe("Config warnings", ()=>{
|
|
5
|
+
it("returns warnings for common Discord config issues", ()=>{
|
|
6
|
+
const base = validateConfig({}).data;
|
|
7
|
+
const config = {
|
|
8
|
+
...base,
|
|
9
|
+
gateway: {
|
|
10
|
+
...base.gateway,
|
|
11
|
+
adapters: {
|
|
12
|
+
...base.gateway.adapters,
|
|
13
|
+
discord: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
token: void 0,
|
|
16
|
+
mentionOnly: true,
|
|
17
|
+
allowBots: false,
|
|
18
|
+
allowedGuilds: [
|
|
19
|
+
" "
|
|
20
|
+
],
|
|
21
|
+
allowedChannels: [
|
|
22
|
+
"",
|
|
23
|
+
" 123 "
|
|
24
|
+
],
|
|
25
|
+
channelSessions: {
|
|
26
|
+
" 123 ": " session-plain ",
|
|
27
|
+
456: "session-plain"
|
|
28
|
+
},
|
|
29
|
+
sessionCommand: " ",
|
|
30
|
+
responseChunkSize: 1900
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const warnings = collectConfigWarnings(config).map((warning)=>warning.message);
|
|
36
|
+
expect(warnings.some((msg)=>msg.includes("token"))).toBe(true);
|
|
37
|
+
expect(warnings.some((msg)=>msg.includes("sessionCommand"))).toBe(true);
|
|
38
|
+
expect(warnings.some((msg)=>msg.includes("channelSessions"))).toBe(true);
|
|
39
|
+
expect(warnings.some((msg)=>msg.includes("agent prefix"))).toBe(true);
|
|
40
|
+
expect(warnings.some((msg)=>msg.includes("allowedChannels"))).toBe(true);
|
|
41
|
+
expect(warnings.some((msg)=>msg.includes("allowedGuilds"))).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
it("returns no warnings when Discord adapter is disabled", ()=>{
|
|
44
|
+
const base = validateConfig({}).data;
|
|
45
|
+
expect(collectConfigWarnings(base)).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
});
|
package/dist/types/agents.d.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import type { createDeepAgent } from "deepagents";
|
|
2
1
|
import type { HooksConfig } from "./hooks.js";
|
|
3
2
|
import type { MCPServersConfig } from "./mcp.js";
|
|
4
3
|
import type { AgentVoiceConfig } from "./voice.js";
|
|
5
|
-
export type
|
|
4
|
+
export type WingmanAgentTool = {
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
schema?: unknown;
|
|
8
|
+
invoke?: (...args: any[]) => unknown;
|
|
9
|
+
};
|
|
10
|
+
export type WingmanAgent = {
|
|
11
|
+
name: string;
|
|
12
|
+
systemPrompt: string;
|
|
13
|
+
tools?: WingmanAgentTool[];
|
|
14
|
+
skills?: string[];
|
|
15
|
+
model?: unknown;
|
|
16
|
+
subagents?: WingmanAgent[];
|
|
6
17
|
description?: string;
|
|
7
18
|
toolHooks?: HooksConfig;
|
|
8
19
|
mcpConfig?: MCPServersConfig;
|