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();