Tag: Power Platform

  • How to Build Your First AI Agent in Copilot Studio

    How to Build Your First AI Agent in Copilot Studio

    Step by step diagram showing how to build an AI agent in Copilot Studio, from instructions to knowledge to tools to publishing

    Microsoft published a guide on how to build an AI agent aimed at anyone, and the framework is genuinely sound: define the job, give the agent knowledge, give it tools, test it, let it run. What the article does not give you is the clicks. So this is how to build an AI agent in Copilot Studio following that exact recipe, end to end. By the end you have a working internal FAQ agent that can also create a ticket, published to Teams. I built a variant of this internally last quarter, and the framework holds up. The gaps between the steps are where it gets interesting.

    Step 1: Define One Job Before You Build an AI Agent in Copilot Studio

    Microsoft’s guide says start with a clear purpose. In practice this means the Instructions field, and this is where most first builds go wrong. People write vibes: “You are a helpful assistant for IT questions.” That constrains nothing. Write scope enforcement instead:

    You answer questions about internal IT policies using only the attached knowledge sources. If the answer is not in the knowledge sources, say so and offer to create a support ticket. Do not answer questions about HR, payroll, or anything outside IT. Do not guess at policy details.

    Keep it under 500 tokens. I covered why in the business skills post: instruction sets that grow past a few hundred tokens start degrading reliability. One job. Tight boundaries. Explicit refusal behavior.

    Step 2: Attach a Knowledge Source the Agent Can Cite

    In the agent’s Knowledge section, add your SharePoint site. Use the site URL, not a document library deep link, and check that the files are PDF or Word. The indexer handles those well. It handles scanned images inside PDFs poorly, and you will not find out until the agent confidently answers from the two readable pages and ignores the rest.

    Turn on “Use general knowledge” only if you have a reason. For an internal policy agent, leave it off. Grounded-only answers with citations beat fluent answers with no source. If you are choosing between SharePoint and Dataverse here, I compared them in a separate post. For a first build, SharePoint is the shorter path. If you plan to give the agent its own identity and audit trail inside Dataverse, Entra Agent ID gives every Dataverse agent its own identity and is worth reading before you commit to the data layer.

    Step 3: Give It One Tool With a Power Automate Flow

    Microsoft’s guide calls this “giving the agent the ability to act.” Concretely: build a flow with the When an agent calls the flow trigger, add two text inputs (ticketTitle, ticketDescription), create the ticket row wherever your ticketing lives, and end with Respond to the agent returning the ticket number and status. Do not return a bare “success” flag. Return state the agent can reason about on the next turn. The Copilot Studio docs cover the wiring, but they undersell the description field.

    Then add the flow as a tool on the agent, and write the tool description as a retrieval hint, not documentation: Creates an IT support ticket when the user reports a problem that the knowledge sources cannot resolve. The orchestrator scores this against user input to decide when to call it. I went deep on this in How to Design Tool Definitions for Copilot Studio Agents. One tool for now. Resist adding more until the first one behaves.

    Step 4: Test in the Canvas With the Activity Map Open

    Open the test pane and turn on the activity map. Now test the way real users will actually talk, not the way you wish they would. Three categories: questions the knowledge sources answer, requests that should trigger the ticket flow, and deliberately bad inputs. “my thing is broken.” “can you help.” A question about payroll that should get refused.

    The activity map shows you which knowledge source or tool the orchestrator picked and why. When it picks wrong, the fix is almost always the tool description or the instructions, not the model. This is the step people consistently skip, and it is the one that decides whether the agent survives contact with real users. I wrote about why agents fail in production after passing testing, and clean test conversations are the whole story. Testers ask questions they already know the agent can answer. Real users do not.

    Step 5: Publish to Teams and Watch the First Week

    Publish, then add the Microsoft Teams channel. Start with “available to specific users” and pick a pilot group of ten people, not the whole org. Then read the transcripts in the Analytics section every day for the first week. Not the satisfaction score. The actual conversations. You will find phrasings you never tested, a refusal that fired too aggressively, and at least one question your knowledge source cannot answer that it obviously should. That first week of transcripts is worth more than any amount of pre-launch testing. If generative answers start overriding your scoped topics during this phase, the fix is covered in Stop Copilot Studio Generative Answers From Hijacking Your Topics.

    The Working Agent and the Pitfall That Breaks Most First Builds

    Final state: one agent, one scoped job, one SharePoint knowledge source, one flow that creates tickets, published to a Teams pilot group. Microsoft’s five-part recipe maps cleanly onto this. The guide is right that anyone can follow the framework.

    The pitfall: skipping step 4 because the happy path worked twice in the test canvas. In my experience the agents that embarrass their builders are never the ones that failed in testing. They are the ones that were never tested against inputs designed to break them. Budget as much time for hostile testing as for building. The building is the easy half.

    Frequently Asked Questions

    How do I build an AI agent in Copilot Studio for the first time?

    Start by writing a tight Instructions prompt that gives the agent one clear job and explicit boundaries, then attach a knowledge source like SharePoint, and connect a single Power Automate flow as a tool. Test it before publishing to a channel like Teams. Keeping the scope narrow on your first build makes it much easier to identify where things go wrong.

    What should I write in the Instructions field when creating a Copilot Studio agent?

    Instead of writing a vague description, define exactly what the agent can and cannot do, which sources it should use, and how it should respond when it does not know the answer. Keeping the instruction set under 500 tokens helps maintain reliability, as longer prompts can reduce consistency.

    When should I turn on general knowledge in Copilot Studio?

    Only enable general knowledge if your agent genuinely needs to draw on information beyond your attached sources. For internal use cases like a policy or FAQ agent, leaving it off produces more trustworthy answers because responses are grounded in your own documents and can be cited.

    Why does my Copilot Studio agent give incomplete answers from PDF files?

    The knowledge indexer in Copilot Studio handles standard PDF and Word files well but struggles with scanned images embedded inside PDFs. If your documents contain scanned pages rather than real text, the agent may only read the portions it can process and skip the rest without flagging it.

    Source: How to build an AI agent: A simple guide for anyone (Microsoft AI Blog).

  • How to Turn HTTP Actions Into a Power Automate Custom Connector

    How to Turn HTTP Actions Into a Power Automate Custom Connector

    I ran into this building something internally: twelve flows, all calling the same internal REST API through the HTTP action, all with the same API key pasted into a header field. The key rotated. Eleven flows broke overnight, and the twelfth broke a week later because nobody remembered it existed. The fix is a Power Automate custom connector. By the end of this walkthrough you will have one connector with connection-level authentication, typed outputs in the dynamic content picker, and zero secrets sitting in flow definitions.

    One thing up front so nobody is surprised: the HTTP action is premium and custom connectors are premium. You are not saving on licensing here. If you want to understand exactly what triggers premium licensing before you ship, How to Run a Power Platform Licensing Audit Before You Ship walks through flagging premium connectors and mapping user licenses. You are saving on secret sprawl, duplicated Parse JSON actions, and the maintenance cost of every flow knowing the raw URL.

    Step 1: Capture the working request

    Before you touch the connector wizard, get one successful call working in a plain HTTP action. You need four things written down: the method, the full URL, every header the API requires, and a real response body. Run the flow once and copy the raw JSON from the run history outputs. Save it somewhere. You will paste it into the connector definition in Step 4, and the quality of your dynamic content depends entirely on how representative this sample is. If a field can be null, make sure your sample shows it populated, or the schema inference will type it wrong.

    Step 2: Create the Power Automate custom connector

    Go to make.powerautomate.com, then Custom connectors under Data, then New custom connector. If you have an OpenAPI file or a Postman collection, import it and skip ahead. For an internal API you probably do not, so pick Create from blank. On the General tab set the scheme to HTTPS, the host to your API domain (api.internal.example.com, no protocol prefix), and the base URL to the shared path segment, for example /v2. Everything you put here is one edit away when the API moves. That is the whole point. The custom connector docs on Microsoft Learn cover the import paths if you go that route.

    Step 3: Move the key into connection-level security

    On the Security tab, choose API Key as the authentication type. Set the parameter label to something a human understands, the parameter name to the exact header the API expects (x-api-key in my case), and the location to Header. This is the step that pays for everything else. The key is now entered once per connection, stored encrypted, and never appears in the flow definition, the export package, or the run history. When the key rotates, you update the connection. Every flow using it picks up the change. Compare that to my eleven broken flows.

    If your API uses OAuth 2.0, the same tab handles it, but you will need an app registration and a redirect URL. API key is the fast path for internal services.

    Step 4: Define the action with Import from sample

    On the Definition tab, click New action. Give it a summary and an operation ID that reads like a verb, because that text is what shows up in the action picker. Then hit Import from sample, set the method and relative path (/invoices/search), and paste the request body you captured in Step 1. Do the same for the response: open the default response, paste your saved JSON, and let it infer the schema.

    This response schema is what kills the Parse JSON actions. Every field in your sample becomes a typed token in dynamic content. Instead of body('HTTP')?['data']?['invoiceNumber'] in a dozen flows, you get invoiceNumber as a pickable token. Untyped payloads always come back to bite you at the consumption end, and that same discipline around schema and parameter definitions applies when you are building tools for AI agents — How to Design Tool Definitions for Copilot Studio Agents covers exactly how typed outputs affect whether an agent selects and uses a tool correctly.

    Step 5: Test the connection and swap the flows

    Use the Test tab. Create a connection, enter the API key, fire the operation, and check the returned status code against what your plain HTTP action produced. Then go through your flows one by one: add the connector action, remap the inputs, repoint downstream references from the old body('HTTP') expressions to the new typed tokens, delete the HTTP action last. Do not delete first. You want the old expression text visible while you remap.

    Since connectors are solution-aware, put the connector inside a solution before you build against it if this ever needs to move environments. Retrofitting that later is painful — understanding how solution layers decide which customization wins makes it much clearer why getting the connector into a solution early avoids hard-to-debug conflicts later.

    The final state and the one pitfall

    End result: one connector, one connection per environment, secrets out of flow definitions, typed outputs everywhere, and a single place to edit when the API changes. The maintenance profile of those twelve flows went from twelve edits to one. In my experience this is the single highest-return refactor available in a flow estate that grew organically.

    The pitfall: custom connector requests have a hard timeout of 2 minutes. A plain HTTP action will happily wait longer with the right retry settings. If your API has a slow endpoint, a report generator, a bulk export, anything that can run past 120 seconds, keep that one call on the HTTP action or redesign it as an async polling pattern. I learned that one the hard way, staring at a 504 that the same request never produced from the raw action.

    Frequently Asked Questions

    What is a Power Automate custom connector and why would I use one?

    A Power Automate custom connector is a reusable wrapper around an external or internal API that lets you call it from flows without hardcoding URLs, headers, or secrets. It centralises authentication and request configuration in one place, so when something like an API key changes, you update it once rather than hunting through every flow that uses the raw HTTP action.

    How do I move an API key out of my flow definitions and into a secure location?

    In a custom connector, you can configure API Key authentication at the connection level on the Security tab. You specify the exact header name the API expects, and the key is entered once when creating a connection, stored encrypted, and never written into the flow definition itself.

    When should I replace HTTP actions in my flows with a custom connector?

    If you have multiple flows calling the same API, sharing the same headers or secrets, or duplicating Parse JSON actions to handle responses, a custom connector is worth building. It reduces secret sprawl, cuts down on repeated configuration, and makes maintenance much easier when API details change.

    How do I get typed outputs and dynamic content when building a custom connector?

    You need to provide a real response body sample from a successful API call, which the connector wizard uses to infer the response schema. The quality of the dynamic content picker depends on how representative that sample is, so make sure any fields that can contain values are populated in the sample rather than null.

  • Inside Solution Layers: How Power Platform Decides What Wins

    Inside Solution Layers: How Power Platform Decides What Wins

    Diagram of stacked Power Platform solution layers with an unmanaged layer sitting on top of managed layers

    Most people assume that importing a managed solution overwrites whatever was there before. It does not. Dataverse keeps every version of every component in a stack, then computes which one you actually see at runtime. That mechanism, Power Platform solution layers, is behind half of the “my update did not show up” tickets I have seen. It is also the thing that quietly decides whether a pro-dev team and a group of citizen devs can work in the same environment without destroying each other’s work.

    The Surface Behaviour: The Update That Never Arrives

    The classic symptom looks like this. A pro-dev team ships version 2.0 of a managed solution with an updated main form on the Account table. The import completes with zero errors. The pipeline is green. And the form in the target environment still shows the old layout.

    The first instinct is to blame caching, then the pipeline, then the solution packager. I burned an afternoon in exactly that rabbit hole before I looked at the layer stack. The real culprit was a maker who had edited that form directly in the target environment three months earlier. That single edit created an unmanaged customization sitting above the managed solution, and it masked every managed update that came afterwards. Version 2.0 landed exactly where it was supposed to. Nobody could see it.

    How Power Platform Solution Layers Resolve What You See

    Every solution-aware component in Dataverse carries an ordered stack. At the bottom sits the system layer, the out-of-box definition Microsoft ships. Above that sit managed layers, one per managed solution that touches the component, ordered by installation sequence. And on top, always, sits the unmanaged layer, which holds any direct customization made in that environment.

    At runtime, Dataverse walks the stack from the top down. For most component types the rule is simple: the topmost layer that defines the component wins entirely. There is no partial blending for a view or a plugin step. Forms and site maps are the notable exceptions, because they merge across layers, which is its own source of surprises.

    You can inspect this yourself. In the maker portal, select a component inside a solution and open Solution layers from the command bar. It shows you the full stack and lets you diff what each layer changed. The official documentation on solution layers covers the merge rules per component type, and it is worth reading properly rather than skimming, because the behaviour is not uniform.

    The Edge Cases That Cost Real Time

    The unmanaged layer never expires. If someone makes a direct edit in production, that layer masks the managed layers below it until someone explicitly removes it with the remove active customizations operation. You can import version 3, version 4, version 5, and nothing visible changes. The imports are not failing. They are landing underneath a mask.

    Layer order is install order, not version number and not intent. If two managed solutions both customize the same view, the one installed second sits higher and wins, even if the first one carries the change your team actually cares about. I have watched teams reorder their deployment sequence to fix a display bug without understanding why it worked, which means the fix was luck, not engineering.

    Form merging deserves its own warning. Because forms merge across layers instead of replacing wholesale, you can end up with a rendered form that no single team designed. A section from the base solution, a tab from a second solution, a field placement from an unmanaged tweak. It looks like corruption. It is the merge algorithm doing exactly what it is documented to do.

    Why This Is the Contract Between Pro Devs and Makers

    The reason I care about this mechanism is not ALM purity. It is that the layer stack is the actual contract that lets pro-dev and low/no-code work coexist. Pro devs ship managed solutions through pipelines and source control. Makers build in a dev environment inside their own solution, which deploys as its own managed layer sitting above the pro-dev layer. Both sides can move independently, and the stack keeps the boundaries honest.

    That contract holds under exactly one condition: no unmanaged edits in test or production. Every direct tweak in a downstream environment is a silent mask over every future deployment. The trade-off is real, and I will not pretend otherwise. Makers lose the ability to hotfix a label in production in thirty seconds. That feels slow until you have spent a day proving that a green import changed nothing, and then it feels cheap. Before you reach that point, running a Power Platform licensing audit across your environments can surface other hidden mismatches that compound the same class of problem.

    I made a similar point about ownership in my post on Dataverse business skills: logic nobody can find is logic nobody can fix. Unmanaged layers in production are the same failure mode wearing a different jacket. In my experience, teams that check the layer stack before blaming the pipeline resolve these tickets in minutes instead of days. The mechanism is not hidden. Most people just never look at it. The same discipline applies when variables behave unexpectedly at scale — as I covered in why variables break when you turn on concurrency in Power Automate, hidden state that looks correct during authoring can silently produce wrong results at runtime for the exact same reason: execution order is not what you assumed.

    Frequently Asked Questions

    What are Power Platform solution layers?

    Power Platform solution layers are an ordered stack that Dataverse maintains for every solution-aware component, starting with Microsoft’s base system layer, followed by managed solution layers, and topped by any unmanaged customizations made directly in the environment. At runtime, Dataverse works down the stack from the top to determine which version of a component is actually displayed or used.

    Why does my managed solution update not show up after importing?

    A direct customization made in the target environment creates an unmanaged layer that sits above all managed layers and takes priority over them. Even if your managed solution imported successfully, that unmanaged layer masks the changes you shipped, making it appear as though the update never arrived.

    How do I see which solution layer is controlling a component in Power Platform?

    In the maker portal, select the component inside a solution and choose Solution layers from the command bar. This shows you the full layer stack for that component and lets you compare what each layer has changed.

    When should I be concerned about unmanaged customizations in a managed environment?

    Any time a maker edits a component directly in an environment that receives managed solutions, an unmanaged layer is created that will permanently override updates shipped through those managed solutions. This is especially important in shared or production environments where pro-dev and citizen dev teams are working alongside each other.

  • Microsoft Previews a Security Agent for Power Pages

    Microsoft Previews a Security Agent for Power Pages

    AI security agent scanning a Power Pages site configuration, illustrating the Power Pages Security Agent preview

    On 29 July 2026, Microsoft announced the Power Pages Security Agent preview, an AI assistant built into the Power Pages experience that can scan a site’s security configuration, diagnose access issues, and walk makers through hardening steps in plain language. It matters because Power Pages security settings are spread across authentication providers, table permissions, web roles, page permissions, site visibility, and WAF settings, and until now nothing sat on top of all of it to tell you what you actually exposed.

    The Power Pages Security Agent Preview Puts Scans, Diagnosis, and Fixes in One Chat

    Concretely, the agent does three things. You can ask it to run a security scan of the site and it inspects the live configuration: which tables are reachable, which table permissions apply, how web roles map to them, whether anonymous access is enabled anywhere it should not be. You can ask it diagnostic questions like why a specific user can see a specific record, and it traces the answer through the actual permission chain instead of you clicking through four different screens to reconstruct it manually. And you can ask it to help harden the site, where it proposes changes to things like authentication settings and access restrictions and explains what each one does before you apply it.

    The important detail is that it reads your real site configuration. This is the same design decision that made the Dataverse plugin for coding agents useful: grounding in the actual environment instead of guessing from training data. A generic chatbot can tell you what table permissions are. This agent can tell you that your Contact table has a Global scope read permission attached to the Anonymous Users web role, on your site, right now.

    Fragmented Settings Are Why Portals Leak, and This Targets the Real Cause

    The model is not the interesting part here. The consolidation is.

    Power Pages sites do not ship with exposed tables because makers are careless. They ship that way because the security surface is fragmented. Authentication lives in one place. Table permissions live in another. Web roles, page permissions, IP restrictions, and site visibility each have their own screen, and none of them gives you a single view of what an anonymous visitor can actually reach. I have watched experienced people get this wrong, because the feedback loop is invisible. You do not find out a table is exposed until someone crafts the right OData URL, and by then it is an incident, not a config review.

    An agent that inspects the whole configuration and surfaces misconfigurations conversationally attacks that fragmentation directly. That is a better fix than another documentation page, because the problem was never that the security documentation is missing. The problem is that applying it requires holding six screens in your head at once. If you are building agents or automations alongside these portals, running a Power Platform licensing audit before you ship is the same class of discipline: catch the configuration gaps before they become incidents.

    Now the honest caveat. This is a preview, and a security tool that gives a wrong answer confidently is worse than no tool at all. If the agent tells you a table is locked down and it is not, you have converted uncertainty into false confidence, which is the most dangerous state a portal can be in. Until this thing has a track record, I would treat every scan result as a guided audit, not a sign-off. Verify what it flags, and verify a sample of what it clears. I have been burned enough times by preview features behaving differently under edge cases to extend that trust slowly.

    Inherited Sites and Anonymous-Access Audits Should Get Scanned First

    Where this fits: the first candidates are inherited sites. Every enterprise has at least one portal built three years ago by someone who has since left, where nobody currently on the team can explain the web role setup. Pointing the agent at that site and asking what an anonymous user can access is worth doing on day one of the preview reaching your tenant. Not because the agent is infallible, but because the alternative is that nobody audits it at all.

    The second candidate is any site with anonymous access enabled on purpose. Public-facing portals with self-registration are exactly where a Global scope permission accidentally attached to the wrong role does the most damage. A conversational audit lowers the cost of checking from an afternoon to ten minutes, and things that cost ten minutes actually get done.

    Who benefits most is the maker in the middle: someone comfortable building the portal but not deep enough in the security model to trace a permission chain by hand. Pro devs who already know where every setting lives will use it as a faster lookup. Citizen devs building portals without understanding table permissions were the risk this feature exists to reduce. The broader pattern here connects to something worth keeping in mind: the model is the cheapest part of every enterprise AI agent, and this feature is a good example of that — the value is in the grounding and the consolidation, not the underlying AI capability itself.

    Security tooling for low/no-code platforms is finally starting to assume the builder is not a security engineer, and that assumption is overdue.

    Source: Announcing the Power Pages Security Agent (Preview): Your AI Partner for Site Security (Microsoft Power Platform Blog).

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • Microsoft Ships the Dataverse Plugin to OpenAI’s Codex Marketplace

    Microsoft Ships the Dataverse Plugin to OpenAI’s Codex Marketplace

    Dataverse plugin Codex marketplace expansion showing a coding agent querying live schema

    On 28 July 2026, Microsoft shipped the Dataverse plugin for coding agents to the OpenAI and Codex marketplaces. The announcement is short, but the Dataverse plugin Codex marketplace expansion means any agent built on OpenAI’s coding stack can now query live Dataverse schema, table metadata, and real data instead of guessing column names from two-year-old tutorial content in its training set.

    I wrote about the Cursor marketplace drop when it happened. That felt like a test balloon. This is the follow-through, and it tells you something about where Microsoft thinks the moat actually sits.

    What a Codex Agent Gets: Live Schema, Metadata, and Query Tools

    The plugin gives a Codex-based agent the same tool surface the Copilot and Cursor versions get. It can list tables in a connected environment, inspect column logical names, walk relationships, read option set values, and run queries against real records. That sounds mundane until you have watched a coding agent confidently generate a plugin against new_customer_id when the actual column is cr7a2_customerid. Without live metadata, the output looks correct and fails on deploy. With it, the code is diffable against reality.

    The hallucination problem I described when the plugin first shipped was never a model quality problem. It was a missing context layer at build time. Codex agents had no sanctioned way to see your schema, so they interpolated from public tutorials. This closes that gap for anyone whose org standardized on OpenAI’s tooling.

    The Codex Marketplace Expansion Signals Dataverse Is the Moat

    Think about what Microsoft is doing here. They are distributing a first-party grounding tool into a direct competitor’s agent ecosystem. GitHub Copilot competes with Codex. Microsoft shipped there anyway.

    That only makes sense if you believe the coding assistant is interchangeable and the data platform is not. Microsoft is betting that developers will switch agents every eighteen months but their organisations will keep business data in Dataverse for a decade. Agent-neutral distribution is the correct call under that assumption. Cursor was proof of concept. OpenAI and Codex confirm the pattern: follow the developers, do not try to pull them back into VS Code.

    There is a quieter governance win too. Developers were already wiring community MCP servers from random GitHub repos into their agents, and platform teams had zero visibility into any of it. A first-party plugin installed from a known marketplace leaves an auditable trail. That matters more inside a large enterprise than any individual feature. If you want to understand the protocol underneath tools like this, How MCP Actually Works Under the Hood When an Agent Calls a Tool walks through the JSON-RPC handshake and capability negotiation in detail.

    Pro-Code Teams on Non-Microsoft Agents Are the Real Audience

    This is not a citizen dev feature. The audience is teams writing Dataverse plugins, custom APIs, PCF controls, and complex flows in source control, whose org happened to standardize on OpenAI’s agent stack instead of GitHub Copilot. Those teams were previously stuck choosing between an ungrounded agent or an unsanctioned community tool. Now they get the first-party path without changing editors.

    Two honest caveats. First, the setup mistake I keep seeing has not gone away: people connect the plugin with System Administrator credentials pointed at production. The sane configuration is still a dedicated app user with a least-privilege role scoped to a dev environment. The marketplace install being one click makes the lazy setup faster too.

    Second, this closes the hallucination gap and nothing else. Environment permissions, DLP policies, and security roles behave exactly as they did before. The plugin does not grant the agent any access your app user does not have, and it does not stop you from misconfiguring that app user. In my experience, the teams that get burned are the ones who treat schema grounding as a security boundary. It is not. It is a correctness tool. Schema grounding also sits inside a broader cost and measurement story — The Model Is the Cheapest Part of Every Enterprise AI Agent makes the case that grounding data and connector governance are where the real budget and hours go.

    If your team builds against Dataverse from Codex today, install this and you get real hallucination reduction on schema-dependent code. If your governance story is not sorted, you also get one more thing to register and scope. Both are true.

    The coding agents will keep changing names. The platforms that ship their grounding everywhere are the ones planning to still be here when they do.

    Source: Dataverse Plugin for Coding Agents: OpenAI and Codex Marketplace Expansion (Microsoft Power Platform Blog).

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • Stop Copilot Studio Generative Answers From Hijacking Your Topics

    Stop Copilot Studio Generative Answers From Hijacking Your Topics

    Copilot Studio settings screen showing generative answers overriding a topic with a weak description

    I keep seeing the same complaint in the community: someone builds a solid topic in Copilot Studio, with an adaptive card, a Power Automate action, exact wording that legal signed off on. It works for weeks. Then generative orchestration gets switched on and suddenly Copilot Studio generative answers take over. The agent paraphrases a SharePoint document instead of running the topic. Same question, wrong path.

    The usual reaction is to pile on more trigger phrases. That does nothing. Under generative orchestration, trigger phrases are not how routing works anymore.

    The problem with generative answers stealing topic-based answers

    With classic orchestration, topics fire on trigger phrase matching. With generative orchestration, the model picks between your topics, your tools, and your knowledge sources by scoring their descriptions against the user’s message. Trigger phrases become a weak secondary signal at best.

    Most topics I look at have no description, or an auto-generated one like “This topic handles expense questions.” That is a losing hand. Your knowledge source is a 40-page policy PDF full of relevant vocabulary. The orchestrator scores “how do I get reimbursed for a client dinner” against that PDF and against your one-line description, and the PDF wins. Generative answers fire, your scripted topic sits idle, and the user gets a paraphrase instead of the exact approved flow.

    It is the same silent misrouting failure mode I wrote about with multi-agent orchestration routing. Nothing errors. Nothing logs a warning. The agent just confidently takes the wrong path.

    The fix

    Write the topic description as a retrieval hint, not documentation. Open the topic, click Details in the top bar, and fill the Description field. The orchestrator reads this field to decide routing, so it needs to contain the words users actually type.

    Weak version:

    Handles expense-related questions.

    Version that wins routing:

    Use this topic for any question about submitting expense reports, reimbursement, expense limits, receipts, client dinners, travel costs, or mileage claims. Always use this topic instead of searching documents when the user asks how to claim or submit an expense.

    Two things matter here. First, the vocabulary overlap: name the concrete nouns users will type, because the scoring is lexical-ish relevance, not comprehension. Second, the explicit priority instruction at the end. “Always use this topic instead of searching documents” is blunt, and blunt works. Microsoft documents this behavior in the generative orchestration docs, but the priority-instruction trick is the part most people miss.

    If you want to understand exactly how the orchestrator scores and selects between topics and tools, How Copilot Studio Agent Tool Selection Actually Works Under the Hood walks through the scoring pass in detail and explains why descriptions carry so much weight.

    One trade-off to be honest about. A description that broad will pull in some borderline questions that generative answers would have handled fine. For compliance-sensitive flows, that is the trade you want. Exact approved wording beats a fluent paraphrase every time. Before you ship any of this, it is also worth running a Power Platform licensing audit to confirm the connectors and flows your topic triggers are covered under the right licenses for every user who will hit this path.

    Test it with five phrasings you did not use in the description. If the topic fires on all five, you are done. If not, add the missing nouns and retest. In my experience this takes ten minutes and fixes ninety percent of “my topic stopped working” reports.

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • How to Run a Power Platform Licensing Audit Before You Ship

    How to Run a Power Platform Licensing Audit Before You Ship

    Checklist and connector diagram representing a power platform licensing audit before solution rollout

    A working app in your dev environment tells you nothing about what it costs to run for 300 people. I have watched a solution sail through UAT and then stall at rollout because one flow used an HTTP action, which flipped the whole thing premium, and suddenly every user needed a license nobody had budgeted. A structured power platform licensing audit takes an afternoon and catches this before procurement finds out the hard way. By the end of this walkthrough you will have a one-page map of every connector, every flow context, and every license gap in your solution.

    Step 1: Inventory Every Connector in the Solution

    Open the solution in make.powerapps.com, then go through each app under Details and check the connections list. Premium connectors carry the diamond Premium tag. SharePoint, Outlook, and Teams are standard. SQL Server, Dataverse, HTTP, and every custom connector are premium. I wrote a full walkthrough on building custom connectors, and the licensing footnote there matters: they are always premium, even when they wrap a free public API.

    Do not stop at the app level. Open every flow in the solution and read the actions, because the HTTP action never appears in the app’s connection list. Search the flow definitions for shared_http if you want to be thorough. This is where most surprises hide.

    Step 2: Trace the Context of Every Flow

    Licensing for flows depends on how they run, not what they do. A flow with a Power Apps (V2) trigger, packaged in the same solution as the app that calls it, runs in the context of that app and is covered by the app user’s Power Apps license. A scheduled or automated flow that runs standalone is not covered by anything. It needs Power Automate Premium on the owner, or a Process license attached to the flow itself.

    While you are here, check who owns each standalone flow. A flow running on the personal license of someone who leaves the organisation gets suspended when that license is removed. Move business-critical standalone flows to a service account or a Process license now, not after the first silent outage. If your flows rely on desktop automation, the selector strategy you choose also affects maintenance overhead — Selectors vs Image Recognition for Power Automate Desktop Flows covers the tradeoffs in detail.

    Step 3: Map Real Users to Real Licenses

    Pull the actual license assignments from the Microsoft 365 admin center, or with Get-MgUserLicenseDetail in PowerShell. Do not assume everyone has the same SKU. Mixed tenants are the norm, and the F3 users in the warehouse do not have what the E5 users in finance have.

    Then do the arithmetic. Per-app runs 5 dollars per user per app per month, Power Apps Premium runs 20 per user per month. The break-even sits at four apps per user. If your solution is app number one for a group of frontline workers, per-app wins. If the same 50 people will end up using five internal apps within a year, per-user is cheaper and you should say so before someone locks in the wrong plan. The Microsoft licensing overview has the current SKU details.

    Step 4: Check API Request Limits and Dataverse Capacity

    Licenses carry daily Power Platform request entitlements, and they are not generous at the low end. A Power Apps Premium user gets 40,000 requests per 24 hours. A user running on a seeded Microsoft 365 license gets 6,000. A flow that loops over 2,000 SharePoint items with three actions per item burns 6,000 requests in one run. The request limits documentation lists the allocations per SKU. Check your heaviest flow against the lowest entitlement in your user base.

    Dataverse capacity is the other quiet cost. If your solution logs every run or every submission into a Dataverse table, estimate table growth per month against your tenant’s storage allocation. Capacity overages show up on someone else’s budget line, which means they show up as an angry email. If you are also planning to add AI features to those Dataverse tables, the new Prompt Columns in Dataverse column type adds storage considerations of its own that are worth factoring in early.

    Step 5: Test With a Standard-Licensed Account

    Your dev account masks everything. It almost certainly has per-user premium plus an E5, so every connector works and every flow runs. Create a test user with exactly the license mix your real end users have, share the app with it, and run every screen and every flow path. If there is a gap, this account hits the premium license prompt immediately, and you fix it before rollout instead of during it. In my experience, this single step catches more licensing problems than the previous four combined, because it tests the actual runtime entitlement chain instead of your reading of the documentation.

    The Final State

    You now have a connector inventory with premium flags, a flow list with run contexts and owners, a user-to-license map with the per-app versus per-user math done, and a request limit sanity check. That one page is the difference between a rollout and a procurement escalation.

    The pitfall to watch: child flows. A standard-looking parent flow that calls a child flow containing one HTTP action inherits the premium requirement, and nothing in the app’s connection list will tell you. Open every child flow. Read every action. It takes ten minutes and it is the ten minutes people skip.

    Frequently Asked Questions

    How do I run a Power Platform licensing audit before deploying a solution?

    Start by inventorying every connector in your solution and flagging anything premium, such as SQL Server, Dataverse, HTTP, or custom connectors. Then trace how each flow runs, since standalone flows need separate licensing while flows triggered by a Power Apps canvas app can be covered by the user’s Power Apps license. Finally, pull real license assignments from the Microsoft 365 admin center to confirm every user has the right SKU before rollout.

    What is the difference between a standard and a premium connector in Power Platform?

    Standard connectors like SharePoint, Outlook, and Teams are included with most Power Platform licenses at no extra cost. Premium connectors, which include SQL Server, Dataverse, HTTP, and all custom connectors, require users to hold a Power Apps or Power Automate Premium license to use them.

    Why does a single HTTP action in a flow affect licensing for all my users?

    The HTTP action is a premium connector, so any flow that includes it requires the users who interact with it to hold a premium license. Because this action does not show up in an app’s connection list, it is easy to miss during a review and can trigger unexpected licensing costs at the point of deployment.

    When should I check who owns standalone flows in my Power Automate solution?

    You should verify flow ownership before any production rollout, not after an incident occurs. If a standalone flow runs on a personal license and that person leaves the organisation, the flow will be suspended when their license is removed, causing silent failures in business processes.

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • The Model Is the Cheapest Part of Every Enterprise AI Agent

    The Model Is the Cheapest Part of Every Enterprise AI Agent

    Cost breakdown diagram showing the model as the smallest layer in enterprise AI agents, beneath data grounding, governance, and measurement

    Every agent conversation I get pulled into starts with the same debate. Opus 5 or GPT. Copilot Studio’s default model or bring-your-own. Someone has a benchmark chart open before anyone has asked what the agent is supposed to do. After more than a year of building enterprise AI agents internally, I am convinced this is the least consequential decision in the entire project. Swapping the model has never taken me more than an afternoon. The data plumbing, the connector policy sprawl, the tool selection behavior, and figuring out whether the thing produces useful work per dollar have each eaten weeks. This post is my map of where the real cost centers sit, and it links out to everything I have written on each layer, so treat it as the index.

    Every Enterprise AI Agent Kickoff Starts With the Wrong Debate

    Model differences are real. I wrote about why Opus 5’s long-horizon task completion numbers matter more than coding benchmarks, and Anthropic shipping verticalized agents like Claude Finance tells you the frontier labs know where the value sits. But here is the asymmetry nobody prices in: the model is the one component you can replace without touching anything else. Copilot Studio lets you change it in a dropdown. A custom orchestration layer changes it in one config line. Meanwhile your Dataverse schema grounding, your DLP policies, your tool descriptions, and your measurement pipeline are all bespoke work that survives every model swap and cannot be bought off a pricing page.

    So when a kickoff burns two hours on model selection, I now say the same thing every time. Budget this project like 10 percent model and 90 percent platform. Every agent I have seen die in month two died in the 90 percent.

    Grounding Data Is Where the Real Engineering Hours Go

    The hardest part of an internal agent is not intelligence. It is getting the agent to behave like someone who actually works at your organisation. Org policies, naming conventions, tribal knowledge, the exception the finance team makes every quarter-end. None of that is in any model’s training data.

    The naive fix is stuffing everything into the system prompt. I learned the hard way that prompts past a few hundred tokens start degrading reliability, and a focused 400-token instruction set beats a 4000-token one every time. That is why I consider business skills in Dataverse an architectural shift rather than a feature: policy moves out of the prompt into a managed record with an owner and a version history. If you want persistent AI output that stays queryable alongside that structured data, Prompt Columns in Dataverse are worth understanding as a companion pattern — you define the prompt once and the result lives as a column rather than a one-off generation.

    Same logic applies to schema. An agent that does not know your column logical names burns tokens guessing, which is why the Dataverse MCP server’s metadata inspection tools matter, and why grounding coding agents in live environment metadata is the only reliable fix for hallucinated column names. If you want to understand what is actually happening on the wire when an agent calls one of these tools, I broke down how MCP works under the hood. It is a stateful JSON-RPC protocol, not a REST connector, and treating it like one breaks in production.

    Knowledge sources carry the same trap at a different layer. Wire the same SharePoint site into four agents four different ways and you get silent misrouting nobody can diagnose. I covered the governance side in my post on knowledge sources and agent feedback loops. None of this work goes away when you change models. All of it decides whether the agent is trustworthy.

    Connector Policies and Tool Selection Decide What Your Agent Can Actually Do

    The second cost center is everything between the agent and the systems it touches. I hit this building a GitHub integration: the connector sat in the Business data group in Dev and the Blocked group in Prod, so an agent that passed UAT would not even load its connection at go-live. The full story is in my post on enterprise environment sprawl, and the lesson generalises. The connector is never the problem. The environment strategy around it is.

    Then there is tool selection, which most teams treat as magic. It is not. In Copilot Studio, the orchestrator scores tool names, descriptions, parameter names, and enum values against the current turn. It is a retrieval problem, not a dispatch problem, and I walked through the mechanics in how Copilot Studio agent tool selection actually works. A vague operation summary like GetData on a custom connector is not lazy metadata. It is a bad prompt that makes the agent pick the wrong action.

    This is also why I push back on premature multi-agent architectures. A model that hits 95 percent tool selection accuracy with two connectors can drop to 70 percent with five, because descriptions start competing with each other. Multi-agent is a tax you pay when a single agent can no longer do the job, not an upgrade, and orchestration routing just moves the misrouting failure one layer deeper where it is harder to debug.

    If You Cannot Measure Useful Work Per Dollar, You Built a Demo

    The last cost center is the one almost everyone skips. If you cannot define what counts as useful work for your agent in one sentence, it does not have a clear enough job to be worth scaling. I documented my full approach in measuring useful work per dollar for AI agents: a single boolean per invocation, sourced from downstream behavioral signals like ticket reopens rather than thumbs-up ratings, divided into a cost stack of model tokens plus per-message consumption plus premium connector actions.

    Measurement is also your early warning system. Agents that sailed through UAT fail in production because test conversations are too clean, and the input distribution shifts the moment real users show up with messy phrasing. A workflow that completes 70 percent of the time is not a workflow, it is a demo, because the human check-in that makes it reliable eliminates the time savings it was supposed to create. Without a useful-work metric you do not find that out until someone quietly stops using the agent.

    The encouraging part: this layer is finally getting platform support. Feedback stored as queryable Dataverse rows, closed-loop learning through the Power Apps MCP server, and certified MCPs giving platform teams a trust-signal list instead of shadow adoption from random repos. The tooling is catching up to the problem.

    So here is the payoff. Next time an agent project kicks off, do not open with the model comparison. Open with four questions. Where does the org knowledge live and who owns it. Which connectors and policies apply in the environment where this will actually run. How many tools before selection accuracy degrades. And what single boolean defines useful work. In my experience, the teams that answer those four before touching a model dropdown ship agents that survive month three. The teams that start with the benchmark chart ship demos.

    Frequently Asked Questions

    What is the most expensive part of building enterprise AI agents?

    The biggest costs in enterprise AI agents are not the model itself but the surrounding layers: data grounding, governance policies, tool configuration, and measurement pipelines. These are bespoke to your organisation and cannot be swapped out the way a model can, which is why they consume the most engineering time and budget.

    How do I choose the right AI model for an enterprise agent?

    Model selection matters far less than most teams assume, since modern platforms let you swap models with minimal effort. A better approach is to spend the majority of your planning budget on data grounding, connector policies, and measurement before you finalise any model choice.

    Why does my enterprise AI agent give unreliable answers despite a strong model?

    Unreliable outputs are usually a grounding problem, not a model problem. If the agent lacks access to your organisation’s policies, naming conventions, and internal context, even a frontier model will produce generic or incorrect responses. Moving that knowledge out of long system prompts and into structured, versioned records tends to improve consistency.

    When should I move AI policy instructions out of the system prompt?

    Once your system prompt grows beyond a few hundred tokens, reliability starts to drop and maintenance becomes difficult. Migrating policy instructions into a managed data layer gives each rule a clear owner and version history, and it keeps the prompt focused on behaviour rather than organisational context.

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • Prompt Columns Reach General Availability as a Dataverse Column Type

    Prompt Columns Reach General Availability as a Dataverse Column Type

    Dataverse table showing prompt columns general availability with AI-generated values persisted per row

    On 29 July 2026, Microsoft announced the general availability of Prompt Columns in Dataverse. You define a natural language prompt once on a table, and AI-generated classifications, summaries, and recommendations are computed and persisted as regular column values on every row. The insight stops being a read-time answer and becomes stored data: filterable in views, aggregable in Power BI, and triggerable in flows, with no code and no custom plumbing.

    Prompt Columns Make AI Output a Persisted Dataverse Value, Not a Read-Time Answer

    The mechanics are simple. On any Dataverse table you add a prompt column, write a natural language instruction that references other columns on the row, and Dataverse computes the result and stores it. Classify this ticket by urgency based on the description field. Summarize this feedback in one sentence. Recommend a next action based on status and history. The output lands in the column like any value a human would have typed.

    I built this exact pattern by hand last year for an internal triage table. Flow triggers on row create, calls an AI Builder custom prompt, patches the result back into a text column, handles retries when the prompt action throttles, and logs failures somewhere nobody checks. It worked. It was also four moving parts to maintain for what is conceptually one thing: a computed field whose formula happens to be a prompt. Prompt Columns deletes that entire plumbing layer. Poof.

    Storing the Insight Beats Regenerating It, With Two Caveats

    Persistence is the whole story here, and I think it is the part most coverage will skip past. Nearly every AI-in-apps pattern generates insights on demand, at read time. That has two costs people underestimate. Every consumer pays inference cost for the same question, and every consumer can get a slightly different answer. A stored value flips both. The inference runs once, then a view can sort by it, a flow can trigger on it, a Power BI report can aggregate it across a million rows without a single additional model call. I wrote before about how the data path behind the model is often the real bottleneck, and this is the same principle from the other direction: put the AI output where the data already lives.

    Two caveats before anyone switches this on across a production table. First, refresh semantics. If the description field changes after the classification was computed, when does the column recompute? A persisted AI value can go stale in a way a read-time answer never does, and you need to know the recompute triggers before you build a queue that sorts on it. Second, cost per row. One prompt execution per row sounds cheap until you enable it on a table with two million existing rows and think about backfill. Model the credit consumption before GA enthusiasm meets your capacity report. If you are already thinking about how to measure that spend against the work it produces, How to Measure Useful Work Per Dollar for Your Power Platform AI Agents is a useful starting point.

    There is a third thing that is less caveat and more governance homework. AI-generated text now sits in a column that looks exactly like human-entered data. Nothing in a view distinguishes the two. If a downstream flow or a report treats that column as ground truth, you have quietly promoted a model output to a system of record. That is fine if it is a deliberate decision with a named owner. It is not fine as an accident.

    Triage Queues and Classification Views Are the First Places This Pays Off

    The obvious first wins are the boring ones, which is a compliment. Triage queues where incoming requests get an AI-assigned category and priority, and the queue view sorts by the AI column. Summary columns on long description fields so a service agent scans a readable sentence instead of opening every record. Sentiment on feedback rows, with a flow triggering on the negative ones and routing them to an owner. Every one of these was possible before with the flow-plus-prompt pattern. Now they are a column definition, which puts them in reach of makers who were never going to build the plumbing version.

    The trade-off is worth naming. If you need per-user, per-context answers, or the insight depends on data outside the row, this is the wrong tool and read-time generation with an agent is still the right shape. That boundary also comes up when you are deciding where to store knowledge in the first place — SharePoint vs Dataverse as a Copilot Studio Knowledge Source covers how the two stores differ in ceiling, governance, and latency. In my experience, the honest split is: persist what is a property of the record, generate on demand what is a property of the question.

    AI output stored as first-class, queryable data is where this whole space is heading, and a column type is exactly the right place for it to land.

    Source: Prompt Columns in GA: Turning Business Apps Data into Persisted AI Insights (Microsoft Power Platform Blog).

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn

  • Dataverse Plugin for Coding Agents Now Available on OpenAI and Codex Marketplaces

    Dataverse Plugin for Coding Agents Now Available on OpenAI and Codex Marketplaces

    Dataverse plugin OpenAI Codex marketplace expansion for coding agents

    Microsoft shipped the Dataverse plugin for coding agents to OpenAI and Codex marketplaces on July 28, 2026. Same plugin story we saw hit Cursor a few weeks back. The dataverse plugin openai codex marketplace expansion is the interesting signal here, not the individual drop.

    If you write Dataverse code with a coding agent, the excuse for hallucinated table and column names is gone. I want to wire this into a real internal repo this week.

    What actually shipped

    The Dataverse plugin is now installable directly from the OpenAI and Codex marketplaces. Single-click install, same as the Cursor drop earlier this month. The plugin itself is unchanged in behavior. It grounds the coding agent in live environment metadata so the model queries your actual column logical names like cr123_customerid instead of guessing based on tutorial data from training.

    Setup story is also unchanged. You point the plugin at a Dataverse environment through an app user with a scoped security role. Not System Administrator. Not production. A dedicated app user in a dev environment with least privilege. Same rule I have been repeating since the first drop.

    What is new is the reach. The plugin now lives inside three of the coding agent surfaces where pro devs actually work. Cursor, OpenAI, and Codex. That covers a real slice of the market I see on LinkedIn when people share their editor screenshots.

    Why this expansion matters more than the Cursor drop did

    The Cursor drop was the proof of concept. It showed Microsoft was willing to follow developers out of VS Code and the maker studio into competing tools. Fine. Interesting signal.

    This expansion is the follow-through. And follow-through is what tells you whether a strategy is real or a one-off gesture.

    Three marketplaces in a few weeks means Microsoft is treating the coding agent surface as a distribution channel, not a partnership. That changes the math for platform teams. When developers install Dataverse tooling from a first-party plugin in a known marketplace, you have an auditable trail. When they pull an MCP server from a random GitHub repo, you have nothing. Marketplace distribution is a governance win before it is a productivity win. The Dataverse July 2026 update actually spells out exactly where Microsoft is taking this with certified partner MCPs and enterprise MCP governance, which is worth reading alongside this drop.

    The second thing this signals is that the pro-code path into Dataverse is now considered permanent strategy. Not a side project. Not a preview experiment. Microsoft is investing in meeting devs where they already work, and that pulls the low/no-code and pro-code stories closer together than they have been in years.

    The third thing, and the one I care about most, is that hallucinated schema is officially not an acceptable failure mode anymore. If you have a coding agent generating Dataverse code and it is still inventing column names, that is a tooling choice now, not a limitation. The grounding layer exists in the tools you already use.

    What I would wire up this week

    I have a plugin project sitting in a dev environment that I want to point this at. Here is the plan.

    First, spin up a dedicated app user in the dev environment with a scoped security role. Read on the tables the plugin project actually touches. Nothing more. This is the part most people skip and regret later when the audit conversation starts.

    Second, install the plugin from the OpenAI marketplace into my coding agent. Point it at the dev environment. Verify it can read metadata. Confirm it cannot see production.

    Third, take an existing plugin file with real custom table references and ask the agent to extend it. The test is not whether the code compiles. The test is whether the generated code uses the actual logical names from my environment or hallucinates something plausible. If it grounds correctly, this becomes part of my normal flow. If it drifts, I want to know exactly where. The failure modes I am watching for here are the same ones I covered in Why Do AI Agents Fail in Production When They Worked Fine in Testing, and schema drift is near the top of that list.

    Fourth, run the same prompt against a Codex install to see if there is any behavior difference across the two marketplaces. My guess is no. The plugin is the same. But I want to confirm.

    The bigger question I am sitting with is what happens when every coding agent has grounded access to your Dataverse schema. The Power Platform pro-dev story has been fragmented for years. If the plugin holds up across three marketplaces, that fragmentation starts to close.

    I will report back on what breaks.

    Source: Dataverse Plugin for Coding Agents: OpenAI and Codex Marketplace Expansion (Microsoft Power Platform Blog).

    About the author: Halilcan Soran is a Senior Business Analyst at Visa working on process optimization with Power Platform, RPA, and agentic AI. He previously led a 15-person team at Thomson Reuters, where the Power Automate solutions he built started his automation career. More about Halilcan · LinkedIn