CommunityCodierung & Entwicklunggithub.com

joshi-chinmay-016/AgentProof

Best Practices für die Implementierung von Guards, Interceptors, Middleware, Pipes und Exception-Filtern im NitroStack SDK.

Was ist AgentProof?

Diese Skill bietet eine umfassende Anleitung zur Implementierung von Verarbeitungspipelines in NitroStack-Tools. Sie beschreibt fünf zentrale Konzepte: Guards (Zugriffskontrolle), Interceptors (Transformation von Ein- und Ausgaben), Middleware (Vor- und Nachbereitung der Ausführung), Pipes (Validierung und Umwandlung von Eingabeargumenten) und Exception-Filter (zentralisierte Fehlerbehandlung). Jedes Konzept wird mit seiner Schnittstelle, einem konkreten Beispiel und der Anwendung über Dekorateure (@UseGuards, @UseInterceptors, @UseMiddleware, @UsePipes, @UseFilters) erläutert. Die Skill ist primär für Entwickler gedacht, die Tools mit dem NitroStack SDK erstellen, und hilft, robuste, sicherheitsgeprüfte und wartbare Tool-Methoden zu definieren. Plattform: NitroStack (TypeScript/Node.js).

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/joshi-chinmay-016/AgentProof/tree/HEAD/agentproof/.agents/skills/middleware-pipeline

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Wann verwenden

Verwenden Sie diese Skill, wenn Sie Anforderungsvalidierung, Autorisierungsprüfungen, Antwortzuordnung, Protokollierung, Fehlerbehandlung oder Leistungsverfolgung in NitroStack-Toolmethoden implementieren möchten.


1. Guards (Guard und @UseGuards)

Guards bestimmen, ob eine Anfrage von einem Tool-Handler basierend auf Authentifizierung, Autorisierung oder anderen Bedingungen verarbeitet werden soll.

Schnittstelle:

import { Guard, ExecutionContext } from '@nitrostack/core';

export interface Guard {
  canActivate(context: ExecutionContext): boolean | Promise<boolean>;
}

Beispiel:

import { Guard, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class RolesGuard implements Guard {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const userRoles = context.clientMetadata?.roles || [];
    return userRoles.includes('admin');
  }
}

Wenden Sie den Guard mit @UseGuards(...) an:

import { Tool, UseGuards, z } from '@nitrostack/core';
import { RolesGuard } from './roles.guard.js';

export class AdminTools {
  @Tool({
    name: 'delete_system_logs',
    description: 'Alle Systemprotokolle vom Server löschen.',
    inputSchema: z.object({}),
  })
  @UseGuards(RolesGuard)
  async deleteLogs() {
    return { success: true };
  }
}

2. Interceptors (InterceptorInterface und @UseInterceptors)

Interceptor können Eingabeargumente oder die zugeordnete Ausgabe einer Tool-Methodenausführung transformieren/abfangen.

Schnittstelle:

import { ExecutionContext } from '@nitrostack/core';

export interface InterceptorInterface {
  intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}

Beispiel:

import { InterceptorInterface, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class TimingInterceptor implements InterceptorInterface {
  async intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
    const start = Date.now();
    const result = await next();
    const duration = Date.now() - start;
    context.logger.info(`Ausführung dauerte ${duration}ms`);
    return {
      ...result,
      _meta: { durationMs: duration }
    };
  }
}

3. Exception-Filter (ExceptionFilterInterface und @UseFilters)

Exception-Filter fangen alle Fehler ab, die in Guards, Interceptors oder den Tool-Handlern selbst geworfen werden, und wandeln sie in benutzerfreundliche JSON-Payloads um.

Schnittstelle:

import { ExecutionContext } from '@nitrostack/core';

export interface ExceptionFilterInterface {
  catch(exception: unknown, context: ExecutionContext): unknown | Promise<unknown>;
}

Beispiel:

import { ExceptionFilterInterface, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class CustomExceptionFilter implements ExceptionFilterInterface {
  catch(exception: unknown, context: ExecutionContext) {
    const message = exception instanceof Error ? exception.message : 'Unbekannter Fehler';
    return {
      error: true,
      message,
      timestamp: new Date().toISOString()
    };
  }
}

Wenden Sie den Filter mit @UseFilters(...) auf einer Tool-Methode an:

import { Tool, UseFilters, z } from '@nitrostack/core';
import { CustomExceptionFilter } from './custom-exception.filter.js';

export class LoggingTools {
  @Tool({
    name: 'generate_report',
    description: 'Erstellt Systemnutzungsberichte.',
    inputSchema: z.object({}),
  })
  @UseFilters(CustomExceptionFilter)
  async generateReport() {
    throw new Error('Berichtserstellung ist noch nicht implementiert.');
  }
}

4. Middleware (MiddlewareInterface, @Middleware und @UseMiddleware)

Middleware wird ausgeführt, bevor die Anfrage den Tool-Handler erreicht, und kann die Handler-Ausführung durch Aufruf von next() umschließen.

Schnittstelle:

import { ExecutionContext } from '@nitrostack/core';

export interface MiddlewareInterface {
  use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}

Beispiel:

import { Middleware, MiddlewareInterface, ExecutionContext } from '@nitrostack/core';

@Middleware()
export class LoggingMiddleware implements MiddlewareInterface {
  async use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
    context.logger.info(`Betrete Tool: ${context.toolName}`);
    try {
      const result = await next();
      context.logger.info(`Verlasse Tool: ${context.toolName}`);
      return result;
    } catch (error) {
      context.logger.error(`Fehler in Tool: ${error}`);
      throw error;
    }
  }
}

Wenden Sie die Middleware mit @UseMiddleware(...) auf einer Tool-Methode an:

import { Tool, UseMiddleware, z } from '@nitrostack/core';
import { LoggingMiddleware } from './logging.middleware.js';

export class StationTools {
  @Tool({
    name: 'fetch_logs',
    description: 'Ruft Stationsbetriebsprotokolle ab.',
    inputSchema: z.object({}),
  })
  @UseMiddleware(LoggingMiddleware)
  async fetchLogs() {
    return { status: 'operational' };
  }
}

5. Pipes (PipeInterface, @Pipe und @UsePipes)

Pipes werden verwendet, um Eingabeargumente zu transformieren oder zu validieren, bevor sie die Tool-Handler-Methode erreichen.

Schnittstelle:

import { ArgumentMetadata } from '@nitrostack/core';

export interface PipeInterface<T = unknown, R = unknown> {
  transform(value: T, metadata: ArgumentMetadata): R | Promise<R>;
}

Beispiel:

import { Pipe, PipeInterface, ArgumentMetadata } from '@nitrostack/core';

@Pipe()
export class TrimPipe implements PipeInterface<Record<string, unknown>, Record<string, unknown>> {
  transform(value: Record<string, unknown>, metadata: ArgumentMetadata) {
    const trimmed: Record<string, unknown> = {};
    for (const [key, val] of Object.entries(value)) {
      trimmed[key] = typeof val === 'string' ? val.trim() : val;
    }
    return trimmed;
  }
}

Wenden Sie die Pipe mit @UsePipes(...) auf einer Tool-Methode an:

import { Tool, UsePipes, z } from '@nitrostack/core';
import { TrimPipe } from './trim.pipe.js';

export class MessagingTools {
  @Tool({
    name: 'send_message',
    description: 'Sende eine Nachricht an andere Stationen.',
    inputSchema: z.object({ text: z.string() }),
  })
  @UsePipes(TrimPipe)
  async sendMessage(input: { text: string }) {
    return { sentText: input.text };
  }
}

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Verwandte Skills