<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ippu Ito</title>
    <description>The latest articles on Forem by Ippu Ito (@ippu_ito_870812).</description>
    <link>https://forem.com/ippu_ito_870812</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3674313%2F3922b033-ebde-438c-825c-9dbbb1f6e831.png</url>
      <title>Forem: Ippu Ito</title>
      <link>https://forem.com/ippu_ito_870812</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ippu_ito_870812"/>
    <language>en</language>
    <item>
      <title>Fix "Exception from HRESULT: 0x80131904" in Power Automate: Check the Recycle Bin</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 03 Mar 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/fix-exception-from-hresult-0x80131904-in-power-automate-check-the-recycle-bin-46cf</link>
      <guid>https://forem.com/ippu_ito_870812/fix-exception-from-hresult-0x80131904-in-power-automate-check-the-recycle-bin-46cf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/error-0x80131904/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently encountered an issue where a "Create new folder" action in a Power Automate (SharePoint connector) flow suddenly failed with the error "Exception from HRESULT: 0x80131904".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The cause was &lt;span&gt;&lt;strong&gt;"too many files accumulated in the SharePoint Recycle Bin"&lt;/strong&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Even though the visible number of files was under 5,000, the total count including the contents of the Recycle Bin exceeded the threshold, causing the error.&lt;/p&gt;

&lt;p&gt;Below are my notes on the investigation and solution.&lt;/p&gt;

&lt;h2&gt;Error Occurred: "Exception from HRESULT: 0x80131904"&lt;/h2&gt;

&lt;p&gt;The flow execution result looked like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2026%2F01%2FHRESULT_0x80131904_001-1024x409.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2026%2F01%2FHRESULT_0x80131904_001-1024x409.png" alt="Error screenshot" width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;
Exception from HRESULT: 0x80131904
clientRequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
serviceRequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
&lt;/pre&gt;

&lt;p&gt;"0x80131904" is a common error code, and there are several reported cases of the same error string occurring in SharePoint Online.&lt;/p&gt;

&lt;h2&gt;Background: The SharePoint "5,000 Item Limit" Problem&lt;/h2&gt;

&lt;p&gt;SharePoint has a "List View Threshold," often referred to with the &lt;span&gt;&lt;strong&gt;5,000 items&lt;/strong&gt;&lt;/span&gt; guideline.&lt;br&gt;
​&lt;br&gt;
If you hit this threshold, errors can occur not only in the screen display but also in "operations via API" (which is exactly what happened this time).&lt;/p&gt;

&lt;h2&gt;The Cause: Recycle Bin Overload&lt;/h2&gt;

&lt;p&gt;Initially, when I checked the number of items in the document library, it was around 3,700, so I didn't see any immediate red flags.&lt;/p&gt;

&lt;p&gt;However, in the Recycle Bin of the same site, &lt;span&gt;&lt;strong&gt;there were over 7,000 files deleted from the same document library&lt;/strong&gt;&lt;/span&gt; remaining. This was the pitfall.&lt;/p&gt;

&lt;p&gt;In SharePoint, there are cases where "items in the Recycle Bin increase too much, causing threshold-related errors." If you only look at the "visible file count" and feel safe, you might get blocked by what is clogged up in the background.&lt;/p&gt;

&lt;h2&gt;Resolution: Delete Unnecessary Files and Empty the Recycle Bin&lt;/h2&gt;

&lt;p&gt;To fix this, &lt;span&gt;&lt;strong&gt;I permanently deleted unnecessary files and emptied the Recycle Bin&lt;/strong&gt;&lt;/span&gt;. After that, the flow executed successfully to the end without any issues.&lt;/p&gt;

&lt;p&gt;By the way, the SharePoint Online Recycle Bin has stages: there is the "Recycle Bin" that users see, and another layer (Second-stage Recycle Bin) beyond that.&lt;br&gt;
​&lt;br&gt;
To reduce the chances of falling into this trap, &lt;span&gt;&lt;strong&gt;it is safer to make "emptying the Recycle Bin periodically" a rule&lt;/strong&gt;&lt;/span&gt; in your operations.&lt;/p&gt;

&lt;h2&gt;Potential Workarounds (Unverified)&lt;/h2&gt;

&lt;p&gt;I solved it by "emptying the Recycle Bin" this time, but there are environments where you can't easily delete files. Here are the workarounds I plan to try if I get stuck with the same issue again.&lt;/p&gt;

&lt;h3&gt;1) Split the Document Library&lt;/h3&gt;

&lt;p&gt;Create a separate document library for archiving and move old files there.&lt;/p&gt;

&lt;p&gt;If you can suppress the total volume of the library that Power Automate accesses, you should be less likely to trigger threshold-related errors.&lt;/p&gt;

&lt;h3&gt;2) Add Indexes to Columns&lt;/h3&gt;

&lt;p&gt;It is a standard best practice that SharePoint List View Threshold issues can be "avoided with indexes."&lt;/p&gt;

&lt;p&gt;Therefore, adding indexes to columns used for search/reference in the flow (such as columns related to creation date or folder path) is also a candidate for resolution.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;Note: 0x80131904 Can Occur for Other Reasons&lt;/h2&gt;

&lt;p&gt;In my environment this time, "massive files in the Recycle Bin" was the cause, but 0x80131904 itself is a generic SQL error and can occur in SharePoint Online due to other factors (like throttling or timeouts).&lt;/p&gt;

&lt;p&gt;So, if you encounter the same error (Exception from HRESULT: 0x80131904), you should suspect the "item count (including Recycle Bin)" first. If that doesn't solve it, you will need to investigate other causes.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>microsoft</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Add CSAT Surveys to Custom Topics in Copilot Studio (and Fix Analytics)</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 24 Feb 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/how-to-add-csat-surveys-to-custom-topics-in-copilot-studio-and-fix-analytics-ok5</link>
      <guid>https://forem.com/ippu_ito_870812/how-to-add-csat-surveys-to-custom-topics-in-copilot-studio-and-fix-analytics-ok5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/copilot-studio/csat/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, CSAT is only in the 'End of Conversation' topic.&lt;/p&gt;

&lt;p&gt;But what if you want to ask for feedback in the middle of a custom flow?&lt;/p&gt;

&lt;p&gt;Here is a quick workaround.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;You can copy the CSATQuestion action from the system topic to any custom topic.&lt;/li&gt;
    &lt;li&gt;Warning: Just answering the CSAT survey does NOT mark the session as "Resolved".&lt;/li&gt;
    &lt;li&gt;To fix the analytics (avoid "Abandoned" status), you must explicitly set the conversationOutcome variable to Resolved in your topic code.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;CSAT&lt;/h2&gt; CSAT stands for Customer Satisfaction rating. In Copilot Studio, it measures user satisfaction using a 5-star rating system (scores from 0 to 5). &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat005-1024x629.png" alt="CSAT 5-star rating interface in Copilot Studio" width="800" height="491"&gt;&lt;br&gt;
For more details about CSAT, see:&lt;br&gt;
[&lt;a href="https://learn.microsoft.com/ja-jp/microsoft-copilot-studio/analytics-csat" rel="noopener noreferrer"&gt;https://learn.microsoft.com/ja-jp/microsoft-copilot-studio/analytics-csat&lt;/a&gt;]

&lt;p&gt;CSAT collection is built into the system topic "End of Conversation" by default, but this time I wanted to test whether it could be collected from custom topics.&lt;/p&gt;



&lt;h2&gt;Implementation&lt;/h2&gt; First, open the system topic "End of Conversation". &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat001-1024x623.png" alt="Opening the End of Conversation system topic" width="800" height="486"&gt; Open the code editor. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat002-1024x635.png" alt="Opening the code editor interface" width="800" height="496"&gt; Find the "CSATQuestion" action and copy this action. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat003-1024x607.png" alt="Locating and copying the CSATQuestion action" width="800" height="474"&gt; Next, open the code editor for the custom topic where you want to integrate CSAT, and paste the action you copied earlier. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat004-1024x416.png" alt="Pasting the CSAT action into custom topic code editor" width="800" height="325"&gt; When you exit the code editor, CSAT will be integrated into your custom topic. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat005-1024x629.png" alt="CSAT successfully integrated into custom topic" width="800" height="491"&gt;&lt;br&gt;&lt;br&gt;
That completes the implementation process.



&lt;h2&gt;Testing the Implementation&lt;/h2&gt; When you publish the agent to Teams and call the topic we just created, CSAT will be displayed like this. Here, I selected 1, &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat006-1024x390.png" alt="CSAT rating interface displayed in Teams with rating options" width="800" height="304"&gt; When you return to the agent building screen and open the [Analytics] tab, you'll see the satisfaction score contains the value you just entered. &lt;br&gt;&lt;br&gt;
*It takes about 30 minutes to 1 hour for the data to be reflected in the Analytics tab. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat007-1024x680.png" alt="Analytics tab showing satisfaction score data" width="800" height="531"&gt; &lt;h2&gt;"Outcome" and "CSAT (Satisfaction Score)" are Different&lt;/h2&gt; I commented out the conversationOutcome setting in the topic we created earlier, &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat008.png" alt="Code editor showing conversationOutcome setting commented out" width="742" height="412"&gt; Then called the topic again and this time selected 5. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat008-2-1024x636.png" alt="CSAT interface with rating 5 selected" width="800" height="496"&gt; The satisfaction score becomes an average of 3, but &lt;span&gt;&lt;strong&gt;the new outcome shows as "Abandoned (session timeout)"&lt;/strong&gt;&lt;/span&gt;. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fcsat009-1024x692.png" alt="Analytics showing satisfaction score and abandoned session outcome" width="800" height="540"&gt;&lt;br&gt;&lt;br&gt;
From these results, we can see that &lt;span&gt;&lt;strong&gt;responding to CSAT does not change the conversation outcome to "Resolved," and if you want the conversation outcome to be "Resolved" or "Escalated," you need to configure the conversationOutcome setting&lt;/strong&gt;&lt;/span&gt;.

</description>
      <category>copilotstudio</category>
      <category>powerplatform</category>
      <category>tutorial</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Stop "Abandoned" Sessions! Fix Copilot Studio Analytics with YAML &amp; System Topics</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 17 Feb 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/stop-abandoned-sessions-fix-copilot-studio-analytics-with-yaml-system-topics-4eg6</link>
      <guid>https://forem.com/ippu_ito_870812/stop-abandoned-sessions-fix-copilot-studio-analytics-with-yaml-system-topics-4eg6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/copilot-studio/conversationoutcome/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is your Copilot Studio analytics dashboard showing too many "Abandoned" sessions? You might be ending conversations incorrectly. In this guide, I will show you how to properly configure conversationOutcome to ensure your Resolution Rate is accurate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analytics Session Outcomes
&lt;/h2&gt;

&lt;p&gt;Conversational agents in Copilot Studio can record &lt;strong&gt;"conversation outcomes (Analytics metrics)"&lt;/strong&gt; during interactions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahr1f3fld4206tdy8hdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahr1f3fld4206tdy8hdg.png" alt="Copilot Studio analytics session outcomes interface showing conversation results" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The types of outcomes are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Escalated&lt;/strong&gt;: When the "Escalation" system topic is called or the "Transfer to Agent" node is executed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolved&lt;/strong&gt;: When the "End Conversation" topic is called and the user enters the resolved branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abandoned&lt;/strong&gt;: When the session times out and is neither "Escalated" nor "Resolved"&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A single conversation can contain one or more analytics sessions.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Conversations that are not in the "Engaged" state (conversations in the "Unengaged" state) will be marked as "Not Engaged".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt; For more details about "Conversations," "Analytics Sessions," and "Engagement," please refer here:&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://learn.microsoft.com/en-us/microsoft-copilot-studio/analytics-overview#conversational-sessions" rel="noopener noreferrer"&gt;Analytics Overview&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 &lt;a href="https://learn.microsoft.com/en-us/microsoft-copilot-studio/guidance/measuring-engagement#engaged-and-unengaged-analytics-sessions" rel="noopener noreferrer"&gt;Measuring Engagement&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This time, I investigated how to record "analytics session outcomes" (referred to as "outcomes" below).&lt;/p&gt;

&lt;h2&gt;Preliminary Setup&lt;/h2&gt; To ensure our prepared topics are reliably called, we'll turn off the generative AI responses. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory000-1024x493.png" alt="Screenshot showing the generative AI response settings turned off in Copilot Studio" width="800" height="385"&gt; &lt;h2&gt;The "End Conversation" Node Alone Doesn't Result in "Resolved" Status&lt;/h2&gt; For example, if you create a topic that calls the "End Conversation" action as shown below: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory002.png" alt="Topic configuration with End Conversation action" width="800" height="533"&gt; When you end the conversation using only this topic: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory003-1024x385.png" alt="Conversation flow ending with the End Conversation action" width="800" height="300"&gt; The result will be marked as "Abandoned" (neither resolved nor escalated). 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory004.png" alt="Analytics showing Abandoned outcome status" width="800" height="597"&gt;
This happens because &lt;span&gt;&lt;strong&gt;the conversation ended without explicitly specifying an outcome such as "Resolved" or "Escalated"&lt;/strong&gt;&lt;/span&gt; within the topic (session), and the session subsequently timed out.

Below, I'll introduce two methods to specify these outcomes.

&lt;h2&gt;Method 1: Redirect to the "End Conversation" Topic&lt;/h2&gt; The first method is to use the system topic "End Conversation".
This is likely the standard approach, as officially documented:

&lt;blockquote&gt; &lt;strong&gt;Properly ending conversations to measure outcomes&lt;/strong&gt; It's important to end conversations with the End Conversation topic, which allows users to confirm whether their issue was resolved (and if escalation might be needed). When the agent confirms success, a CSAT survey is presented to the user and a score from 0-5 is collected.
If the conversation outcome is certain based on your topic logic, you can either directly flag it as success-confirmed or redirect to the escalate topic.
&lt;a href="https://learn.microsoft.com/en-us/microsoft-copilot-studio/guidance/measuring-outcomes#properly-ending-conversations-to-measure-outcomes" rel="noopener nofollow sponsored ugc noreferrer"&gt;Official documentation here&lt;/a&gt;
&lt;/blockquote&gt; 
Implementation is simple: when the conversation reaches a natural conclusion (where you want to segment your analytics), select [Topic Management] → [Go to another topic], then choose the system topic "End Conversation". 
Note: System topic "End Conversation" ≠ "End Conversation" node 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory005-1024x601.png" alt="Screenshot showing how to navigate to Topic Management and select Go to another topic" width="800" height="469"&gt; 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory006-1024x660.png" alt="Screenshot showing the End Conversation system topic selection" width="800" height="515"&gt; Once this system topic is called: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory012-1024x656.png" alt="Screenshot of the End Conversation system topic flow in action" width="800" height="512"&gt;  The outcome will be recorded. 
Note: It may take 30 minutes to 1 hour for the results to appear in the analytics tab. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory001-2-1024x658.png" alt="Analytics tab showing the recorded conversation outcome" width="800" height="514"&gt;

&lt;h2&gt;Method 2: Explicitly Specify conversationOutcome&lt;/h2&gt; The second method is to explicitly specify either "Resolved" or "Escalated". &lt;blockquote&gt; You can also set the outcome of actions using the conversationOutcome parameter in the action code editor. For example, use conversationOutcome: ResolvedConfirmed for confirmed success, and conversationOutcome: ResolvedImplied for implicit success. 
&lt;a href="https://learn.microsoft.com/en-us/microsoft-copilot-studio/analytics-improve-agent-effectiveness?wt.mc_id=copilotstudio_inproduct_analytics#outcomes-and-engagement" rel="noopener nofollow sponsored ugc noreferrer"&gt;From official documentation&lt;/a&gt; 
&lt;/blockquote&gt; To specify an outcome, first open the topic's source code: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory013-1024x658.png" alt="Screenshot showing how to access the topic source code in Copilot Studio" width="800" height="514"&gt; Then simply specify the conversationOutcome for the node where you want to set the analytics result (in this case, the "End Conversation" node). 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory014-1024x617.png" alt="Screenshot showing how to add the conversationOutcome parameter to the End Conversation node" width="800" height="482"&gt;
&lt;pre&gt;
kind: AdaptiveDialog
beginDialog:
  kind: OnRecognizedIntent
  id: main
  actions:
    - kind: SendActivity
      id: sendActivity_1
      activity: "Ending conversation..."
      conversationOutcome: ResolvedConfirmed  # &amp;lt;--- This is the key!
&lt;/pre&gt;


When this topic is called: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory015-1024x560.png" alt="Screenshot of the conversation flow using the modified topic" width="800" height="437"&gt; The outcome will be marked as "Resolved". 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory016.png" alt="Analytics showing the Resolved outcome status" width="800" height="604"&gt; Similarly, you can create a topic that ends with an escalation: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory017.png" alt="Screenshot showing the creation of an escalation topic" width="800" height="467"&gt; Specify "Escalated" for the conversationOutcome: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory018.png" alt="Screenshot showing how to set the conversationOutcome to Escalated" width="653" height="391"&gt; When this topic is called: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory019-1024x617.png" alt="Screenshot of the conversation flow using the escalation topic" width="800" height="482"&gt; The "Escalated" count increases by one in the analytics. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory020-1024x713.png" alt="Analytics showing the increased Escalated outcome count" width="800" height="557"&gt;
Note: The values that can be specified are as follows:
&lt;pre&gt;
conversationOutcome: Escalated
conversationOutcome: ResolvedImplied
conversationOutcome: ResolvedConfirmed
conversationOutcome: Abandoned
&lt;/pre&gt;

As such, when using "Analytics" to improve Copilot Studio, you need to pay attention to how conversations are ended.&lt;br&gt;
&lt;br&gt;
Official documentation&lt;br&gt;
https://learn.microsoft.com/en-us/microsoft-copilot-studio/guidance/measuring-outcomes
&lt;br&gt;
https://learn.microsoft.com/en-us/microsoft-copilot-studio/analytics-improve-agent-effectiveness?wt.mc_id=copilotstudio_inproduct_analytics#outcomes-and-engagement&lt;br&gt;

&lt;h2&gt;Deep Dive: How System Topics Handle conversationOutcome in Code&lt;/h2&gt; The system topic "End Conversation" also sets conversationOutcome. If you click [Open Code Editor] to view the source: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory007-1024x596.png" alt="Screenshot showing how to access the code editor for the End Conversation system topic" width="800" height="465"&gt; You can see that "Resolved" is configured. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory008-1024x635.png" alt="Screenshot showing the ResolvedConfirmed conversationOutcome setting in the End Conversation topic code" width="800" height="496"&gt; Incidentally, if the user is not satisfied with the answer, the system topic "Escalate" is called: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory009-1024x725.png" alt="Screenshot showing the Escalate system topic being called when a user is not satisfied" width="800" height="566"&gt; Looking at the source code of this system topic: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory010-1024x543.png" alt="Screenshot showing how to access the code editor for the Escalate system topic" width="800" height="424"&gt; You can see that conversationOutcome is set to "Escalated". 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory011-1024x752.png" alt="Screenshot showing the Escalated conversationOutcome setting in the Escalate topic code" width="800" height="587"&gt; 

&lt;h2&gt;How to Check Session Outcomes&lt;/h2&gt; 

&lt;h3&gt;1. From Copilot Studio&lt;/h3&gt; 

&lt;p&gt;To check from Copilot Studio, go to the [Analytics] tab, click [View details], then [Download sessions] to download a CSV file. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory021-1024x580.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory021-1024x580.png" alt="Screenshot showing how to download session data from Copilot Studio analytics" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can view the session outcomes and conversation content.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory022-1024x216.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory022-1024x216.png" alt="Screenshot of the downloaded CSV file showing session outcomes and conversation data" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;2. From Power Apps (Dataverse)&lt;/h3&gt; 

&lt;p&gt;Copilot Studio conversation history is stored in the "ConversationTranscript" table: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory023-1024x514.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory023-1024x514.png" alt="Screenshot showing the ConversationTranscript table in Dataverse" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By referencing this table, you can view detailed data such as the reason for ending (outcomeReason), number of events (turnCount), and other granular information.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory024-1024x634.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory024-1024x634.png" alt="Screenshot showing detailed conversation data in the Dataverse table" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;When you call the operation to set conversationOutcome consecutively&lt;/h2&gt; Create a topic like this, &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory025.png" alt="" width="800" height="510"&gt; Edit the code so that conversationOutcome is set when sending the "End" message. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory026.png" alt="" width="749" height="390"&gt; If you call this topic from the user's side in rapid succession, &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory027-1024x807.png" alt="" width="800" height="630"&gt; The number of sessions increases according to the number of times it is called. &lt;br&gt;&lt;br&gt;
*The reason the number is 6 is because a test run was performed once before this test. &lt;br&gt;&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Fchathistory028-1024x576.png" alt="" width="800" height="450"&gt;

</description>
      <category>powerplatform</category>
      <category>microsoft</category>
      <category>ai</category>
      <category>copilotstudio</category>
    </item>
    <item>
      <title>Forget Canvas Apps? Build Full-Code React + Azure OpenAI Apps on Power Platform</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 10 Feb 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/forget-canvas-apps-build-full-code-react-azure-openai-apps-on-power-platform-kb</link>
      <guid>https://forem.com/ippu_ito_870812/forget-canvas-apps-build-full-code-react-azure-openai-apps-on-power-platform-kb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/powerapps/code-apps/first-code-app/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Power Apps recently released a preview feature called "Code Apps" that enables building web applications, so I decided to create an actual app to try it out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1enew8mevz1mc7ngr27u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1enew8mevz1mc7ngr27u.gif" alt="" width="600" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Public Preview Notice&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Power Apps Code Apps&lt;/strong&gt; is currently in &lt;strong&gt;Public Preview&lt;/strong&gt;. Please note that features and CLI commands are subject to change before General Availability (GA).&lt;/p&gt;

&lt;p&gt;While it's not ready for production yet, now is the perfect time to explore the future of "Full-Code" development on Power Platform. Let’s dive in and see what’s possible!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Code Apps (Preview)&lt;/h2&gt; 

&lt;p&gt;Code Apps is a new application format that allows you to &lt;span&gt;&lt;strong&gt;host full-code web applications built with React and other frameworks on the Power Platform, while integrating them with Power Platform's authentication, connectors, and management capabilities for distribution&lt;/strong&gt;&lt;/span&gt;.&lt;br&gt;
While the Power Apps Component Framework creates components that run within Power Apps canvas or model-driven apps, Code Apps enables building complete web applications from the ground up.&lt;/p&gt;

&lt;p&gt;Official documentation here:&lt;br&gt;
[&lt;a href="https://learn.microsoft.com/en-us/power-apps/developer/code-apps/" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/power-apps/developer/code-apps/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;In this article, I'll walk through creating a Code Apps application and building a web app that runs on Power Apps.&lt;/p&gt;


&lt;h2&gt;Prerequisites&lt;/h2&gt; There are three prerequisites: &lt;ul&gt; &lt;li&gt;Install the latest version of Power Platform CLI&lt;/li&gt; &lt;li&gt;Enable Code Apps in the environment where you'll upload the app&lt;/li&gt; &lt;li&gt;Note down the GUID of the environment where you'll upload the app&lt;/li&gt; &lt;/ul&gt;
&lt;br&gt;
 &lt;h3&gt;Install the Latest Version of Power Platform CLI&lt;/h3&gt; First, install the latest version of Power Platform CLI (PAC) in your development environment. &lt;br&gt;
*Note: Older versions don't support the [pac code] command. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app004-1024x534.png" alt="" width="800" height="417"&gt;&lt;br&gt;
 &lt;h3&gt;Enable Code Apps in the Target Environment&lt;/h3&gt; Next, enable Code Apps on the Power Platform side. From the Power Platform admin center, click [Settings] for the target environment. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app001-1024x590.png" alt="" width="800" height="460"&gt;&lt;br&gt;
 Navigate to [Features]. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app002.png" alt="" width="800" height="491"&gt;&lt;br&gt;
 Enable [Power Apps code apps] and save. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app003-1024x659.png" alt="" width="800" height="514"&gt;&lt;br&gt;
 &lt;h3&gt;Note Down the Environment GUID&lt;/h3&gt; Finally, note down the GUID of the environment where you'll upload the app. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app007-1024x505.png" alt="" width="800" height="394"&gt;

&lt;p&gt;That completes the prerequisites.&lt;/p&gt;


&lt;h2&gt;Building the App&lt;/h2&gt; &lt;h3&gt;Launch the Sample App&lt;/h3&gt; First, let's follow the official reference guide to launch the sample app provided by Microsoft locally. Start by cloning the sample project from GitHub. *Note: URL is current as of the time of writing. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app005-1024x436.png" alt="" width="800" height="340"&gt; &lt;pre&gt;git clone &lt;a href="https://github.com/microsoft/PowerAppsCodeApps.git" rel="noopener noreferrer"&gt;https://github.com/microsoft/PowerAppsCodeApps.git&lt;/a&gt;&lt;/pre&gt;
&lt;br&gt;
 Next, install the required packages using npm install. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app006-1024x578.png" alt="" width="800" height="451"&gt;&lt;br&gt;
 Create an authentication profile for the target environment using the pac auth command. Use the environment GUID you noted down during the prerequisites. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app008-1024x663.png" alt="" width="800" height="517"&gt; &lt;pre&gt;pac auth create --environment [Environment GUID]&lt;/pre&gt;
&lt;br&gt;
 If you see the following message, authentication was successful. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app009-1024x419.png" alt="" width="800" height="327"&gt;&lt;br&gt;
 Next, initialize using pac code init. The "Hello World" portion sets the app name. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app010-1024x400.png" alt="" width="800" height="312"&gt; &lt;pre&gt;pac code init --displayName '[App Name]'&lt;/pre&gt;
&lt;br&gt;
 Then, launch locally with the following command. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app011-1024x528.png" alt="" width="800" height="412"&gt; &lt;pre&gt;npm run dev | pac code run&lt;/pre&gt;
&lt;br&gt;
 Once it launches successfully, access localhost:3000. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app012-1024x452.png" alt="" width="800" height="353"&gt;&lt;br&gt;
 The web app is running! &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app013-1024x602.png" alt="" width="800" height="470"&gt;


&lt;h3&gt;Building a Chat App with Azure OpenAI (AOAI)&lt;/h3&gt; Let's take it a step further by customizing the sample app to create a chat application. Edit App.tsx in the project and save. *The code is available &lt;a href="https://gist.github.com/ippu-i/cbff9bc767ba9b6f43380159af846dc4" rel="noopener nofollow sponsored ugc noreferrer"&gt;here&lt;/a&gt;. Note: This code has not been tested. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app013-2-1024x687.png" alt="" width="800" height="536"&gt;

Launch the app again, and you'll have a web application that enables conversations with Azure OpenAI. Since I've implemented SSE (Server-Sent Events) support, you can now have these types of real-time conversations that weren't possible in canvas apps. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1enew8mevz1mc7ngr27u.gif" alt="" width="600" height="387"&gt;



&lt;h2&gt;Upload the App to Power Platform&lt;/h2&gt; Finally, let's upload the created app to Power Apps. Use the pac code push command to push the app to your environment. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app015-1024x493.png" alt="" width="800" height="385"&gt; &lt;pre&gt;npm run build | pac code push&lt;/pre&gt; &lt;br&gt;
 The app you created will now appear in the app list! &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F09%2Ffirst-code-app016-1024x596.png" alt="" width="800" height="465"&gt;&lt;br&gt;
 When launched, you can interact with your custom web app directly within the Power Apps interface.&lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4d1k05z5yeaqg3n0zme2.gif" alt="" width="720" height="464"&gt;&lt;br&gt;


&lt;p&gt;This exciting new feature, "Code Apps," is likely to become the standard approach for internal applications where users have paid licenses, rather than using Azure Web Apps.&lt;/p&gt;

&lt;p&gt;The code is available here. Please note this is for demonstration purposes only and has not been tested:&lt;br&gt;
[&lt;a href="https://gist.github.com/ippu-i/cbff9bc767ba9b6f43380159af846dc4" rel="noopener noreferrer"&gt;https://gist.github.com/ippu-i/cbff9bc767ba9b6f43380159af846dc4&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>powerapps</category>
      <category>react</category>
      <category>azureopenai</category>
      <category>powerplatform</category>
    </item>
    <item>
      <title>Stop Initializing Arrays (In Single Loops): A Cleaner Power Automate Hack</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 03 Feb 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/stop-initializing-arrays-in-single-loops-a-cleaner-power-automate-hack-392l</link>
      <guid>https://forem.com/ippu_ito_870812/stop-initializing-arrays-in-single-loops-a-cleaner-power-automate-hack-392l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/compose-array/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just a quick note: I found that Power Automate’s “Compose” action can handle arrays, which is pretty handy.&lt;/p&gt;

&lt;h2&gt;The standard way to use an array&lt;/h2&gt;

&lt;p&gt;For example, if you want to store SharePoint Online (SPO) list items one by one into a variable, I used to do it like this with an array variable.&lt;br&gt;
Note: You can also use the “Select” action, but I’ll skip that for this post.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose001.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose001.png" alt="" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you output the variable contents, you’ll of course see multiple values stored like this.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose002-1024x759.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose002-1024x759.png" alt="" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;You can use “Compose” instead&lt;/h2&gt;

&lt;p&gt;It turns out you can actually replace this process with the “Compose” action. If you add “Compose” inside Apply to each like this and then output it using the outputs() function,&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose003-1024x621.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose003-1024x621.png" alt="" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;it outputs multiple values in an array format like this.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose004-1024x651.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose004-1024x651.png" alt="" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally, what I like about this is that since you don’t use “Initialize variable,” you can keep everything contained within the scope.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose005-1024x550.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose005-1024x550.png" alt="" width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;⚠️However, you can’t put it in a nested loop&lt;/h2&gt;

&lt;p&gt;That said, you can’t put it inside a nested loop, so the scenarios where you can use it may be a bit limited.&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose006-1024x620.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fcompose006-1024x620.png" alt="" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sharing this as a small tip that might come in handy someday.&lt;/p&gt;

</description>
      <category>powerautomate</category>
      <category>powerplatform</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dataverse Functions Deep Dive: Limitations, Transactions, and Performance</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 27 Jan 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/dataverse-functions-deep-dive-limitations-transactions-and-performance-ni4</link>
      <guid>https://forem.com/ippu_ito_870812/dataverse-functions-deep-dive-limitations-transactions-and-performance-ni4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/dataverse/dataverse-functions/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since a new feature called "Dataverse Functions" (or rather, a renamed feature) was added to Dataverse, I decided to put it to the test. Note: Formerly known as "Instant low-code plug-ins".&lt;/p&gt;

&lt;p&gt;This is a very welcome feature that effectively means "you can now write heavy server-side logic using Power Fx instead of C#."&lt;/p&gt;

&lt;p&gt;However, since the underlying architecture is still a hardcore "Dataverse Plugin," it inherits all the specific "limitations" and "pitfalls" associated with them.&lt;/p&gt;

&lt;p&gt;In this post, I’ll cover everything from the basics of how to create and use them, to verifying "transaction behavior," "processing speed," and the "limits of recursion."&lt;/p&gt;

&lt;h2&gt;
  
  
  About Dataverse Functions
&lt;/h2&gt;

&lt;p&gt;In a nutshell, this feature allows you to &lt;strong&gt;"create server-side logic using Power Fx."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Until now, whenever someone mentioned "Plug-ins," it was considered the "sanctuary of Pro Developers," requiring compiling C# code. This feature democratizes that process, allowing you to write logic using the Power Fx language you already use in apps.&lt;/p&gt;

&lt;p&gt;It used to be called "Instant low-code plug-ins" and was created via the "Dataverse Accelerator," but it has been renamed to "Functions" and feels much easier to create now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Use Cases for Dataverse Functions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server-side Execution:&lt;/strong&gt; Since it runs on the server rather than the app (client) side, &lt;strong&gt;it offers significant performance advantages when handling large amounts of data.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Written in Power Fx:&lt;/strong&gt; No need for &lt;code&gt;.NET&lt;/code&gt; knowledge. You can build backend logic with the same feel as writing formulas in Canvas Apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable:&lt;/strong&gt; Once created, a Function can be called from both Power Apps and Power Automate. This allows you to create "common components" that can be reused, preventing your logic from becoming scattered.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key selling point is: &lt;strong&gt;"Citizen developers can now create heavy server-side processing and shared logic using the Power Fx they are accustomed to."&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚠️ Limitations of Dataverse Functions
&lt;/h3&gt;

&lt;p&gt;Since these Functions run on the traditional "Dataverse Plug-in" infrastructure, they inherit strict constraints.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The 2-Minute Timeout
&lt;/h4&gt;

&lt;p&gt;Functions (Custom APIs) are synchronous by default. The caller (e.g., the App) waits for the result, but there is a &lt;strong&gt;strict limit of "2 minutes (120 seconds)."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the process exceeds 2 minutes, the server will forcibly terminate the execution (Timeout Exception).&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Depth Limit (Call Chain) is capped at 8
&lt;/h4&gt;

&lt;p&gt;There is a limit to "nesting" (Function A calls Function B, which calls C...) or chains where data updates trigger other logic.&lt;/p&gt;

&lt;p&gt;Generally, if the &lt;strong&gt;Depth exceeds 8&lt;/strong&gt;, the platform assumes an "infinite loop" and throws an error. (Depending on the environment, 16 might be allowed, but it is a golden rule to design within a depth of 8).&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Power Fx "Dialect" Restrictions
&lt;/h4&gt;

&lt;p&gt;Not all functions available in Canvas Apps can be used here.&lt;/p&gt;

&lt;p&gt;UI-related functions like &lt;code&gt;Launch()&lt;/code&gt; (screen transition) or &lt;code&gt;Maps()&lt;/code&gt; are strictly off-limits. This is purely for "data calculation and logic."&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics: How to Create and Use
&lt;/h2&gt;

&lt;p&gt;Now, let's look at the basic creation and usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Dataverse Function
&lt;/h3&gt;

&lt;p&gt;As an example, I'll create a function that "extracts an invoice number from an email body using Regular Expressions."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffds9xdn8dpagbb4f4v9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffds9xdn8dpagbb4f4v9b.png" alt="Dataverse Functions creation dashboard" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, create a solution, then:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnkpy6flu2xxdsm2cvu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdnkpy6flu2xxdsm2cvu1.png" alt="Selecting the solution and navigating to the add menu" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select [New] -&amp;gt; [Automation] -&amp;gt; [Function].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaqes2td9t1r5f70b0je.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaqes2td9t1r5f70b0je.png" alt="Navigating to New, Automation, then Function in Dataverse" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in the Display Name, Description, Parameters, and the Formula (Power Fx), then press [Save].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc2ferko8cgx8h04ghf4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc2ferko8cgx8h04ghf4.png" alt="Configuring Dataverse Function parameters and Power Fx formula" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Use the Match function to get all matches and return them as formatted JSON text
{
    MatchedItems: JSON(
        ForAll(MatchAll(InputText, "INV-\d{6}-\d{4}"), FullMatch),
        JSONFormat.IndentFour
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "Function" is now complete. If you want to edit it later, simply select the item where the Type is "Function".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodnsh7goot1sjg56fvz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodnsh7goot1sjg56fvz2.png" alt="Selecting the created Function from the solution list" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can then edit the formula.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0a16njvdshdtilkzjsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0a16njvdshdtilkzjsq.png" alt="Editing an existing Dataverse Function formula" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Dataverse Functions from Power Automate
&lt;/h3&gt;

&lt;p&gt;To call the created function from Power Automate, use the "Perform an unbound action" step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v0y0orxw0gjpe9p1h98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6v0y0orxw0gjpe9p1h98.png" alt="Power Automate action - Perform an unbound action step" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the created function in [Action Name] and set the arguments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dt36zz1f0dochb6ro6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7dt36zz1f0dochb6ro6a.png" alt="Configuring the unbound action with specific function parameters" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The invoice number is successfully extracted using regex.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz4nop8oljb91usqq506z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz4nop8oljb91usqq506z.png" alt="Power Automate flow run result showing successful regex extraction" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Dataverse Functions from Power Apps (Canvas)
&lt;/h3&gt;

&lt;p&gt;To call the created function from a Canvas App, you need to add the &lt;strong&gt;Environment&lt;/strong&gt; table to the app. You can call the function from there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruid7rs1zvz56p1azyhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruid7rs1zvz56p1azyhc.png" alt="Adding the Environment table to Power Apps to call Functions" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling Other Functions &amp;amp; Recursion
&lt;/h2&gt;

&lt;p&gt;It is also possible to call a created function from within another function.&lt;/p&gt;

&lt;p&gt;You can create a new function and call an existing one via &lt;code&gt;Environment&lt;/code&gt;, just like in Canvas Apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9i7kh25e8bdtg957u3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9i7kh25e8bdtg957u3g.png" alt="Calling a separate Dataverse Function within another Function" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-referencing is possible = Recursion! (Or so I thought…)
&lt;/h3&gt;

&lt;p&gt;Once saved, a function can even call itself.&lt;/p&gt;

&lt;p&gt;So, theoretically, you could construct a recursive process to calculate a factorial like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jqk1qqr6evm6ol7dbo2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jqk1qqr6evm6ol7dbo2.png" alt="Setting up a recursive factorial calculation in Power Fx" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, while this function works if &lt;code&gt;n&lt;/code&gt; is 8 or less (it's 5 in the image),&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyztsa74bfr2lgfkpon7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyztsa74bfr2lgfkpon7.png" alt="Successful result of the recursive function for small input" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you increase &lt;code&gt;n&lt;/code&gt; beyond that...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frblta3ry69h9hwbmc0ve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frblta3ry69h9hwbmc0ve.png" alt="Inputting a larger number to test recursion depth limits" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An error occurs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8trbi3s87pkuutzxcv94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8trbi3s87pkuutzxcv94.png" alt="Dataverse error notification showing execution was cancelled due to infinite loop" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Error Message:&lt;/strong&gt;&lt;br&gt;
Plugin Factorial failed with: CustomAPI parameter &lt;code&gt;$result&lt;/code&gt; failed with error Error: Error attempting Invoke: new_Factorial. This low-code plugin's execution was cancelled because the plugin logic caused an inifinite loop. Correct the plugin logic and try again.;;;;;;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This hits the "Depth Limit" mentioned in the limitations section.&lt;/p&gt;

&lt;p&gt;Since the max depth is 8 (technically 16 in some cases), building recursive processes like digging through folder structures isn't realistic. &lt;br&gt;
&lt;em&gt;Note: There probably aren't many use cases for this anyway.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Does Dataverse Functions Support Transactions?
&lt;/h2&gt;

&lt;p&gt;Reading through various documents, it seems Dataverse Functions should behave transactionally, so I conducted an experiment.&lt;/p&gt;

&lt;p&gt;I created a function that simply adds records to a "Child table" and a "Parent table". &lt;em&gt;(I will explain later why I didn't use Patch).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgn0jxrov7b9d9s0xh9k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgn0jxrov7b9d9s0xh9k.png" alt="Formula for adding records to multiple tables in a single Function" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Calling this normally succeeds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddhtuw36etsnxo1txxhe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddhtuw36etsnxo1txxhe.png" alt="Successful execution result of parent and child record creation" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30nw08dy7umnb6s4q7tn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30nw08dy7umnb6s4q7tn.png" alt="Database view showing newly created parent and child records" width="479" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, what if I force the function to crash with a "divide by zero" error &lt;em&gt;after&lt;/em&gt; creating the Child record?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ov7n09v08fmxrjtc5lf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ov7n09v08fmxrjtc5lf.png" alt="Injecting a divide by zero error to test transaction rollback" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp3n84pcz25o0adf73o1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdp3n84pcz25o0adf73o1.png" alt="Error thrown during the test execution" width="794" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As expected, neither the Parent nor the Child record was created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9xt07spwhsn8rxmrhq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9xt07spwhsn8rxmrhq1.png" alt="Empty database view confirming transaction rollback" width="480" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on this behavior, it seems to function correctly as a transaction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Further verification is needed to see if this applies to all Create/Update/Delete operations.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Tip 1: Comparing with Power Apps (Canvas) Behavior
&lt;/h3&gt;

&lt;p&gt;Incidentally, if you execute the same logic (error halfway through) directly in a Canvas App:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folwwfxp7kpniocyndy89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folwwfxp7kpniocyndy89.png" alt="Testing the same error-prone logic directly within a Canvas App" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surprisingly, the Parent record creation (the process &lt;em&gt;after&lt;/em&gt; the error) succeeds. This behavior might need its own detailed investigation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxndx8uorkxqj211nivoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxndx8uorkxqj211nivoy.png" alt="Database showing partial success in Canvas App despite error" width="472" height="396"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Tip 2: Cannot Save Function if using "Patch" for Creation
&lt;/h3&gt;

&lt;p&gt;Currently, if you try to use &lt;code&gt;Patch&lt;/code&gt; to &lt;strong&gt;add&lt;/strong&gt; data within a Function, you will encounter a save error. Therefore, when adding data, you must use the &lt;code&gt;Collect&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;However, "Updating" records with Patch works fine.&lt;/p&gt;

&lt;p&gt;You cannot specify the second argument of Patch because the &lt;code&gt;Defaults&lt;/code&gt; function is not supported in Functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d96vkqasgw8tug0mbvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d96vkqasgw8tug0mbvf.png" alt="Save error when attempting to use Patch with Defaults in a Function" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Error Message:&lt;/strong&gt;&lt;br&gt;
An unexpected error occurred while updating Function: Dependency check failed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Validating Bulk Updates (Canvas vs. Functions)
&lt;/h2&gt;

&lt;p&gt;Finally, let's compare "Processing Speed."&lt;/p&gt;

&lt;p&gt;As mentioned in the article below, when performing bulk updates from a Canvas App, using &lt;code&gt;Patch&lt;/code&gt; was generally the fastest method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ippu-biz.com/development/powerplatform/powerapps/update-all-data-dataverse" rel="noopener noreferrer"&gt;https://ippu-biz.com/development/powerplatform/powerapps/update-all-data-dataverse&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When doing this from Functions, doing a bulk &lt;code&gt;Patch&lt;/code&gt; is tricky (no UI, and &lt;code&gt;UpdateIf&lt;/code&gt; isn't stable), so you'll likely end up looping with &lt;code&gt;ForAll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0en1mny619xrww34bvjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0en1mny619xrww34bvjg.png" alt="Formula using ForAll and Patch for bulk updates in a Function" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Surprisingly, even executing Patch 500 times in a loop took only &lt;strong&gt;13 seconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0npvnit34212apzzsw0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0npvnit34212apzzsw0l.png" alt="Execution time result showing 13 seconds for 500 record updates" width="800" height="498"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;With({records:Sample500},
    ForAll(records As record,
        Patch(Sample500 , record, {str:"a"});
    )
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the request from the client is sent only once, significantly reducing communication overhead.&lt;/p&gt;

&lt;p&gt;If you need to update a large amount of data with fine-grained control via loops, it seems best to handle it on the Functions side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Dataverse Functions is still in preview and has various limitations, but it proved to be a very useful feature that I expect to use more frequently in the future.&lt;/p&gt;

</description>
      <category>powerplatform</category>
      <category>dataverse</category>
      <category>microsoft</category>
      <category>powerautomate</category>
    </item>
    <item>
      <title>Agent Evaluation in Copilot Studio: Test Methods, Thresholds, and Regression Checks</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Thu, 25 Dec 2025 13:10:04 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/agent-evaluation-in-copilot-studio-test-methods-thresholds-and-regression-checks-10do</link>
      <guid>https://forem.com/ippu_ito_870812/agent-evaluation-in-copilot-studio-test-methods-thresholds-and-regression-checks-10do</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/copilot-studio/automated-testing/" rel="noopener noreferrer"&gt;My Tech Blog.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I tried out the automated testing (evaluation feature) for agents created with Copilot Studio, which is now available.&lt;br&gt;
It is a huge deal that we can now check response accuracy in bulk using a test set (CSV), a task that previously had to be done manually.&lt;/p&gt;

&lt;h2&gt;The Importance of Automated Testing in AI Agent Development to Ensure Quality in Copilot Studio&lt;/h2&gt;

&lt;p&gt;In AI agent development, quality assurance is a very important theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unlike traditional rule-based development, generative AI is always accompanied by variability in answers and hallucinations.&lt;/strong&gt; A single mistake can easily lead users to have a negative impression, thinking, "This is why AI is..."&lt;/p&gt;

&lt;p&gt;Therefore, a rigorous testing process is crucial, but &lt;span&gt;&lt;strong&gt;it is not realistic for humans to manually keep checking nearly infinite input patterns in natural language&lt;/strong&gt;&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;This is why the introduction of "Automated Testing," which I will introduce here, becomes an essential element in creating "trusted agents" that can be operated in production with peace of mind.&lt;/p&gt;

&lt;h2&gt;Automated Testing in Copilot Studio&lt;/h2&gt;

&lt;p&gt;Automated testing in Copilot Studio is performed from the [Evaluation] tab.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing003-1024x618.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing003-1024x618.png" alt="" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For testing, first prepare data containing the following four items:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Questions for the agent&lt;/li&gt;
    &lt;li&gt;Ideal responses (Expected responses)&lt;/li&gt;
    &lt;li&gt;Evaluation method (Test Method)&lt;/li&gt;
    &lt;li&gt;Threshold for success (depending on the evaluation method)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Select the "Test Method" from the following options according to what you want to verify:&lt;/p&gt;

&lt;dl&gt;
    &lt;dt&gt;&lt;strong&gt;・General quality&lt;/strong&gt;&lt;/dt&gt;
    &lt;dd&gt;
        The most advanced evaluation method using generative AI. An LLM acts as a judge and scores comprehensively from the following four perspectives. It is ideal for testing generative AI-like responses where "there is no single correct answer."
        &lt;ul&gt;
            &lt;li&gt;Relevance: Does it answer the intent of the question accurately?&lt;/li&gt;
            &lt;li&gt;Groundedness: Is the answer based on the data source (free of hallucinations)?&lt;/li&gt;
            &lt;li&gt;Completeness: Is all necessary information covered without omission?&lt;/li&gt;
            &lt;li&gt;Politeness: Is the tone polite and free of inappropriate expressions?&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/dd&gt;

    &lt;dt&gt;&lt;strong&gt;・Compare meaning&lt;/strong&gt;&lt;/dt&gt;
    &lt;dd&gt;
        Determines whether the "intent of the text" matches. It does not require a word-for-word match; if the underlying meaning and ideas match the expected value (ideal response), it is considered a pass, even if the expression is different. Effective when you want to emphasize semantic correctness.
    &lt;/dd&gt;

    &lt;dt&gt;&lt;strong&gt;・Similarity&lt;/strong&gt;&lt;/dt&gt;
    &lt;dd&gt;
        The AI uses "cosine similarity" to calculate the closeness between the agent's response and the expected value with a score of 0 to 1. Used when you want to evaluate mechanically, including semantic closeness, not just exact word matches.
    &lt;/dd&gt;

    &lt;dt&gt;&lt;strong&gt;・Exact match&lt;/strong&gt;&lt;/dt&gt;
    &lt;dd&gt;
        Checks if the response is "completely identical" to the expected value. A 100% match is required, including characters, numbers, and symbols. Used for confirming data where absolutely no variability is allowed, such as model numbers, codes, or fixed standard phrases.
    &lt;/dd&gt;

    &lt;dt&gt;&lt;strong&gt;・Partial match&lt;/strong&gt;&lt;/dt&gt;
    &lt;dd&gt;
        Checks if the response contains expected "specific keywords" or "phrases." Useful for requirement checks, such as whether a guidance sentence like "Contact support for unclear points" is included, or if a mandatory URL is present.
    &lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;Now, let's actually perform an automated test.&lt;br&gt;
In this article, I will walk you through 1) Creating a test set, 2) Execution procedure, 3) How to judge results, and 4) How to deal with garbled text.&lt;/p&gt;

&lt;h2&gt;Prerequisites: Creating an Agent to Test&lt;/h2&gt;

&lt;p&gt;As preparation, create an agent to be tested. This time, I will create one with the setting of an "Agent working at a cafe."&lt;/p&gt;

&lt;p&gt;First, create an agent that can converse in Japanese (or your target language),&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing001-1024x579.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing001-1024x579.png" alt="" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the following prompt in the instructions:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing002-1024x567.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing002-1024x567.png" alt="" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;small&gt;You are the AI Virtual Barista for "Blue Cloud Coffee."
In this cafe, primarily visited by cloud engineers and developers, your role is to answer questions from customers and provide a comfortable "deployment wait time."

## Character Settings and Behavior
- Tone &amp;amp; Manner: Intelligent and friendly, with a bit of humor. Converse by moderately mixing IT terminology and jokes for engineers.
- Politeness: Basically use polite language, but do not be too stiff; maintain a flat sense of distance like talking to a colleague engineer.
- Expertise: In addition to coffee knowledge, be particularly accurate in answering infrastructure information that engineers care about, such as Wi-Fi and power supply environments.

## Response Guidelines
1. Add a welcome message mixed with some IT terms to your greeting. (e.g., "Thank you for accessing," "Connection established," etc.)
2. When guiding the menu, do not just explain the taste but add benefits for engineers (boost effect from caffeine, relaxation effect, etc.).
3. Respond humorously to errors or unclear questions, mixing expressions like "404 Not Found (Answer not found)" or "Internal Server Error (Thinking)."
4. Do not force the creation of information that is not in the knowledge base; honestly convey, "That data is not indexed in my database."

## Prohibitions
- For topics about competitors (other cafe chains), lightly brush them off as "stories from another region."
- Do not perform code debugging or actual programming support. Decline by saying, "I leave that to Stack Overflow."&lt;/small&gt;&lt;/pre&gt;

&lt;p&gt;Add the following text file and description to Knowledge.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing002-2-1024x569.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing002-2-1024x569.png" alt="" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
Text file below:&lt;/p&gt;

&lt;pre&gt;&lt;small&gt;Store Name: Blue Cloud Coffee
Concept: A cafe where cloud engineers can relax, fusing technology and coffee.
Address: 1-2-3 Tech Park, Minato-ku, Tokyo
Business Hours: Weekdays 8:00-20:00, Weekends/Holidays 10:00-18:00
Closed: Every Tuesday
Wi-Fi SSID: BlueCloud_Guest
Wi-Fi Password: Coffee2025!
Payment Methods: Completely cashless (Credit card, Transit IC, QR payment only). Cash cannot be used.
Menu:
- Serverless Espresso: 400 yen (Rich and strong bitterness)
- API Latte: 550 yen (Plenty of milk and sweet)
- Deploy Donut: 300 yen (Excellent compatibility with coffee)
Power Supply: Available at all seats. Monitor rental is also available.&lt;/small&gt;&lt;/pre&gt;

&lt;p&gt;Description below:&lt;/p&gt;

&lt;pre&gt;&lt;small&gt;Use this knowledge when the user is seeking basic information about the cafe "Blue Cloud Coffee."
Specifically, refer to this when answering the following questions:
- Basic information such as store address, business hours, and closed days
- Connection information such as Wi-Fi SSID and password
- Available payment methods (cashless support, etc.)
- Coffee and food menu and prices
- In-store facilities and atmosphere (power supply, for engineers, etc.)

Import the test cases you want to use for testing the agent.&lt;/small&gt;&lt;/pre&gt;

&lt;p&gt;The construction of the agent to be tested is now complete.&lt;/p&gt;

&lt;h2&gt;Creating a Test Set (Test Items)&lt;/h2&gt;

&lt;p&gt;Next, create the test set (test items) to be used for automated testing.&lt;/p&gt;

&lt;p&gt;From [Create test set] in the [Evaluation] tab,&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing003-1024x618.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing003-1024x618.png" alt="" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the test set template (CSV) file.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing004-1024x620.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing004-1024x620.png" alt="" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the downloaded file. Lines up to 14 are comments, and line 15 onwards are the actual test items.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing005-1024x520.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing005-1024x520.png" alt="" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time, I created the test items as follows. From left to right: "Question to AI," "Ideal (Expected) Answer," "Test Method," "Score to be considered a success."&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing006.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing006.png" alt="" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upload this, and preparation is complete.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is convenient to save the uploaded test set with a name, as you can test it as many times as you like afterwards.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing008-1024x605.png" alt="" width="800" height="472"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Executing Automated Tests&lt;/h2&gt;

&lt;p&gt;When you press the [Evaluation] button in the previous state,&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing008-1024x605.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing008-1024x605.png" alt="" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be asked for a connection (connector), so connect with your account and execute.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing009-1024x610.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing009-1024x610.png" alt="" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the test is completed, the success rate is displayed like this.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing010-1024x360.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing010-1024x360.png" alt="" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Details of Test Results&lt;/h2&gt;

&lt;p&gt;Finally, let's look at the details of the test results.&lt;/p&gt;

&lt;p&gt;First, the question about closed days. Since I selected "Compare meaning" as the test method and set the success threshold to 70, it was judged as a success. Comparing the expected response and the agent's response, it looks quite acceptable.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing011-1024x609.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing011-1024x609.png" alt="" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, the question about cash payment. Since I selected "Partial match" as the test method, it resulted in NG because the ideal response (Cash cannot be used) was not included in the answer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is an example of poor test item creation; originally, this should have been carried out with "Compare meaning" or similar.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing012-1024x613.png" alt="" width="800" height="478"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the question about business hours. When I set the test method to "Similarity" and the threshold to 70, it resulted in NG.&lt;br&gt;
However, since the AI answered correctly here as well, this is a test item where the "threshold" should be lowered, or the test method should be changed to "Compare meaning."&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing013-1024x619.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F12%2Fautomated-testing013-1024x619.png" alt="" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, this is a very powerful automated testing feature.&lt;/p&gt;

&lt;p&gt;Even when you make minor corrections to prompts or update knowledge (like SPO), you can immediately detect "if previous answers are broken" just by running this test, so I recommend introducing it at a mandatory level for actual operations.&lt;/p&gt;

</description>
      <category>powerplatform</category>
      <category>copilotstudio</category>
      <category>testing</category>
    </item>
    <item>
      <title>Power Automate Trigger Condition Formulas Cheat Sheet: Ready-to-Use Examples for Business Hours &amp; Email Filtering</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Thu, 25 Dec 2025 13:08:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/power-automate-trigger-condition-formulas-cheat-sheet-ready-to-use-examples-for-business-hours--28nc</link>
      <guid>https://forem.com/ippu_ito_870812/power-automate-trigger-condition-formulas-cheat-sheet-ready-to-use-examples-for-business-hours--28nc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally &lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/trigger-condition-templates/" rel="noopener noreferrer"&gt;published on My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's a collection of Power Automate trigger condition formulas that I personally use frequently or get asked about often.&lt;/p&gt;

&lt;h2&gt;Trigger Conditions&lt;/h2&gt; Power Automate trigger conditions are a feature that allows you to set conditions for when a trigger should execute. In the new designer, you can access this from the [Settings] tab: &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-3.png" alt="" width="781" height="566"&gt; In the classic designer, you can specify this from the [Settings] menu: &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-1-1024x327.png" alt="" width="800" height="255"&gt; &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-2-1024x600.png" alt="" width="800" height="468"&gt; By the way, this formula uses the same syntax as when editing the "Filter array" action in "advanced mode": &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-4.png" alt="" width="641" height="192"&gt;
The major benefit of using trigger conditions is that &lt;span&gt;&lt;strong&gt;the flow execution itself doesn't occur, which helps reduce execution counts and resource consumption&lt;/strong&gt;&lt;/span&gt;.
[https://learn.microsoft.com/en-us/power-automate/limits-and-config]

In this article, I'll compile the trigger condition processes that I personally use most frequently.

&lt;h2&gt;Date and Time&lt;/h2&gt; Date and time condition formulas are commonly used with "Scheduled" triggers. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-1024x408.png" alt="" width="800" height="318"&gt; &lt;h3&gt;Day of the Week&lt;/h3&gt; Let's start with days of the week. These are frequently used for flows that should run only on weekdays or only on weekends (like batch processes). 
* Public holidays are difficult to handle with trigger conditions (while not impossible if you specify fixed values, it's quite cumbersome...), so holidays are often filtered out using conditional logic within the flow itself.

&lt;pre&gt;
// Only run from Monday to Friday
&lt;a class="mentioned-user" href="https://dev.to/and"&gt;@and&lt;/a&gt;(
  greaterOrEquals(dayOfWeek(addHours(utcNow(), 9)), 1),
  lessOrEquals(dayOfWeek(addHours(utcNow(), 9)), 5)
)

// Only run on Saturday and Sunday
&lt;a class="mentioned-user" href="https://dev.to/or"&gt;@or&lt;/a&gt;(
  equals(dayOfWeek(addHours(utcNow(), 9)), 0),
  equals(dayOfWeek(addHours(utcNow(), 9)), 6)
)

// Only run on a specific day of the week (in this example, Wednesday only)
@equals(dayOfWeek(addHours(utcNow(), 9)), 3)

// Result of dayOfWeek function: Sunday=0, Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6
&lt;/pre&gt;

&lt;h3&gt;Time&lt;/h3&gt; 
Next is time. These are commonly used for flows that should run during business hours or outside of business hours.

&lt;pre&gt;
// Within business hours (in this example, business hours are from 09:00 to 18:00)
&lt;a class="mentioned-user" href="https://dev.to/and"&gt;@and&lt;/a&gt;(
  greaterOrEquals(addHours(utcNow(), 9, 'HH:mm'), '09:00'), // (Time must be in 24-hour format with leading zeros)
  lessOrEquals(addHours(utcNow(), 9, 'HH:mm'), '18:00')
)

// Outside of business hours
&lt;a class="mentioned-user" href="https://dev.to/or"&gt;@or&lt;/a&gt;(
  less(addHours(utcNow(), 9, 'HH:mm'), '08:00'),
  greater(addHours(utcNow(), 9, 'HH:mm'), '18:00')
)
&lt;/pre&gt;

&lt;h2&gt;Outlook&lt;/h2&gt; Next is Outlook. These are used for flows that should run only when the subject contains specific text, or when emails are received from specific senders.
&lt;pre&gt;
// Only trigger for emails from a specific sender (in this example, sample@example.com)
@equals(triggerOutputs()?['body/from'], 'sample@example.com')

// If there are multiple specific email addresses
&lt;a class="mentioned-user" href="https://dev.to/or"&gt;@or&lt;/a&gt;(
  equals(triggerOutputs()?['body/from'], 'sample1@example.com'),
  equals(triggerOutputs()?['body/from'], 'sample2@example.com')
)

// Only trigger for emails from a specific domain
@endsWith(toLower(triggerOutputs()?['body/from']), '@example.com')

// If there are multiple specific domains
&lt;a class="mentioned-user" href="https://dev.to/or"&gt;@or&lt;/a&gt;(
  endsWith(toLower(triggerOutputs()?['body/from']), '@example.com'),
  endsWith(toLower(triggerOutputs()?['body/from']), '@example.org')
)

// Only trigger if the subject contains a specific keyword (in this example, "invoice")
@contains(triggerOutputs()?['body/subject'], 'invoice')
&lt;/pre&gt;

&lt;h2&gt;SharePoint, OneDrive&lt;/h2&gt; For SharePoint and OneDrive, these are primarily used for flows that trigger only when files with specific extensions or files containing specific text in their names are uploaded to document libraries.

&lt;pre&gt;
// Trigger only for specific file extensions (e.g., .pdf files)
@endsWith(toLower(triggerOutputs()?['body/{FilenameWithExtension}']), '.pdf')

// Trigger only when filename contains specific text (e.g., "invoice")
@contains(triggerOutputs()?['body/{FilenameWithExtension}'], 'invoice')
&lt;/pre&gt;

The following sections are for testing each formula. Please proceed if you're interested.

&lt;h2&gt;Testing&lt;/h2&gt; 


&lt;h3&gt;Date and Time&lt;/h3&gt; For testing date and time functionality, I set up a scheduled trigger that runs every minute. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions000-5-1024x408.png" alt="" width="800" height="318"&gt; &lt;br&gt;
&lt;h4&gt;Day of the Week&lt;/h4&gt; First, I configured the trigger condition to run only "Monday through Friday": &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions001-1024x531.png" alt="" width="800" height="414"&gt; When tested on 5/29 (Thursday), the flow triggers successfully. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions002-1024x726.png" alt="" width="800" height="567"&gt; In contrast, when configured to run only on weekends: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions003-1024x465.png" alt="" width="800" height="363"&gt; Since it's Thursday, the flow doesn't trigger. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions004-1024x708.png" alt="" width="800" height="553"&gt; &lt;h4&gt;Time&lt;/h4&gt; Next, when configured to run only between "08:00 ~ 22:05": &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions005-1024x465.png" alt="" width="800" height="363"&gt; The flow doesn't trigger after 22:06. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions006-1024x729.png" alt="" width="800" height="569"&gt; Conversely, when configured to trigger after 22:10: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions007-1024x468.png" alt="" width="800" height="365"&gt; The flow starts triggering from 22:11 onwards. 

&lt;ul&gt;
&lt;li&gt;22:11 was skipped due to the timing of saving the flow. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions008-1024x639.png" alt="" width="800" height="499"&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;h3&gt;Outlook&lt;/h3&gt; The trigger used is "When a new email arrives". &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions008-2-1024x257.png" alt="" width="800" height="200"&gt; First, when configured to trigger only for a specific email address: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions009-1024x697.png" alt="" width="800" height="544"&gt; Even when two emails arrive simultaneously: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions010.png" alt="" width="778" height="411"&gt; The flow triggers only once (only for the specified email address). &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions011-1024x584.png" alt="" width="800" height="456"&gt; Next, when configured to trigger only for a specific domain: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions011-2.png" alt="" width="800" height="656"&gt; Even when emails from two different domains arrive (one being Gmail): &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions012.png" alt="" width="800" height="347"&gt; The flow triggers only once (for the specified domain only). &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions013-1024x610.png" alt="" width="800" height="476"&gt;


&lt;h3&gt;SharePoint&lt;/h3&gt; For the SharePoint experiment, I used the "When a file is created" trigger. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions016-1024x409.png" alt="" width="800" height="319"&gt; First, when configured to trigger only for PDF files: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions017-1024x651.png" alt="" width="800" height="508"&gt; Even when uploading two files simultaneously: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions018.png" alt="" width="633" height="321"&gt; The flow triggers only once (for the PDF file). &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions019-1024x642.png" alt="" width="800" height="501"&gt; Next, when configured to trigger only when the filename contains "invoice": &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions020-1024x724.png" alt="" width="800" height="565"&gt; Even when uploading two files: &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions021.png" alt="" width="535" height="363"&gt; Only the invoice file triggers the flow. &lt;br&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F05%2Ftrigger-conditions022-1024x632.png" alt="" width="800" height="493"&gt; 

&lt;h2&gt;Related Articles&lt;/h2&gt;

&lt;p&gt;[&lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/get-items/" rel="noopener noreferrer"&gt;https://ippu-biz.com/en/development/powerplatform/powerautomate/get-items/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/filter-sharepoint-list-boolean/" rel="noopener noreferrer"&gt;https://ippu-biz.com/en/development/powerplatform/powerautomate/filter-sharepoint-list-boolean/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/excel-filter-query/" rel="noopener noreferrer"&gt;https://ippu-biz.com/en/development/powerplatform/powerautomate/excel-filter-query/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://ippu-biz.com/en/development/powerplatform/powerautomate/filter-using-datetime/" rel="noopener noreferrer"&gt;https://ippu-biz.com/en/development/powerplatform/powerautomate/filter-using-datetime/&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>powerplatform</category>
      <category>powerautomate</category>
    </item>
    <item>
      <title>How to Use Structured JSON Output in AI Builder for Power Automate</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Wed, 24 Dec 2025 13:00:00 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/how-to-use-structured-json-output-in-ai-builder-for-power-automate-2g6n</link>
      <guid>https://forem.com/ippu_ito_870812/how-to-use-structured-json-output-in-ai-builder-for-power-automate-2g6n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/ai-builder/change-prompt-output/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI Builder has added a feature similar to structured outputs, so I decided to try it out.&lt;/p&gt;

&lt;h2&gt;What is JSON Output?&lt;/h2&gt;

&lt;p&gt;Broadly speaking, JSON output (structured output) means &lt;span&gt;&lt;strong&gt;"specifying the LLM's response into a designated JSON format data."&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Until now, we used prompts like the following to specify the output, but the stability of the output wasn't quite there.&lt;/p&gt;

&lt;pre&gt;
Generate the output in the following JSON format.

# output json schema
{
    "type" : "object",
    "properties" :
(omitted below)
}
&lt;/pre&gt;

&lt;p&gt;Original OpenAI models and Azure OpenAI GPT models added "Structured Outputs" (formerly JSON mode), and now a corresponding feature has been equipped in AI Builder as well.&lt;/p&gt;

&lt;p&gt;So, I decided to play around with it immediately.&lt;/p&gt;

&lt;p&gt;*Official documentation is here:&lt;br&gt;
[&lt;a href="https://learn.microsoft.com/en-us/ai-builder/change-prompt-output" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/ai-builder/change-prompt-output&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;Building JSON Output&lt;/h2&gt;

&lt;p&gt;For example, let's say we receive an email like this and want to use AI to extract "candidate dates and times."&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output001.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output001.png" alt="" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, select the "Create text with GPT using a prompt" action and choose [New custom prompt].&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output001-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output001-2.png" alt="" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up a nice prompt.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output002-1024x601.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output002-1024x601.png" alt="" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, select the "Output" icon, click [JSON] -&amp;gt; [Edit].&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output003-1024x581.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output003-1024x581.png" alt="" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter an example of the JSON you want to output, click [Apply], and then [Save custom prompt].&lt;br&gt;
*You can also specify the output JSON using a schema.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output004-1024x592.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output004-1024x592.png" alt="" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, go back to Power Automate and input the string from earlier into the Input field to complete it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output005.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output005.png" alt="" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you run the flow, it returns the response in the "specified JSON" like this.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output006-1024x569.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output006-1024x569.png" alt="" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;The Benefits of JSON Output&lt;/h2&gt;

&lt;p&gt;The advantage of outputting in JSON is that &lt;span&gt;&lt;strong&gt;"it is easy to handle the results generated by GPT as data."&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For example, in this case, by combining the generation results from GPT with Outlook's "Create event" action,&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output009.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output009.png" alt="" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you can easily set the generated values to "Start time" and "End time,"&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output010.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output010.png" alt="" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and easily add a schedule using a flow combined with GPT.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output011-1024x575.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2024%2F12%2Fjson-output011-1024x575.png" alt="" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, that was the extremely convenient JSON output.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>powerplatform</category>
      <category>pwabuilder</category>
    </item>
    <item>
      <title>How to Use the New Dataverse “Prompt Column” to Automate Categorization with AI</title>
      <dc:creator>Ippu Ito</dc:creator>
      <pubDate>Tue, 23 Dec 2025 01:52:19 +0000</pubDate>
      <link>https://forem.com/ippu_ito_870812/how-to-use-the-new-dataverse-prompt-column-to-automate-categorization-with-ai-3e37</link>
      <guid>https://forem.com/ippu_ito_870812/how-to-use-the-new-dataverse-prompt-column-to-automate-categorization-with-ai-3e37</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally published on &lt;a href="https://ippu-biz.com/en/development/powerplatform/dataverse/prompt-column/" rel="noopener noreferrer"&gt;My Tech Blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A new "Prompt column" has been added to Dataverse, so I verified how it works.&lt;/p&gt;

&lt;h2&gt;Prompt column&lt;/h2&gt;

&lt;p&gt;The new Dataverse feature, "Prompt column," is a column where generative AI automatically populates values by referencing information from other columns in the table.&lt;/p&gt;

&lt;p&gt;It is faster to demonstrate it in action than to explain it, so here is a verification of its behavior.&lt;/p&gt;

&lt;h2&gt;Preparation&lt;/h2&gt;

&lt;p&gt;Let's assume we have an "Inquiry" table like the following.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column001-1024x541.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column001-1024x541.png" alt="" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suppose we want to &lt;span&gt;&lt;strong&gt;add a "Category" column to this table and "automatically" categorize items into "Request," "Question," "Consultation," etc.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Previously, I would combine Power Automate and AI Builder, but this time I will achieve this using the Prompt column.&lt;/p&gt;

&lt;h2&gt;Configuration&lt;/h2&gt;

&lt;p&gt;First, select [New column], choose [Prompt] for the [Data type], and&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column002-1024x721.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column002-1024x721.png" alt="" width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click [Add new prompt].&lt;br&gt;
*Currently, the format is "Text" only.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column003-1024x629.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column003-1024x629.png" alt="" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, configure the prompt as shown below and save it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column004-1024x636.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column004-1024x636.png" alt="" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, save the column to complete the configuration.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column005-1024x639.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column005-1024x639.png" alt="" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Verification&lt;/h2&gt;

&lt;p&gt;Add the category column to the form for verification.&lt;br&gt;
*Set it to read-only so it is not modified by mistake.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column006-1024x630.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column006-1024x630.png" alt="" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, enter an appropriate title and body in the form, and when you click [Save],&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column007-1024x283.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column007-1024x283.png" alt="" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result categorized by the AI will be populated.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column008-1024x293.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column008-1024x293.png" alt="" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the title and body indicate a "Question," the category becomes "Question."&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column009-1024x287.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column009-1024x287.png" alt="" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is convenient!&lt;/p&gt;

&lt;p&gt;While the Prompt column is extremely useful, it appears to operate using AI Builder credits. Therefore, exercise caution if you create it in a table where a large number of records are added, as unexpected costs may occur.&lt;/p&gt;

&lt;h2&gt;Bonus 1: Structured output (JSON mode) is also possible&lt;/h2&gt;

&lt;p&gt;Structured output is also possible, so use this if you want to strictly constrain the output.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column011-1024x603.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column011-1024x603.png" alt="" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more on structured output:&lt;br&gt;
[&lt;a href="https://ippu-biz.com/en/development/powerplatform/ai-builder/change-prompt-output/" rel="noopener noreferrer"&gt;https://ippu-biz.com/en/development/powerplatform/ai-builder/change-prompt-output/&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;Bonus 2: "PromptColumnExtension" error occurs without AI Builder license or credits&lt;/h2&gt;

&lt;p&gt;If users without an AI Builder trial license run this, or if executed in an environment with no credits, a PromptColumnExtension error will occur.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column010-1024x464.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fippu-biz.com%2Fwp-content%2Fuploads%2F2025%2F10%2Fprompt_column010-1024x464.png" alt="" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>powerapps</category>
      <category>powerplatform</category>
    </item>
  </channel>
</rss>
