reasonix 0.4.3 → 0.4.5
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/cli/index.js +161 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +95 -4
- package/dist/index.js +97 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -366,7 +366,7 @@ declare class ToolCallRepair {
|
|
|
366
366
|
private readonly storm;
|
|
367
367
|
private readonly opts;
|
|
368
368
|
constructor(opts: ToolCallRepairOptions);
|
|
369
|
-
process(declaredCalls: ToolCall[], reasoningContent: string | null): {
|
|
369
|
+
process(declaredCalls: ToolCall[], reasoningContent: string | null, content?: string | null): {
|
|
370
370
|
calls: ToolCall[];
|
|
371
371
|
report: RepairReport;
|
|
372
372
|
};
|
|
@@ -901,8 +901,9 @@ declare function renderMarkdown(report: DiffReport): string;
|
|
|
901
901
|
* insulated as long as we keep up with the spec itself.
|
|
902
902
|
*
|
|
903
903
|
* Spec reference: https://spec.modelcontextprotocol.io/ (2024-11-05 draft
|
|
904
|
-
* at time of writing).
|
|
905
|
-
*
|
|
904
|
+
* at time of writing). Reasonix models the subset it consumes: tools
|
|
905
|
+
* list/call, resources list/read, prompts list/get, plus the init
|
|
906
|
+
* handshake. Sampling and progress notifications remain deferred.
|
|
906
907
|
*
|
|
907
908
|
* Transport note: the wire format for stdio MCP is **newline-delimited
|
|
908
909
|
* JSON** (NDJSON), not the LSP-style Content-Length header framing that
|
|
@@ -989,6 +990,78 @@ interface CallToolResult {
|
|
|
989
990
|
/** True = tool raised an error; the content describes it. */
|
|
990
991
|
isError?: boolean;
|
|
991
992
|
}
|
|
993
|
+
/**
|
|
994
|
+
* A resource the server can expose — think "file the model can read."
|
|
995
|
+
* The URI is opaque to the client: servers may use `file://`, custom
|
|
996
|
+
* schemes, or bare strings. Reasonix doesn't interpret them.
|
|
997
|
+
*/
|
|
998
|
+
interface McpResource {
|
|
999
|
+
uri: string;
|
|
1000
|
+
name: string;
|
|
1001
|
+
description?: string;
|
|
1002
|
+
/** Hint for the content type (e.g. "text/markdown"). Purely informational. */
|
|
1003
|
+
mimeType?: string;
|
|
1004
|
+
}
|
|
1005
|
+
interface ListResourcesResult {
|
|
1006
|
+
resources: McpResource[];
|
|
1007
|
+
nextCursor?: string;
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* One resource can return multiple content blobs (e.g. the file + a
|
|
1011
|
+
* side-car). `text` is the common case for UTF-8 content; `blob` is
|
|
1012
|
+
* base64-encoded bytes for binary content. Servers populate exactly
|
|
1013
|
+
* one of the two for each entry.
|
|
1014
|
+
*/
|
|
1015
|
+
interface McpResourceContentsText {
|
|
1016
|
+
uri: string;
|
|
1017
|
+
mimeType?: string;
|
|
1018
|
+
text: string;
|
|
1019
|
+
}
|
|
1020
|
+
interface McpResourceContentsBlob {
|
|
1021
|
+
uri: string;
|
|
1022
|
+
mimeType?: string;
|
|
1023
|
+
blob: string;
|
|
1024
|
+
}
|
|
1025
|
+
type McpResourceContents = McpResourceContentsText | McpResourceContentsBlob;
|
|
1026
|
+
interface ReadResourceResult {
|
|
1027
|
+
contents: McpResourceContents[];
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* A parameterizable prompt template the server exposes. Clients fetch
|
|
1031
|
+
* it with `prompts/get` and pass the result to the model as-is.
|
|
1032
|
+
*/
|
|
1033
|
+
interface McpPromptArgument {
|
|
1034
|
+
name: string;
|
|
1035
|
+
description?: string;
|
|
1036
|
+
required?: boolean;
|
|
1037
|
+
}
|
|
1038
|
+
interface McpPrompt {
|
|
1039
|
+
name: string;
|
|
1040
|
+
description?: string;
|
|
1041
|
+
arguments?: McpPromptArgument[];
|
|
1042
|
+
}
|
|
1043
|
+
interface ListPromptsResult {
|
|
1044
|
+
prompts: McpPrompt[];
|
|
1045
|
+
nextCursor?: string;
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* MCP prompt messages are modeled after chat completions: role + content.
|
|
1049
|
+
* Content can be a text block OR (per the spec) a resource/image block;
|
|
1050
|
+
* Reasonix cares about text in v1, but surfaces the raw array so callers
|
|
1051
|
+
* can render other kinds if they need to.
|
|
1052
|
+
*/
|
|
1053
|
+
interface McpPromptMessage {
|
|
1054
|
+
role: "user" | "assistant";
|
|
1055
|
+
content: McpContentBlock | McpPromptResourceBlock;
|
|
1056
|
+
}
|
|
1057
|
+
interface McpPromptResourceBlock {
|
|
1058
|
+
type: "resource";
|
|
1059
|
+
resource: McpResourceContents;
|
|
1060
|
+
}
|
|
1061
|
+
interface GetPromptResult {
|
|
1062
|
+
description?: string;
|
|
1063
|
+
messages: McpPromptMessage[];
|
|
1064
|
+
}
|
|
992
1065
|
/** Current MCP protocol version Reasonix is coded against. */
|
|
993
1066
|
declare const MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
994
1067
|
/** Type guard — success vs error response. */
|
|
@@ -1091,6 +1164,24 @@ declare class McpClient {
|
|
|
1091
1164
|
listTools(): Promise<ListToolsResult>;
|
|
1092
1165
|
/** Invoke a tool by name. Returns the raw MCP result (caller unwraps content). */
|
|
1093
1166
|
callTool(name: string, args?: Record<string, unknown>): Promise<CallToolResult>;
|
|
1167
|
+
/**
|
|
1168
|
+
* List resources the server exposes. Supports a pagination cursor;
|
|
1169
|
+
* callers interested in the full set should loop on `nextCursor`.
|
|
1170
|
+
* Servers that don't support resources respond with method-not-found
|
|
1171
|
+
* (−32601) — we surface that as a thrown Error so callers can gate
|
|
1172
|
+
* on the `serverCapabilities.resources` field first.
|
|
1173
|
+
*/
|
|
1174
|
+
listResources(cursor?: string): Promise<ListResourcesResult>;
|
|
1175
|
+
/** Read the contents of a resource by URI. */
|
|
1176
|
+
readResource(uri: string): Promise<ReadResourceResult>;
|
|
1177
|
+
/** List prompt templates the server exposes. */
|
|
1178
|
+
listPrompts(cursor?: string): Promise<ListPromptsResult>;
|
|
1179
|
+
/**
|
|
1180
|
+
* Fetch a rendered prompt by name. `args` supplies values for any
|
|
1181
|
+
* required template arguments; the server validates. Returns messages
|
|
1182
|
+
* ready to prepend to the model's input.
|
|
1183
|
+
*/
|
|
1184
|
+
getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult>;
|
|
1094
1185
|
/** Close the transport and reject any outstanding requests. */
|
|
1095
1186
|
close(): Promise<void>;
|
|
1096
1187
|
private assertInitialized;
|
|
@@ -1441,4 +1532,4 @@ declare function redactKey(key: string): string;
|
|
|
1441
1532
|
|
|
1442
1533
|
declare const VERSION = "0.4.3";
|
|
1443
1534
|
|
|
1444
|
-
export { AppendOnlyLog, type ApplyResult, type ApplyStatus, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CODE_SYSTEM_PROMPT, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DEFAULT_MAX_RESULT_CHARS, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EditBlock, type EditSnapshot, type EventRole, type FlattenDecision, type FlattenOptions, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, McpClient, type McpClientOptions, type McpContentBlock, type McpSpec, type McpTool, type McpToolSchema, type McpTransport, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type ScavengeOptions, type ScavengeResult, type SessionInfo, SessionStats, type SessionSummary, type SseMcpSpec, SseTransport, type SseTransportOptions, type StdioMcpSpec, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, Usage, VERSION, VolatileScratch, aggregateBranchUsage, analyzeSchema, appendSessionMessage, applyEditBlock, applyEditBlocks, bridgeMcpTools, claudeEquivalentCost, codeSystemPrompt, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, formatLoopError, harvest, healLoadedMessages, isJsonRpcError, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, nestArguments, openTranscriptFile, parseEditBlocks, parseMcpSpec, parseTranscript, readConfig, readTranscript, recordFromLoopEvent, redactKey, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, restoreSnapshots, runBranches, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, truncateForModel, writeConfig, writeMeta, writeRecord };
|
|
1535
|
+
export { AppendOnlyLog, type ApplyResult, type ApplyStatus, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CODE_SYSTEM_PROMPT, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DEFAULT_MAX_RESULT_CHARS, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EditBlock, type EditSnapshot, type EventRole, type FlattenDecision, type FlattenOptions, type GetPromptResult, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, type ListPromptsResult, type ListResourcesResult, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, McpClient, type McpClientOptions, type McpContentBlock, type McpPrompt, type McpPromptArgument, type McpPromptMessage, type McpPromptResourceBlock, type McpResource, type McpResourceContents, type McpResourceContentsBlob, type McpResourceContentsText, type McpSpec, type McpTool, type McpToolSchema, type McpTransport, type ReadResourceResult, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type ScavengeOptions, type ScavengeResult, type SessionInfo, SessionStats, type SessionSummary, type SseMcpSpec, SseTransport, type SseTransportOptions, type StdioMcpSpec, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, Usage, VERSION, VolatileScratch, aggregateBranchUsage, analyzeSchema, appendSessionMessage, applyEditBlock, applyEditBlocks, bridgeMcpTools, claudeEquivalentCost, codeSystemPrompt, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, formatLoopError, harvest, healLoadedMessages, isJsonRpcError, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, nestArguments, openTranscriptFile, parseEditBlocks, parseMcpSpec, parseTranscript, readConfig, readTranscript, recordFromLoopEvent, redactKey, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, restoreSnapshots, runBranches, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, snapshotBeforeEdits, stripHallucinatedToolMarkup, truncateForModel, writeConfig, writeMeta, writeRecord };
|
package/dist/index.js
CHANGED
|
@@ -673,7 +673,19 @@ function scavengeToolCalls(reasoningContent, opts) {
|
|
|
673
673
|
const max = opts.maxCalls ?? 4;
|
|
674
674
|
const notes = [];
|
|
675
675
|
const out = [];
|
|
676
|
-
for (const
|
|
676
|
+
for (const invoke of iterateDsmlInvokes(reasoningContent)) {
|
|
677
|
+
if (out.length >= max) break;
|
|
678
|
+
if (!opts.allowedNames.has(invoke.name)) continue;
|
|
679
|
+
out.push({
|
|
680
|
+
function: {
|
|
681
|
+
name: invoke.name,
|
|
682
|
+
arguments: JSON.stringify(invoke.args)
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
notes.push(`scavenged DSML call: ${invoke.name}`);
|
|
686
|
+
}
|
|
687
|
+
const nonDsml = stripDsmlBlocks(reasoningContent);
|
|
688
|
+
for (const candidate of iterateJsonObjects(nonDsml)) {
|
|
677
689
|
if (out.length >= max) break;
|
|
678
690
|
const call = coerceToToolCall(candidate, opts.allowedNames);
|
|
679
691
|
if (call) {
|
|
@@ -683,6 +695,40 @@ function scavengeToolCalls(reasoningContent, opts) {
|
|
|
683
695
|
}
|
|
684
696
|
return { calls: out, notes };
|
|
685
697
|
}
|
|
698
|
+
function stripDsmlBlocks(text) {
|
|
699
|
+
let out = text;
|
|
700
|
+
out = out.replace(/<[||]DSML[||]function_calls>[\s\S]*?<\/?[||]DSML[||]function_calls>/g, "");
|
|
701
|
+
out = out.replace(/<[||]DSML[||]invoke\s+[^>]*>[\s\S]*?<\/[||]DSML[||]invoke>/g, "");
|
|
702
|
+
return out;
|
|
703
|
+
}
|
|
704
|
+
function* iterateDsmlInvokes(text) {
|
|
705
|
+
const INVOKE_RE = /<[||]DSML[||]invoke\s+name="([^"]+)">([\s\S]*?)<\/[||]DSML[||]invoke>/g;
|
|
706
|
+
for (const match of text.matchAll(INVOKE_RE)) {
|
|
707
|
+
const name = match[1];
|
|
708
|
+
const body = match[2];
|
|
709
|
+
if (!name || body === void 0) continue;
|
|
710
|
+
yield { name, args: parseDsmlParameters(body) };
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function parseDsmlParameters(body) {
|
|
714
|
+
const PARAM_RE = /<[||]DSML[||]parameter\s+name="([^"]+)"(?:\s+string="(true|false)")?\s*>([\s\S]*?)<\/[||]DSML[||]parameter>/g;
|
|
715
|
+
const args = {};
|
|
716
|
+
for (const m of body.matchAll(PARAM_RE)) {
|
|
717
|
+
const key = m[1];
|
|
718
|
+
const stringFlag = m[2];
|
|
719
|
+
const raw = (m[3] ?? "").trim();
|
|
720
|
+
if (!key) continue;
|
|
721
|
+
if (stringFlag === "false") {
|
|
722
|
+
try {
|
|
723
|
+
args[key] = JSON.parse(raw);
|
|
724
|
+
continue;
|
|
725
|
+
} catch {
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
args[key] = raw;
|
|
729
|
+
}
|
|
730
|
+
return args;
|
|
731
|
+
}
|
|
686
732
|
function* iterateJsonObjects(text) {
|
|
687
733
|
for (let i = 0; i < text.length; i++) {
|
|
688
734
|
if (text[i] !== "{") continue;
|
|
@@ -868,14 +914,15 @@ var ToolCallRepair = class {
|
|
|
868
914
|
this.opts = opts;
|
|
869
915
|
this.storm = new StormBreaker(opts.stormWindow ?? 6, opts.stormThreshold ?? 3);
|
|
870
916
|
}
|
|
871
|
-
process(declaredCalls, reasoningContent) {
|
|
917
|
+
process(declaredCalls, reasoningContent, content = null) {
|
|
872
918
|
const report = {
|
|
873
919
|
scavenged: 0,
|
|
874
920
|
truncationsFixed: 0,
|
|
875
921
|
stormsBroken: 0,
|
|
876
922
|
notes: []
|
|
877
923
|
};
|
|
878
|
-
const
|
|
924
|
+
const combined = [reasoningContent ?? "", content ?? ""].filter(Boolean).join("\n");
|
|
925
|
+
const scavenged = scavengeToolCalls(combined || null, {
|
|
879
926
|
allowedNames: this.opts.allowedToolNames,
|
|
880
927
|
maxCalls: this.opts.maxScavenge ?? 4
|
|
881
928
|
});
|
|
@@ -1453,7 +1500,8 @@ var CacheFirstLoop = class {
|
|
|
1453
1500
|
const planState = preHarvestedPlanState ? preHarvestedPlanState : this.harvestEnabled ? await harvest(reasoningContent || null, this.client, this.harvestOptions) : emptyPlanState();
|
|
1454
1501
|
const { calls: repairedCalls, report } = this.repair.process(
|
|
1455
1502
|
toolCalls,
|
|
1456
|
-
reasoningContent || null
|
|
1503
|
+
reasoningContent || null,
|
|
1504
|
+
assistantContent || null
|
|
1457
1505
|
);
|
|
1458
1506
|
this.appendAndPersist(this.assistantMessage(assistantContent, repairedCalls));
|
|
1459
1507
|
yield {
|
|
@@ -2166,7 +2214,12 @@ var McpClient = class {
|
|
|
2166
2214
|
this.startReaderIfNeeded();
|
|
2167
2215
|
const result = await this.request("initialize", {
|
|
2168
2216
|
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
2169
|
-
|
|
2217
|
+
// Advertise every method the client can consume so servers know
|
|
2218
|
+
// they can send listChanged notifications etc. Sub-feature flags
|
|
2219
|
+
// (e.g. `resources.subscribe`) are omitted — we don't implement
|
|
2220
|
+
// those yet and the empty object means "method-level support, no
|
|
2221
|
+
// sub-features."
|
|
2222
|
+
capabilities: { tools: {}, resources: {}, prompts: {} },
|
|
2170
2223
|
clientInfo: this.clientInfo
|
|
2171
2224
|
});
|
|
2172
2225
|
this._serverCapabilities = result.capabilities ?? {};
|
|
@@ -2190,6 +2243,45 @@ var McpClient = class {
|
|
|
2190
2243
|
arguments: args ?? {}
|
|
2191
2244
|
});
|
|
2192
2245
|
}
|
|
2246
|
+
/**
|
|
2247
|
+
* List resources the server exposes. Supports a pagination cursor;
|
|
2248
|
+
* callers interested in the full set should loop on `nextCursor`.
|
|
2249
|
+
* Servers that don't support resources respond with method-not-found
|
|
2250
|
+
* (−32601) — we surface that as a thrown Error so callers can gate
|
|
2251
|
+
* on the `serverCapabilities.resources` field first.
|
|
2252
|
+
*/
|
|
2253
|
+
async listResources(cursor) {
|
|
2254
|
+
this.assertInitialized();
|
|
2255
|
+
return this.request("resources/list", {
|
|
2256
|
+
...cursor ? { cursor } : {}
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2259
|
+
/** Read the contents of a resource by URI. */
|
|
2260
|
+
async readResource(uri) {
|
|
2261
|
+
this.assertInitialized();
|
|
2262
|
+
return this.request("resources/read", {
|
|
2263
|
+
uri
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2266
|
+
/** List prompt templates the server exposes. */
|
|
2267
|
+
async listPrompts(cursor) {
|
|
2268
|
+
this.assertInitialized();
|
|
2269
|
+
return this.request("prompts/list", {
|
|
2270
|
+
...cursor ? { cursor } : {}
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
/**
|
|
2274
|
+
* Fetch a rendered prompt by name. `args` supplies values for any
|
|
2275
|
+
* required template arguments; the server validates. Returns messages
|
|
2276
|
+
* ready to prepend to the model's input.
|
|
2277
|
+
*/
|
|
2278
|
+
async getPrompt(name, args) {
|
|
2279
|
+
this.assertInitialized();
|
|
2280
|
+
return this.request("prompts/get", {
|
|
2281
|
+
name,
|
|
2282
|
+
...args ? { arguments: args } : {}
|
|
2283
|
+
});
|
|
2284
|
+
}
|
|
2193
2285
|
/** Close the transport and reject any outstanding requests. */
|
|
2194
2286
|
async close() {
|
|
2195
2287
|
for (const [, pending] of this.pending) {
|