avantgate 1.3.0 → 1.4.0

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.
@@ -0,0 +1,558 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/workflow/index.ts
21
+ var workflow_exports = {};
22
+ __export(workflow_exports, {
23
+ WorkflowSagaRollbackError: () => WorkflowSagaRollbackError,
24
+ WorkflowValidationError: () => WorkflowValidationError,
25
+ defineWorkflow: () => defineWorkflow,
26
+ executeWorkflow: () => executeWorkflow
27
+ });
28
+ module.exports = __toCommonJS(workflow_exports);
29
+
30
+ // src/agent/errors.ts
31
+ var StepSuspendedError = class extends Error {
32
+ stepId;
33
+ workflowId;
34
+ metadata;
35
+ constructor(stepId, workflowId, metadata) {
36
+ super(`Step execution suspended for human approval: [${workflowId}::${stepId}]`);
37
+ this.name = "StepSuspendedError";
38
+ this.stepId = stepId;
39
+ this.workflowId = workflowId;
40
+ this.metadata = metadata;
41
+ }
42
+ };
43
+ var PiiLeakError = class extends Error {
44
+ toolName;
45
+ maskedCount;
46
+ constructor(toolName, maskedCount) {
47
+ super(`PII leak detected in tool output for "${toolName}" (${maskedCount} occurrences detected).`);
48
+ this.name = "PiiLeakError";
49
+ this.toolName = toolName;
50
+ this.maskedCount = maskedCount;
51
+ }
52
+ };
53
+ var ToolAccessDeniedError = class extends Error {
54
+ toolName;
55
+ requiredRole;
56
+ reason;
57
+ constructor(toolName, reasonOrRole) {
58
+ const isRole = Boolean(reasonOrRole && !reasonOrRole.includes(" "));
59
+ const roleMsg = isRole ? ` (requires role "${reasonOrRole}")` : "";
60
+ const reasonMsg = reasonOrRole && !isRole ? `: ${reasonOrRole}` : "";
61
+ super(`Access denied for tool "${toolName}"${roleMsg}${reasonMsg}.`);
62
+ this.name = "ToolAccessDeniedError";
63
+ this.toolName = toolName;
64
+ if (isRole) {
65
+ this.requiredRole = reasonOrRole;
66
+ } else {
67
+ this.reason = reasonOrRole;
68
+ }
69
+ }
70
+ };
71
+ var DtoValidationError = class extends Error {
72
+ toolName;
73
+ issues;
74
+ constructor(toolName, message, issues = []) {
75
+ super(`LLM DTO validation failed for tool "${toolName}": ${message}`);
76
+ this.name = "DtoValidationError";
77
+ this.toolName = toolName;
78
+ this.issues = issues;
79
+ }
80
+ };
81
+
82
+ // src/sanitizer.ts
83
+ var EMAIL_REGEX = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b/g;
84
+ var PHONE_FR_REGEX = /\b(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}\b/g;
85
+ var NIR_SSN_REGEX = /\b[12]\s*\d{2}\s*(?:0[1-9]|1[0-2]|[2-9]\d)\s*(?:0[1-9]|[1-8]\d|9[0-8]|2[ABab])\s*(?!000)\d{3}\s*(?!000)\d{3}(?:\s*\d{2})?\b/g;
86
+ var SPI_LABELLED_REGEX = /(?:(?:num[ée]ro\s+fiscal|spi|n[°o]\s*fiscal|d[ée]clarant(?: fiscal)?)\s*[:=]?\s*)\b(\d{2}(?:[\s.-]?\d{2}){5}[\s.-]?\d|\d{13})\b/gi;
87
+ var SPI_FORMATTED_REGEX = /\b[0-3]\d(?:\s+\d{2}){5}\s+\d\b/g;
88
+ var IBAN_REGEX = /\b[A-Z]{2}\s*[0-9]{2}(?:[\s\r\n.-]*[A-Z0-9]){11,30}\b/g;
89
+ var BIC_LABELLED_REGEX = /(?:(?:bic|swift)\s*[:=]?\s*)\b([A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?)\b/gi;
90
+ function sanitizePII(input) {
91
+ let count = 0;
92
+ let result = input;
93
+ result = result.replace(EMAIL_REGEX, () => {
94
+ count++;
95
+ return "[REDACTED_EMAIL]";
96
+ });
97
+ result = result.replace(PHONE_FR_REGEX, () => {
98
+ count++;
99
+ return "[REDACTED_PHONE]";
100
+ });
101
+ result = result.replace(IBAN_REGEX, (match) => {
102
+ const cleanChars = match.replace(/[\s\r\n.-]/g, "");
103
+ if (cleanChars.length >= 15 && cleanChars.length <= 34) {
104
+ count++;
105
+ return "[REDACTED_IBAN]";
106
+ }
107
+ return match;
108
+ });
109
+ result = result.replace(BIC_LABELLED_REGEX, (_, bicCode) => {
110
+ count++;
111
+ return `[REDACTED_BIC: ${bicCode.slice(0, 4)}****]`;
112
+ });
113
+ result = result.replace(SPI_LABELLED_REGEX, (fullMatch, digits) => {
114
+ count++;
115
+ return fullMatch.replace(digits, "[REDACTED_SPI]");
116
+ });
117
+ result = result.replace(NIR_SSN_REGEX, (match) => {
118
+ const rawDigits = match.replace(/\s+/g, "");
119
+ if (rawDigits.length === 13 || rawDigits.length === 15) {
120
+ count++;
121
+ return "[REDACTED_NIR]";
122
+ }
123
+ return match;
124
+ });
125
+ result = result.replace(SPI_FORMATTED_REGEX, (match) => {
126
+ if (!match.includes("[REDACTED")) {
127
+ count++;
128
+ return "[REDACTED_SPI]";
129
+ }
130
+ return match;
131
+ });
132
+ return { text: result, maskedCount: count };
133
+ }
134
+
135
+ // src/agent/guardrails.ts
136
+ function sanitizeString(value) {
137
+ const result = sanitizePII(value);
138
+ return { text: result.text, count: result.maskedCount };
139
+ }
140
+ function sanitizeArray(items, options, visited) {
141
+ let totalCount = 0;
142
+ const sanitized = items.map((item) => {
143
+ const res = recursivelySanitize(item, options, visited);
144
+ totalCount += res.count;
145
+ return res.sanitized;
146
+ });
147
+ return { sanitized, count: totalCount };
148
+ }
149
+ function sanitizeObject(target, options, visited) {
150
+ let totalCount = 0;
151
+ const copy = {};
152
+ for (const [key, val] of Object.entries(target)) {
153
+ const res = recursivelySanitize(val, options, visited);
154
+ copy[key] = res.sanitized;
155
+ totalCount += res.count;
156
+ }
157
+ return { sanitized: copy, count: totalCount };
158
+ }
159
+ function recursivelySanitize(data, options, visited = /* @__PURE__ */ new WeakSet()) {
160
+ if (typeof data === "string") {
161
+ const res = sanitizeString(data);
162
+ return { sanitized: res.text, count: res.count };
163
+ }
164
+ if (data !== null && typeof data === "object") {
165
+ if (visited.has(data)) {
166
+ return { sanitized: "[CIRCULAR_REFERENCE]", count: 0 };
167
+ }
168
+ visited.add(data);
169
+ if (Array.isArray(data)) {
170
+ return sanitizeArray(data, options, visited);
171
+ }
172
+ return sanitizeObject(data, options, visited);
173
+ }
174
+ return { sanitized: data, count: 0 };
175
+ }
176
+ function auditToolResult(data, options) {
177
+ const { sanitized, count } = recursivelySanitize(data, options);
178
+ if (options.throwOnPii && count > 0) {
179
+ throw new PiiLeakError(options.toolName, count);
180
+ }
181
+ return {
182
+ sanitizedData: sanitized,
183
+ maskedCount: count
184
+ };
185
+ }
186
+
187
+ // src/agent/isolated-tool.ts
188
+ async function verifyDataAccessGuard(guard, args, context, toolIdentifier) {
189
+ if (!guard) {
190
+ return;
191
+ }
192
+ const isAllowed = await guard(args, context);
193
+ if (!isAllowed) {
194
+ throw new ToolAccessDeniedError(toolIdentifier, "Access denied by data access guard");
195
+ }
196
+ }
197
+ async function resolveInvalidationTags(config, args, rawResult, context) {
198
+ if (!config.invalidationTags) {
199
+ return void 0;
200
+ }
201
+ const tags = typeof config.invalidationTags === "function" ? await config.invalidationTags(args, rawResult) : config.invalidationTags;
202
+ if (tags && tags.length > 0 && context?.onInvalidationTags) {
203
+ await context.onInvalidationTags(tags);
204
+ }
205
+ return tags;
206
+ }
207
+ async function dispatchClientData(rawResult, callback) {
208
+ if (!callback) {
209
+ return;
210
+ }
211
+ await callback(rawResult);
212
+ }
213
+ async function produceLlmPayload(rawResult, args, context, transformer) {
214
+ if (transformer) {
215
+ return await transformer(rawResult, args, context);
216
+ }
217
+ return rawResult;
218
+ }
219
+ function validateLlmDto(payload, schema, toolIdentifier) {
220
+ const parseResult = schema.safeParse(payload);
221
+ if (!parseResult.success) {
222
+ const issues = parseResult.error.issues ?? [];
223
+ const errorMessages = issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join(", ");
224
+ throw new DtoValidationError(
225
+ toolIdentifier,
226
+ errorMessages,
227
+ issues
228
+ );
229
+ }
230
+ return parseResult.data;
231
+ }
232
+ function protectLlmPayload(payload, toolIdentifier, sanitizePii = true, throwOnPii = false) {
233
+ if (!sanitizePii) {
234
+ return { sanitized: payload, count: 0 };
235
+ }
236
+ const { sanitizedData, maskedCount } = auditToolResult(payload, {
237
+ toolName: toolIdentifier,
238
+ throwOnPii
239
+ });
240
+ return { sanitized: sanitizedData, count: maskedCount };
241
+ }
242
+ async function processLlmPayload(rawResult, args, context, config, toolIdentifier) {
243
+ let payload = await produceLlmPayload(rawResult, args, context, config.llmDto);
244
+ if (config.llmDtoSchema) {
245
+ payload = validateLlmDto(payload, config.llmDtoSchema, toolIdentifier);
246
+ }
247
+ return protectLlmPayload(
248
+ payload,
249
+ toolIdentifier,
250
+ config.sanitizePii !== false,
251
+ config.throwOnPii === true
252
+ );
253
+ }
254
+ function createIsolatedTool(config) {
255
+ const toolId = config.id || config.name;
256
+ const toolAlias = config.alias;
257
+ const clientCallback = config.clientDto;
258
+ const toolIdentifier = toolAlias || config.name;
259
+ const toolImpact = config.impact ?? "READ_ONLY";
260
+ const requireApproval = config.requireApproval ?? toolImpact === "DESTRUCTIVE";
261
+ const tool = {
262
+ description: config.description,
263
+ parameters: config.parameters,
264
+ _toolId: toolId,
265
+ _toolName: config.name,
266
+ _toolAlias: toolAlias,
267
+ _isIsolated: true,
268
+ _cacheTTL: config.cacheTTL,
269
+ _domain: config.domain,
270
+ _resource: config.resource,
271
+ _roles: config.roles ? Object.freeze([...config.roles]) : void 0,
272
+ _impact: toolImpact,
273
+ _requireApproval: requireApproval,
274
+ _lastPiiFilteredCount: 0,
275
+ _lastInvalidationTags: void 0,
276
+ async execute(args, context) {
277
+ const updatedContext = {
278
+ ...context,
279
+ callChain: context?.callChain ?? Object.freeze([toolId])
280
+ };
281
+ await verifyDataAccessGuard(
282
+ config.dataAccessGuard,
283
+ args,
284
+ updatedContext,
285
+ toolIdentifier
286
+ );
287
+ const rawResult = await config.execute(args, updatedContext);
288
+ const tags = await resolveInvalidationTags(
289
+ config,
290
+ args,
291
+ rawResult,
292
+ updatedContext
293
+ );
294
+ if (tags) {
295
+ tool._lastInvalidationTags = tags;
296
+ }
297
+ await dispatchClientData(rawResult, clientCallback);
298
+ const protection = await processLlmPayload(
299
+ rawResult,
300
+ args,
301
+ updatedContext,
302
+ config,
303
+ toolIdentifier
304
+ );
305
+ tool._lastPiiFilteredCount = protection.count;
306
+ return protection.sanitized;
307
+ }
308
+ };
309
+ return tool;
310
+ }
311
+
312
+ // src/workflow/errors.ts
313
+ var WorkflowSagaRollbackError = class extends Error {
314
+ workflowId;
315
+ failedStepId;
316
+ originalError;
317
+ compensatedSteps;
318
+ failedCompensations;
319
+ constructor(params) {
320
+ const errorDetails = params.originalError instanceof Error ? params.originalError.message : String(params.originalError);
321
+ super(
322
+ `\xC9chec de l'\xE9tape '${params.failedStepId}' dans le workflow '${params.workflowId}'. Rollback Saga ex\xE9cut\xE9 sur [${params.compensatedSteps.join(", ")}]. Cause initiale: ${errorDetails}`
323
+ );
324
+ this.name = "WorkflowSagaRollbackError";
325
+ this.workflowId = params.workflowId;
326
+ this.failedStepId = params.failedStepId;
327
+ this.originalError = params.originalError;
328
+ this.compensatedSteps = params.compensatedSteps;
329
+ this.failedCompensations = params.failedCompensations ?? [];
330
+ }
331
+ };
332
+ var WorkflowValidationError = class extends Error {
333
+ workflowId;
334
+ issues;
335
+ constructor(workflowId, issues) {
336
+ super(`Validation des entr\xE9es \xE9chou\xE9e pour le workflow '${workflowId}'.`);
337
+ this.name = "WorkflowValidationError";
338
+ this.workflowId = workflowId;
339
+ this.issues = issues;
340
+ }
341
+ };
342
+
343
+ // src/workflow/engine.ts
344
+ function generateRunId(workflowId) {
345
+ const timestamp = Date.now();
346
+ const randomSuffix = Math.random().toString(36).substring(2, 9);
347
+ return `run_${workflowId}_${timestamp}_${randomSuffix}`;
348
+ }
349
+ function validateInput(config, input) {
350
+ const parseResult = config.inputSchema.safeParse(input);
351
+ if (!parseResult.success) {
352
+ throw new WorkflowValidationError(config.id, parseResult.error.issues);
353
+ }
354
+ return parseResult.data;
355
+ }
356
+ function createStepContext(params) {
357
+ const { workflowId, stepId, runId, context, stepResults } = params;
358
+ return {
359
+ workflowId,
360
+ stepId,
361
+ runId,
362
+ tenantId: context?.tenantId,
363
+ userId: context?.userId,
364
+ services: context?.services ?? {},
365
+ storage: context?.storage,
366
+ getStepResult: (id) => stepResults[id],
367
+ waitForApproval: async (options) => {
368
+ if (context?.storage) {
369
+ const existing = await context.storage.getStep(workflowId, stepId);
370
+ if (existing && existing.status === "COMPLETED") {
371
+ return existing.result ?? options?.defaultResult;
372
+ }
373
+ const now = (/* @__PURE__ */ new Date()).toISOString();
374
+ await context.storage.saveStep({
375
+ workflowId,
376
+ stepId,
377
+ runId,
378
+ status: "WAITING_APPROVAL",
379
+ metadata: options?.metadata,
380
+ createdAt: now,
381
+ updatedAt: now
382
+ });
383
+ }
384
+ throw new StepSuspendedError(stepId, workflowId, options?.prompt);
385
+ }
386
+ };
387
+ }
388
+ async function rollbackSaga(params) {
389
+ const {
390
+ workflowId,
391
+ failedStepId,
392
+ originalError,
393
+ completedSteps,
394
+ input,
395
+ runId,
396
+ context,
397
+ stepResults
398
+ } = params;
399
+ const compensatedSteps = [];
400
+ const failedCompensations = [];
401
+ for (let i = completedSteps.length - 1; i >= 0; i--) {
402
+ const { step, result } = completedSteps[i];
403
+ if (!step.compensate) {
404
+ continue;
405
+ }
406
+ const stepCtx = createStepContext({
407
+ workflowId,
408
+ stepId: step.id,
409
+ runId,
410
+ context,
411
+ stepResults
412
+ });
413
+ try {
414
+ await step.compensate(result, input, stepCtx);
415
+ compensatedSteps.push(step.id);
416
+ if (context?.storage) {
417
+ await context.storage.updateStepStatus(workflowId, step.id, "FAILED", {
418
+ metadata: { compensated: true }
419
+ });
420
+ }
421
+ } catch (compensationError) {
422
+ failedCompensations.push({ stepId: step.id, error: compensationError });
423
+ }
424
+ }
425
+ throw new WorkflowSagaRollbackError({
426
+ workflowId,
427
+ failedStepId,
428
+ originalError,
429
+ compensatedSteps,
430
+ failedCompensations
431
+ });
432
+ }
433
+ async function executeWorkflow(config, rawInput, context) {
434
+ const input = validateInput(config, rawInput);
435
+ const runId = context?.runId ?? generateRunId(config.id);
436
+ const stepResults = {};
437
+ const completedSteps = [];
438
+ for (const step of config.steps) {
439
+ const stepCtx = createStepContext({
440
+ workflowId: config.id,
441
+ stepId: step.id,
442
+ runId,
443
+ context,
444
+ stepResults
445
+ });
446
+ try {
447
+ const result = await step.execute(input, stepCtx);
448
+ stepResults[step.id] = result;
449
+ completedSteps.push({ step, result });
450
+ if (context?.storage) {
451
+ await context.storage.updateStepStatus(config.id, step.id, "COMPLETED", { result });
452
+ }
453
+ } catch (error) {
454
+ if (error instanceof StepSuspendedError) {
455
+ return {
456
+ workflowId: config.id,
457
+ runId,
458
+ status: "WAITING_APPROVAL",
459
+ stepResults
460
+ };
461
+ }
462
+ await rollbackSaga({
463
+ workflowId: config.id,
464
+ failedStepId: step.id,
465
+ originalError: error,
466
+ completedSteps,
467
+ input,
468
+ runId,
469
+ context,
470
+ stepResults
471
+ });
472
+ }
473
+ }
474
+ const finalOutput = config.outputDto ? config.outputDto(stepResults, input) : stepResults;
475
+ return {
476
+ workflowId: config.id,
477
+ runId,
478
+ status: "COMPLETED",
479
+ stepResults,
480
+ output: finalOutput
481
+ };
482
+ }
483
+
484
+ // src/workflow/define-workflow.ts
485
+ function resolveWorkflowImpact(config, options) {
486
+ if (options?.impact) {
487
+ return options.impact;
488
+ }
489
+ return config.impact ?? "MUTATIVE";
490
+ }
491
+ function resolveRequireApproval(impact, options) {
492
+ if (options?.requireApproval !== void 0) {
493
+ return options.requireApproval;
494
+ }
495
+ return impact === "DESTRUCTIVE";
496
+ }
497
+ function buildToolExecutionContext(options, toolCtx) {
498
+ const tenantId = typeof toolCtx?.tenantId === "string" ? toolCtx.tenantId : options?.defaultContext?.tenantId;
499
+ const userId = typeof toolCtx?.userId === "string" ? toolCtx.userId : options?.defaultContext?.userId;
500
+ return {
501
+ tenantId,
502
+ userId,
503
+ services: options?.defaultContext?.services ?? {},
504
+ storage: options?.storage ?? options?.defaultContext?.storage
505
+ };
506
+ }
507
+ function defineWorkflow(config) {
508
+ const workflowImpact = config.impact ?? "MUTATIVE";
509
+ return {
510
+ id: config.id,
511
+ name: config.name,
512
+ description: config.description,
513
+ impact: workflowImpact,
514
+ roles: config.roles,
515
+ config,
516
+ execute: async (input, context) => {
517
+ return await executeWorkflow(config, input, context);
518
+ },
519
+ asTool: (options) => {
520
+ const impact = resolveWorkflowImpact(config, options);
521
+ const requireApproval = resolveRequireApproval(impact, options);
522
+ const tool = createIsolatedTool({
523
+ name: config.id,
524
+ description: config.description ?? config.name,
525
+ roles: config.roles,
526
+ impact,
527
+ requireApproval,
528
+ parameters: config.inputSchema,
529
+ invalidationTags: typeof config.invalidationTags === "function" ? async (args, res) => {
530
+ const resolver = config.invalidationTags;
531
+ return await resolver(args, res ?? {});
532
+ } : config.invalidationTags,
533
+ execute: async (args, toolCtx) => {
534
+ const executionContext = buildToolExecutionContext(options, toolCtx);
535
+ const result = await executeWorkflow(config, args, executionContext);
536
+ return result.output;
537
+ },
538
+ llmDto: (result) => result
539
+ });
540
+ Object.assign(tool, {
541
+ _isWorkflow: true,
542
+ workflowId: config.id,
543
+ workflowConfig: {
544
+ totalSteps: config.steps.length,
545
+ impact
546
+ }
547
+ });
548
+ return tool;
549
+ }
550
+ };
551
+ }
552
+ // Annotate the CommonJS export names for ESM import in node:
553
+ 0 && (module.exports = {
554
+ WorkflowSagaRollbackError,
555
+ WorkflowValidationError,
556
+ defineWorkflow,
557
+ executeWorkflow
558
+ });
@@ -0,0 +1,13 @@
1
+ import {
2
+ WorkflowSagaRollbackError,
3
+ WorkflowValidationError,
4
+ defineWorkflow,
5
+ executeWorkflow
6
+ } from "../chunk-DTM2OLCG.mjs";
7
+ import "../chunk-5VA3EKPJ.mjs";
8
+ export {
9
+ WorkflowSagaRollbackError,
10
+ WorkflowValidationError,
11
+ defineWorkflow,
12
+ executeWorkflow
13
+ };
@@ -0,0 +1,64 @@
1
+ import type { ZodType } from "zod";
2
+ import type { IsolatedTool, StepApprovalOptions, StepStorageAdapter, ToolImpact } from "../agent/types";
3
+ export interface WorkflowStepContext {
4
+ readonly workflowId: string;
5
+ readonly stepId: string;
6
+ readonly runId?: string;
7
+ readonly tenantId?: string;
8
+ readonly userId?: string;
9
+ readonly services: Record<string, any>;
10
+ readonly storage?: StepStorageAdapter;
11
+ getStepResult<T = unknown>(stepId: string): T | undefined;
12
+ waitForApproval<T = unknown>(options?: StepApprovalOptions<T>): Promise<T>;
13
+ }
14
+ export interface WorkflowStepConfig<TInput = any, TOutput = any> {
15
+ id: string;
16
+ name: string;
17
+ description?: string;
18
+ impact?: ToolImpact;
19
+ checkpoint?: boolean;
20
+ execute: (input: TInput, ctx: WorkflowStepContext) => Promise<TOutput>;
21
+ compensate?: (stepResult: TOutput, input: TInput, ctx: WorkflowStepContext) => Promise<void>;
22
+ }
23
+ export interface WorkflowConfig<TInput = any, TOutput = any> {
24
+ id: string;
25
+ name: string;
26
+ description?: string;
27
+ inputSchema: ZodType<TInput>;
28
+ roles?: string[];
29
+ impact?: ToolImpact;
30
+ invalidationTags?: string[] | ((input: TInput, results: Record<string, any>) => string[] | Promise<string[]>);
31
+ steps: WorkflowStepConfig<TInput, any>[];
32
+ outputDto?: (results: Record<string, any>, input: TInput) => TOutput;
33
+ }
34
+ export interface WorkflowExecutionContext {
35
+ tenantId?: string;
36
+ userId?: string;
37
+ runId?: string;
38
+ services?: Record<string, any>;
39
+ storage?: StepStorageAdapter;
40
+ }
41
+ export interface WorkflowAsToolOptions {
42
+ storage?: StepStorageAdapter;
43
+ impact?: ToolImpact;
44
+ requireApproval?: boolean;
45
+ defaultContext?: Partial<WorkflowExecutionContext>;
46
+ }
47
+ export interface WorkflowExecutionResult<TOutput = any> {
48
+ workflowId: string;
49
+ runId: string;
50
+ status: "COMPLETED" | "FAILED" | "WAITING_APPROVAL";
51
+ stepResults: Record<string, any>;
52
+ output?: TOutput;
53
+ }
54
+ export interface WorkflowInstance<TInput = any, TOutput = any> {
55
+ readonly id: string;
56
+ readonly name: string;
57
+ readonly description?: string;
58
+ readonly impact: ToolImpact;
59
+ readonly roles?: string[];
60
+ readonly config: WorkflowConfig<TInput, TOutput>;
61
+ execute(input: TInput, context?: WorkflowExecutionContext): Promise<WorkflowExecutionResult<TOutput>>;
62
+ asTool(options?: WorkflowAsToolOptions): IsolatedTool<TInput, TOutput>;
63
+ }
64
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workflow/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "avantgate",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Zero-infrastructure, in-process AI Application Firewall (AI-WAF) & privacy control plane for TypeScript: real-time prompt guardrails, zero-egress PII redaction, agent tool isolation, anti-IDOR defense, pre-flight token budgets, and multi-model failover.",
5
5
  "author": "Antigravity & LexTalk Team",
6
6
  "license": "MIT",
@@ -54,6 +54,11 @@
54
54
  "import": "./dist/agent/index.mjs",
55
55
  "require": "./dist/agent/index.js"
56
56
  },
57
+ "./workflow": {
58
+ "types": "./dist/workflow/index.d.ts",
59
+ "import": "./dist/workflow/index.mjs",
60
+ "require": "./dist/workflow/index.js"
61
+ },
57
62
  "./package.json": "./package.json"
58
63
  },
59
64
  "files": [
@@ -62,12 +67,13 @@
62
67
  "LICENSE"
63
68
  ],
64
69
  "scripts": {
65
- "build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
66
- "test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && npm run test:agent",
70
+ "build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts src/workflow/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
71
+ "test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && npm run test:agent && npm run test:workflow",
67
72
  "test:finance": "tsx tests/financial-normalizer.test.ts",
68
73
  "test:prompts": "tsx tests/prompt-builder.test.ts",
69
74
  "test:pii": "tsx tests/pii-extended.test.ts",
70
75
  "test:agent": "tsx tests/agent/step-runner.test.ts && tsx tests/agent/isolated-tool.test.ts && tsx tests/agent/dto-pattern.test.ts && tsx tests/agent/tool-patterns.test.ts && tsx tests/agent/storage-adapters.test.ts && tsx tests/agent/tool-aliasing.test.ts && tsx tests/agent/tool-chaining.test.ts && tsx tests/agent/tool-storage.test.ts && tsx tests/agent/telemetry-exporter.test.ts && tsx tests/agent/platform-adapter.test.ts && tsx tests/agent/tool-governance.test.ts && tsx tests/agent/tool-impact.test.ts",
76
+ "test:workflow": "tsx tests/workflow/workflow-saga.test.ts",
71
77
  "lint": "tsc --noEmit",
72
78
  "prepublishOnly": "npm run build && npm test"
73
79
  },