WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7df83b6
feat: improve processor primitive
DanielSLew Dec 5, 2025
12e5d2e
fix types
DanielSLew Dec 5, 2025
eeaf923
fix: simplify retryProcessorId access in llm-execution-step
DanielSLew Dec 5, 2025
6de603b
fix: add type narrowing for tripwire result in runner.ts
DanielSLew Dec 5, 2025
946e264
fix: correct processor step output schema type in workflow.ts
DanielSLew Dec 5, 2025
0e1c99a
fix: correct ZodLiteral def access (values -> value)
DanielSLew Dec 5, 2025
b357213
fix: improve type definitions for processor finish reasons
DanielSLew Dec 5, 2025
fd20038
fix: support both Zod v3 and v4 for ZodLiteral field type inference
DanielSLew Dec 5, 2025
d216181
fix: add tripwire types to StepFailure and WorkflowRunState
DanielSLew Dec 5, 2025
3672baf
fix: remove unnecessary as any cast in workflow-default-node.tsx
DanielSLew Dec 5, 2025
43e5989
fix: use !== undefined for tripwire metadata truthiness check
DanielSLew Dec 5, 2025
6fa1984
fix: remove duplicate TripwireData type definition
DanielSLew Dec 5, 2025
73d32e5
fix: add MastraFinishReason type and fix ai-sdk build error
DanielSLew Dec 8, 2025
6dbd64c
fix: handle MessageList returns from processInput in workflow.ts
DanielSLew Dec 8, 2025
de5899d
fix: map tripwire/retry to 'other' in AI SDK finish reason conversion
DanielSLew Dec 8, 2025
31f1a1b
fix: handle system messages in all processor phase returns
DanielSLew Dec 8, 2025
e357357
lint
DanielSLew Dec 8, 2025
0242c3b
refactor: consolidate tripwire fields into single object
DanielSLew Dec 8, 2025
c1d45d0
refactor: unify tripwire data to use 'reason' field consistently
DanielSLew Dec 8, 2025
382d3d1
clean up
DanielSLew Dec 8, 2025
8a1545c
merge main
DanielSLew Dec 8, 2025
4f8fe9a
fix: use LanguageModel instance instead of string in wrapLanguageModel
DanielSLew Dec 8, 2025
d1fe0dc
docs: clarify maxProcessorRetries JSDoc comment
DanielSLew Dec 8, 2025
208ece0
fix: avoid unnecessary workflow type mutation in combineProcessorsInt…
DanielSLew Dec 8, 2025
fbb7694
tripwire fixes
DanielSLew Dec 8, 2025
58d1208
fix: align playground TripwireData schema with core
DanielSLew Dec 8, 2025
2b96ecf
fix: update remaining tripwireReason references to use reason
DanielSLew Dec 8, 2025
c93d7fd
fix: properly handle tripwire status in workflow streams
DanielSLew Dec 8, 2025
4250136
fix tests
DanielSLew Dec 8, 2025
65a9ef7
fix more tests
DanielSLew Dec 8, 2025
778a49e
fix: update snapshots for tripwire field and fix context message sour…
DanielSLew Dec 8, 2025
a358e2e
fix: result.text now reflects output processor modifications
DanielSLew Dec 8, 2025
b49d156
add docs and changesets
DanielSLew Dec 8, 2025
f78f05b
cleanup
DanielSLew Dec 8, 2025
644420f
merge main
DanielSLew Dec 9, 2025
273dd3b
merge main
DanielSLew Dec 9, 2025
7a043eb
fix schema
DanielSLew Dec 9, 2025
3e4653a
fix test
DanielSLew Dec 9, 2025
a9da2a9
fix test
DanielSLew Dec 9, 2025
5efae23
lint
DanielSLew Dec 9, 2025
1d95c64
handle processing messages in steps
DanielSLew Dec 9, 2025
f404ea7
fix: validate workflow result shape and add defensive part extraction
DanielSLew Dec 9, 2025
710d747
fix: preserve tripwire property in executeConditional
DanielSLew Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .changeset/three-falcons-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
'@mastra/playground-ui': patch
'@mastra/client-js': patch
'@mastra/ai-sdk': patch
'@mastra/react': patch
'@mastra/server': patch
'@mastra/inngest': patch
---
Comment on lines +1 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Read the full changeset file content
cat -n .changeset/three-falcons-pump.md

Repository: mastra-ai/mastra

Length of output: 1356


🏁 Script executed:

# Search for references to this changeset or PR #7923 to understand scope
rg "7923|three-falcons-pump" --type md --type json -A 3 -B 1 | head -50

Repository: mastra-ai/mastra

Length of output: 7300


🏁 Script executed:

# Look for tripwire-related changes in package files to confirm scope
rg "tripwire" --type ts --type tsx --type js -l | head -20

Repository: mastra-ai/mastra

Length of output: 87


🏁 Script executed:

# Search for inngest-related changes in the codebase
rg "inngest" --type ts --type js -l | head -20

Repository: mastra-ai/mastra

Length of output: 461


🏁 Script executed:

# Look for workflow tripwire implementation to understand scope
rg "tripwire" --type ts --type js -A 2 -B 2 | head -100

Repository: mastra-ai/mastra

Length of output: 8621


🏁 Script executed:

# Check if there are recent commits/PR mentions of tripwire and inngest
git log --oneline --all --grep="tripwire" 2>/dev/null | head -10

Repository: mastra-ai/mastra

Length of output: 42


Add a link to the related issue or PR for context.

The frontmatter correctly lists all six packages, including @mastra/inngest. The changes to workflows/inngest/src/execution-engine.ts confirm that the inngest package has legitimate tripwire support modifications (handling tripwire status and emitting workflow step results). However, per the coding guidelines, changeset files should include links to related issues or PRs when relevant. Consider adding a reference to issue #7923 or the associated PR.

🤖 Prompt for AI Agents
.changeset/three-falcons-pump.md lines 1-8: The changeset frontmatter lists
updated packages but lacks a reference to the related issue/PR; update the file
by appending a brief line in the markdown (below the frontmatter or in a note
section) that links to the related issue or PR (e.g., "Related: #7923" or a full
GitHub PR URL) so reviewers have context; keep the entry concise and formatted
consistently with other changesets.


Support new Workflow tripwire run status. Tripwires that are thrown from within a workflow will now bubble up and return a graceful state with information about tripwires.

When a workflow contains an agent step that triggers a tripwire, the workflow returns with `status: 'tripwire'` and includes tripwire details:

```typescript showLineNumbers copy
const run = await workflow.createRun();
const result = await run.start({ inputData: { message: 'Hello' } });

if (result.status === 'tripwire') {
console.log('Workflow terminated by tripwire:', result.tripwire?.reason);
console.log('Processor ID:', result.tripwire?.processorId);
console.log('Retry requested:', result.tripwire?.retry);
}
```

Adds new UI state for tripwire in agent chat and workflow UI.

This is distinct from `status: 'failed'` which indicates an unexpected error. A tripwire status means a processor intentionally stopped execution (e.g., for content moderation).
54 changes: 54 additions & 0 deletions .changeset/yummy-hats-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
'@mastra/core': patch
---

Multiple Processor improvements including:

- Workflows can now return tripwires, they bubble up from agents that return tripwires in a step
- You can write processors as workflows using the existing Workflow primitive, every processor flow is now a workflow.
- tripwires that you throw can now return additional information including ability to retry the step
- New processor method `processOutputStep` added which runs after every step.

**What's new:**

**1. Retry mechanism with LLM feedback** - Processors can now request retries with feedback that gets sent back to the LLM:

```typescript
processOutputStep: async ({ text, abort, retryCount }) => {
if (isLowQuality(text)) {
abort('Response quality too low', { retry: true, metadata: { score: 0.6 } });
}
return [];
};
```

Configure with `maxProcessorRetries` (default: 3). Rejected steps are preserved in `result.steps[n].tripwire`. Retries are only available in `processOutputStep` and `processInputStep`. It will replay the step with additional context added.

**2. Workflow orchestration for processors** - Processors can now be composed using workflow primitives:

```typescript
import { createStep, createWorkflow } from '@mastra/core/workflows';
import {
ProcessorStepSchema,
} from '@mastra/core/processors';

const moderationWorkflow = createWorkflow({ id: 'moderation', inputSchema: ProcessorStepSchema, outputSchema: ProcessorStepSchema })
.then(createStep(new lengthValidator({...})))
.parallel([createStep(new piiDetector({...}), createStep(new toxicityChecker({...}))])
.commit();

const agent = new Agent({ inputProcessors: [moderationWorkflow] });
```

Every processor array that gets passed to an agent gets added as a workflow
<img width="614" height="673" alt="image" src="https://github.com/user-attachments/assets/0d79f1fd-8fca-4d86-8b45-22fddea984a8" />

**3. Extended tripwire API** - `abort()` now accepts options for retry control and typed metadata:

```typescript
abort('reason', { retry: true, metadata: { score: 0.8, category: 'quality' } });
```

**4. New `processOutputStep` method** - Per-step output processing with access to step number, finish reason, tool calls, and retry count.

**5. Workflow tripwire status** - Workflows now have a `'tripwire'` status distinct from `'failed'`, properly bubbling up processor rejections.
6 changes: 3 additions & 3 deletions client-sdks/ai-sdk/src/__tests__/convert-messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('toAISdkFormat', () => {
type: 'tripwire',
runId: 'test-run-id',
payload: {
tripwireReason,
reason: tripwireReason,
},
});

Expand Down Expand Up @@ -154,7 +154,7 @@ describe('toAISdkFormat', () => {
// Verify tripwire chunk was received
expect(tripwireChunk).toBeDefined();
expect(tripwireChunk.type).toBe('data-tripwire');
expect(tripwireChunk.data.tripwireReason).toBe(tripwireReason);
expect(tripwireChunk.data.reason).toBe(tripwireReason);

// Verify finish event was sent with finishReason 'other'
expect(finishChunk).toBeDefined();
Expand All @@ -178,7 +178,7 @@ describe('toAISdkFormat', () => {
type: 'tripwire',
runId: 'test-run-id',
payload: {
tripwireReason,
reason: tripwireReason,
},
});

Expand Down
33 changes: 27 additions & 6 deletions client-sdks/ai-sdk/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import { DefaultGeneratedFile, DefaultGeneratedFileWithType } from '@mastra/core/stream';
import type { PartialSchemaOutput, OutputSchema, DataChunkType, ChunkType } from '@mastra/core/stream';

import type { InferUIMessageChunk, ObjectStreamPart, TextStreamPart, ToolSet, UIMessage } from 'ai';
import type {
PartialSchemaOutput,
OutputSchema,
DataChunkType,
ChunkType,
MastraFinishReason,
} from '@mastra/core/stream';

import type { InferUIMessageChunk, ObjectStreamPart, TextStreamPart, ToolSet, UIMessage, FinishReason } from 'ai';
import { isDataChunkType } from './utils';

/**
* Maps Mastra's extended finish reasons to AI SDK-compatible values.
* 'tripwire' and 'retry' are Mastra-specific reasons for processor scenarios,
* which are mapped to 'other' for AI SDK compatibility.
*/
export function toAISDKFinishReason(reason: MastraFinishReason): FinishReason {
if (reason === 'tripwire' || reason === 'retry') {
return 'other';
}
return reason;
}

export type OutputChunkType<OUTPUT extends OutputSchema = undefined> =
| TextStreamPart<ToolSet>
| ObjectStreamPart<PartialSchemaOutput<OUTPUT>>
Expand Down Expand Up @@ -42,7 +60,7 @@ export function convertMastraChunkToAISDKv5<OUTPUT extends OutputSchema = undefi
case 'finish': {
return {
type: 'finish',
finishReason: chunk.payload.stepResult.reason,
finishReason: toAISDKFinishReason(chunk.payload.stepResult.reason),
totalUsage: chunk.payload.output.usage,
};
}
Expand Down Expand Up @@ -182,7 +200,7 @@ export function convertMastraChunkToAISDKv5<OUTPUT extends OutputSchema = undefi
...rest,
},
usage: chunk.payload.output.usage,
finishReason: chunk.payload.stepResult.reason,
finishReason: toAISDKFinishReason(chunk.payload.stepResult.reason),
providerMetadata,
};
}
Expand Down Expand Up @@ -246,7 +264,10 @@ export function convertMastraChunkToAISDKv5<OUTPUT extends OutputSchema = undefi
return {
type: 'data-tripwire',
data: {
tripwireReason: chunk.payload.tripwireReason,
reason: chunk.payload.reason,
retry: chunk.payload.retry,
metadata: chunk.payload.metadata,
processorId: chunk.payload.processorId,
},
};
default:
Expand Down
3 changes: 2 additions & 1 deletion client-sdks/ai-sdk/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { convertFullStreamChunkToMastra } from '@mastra/core/stream';
import type { ChunkType } from '@mastra/core/stream';
import type { MastraEmbeddingModel, MastraVector } from '@mastra/core/vector';
import { wrapLanguageModel } from 'ai';
import { toAISDKFinishReason } from './helpers';

/**
* Memory context for processors that need thread/resource info
Expand Down Expand Up @@ -737,7 +738,7 @@ function convertMastraChunkToAISDKStreamPart(chunk: ChunkType): LanguageModelV2S
const usage = chunk.payload.output?.usage;
return {
type: 'finish',
finishReason: chunk.payload.stepResult?.reason || 'stop',
finishReason: toAISDKFinishReason(chunk.payload.stepResult?.reason || 'stop'),
usage: usage
? {
inputTokens: usage.inputTokens || 0,
Expand Down
2 changes: 1 addition & 1 deletion client-sdks/client-js/src/resources/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ export class Agent extends BaseResource {
case 'tripwire': {
message.parts.push({
type: 'text',
text: chunk.payload.tripwireReason,
text: chunk.payload.reason,
});

execUpdate();
Expand Down
2 changes: 2 additions & 0 deletions client-sdks/client-js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ export interface GetWorkflowResponse {
stepGraph: Workflow['serializedStepGraph'];
inputSchema: string;
outputSchema: string;
/** Whether this workflow is a processor workflow (auto-generated from agent processors) */
isProcessorWorkflow?: boolean;
}

export type WorkflowRunResult = WorkflowResult<any, any, any, any>;
Expand Down
16 changes: 15 additions & 1 deletion client-sdks/react/src/lib/ai-sdk/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { UIMessage } from '@ai-sdk/react';
import { CompleteAttachment } from '@assistant-ui/react';

/**
* Tripwire metadata included when a processor triggers a tripwire
*/
export type TripwireMetadata = {
/** Whether the agent should retry with feedback */
retry?: boolean;
/** Custom metadata from the processor */
tripwirePayload?: unknown;
/** ID of the processor that triggered the tripwire */
processorId?: string;
};

export type MastraUIMessageMetadata = {
status?: 'warning' | 'error';
status?: 'warning' | 'error' | 'tripwire';
/** Tripwire-specific metadata when status is 'tripwire' */
tripwire?: TripwireMetadata;
} & (
| {
mode: 'generate';
Expand Down
46 changes: 44 additions & 2 deletions client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ describe('toUIMessage', () => {
it('should create a new assistant message for tripwire chunk', () => {
const chunk: ChunkType = {
type: 'tripwire',
payload: { tripwireReason: 'Security warning detected' },
payload: { reason: 'Security warning detected' },
runId: 'run-123',
from: ChunkFrom.AGENT,
};
Expand All @@ -456,11 +456,53 @@ describe('toUIMessage', () => {
],
metadata: {
...baseMetadata,
status: 'warning',
status: 'tripwire',
tripwire: {
retry: undefined,
tripwirePayload: undefined,
processorId: undefined,
},
},
});
expect(result[0].id).toMatch(/^tripwire-run-123/);
});

it('should include tripwire metadata when provided', () => {
const chunk: ChunkType = {
type: 'tripwire',
payload: {
reason: 'PII detected in message',
retry: false,
metadata: { detectedPII: ['email', 'phone'], severity: 'high' },
processorId: 'pii-detection',
},
runId: 'run-456',
from: ChunkFrom.AGENT,
};

const conversation: MastraUIMessage[] = [];
const result = toUIMessage({ chunk, conversation, metadata: baseMetadata });

expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
role: 'assistant',
parts: [
{
type: 'text',
text: 'PII detected in message',
},
],
metadata: {
...baseMetadata,
status: 'tripwire',
tripwire: {
retry: false,
tripwirePayload: { detectedPII: ['email', 'phone'], severity: 'high' },
processorId: 'pii-detection',
},
},
});
});
});

describe('toUIMessage - start chunk', () => {
Expand Down
15 changes: 11 additions & 4 deletions client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export const mapWorkflowStreamChunkToWatchResult = (
? { result: lastStep?.output }
: finalStatus === 'failed' && lastStep?.status === 'failed'
? { error: lastStep?.error }
: {}),
: finalStatus === 'tripwire' && chunk.payload.tripwire
? { tripwire: chunk.payload.tripwire }
: {}),
Comment on lines +45 to +47
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd -e ts -e tsx packages/core/src | head -20

Repository: mastra-ai/mastra

Length of output: 433


🏁 Script executed:

# Find ChunkType definition
rg -nP --type=ts 'type\s+ChunkType|interface\s+ChunkType' --max-count=10

Repository: mastra-ai/mastra

Length of output: 186


🏁 Script executed:

# Search for ChunkType and tripwire definitions more broadly
rg -nP --type=ts 'ChunkType.*=|payload.*tripwire' --max-count=20

Repository: mastra-ai/mastra

Length of output: 22628


🏁 Script executed:

cat -n packages/core/src/stream/types.ts | sed -n '630,660p'

Repository: mastra-ai/mastra

Length of output: 1659


🏁 Script executed:

# Find TypedChunkType definition
cat -n packages/core/src/stream/types.ts | sed -n '639,645p'

Repository: mastra-ai/mastra

Length of output: 437


🏁 Script executed:

# Search for payload structure and tripwire in the types file
rg -n 'payload.*tripwire|type.*Payload|interface.*Payload' packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 6248


🏁 Script executed:

cat -n packages/core/src/stream/types.ts | sed -n '328,340p'

Repository: mastra-ai/mastra

Length of output: 591


🏁 Script executed:

# Also check StepTripwireData which is referenced in BaseChunkType
rg -n 'type StepTripwireData|interface StepTripwireData' packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 99


🏁 Script executed:

cat -n client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts | sed -n '30,60p'

Repository: mastra-ai/mastra

Length of output: 1154


🏁 Script executed:

# Also check around line 150-173 mentioned in the original comment
cat -n client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts | sed -n '140,180p'

Repository: mastra-ai/mastra

Length of output: 1426


🏁 Script executed:

rg -n 'WorkflowFinishPayload|workflow-finish' packages/core/src/stream/types.ts | head -20

Repository: mastra-ai/mastra

Length of output: 94


🏁 Script executed:

# Find the payload structure for workflow-finish
cat -n packages/core/src/stream/types.ts | sed -n '415,435p'

Repository: mastra-ai/mastra

Length of output: 608


🏁 Script executed:

cat -n packages/core/src/stream/types.ts | sed -n '560,575p'

Repository: mastra-ai/mastra

Length of output: 546


🏁 Script executed:

# Also search for any payload type that has tripwire field
rg -n 'tripwire:' packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

cat -n packages/core/src/stream/types.ts | sed -n '564,585p'

Repository: mastra-ai/mastra

Length of output: 718


🏁 Script executed:

# Search for tripwire in workflow-finish context more broadly
rg -B5 -A5 'workflow-finish' packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 304


🏁 Script executed:

rg -n 'workflow-finish.*tripwire|tripwire.*workflow-finish' client-sdks/react/src/lib/ai-sdk/utils/

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

# Check the test file for toUIMessage
rg -B3 -A3 'workflow-finish' client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts | head -40

Repository: mastra-ai/mastra

Length of output: 1064


🏁 Script executed:

rg -n "workflowStatus.*tripwire|'tripwire'" client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts

Repository: mastra-ai/mastra

Length of output: 187


🏁 Script executed:

# Find WorkflowRunStatus type definition
rg -n 'type WorkflowRunStatus|enum WorkflowRunStatus' packages/core/src/

Repository: mastra-ai/mastra

Length of output: 132


🏁 Script executed:

# Search for tripwire in workflow context
rg -n "workflowStatus.*=.*'tripwire'" packages/core/src/

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

cat -n packages/core/src/workflows/types.ts | sed -n '215,225p'

Repository: mastra-ai/mastra

Length of output: 298


🏁 Script executed:

# Also check the tripwire test cases in toUIMessage.test.ts
rg -B5 -A10 "type: 'tripwire'" client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts | head -50

Repository: mastra-ai/mastra

Length of output: 1036


🏁 Script executed:

rg -B5 -A15 "workflow-finish.*tripwire|tripwire.*workflow-finish" client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

# Search more broadly for workflow-finish with tripwire in tests
rg -B10 "workflowStatus.*'tripwire'|'tripwire'.*workflow" client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.test.ts

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

cat -n client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts | sed -n '34,50p'

Repository: mastra-ai/mastra

Length of output: 803


🏁 Script executed:

# Check if there are any recent changes to workflow-finish handling
git log --oneline -n 20 -- client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts

Repository: mastra-ai/mastra

Length of output: 73


🏁 Script executed:

# Check git diff to see what was changed in this PR
git diff HEAD~1 client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts | head -100

Repository: mastra-ai/mastra

Length of output: 246


🏁 Script executed:

# Look at the workflow-finish in the actual code to see what metadata contains
rg -B5 -A5 'workflowStatus.*tripwire' packages/core/src/

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

# Check if there's any tripwire data being added to workflow-finish metadata
rg -n 'workflow-finish' packages/core/src/workflows/ | grep -i tripwire

Repository: mastra-ai/mastra

Length of output: 42


🏁 Script executed:

# Look at step-finish handling which might show the pattern
cat -n client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts | sed -n '60,120p'

Repository: mastra-ai/mastra

Length of output: 2088


🏁 Script executed:

# Get the full workflow-finish payload structure including all fields
cat -n packages/core/src/stream/types.ts | sed -n '564,580p'

Repository: mastra-ai/mastra

Length of output: 583


🏁 Script executed:

# Check if tripwire was supposed to be added to WorkflowFinishPayload
rg -A20 "type: 'workflow-finish'" packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 541


🏁 Script executed:

# Verify what the actual current state of the file is
head -1 client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts

Repository: mastra-ai/mastra

Length of output: 124


🏁 Script executed:

# Verify the tripwire chunk type definition
rg -B2 -A2 "type: 'tripwire'" packages/core/src/stream/types.ts

Repository: mastra-ai/mastra

Length of output: 301


Remove the non-existent chunk.payload.tripwire check from the workflow-finish handler.

The workflow-finish chunk payload does not include a tripwire field. The payload structure contains only workflowStatus, output, and metadata. When workflowStatus is 'tripwire', the tripwire data is delivered via a separate chunk with type: 'tripwire' (already correctly handled at lines 150-173), not within the workflow-finish payload.

Lines 45-46 should be simplified to:

: {}

The condition finalStatus === 'tripwire' && chunk.payload.tripwire will never evaluate to true since chunk.payload.tripwire does not exist in the WorkflowFinishPayload type definition.

🤖 Prompt for AI Agents
In client-sdks/react/src/lib/ai-sdk/utils/toUIMessage.ts around lines 45-47,
remove the non-existent check for chunk.payload.tripwire inside the
workflow-finish handler and replace that conditional branch with an empty
object; specifically simplify the ternary that currently uses "finalStatus ===
'tripwire' && chunk.payload.tripwire ? { tripwire: ... } : {}" (or similar) so
it always yields {} for the workflow-finish path, since tripwire data comes from
separate 'tripwire' chunks and WorkflowFinishPayload contains only
workflowStatus, output, and metadata.

};
}

Expand Down Expand Up @@ -146,19 +148,24 @@ export const toUIMessage = ({ chunk, conversation, metadata }: ToUIMessageArgs):

switch (chunk.type) {
case 'tripwire': {
// Create a new assistant message
// Create a new assistant message with tripwire-specific metadata
const newMessage: MastraUIMessage = {
id: `tripwire-${chunk.runId + Date.now()}`,
role: 'assistant',
parts: [
{
type: 'text',
text: chunk.payload.tripwireReason,
text: chunk.payload.reason,
},
],
metadata: {
...metadata,
status: 'warning',
status: 'tripwire',
tripwire: {
retry: chunk.payload.retry,
tripwirePayload: chunk.payload.metadata,
processorId: chunk.payload.processorId,
},
},
};

Expand Down
Loading
Loading