@sensigo/realm-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/agent/agent-utils.d.ts +27 -0
- package/dist/agent/agent-utils.d.ts.map +1 -0
- package/dist/agent/agent-utils.js +79 -0
- package/dist/agent/agent-utils.js.map +1 -0
- package/dist/agent/anthropic-provider.d.ts +23 -0
- package/dist/agent/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/anthropic-provider.js +245 -0
- package/dist/agent/anthropic-provider.js.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.js +315 -0
- package/dist/agent/gate/slack-gate-notifier.js.map +1 -0
- package/dist/agent/gate/slack-gate-server.d.ts +30 -0
- package/dist/agent/gate/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-server.js +99 -0
- package/dist/agent/gate/slack-gate-server.js.map +1 -0
- package/dist/agent/gate/slack-socket-client.d.ts +20 -0
- package/dist/agent/gate/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/gate/slack-socket-client.js +141 -0
- package/dist/agent/gate/slack-socket-client.js.map +1 -0
- package/dist/agent/gate-intent-interpreter.d.ts +29 -0
- package/dist/agent/gate-intent-interpreter.d.ts.map +1 -0
- package/dist/agent/gate-intent-interpreter.js +33 -0
- package/dist/agent/gate-intent-interpreter.js.map +1 -0
- package/dist/agent/index.d.ts +4 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +4 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/llm-provider.d.ts +46 -0
- package/dist/agent/llm-provider.d.ts.map +1 -0
- package/dist/agent/llm-provider.js +55 -0
- package/dist/agent/llm-provider.js.map +1 -0
- package/dist/agent/mcp/mcp-client.d.ts +18 -0
- package/dist/agent/mcp/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-client.js +108 -0
- package/dist/agent/mcp/mcp-client.js.map +1 -0
- package/dist/agent/mcp/mcp-extensions.d.ts +40 -0
- package/dist/agent/mcp/mcp-extensions.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-extensions.js +2 -0
- package/dist/agent/mcp/mcp-extensions.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +18 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +108 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-types.d.ts +40 -0
- package/dist/agent/mcp-types.d.ts.map +1 -0
- package/dist/agent/mcp-types.js +2 -0
- package/dist/agent/mcp-types.js.map +1 -0
- package/dist/agent/openai-provider.d.ts +30 -0
- package/dist/agent/openai-provider.d.ts.map +1 -0
- package/dist/agent/openai-provider.js +253 -0
- package/dist/agent/openai-provider.js.map +1 -0
- package/dist/agent/openai-reasoning-provider.d.ts +18 -0
- package/dist/agent/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/openai-reasoning-provider.js +76 -0
- package/dist/agent/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/preflight.d.ts +36 -0
- package/dist/agent/preflight.d.ts.map +1 -0
- package/dist/agent/preflight.js +81 -0
- package/dist/agent/preflight.js.map +1 -0
- package/dist/agent/providers/agent-utils.d.ts +27 -0
- package/dist/agent/providers/agent-utils.d.ts.map +1 -0
- package/dist/agent/providers/agent-utils.js +79 -0
- package/dist/agent/providers/agent-utils.js.map +1 -0
- package/dist/agent/providers/anthropic-provider.d.ts +23 -0
- package/dist/agent/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/providers/anthropic-provider.js +257 -0
- package/dist/agent/providers/anthropic-provider.js.map +1 -0
- package/dist/agent/providers/llm-provider.d.ts +46 -0
- package/dist/agent/providers/llm-provider.d.ts.map +1 -0
- package/dist/agent/providers/llm-provider.js +56 -0
- package/dist/agent/providers/llm-provider.js.map +1 -0
- package/dist/agent/providers/openai-provider.d.ts +30 -0
- package/dist/agent/providers/openai-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-provider.js +253 -0
- package/dist/agent/providers/openai-provider.js.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts +19 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.js +89 -0
- package/dist/agent/providers/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/run-agent.d.ts +50 -0
- package/dist/agent/run-agent.d.ts.map +1 -0
- package/dist/agent/run-agent.js +327 -0
- package/dist/agent/run-agent.js.map +1 -0
- package/dist/agent/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/slack-gate-notifier.js +315 -0
- package/dist/agent/slack-gate-notifier.js.map +1 -0
- package/dist/agent/slack-gate-poller.d.ts +28 -0
- package/dist/agent/slack-gate-poller.d.ts.map +1 -0
- package/dist/agent/slack-gate-poller.js +66 -0
- package/dist/agent/slack-gate-poller.js.map +1 -0
- package/dist/agent/slack-gate-server.d.ts +30 -0
- package/dist/agent/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/slack-gate-server.js +99 -0
- package/dist/agent/slack-gate-server.js.map +1 -0
- package/dist/agent/slack-socket-client.d.ts +20 -0
- package/dist/agent/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/slack-socket-client.js +141 -0
- package/dist/agent/slack-socket-client.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +183 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/cleanup.d.ts +16 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +79 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/diff.d.ts +41 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +203 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +97 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +14 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +224 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/list.d.ts +18 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +88 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +22 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +42 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/register.d.ts +6 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +51 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/replay-format.d.ts +3 -0
- package/dist/commands/replay-format.d.ts.map +1 -0
- package/dist/commands/replay-format.js +10 -0
- package/dist/commands/replay-format.js.map +1 -0
- package/dist/commands/replay.d.ts +38 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +173 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/respond.d.ts +20 -0
- package/dist/commands/respond.d.ts.map +1 -0
- package/dist/commands/respond.js +49 -0
- package/dist/commands/respond.js.map +1 -0
- package/dist/commands/resume.d.ts +15 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +63 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +127 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serve.d.ts +33 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +144 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +58 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +35 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch.d.ts +18 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +112 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/webhook.d.ts +51 -0
- package/dist/commands/webhook.d.ts.map +1 -0
- package/dist/commands/webhook.js +227 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/commands-registry.d.ts +7 -0
- package/dist/commands-registry.d.ts.map +1 -0
- package/dist/commands-registry.js +44 -0
- package/dist/commands-registry.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/store/replay-store.d.ts +29 -0
- package/dist/store/replay-store.d.ts.map +1 -0
- package/dist/store/replay-store.js +31 -0
- package/dist/store/replay-store.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// openai-provider.ts — OpenAI LLM provider implementation for realm agent.
|
|
2
|
+
// Requires openai >= 4.0.0 as an optional peer dependency (npm install openai).
|
|
3
|
+
import { WorkflowError } from '@sensigo/realm';
|
|
4
|
+
import { ToolCapableLlmProvider } from './llm-provider.js';
|
|
5
|
+
import { sanitizeError, serializeToolResult, parseNamespacedId, tryParseJson, validateSchema, rejectAfter, buildSystemPrompt, } from './agent-utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* OpenAI LLM provider for realm agent.
|
|
8
|
+
* Uses the Chat Completions API. Sends `response_format: json_object` on native
|
|
9
|
+
* OpenAI endpoints; falls back to prompt-only JSON enforcement on compat endpoints
|
|
10
|
+
* behind `--base-url`. Retries once if the model returns non-JSON content.
|
|
11
|
+
*/
|
|
12
|
+
export class OpenAIProvider extends ToolCapableLlmProvider {
|
|
13
|
+
model;
|
|
14
|
+
baseUrl;
|
|
15
|
+
constructor(model, baseUrl) {
|
|
16
|
+
super();
|
|
17
|
+
this.model = model;
|
|
18
|
+
this.baseUrl = baseUrl;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Native OpenAI endpoints have a well-defined, tested capability surface that includes
|
|
22
|
+
* json_object mode. Custom compat endpoints behind --base-url do not guarantee this feature.
|
|
23
|
+
* Default to prompt-only enforcement for any unknown endpoint.
|
|
24
|
+
*/
|
|
25
|
+
capabilities() {
|
|
26
|
+
return { jsonMode: this.baseUrl === undefined };
|
|
27
|
+
}
|
|
28
|
+
async callStep(prompt, inputSchema) {
|
|
29
|
+
// Dynamically import openai to keep it an optional peer dependency.
|
|
30
|
+
// Assigning the module specifier to a typed variable via 'string' makes TS
|
|
31
|
+
// treat it as Promise<any>, bypassing static module resolution at build time.
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
let mod;
|
|
34
|
+
try {
|
|
35
|
+
const moduleId = 'openai';
|
|
36
|
+
mod = await import(moduleId);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
console.error('realm agent requires the openai package. Run: npm install openai');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
const client = new mod.default({
|
|
44
|
+
apiKey: process.env['OPENAI_API_KEY'],
|
|
45
|
+
...(this.baseUrl !== undefined ? { baseURL: this.baseUrl } : {}),
|
|
46
|
+
});
|
|
47
|
+
const systemPrompt = buildSystemPrompt(inputSchema);
|
|
48
|
+
const messages = [
|
|
49
|
+
{ role: 'system', content: systemPrompt },
|
|
50
|
+
{ role: 'user', content: prompt },
|
|
51
|
+
];
|
|
52
|
+
const makeRequest = async (msgs) => {
|
|
53
|
+
const opts = {
|
|
54
|
+
model: this.model,
|
|
55
|
+
messages: msgs,
|
|
56
|
+
};
|
|
57
|
+
if (this.capabilities().jsonMode) {
|
|
58
|
+
opts['response_format'] = { type: 'json_object' };
|
|
59
|
+
}
|
|
60
|
+
const response = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
+
client.chat.completions.create(opts);
|
|
62
|
+
return response.choices[0]?.message?.content ?? '';
|
|
63
|
+
};
|
|
64
|
+
const content = await makeRequest(messages);
|
|
65
|
+
try {
|
|
66
|
+
return JSON.parse(content);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Retry once with an explicit reminder to return JSON.
|
|
70
|
+
const retryMessages = [
|
|
71
|
+
...messages,
|
|
72
|
+
{ role: 'assistant', content },
|
|
73
|
+
{
|
|
74
|
+
role: 'user',
|
|
75
|
+
content: 'Your previous response was not valid JSON. Respond with a JSON object only.',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
const retry = await makeRequest(retryMessages);
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(retry);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
throw new Error(`OpenAI returned non-JSON content after retry: ${retry.slice(0, 200)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Agentic loop for tool-capable steps. Executes tool calls serially (V1 constraint)
|
|
89
|
+
* until the model returns a final JSON answer or the tool call budget is exhausted.
|
|
90
|
+
*/
|
|
91
|
+
async callStepWithTools(prompt, tools, executor, options) {
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
|
+
let mod;
|
|
94
|
+
try {
|
|
95
|
+
const moduleId = 'openai';
|
|
96
|
+
mod = await import(moduleId);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
console.error('realm agent requires the openai package. Run: npm install openai');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
|
+
const client = new mod.default({
|
|
104
|
+
apiKey: process.env['OPENAI_API_KEY'],
|
|
105
|
+
...(this.baseUrl !== undefined ? { baseURL: this.baseUrl } : {}),
|
|
106
|
+
});
|
|
107
|
+
const responseFormat = this.capabilities().jsonMode && options.inputSchema !== undefined
|
|
108
|
+
? { type: 'json_object' }
|
|
109
|
+
: undefined;
|
|
110
|
+
// toolIdMap: bareName → namespaced id, used to recover routing key from LLM responses.
|
|
111
|
+
// Collision guard: two MCP servers may not expose the same bare tool name in the same step.
|
|
112
|
+
const toolIdMap = new Map();
|
|
113
|
+
const openaiTools = [];
|
|
114
|
+
for (const tool of tools) {
|
|
115
|
+
if (toolIdMap.has(tool.name)) {
|
|
116
|
+
throw new Error(`invariant: duplicate bare tool name '${tool.name}' in toolIdMap — this should have been caught at toolDefs assembly in run-agent.ts`);
|
|
117
|
+
}
|
|
118
|
+
toolIdMap.set(tool.name, tool.id);
|
|
119
|
+
openaiTools.push({
|
|
120
|
+
type: 'function',
|
|
121
|
+
function: {
|
|
122
|
+
name: tool.name,
|
|
123
|
+
description: tool.description,
|
|
124
|
+
parameters: tool.inputSchema,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const maxCalls = options.maxToolCalls ?? 20;
|
|
129
|
+
let tool_call_count = 0;
|
|
130
|
+
const tool_call_records = [];
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
const history = [
|
|
133
|
+
{ role: 'system', content: buildSystemPrompt(options.inputSchema) },
|
|
134
|
+
{ role: 'user', content: prompt },
|
|
135
|
+
];
|
|
136
|
+
const buildMainCallOpts = () => {
|
|
137
|
+
const opts = { model: this.model, messages: history };
|
|
138
|
+
if (openaiTools.length > 0)
|
|
139
|
+
opts['tools'] = openaiTools;
|
|
140
|
+
if (responseFormat !== undefined)
|
|
141
|
+
opts['response_format'] = responseFormat;
|
|
142
|
+
return opts;
|
|
143
|
+
};
|
|
144
|
+
const buildFinalCallOpts = () => {
|
|
145
|
+
const opts = { model: this.model, messages: history };
|
|
146
|
+
if (responseFormat !== undefined)
|
|
147
|
+
opts['response_format'] = responseFormat;
|
|
148
|
+
return opts;
|
|
149
|
+
};
|
|
150
|
+
// Injects the over-budget message and calls the API without tools to produce a final answer.
|
|
151
|
+
const performFinalExtraction = async () => {
|
|
152
|
+
history.push({
|
|
153
|
+
role: 'user',
|
|
154
|
+
content: 'You have reached the maximum number of tool calls. Produce your final JSON answer now using only what you have already gathered. No further tool calls will be executed.',
|
|
155
|
+
});
|
|
156
|
+
const final = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
157
|
+
client.chat.completions.create(buildFinalCallOpts());
|
|
158
|
+
const text = final.choices[0].message.content ?? '';
|
|
159
|
+
const parsed = tryParseJson(text);
|
|
160
|
+
if (parsed && validateSchema(parsed, options.inputSchema)) {
|
|
161
|
+
return { output: parsed, toolCalls: tool_call_records };
|
|
162
|
+
}
|
|
163
|
+
throw new WorkflowError('max_tool_calls reached; final extraction failed', {
|
|
164
|
+
code: 'ENGINE_STEP_FAILED',
|
|
165
|
+
category: 'ENGINE',
|
|
166
|
+
agentAction: 'stop',
|
|
167
|
+
retryable: false,
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
while (true) {
|
|
171
|
+
const response = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
172
|
+
client.chat.completions.create(buildMainCallOpts());
|
|
173
|
+
const message = response.choices[0].message;
|
|
174
|
+
if (message.tool_calls?.length) {
|
|
175
|
+
const batch = message.tool_calls;
|
|
176
|
+
history.push(message);
|
|
177
|
+
let budget_exhausted_mid_batch = false;
|
|
178
|
+
for (const tool of batch) {
|
|
179
|
+
const llmToolCallId = tool.id; // captured verbatim — API returns 400 if echoed incorrectly
|
|
180
|
+
if (tool_call_count >= maxCalls) {
|
|
181
|
+
// Budget exhausted — must still answer every id in the assistant message.
|
|
182
|
+
history.push({
|
|
183
|
+
role: 'tool',
|
|
184
|
+
tool_call_id: llmToolCallId,
|
|
185
|
+
content: 'Error: tool call budget exhausted',
|
|
186
|
+
});
|
|
187
|
+
budget_exhausted_mid_batch = true;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const originalId = toolIdMap.get(tool.function.name);
|
|
191
|
+
const { serverId, toolName } = parseNamespacedId(originalId);
|
|
192
|
+
const args = JSON.parse(tool.function.arguments || '{}');
|
|
193
|
+
const start = Date.now();
|
|
194
|
+
let resultContent;
|
|
195
|
+
let record;
|
|
196
|
+
try {
|
|
197
|
+
const rawResult = await Promise.race([
|
|
198
|
+
executor(originalId, args),
|
|
199
|
+
rejectAfter(options.toolTimeoutMs ?? 30000),
|
|
200
|
+
]);
|
|
201
|
+
const serialized = serializeToolResult(rawResult);
|
|
202
|
+
record = {
|
|
203
|
+
server_id: serverId,
|
|
204
|
+
tool: toolName,
|
|
205
|
+
args,
|
|
206
|
+
result: serialized,
|
|
207
|
+
duration_ms: Date.now() - start,
|
|
208
|
+
};
|
|
209
|
+
resultContent = serialized;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
const sanitized = sanitizeError(err);
|
|
213
|
+
const content = sanitized.length > 0 ? `Error: ${sanitized}` : 'Error: (redacted)';
|
|
214
|
+
record = {
|
|
215
|
+
server_id: serverId,
|
|
216
|
+
tool: toolName,
|
|
217
|
+
args,
|
|
218
|
+
result: null,
|
|
219
|
+
duration_ms: Date.now() - start,
|
|
220
|
+
error: sanitized,
|
|
221
|
+
};
|
|
222
|
+
resultContent = content;
|
|
223
|
+
}
|
|
224
|
+
tool_call_records.push(record);
|
|
225
|
+
tool_call_count++;
|
|
226
|
+
history.push({ role: 'tool', tool_call_id: llmToolCallId, content: resultContent });
|
|
227
|
+
}
|
|
228
|
+
if (budget_exhausted_mid_batch || tool_call_count >= maxCalls) {
|
|
229
|
+
return performFinalExtraction();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// No tool calls — attempt to parse the final answer.
|
|
234
|
+
const text = message.content ?? '';
|
|
235
|
+
const parsed = tryParseJson(text);
|
|
236
|
+
if (parsed && validateSchema(parsed, options.inputSchema)) {
|
|
237
|
+
return { output: parsed, toolCalls: tool_call_records };
|
|
238
|
+
}
|
|
239
|
+
// Schema mismatch — append correction message and continue the loop.
|
|
240
|
+
history.push({ role: 'assistant', content: text });
|
|
241
|
+
history.push({
|
|
242
|
+
role: 'user',
|
|
243
|
+
content: 'Your response did not match the required JSON schema. Try again.',
|
|
244
|
+
});
|
|
245
|
+
tool_call_count++; // schema correction consumes a slot
|
|
246
|
+
if (tool_call_count >= maxCalls) {
|
|
247
|
+
return performFinalExtraction();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../src/agent/openai-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LlmProvider } from './llm-provider.js';
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI reasoning model provider for realm agent.
|
|
4
|
+
* Handles the o1/o3 model families, which differ from standard chat completions:
|
|
5
|
+
* - No `response_format` parameter (JSON enforced via system prompt + retry).
|
|
6
|
+
* - System prompt content is folded into the first user message — the safe
|
|
7
|
+
* universal approach for the full o1/o3 lineage. (o1 originally rejected the
|
|
8
|
+
* system role; later versions accept it as a developer role, but prepending
|
|
9
|
+
* to the user message works uniformly across all revisions.)
|
|
10
|
+
* - Tool calling is not supported — this class extends LlmProvider, not
|
|
11
|
+
* ToolCapableLlmProvider, so `isToolCapable` returns false for these instances.
|
|
12
|
+
*/
|
|
13
|
+
export declare class OpenAIReasoningProvider extends LlmProvider {
|
|
14
|
+
private readonly model;
|
|
15
|
+
constructor(model: string);
|
|
16
|
+
callStep(prompt: string, inputSchema?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=openai-reasoning-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-reasoning-provider.d.ts","sourceRoot":"","sources":["../../src/agent/openai-reasoning-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,SAAQ,WAAW;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,KAAK,EAAE,MAAM;IAKnB,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAwDpC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// openai-reasoning-provider.ts — OpenAI reasoning model provider (o1/o3) for realm agent.
|
|
2
|
+
// Extends LlmProvider (not ToolCapableLlmProvider) — reasoning models do not support the tools parameter.
|
|
3
|
+
import { LlmProvider } from './llm-provider.js';
|
|
4
|
+
import { buildSystemPrompt } from './agent-utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* OpenAI reasoning model provider for realm agent.
|
|
7
|
+
* Handles the o1/o3 model families, which differ from standard chat completions:
|
|
8
|
+
* - No `response_format` parameter (JSON enforced via system prompt + retry).
|
|
9
|
+
* - System prompt content is folded into the first user message — the safe
|
|
10
|
+
* universal approach for the full o1/o3 lineage. (o1 originally rejected the
|
|
11
|
+
* system role; later versions accept it as a developer role, but prepending
|
|
12
|
+
* to the user message works uniformly across all revisions.)
|
|
13
|
+
* - Tool calling is not supported — this class extends LlmProvider, not
|
|
14
|
+
* ToolCapableLlmProvider, so `isToolCapable` returns false for these instances.
|
|
15
|
+
*/
|
|
16
|
+
export class OpenAIReasoningProvider extends LlmProvider {
|
|
17
|
+
model;
|
|
18
|
+
constructor(model) {
|
|
19
|
+
super();
|
|
20
|
+
this.model = model;
|
|
21
|
+
}
|
|
22
|
+
async callStep(prompt, inputSchema) {
|
|
23
|
+
// Dynamically import openai to keep it an optional peer dependency.
|
|
24
|
+
// Assigning the module specifier to a typed variable via 'string' makes TS
|
|
25
|
+
// treat it as Promise<any>, bypassing static module resolution at build time.
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
let mod;
|
|
28
|
+
try {
|
|
29
|
+
const moduleId = 'openai';
|
|
30
|
+
mod = await import(moduleId);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
console.error('realm agent requires the openai package. Run: npm install openai');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
const client = new mod.default({
|
|
38
|
+
apiKey: process.env['OPENAI_API_KEY'],
|
|
39
|
+
});
|
|
40
|
+
// Fold system prompt into the user message — safe for all o1/o3 API revisions.
|
|
41
|
+
const systemPrompt = buildSystemPrompt(inputSchema);
|
|
42
|
+
const userContent = `${systemPrompt}\n\n${prompt}`;
|
|
43
|
+
const messages = [{ role: 'user', content: userContent }];
|
|
44
|
+
const makeRequest = async (msgs) => {
|
|
45
|
+
const response = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
client.chat.completions.create({
|
|
47
|
+
model: this.model,
|
|
48
|
+
messages: msgs,
|
|
49
|
+
});
|
|
50
|
+
return response.choices[0]?.message?.content ?? '';
|
|
51
|
+
};
|
|
52
|
+
const content = await makeRequest(messages);
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(content);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Retry once with an explicit reminder to return JSON.
|
|
58
|
+
const retryMessages = [
|
|
59
|
+
...messages,
|
|
60
|
+
{ role: 'assistant', content },
|
|
61
|
+
{
|
|
62
|
+
role: 'user',
|
|
63
|
+
content: 'Your previous response was not valid JSON. Respond with a JSON object only.',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
const retry = await makeRequest(retryMessages);
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(retry);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
throw new Error(`OpenAI returned non-JSON content after retry: ${retry.slice(0, 200)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=openai-reasoning-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-reasoning-provider.js","sourceRoot":"","sources":["../../src/agent/openai-reasoning-provider.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,0GAA0G;AAC1G,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,uBAAwB,SAAQ,WAAW;IACrC,KAAK,CAAS;IAE/B,YAAY,KAAa;QACvB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,MAAc,EACd,WAAqC;QAErC,oEAAoE;QACpE,2EAA2E;QAC3E,8EAA8E;QAC9E,8DAA8D;QAC9D,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAW,QAAQ,CAAC;YAClC,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,8DAA8D;QAC9D,MAAM,MAAM,GAAG,IAAK,GAAG,CAAC,OAAsD,CAAC;YAC7E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;SACtC,CAAC,CAAC;QAEH,+EAA+E;QAC/E,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,GAAG,YAAY,OAAO,MAAM,EAAE,CAAC;QAGnD,MAAM,QAAQ,GAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAErE,MAAM,WAAW,GAAG,KAAK,EAAE,IAAe,EAAmB,EAAE;YAC7D,MAAM,QAAQ,GAAG,MAAM,8DAA8D;aACpF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAA0D,CAAC;gBAClF,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,OAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAA8B,IAAI,EAAE,CAAC;QAC7E,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;YACvD,MAAM,aAAa,GAAc;gBAC/B,GAAG,QAAQ;gBACX,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE;gBAC9B;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,6EAA6E;iBACvF;aACF,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC;YAC/C,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAA4B,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,iDAAiD,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { WorkflowDefinition } from '@sensigo/realm';
|
|
2
|
+
export interface PreflightFinding {
|
|
3
|
+
/** Service name from the workflow definition. */
|
|
4
|
+
serviceName: string;
|
|
5
|
+
/** Adapter name (e.g. 'github', 'slack'). */
|
|
6
|
+
adapter: string;
|
|
7
|
+
/** Name of the missing environment variable. */
|
|
8
|
+
missingVar: string;
|
|
9
|
+
/** Ready-to-paste export command for the missing variable. */
|
|
10
|
+
exportExample: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inspects the workflow's `services` block and returns a finding for each
|
|
14
|
+
* built-in adapter whose required environment variable is absent from env.
|
|
15
|
+
* Returns an empty array when all prerequisites are satisfied.
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkAdapterPrerequisites(definition: WorkflowDefinition, env?: NodeJS.ProcessEnv): PreflightFinding[];
|
|
18
|
+
/**
|
|
19
|
+
* Formats preflight findings into a multi-line actionable error message.
|
|
20
|
+
* Does not include secrets or values — only variable names and export examples.
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatPreflightError(findings: PreflightFinding[]): string;
|
|
23
|
+
/** An advisory (non-blocking) Slack configuration warning. */
|
|
24
|
+
export interface PreflightWarning {
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Checks for incomplete Slack bidirectional configuration and returns advisory warnings.
|
|
29
|
+
* These are non-blocking — the run proceeds but with degraded Slack functionality.
|
|
30
|
+
*
|
|
31
|
+
* Bidirectional resolution requires SLACK_BOT_TOKEN + SLACK_CHANNEL_ID and at least one of:
|
|
32
|
+
* - SLACK_APP_TOKEN (Socket Mode — WebSocket push, no public URL required)
|
|
33
|
+
* - SLACK_SIGNING_SECRET (Events API — HTTP push, requires public URL)
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkSlackBidirectionalConfig(env?: NodeJS.ProcessEnv): PreflightWarning[];
|
|
36
|
+
//# sourceMappingURL=preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/agent/preflight.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAczD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,gBAAgB,EAAE,CAepB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAUzE;AAED,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,gBAAgB,EAAE,CAgCpB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Maps adapter name to the env var it requires. */
|
|
2
|
+
const ADAPTER_ENV_REQS = {
|
|
3
|
+
github: {
|
|
4
|
+
envVar: 'GITHUB_TOKEN',
|
|
5
|
+
exportExample: 'export GITHUB_TOKEN=ghp_...',
|
|
6
|
+
},
|
|
7
|
+
slack: {
|
|
8
|
+
envVar: 'SLACK_WEBHOOK_URL',
|
|
9
|
+
exportExample: 'export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...',
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Inspects the workflow's `services` block and returns a finding for each
|
|
14
|
+
* built-in adapter whose required environment variable is absent from env.
|
|
15
|
+
* Returns an empty array when all prerequisites are satisfied.
|
|
16
|
+
*/
|
|
17
|
+
export function checkAdapterPrerequisites(definition, env = process.env) {
|
|
18
|
+
const findings = [];
|
|
19
|
+
for (const [serviceName, serviceDef] of Object.entries(definition.services ?? {})) {
|
|
20
|
+
const req = ADAPTER_ENV_REQS[serviceDef.adapter];
|
|
21
|
+
if (req === undefined)
|
|
22
|
+
continue;
|
|
23
|
+
if (env[req.envVar] === undefined) {
|
|
24
|
+
findings.push({
|
|
25
|
+
serviceName,
|
|
26
|
+
adapter: serviceDef.adapter,
|
|
27
|
+
missingVar: req.envVar,
|
|
28
|
+
exportExample: req.exportExample,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return findings;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Formats preflight findings into a multi-line actionable error message.
|
|
36
|
+
* Does not include secrets or values — only variable names and export examples.
|
|
37
|
+
*/
|
|
38
|
+
export function formatPreflightError(findings) {
|
|
39
|
+
const lines = ['Error: Missing required environment variables for workflow services:'];
|
|
40
|
+
for (const f of findings) {
|
|
41
|
+
lines.push(` - service '${f.serviceName}' (adapter '${f.adapter}'): ${f.missingVar}`);
|
|
42
|
+
}
|
|
43
|
+
lines.push('', 'Set and retry:');
|
|
44
|
+
for (const f of findings) {
|
|
45
|
+
lines.push(` ${f.exportExample}`);
|
|
46
|
+
}
|
|
47
|
+
return lines.join('\n');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Checks for incomplete Slack bidirectional configuration and returns advisory warnings.
|
|
51
|
+
* These are non-blocking — the run proceeds but with degraded Slack functionality.
|
|
52
|
+
*
|
|
53
|
+
* Bidirectional resolution requires SLACK_BOT_TOKEN + SLACK_CHANNEL_ID and at least one of:
|
|
54
|
+
* - SLACK_APP_TOKEN (Socket Mode — WebSocket push, no public URL required)
|
|
55
|
+
* - SLACK_SIGNING_SECRET (Events API — HTTP push, requires public URL)
|
|
56
|
+
*/
|
|
57
|
+
export function checkSlackBidirectionalConfig(env = process.env) {
|
|
58
|
+
const warnings = [];
|
|
59
|
+
if (env['SLACK_WEBHOOK_URL'] !== undefined && env['SLACK_BOT_TOKEN'] === undefined) {
|
|
60
|
+
warnings.push({
|
|
61
|
+
message: 'SLACK_WEBHOOK_URL is set but SLACK_BOT_TOKEN is not. Gate replies cannot be received from Slack — approval requires the terminal command.',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (env['SLACK_BOT_TOKEN'] !== undefined &&
|
|
65
|
+
env['SLACK_APP_TOKEN'] === undefined &&
|
|
66
|
+
env['SLACK_SIGNING_SECRET'] === undefined) {
|
|
67
|
+
warnings.push({
|
|
68
|
+
message: 'SLACK_BOT_TOKEN is set but neither SLACK_APP_TOKEN nor SLACK_SIGNING_SECRET is set. ' +
|
|
69
|
+
'Gate replies cannot be resolved automatically from Slack — set SLACK_APP_TOKEN (Socket Mode, recommended) ' +
|
|
70
|
+
'or SLACK_SIGNING_SECRET (Events API) to enable automatic resolution.',
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (env['SLACK_APP_TOKEN'] !== undefined && env['SLACK_SIGNING_SECRET'] !== undefined) {
|
|
74
|
+
warnings.push({
|
|
75
|
+
message: 'Both SLACK_APP_TOKEN and SLACK_SIGNING_SECRET are set — Socket Mode (Mode 2) takes precedence. ' +
|
|
76
|
+
'Remove SLACK_APP_TOKEN to use Events API (Mode 3).',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return warnings;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../src/agent/preflight.ts"],"names":[],"mappings":"AAIA,oDAAoD;AACpD,MAAM,gBAAgB,GAA8D;IAClF,MAAM,EAAE;QACN,MAAM,EAAE,cAAc;QACtB,aAAa,EAAE,6BAA6B;KAC7C;IACD,KAAK,EAAE;QACL,MAAM,EAAE,mBAAmB;QAC3B,aAAa,EAAE,+DAA+D;KAC/E;CACF,CAAC;AAaF;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAA8B,EAC9B,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QAClF,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACZ,WAAW;gBACX,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,UAAU,EAAE,GAAG,CAAC,MAAM;gBACtB,aAAa,EAAE,GAAG,CAAC,aAAa;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAA4B;IAC/D,MAAM,KAAK,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACvF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,WAAW,eAAe,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAOD;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAC3C,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,IAAI,GAAG,CAAC,mBAAmB,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,iBAAiB,CAAC,KAAK,SAAS,EAAE,CAAC;QACnF,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO,EACL,2IAA2I;SAC9I,CAAC,CAAC;IACL,CAAC;IAED,IACE,GAAG,CAAC,iBAAiB,CAAC,KAAK,SAAS;QACpC,GAAG,CAAC,iBAAiB,CAAC,KAAK,SAAS;QACpC,GAAG,CAAC,sBAAsB,CAAC,KAAK,SAAS,EACzC,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO,EACL,sFAAsF;gBACtF,4GAA4G;gBAC5G,sEAAsE;SACzE,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,iBAAiB,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,sBAAsB,CAAC,KAAK,SAAS,EAAE,CAAC;QACtF,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO,EACL,iGAAiG;gBACjG,oDAAoD;SACvD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Builds the system prompt for an agent step, optionally including the output schema. */
|
|
2
|
+
export declare function buildSystemPrompt(inputSchema?: Record<string, unknown>): string;
|
|
3
|
+
/**
|
|
4
|
+
* Converts an error value to a string and strips sensitive patterns:
|
|
5
|
+
* Bearer tokens, query-string tokens, and any process.env value longer than 4 characters.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sanitizeError(err: unknown): string;
|
|
8
|
+
/**
|
|
9
|
+
* Serializes an MCP tool result to a string and applies the same sanitization pass
|
|
10
|
+
* as sanitizeError to strip any tokens that upstream services may have echoed.
|
|
11
|
+
*/
|
|
12
|
+
export declare function serializeToolResult(result: unknown): string;
|
|
13
|
+
/** Splits "server_id:tool_name" into its components. Throws if the format is invalid. */
|
|
14
|
+
export declare function parseNamespacedId(id: string): {
|
|
15
|
+
serverId: string;
|
|
16
|
+
toolName: string;
|
|
17
|
+
};
|
|
18
|
+
/** Tries to parse JSON; returns a plain object or null if parsing fails or the result is not an object. */
|
|
19
|
+
export declare function tryParseJson(text: string): Record<string, unknown> | null;
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if all required properties from the schema are present in the parsed object.
|
|
22
|
+
* Returns true when no schema is provided.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateSchema(parsed: Record<string, unknown>, schema?: Record<string, unknown>): boolean;
|
|
25
|
+
/** Returns a Promise that rejects with a timeout error after `ms` milliseconds. */
|
|
26
|
+
export declare function rejectAfter(ms: number): Promise<never>;
|
|
27
|
+
//# sourceMappingURL=agent-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-utils.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/agent-utils.ts"],"names":[],"mappings":"AAMA,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAG/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAiBlD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAG3D;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAMpF;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUzE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAKT;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAItD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// agent-utils.ts — Shared utility functions for LLM provider agentic loops.
|
|
2
|
+
const SYSTEM_PROMPT_BASE = 'You are an AI agent executing a step in a structured workflow.\n' +
|
|
3
|
+
'Your task is described below. Respond with a JSON object only — no markdown, no explanation.';
|
|
4
|
+
/** Builds the system prompt for an agent step, optionally including the output schema. */
|
|
5
|
+
export function buildSystemPrompt(inputSchema) {
|
|
6
|
+
if (inputSchema === undefined)
|
|
7
|
+
return SYSTEM_PROMPT_BASE;
|
|
8
|
+
return `${SYSTEM_PROMPT_BASE}\nThe JSON must conform to this schema: ${JSON.stringify(inputSchema)}`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Converts an error value to a string and strips sensitive patterns:
|
|
12
|
+
* Bearer tokens, query-string tokens, and any process.env value longer than 4 characters.
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeError(err) {
|
|
15
|
+
let text;
|
|
16
|
+
if (err instanceof Error) {
|
|
17
|
+
text = err.message;
|
|
18
|
+
}
|
|
19
|
+
else if (typeof err === 'string') {
|
|
20
|
+
text = err;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
text = String(err);
|
|
24
|
+
}
|
|
25
|
+
text = text.replace(/Bearer [A-Za-z0-9._-]+/g, 'Bearer [REDACTED]');
|
|
26
|
+
text = text.replace(/token=[A-Za-z0-9._-]+/g, 'token=[REDACTED]');
|
|
27
|
+
for (const val of Object.values(process.env)) {
|
|
28
|
+
if (val !== undefined && val.length > 4) {
|
|
29
|
+
text = text.split(val).join('[REDACTED]');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return text;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Serializes an MCP tool result to a string and applies the same sanitization pass
|
|
36
|
+
* as sanitizeError to strip any tokens that upstream services may have echoed.
|
|
37
|
+
*/
|
|
38
|
+
export function serializeToolResult(result) {
|
|
39
|
+
const raw = typeof result === 'string' ? result : JSON.stringify(result);
|
|
40
|
+
return sanitizeError(raw);
|
|
41
|
+
}
|
|
42
|
+
/** Splits "server_id:tool_name" into its components. Throws if the format is invalid. */
|
|
43
|
+
export function parseNamespacedId(id) {
|
|
44
|
+
const colonIdx = id.indexOf(':');
|
|
45
|
+
if (colonIdx === -1) {
|
|
46
|
+
throw new Error(`Invalid namespaced tool id '${id}' (expected format: 'serverId:toolName')`);
|
|
47
|
+
}
|
|
48
|
+
return { serverId: id.slice(0, colonIdx), toolName: id.slice(colonIdx + 1) };
|
|
49
|
+
}
|
|
50
|
+
/** Tries to parse JSON; returns a plain object or null if parsing fails or the result is not an object. */
|
|
51
|
+
export function tryParseJson(text) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(text);
|
|
54
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if all required properties from the schema are present in the parsed object.
|
|
65
|
+
* Returns true when no schema is provided.
|
|
66
|
+
*/
|
|
67
|
+
export function validateSchema(parsed, schema) {
|
|
68
|
+
if (!schema)
|
|
69
|
+
return true;
|
|
70
|
+
const required = schema['required'];
|
|
71
|
+
if (!Array.isArray(required))
|
|
72
|
+
return true;
|
|
73
|
+
return required.every((key) => typeof key === 'string' && key in parsed);
|
|
74
|
+
}
|
|
75
|
+
/** Returns a Promise that rejects with a timeout error after `ms` milliseconds. */
|
|
76
|
+
export function rejectAfter(ms) {
|
|
77
|
+
return new Promise((_, reject) => setTimeout(() => reject(new Error(`tool call timed out after ${ms}ms`)), ms));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=agent-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-utils.js","sourceRoot":"","sources":["../../../src/agent/providers/agent-utils.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,MAAM,kBAAkB,GACtB,kEAAkE;IAClE,8FAA8F,CAAC;AAEjG,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,WAAqC;IACrE,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,kBAAkB,CAAC;IACzD,OAAO,GAAG,kBAAkB,2CAA2C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;AACvG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,IAAY,CAAC;IACjB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;SAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,GAAG,GAAG,CAAC;IACb,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;IACpE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;IAClE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,0CAA0C,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5E,OAAO,MAAiC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,MAA+B,EAC/B,MAAgC;IAEhC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAQ,QAAsB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC;AAC1F,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACtC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ToolCapableLlmProvider } from './llm-provider.js';
|
|
2
|
+
import type { ToolDefinition, ToolExecutor, StepWithToolsResult } from '../mcp/mcp-extensions.js';
|
|
3
|
+
/**
|
|
4
|
+
* Anthropic LLM provider for realm agent.
|
|
5
|
+
* Uses the Messages API and extracts JSON from the first text content block.
|
|
6
|
+
* Retries once if the model returns non-JSON content.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AnthropicProvider extends ToolCapableLlmProvider {
|
|
9
|
+
private readonly model;
|
|
10
|
+
constructor(model: string);
|
|
11
|
+
callStep(prompt: string, inputSchema?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
12
|
+
/**
|
|
13
|
+
* Agentic loop for tool-capable steps. Executes tool calls serially (V1 constraint).
|
|
14
|
+
* All tool results for one turn are accumulated into a single user message with an array
|
|
15
|
+
* of tool_result blocks — the Anthropic API rejects interleaved assistant/user turns.
|
|
16
|
+
*/
|
|
17
|
+
callStepWithTools(prompt: string, tools: ToolDefinition[], executor: ToolExecutor, options: {
|
|
18
|
+
inputSchema?: Record<string, unknown>;
|
|
19
|
+
maxToolCalls?: number;
|
|
20
|
+
toolTimeoutMs?: number;
|
|
21
|
+
}): Promise<StepWithToolsResult>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=anthropic-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../../src/agent/providers/anthropic-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAEV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAuBlC;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IAIpC,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoDnC;;;;OAIG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EAAE,EACvB,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,OAAO,CAAC,mBAAmB,CAAC;CAiNhC"}
|