bb855d2ddc
* feat(branding): implement dynamic branding in service worker and reports * feat(auth): enhance API key scopes and add bookkeeping write scope - Updated transaction write scope description to include additional tools. - Enhanced reports read scope description to reflect new functionality. - Introduced bookkeeping write scope with relevant description. - Updated SCOPE_GROUPS to include bookkeeping domain. - Modified TOOL_SCOPE_MAP to include new bookkeeping operations. - Updated validateApiKey function to return api_key_id and api_key_name for better actor attribution. feat(tests): add unit tests for MCP resource registry - Created tests for data resources to ensure all required fields are present. - Added tests for resource query parsing and retrieval. feat(resources): implement MCP resources for company and accounting data - Added capabilities resource to expose API key capabilities based on granted scopes. - Implemented chart of accounts resource to retrieve active BAS chart. - Created company current resource to fetch active company details. - Developed active fiscal period resource to check posting eligibility. - Implemented recent activity resource to fetch latest journal entries, invoices, and transactions. - Added VAT treatments resource to provide available VAT rates per customer type. feat(pending-operations): introduce risk tiers for operations - Added risk level classification for pending operations to determine auto-commit eligibility. - Implemented functions to classify operation risk levels and identify high-risk operations. feat(migrations): add actor model and risk tier to pending operations - Updated pending_operations table to include actor type and risk level columns. - Enhanced audit_log to mirror actor information for compliance. - Modified validate_and_increment_api_key function to return actor details. - Expanded operation types in pending_operations to include new high-risk operations. * feat: add auto-commit functionality for low-risk pending operations - Implemented shouldAutoCommit function to determine eligibility for auto-commit based on operation type, actor type, and company settings. - Created commitPendingOperation function to handle execution of pending operations with consistent status updates. - Added tests for shouldAutoCommit to cover various scenarios including high-risk operations, user actors, company opt-in status, and monetary thresholds. - Introduced new columns in company_settings for agent_auto_commit_enabled and agent_auto_commit_max_amount to allow companies to opt-in for auto-commit functionality. - Added SQL migration to update the database schema for new auto-commit settings. * feat(idempotency): implement idempotency key handling for safe retries and cleanup * feat: expand API key scopes and pending operations for bookkeeping - Added 'suppliers:write' scope to API key scopes for supplier invoice management. - Updated SCOPE_GROUPS to include the new 'suppliers:write' scope. - Introduced new pending operation types for bookkeeping: close_period, lock_period, run_year_end, set_opening_balances, run_currency_revaluation, explain_voucher_gap, uncategorize_transaction, approve_supplier_invoice, credit_supplier_invoice, and convert_invoice. - Implemented corresponding commit functions for the new operations in the pending operations module. - Enhanced PendingOperation type to include actor model and risk level attributes. - Added tests for new functionality, ensuring proper behavior and constraints in the database. * feat: implement unlockPeriod functionality and related tests * feat: add agent auto-commit settings and related functionality * feat: add attention resource with comprehensive summary of outstanding tasks * feat: enhance pending operations with 'committing' status and immutability checks, improve idempotency handling, and add original voucher reference for credit notes
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
/**
|
|
* Helpers for shaping MCP tool results in an agent-actionable form.
|
|
*
|
|
* Two additive concepts:
|
|
* 1. `next` — when a tool succeeds and there's an obvious follow-up tool or
|
|
* resource the agent should call, expose it directly so Claude doesn't
|
|
* have to re-derive it from prose.
|
|
* 2. structured errors — failures include a stable code, English + Swedish
|
|
* messages, and a remediation hint when one exists.
|
|
*
|
|
* Both are folded into the JSON `text` payload that the JSON-RPC handler
|
|
* already serializes — no protocol change needed, and existing string-only
|
|
* consumers keep working.
|
|
*/
|
|
import { getStructuredError, type StructuredError } from '@/lib/errors/get-structured-error'
|
|
|
|
export interface NextActionHint {
|
|
description: string
|
|
tool?: string
|
|
args?: Record<string, unknown>
|
|
resource?: string
|
|
}
|
|
|
|
export interface AgentToolResult<T = unknown> {
|
|
data: T
|
|
next?: NextActionHint
|
|
}
|
|
|
|
export interface AgentToolError {
|
|
error: StructuredError
|
|
}
|
|
|
|
/**
|
|
* Wrap a successful tool payload with an optional `next` hint. Returns the
|
|
* payload as-is if the input is already wrapped (idempotent), or a plain object
|
|
* if no hint is supplied.
|
|
*/
|
|
export function withNext<T>(data: T, next?: NextActionHint): AgentToolResult<T> {
|
|
return next ? { data, next } : { data }
|
|
}
|
|
|
|
/**
|
|
* Convert a thrown error into the structured tool-error envelope the agent
|
|
* sees. If the error is a string already containing "Insufficient scope:",
|
|
* the attempted scope is propagated to the remediation hint so the agent can
|
|
* surface a precise request to the user.
|
|
*/
|
|
export function toToolError(err: unknown, opts: { toolName?: string } = {}): AgentToolError {
|
|
let attemptedScope: string | undefined
|
|
const message = err instanceof Error ? err.message : typeof err === 'string' ? err : ''
|
|
const scopeMatch = message.match(/Insufficient scope: this API key does not have the "([^"]+)" scope/)
|
|
if (scopeMatch) attemptedScope = scopeMatch[1]
|
|
|
|
return {
|
|
error: getStructuredError(err, { attemptedScope, toolName: opts.toolName }),
|
|
}
|
|
}
|