The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.
Commit 5dab768c
5dab768c7927Merged
aryaamin <[email protected]> · 2 months ago · 1 file · ~1 modified
Description
fix: bound fast shield reasoning
Details
- Commit
- 5dab768c7927
- Parent
- c2393f876b9d
packages/mcp-server/src/shield-agent.tsmodifiedView file
@@ -1,6 +1,14 @@
11
import crypto from 'node:crypto';2-
import { createAnthropic } from '@ai-sdk/anthropic';3-
import { generateText, isStepCount, Output, ToolLoopAgent, tool } from 'ai';2+
import { createAnthropic, type AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';3+
import {4+
generateText,5+
isStepCount,6+
NoObjectGeneratedError,7+
NoOutputGeneratedError,8+
Output,9+
ToolLoopAgent,10+
tool,11+
} from 'ai';412
import { z } from 'zod';513
import {614
ShieldAnalysisSchema,@@ -18,7 +26,7 @@
1826
type ShieldPolicy,1927
} from '../../protocol/src/index.js';2028
21-
export const SHIELD_PROMPT_VERSION = 'shield-agent-v2';29+
export const SHIELD_PROMPT_VERSION = 'shield-agent-v3';2230
export const DEFAULT_SHIELD_MODEL = 'claude-sonnet-5';2331
const DEFAULT_SHIELD_TIMEOUT_MS = 50_000;2432
@@ -277,11 +285,29 @@
277285
instructions: fastShieldInstructions(),278286
prompt: generationPrompt(caseRecord, consultation, previousConsultations),279287
output: Output.object({ schema: ShieldAnalysisSchema }),280-
maxOutputTokens: 2500,288+
maxOutputTokens: 3000,289+
providerOptions: {290+
anthropic: {291+
thinking: { type: 'disabled' },292+
effort: 'low',293+
} satisfies AnthropicLanguageModelOptions,294+
},281295
abortSignal: AbortSignal.timeout(shieldTimeoutMs()),282296
});297+
let output: ShieldAnalysis;298+
try {299+
output = ShieldAnalysisSchema.parse(result.output);300+
} catch (error) {301+
if (NoOutputGeneratedError.isInstance(error)) {302+
Object.assign(error, {303+
openclaspFinishReason: result.finishReason,304+
openclaspTotalTokens: result.usage.totalTokens,305+
});306+
}307+
throw error;308+
}283309
return {284-
analysis: ShieldAnalysisSchema.parse(result.output),310+
analysis: output,285311
model: `anthropic/${model}`,286312
strategy: 'fast',287313
tokenUsage: {@@ -407,6 +433,29 @@
407433
});408434
}409435
436+
function generationErrorMetadata(error: unknown) {437+
if (NoObjectGeneratedError.isInstance(error)) {438+
return {439+
finishReason: error.finishReason,440+
totalTokens: error.usage?.totalTokens,441+
generatedTextLength: error.text?.length,442+
cause: error.cause instanceof Error ? error.cause.name : undefined,443+
};444+
}445+
if (NoOutputGeneratedError.isInstance(error)) {446+
const metadata = error as typeof error & {447+
openclaspFinishReason?: string;448+
openclaspTotalTokens?: number;449+
};450+
return {451+
finishReason: metadata.openclaspFinishReason,452+
totalTokens: metadata.openclaspTotalTokens,453+
cause: error.cause instanceof Error ? error.cause.name : undefined,454+
};455+
}456+
return {};457+
}458+
410459
export async function consultShield(411460
caseValue: ShieldCase,412461
consultationValue: ShieldConsultInput,@@ -448,6 +497,7 @@
448497
strategy: consultationInput.analysisDepth,449498
durationMs: Date.now() - startedAt,450499
model: process.env.OPENCLASP_SHIELD_MODEL?.trim() || DEFAULT_SHIELD_MODEL,500+
...generationErrorMetadata(error),451501
});452502
}453503
const consultationId = crypto.randomUUID();