@wingman-ai/gateway 0.2.2 → 0.2.4
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/.wingman/agents/README.md +7 -1
- package/.wingman/agents/coding/agent.md +299 -201
- package/.wingman/agents/coding-v2/agent.md +127 -0
- package/.wingman/agents/coding-v2/implementor.md +89 -0
- package/.wingman/agents/main/agent.md +4 -0
- package/README.md +1 -0
- package/dist/agent/config/agentConfig.cjs +31 -17
- package/dist/agent/config/agentConfig.d.ts +23 -1
- package/dist/agent/config/agentConfig.js +30 -19
- package/dist/agent/config/agentLoader.cjs +26 -8
- package/dist/agent/config/agentLoader.d.ts +4 -2
- package/dist/agent/config/agentLoader.js +26 -8
- package/dist/agent/config/modelFactory.cjs +95 -25
- package/dist/agent/config/modelFactory.d.ts +13 -1
- package/dist/agent/config/modelFactory.js +95 -25
- package/dist/agent/config/toolRegistry.cjs +19 -6
- package/dist/agent/config/toolRegistry.d.ts +5 -2
- package/dist/agent/config/toolRegistry.js +19 -6
- package/dist/agent/middleware/hooks/types.cjs +13 -13
- package/dist/agent/middleware/hooks/types.d.ts +1 -1
- package/dist/agent/middleware/hooks/types.js +14 -14
- package/dist/agent/tests/agentConfig.test.cjs +22 -2
- package/dist/agent/tests/agentConfig.test.js +22 -2
- package/dist/agent/tests/agentLoader.test.cjs +38 -1
- package/dist/agent/tests/agentLoader.test.js +38 -1
- package/dist/agent/tests/backgroundTerminal.test.cjs +70 -0
- package/dist/agent/tests/backgroundTerminal.test.d.ts +1 -0
- package/dist/agent/tests/backgroundTerminal.test.js +64 -0
- package/dist/agent/tests/commandExecuteTool.test.cjs +29 -0
- package/dist/agent/tests/commandExecuteTool.test.d.ts +1 -0
- package/dist/agent/tests/commandExecuteTool.test.js +23 -0
- package/dist/agent/tests/modelFactory.test.cjs +47 -5
- package/dist/agent/tests/modelFactory.test.js +47 -5
- package/dist/agent/tests/terminalSessionManager.test.cjs +121 -0
- package/dist/agent/tests/terminalSessionManager.test.d.ts +1 -0
- package/dist/agent/tests/terminalSessionManager.test.js +115 -0
- package/dist/agent/tests/toolRegistry.test.cjs +14 -2
- package/dist/agent/tests/toolRegistry.test.js +14 -2
- package/dist/agent/tools/background_terminal.cjs +128 -0
- package/dist/agent/tools/background_terminal.d.ts +41 -0
- package/dist/agent/tools/background_terminal.js +94 -0
- package/dist/agent/tools/code_search.cjs +6 -6
- package/dist/agent/tools/code_search.d.ts +1 -1
- package/dist/agent/tools/code_search.js +7 -7
- package/dist/agent/tools/command_execute.cjs +22 -7
- package/dist/agent/tools/command_execute.d.ts +3 -2
- package/dist/agent/tools/command_execute.js +23 -8
- package/dist/agent/tools/git_status.cjs +3 -3
- package/dist/agent/tools/git_status.d.ts +1 -1
- package/dist/agent/tools/git_status.js +4 -4
- package/dist/agent/tools/internet_search.cjs +6 -6
- package/dist/agent/tools/internet_search.d.ts +1 -1
- package/dist/agent/tools/internet_search.js +7 -7
- package/dist/agent/tools/terminal_session_manager.cjs +321 -0
- package/dist/agent/tools/terminal_session_manager.d.ts +77 -0
- package/dist/agent/tools/terminal_session_manager.js +284 -0
- package/dist/agent/tools/think.cjs +4 -4
- package/dist/agent/tools/think.d.ts +1 -1
- package/dist/agent/tools/think.js +5 -5
- package/dist/agent/tools/ui_registry.cjs +13 -13
- package/dist/agent/tools/ui_registry.d.ts +4 -4
- package/dist/agent/tools/ui_registry.js +14 -14
- package/dist/agent/tools/web_crawler.cjs +4 -4
- package/dist/agent/tools/web_crawler.d.ts +1 -1
- package/dist/agent/tools/web_crawler.js +5 -5
- package/dist/agent/utils.cjs +2 -1
- package/dist/agent/utils.js +2 -1
- package/dist/cli/commands/init.cjs +7 -6
- package/dist/cli/commands/init.js +7 -6
- package/dist/cli/commands/provider.cjs +17 -3
- package/dist/cli/commands/provider.js +17 -3
- package/dist/cli/config/loader.cjs +27 -0
- package/dist/cli/config/loader.js +27 -0
- package/dist/cli/config/schema.cjs +146 -68
- package/dist/cli/config/schema.d.ts +89 -1
- package/dist/cli/config/schema.js +134 -68
- package/dist/cli/core/agentInvoker.cjs +344 -17
- package/dist/cli/core/agentInvoker.d.ts +63 -3
- package/dist/cli/core/agentInvoker.js +303 -12
- package/dist/cli/core/sessionManager.cjs +32 -5
- package/dist/cli/core/sessionManager.js +32 -5
- package/dist/cli/core/streamParser.cjs +15 -0
- package/dist/cli/core/streamParser.js +15 -0
- package/dist/cli/index.cjs +6 -5
- package/dist/cli/index.js +6 -5
- package/dist/cli/types.d.ts +32 -0
- package/dist/cli/ui/toolDisplayHelpers.cjs +2 -0
- package/dist/cli/ui/toolDisplayHelpers.js +2 -0
- package/dist/gateway/hooks/registry.cjs +2 -1
- package/dist/gateway/hooks/registry.d.ts +1 -1
- package/dist/gateway/hooks/registry.js +2 -1
- package/dist/gateway/hooks/types.cjs +11 -11
- package/dist/gateway/hooks/types.d.ts +1 -1
- package/dist/gateway/hooks/types.js +12 -12
- package/dist/gateway/http/agents.cjs +67 -4
- package/dist/gateway/http/agents.js +67 -4
- package/dist/gateway/http/sessions.cjs +7 -7
- package/dist/gateway/http/sessions.js +7 -7
- package/dist/gateway/http/types.d.ts +5 -3
- package/dist/gateway/http/webhooks.cjs +6 -5
- package/dist/gateway/http/webhooks.js +6 -5
- package/dist/gateway/server.cjs +198 -41
- package/dist/gateway/server.d.ts +9 -1
- package/dist/gateway/server.js +198 -41
- package/dist/gateway/types.d.ts +1 -0
- package/dist/gateway/validation.cjs +39 -39
- package/dist/gateway/validation.d.ts +1 -1
- package/dist/gateway/validation.js +40 -40
- package/dist/providers/codex.cjs +167 -0
- package/dist/providers/codex.d.ts +15 -0
- package/dist/providers/codex.js +127 -0
- package/dist/providers/credentials.cjs +8 -0
- package/dist/providers/credentials.js +8 -0
- package/dist/providers/registry.cjs +11 -0
- package/dist/providers/registry.d.ts +1 -1
- package/dist/providers/registry.js +11 -0
- package/dist/tests/additionalMessageMiddleware.test.cjs +3 -0
- package/dist/tests/additionalMessageMiddleware.test.js +3 -0
- package/dist/tests/agentInvokerSummarization.test.cjs +455 -0
- package/dist/tests/agentInvokerSummarization.test.d.ts +1 -0
- package/dist/tests/agentInvokerSummarization.test.js +449 -0
- package/dist/tests/agents-api.test.cjs +45 -5
- package/dist/tests/agents-api.test.js +45 -5
- package/dist/tests/cli-config-loader.test.cjs +88 -0
- package/dist/tests/cli-config-loader.test.js +88 -0
- package/dist/tests/cli-init.test.cjs +27 -3
- package/dist/tests/cli-init.test.js +27 -3
- package/dist/tests/codex-credentials-precedence.test.cjs +94 -0
- package/dist/tests/codex-credentials-precedence.test.d.ts +1 -0
- package/dist/tests/codex-credentials-precedence.test.js +88 -0
- package/dist/tests/codex-provider.test.cjs +210 -0
- package/dist/tests/codex-provider.test.d.ts +1 -0
- package/dist/tests/codex-provider.test.js +204 -0
- package/dist/tests/gateway.test.cjs +115 -8
- package/dist/tests/gateway.test.js +115 -8
- package/dist/tests/provider-command-codex.test.cjs +57 -0
- package/dist/tests/provider-command-codex.test.d.ts +1 -0
- package/dist/tests/provider-command-codex.test.js +51 -0
- package/dist/tests/sessionStateMessages.test.cjs +38 -0
- package/dist/tests/sessionStateMessages.test.js +38 -0
- package/dist/tests/toolDisplayHelpers.test.cjs +3 -0
- package/dist/tests/toolDisplayHelpers.test.js +3 -0
- package/dist/tools/mcp-finance.cjs +48 -48
- package/dist/tools/mcp-finance.js +48 -48
- package/dist/types/mcp.cjs +15 -15
- package/dist/types/mcp.d.ts +1 -1
- package/dist/types/mcp.js +16 -16
- package/dist/types/voice.cjs +21 -21
- package/dist/types/voice.d.ts +1 -1
- package/dist/types/voice.js +22 -22
- package/dist/webui/assets/index-DVWQluit.css +11 -0
- package/dist/webui/assets/index-Dlyzwalc.js +270 -0
- package/dist/webui/favicon-32x32.png +0 -0
- package/dist/webui/favicon-64x64.png +0 -0
- package/dist/webui/favicon.webp +0 -0
- package/dist/webui/index.html +4 -2
- package/package.json +13 -12
- package/.wingman/agents/coding/implementor.md +0 -79
- package/dist/webui/assets/index-CPhfGPHc.js +0 -182
- package/dist/webui/assets/index-DDsMIOTX.css +0 -11
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_exports__ = {};
|
|
3
|
-
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
-
const modelFactory_cjs_namespaceObject = require("../config/modelFactory.cjs");
|
|
5
3
|
const anthropic_namespaceObject = require("@langchain/anthropic");
|
|
6
4
|
const openai_namespaceObject = require("@langchain/openai");
|
|
5
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
6
|
+
const modelFactory_cjs_namespaceObject = require("../config/modelFactory.cjs");
|
|
7
7
|
const originalAnthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
8
8
|
(0, external_vitest_namespaceObject.beforeEach)(()=>{
|
|
9
9
|
process.env.ANTHROPIC_API_KEY = "test-anthropic-api-key";
|
|
@@ -22,15 +22,54 @@ const originalAnthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
|
22
22
|
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openai:gpt-4o");
|
|
23
23
|
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
24
24
|
});
|
|
25
|
+
(0, external_vitest_namespaceObject.it)("should create a Codex model", ()=>{
|
|
26
|
+
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("codex:codex-mini-latest");
|
|
27
|
+
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
28
|
+
(0, external_vitest_namespaceObject.expect)(model.useResponsesApi).toBe(true);
|
|
29
|
+
(0, external_vitest_namespaceObject.expect)(model.zdrEnabled).toBe(true);
|
|
30
|
+
});
|
|
25
31
|
(0, external_vitest_namespaceObject.it)("should force OpenAI models onto the responses API", ()=>{
|
|
26
32
|
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openai:gpt-5.2-codex");
|
|
27
33
|
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
28
34
|
(0, external_vitest_namespaceObject.expect)(model.useResponsesApi).toBe(true);
|
|
29
35
|
});
|
|
36
|
+
(0, external_vitest_namespaceObject.it)("should apply reasoning effort for supported OpenAI reasoning models", ()=>{
|
|
37
|
+
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openai:gpt-5.2-codex", {
|
|
38
|
+
reasoningEffort: "high"
|
|
39
|
+
});
|
|
40
|
+
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
41
|
+
(0, external_vitest_namespaceObject.expect)(model.reasoning).toEqual({
|
|
42
|
+
effort: "high"
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
(0, external_vitest_namespaceObject.it)("should ignore reasoning effort for unsupported OpenAI models", ()=>{
|
|
46
|
+
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openai:gpt-4o", {
|
|
47
|
+
reasoningEffort: "medium"
|
|
48
|
+
});
|
|
49
|
+
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
50
|
+
(0, external_vitest_namespaceObject.expect)(model.reasoning).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
(0, external_vitest_namespaceObject.it)("should map reasoning effort to anthropic thinking budget", ()=>{
|
|
53
|
+
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("anthropic:claude-sonnet-4-5", {
|
|
54
|
+
reasoningEffort: "medium"
|
|
55
|
+
});
|
|
56
|
+
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(anthropic_namespaceObject.ChatAnthropic);
|
|
57
|
+
(0, external_vitest_namespaceObject.expect)(model.thinking).toEqual({
|
|
58
|
+
type: "enabled",
|
|
59
|
+
budget_tokens: 4096
|
|
60
|
+
});
|
|
61
|
+
});
|
|
30
62
|
(0, external_vitest_namespaceObject.it)("should create an OpenRouter model", ()=>{
|
|
31
63
|
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openrouter:openai/gpt-4o");
|
|
32
64
|
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
33
65
|
});
|
|
66
|
+
(0, external_vitest_namespaceObject.it)("should ignore reasoning effort for unsupported providers", ()=>{
|
|
67
|
+
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("openrouter:openai/gpt-5", {
|
|
68
|
+
reasoningEffort: "high"
|
|
69
|
+
});
|
|
70
|
+
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
71
|
+
(0, external_vitest_namespaceObject.expect)(model.reasoning).toBeUndefined();
|
|
72
|
+
});
|
|
34
73
|
(0, external_vitest_namespaceObject.it)("should create a Copilot model", ()=>{
|
|
35
74
|
const model = modelFactory_cjs_namespaceObject.ModelFactory.createModel("copilot:gpt-4o");
|
|
36
75
|
(0, external_vitest_namespaceObject.expect)(model).toBeInstanceOf(openai_namespaceObject.ChatOpenAI);
|
|
@@ -79,6 +118,7 @@ const originalAnthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
|
79
118
|
const validModels = [
|
|
80
119
|
"anthropic:claude-opus-4-5",
|
|
81
120
|
"openai:gpt-4o",
|
|
121
|
+
"codex:codex-mini-latest",
|
|
82
122
|
"anthropic:claude-sonnet-4-5-20250929",
|
|
83
123
|
"openrouter:openai/gpt-4o",
|
|
84
124
|
"copilot:gpt-4o",
|
|
@@ -115,14 +155,16 @@ const originalAnthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
|
115
155
|
(0, external_vitest_namespaceObject.it)("should accept case variations of providers", ()=>{
|
|
116
156
|
const result1 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("Anthropic:model");
|
|
117
157
|
const result2 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("OPENAI:model");
|
|
118
|
-
const result3 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("
|
|
119
|
-
const result4 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("
|
|
120
|
-
const result5 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("
|
|
158
|
+
const result3 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("CODEX:model");
|
|
159
|
+
const result4 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("Copilot:model");
|
|
160
|
+
const result5 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("LMStudio:model");
|
|
161
|
+
const result6 = modelFactory_cjs_namespaceObject.ModelFactory.validateModelString("OLLAMA:model");
|
|
121
162
|
(0, external_vitest_namespaceObject.expect)(result1.valid).toBe(true);
|
|
122
163
|
(0, external_vitest_namespaceObject.expect)(result2.valid).toBe(true);
|
|
123
164
|
(0, external_vitest_namespaceObject.expect)(result3.valid).toBe(true);
|
|
124
165
|
(0, external_vitest_namespaceObject.expect)(result4.valid).toBe(true);
|
|
125
166
|
(0, external_vitest_namespaceObject.expect)(result5.valid).toBe(true);
|
|
167
|
+
(0, external_vitest_namespaceObject.expect)(result6.valid).toBe(true);
|
|
126
168
|
});
|
|
127
169
|
});
|
|
128
170
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
-
import { ModelFactory } from "../config/modelFactory.js";
|
|
3
1
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
4
2
|
import { ChatOpenAI } from "@langchain/openai";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { ModelFactory } from "../config/modelFactory.js";
|
|
5
5
|
const originalAnthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
6
6
|
beforeEach(()=>{
|
|
7
7
|
process.env.ANTHROPIC_API_KEY = "test-anthropic-api-key";
|
|
@@ -20,15 +20,54 @@ describe("ModelFactory", ()=>{
|
|
|
20
20
|
const model = ModelFactory.createModel("openai:gpt-4o");
|
|
21
21
|
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
22
22
|
});
|
|
23
|
+
it("should create a Codex model", ()=>{
|
|
24
|
+
const model = ModelFactory.createModel("codex:codex-mini-latest");
|
|
25
|
+
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
26
|
+
expect(model.useResponsesApi).toBe(true);
|
|
27
|
+
expect(model.zdrEnabled).toBe(true);
|
|
28
|
+
});
|
|
23
29
|
it("should force OpenAI models onto the responses API", ()=>{
|
|
24
30
|
const model = ModelFactory.createModel("openai:gpt-5.2-codex");
|
|
25
31
|
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
26
32
|
expect(model.useResponsesApi).toBe(true);
|
|
27
33
|
});
|
|
34
|
+
it("should apply reasoning effort for supported OpenAI reasoning models", ()=>{
|
|
35
|
+
const model = ModelFactory.createModel("openai:gpt-5.2-codex", {
|
|
36
|
+
reasoningEffort: "high"
|
|
37
|
+
});
|
|
38
|
+
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
39
|
+
expect(model.reasoning).toEqual({
|
|
40
|
+
effort: "high"
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it("should ignore reasoning effort for unsupported OpenAI models", ()=>{
|
|
44
|
+
const model = ModelFactory.createModel("openai:gpt-4o", {
|
|
45
|
+
reasoningEffort: "medium"
|
|
46
|
+
});
|
|
47
|
+
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
48
|
+
expect(model.reasoning).toBeUndefined();
|
|
49
|
+
});
|
|
50
|
+
it("should map reasoning effort to anthropic thinking budget", ()=>{
|
|
51
|
+
const model = ModelFactory.createModel("anthropic:claude-sonnet-4-5", {
|
|
52
|
+
reasoningEffort: "medium"
|
|
53
|
+
});
|
|
54
|
+
expect(model).toBeInstanceOf(ChatAnthropic);
|
|
55
|
+
expect(model.thinking).toEqual({
|
|
56
|
+
type: "enabled",
|
|
57
|
+
budget_tokens: 4096
|
|
58
|
+
});
|
|
59
|
+
});
|
|
28
60
|
it("should create an OpenRouter model", ()=>{
|
|
29
61
|
const model = ModelFactory.createModel("openrouter:openai/gpt-4o");
|
|
30
62
|
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
31
63
|
});
|
|
64
|
+
it("should ignore reasoning effort for unsupported providers", ()=>{
|
|
65
|
+
const model = ModelFactory.createModel("openrouter:openai/gpt-5", {
|
|
66
|
+
reasoningEffort: "high"
|
|
67
|
+
});
|
|
68
|
+
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
69
|
+
expect(model.reasoning).toBeUndefined();
|
|
70
|
+
});
|
|
32
71
|
it("should create a Copilot model", ()=>{
|
|
33
72
|
const model = ModelFactory.createModel("copilot:gpt-4o");
|
|
34
73
|
expect(model).toBeInstanceOf(ChatOpenAI);
|
|
@@ -77,6 +116,7 @@ describe("ModelFactory", ()=>{
|
|
|
77
116
|
const validModels = [
|
|
78
117
|
"anthropic:claude-opus-4-5",
|
|
79
118
|
"openai:gpt-4o",
|
|
119
|
+
"codex:codex-mini-latest",
|
|
80
120
|
"anthropic:claude-sonnet-4-5-20250929",
|
|
81
121
|
"openrouter:openai/gpt-4o",
|
|
82
122
|
"copilot:gpt-4o",
|
|
@@ -113,14 +153,16 @@ describe("ModelFactory", ()=>{
|
|
|
113
153
|
it("should accept case variations of providers", ()=>{
|
|
114
154
|
const result1 = ModelFactory.validateModelString("Anthropic:model");
|
|
115
155
|
const result2 = ModelFactory.validateModelString("OPENAI:model");
|
|
116
|
-
const result3 = ModelFactory.validateModelString("
|
|
117
|
-
const result4 = ModelFactory.validateModelString("
|
|
118
|
-
const result5 = ModelFactory.validateModelString("
|
|
156
|
+
const result3 = ModelFactory.validateModelString("CODEX:model");
|
|
157
|
+
const result4 = ModelFactory.validateModelString("Copilot:model");
|
|
158
|
+
const result5 = ModelFactory.validateModelString("LMStudio:model");
|
|
159
|
+
const result6 = ModelFactory.validateModelString("OLLAMA:model");
|
|
119
160
|
expect(result1.valid).toBe(true);
|
|
120
161
|
expect(result2.valid).toBe(true);
|
|
121
162
|
expect(result3.valid).toBe(true);
|
|
122
163
|
expect(result4.valid).toBe(true);
|
|
123
164
|
expect(result5.valid).toBe(true);
|
|
165
|
+
expect(result6.valid).toBe(true);
|
|
124
166
|
});
|
|
125
167
|
});
|
|
126
168
|
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const terminal_session_manager_cjs_namespaceObject = require("../tools/terminal_session_manager.cjs");
|
|
5
|
+
async function waitForTerminalCompletion(manager, ownerId, sessionId, timeoutMs = 5000) {
|
|
6
|
+
const started = Date.now();
|
|
7
|
+
let lastOutput = "";
|
|
8
|
+
while(Date.now() - started < timeoutMs){
|
|
9
|
+
const poll = await manager.pollSession({
|
|
10
|
+
ownerId,
|
|
11
|
+
sessionId,
|
|
12
|
+
waitMs: 200,
|
|
13
|
+
maxOutputChars: 2000
|
|
14
|
+
});
|
|
15
|
+
lastOutput += poll.output;
|
|
16
|
+
if ("running" !== poll.status) return {
|
|
17
|
+
...poll,
|
|
18
|
+
output: lastOutput
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`Timed out waiting for terminal session ${sessionId}`);
|
|
22
|
+
}
|
|
23
|
+
(0, external_vitest_namespaceObject.describe)("TerminalSessionManager", ()=>{
|
|
24
|
+
(0, external_vitest_namespaceObject.it)("runs commands and returns output", async ()=>{
|
|
25
|
+
const manager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
|
|
26
|
+
try {
|
|
27
|
+
const session = manager.startSession({
|
|
28
|
+
ownerId: "owner-a",
|
|
29
|
+
command: "node -e \"process.stdout.write('hello\\n')\"",
|
|
30
|
+
cwd: process.cwd(),
|
|
31
|
+
env: process.env
|
|
32
|
+
});
|
|
33
|
+
const finalState = await waitForTerminalCompletion(manager, "owner-a", session.sessionId);
|
|
34
|
+
(0, external_vitest_namespaceObject.expect)(finalState.output).toContain("hello");
|
|
35
|
+
(0, external_vitest_namespaceObject.expect)([
|
|
36
|
+
"completed",
|
|
37
|
+
"error",
|
|
38
|
+
"killed",
|
|
39
|
+
"timed_out"
|
|
40
|
+
]).toContain(finalState.status);
|
|
41
|
+
} finally{
|
|
42
|
+
manager.dispose();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
(0, external_vitest_namespaceObject.it)("enforces session ownership", async ()=>{
|
|
46
|
+
const manager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
|
|
47
|
+
try {
|
|
48
|
+
const session = manager.startSession({
|
|
49
|
+
ownerId: "owner-allowed",
|
|
50
|
+
command: 'node -e "setTimeout(() => {}, 500)"',
|
|
51
|
+
cwd: process.cwd(),
|
|
52
|
+
env: process.env
|
|
53
|
+
});
|
|
54
|
+
await (0, external_vitest_namespaceObject.expect)(manager.pollSession({
|
|
55
|
+
ownerId: "owner-denied",
|
|
56
|
+
sessionId: session.sessionId,
|
|
57
|
+
waitMs: 0
|
|
58
|
+
})).rejects.toThrow("not accessible");
|
|
59
|
+
} finally{
|
|
60
|
+
manager.dispose();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
(0, external_vitest_namespaceObject.it)("supports stdin writes and kill", async ()=>{
|
|
64
|
+
const manager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
|
|
65
|
+
try {
|
|
66
|
+
const session = manager.startSession({
|
|
67
|
+
ownerId: "owner-b",
|
|
68
|
+
command: "cat",
|
|
69
|
+
cwd: process.cwd(),
|
|
70
|
+
env: process.env
|
|
71
|
+
});
|
|
72
|
+
manager.writeSession({
|
|
73
|
+
ownerId: "owner-b",
|
|
74
|
+
sessionId: session.sessionId,
|
|
75
|
+
chars: "ping\n"
|
|
76
|
+
});
|
|
77
|
+
const poll = await manager.pollSession({
|
|
78
|
+
ownerId: "owner-b",
|
|
79
|
+
sessionId: session.sessionId,
|
|
80
|
+
waitMs: 1000,
|
|
81
|
+
maxOutputChars: 2000
|
|
82
|
+
});
|
|
83
|
+
(0, external_vitest_namespaceObject.expect)(poll.output).toContain("ping");
|
|
84
|
+
const killed = manager.killSession({
|
|
85
|
+
ownerId: "owner-b",
|
|
86
|
+
sessionId: session.sessionId,
|
|
87
|
+
signal: "SIGTERM"
|
|
88
|
+
});
|
|
89
|
+
(0, external_vitest_namespaceObject.expect)([
|
|
90
|
+
"running",
|
|
91
|
+
"killed",
|
|
92
|
+
"timed_out",
|
|
93
|
+
"error",
|
|
94
|
+
"completed"
|
|
95
|
+
]).toContain(killed.status);
|
|
96
|
+
} finally{
|
|
97
|
+
manager.dispose();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
(0, external_vitest_namespaceObject.it)("drops buffered output when max buffer is exceeded", async ()=>{
|
|
101
|
+
const manager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager({
|
|
102
|
+
maxBufferedCharsPerSession: 32
|
|
103
|
+
});
|
|
104
|
+
try {
|
|
105
|
+
const session = manager.startSession({
|
|
106
|
+
ownerId: "owner-c",
|
|
107
|
+
command: "node -e \"process.stdout.write('abcdefghijklmnopqrstuvwxyz0123456789')\"",
|
|
108
|
+
cwd: process.cwd(),
|
|
109
|
+
env: process.env
|
|
110
|
+
});
|
|
111
|
+
const finalState = await waitForTerminalCompletion(manager, "owner-c", session.sessionId);
|
|
112
|
+
(0, external_vitest_namespaceObject.expect)(finalState.droppedChars).toBeGreaterThan(0);
|
|
113
|
+
} finally{
|
|
114
|
+
manager.dispose();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
119
|
+
Object.defineProperty(exports, '__esModule', {
|
|
120
|
+
value: true
|
|
121
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { TerminalSessionManager } from "../tools/terminal_session_manager.js";
|
|
3
|
+
async function waitForTerminalCompletion(manager, ownerId, sessionId, timeoutMs = 5000) {
|
|
4
|
+
const started = Date.now();
|
|
5
|
+
let lastOutput = "";
|
|
6
|
+
while(Date.now() - started < timeoutMs){
|
|
7
|
+
const poll = await manager.pollSession({
|
|
8
|
+
ownerId,
|
|
9
|
+
sessionId,
|
|
10
|
+
waitMs: 200,
|
|
11
|
+
maxOutputChars: 2000
|
|
12
|
+
});
|
|
13
|
+
lastOutput += poll.output;
|
|
14
|
+
if ("running" !== poll.status) return {
|
|
15
|
+
...poll,
|
|
16
|
+
output: lastOutput
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`Timed out waiting for terminal session ${sessionId}`);
|
|
20
|
+
}
|
|
21
|
+
describe("TerminalSessionManager", ()=>{
|
|
22
|
+
it("runs commands and returns output", async ()=>{
|
|
23
|
+
const manager = new TerminalSessionManager();
|
|
24
|
+
try {
|
|
25
|
+
const session = manager.startSession({
|
|
26
|
+
ownerId: "owner-a",
|
|
27
|
+
command: "node -e \"process.stdout.write('hello\\n')\"",
|
|
28
|
+
cwd: process.cwd(),
|
|
29
|
+
env: process.env
|
|
30
|
+
});
|
|
31
|
+
const finalState = await waitForTerminalCompletion(manager, "owner-a", session.sessionId);
|
|
32
|
+
expect(finalState.output).toContain("hello");
|
|
33
|
+
expect([
|
|
34
|
+
"completed",
|
|
35
|
+
"error",
|
|
36
|
+
"killed",
|
|
37
|
+
"timed_out"
|
|
38
|
+
]).toContain(finalState.status);
|
|
39
|
+
} finally{
|
|
40
|
+
manager.dispose();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
it("enforces session ownership", async ()=>{
|
|
44
|
+
const manager = new TerminalSessionManager();
|
|
45
|
+
try {
|
|
46
|
+
const session = manager.startSession({
|
|
47
|
+
ownerId: "owner-allowed",
|
|
48
|
+
command: 'node -e "setTimeout(() => {}, 500)"',
|
|
49
|
+
cwd: process.cwd(),
|
|
50
|
+
env: process.env
|
|
51
|
+
});
|
|
52
|
+
await expect(manager.pollSession({
|
|
53
|
+
ownerId: "owner-denied",
|
|
54
|
+
sessionId: session.sessionId,
|
|
55
|
+
waitMs: 0
|
|
56
|
+
})).rejects.toThrow("not accessible");
|
|
57
|
+
} finally{
|
|
58
|
+
manager.dispose();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
it("supports stdin writes and kill", async ()=>{
|
|
62
|
+
const manager = new TerminalSessionManager();
|
|
63
|
+
try {
|
|
64
|
+
const session = manager.startSession({
|
|
65
|
+
ownerId: "owner-b",
|
|
66
|
+
command: "cat",
|
|
67
|
+
cwd: process.cwd(),
|
|
68
|
+
env: process.env
|
|
69
|
+
});
|
|
70
|
+
manager.writeSession({
|
|
71
|
+
ownerId: "owner-b",
|
|
72
|
+
sessionId: session.sessionId,
|
|
73
|
+
chars: "ping\n"
|
|
74
|
+
});
|
|
75
|
+
const poll = await manager.pollSession({
|
|
76
|
+
ownerId: "owner-b",
|
|
77
|
+
sessionId: session.sessionId,
|
|
78
|
+
waitMs: 1000,
|
|
79
|
+
maxOutputChars: 2000
|
|
80
|
+
});
|
|
81
|
+
expect(poll.output).toContain("ping");
|
|
82
|
+
const killed = manager.killSession({
|
|
83
|
+
ownerId: "owner-b",
|
|
84
|
+
sessionId: session.sessionId,
|
|
85
|
+
signal: "SIGTERM"
|
|
86
|
+
});
|
|
87
|
+
expect([
|
|
88
|
+
"running",
|
|
89
|
+
"killed",
|
|
90
|
+
"timed_out",
|
|
91
|
+
"error",
|
|
92
|
+
"completed"
|
|
93
|
+
]).toContain(killed.status);
|
|
94
|
+
} finally{
|
|
95
|
+
manager.dispose();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
it("drops buffered output when max buffer is exceeded", async ()=>{
|
|
99
|
+
const manager = new TerminalSessionManager({
|
|
100
|
+
maxBufferedCharsPerSession: 32
|
|
101
|
+
});
|
|
102
|
+
try {
|
|
103
|
+
const session = manager.startSession({
|
|
104
|
+
ownerId: "owner-c",
|
|
105
|
+
command: "node -e \"process.stdout.write('abcdefghijklmnopqrstuvwxyz0123456789')\"",
|
|
106
|
+
cwd: process.cwd(),
|
|
107
|
+
env: process.env
|
|
108
|
+
});
|
|
109
|
+
const finalState = await waitForTerminalCompletion(manager, "owner-c", session.sessionId);
|
|
110
|
+
expect(finalState.droppedChars).toBeGreaterThan(0);
|
|
111
|
+
} finally{
|
|
112
|
+
manager.dispose();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_exports__ = {};
|
|
3
|
-
const external_vitest_namespaceObject = require("vitest");
|
|
4
3
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
5
|
-
const external_node_path_namespaceObject = require("node:path");
|
|
6
4
|
const external_node_os_namespaceObject = require("node:os");
|
|
5
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
6
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
7
7
|
const toolRegistry_cjs_namespaceObject = require("../config/toolRegistry.cjs");
|
|
8
|
+
const terminal_session_manager_cjs_namespaceObject = require("../tools/terminal_session_manager.cjs");
|
|
8
9
|
(0, external_vitest_namespaceObject.describe)("Tool Registry", ()=>{
|
|
9
10
|
(0, external_vitest_namespaceObject.describe)("createTool", ()=>{
|
|
10
11
|
(0, external_vitest_namespaceObject.it)("should create internet_search tool", ()=>{
|
|
@@ -35,6 +36,15 @@ const toolRegistry_cjs_namespaceObject = require("../config/toolRegistry.cjs");
|
|
|
35
36
|
(0, external_vitest_namespaceObject.expect)(tool).not.toBeNull();
|
|
36
37
|
(0, external_vitest_namespaceObject.expect)(tool?.name).toBe("command_execute");
|
|
37
38
|
});
|
|
39
|
+
(0, external_vitest_namespaceObject.it)("should create terminal tools", ()=>{
|
|
40
|
+
const manager = new terminal_session_manager_cjs_namespaceObject.TerminalSessionManager();
|
|
41
|
+
const terminalTool = (0, toolRegistry_cjs_namespaceObject.createTool)("background_terminal", {
|
|
42
|
+
terminalOwnerId: "owner-1",
|
|
43
|
+
terminalSessionManager: manager
|
|
44
|
+
});
|
|
45
|
+
(0, external_vitest_namespaceObject.expect)(terminalTool?.name).toBe("background_terminal");
|
|
46
|
+
manager.dispose();
|
|
47
|
+
});
|
|
38
48
|
(0, external_vitest_namespaceObject.it)("should execute command tools in executionWorkspace when provided", async ()=>{
|
|
39
49
|
const executionWorkspace = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-tool-workspace-"));
|
|
40
50
|
const tool = (0, toolRegistry_cjs_namespaceObject.createTool)("command_execute", {
|
|
@@ -42,6 +52,7 @@ const toolRegistry_cjs_namespaceObject = require("../config/toolRegistry.cjs");
|
|
|
42
52
|
executionWorkspace
|
|
43
53
|
});
|
|
44
54
|
(0, external_vitest_namespaceObject.expect)(tool).not.toBeNull();
|
|
55
|
+
if (!tool) throw new Error("Expected command_execute tool to be created");
|
|
45
56
|
const result = await tool.invoke({
|
|
46
57
|
command: 'node -e "process.stdout.write(process.cwd())"'
|
|
47
58
|
});
|
|
@@ -106,6 +117,7 @@ const toolRegistry_cjs_namespaceObject = require("../config/toolRegistry.cjs");
|
|
|
106
117
|
"internet_search",
|
|
107
118
|
"web_crawler",
|
|
108
119
|
"command_execute",
|
|
120
|
+
"background_terminal",
|
|
109
121
|
"think",
|
|
110
122
|
"code_search",
|
|
111
123
|
"git_status",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
1
|
import { mkdtempSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
4
2
|
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
5
|
import { createTool, createTools, getAvailableTools } from "../config/toolRegistry.js";
|
|
6
|
+
import { TerminalSessionManager } from "../tools/terminal_session_manager.js";
|
|
6
7
|
describe("Tool Registry", ()=>{
|
|
7
8
|
describe("createTool", ()=>{
|
|
8
9
|
it("should create internet_search tool", ()=>{
|
|
@@ -33,6 +34,15 @@ describe("Tool Registry", ()=>{
|
|
|
33
34
|
expect(tool).not.toBeNull();
|
|
34
35
|
expect(tool?.name).toBe("command_execute");
|
|
35
36
|
});
|
|
37
|
+
it("should create terminal tools", ()=>{
|
|
38
|
+
const manager = new TerminalSessionManager();
|
|
39
|
+
const terminalTool = createTool("background_terminal", {
|
|
40
|
+
terminalOwnerId: "owner-1",
|
|
41
|
+
terminalSessionManager: manager
|
|
42
|
+
});
|
|
43
|
+
expect(terminalTool?.name).toBe("background_terminal");
|
|
44
|
+
manager.dispose();
|
|
45
|
+
});
|
|
36
46
|
it("should execute command tools in executionWorkspace when provided", async ()=>{
|
|
37
47
|
const executionWorkspace = mkdtempSync(join(tmpdir(), "wingman-tool-workspace-"));
|
|
38
48
|
const tool = createTool("command_execute", {
|
|
@@ -40,6 +50,7 @@ describe("Tool Registry", ()=>{
|
|
|
40
50
|
executionWorkspace
|
|
41
51
|
});
|
|
42
52
|
expect(tool).not.toBeNull();
|
|
53
|
+
if (!tool) throw new Error("Expected command_execute tool to be created");
|
|
43
54
|
const result = await tool.invoke({
|
|
44
55
|
command: 'node -e "process.stdout.write(process.cwd())"'
|
|
45
56
|
});
|
|
@@ -104,6 +115,7 @@ describe("Tool Registry", ()=>{
|
|
|
104
115
|
"internet_search",
|
|
105
116
|
"web_crawler",
|
|
106
117
|
"command_execute",
|
|
118
|
+
"background_terminal",
|
|
107
119
|
"think",
|
|
108
120
|
"code_search",
|
|
109
121
|
"git_status",
|
|
@@ -0,0 +1,128 @@
|
|
|
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
|
+
createBackgroundTerminalTool: ()=>createBackgroundTerminalTool
|
|
28
|
+
});
|
|
29
|
+
const external_langchain_namespaceObject = require("langchain");
|
|
30
|
+
const external_zod_namespaceObject = require("zod");
|
|
31
|
+
const external_command_execute_cjs_namespaceObject = require("./command_execute.cjs");
|
|
32
|
+
const normalizeCommandParts = (command)=>{
|
|
33
|
+
const commandParts = command.trim().split(/\s+/);
|
|
34
|
+
const commandName = (commandParts[0] || "").toLowerCase();
|
|
35
|
+
return commandName.split(/[\\/]/).pop() || "";
|
|
36
|
+
};
|
|
37
|
+
const isScriptCommand = (command)=>{
|
|
38
|
+
const normalized = command.trim().toLowerCase();
|
|
39
|
+
return normalized.endsWith(".sh") || normalized.endsWith(".bash") || normalized.endsWith(".zsh") || normalized.endsWith(".ps1") || normalized.endsWith(".cmd") || normalized.endsWith(".bat");
|
|
40
|
+
};
|
|
41
|
+
const createSafeEnv = (envVariables)=>{
|
|
42
|
+
const { NODE_OPTIONS, NODE_DEBUG, VSCODE_INSPECTOR_OPTIONS, ...cleanEnv } = process.env;
|
|
43
|
+
return {
|
|
44
|
+
...cleanEnv,
|
|
45
|
+
FORCE_COLOR: "0",
|
|
46
|
+
NO_COLOR: "1",
|
|
47
|
+
GIT_PAGER: "cat",
|
|
48
|
+
...envVariables ?? {}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const buildTerminalResponse = (payload)=>payload;
|
|
52
|
+
const createBackgroundTerminalTool = (options)=>{
|
|
53
|
+
const { workspace, ownerId, sessionManager, envVariables, blockedCommands = external_command_execute_cjs_namespaceObject.DEFAULT_BLOCKED_COMMANDS, allowScriptExecution = true, commandTimeout = 300000 } = options;
|
|
54
|
+
return (0, external_langchain_namespaceObject.tool)(async ({ command, session_id, chars, wait_ms, max_output_chars })=>{
|
|
55
|
+
try {
|
|
56
|
+
if (command && session_id) return buildTerminalResponse({
|
|
57
|
+
error: "Provide either command or session_id, not both"
|
|
58
|
+
});
|
|
59
|
+
if (!command && !session_id) return buildTerminalResponse({
|
|
60
|
+
error: "Provide command to start a session or session_id to poll/write"
|
|
61
|
+
});
|
|
62
|
+
let resolvedSessionId = session_id;
|
|
63
|
+
if (command) {
|
|
64
|
+
const baseCommand = normalizeCommandParts(command);
|
|
65
|
+
if (blockedCommands.includes(baseCommand)) return buildTerminalResponse({
|
|
66
|
+
error: `Command "${command}" rejected by blockedCommands policy`
|
|
67
|
+
});
|
|
68
|
+
if (!allowScriptExecution && isScriptCommand(command)) return buildTerminalResponse({
|
|
69
|
+
error: `Command "${command}" rejected because script execution is disabled`
|
|
70
|
+
});
|
|
71
|
+
const session = sessionManager.startSession({
|
|
72
|
+
ownerId,
|
|
73
|
+
command,
|
|
74
|
+
cwd: workspace,
|
|
75
|
+
env: createSafeEnv(envVariables),
|
|
76
|
+
runtimeLimitMs: commandTimeout
|
|
77
|
+
});
|
|
78
|
+
resolvedSessionId = session.sessionId;
|
|
79
|
+
}
|
|
80
|
+
if (!resolvedSessionId) return buildTerminalResponse({
|
|
81
|
+
error: "session_id is required"
|
|
82
|
+
});
|
|
83
|
+
if (chars && chars.length > 0) sessionManager.writeSession({
|
|
84
|
+
ownerId,
|
|
85
|
+
sessionId: resolvedSessionId,
|
|
86
|
+
chars
|
|
87
|
+
});
|
|
88
|
+
const pollResult = await sessionManager.pollSession({
|
|
89
|
+
ownerId,
|
|
90
|
+
sessionId: resolvedSessionId,
|
|
91
|
+
waitMs: wait_ms,
|
|
92
|
+
maxOutputChars: max_output_chars
|
|
93
|
+
});
|
|
94
|
+
return buildTerminalResponse({
|
|
95
|
+
session_id: pollResult.sessionId,
|
|
96
|
+
status: pollResult.status,
|
|
97
|
+
output: pollResult.output,
|
|
98
|
+
has_more: pollResult.hasMore,
|
|
99
|
+
exit_code: pollResult.exitCode,
|
|
100
|
+
signal: pollResult.signal,
|
|
101
|
+
command: pollResult.command,
|
|
102
|
+
cwd: pollResult.cwd,
|
|
103
|
+
dropped_chars: pollResult.droppedChars
|
|
104
|
+
});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
return buildTerminalResponse({
|
|
107
|
+
error: error instanceof Error ? error.message : String(error)
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}, {
|
|
111
|
+
name: "background_terminal",
|
|
112
|
+
description: "Single background terminal interface for long-running sessions. Use this for commands that may not exit on their own (for example web servers, test watchers, or log tailing). Start a session with command, then poll or write using session_id. Use normal shell commands in-session (for example ps/jobs/kill) and control chars like \\u0003 to interrupt running programs.",
|
|
113
|
+
schema: external_zod_namespaceObject.object({
|
|
114
|
+
command: external_zod_namespaceObject.string().optional().describe("Command to start a new terminal session"),
|
|
115
|
+
session_id: external_zod_namespaceObject.string().optional().describe("Existing terminal session id for poll/write"),
|
|
116
|
+
chars: external_zod_namespaceObject.string().optional().default("").describe("Optional stdin text to write before polling"),
|
|
117
|
+
wait_ms: external_zod_namespaceObject.number().min(0).max(30000).optional().default(1000).describe("How long to wait for output before returning"),
|
|
118
|
+
max_output_chars: external_zod_namespaceObject.number().min(1).max(200000).optional().default(8000).describe("Maximum output characters to return")
|
|
119
|
+
})
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
exports.createBackgroundTerminalTool = __webpack_exports__.createBackgroundTerminalTool;
|
|
123
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
124
|
+
"createBackgroundTerminalTool"
|
|
125
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
126
|
+
Object.defineProperty(exports, '__esModule', {
|
|
127
|
+
value: true
|
|
128
|
+
});
|