@rynfar/meridian 1.45.0 → 1.45.1
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-rakysex2.js → cli-9pcv2qnp.js} +255 -24
- package/dist/cli.js +1 -1
- package/dist/proxy/passthroughTools.d.ts +12 -0
- package/dist/proxy/passthroughTools.d.ts.map +1 -1
- package/dist/proxy/query.d.ts +4 -2
- package/dist/proxy/query.d.ts.map +1 -1
- package/dist/proxy/requestAbort.d.ts +8 -0
- package/dist/proxy/requestAbort.d.ts.map +1 -0
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/structuredOutput.d.ts +21 -0
- package/dist/proxy/structuredOutput.d.ts.map +1 -0
- package/dist/server.js +1 -1
- package/package.json +1 -1
|
@@ -3818,6 +3818,33 @@ async function* guardUpstreamIdle(source, idleMs, onStall, clock = realClock) {
|
|
|
3818
3818
|
}
|
|
3819
3819
|
}
|
|
3820
3820
|
|
|
3821
|
+
// src/proxy/requestAbort.ts
|
|
3822
|
+
function linkRequestAbort(signal) {
|
|
3823
|
+
const controller = new AbortController;
|
|
3824
|
+
let attached = false;
|
|
3825
|
+
const abort = (reason) => {
|
|
3826
|
+
if (!controller.signal.aborted)
|
|
3827
|
+
controller.abort(reason);
|
|
3828
|
+
};
|
|
3829
|
+
const forwardAbort = () => abort(signal.reason);
|
|
3830
|
+
if (signal.aborted) {
|
|
3831
|
+
forwardAbort();
|
|
3832
|
+
} else {
|
|
3833
|
+
signal.addEventListener("abort", forwardAbort, { once: true });
|
|
3834
|
+
attached = true;
|
|
3835
|
+
}
|
|
3836
|
+
return {
|
|
3837
|
+
controller,
|
|
3838
|
+
abort,
|
|
3839
|
+
detach: () => {
|
|
3840
|
+
if (!attached)
|
|
3841
|
+
return;
|
|
3842
|
+
signal.removeEventListener("abort", forwardAbort);
|
|
3843
|
+
attached = false;
|
|
3844
|
+
}
|
|
3845
|
+
};
|
|
3846
|
+
}
|
|
3847
|
+
|
|
3821
3848
|
// src/proxy/oauthUsage.ts
|
|
3822
3849
|
var OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
3823
3850
|
var OAUTH_BETA_HEADER = "oauth-2025-04-20";
|
|
@@ -8111,6 +8138,9 @@ function stableStringify(value) {
|
|
|
8111
8138
|
const parts = keys.map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`);
|
|
8112
8139
|
return `{${parts.join(",")}}`;
|
|
8113
8140
|
}
|
|
8141
|
+
function toolUseSignature(name, input) {
|
|
8142
|
+
return `${name}::${stableStringify(input ?? null)}`;
|
|
8143
|
+
}
|
|
8114
8144
|
function stripMcpPrefix(toolName) {
|
|
8115
8145
|
if (toolName.startsWith(PASSTHROUGH_MCP_PREFIX)) {
|
|
8116
8146
|
return toolName.slice(PASSTHROUGH_MCP_PREFIX.length);
|
|
@@ -9987,7 +10017,6 @@ var BLOCKED_BUILTIN_TOOLS = [
|
|
|
9987
10017
|
"Read",
|
|
9988
10018
|
"Write",
|
|
9989
10019
|
"Edit",
|
|
9990
|
-
"MultiEdit",
|
|
9991
10020
|
"Bash",
|
|
9992
10021
|
"Glob",
|
|
9993
10022
|
"Grep",
|
|
@@ -16563,7 +16592,9 @@ function stripConfigDir(env2) {
|
|
|
16563
16592
|
}
|
|
16564
16593
|
function computePassthroughMaxTurns(resumeSessionId, hasDeferredTools, advisorModel) {
|
|
16565
16594
|
const hasResume = !!resumeSessionId;
|
|
16566
|
-
const
|
|
16595
|
+
const defaultBase = hasResume && hasDeferredTools ? 4 : 3;
|
|
16596
|
+
const configured = envInt("PASSTHROUGH_MAX_TURNS", defaultBase);
|
|
16597
|
+
const base = configured > 0 ? configured : defaultBase;
|
|
16567
16598
|
const advisorBump = advisorModel ? 3 : 0;
|
|
16568
16599
|
return base + advisorBump;
|
|
16569
16600
|
}
|
|
@@ -16594,7 +16625,7 @@ function resolveSystemPrompt(systemContext, passthrough, settingSources, codeSys
|
|
|
16594
16625
|
return { systemPrompt: "" };
|
|
16595
16626
|
return {};
|
|
16596
16627
|
}
|
|
16597
|
-
function buildQueryOptions(ctx) {
|
|
16628
|
+
function buildQueryOptions(ctx, abortController) {
|
|
16598
16629
|
const {
|
|
16599
16630
|
prompt,
|
|
16600
16631
|
model,
|
|
@@ -16620,6 +16651,7 @@ function buildQueryOptions(ctx) {
|
|
|
16620
16651
|
effort,
|
|
16621
16652
|
thinking,
|
|
16622
16653
|
taskBudget,
|
|
16654
|
+
outputFormat,
|
|
16623
16655
|
betas,
|
|
16624
16656
|
settingSources,
|
|
16625
16657
|
codeSystemPrompt,
|
|
@@ -16642,6 +16674,7 @@ function buildQueryOptions(ctx) {
|
|
|
16642
16674
|
cwd: workingDirectory,
|
|
16643
16675
|
model,
|
|
16644
16676
|
pathToClaudeCodeExecutable: claudeExecutable,
|
|
16677
|
+
...abortController ? { abortController } : {},
|
|
16645
16678
|
...stream2 ? { includePartialMessages: true } : {},
|
|
16646
16679
|
permissionMode: "bypassPermissions",
|
|
16647
16680
|
allowDangerouslySkipPermissions: true,
|
|
@@ -16682,6 +16715,7 @@ function buildQueryOptions(ctx) {
|
|
|
16682
16715
|
...effort ? { effort } : {},
|
|
16683
16716
|
...thinking ? { thinking } : {},
|
|
16684
16717
|
...taskBudget ? { taskBudget } : {},
|
|
16718
|
+
...outputFormat ? { outputFormat } : {},
|
|
16685
16719
|
...betas && betas.length > 0 ? { betas } : {},
|
|
16686
16720
|
...maxBudgetUsd && maxBudgetUsd > 0 ? { maxBudgetUsd } : {},
|
|
16687
16721
|
...fallbackModel ? { fallbackModel } : {},
|
|
@@ -16698,6 +16732,40 @@ function normalizeEffort(value) {
|
|
|
16698
16732
|
return typeof value === "string" && VALID_EFFORTS.includes(value) ? value : undefined;
|
|
16699
16733
|
}
|
|
16700
16734
|
|
|
16735
|
+
// src/proxy/structuredOutput.ts
|
|
16736
|
+
function isRecord(value) {
|
|
16737
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16738
|
+
}
|
|
16739
|
+
function parseOutputFormat(outputConfig, tools) {
|
|
16740
|
+
if (outputConfig === undefined)
|
|
16741
|
+
return { ok: true, value: undefined };
|
|
16742
|
+
if (!isRecord(outputConfig)) {
|
|
16743
|
+
return { ok: false, message: "output_config: Expected an object" };
|
|
16744
|
+
}
|
|
16745
|
+
const format = outputConfig.format;
|
|
16746
|
+
if (format === undefined)
|
|
16747
|
+
return { ok: true, value: undefined };
|
|
16748
|
+
if (!isRecord(format)) {
|
|
16749
|
+
return { ok: false, message: "output_config.format: Expected an object" };
|
|
16750
|
+
}
|
|
16751
|
+
if (format.type !== "json_schema") {
|
|
16752
|
+
return { ok: false, message: "output_config.format.type: Only 'json_schema' is supported" };
|
|
16753
|
+
}
|
|
16754
|
+
if (!isRecord(format.schema)) {
|
|
16755
|
+
return { ok: false, message: "output_config.format.schema: Expected a JSON Schema object" };
|
|
16756
|
+
}
|
|
16757
|
+
if (Array.isArray(tools) && tools.length > 0) {
|
|
16758
|
+
return { ok: false, message: "output_config.format: Cannot be combined with tools" };
|
|
16759
|
+
}
|
|
16760
|
+
return {
|
|
16761
|
+
ok: true,
|
|
16762
|
+
value: { type: "json_schema", schema: format.schema }
|
|
16763
|
+
};
|
|
16764
|
+
}
|
|
16765
|
+
function structuredOutputText(value) {
|
|
16766
|
+
return JSON.stringify(value);
|
|
16767
|
+
}
|
|
16768
|
+
|
|
16701
16769
|
// src/proxy/transforms/registry.ts
|
|
16702
16770
|
var ADAPTER_TRANSFORMS = {
|
|
16703
16771
|
opencode: openCodeTransforms,
|
|
@@ -17829,6 +17897,8 @@ function createProxyServer(config = {}) {
|
|
|
17829
17897
|
}
|
|
17830
17898
|
const handleMessages = async (c, requestMeta) => {
|
|
17831
17899
|
const requestStartAt = Date.now();
|
|
17900
|
+
const requestAbort = linkRequestAbort(c.req.raw.signal);
|
|
17901
|
+
let streamOwnsAbortLink = false;
|
|
17832
17902
|
return withClaudeLogContext({ requestId: requestMeta.requestId, endpoint: requestMeta.endpoint }, async () => {
|
|
17833
17903
|
const adapter = detectAdapter(c);
|
|
17834
17904
|
try {
|
|
@@ -17849,13 +17919,18 @@ function createProxyServer(config = {}) {
|
|
|
17849
17919
|
if (body.messages.length === 0) {
|
|
17850
17920
|
return c.json({ type: "error", error: { type: "invalid_request_error", message: "messages: Cannot be empty — at least one message is required" } }, 400);
|
|
17851
17921
|
}
|
|
17922
|
+
const parsedOutputFormat = parseOutputFormat(body.output_config, body.tools);
|
|
17923
|
+
if (!parsedOutputFormat.ok) {
|
|
17924
|
+
return c.json({ type: "error", error: { type: "invalid_request_error", message: parsedOutputFormat.message } }, 400);
|
|
17925
|
+
}
|
|
17926
|
+
const outputFormat = parsedOutputFormat.value;
|
|
17852
17927
|
const profile = resolveProfile(finalConfig.profiles, finalConfig.defaultProfile, c.req.header("x-meridian-profile") || undefined);
|
|
17853
17928
|
const authStatus = await getClaudeAuthStatusAsync(profile.id !== "default" ? profile.id : undefined, Object.keys(profile.env).length > 0 ? profile.env : undefined);
|
|
17854
17929
|
const agentMode = c.req.header("x-opencode-agent-mode") ?? null;
|
|
17855
17930
|
const requestSource = c.req.header("x-meridian-source")?.slice(0, 64) || undefined;
|
|
17856
17931
|
const requestedModel = typeof body.model === "string" ? body.model : "sonnet";
|
|
17857
17932
|
let model = mapModelToClaudeModel(requestedModel, authStatus?.subscriptionType, agentMode);
|
|
17858
|
-
const envOverrides = requestedModel.startsWith("claude-opus-") ? { ANTHROPIC_DEFAULT_OPUS_MODEL: requestedModel } : requestedModel.startsWith("claude-fable-") ? { ANTHROPIC_DEFAULT_FABLE_MODEL: requestedModel } : undefined;
|
|
17933
|
+
const envOverrides = requestedModel.startsWith("claude-opus-") ? { ANTHROPIC_DEFAULT_OPUS_MODEL: requestedModel } : requestedModel.startsWith("claude-fable-") ? { ANTHROPIC_DEFAULT_FABLE_MODEL: requestedModel } : requestedModel.startsWith("claude-sonnet-") ? { ANTHROPIC_DEFAULT_SONNET_MODEL: requestedModel } : requestedModel.startsWith("claude-haiku-") ? { ANTHROPIC_DEFAULT_HAIKU_MODEL: requestedModel } : undefined;
|
|
17859
17934
|
const cwdResolution = resolveSdkWorkingDirectory({
|
|
17860
17935
|
envOverride: process.env.MERIDIAN_WORKDIR ?? process.env.CLAUDE_PROXY_WORKDIR,
|
|
17861
17936
|
adapterCwd: adapter.extractWorkingDirectory(body),
|
|
@@ -17946,7 +18021,10 @@ function createProxyServer(config = {}) {
|
|
|
17946
18021
|
const agentSessionId = adapter.getSessionId(c);
|
|
17947
18022
|
const profileSessionId = profile.id !== "default" && agentSessionId ? `${profile.id}:${agentSessionId}` : agentSessionId;
|
|
17948
18023
|
const profileScopedCwd = profile.id !== "default" ? `${clientWorkingDirectory}::profile=${profile.id}` : clientWorkingDirectory;
|
|
17949
|
-
const
|
|
18024
|
+
const lastMessage = Array.isArray(body.messages) ? body.messages[body.messages.length - 1] : undefined;
|
|
18025
|
+
const lastIsToolResult = Array.isArray(lastMessage?.content) && lastMessage.content.some((b) => b?.type === "tool_result");
|
|
18026
|
+
const isClientDrivenLoop = !agentSessionId && lastIsToolResult;
|
|
18027
|
+
const isIndependentSession = requestSource?.startsWith("fork-") || requestSource?.startsWith("subagent-") || isClientDrivenLoop || false;
|
|
17950
18028
|
let lineageResult = isIndependentSession ? { type: "diverged" } : lookupSession(profileSessionId, body.messages || [], profileScopedCwd);
|
|
17951
18029
|
if (lineageResult.type === "undo" && adapter.name === "opencode" && !agentSessionId) {
|
|
17952
18030
|
lineageResult = { type: "diverged" };
|
|
@@ -18056,6 +18134,11 @@ function createProxyServer(config = {}) {
|
|
|
18056
18134
|
const passthrough = pipelineCtx.passthrough !== undefined ? pipelineCtx.passthrough : envBool("PASSTHROUGH");
|
|
18057
18135
|
const settingSources = envBool("LOAD_CONTEXT") || sdkFeatures.claudeMd === "full" ? ["user", "project"] : sdkFeatures.claudeMd === "project" ? ["project"] : pipelineCtx.settingSources ?? [];
|
|
18058
18136
|
const capturedToolUses = [];
|
|
18137
|
+
const capturedSignatures = new Set;
|
|
18138
|
+
const capturedToolNames = new Set;
|
|
18139
|
+
let sawDuplicateToolUse = false;
|
|
18140
|
+
const toolChoice = body.tool_choice;
|
|
18141
|
+
const forceSingleToolUse = !!toolChoice && (toolChoice.type === "tool" || toolChoice.disable_parallel_tool_use === true);
|
|
18059
18142
|
const fileChanges = [];
|
|
18060
18143
|
let passthroughMcp;
|
|
18061
18144
|
let requestTools = Array.isArray(body.tools) ? body.tools : [];
|
|
@@ -18104,6 +18187,8 @@ function createProxyServer(config = {}) {
|
|
|
18104
18187
|
hooks: [async (input) => {
|
|
18105
18188
|
if (input.tool_name === "ToolSearch")
|
|
18106
18189
|
return {};
|
|
18190
|
+
if (input.tool_name === "StructuredOutput")
|
|
18191
|
+
return {};
|
|
18107
18192
|
const toolName = stripMcpPrefix(input.tool_name);
|
|
18108
18193
|
if (hasDeferredTools && coreSet && !coreSet.has(toolName.toLowerCase())) {
|
|
18109
18194
|
discoveredTools.add(toolName);
|
|
@@ -18113,11 +18198,28 @@ function createProxyServer(config = {}) {
|
|
|
18113
18198
|
if (toolName.toLowerCase() === "task" && toolInput?.subagent_type && typeof toolInput.subagent_type === "string") {
|
|
18114
18199
|
toolInput = { ...toolInput, subagent_type: resolveAgentAlias(toolInput.subagent_type) };
|
|
18115
18200
|
}
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18201
|
+
const signature = toolUseSignature(toolName, toolInput);
|
|
18202
|
+
const isExactDuplicate = capturedSignatures.has(signature);
|
|
18203
|
+
const isSameToolRepeat = !isExactDuplicate && capturedToolNames.has(toolName);
|
|
18204
|
+
const exceedsForcedSingle = forceSingleToolUse && capturedToolUses.length >= 1;
|
|
18205
|
+
if (isExactDuplicate) {
|
|
18206
|
+
claudeLog("passthrough.duplicate_tool_use_dropped", { name: toolName });
|
|
18207
|
+
} else if (isSameToolRepeat || exceedsForcedSingle) {
|
|
18208
|
+
sawDuplicateToolUse = true;
|
|
18209
|
+
claudeLog("passthrough.extra_tool_use_dropped", {
|
|
18210
|
+
name: toolName,
|
|
18211
|
+
reason: exceedsForcedSingle ? "forced_single" : "same_tool_repeat"
|
|
18212
|
+
});
|
|
18213
|
+
requestAbort.abort("passthrough single-step complete");
|
|
18214
|
+
} else {
|
|
18215
|
+
capturedSignatures.add(signature);
|
|
18216
|
+
capturedToolNames.add(toolName);
|
|
18217
|
+
capturedToolUses.push({
|
|
18218
|
+
id: input.tool_use_id,
|
|
18219
|
+
name: toolName,
|
|
18220
|
+
input: toolInput
|
|
18221
|
+
});
|
|
18222
|
+
}
|
|
18121
18223
|
return {
|
|
18122
18224
|
decision: "block",
|
|
18123
18225
|
reason: "This tool call has been forwarded to the client for execution. " + "The result will be delivered in a future turn. " + "Do not retry, do not call additional tools, and do not generate further text — end your turn now."
|
|
@@ -18136,6 +18238,8 @@ function createProxyServer(config = {}) {
|
|
|
18136
18238
|
if (!stream2) {
|
|
18137
18239
|
const contentBlocks = [];
|
|
18138
18240
|
let assistantMessages = 0;
|
|
18241
|
+
let hasStructuredOutput = false;
|
|
18242
|
+
let structuredOutput;
|
|
18139
18243
|
const upstreamStartAt = Date.now();
|
|
18140
18244
|
let firstChunkAt;
|
|
18141
18245
|
let currentSessionId;
|
|
@@ -18187,6 +18291,7 @@ function createProxyServer(config = {}) {
|
|
|
18187
18291
|
effort,
|
|
18188
18292
|
thinking,
|
|
18189
18293
|
taskBudget,
|
|
18294
|
+
outputFormat,
|
|
18190
18295
|
betas,
|
|
18191
18296
|
settingSources,
|
|
18192
18297
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18199,7 +18304,7 @@ function createProxyServer(config = {}) {
|
|
|
18199
18304
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18200
18305
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18201
18306
|
advisorModel
|
|
18202
|
-
}))) {
|
|
18307
|
+
}, requestAbort.controller))) {
|
|
18203
18308
|
if (event.type === "rate_limit_event") {
|
|
18204
18309
|
rateLimitStore.record(event.rate_limit_info);
|
|
18205
18310
|
}
|
|
@@ -18250,6 +18355,7 @@ function createProxyServer(config = {}) {
|
|
|
18250
18355
|
effort,
|
|
18251
18356
|
thinking,
|
|
18252
18357
|
taskBudget,
|
|
18358
|
+
outputFormat,
|
|
18253
18359
|
betas,
|
|
18254
18360
|
settingSources,
|
|
18255
18361
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18262,7 +18368,7 @@ function createProxyServer(config = {}) {
|
|
|
18262
18368
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18263
18369
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18264
18370
|
advisorModel
|
|
18265
|
-
}));
|
|
18371
|
+
}, requestAbort.controller));
|
|
18266
18372
|
return;
|
|
18267
18373
|
}
|
|
18268
18374
|
if (isExtraUsageRequiredError(errMsg) && hasExtendedContext(model)) {
|
|
@@ -18316,6 +18422,7 @@ function createProxyServer(config = {}) {
|
|
|
18316
18422
|
effort,
|
|
18317
18423
|
thinking,
|
|
18318
18424
|
taskBudget,
|
|
18425
|
+
outputFormat,
|
|
18319
18426
|
betas,
|
|
18320
18427
|
settingSources,
|
|
18321
18428
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18328,7 +18435,7 @@ function createProxyServer(config = {}) {
|
|
|
18328
18435
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18329
18436
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18330
18437
|
advisorModel
|
|
18331
|
-
}));
|
|
18438
|
+
}, requestAbort.controller));
|
|
18332
18439
|
return;
|
|
18333
18440
|
}
|
|
18334
18441
|
if (isExpiredTokenError(errMsg) && !tokenRefreshed) {
|
|
@@ -18376,6 +18483,10 @@ function createProxyServer(config = {}) {
|
|
|
18376
18483
|
if (message.session_id) {
|
|
18377
18484
|
currentSessionId = message.session_id;
|
|
18378
18485
|
}
|
|
18486
|
+
if (passthrough && sawDuplicateToolUse) {
|
|
18487
|
+
claudeLog("passthrough.loop_break", { mode: "non_stream", assistantMessages, captured: capturedToolUses.length });
|
|
18488
|
+
break;
|
|
18489
|
+
}
|
|
18379
18490
|
if (message.type === "assistant") {
|
|
18380
18491
|
assistantMessages += 1;
|
|
18381
18492
|
if (message.uuid) {
|
|
@@ -18421,6 +18532,10 @@ function createProxyServer(config = {}) {
|
|
|
18421
18532
|
if (resultUsage) {
|
|
18422
18533
|
lastUsage = { ...lastUsage, ...resultUsage };
|
|
18423
18534
|
}
|
|
18535
|
+
if (outputFormat && "structured_output" in message) {
|
|
18536
|
+
hasStructuredOutput = true;
|
|
18537
|
+
structuredOutput = message.structured_output;
|
|
18538
|
+
}
|
|
18424
18539
|
}
|
|
18425
18540
|
}
|
|
18426
18541
|
claudeLog("upstream.completed", {
|
|
@@ -18448,14 +18563,40 @@ function createProxyServer(config = {}) {
|
|
|
18448
18563
|
error.message = `${error.message}
|
|
18449
18564
|
Subprocess stderr: ${stderrOutput}`;
|
|
18450
18565
|
}
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
|
|
18454
|
-
|
|
18455
|
-
|
|
18456
|
-
|
|
18566
|
+
const sdkTerm = extractSdkTermination(error instanceof Error ? error.message : String(error));
|
|
18567
|
+
const canRecoverAsToolUse = passthrough && capturedToolUses.length > 0 && (sdkTerm.reason === "max_turns" || sdkTerm.reason === "aborted");
|
|
18568
|
+
if (canRecoverAsToolUse) {
|
|
18569
|
+
diagnosticLog2.session(`${requestMeta.requestId} sdk_termination_recovered ${formatSdkTermination(sdkTerm, {
|
|
18570
|
+
model,
|
|
18571
|
+
requestSource,
|
|
18572
|
+
isResume,
|
|
18573
|
+
hasDeferredTools,
|
|
18574
|
+
sdkSessionId: resumeSessionId
|
|
18575
|
+
})} captured=${capturedToolUses.length}`, requestMeta.requestId);
|
|
18576
|
+
claudeLog("passthrough.max_turns_recovered", {
|
|
18577
|
+
mode: "non_stream",
|
|
18578
|
+
reason: sdkTerm.reason,
|
|
18579
|
+
captured: capturedToolUses.length
|
|
18580
|
+
});
|
|
18581
|
+
} else {
|
|
18582
|
+
claudeLog("upstream.failed", {
|
|
18583
|
+
mode: "non_stream",
|
|
18584
|
+
model,
|
|
18585
|
+
durationMs: Date.now() - upstreamStartAt,
|
|
18586
|
+
error: error instanceof Error ? error.message : String(error),
|
|
18587
|
+
...stderrOutput ? { stderr: stderrOutput } : {}
|
|
18588
|
+
});
|
|
18589
|
+
throw error;
|
|
18590
|
+
}
|
|
18591
|
+
}
|
|
18592
|
+
if (outputFormat) {
|
|
18593
|
+
if (!hasStructuredOutput) {
|
|
18594
|
+
throw new Error("Structured output was requested but the SDK returned no structured_output result");
|
|
18595
|
+
}
|
|
18596
|
+
contentBlocks.splice(0, contentBlocks.length, {
|
|
18597
|
+
type: "text",
|
|
18598
|
+
text: structuredOutputText(structuredOutput)
|
|
18457
18599
|
});
|
|
18458
|
-
throw error;
|
|
18459
18600
|
}
|
|
18460
18601
|
if (passthrough && capturedToolUses.length > 0) {
|
|
18461
18602
|
const capturedById = new Map(capturedToolUses.map((tu) => [tu.id, tu]));
|
|
@@ -18606,6 +18747,8 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18606
18747
|
sdkUuidMap.push(null);
|
|
18607
18748
|
let messageStartEmitted = false;
|
|
18608
18749
|
let lastUsage;
|
|
18750
|
+
let hasStructuredOutput = false;
|
|
18751
|
+
let structuredOutput;
|
|
18609
18752
|
const streamedToolUseIds = new Set;
|
|
18610
18753
|
try {
|
|
18611
18754
|
let currentSessionId;
|
|
@@ -18647,6 +18790,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18647
18790
|
effort,
|
|
18648
18791
|
thinking,
|
|
18649
18792
|
taskBudget,
|
|
18793
|
+
outputFormat,
|
|
18650
18794
|
betas,
|
|
18651
18795
|
settingSources,
|
|
18652
18796
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18659,7 +18803,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18659
18803
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18660
18804
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18661
18805
|
advisorModel
|
|
18662
|
-
}))) {
|
|
18806
|
+
}, requestAbort.controller))) {
|
|
18663
18807
|
if (event.type === "rate_limit_event") {
|
|
18664
18808
|
rateLimitStore.record(event.rate_limit_info);
|
|
18665
18809
|
}
|
|
@@ -18710,6 +18854,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18710
18854
|
effort,
|
|
18711
18855
|
thinking,
|
|
18712
18856
|
taskBudget,
|
|
18857
|
+
outputFormat,
|
|
18713
18858
|
betas,
|
|
18714
18859
|
settingSources,
|
|
18715
18860
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18722,7 +18867,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18722
18867
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18723
18868
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18724
18869
|
advisorModel
|
|
18725
|
-
}));
|
|
18870
|
+
}, requestAbort.controller));
|
|
18726
18871
|
return;
|
|
18727
18872
|
}
|
|
18728
18873
|
if (isExtraUsageRequiredError(errMsg) && hasExtendedContext(model)) {
|
|
@@ -18776,6 +18921,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18776
18921
|
effort,
|
|
18777
18922
|
thinking,
|
|
18778
18923
|
taskBudget,
|
|
18924
|
+
outputFormat,
|
|
18779
18925
|
betas,
|
|
18780
18926
|
settingSources,
|
|
18781
18927
|
codeSystemPrompt: sdkFeatures.codeSystemPrompt,
|
|
@@ -18788,7 +18934,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18788
18934
|
sdkDebug: sdkFeatures.sdkDebug,
|
|
18789
18935
|
additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
|
|
18790
18936
|
advisorModel
|
|
18791
|
-
}));
|
|
18937
|
+
}, requestAbort.controller));
|
|
18792
18938
|
return;
|
|
18793
18939
|
}
|
|
18794
18940
|
if (isExpiredTokenError(errMsg) && !tokenRefreshed) {
|
|
@@ -18876,6 +19022,15 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18876
19022
|
if (message.type === "assistant" && message.uuid) {
|
|
18877
19023
|
sdkUuidMap.push(message.uuid);
|
|
18878
19024
|
}
|
|
19025
|
+
if (message.type === "result") {
|
|
19026
|
+
const resultUsage = message.usage;
|
|
19027
|
+
if (resultUsage)
|
|
19028
|
+
lastUsage = { ...lastUsage, ...resultUsage };
|
|
19029
|
+
if (outputFormat && "structured_output" in message) {
|
|
19030
|
+
hasStructuredOutput = true;
|
|
19031
|
+
structuredOutput = message.structured_output;
|
|
19032
|
+
}
|
|
19033
|
+
}
|
|
18879
19034
|
if (message.type === "stream_event") {
|
|
18880
19035
|
streamEventsSeen += 1;
|
|
18881
19036
|
if (!firstChunkAt) {
|
|
@@ -18889,6 +19044,18 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
18889
19044
|
const event = message.event;
|
|
18890
19045
|
const eventType = event.type;
|
|
18891
19046
|
const eventIndex = event.index;
|
|
19047
|
+
if (outputFormat) {
|
|
19048
|
+
if (eventType === "message_start") {
|
|
19049
|
+
const startUsage = event.message?.usage;
|
|
19050
|
+
if (startUsage)
|
|
19051
|
+
lastUsage = { ...lastUsage, ...startUsage };
|
|
19052
|
+
} else if (eventType === "message_delta") {
|
|
19053
|
+
const deltaUsage = event.usage;
|
|
19054
|
+
if (deltaUsage)
|
|
19055
|
+
lastUsage = { ...lastUsage, ...deltaUsage };
|
|
19056
|
+
}
|
|
19057
|
+
continue;
|
|
19058
|
+
}
|
|
18892
19059
|
if (eventType === "message_start") {
|
|
18893
19060
|
skipBlockIndices.clear();
|
|
18894
19061
|
sdkToClientIndex.clear();
|
|
@@ -19026,6 +19193,60 @@ data: ${JSON.stringify({ type: "message_stop" })}
|
|
|
19026
19193
|
} finally {
|
|
19027
19194
|
clearInterval(heartbeat);
|
|
19028
19195
|
}
|
|
19196
|
+
if (outputFormat) {
|
|
19197
|
+
if (!hasStructuredOutput) {
|
|
19198
|
+
throw new Error("Structured output was requested but the SDK returned no structured_output result");
|
|
19199
|
+
}
|
|
19200
|
+
const text = structuredOutputText(structuredOutput);
|
|
19201
|
+
const messageId = `msg_${Date.now()}`;
|
|
19202
|
+
safeEnqueue(encoder.encode(`event: message_start
|
|
19203
|
+
data: ${JSON.stringify({
|
|
19204
|
+
type: "message_start",
|
|
19205
|
+
message: {
|
|
19206
|
+
id: messageId,
|
|
19207
|
+
type: "message",
|
|
19208
|
+
role: "assistant",
|
|
19209
|
+
content: [],
|
|
19210
|
+
model: body.model,
|
|
19211
|
+
stop_reason: null,
|
|
19212
|
+
stop_sequence: null,
|
|
19213
|
+
usage: { input_tokens: lastUsage?.input_tokens ?? 0, output_tokens: 0 }
|
|
19214
|
+
}
|
|
19215
|
+
})}
|
|
19216
|
+
|
|
19217
|
+
`), "structured_message_start");
|
|
19218
|
+
safeEnqueue(encoder.encode(`event: content_block_start
|
|
19219
|
+
data: ${JSON.stringify({
|
|
19220
|
+
type: "content_block_start",
|
|
19221
|
+
index: 0,
|
|
19222
|
+
content_block: { type: "text", text: "" }
|
|
19223
|
+
})}
|
|
19224
|
+
|
|
19225
|
+
`), "structured_block_start");
|
|
19226
|
+
safeEnqueue(encoder.encode(`event: content_block_delta
|
|
19227
|
+
data: ${JSON.stringify({
|
|
19228
|
+
type: "content_block_delta",
|
|
19229
|
+
index: 0,
|
|
19230
|
+
delta: { type: "text_delta", text }
|
|
19231
|
+
})}
|
|
19232
|
+
|
|
19233
|
+
`), "structured_text_delta");
|
|
19234
|
+
safeEnqueue(encoder.encode(`event: content_block_stop
|
|
19235
|
+
data: ${JSON.stringify({ type: "content_block_stop", index: 0 })}
|
|
19236
|
+
|
|
19237
|
+
`), "structured_block_stop");
|
|
19238
|
+
safeEnqueue(encoder.encode(`event: message_delta
|
|
19239
|
+
data: ${JSON.stringify({
|
|
19240
|
+
type: "message_delta",
|
|
19241
|
+
delta: { stop_reason: "end_turn", stop_sequence: null },
|
|
19242
|
+
usage: { output_tokens: lastUsage?.output_tokens ?? 0 }
|
|
19243
|
+
})}
|
|
19244
|
+
|
|
19245
|
+
`), "structured_message_delta");
|
|
19246
|
+
messageStartEmitted = true;
|
|
19247
|
+
eventsForwarded += 5;
|
|
19248
|
+
textEventsForwarded += 1;
|
|
19249
|
+
}
|
|
19029
19250
|
claudeLog("upstream.completed", {
|
|
19030
19251
|
mode: "stream",
|
|
19031
19252
|
model,
|
|
@@ -19230,7 +19451,7 @@ Subprocess stderr: ${stderrOutput}`;
|
|
|
19230
19451
|
} : classifyError(errMsg);
|
|
19231
19452
|
claudeLog("proxy.anthropic.error", { error: errMsg, classified: streamErr.type });
|
|
19232
19453
|
const sdkTerm = extractSdkTermination(errMsg);
|
|
19233
|
-
const canRecoverAsToolUse = sdkTerm.reason === "max_turns" && passthrough && capturedToolUses.length > 0 && messageStartEmitted;
|
|
19454
|
+
const canRecoverAsToolUse = (sdkTerm.reason === "max_turns" || sdkTerm.reason === "aborted" && sawDuplicateToolUse) && passthrough && capturedToolUses.length > 0 && messageStartEmitted;
|
|
19234
19455
|
if (canRecoverAsToolUse) {
|
|
19235
19456
|
diagnosticLog2.session(`${requestMeta.requestId} sdk_termination_recovered ${formatSdkTermination(sdkTerm, {
|
|
19236
19457
|
model,
|
|
@@ -19377,10 +19598,17 @@ data: ${JSON.stringify({
|
|
|
19377
19598
|
} catch {}
|
|
19378
19599
|
streamClosed = true;
|
|
19379
19600
|
}
|
|
19601
|
+
} finally {
|
|
19602
|
+
requestAbort.detach();
|
|
19380
19603
|
}
|
|
19604
|
+
},
|
|
19605
|
+
cancel(reason) {
|
|
19606
|
+
requestAbort.abort(reason);
|
|
19607
|
+
requestAbort.detach();
|
|
19381
19608
|
}
|
|
19382
19609
|
});
|
|
19383
19610
|
const streamSessionId = resumeSessionId || `session_${Date.now()}`;
|
|
19611
|
+
streamOwnsAbortLink = true;
|
|
19384
19612
|
return new Response(readable, {
|
|
19385
19613
|
headers: {
|
|
19386
19614
|
"Content-Type": "text/event-stream",
|
|
@@ -19428,6 +19656,9 @@ data: ${JSON.stringify({
|
|
|
19428
19656
|
error: classified.type
|
|
19429
19657
|
});
|
|
19430
19658
|
return new Response(JSON.stringify({ type: "error", error: { type: classified.type, message: classified.message } }), { status: classified.status, headers: { "Content-Type": "application/json" } });
|
|
19659
|
+
} finally {
|
|
19660
|
+
if (!streamOwnsAbortLink)
|
|
19661
|
+
requestAbort.detach();
|
|
19431
19662
|
}
|
|
19432
19663
|
});
|
|
19433
19664
|
};
|
package/dist/cli.js
CHANGED
|
@@ -40,6 +40,18 @@ export declare function computeToolSetKey(tools: Array<{
|
|
|
40
40
|
input_schema?: unknown;
|
|
41
41
|
defer_loading?: boolean;
|
|
42
42
|
}>): string;
|
|
43
|
+
/**
|
|
44
|
+
* Stable semantic signature for a forwarded tool_use: tool name + a
|
|
45
|
+
* key-order-independent serialization of its input. Two tool calls with the
|
|
46
|
+
* same name and the same arguments share a signature even if the SDK assigns
|
|
47
|
+
* them different tool_use ids.
|
|
48
|
+
*
|
|
49
|
+
* Used by the passthrough capture path to tell apart genuine parallel calls
|
|
50
|
+
* (distinct signatures — e.g. get_weather vs get_time) from an SDK internal
|
|
51
|
+
* continuation turn re-emitting a blocked call (identical signature, new id).
|
|
52
|
+
* The former are all forwarded; the latter is a duplicate and dropped.
|
|
53
|
+
*/
|
|
54
|
+
export declare function toolUseSignature(name: string, input: unknown): string;
|
|
43
55
|
/**
|
|
44
56
|
* Strip the MCP prefix from a tool name to get the OpenCode tool name.
|
|
45
57
|
* e.g., "mcp__oc__todowrite" → "todowrite"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passthroughTools.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AACxC,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0CtE,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACjG,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE;;;;EA4DlC;AAqBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAC9E,MAAM,CASR;AAUD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvD;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,YAAY,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,GACtF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgCrC"}
|
|
1
|
+
{"version":3,"file":"passthroughTools.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AACxC,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0CtE,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACjG,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE;;;;EA4DlC;AAqBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAC9E,MAAM,CASR;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvD;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,YAAY,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,GACtF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgCrC"}
|
package/dist/proxy/query.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Centralizes the construction of query() options, eliminating duplication
|
|
5
5
|
* between the streaming and non-streaming paths in server.ts.
|
|
6
6
|
*/
|
|
7
|
-
import type { Options, SettingSource } from "@anthropic-ai/claude-agent-sdk";
|
|
7
|
+
import type { Options, OutputFormat, SettingSource } from "@anthropic-ai/claude-agent-sdk";
|
|
8
8
|
import { createPassthroughMcpServer } from "./passthroughTools";
|
|
9
9
|
import type { Effort } from "./effort";
|
|
10
10
|
export interface QueryContext {
|
|
@@ -72,6 +72,8 @@ export interface QueryContext {
|
|
|
72
72
|
taskBudget?: {
|
|
73
73
|
total: number;
|
|
74
74
|
};
|
|
75
|
+
/** Native JSON-schema output contract for the Claude Agent SDK */
|
|
76
|
+
outputFormat?: OutputFormat;
|
|
75
77
|
/** Beta features to enable */
|
|
76
78
|
betas?: string[];
|
|
77
79
|
/** SDK setting sources — controls CLAUDE.md and user settings loading */
|
|
@@ -115,5 +117,5 @@ export interface BuildQueryResult {
|
|
|
115
117
|
* reports that as its working directory.
|
|
116
118
|
*/
|
|
117
119
|
export declare function buildCwdNote(sdkCwd: string, clientCwd?: string): string;
|
|
118
|
-
export declare function buildQueryOptions(ctx: QueryContext): BuildQueryResult;
|
|
120
|
+
export declare function buildQueryOptions(ctx: QueryContext, abortController?: AbortController): BuildQueryResult;
|
|
119
121
|
//# sourceMappingURL=query.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAW,aAAa,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface RequestAbortLink {
|
|
2
|
+
controller: AbortController;
|
|
3
|
+
abort: (reason?: unknown) => void;
|
|
4
|
+
detach: () => void;
|
|
5
|
+
}
|
|
6
|
+
/** Forward an HTTP request abort into the SDK query lifecycle. */
|
|
7
|
+
export declare function linkRequestAbort(signal: AbortSignal): RequestAbortLink;
|
|
8
|
+
//# sourceMappingURL=requestAbort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestAbort.d.ts","sourceRoot":"","sources":["../../src/proxy/requestAbort.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,eAAe,CAAA;IAC3B,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACjC,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAyBtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAkCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AAiQ7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAk8FhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OutputFormat } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
export type OutputFormatParseResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
value: OutputFormat | undefined;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Parse Anthropic's `output_config.format` into the Claude Agent SDK's native
|
|
11
|
+
* structured-output option. Absence is a no-op; malformed or unsupported
|
|
12
|
+
* values are rejected at the HTTP boundary instead of failing in the SDK.
|
|
13
|
+
*
|
|
14
|
+
* Combining `tools` with `output_config.format` is rejected: structured-output
|
|
15
|
+
* mode buffers the SDK's wire events and replaces the response content with the
|
|
16
|
+
* validated result, so a tool_use turn would be swallowed and the client-driven
|
|
17
|
+
* tool loop would never see it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseOutputFormat(outputConfig: unknown, tools?: unknown): OutputFormatParseResult;
|
|
20
|
+
export declare function structuredOutputText(value: unknown): string;
|
|
21
|
+
//# sourceMappingURL=structuredOutput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structuredOutput.d.ts","sourceRoot":"","sources":["../../src/proxy/structuredOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAMlC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAyBjG;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE3D"}
|
package/dist/server.js
CHANGED
package/package.json
CHANGED