<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://adamstephensen.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://adamstephensen.com/" rel="alternate" type="text/html" /><updated>2026-04-18T13:09:33+00:00</updated><id>http://adamstephensen.com/feed.xml</id><title type="html">Adam Stephensen</title><subtitle>Hi. I&apos;m Adam. I love to build things, paddle kayaks and look at the stars.</subtitle><entry><title type="html">Is the Microsoft IQ Layer just another layer?</title><link href="http://adamstephensen.com/2026/04/18/positioning-the-iq-layer/" rel="alternate" type="text/html" title="Is the Microsoft IQ Layer just another layer?" /><published>2026-04-18T00:00:00+00:00</published><updated>2026-04-18T00:00:00+00:00</updated><id>http://adamstephensen.com/2026/04/18/Positioning-the-IQ-layer</id><content type="html" xml:base="http://adamstephensen.com/2026/04/18/positioning-the-iq-layer/"><![CDATA[<h2 id="microsoft-ai-ecosystem-rethinking-the-diagram-after-ignite">Microsoft AI Ecosystem: Rethinking the Diagram After Ignite</h2>

<p>After Build 2025—and the flood of announcements across Copilot, Copilot Studio, Foundry, and Fabric—I found myself stepping back and trying to make sense of what was actually happening.</p>

<p>What struck me was that we were moving beyond the days of picking a single tool and trying to use it for everything. Instead, we were starting to see a more mature ecosystem emerge—one where you could choose the right tool for the job, and more importantly, start connecting them together.</p>

<p>With emerging protocols like MCP and A2A, it felt like these previously separate parts of the Microsoft AI ecosystem were beginning to integrate into something more cohesive.</p>

<p>A high-level map started to form in my head.</p>

<p>And I managed to get down what I thought was a pretty solid representation of the Microsoft AI ecosystem.</p>

<p><img src="/assets/images/2026-04/MS-AI-Ecosystem.png" alt="The Microsoft AI Ecosystem - Build 2025" /></p>

<p>At the time, the model made sense:</p>

<ul>
  <li>Experiences at the top</li>
  <li>Agents emerging as a new application layer</li>
  <li>Data and integration underneath</li>
  <li>Platform capabilities powering everything</li>
</ul>

<p>It reflected what we were building.</p>

<hr />

<h2 id="then-ignite-happened">Then Ignite happened</h2>

<p>And with it, something that I think is genuinely significant:</p>

<p><strong>The introduction of the “IQ Layer”</strong></p>

<ul>
  <li>Work IQ</li>
  <li>Fabric IQ</li>
  <li>Foundry IQ</li>
</ul>

<p>Microsoft is formalising something many of us have been feeling for a while:</p>

<blockquote>
  <p>Intelligence is becoming a <em>first-class architectural concept</em>.</p>
</blockquote>

<p>A set of <strong>cross-cutting intelligence capabilities</strong> that span:</p>

<ul>
  <li><strong>Human context</strong> (Work IQ) — people, meetings, emails, conversations</li>
  <li><strong>Data context</strong> (Fabric IQ) — structured, semantic, and real-time enterprise data</li>
  <li><strong>Execution intelligence</strong> (Foundry IQ) — models, tools, memory, and orchestration</li>
</ul>

<hr />

<h2 id="so-now-im-rethinking-the-diagram">So now I’m rethinking the diagram</h2>

<p>The question I’ve been wrestling with is this:</p>

<p><strong>Where does the IQ layer actually sit?</strong></p>

<p>Is it:</p>

<h3 id="option-1--a-layer-in-the-stack">Option 1 — A layer in the stack?</h3>

<p>Something that sits between data and agents?</p>

<p><img src="/assets/images/2026-04/MS-EI-Architecture.png" alt="The Microsoft Enterprise Ecosystem - Ignite 2025" /></p>

<p>This is intuitive, clean and familiar… using layers as we have done for many years.</p>

<p>It makes sense when calling out all the components in a smaller piece of architecture.</p>

<p>But… it also undersells what IQ is trying to be.</p>

<p>It makes intelligence look like just another capability in the stack.</p>

<hr />

<h3 id="option-2--a-cross-cutting-layer-over-the-entire-microsoft-cloud">Option 2 — A cross-cutting layer over the entire Microsoft Cloud?</h3>

<p>Something that <em>wraps</em> the ecosystem?
<img src="/assets/images/2026-04/MS-EI-Ecosystem.png" alt="The Microsoft Enterprise Ecosystem - Ignite 2025" /></p>

<p>This feels closer to the intent.</p>

<p>It positions the IQ layer as the thing that turns all the other layers into something smarter.</p>

<p>It reflects:</p>

<ul>
  <li>Agents are becoming orchestrators, not the intelligence itself</li>
  <li>Data platforms are becoming semantic, not just storage</li>
  <li>Applications are becoming entry points into intelligence, not logic containers</li>
</ul>

<hr />

<h2 id="why-this-matters">Why this matters</h2>

<p>How this is represented shapes how people think about how their solutions hang together.</p>

<p>If IQ is “just another layer”, you’ll build differently<br />
than if IQ is “the thing that powers everything”.</p>

<hr />

<h2 id="my-current-leaning">My current leaning</h2>

<p>Right now, for the workshop I’m running this week… I’m using both.</p>

<ul>
  <li>The IQ layer at the top to introduce the concepts and focus on the new capabilities</li>
  <li>IQ Layer sitting over integration and knowledge when I start looking at subsets of the ecosystem as they ralate in individual projects and more directly in application architecture diagrams.</li>
</ul>

<hr />

<p>I’m keen for feedback (the reason for this post):</p>

<p><strong>How are you thinking about the IQ layer?</strong><br />
<strong>Where would you place it in the architecture?</strong><br />
<strong>What have I missed that should be included ?</strong></p>]]></content><author><name></name></author><category term="Azure" /><category term="AI" /><summary type="html"><![CDATA[Microsoft AI Ecosystem: Rethinking the Diagram After Ignite]]></summary></entry><entry><title type="html">DevGovOps: Building Trust in AI</title><link href="http://adamstephensen.com/2026/04/14/devgovops-trusted-ai-at-scale/" rel="alternate" type="text/html" title="DevGovOps: Building Trust in AI" /><published>2026-04-14T00:00:00+00:00</published><updated>2026-04-14T00:00:00+00:00</updated><id>http://adamstephensen.com/2026/04/14/DevGovOps</id><content type="html" xml:base="http://adamstephensen.com/2026/04/14/devgovops-trusted-ai-at-scale/"><![CDATA[<h1 id="devgovops-governance-belongs-in-the-loop">DevGovOps: Governance Belongs in the Loop</h1>

<p>Let me start with a pattern I keep running into.</p>

<p>You’re deep into delivery — maybe building an AI system, maybe scaling one — and the team is moving well. Then, right before you’re ready to ship, the <strong>governance checkpoint</strong> arrives. A compliance review. A risk board. A stack of late-stage concerns that nobody surfaced earlier because nobody was in the room earlier.</p>

<p>Progress stalls. Trust between builders and gatekeepers frays. Timelines slip.</p>

<p>And here’s the thing: this isn’t a one-off.</p>

<p>The problem isn’t that governance people are difficult, and it isn’t that delivery teams don’t care about risk.</p>

<p>It’s that <strong>governance is still treated as a gate</strong> — something that lives outside the flow of work, applied after the fact, rather than woven into how we build and operate systems from the start.</p>

<hr />

<p><img src="/assets/images/posts/2026-04-14-DevGovOps-01.png" alt="Noosa beach" class="img-responsive" /></p>

<h2 id="weve-seen-this-movie-before">We’ve seen this movie before</h2>

<p>The lineage matters here, because it shows we already know how to solve this kind of problem.</p>

<p><strong>DevOps</strong> emerged because dev and operations/infra teams were at war. Devs threw code over the wall; ops threw it back. The fix was continuous delivery and shared ownership of the entire lifecycle. The outcome was faster, more reliable software.</p>

<p><strong>DevSecOps</strong> emerged because security kept arriving too late. Teams would build for months and then hit a penetration test or security review that blew up their timeline. The fix was shifting security left — embedding it into the pipeline, making it part of everyday delivery. The outcome was safer software without killing velocity.</p>

<p>In both cases, the pattern was the same:</p>

<blockquote>
  <p>A critical concern that was being treated as an external checkpoint got pulled into the continuous flow of delivery.</p>
</blockquote>

<p>And in both cases, people worried it would slow teams down. In practice, the opposite happened. Automation and shared ownership reduced late-stage surprises — and accelerated delivery.</p>

<p>Now look at governance.</p>

<p>Same story. New decade.</p>

<p><strong>Governance is still being thrown over the fence.</strong></p>

<p>And with AI, that doesn’t work.</p>

<hr />

<h2 id="devgovops--what-i-mean-by-it">DevGovOps — what I mean by it</h2>

<p>Here’s the crisp version:</p>

<blockquote>
  <p><strong>DevGovOps is the practice of embedding governance, risk, and compliance directly into the development and operational lifecycle of AI systems.</strong></p>
</blockquote>

<p>Governance, in this framing, is:</p>

<ul>
  <li>Not a review board</li>
  <li>Not a checklist</li>
  <li>Not a single control</li>
</ul>

<p><strong>It lives in the execution loop.</strong></p>

<p>The fix is to embed governance into the lifecycle.<br />
The outcome is <strong>trusted AI at scale</strong>.</p>

<p>Or put another way:</p>

<blockquote>
  <p><strong>DevOps gave us speed.<br />
DevSecOps gave us safety.<br />
DevGovOps gives us trust.</strong></p>
</blockquote>

<p><img src="/assets/images/posts/2026-04-14-DevGovOps-02.png" alt="Noosa beach" class="img-responsive" /></p>

<hr />

<h2 id="why-ai-makes-this-urgent">Why AI makes this urgent</h2>

<p>You might reasonably ask: governance has <em>always</em> existed — why does it need its own “‑Ops” moment now?</p>

<p>Because <strong>AI systems fail differently</strong>.</p>

<p>Traditional software systems are largely deterministic. You test them, you deploy them, and if the tests pass, you have reasonable confidence they’ll behave as expected.</p>

<p>AI systems are <strong>probabilistic</strong>.</p>

<ul>
  <li>Behaviour evolves</li>
  <li>Risk emerges at runtime</li>
  <li>A system that “passed” pre‑deployment can drift out of acceptable bounds weeks or months later</li>
</ul>

<p>You can’t define exact expected outcomes. You have to define <strong>acceptable ranges of behaviour</strong> — and continuously verify that the system stays within them.</p>

<p>A governance model built around a single pre‑deployment review is structurally inadequate for this.</p>

<p>If your approach is <em>“pause everything for a big review before go‑live, then hope for the best”</em>, you’re not governing AI — you’re ignoring risk after day one.</p>

<p>The implication is uncomfortable but clear:</p>

<blockquote>
  <p><strong>Governance for AI systems has to be continuous, automated, and embedded into runtime — not treated as a one‑off gate.</strong></p>
</blockquote>

<p>If you don’t bring risk, governance, security, and infrastructure teams on the journey, you never get to production.</p>

<hr />

<h2 id="what-this-might-look-like">What this might look like</h2>

<p>This is not a finished framework. It’s an early articulation, grounded in patterns I’ve seen work (and fail) in our project deliveries.</p>

<h3 id="designtime-shiftleft-governance">Design‑time: shift‑left governance</h3>
<ul>
  <li>Threat modelling for AI systems</li>
  <li>Explicitly defining acceptable behavioural ranges</li>
  <li>Defining agent capabilities and boundaries before code exists</li>
</ul>

<h3 id="buildtime-governance-as-code">Build‑time: governance as code</h3>
<ul>
  <li>Policies embedded directly into prompts, system messages, and agent schemas</li>
  <li>Infrastructure‑as‑code enforcing guardrails by default</li>
  <li>CI/CD checks that validate governance constraints — not just unit tests</li>
</ul>

<h3 id="testtime-continuous-evaluation">Test‑time: continuous evaluation</h3>
<ul>
  <li>Automated evaluation pipelines</li>
  <li>Hallucination testing, safety testing, prompt‑injection scenarios</li>
  <li>Regression testing for prompts, agents, and workflows (because prompts <em>are</em> code now)</li>
</ul>

<h3 id="runtime-guardrails-and-enforcement">Runtime: guardrails and enforcement</h3>
<ul>
  <li>Real‑time restrictions on outputs and actions</li>
  <li>Human‑in‑the‑loop escalation enforced via the orchestrator — not left to the model</li>
  <li>Controls that assume failure is inevitable, not exceptional</li>
</ul>

<h3 id="identity--permissions-agents-as-identities">Identity &amp; permissions: agents as identities</h3>
<ul>
  <li>Agents treated like first‑class identities</li>
  <li>Least‑privilege by default</li>
  <li>Every tool added increases the attack surface and must be justified</li>
</ul>

<h3 id="observability--ops-continuous-governance">Observability &amp; ops: continuous governance</h3>
<ul>
  <li>Monitoring drift, quality, and risk signals</li>
  <li>Feeding those signals back into the system</li>
  <li>Cost and usage anomalies treated as governance signals, not just ops metrics</li>
</ul>

<p>None of these ideas are radical on their own.</p>

<p>The argument for DevGovOps is that <strong>they only work when treated as one coherent system</strong> — enforced via architecture and automation rather than process and paperwork.</p>

<hr />

<h2 id="what-this-is-and-isnt">What this is (and isn’t)</h2>

<p>A few important boundaries.</p>

<ul>
  <li><strong>This is early thinking</strong>, not a finished methodology.</li>
  <li>It’s a pattern I keep seeing, a name I’m putting on it, and a hypothesis about where delivery needs to go.</li>
  <li>I’m certain there are blind spots.</li>
</ul>

<p>The trade‑off I’m most wary of is bureaucracy‑by‑another‑name. If DevGovOps turns into more forms, more YAML, and more friction, it has failed. The goal is for <strong>lightweight, automated, continuous governance to replace heavyweight, manual gates</strong> — not to add more ceremony.</p>

<p>And yes, governance overlaps with security — but it’s broader:</p>
<ul>
  <li>Regulatory compliance</li>
  <li>Data sovereignty</li>
  <li>Ethical use</li>
  <li>Auditability</li>
  <li>Trust and explainability</li>
</ul>

<p>DevSecOps brought security into the pipeline.<br />
DevGovOps is about bringing the <em>rest of governance</em> in as well.</p>

<hr />

<h2 id="whats-next">What’s next</h2>

<p>My goal isn’t to convince everyone — it’s to see where this resonates, where it breaks down, and what I’m missing.</p>

<p>If this mirrors pain you’re feeling in delivery, I’d love to hear from you.<br />
If you think this is misguided, even better — tell me why.</p>

<p>DevGovOps only makes sense as a conversation <strong>we start earlier</strong>.</p>

<p>So let’s start it.</p>

<ul>
  <li>Adam</li>
</ul>]]></content><author><name></name></author><category term="Azure" /><category term="AI" /><summary type="html"><![CDATA[DevGovOps: Governance Belongs in the Loop]]></summary></entry><entry><title type="html">NDC Melbourne 2025 - AI Lessons Learned - Real world learnings delivering enterprise AI solutions</title><link href="http://adamstephensen.com/2025/04/29/ndc-melbourne-ai-lessons-learned/" rel="alternate" type="text/html" title="NDC Melbourne 2025 - AI Lessons Learned - Real world learnings delivering enterprise AI solutions" /><published>2025-04-29T00:00:00+00:00</published><updated>2025-04-29T00:00:00+00:00</updated><id>http://adamstephensen.com/2025/04/29/NDC-Melbourne-AI-Lessons-Learned</id><content type="html" xml:base="http://adamstephensen.com/2025/04/29/ndc-melbourne-ai-lessons-learned/"><![CDATA[<p>Every enterprise is under pressure to implement AI - from board mandates to competitive necessity. Yet the path from aspiration to successful implementation is filled with misconceptions, unrealistic expectations, and poorly chosen use cases that waste time and resources before we even tackle technical implementation decisions in this rapidly evolving field..</p>

<p>I’ve spent the past few years implementing AI solutions that deliver measurable business value across government agencies, educational institutions and healthcare organizations.</p>

<p>This session shares the reality of enterprise AI development beyond the hype - the real-world benefits you can expect, which use cases are genuinely transforming operations, the shiny paths that lead to complexity (and often failure), several well-trodden paths to success and the hard-learned lessons that only come from navigating complex organizational challenges. Leave armed with practical strategies to accelerate your own AI journey and the hard-earned wisdom that will dramatically increase your odds of AI success.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/KTbeNNUOmVI?si=khRKWblrwowwtM1t" frameborder="0" allowfullscreen=""></iframe>]]></content><author><name></name></author><category term="Azure" /><category term="AI" /><category term="Videos" /><category term="NDC" /><summary type="html"><![CDATA[Every enterprise is under pressure to implement AI - from board mandates to competitive necessity. Yet the path from aspiration to successful implementation is filled with misconceptions, unrealistic expectations, and poorly chosen use cases that waste time and resources before we even tackle technical implementation decisions in this rapidly evolving field..]]></summary></entry><entry><title type="html">NDC Sydney 2024 - Next Generation Developer Platforms &amp;amp; Deployable Architectural Archetypes</title><link href="http://adamstephensen.com/2024/02/12/next-generation-developer-platforms/" rel="alternate" type="text/html" title="NDC Sydney 2024 - Next Generation Developer Platforms &amp;amp; Deployable Architectural Archetypes" /><published>2024-02-12T00:00:00+00:00</published><updated>2024-02-12T00:00:00+00:00</updated><id>http://adamstephensen.com/2024/02/12/Next-Generation-Developer-Platforms</id><content type="html" xml:base="http://adamstephensen.com/2024/02/12/next-generation-developer-platforms/"><![CDATA[<p>Every enterprise is under pressure to implement AI - from board mandates to competitive necessity. Yet the path from aspiration to successful implementation is filled with misconceptions, unrealistic expectations, and poorly chosen use cases that waste time and resources before we even tackle technical implementation decisions in this rapidly evolving field..</p>

<p>I’ve spent the past few years implementing AI solutions that deliver measurable business value across government agencies, educational institutions and healthcare organizations.</p>

<p>This session shares the reality of enterprise AI development beyond the hype - the real-world benefits you can expect, which use cases are genuinely transforming operations, the shiny paths that lead to complexity (and often failure), several well-trodden paths to success and the hard-learned lessons that only come from navigating complex organizational challenges. Leave armed with practical strategies to accelerate your own AI journey and the hard-earned wisdom that will dramatically increase your odds of AI success.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/mo2w7BwPhdA?si=0P2tj-4F2sYq1XAJ" allowfullscreen=""></iframe>]]></content><author><name></name></author><category term="Azure" /><category term="Videos" /><category term="NDC" /><summary type="html"><![CDATA[Every enterprise is under pressure to implement AI - from board mandates to competitive necessity. Yet the path from aspiration to successful implementation is filled with misconceptions, unrealistic expectations, and poorly chosen use cases that waste time and resources before we even tackle technical implementation decisions in this rapidly evolving field..]]></summary></entry><entry><title type="html">Tomorrow’s Everyday Impossibilities</title><link href="http://adamstephensen.com/2022/03/21/tomorrows-everyday-impossibilities/" rel="alternate" type="text/html" title="Tomorrow’s Everyday Impossibilities" /><published>2022-03-21T00:00:00+00:00</published><updated>2022-03-21T00:00:00+00:00</updated><id>http://adamstephensen.com/2022/03/21/tomorrows-everyday-impossibilities</id><content type="html" xml:base="http://adamstephensen.com/2022/03/21/tomorrows-everyday-impossibilities/"><![CDATA[<p>I went to the planetarium recently with my daughter’s grade 4 class. Knowing I was an amateur astronomer the teacher put me on the spot before we went in and asked me if I wanted to say something to the class.</p>

<p>This is a (slightly more pollished) version of what popped into my head to explain to a group of 9 year old’s why astronomy keeps me up at night.</p>

<p>My mother’s mother’s mother was Mary Holt. She passed when I was young…. But I used to call her Ga-Ga.</p>

<p>I think about Ga-Ga a lot, and what she saw in her life. When Ga-Ga was born, the telephone had just been invented, and the Wright brothers had yet to invent the aeroplane.
When she was born the world was large. To get a photo or a person from Sydney to London they had to be put on a ship and endure 45 days at sea. 
If I had told Ga-Ga’s parents that one-day people would fly through the sky, they would have thought I was joking.
If I had told them that we would take metal tubes and put 500 people in them and that these 200 tonne vehicles would fly through the sky at 800km per hour and take people from London to Sydney in 26 hours, they would have thought I was mad. 
If I pointed to the moon and told Mary’s dad that his daughter would watch men walking on the moon, he would never have believed me
… and, as for nearly everyone having a magic mirror in their pocket that lets them see and talk to people on the other side of the world…. he’d have thought I’d stolen that from a fairy tale.</p>

<p>The 747, the Apollo missions and the smart phone are all appreciated in today’s context as important scientific and technological advances, but in the context of someone looking from 1900 they are unbelievable impossibilities.</p>

<p>In one lifetime, GaGa saw impossibilities from science fiction and fairy tales come to life.</p>

<p>Astronomy is about imagination, science, exploration and discovery.</p>

<p>I don’t have one particular field of astronomy that I find the most fascinating. Rather it is the exploration, the innovation and the discovery that inspires me. I sat transfixed with my daughter as we watched the Curiosity Rover’s seven minutes of terror. I was overjoyed when Ingenuity successfully made its first flight. I am constantly amazed as new astronomical discoveries are published like the <a href="https://www.newscientist.com/article/2307246-first-truly-isolated-black-hole-detected-in-interstellar-space/">first isolated black hole to be discovered in interstellar space</a>.</p>

<p>What I love about Astronomy is exploring the big dark holes in our current understanding of how the Universe works, and the potential impossibilities that those tunnels may lead to. Could a better understanding of relativity and the nature of the fabric of the universe enable faster than light travel? What will a better understanding of black holes and dark energy yield? Will we discover life beyond our solar system? The more I study Astronomy, the more opportunities for amazing discoveries I find.</p>

<p>The promise of Astronomy is tomorrow’s everyday impossibilities.</p>

<p>It’s a privilege to be able to participate in that journey.</p>]]></content><author><name></name></author><category term="Azure" /><category term="Space" /><summary type="html"><![CDATA[I went to the planetarium recently with my daughter’s grade 4 class. Knowing I was an amateur astronomer the teacher put me on the spot before we went in and asked me if I wanted to say something to the class.]]></summary></entry><entry><title type="html">NDC Oslo 2019 Drones &amp;amp; AI - What’s all the buzz about ?</title><link href="http://adamstephensen.com/2019/06/25/ndc-oslo-drones-ai/" rel="alternate" type="text/html" title="NDC Oslo 2019 Drones &amp;amp; AI - What’s all the buzz about ?" /><published>2019-06-25T00:00:00+00:00</published><updated>2019-06-25T00:00:00+00:00</updated><id>http://adamstephensen.com/2019/06/25/ndc-oslo-drones-ai</id><content type="html" xml:base="http://adamstephensen.com/2019/06/25/ndc-oslo-drones-ai/"><![CDATA[<p>Drones and AI are changing our world.</p>

<p>In this session we will look at some of the real world solutions utilising these emerging technologies: you will get an understanding of the core use cases, learn how to get started with the tech, and find out about the pitfalls to avoid when building solutions with drones and Artificial Intelligence.</p>

<!-- << youtube omHp3NxKcVs %} -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/omHp3NxKcVs"></iframe>]]></content><author><name></name></author><category term="Azure" /><category term="Drones" /><category term="AI" /><category term="Cognitive Services" /><category term="Videos" /><category term="NDC" /><summary type="html"><![CDATA[Drones and AI are changing our world.]]></summary></entry><entry><title type="html">Containers - The secret to shipping cloud workloads (Slide deck)</title><link href="http://adamstephensen.com/2019/04/11/containers-talk.html" rel="alternate" type="text/html" title="Containers - The secret to shipping cloud workloads (Slide deck)" /><published>2019-04-11T00:00:00+00:00</published><updated>2019-04-11T00:00:00+00:00</updated><id>http://adamstephensen.com/2019/04/11/containers-talk</id><content type="html" xml:base="http://adamstephensen.com/2019/04/11/containers-talk.html"><![CDATA[<p>I have put a new slide deck together as an overview of containers.</p>

<p><img src="/assets/images/2019-04/containers-summary.jpg" alt="Summary Slide" /></p>

<p style="   margin: 12px auto 6px auto;   font-family: Helvetica,Arial,Sans-serif;   font-style: normal;   font-variant: normal;   font-weight: normal;   font-size: 14px;   line-height: normal;   font-size-adjust: none;   font-stretch: normal;   -x-system-font: none;   display: block;"><a title="View Containers - The secret to shipping cloud workloads on Scribd" href="https://www.scribd.com/presentation/405762156/Containers-The-secret-to-shipping-cloud-workloads#from_embed" style="text-decoration: underline;">Containers - The secret to shipping cloud workloads</a> by <a title="View 's profile on Scribd" href="undefined#from_embed" style="text-decoration: underline;"></a> on Scribd</p>
<iframe class="scribd_iframe_embed" title="Containers - The secret to shipping cloud workloads" src="https://www.scribd.com/embeds/405762156/content?start_page=1&amp;view_mode=scroll&amp;show_recommendations=true&amp;access_key=key-0HQYEksHZNhpmDhLBn61" data-auto-height="true" data-aspect-ratio="null" scrolling="no" width="100%" height="600" frameborder="0"></iframe>]]></content><author><name></name></author><category term="Azure" /><category term="Containers" /><category term="AKS" /><summary type="html"><![CDATA[I have put a new slide deck together as an overview of containers.]]></summary></entry><entry><title type="html">AI on Drones - Case Study Overview</title><link href="http://adamstephensen.com/2019/04/01/drone-highlights.html" rel="alternate" type="text/html" title="AI on Drones - Case Study Overview" /><published>2019-04-01T00:00:00+00:00</published><updated>2019-04-01T00:00:00+00:00</updated><id>http://adamstephensen.com/2019/04/01/drone-highlights</id><content type="html" xml:base="http://adamstephensen.com/2019/04/01/drone-highlights.html"><![CDATA[<p>It is a great time to be a technologist. I am spending lots of my time at the moment thinking about drones, AI &amp; IOT, about where these technologies intersect, and where they can help people.</p>

<p>I was very happy when I got asked today to do a quick 10 minute presentation on ‘Where are we at with drones’.</p>

<p>Rather than just deliver it once I thought I’d capture some thoughts here.</p>

<h2 id="esmart-systems---using-drones-for-power-line-inspection">eSmart Systems - Using drones for power line inspection</h2>

<p>Maintenance of electrical grids is not only time consuming and costly, but it can also be very dangerous. By developing a connected drone that uses AI and cognitive services from Microsoft Azure, utility companies can reduce blackouts and inspect power lines more safely.</p>

<!-- << youtube Jzj1e7CutnU %} -->
<iframe src="https://www.youtube.com/embed/Jzj1e7CutnU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<h2 id="microsoft-farmbeats--uses-drones-ai-and-iot-edge-to-increase-farm-productivity">Microsoft FarmBeats -Uses drones, AI and IOT Edge to increase farm productivity</h2>

<p>Microsoft FarmBeats aims to enable farmers to increase farm productivity and reduce costs by enabling data-driven farming.</p>

<blockquote>
  <p>A new partnership between Microsoft and leading drone maker DJI builds on the work both companies are doing with data and agriculture that could make it easier and more affordable for farmers to quickly get the information they need to make crucial decisions about soil moisture and temperature, pesticides and fertilizer. Hours and days spent walking or driving the fields to try to detect problems can be eliminated.
Since 2011, farmer Sean Stratman has grown kale, cauliflower, broccoli and squash in Carnation, Washington. Then, a few years ago, he added a new crop to his bounty: knowledge, using drones and the intelligent edge to get near-real-time information about issues like soil moisture and pests. It’s the kind of information that is not only helping him, but could benefit farmers around the world.
Source: <a href="https://news.microsoft.com/transform/farmings-most-important-crop-may-be-the-knowledge-harvested-by-drones-and-the-intelligent-edge/"></a></p>
</blockquote>

<!-- youtube KTvdjcU0lf8 % -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/KTvdjcU0lf8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>Links: 
<a href="https://www.microsoft.com/en-us/research/project/farmbeats-iot-agriculture/">More reading on FarmBeats</a></p>

<h2 id="project-premonition---using-drones-to-fight-infectious-diseases">Project Premonition - Using drones to fight infectious diseases</h2>

<p>Emerging infectious diseases such as Zika, Ebola, Chikungunya and MERS are dangerous and unpredictable. Public health organizations need data as early as possible to predict disease spread and plan responses. Yet early data is very difficult to obtain, because it must be proactively collected from potential disease sources in the environment. Researchers estimate between 60 and 75% of emerging infectious diseases originate from animals, which are very difficult to monitor.</p>

<p>Project Premonition aims to detect pathogens before they cause outbreaks — by turning mosquitoes into devices that collect data from animals in the environment.</p>

<p>It does this by</p>
<ul>
  <li>Finding mosquito hotspots by drone</li>
  <li>Collecting mosquitos with robots</li>
  <li>Detecting pathogens by gene sequencing</li>
</ul>

<!-- << youtube kSUpk5CJmkw %} -->
<iframe src="https://www.youtube.com/embed/kSUpk5CJmkw"></iframe>

<p><a href="https://www.microsoft.com/en-us/research/project/project-premonition/">Full Article available here</a>
<a href="https://www.microsoft.com/en-us/research/video/project-premonition-seeking-to-prevent-disease-outbreaks-extended/">More Info here</a></p>

<h2 id="teaching-drones-to-aid-search-and-rescue-efforts-via-cognitive-services">Teaching Drones to Aid Search and Rescue efforts via Cognitive Services</h2>

<p>InDro Robotics, a drone operating outfit based in Salt Spring Island British Columbia, recently connected with Microsoft to explore how they could better enable their drones for search and rescue efforts.</p>

<p><img src="/assets/images/2019-04/InDroRobotics.jpg" alt="Drones aiding search and rescue" /></p>

<p>Leveraging Custom Vision Cognitive Service and other Azure services, including IoT Hub, InDro Robotics developers can now successfully equip their drones to:</p>

<ul>
  <li>Identify objects in large bodies of water, such as life vests, boats, etc. as well as determine the severity of the findings</li>
  <li>Recognize emergency situations and notify control stations immediately, before assigning to a rescue squad</li>
  <li>Establish communication between boats, rescue squads and the control stations. The infrastructure supports permanent storage and per-device authentication</li>
</ul>

<p><a href="https://blogs.technet.microsoft.com/canitpro/2017/05/10/teaching-drones-to-aid-search-and-rescue-efforts-via-cognitive-services/">Full article available here</a></p>

<h2 id="more-info">More info</h2>

<p>If you are interested in other use cases or info on drones I keep a scratch pad on drone tech in my <a href="https://github.com/adamstephensen/faqs/tree/master/drones">FAQs collection on drones</a>.</p>

<p>If you are doing something awesome with Drones, AI and Azure please reach out. I would love to chat !</p>]]></content><author><name></name></author><category term="Azure" /><category term="Drones" /><category term="AI" /><category term="IOT" /><category term="Cognitive Services" /><summary type="html"><![CDATA[It is a great time to be a technologist. I am spending lots of my time at the moment thinking about drones, AI &amp; IOT, about where these technologies intersect, and where they can help people.]]></summary></entry><entry><title type="html">Azure DevOps Pipelines Workshop &amp;amp; Demo Scripts</title><link href="http://adamstephensen.com/2019/03/25/azure-pipelines-workshop-demo-scripts/" rel="alternate" type="text/html" title="Azure DevOps Pipelines Workshop &amp;amp; Demo Scripts" /><published>2019-03-25T00:00:00+00:00</published><updated>2019-03-25T00:00:00+00:00</updated><id>http://adamstephensen.com/2019/03/25/devops-workshop</id><content type="html" xml:base="http://adamstephensen.com/2019/03/25/azure-pipelines-workshop-demo-scripts/"><![CDATA[<p>I recently ran a hands-on workshop about how to build Azure Pipelines for ‘build’ and ‘release’.</p>

<p>Pipelines are great as the allow you to automate your builds and deployments so you spend less time with the nuts and bolts, and more time being creative.</p>

<p>The materials put together by the Azure DevOps team are fantastic and cover a very broad range of topics.</p>

<p>You can get them here <a href="https://www.azuredevopslabs.com">https://www.azuredevopslabs.com</a>.</p>

<p><img src="/assets/images/2019-03/azure-pipelines-labs.jpg" alt="Available DevOps Labs" /></p>

<h2 id="demo-scripts-in-progress">Demo Scripts (In-Progress)</h2>

<p>Here is an overview of what I covered on the day and some basic notes I use for when I demo the day (to save me looking up the complete docs).</p>

<p>Tip: After you have followed the step by step instructions - see if you can complete the task again just following my demo script notes.</p>

<h2 id="exercise-1a-enabling-continuous-integration-with-azure-pipelines">Exercise 1a: Enabling Continuous Integration with Azure Pipelines</h2>
<p>Source: https://www.azuredevopslabs.com/labs/azuredevops/continuousintegration/</p>

<hr />

<h2 id="exercise-1b-configuring-builds-as-code-with-yaml-in-azure-pipelines">Exercise 1b: Configuring Builds as Code with YAML in Azure Pipelines</h2>
<p>Source: https://www.azuredevopslabs.com/labs/azuredevops/yaml/</p>

<h3 id="task-1-setting-up-azure-resources">Task 1: Setting up Azure resources</h3>
<ol>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Disable the CI trigger for the default build definition. Edit</td>
          <td>Triggers</td>
          <td>Enabled</td>
          <td>Save</td>
        </tr>
      </tbody>
    </table>
  </li>
</ol>

<h3 id="task-2-adding-a-yaml-build-definition">Task 2: Adding a YAML build definition</h3>
<ol>
  <li>Repos | Files | New File | ‘azure-pipelines.yml’
    <blockquote>
      <p>Azure DevOps will automatically create a definition when you add this file to root of repo.</p>
    </blockquote>
  </li>
  <li>Add the yaml below and commit.
    <pre><code class="language-YML"> steps:
 - script: echo hello world
</code></pre>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Go to Pipelines</td>
          <td>Build</td>
          <td>Start the build</td>
          <td>View the last build step.</td>
        </tr>
      </tbody>
    </table>
  </li>
</ol>

<h3 id="task-3-crafting-sophisticated-yaml-definitions">Task 3: Crafting sophisticated YAML definitions</h3>
<p>You can even export existing build definitions as YAML if you would prefer to manage them in code.</p>

<ol>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Builds</td>
          <td>PartsUnlimitedE2E</td>
          <td>Edit</td>
          <td>View YAML</td>
          <td>Copy to clipboard</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>Open our ‘azure-pipelines.yml’ and paste in contents. Commit changes
    <blockquote>
      <p>Note: In the comment blog: The SymbolPath reference is coincidental (it’s a literal needed for the build), but the BuildPlatform and BuildConfguration variables will play a role later.</p>
    </blockquote>
  </li>
  <li>Pipelines | Build | Open the new build to follow its progress. 
It will be successful but report there were no tests - there should have been. 
we will work out the problem.</li>
  <li>Build | Logs tab | Test Assemblies task
Note that there is a warning that the test assembly pattern didn’t find any matches. Upon closer inspection, it appears that it was expecting a build variable for BuildConfiguration to be available, but since it wasn’t, the platform simply used the text as-is. This was something we probably should have expected given the warnings in the YAML.</li>
  <li>Edit build | Variables | Add |
    <ul>
      <li>
        <table>
          <tbody>
            <tr>
              <td>“BuildPlatform”</td>
              <td>“any cpu”</td>
            </tr>
          </tbody>
        </table>
      </li>
      <li>
        <table>
          <tbody>
            <tr>
              <td>“BuildConfiguration”</td>
              <td>“release”</td>
            </tr>
          </tbody>
        </table>
      </li>
      <li>Check the ‘Settable at queue time’ option for each</li>
    </ul>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Triggers tab</td>
          <td>Note that you can override the YAML settings and configure CI like web-based builds</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>Save and Queue</li>
  <li>Check the tests. All good.</li>
</ol>

<hr />

<h2 id="exercise-2-embracing-continuous-delivery-with-azure-pipelines">Exercise #2 Embracing Continuous Delivery with Azure Pipelines</h2>
<p>Source: https://www.azuredevopslabs.com/labs/azuredevops/continuousdeployment/</p>

<h3 id="task-1-setting-up-azure-resources-1">Task 1 Setting up Azure Resources</h3>
<ol>
  <li>Create a SQL Database (if you haven’t already made it)
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  database name: partsunlimited
  source: blank database
  server name: &lt;yourname&gt;-partsunlimited
</code></pre></div>    </div>
    <p>2.Create a web app (if you haven’t already made it)</p>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  app name: &lt;yourname&gt;-partsunlimited-qa
  resource group &amp; subscription: same as previous
  app service plan: accept the defaults
  OS: Windows
  App Insights: Off
</code></pre></div>    </div>
  </li>
</ol>

<h3 id="task-2-creating-a-continuous-release-to-the-qa-state">Task 2: Creating a continuous release to the QA state</h3>
<ul>
  <li>open a new browser tab for Azure DevOps https://dev.azure.com/YOURACCOUNT/Parts%20Unlimited.</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>Navigate to Pipelines</td>
          <td>Releases</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>Delete the existing PartsUnlimitedE2E release pipeline</li>
  <li>Create a new release pipeline
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>template: Azure App Service Deployment
default stage: QA
pipeline name: PUL-CICD
artifact: Build | PartsUnlimitedE2E
QA environment task | select QA web app
</code></pre></div>    </div>
  </li>
  <li>Turn on CI trigger</li>
  <li>Add a build branch trigger &gt; “The build pipeline’s default branch”</li>
  <li>Save</li>
</ul>

<h3 id="task-3-configuring-the-azure-app-services-for-cd">Task 3: Configuring the Azure app services for CD</h3>
<ol>
  <li>Open the SQL Database - get the db connection strings</li>
  <li>Copy the ADO.NET string to your clipboard.</li>
  <li>Update username and password in the connection string with SQL credentials</li>
  <li>Open the QA app service | Application Settings | Connection Strings
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DefaultConnectionString: &lt;paste in the connectionstring&gt;
</code></pre></div>    </div>
  </li>
  <li>Click Save</li>
  <li>Repeat for Prod web app</li>
</ol>

<h3 id="task-4-invoking-a-cd-release-to-qa">Task 4: Invoking a CD release to QA</h3>
<ol>
  <li>Open Azure Devops Repos tab in a new browser tab</li>
  <li>Edit <code class="language-plaintext highlighter-rouge">PartsUnlimited-aspnet45/src/PartsUnlimitedWebsite/Views/Shared/_Layout.cshtml.</code>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>//add v2.0 text after the image
&lt;img src="/images/unlimited_logo.png" &gt;v2.0
</code></pre></div>    </div>
  </li>
  <li>Commit changes</li>
  <li>Open the build that is kicked off &gt; follow until completion</li>
  <li>Open the release &gt; follow it until completion</li>
  <li>Navigate to the QA Site &gt; <app-service-name>.azurewebsites.net</app-service-name></li>
  <li>Check that it now says ‘v2.0’ after the image</li>
</ol>

<h3 id="task5-creating-a-gated-release-to-the-production-stage">Task5: Creating a gated release to the production stage</h3>
<p>We are including both automated quality gates as well as a manual approver gate. 
We will make it our policy that the QA deployment cannot be considered a success until all critical bugs have been resolved.</p>

<ol>
  <li>Open the Release pipeline. Clone the QA stage.</li>
  <li>Apply post-deployment considitions on QA gate
    <ul>
      <li>Enable the Gates option</li>
      <li>Change ‘Delay before evaluation’ to 0</li>
      <li>Add ‘Query Work Items’ Deployment gates</li>
      <li>
        <table>
          <tbody>
            <tr>
              <td>Query &gt; Shared Queries</td>
              <td>Critical Bugs</td>
            </tr>
          </tbody>
        </table>
      </li>
      <li>Evuation options &gt; Time between re-evaluation of gates to 5.</li>
    </ul>
  </li>
  <li>Rename ‘Copy of QA’ to Prod</li>
  <li>Add Pre-deployment approvals &gt; add yourself as an Approver</li>
  <li>Click the Prod job &gt; change the app service name to be the Prod web app</li>
  <li>Save the pipeline</li>
  <li>Edit <code class="language-plaintext highlighter-rouge">PartsUnlimited-aspnet45/src/PartsUnlimitedWebsite/Views/Shared/_Layout.cshtml.</code>
Change v2.0 to v3.0</li>
  <li>Follow the release through to QA. It will fail. 
Click the View post-deployment gates button.</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>In a new tab open ‘Boards</td>
          <td>Queries</td>
          <td>Shared Queries</td>
          <td>Critical Bugs’ to locate the bug</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>Open the bug and mark it as Done. Click Save. (Usually we’d actually fix the bug ;-))</li>
  <li>Return to release tab. After approx 5 mins Azure DevOps will check the query again. 
Once it does, the bugs will be cleared and the release will be approved. You can then click Approve to approve deployment to production.</li>
  <li>Confirm the release and watch it, and then check the prod website</li>
</ol>

<h3 id="task-6-working-with-deployment-slots">Task 6: Working with deployment slots</h3>

<p>The most common scenario for using a deployment slot is to have a staging stage for your application to run against productions services, but without replacing the current production application. If the staging deployment passes review, it can immediately be “swapped” in as the production slot with the click of a button. As an additional benefit, the swap can be quickly reversed in the event an issue is uncovered with the new build.</p>

<ol>
  <li>Open the prod app service &gt; Deployment Slots &gt; Add Slot &gt; ‘staging’ with ‘Config Source’ as the current deployment.
Note: the ‘production’ slot is considered a ‘default’ and is not shown as a separate slot</li>
  <li>Edit the Azure DevOps Prod stage pipeline &gt; Select ‘Deploy Azure App Service’ task &gt;</li>
  <li>Select Deploy to slot &gt; choose ‘staging’. Click Save</li>
  <li>Commit a change to ‘v4.0’. Follow pipeilne through and approve release.</li>
  <li>Refresh browser tab for Prod website -&gt; Still v3.0</li>
  <li>Open a new tab to the staging slot…. ‘https://<app-name>-staging.azurewebsites.net</app-name></li>
  <li>Return to the App Service in Azure Portal. Deployment Slots &gt; Swap &gt; OK (with defaults)</li>
  <li>Refresh prod browser window -&gt; v4.0</li>
</ol>

<blockquote>
  <p>Note:  Note that if your apps rely on slot-level configuration settings (such as connection strings or app settings marked “slot”), then the worker processes will be restarted. If you’re working under those circumstances and would like to warm up the app before the swap completes, you can select the Swap with preview swap type.</p>
</blockquote>

<hr />

<h2 id="exercise-3-github-integration-with-azure-pipelines">Exercise #3 GitHub integration with Azure Pipelines</h2>
<p>Source: https://www.azuredevopslabs.com/labs/vstsextend/github-azurepipelines/</p>]]></content><author><name></name></author><category term="Azure" /><category term="DevOps" /><summary type="html"><![CDATA[I recently ran a hands-on workshop about how to build Azure Pipelines for ‘build’ and ‘release’.]]></summary></entry><entry><title type="html">Understanding the Enterprise Bot Template</title><link href="http://adamstephensen.com/2019/03/20/enterprise-bot-template.html" rel="alternate" type="text/html" title="Understanding the Enterprise Bot Template" /><published>2019-03-20T00:00:00+00:00</published><updated>2019-03-20T00:00:00+00:00</updated><id>http://adamstephensen.com/2019/03/20/enterprise-bot-template</id><content type="html" xml:base="http://adamstephensen.com/2019/03/20/enterprise-bot-template.html"><![CDATA[<h1 id="understanding-the-enterprise-bot-template">Understanding the Enterprise Bot Template</h1>

<p>This is my version of the <a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0&amp;tabs=cs">how bots work</a> doco page,  customised to explain the Enterprise Bot Template.</p>

<p>The reason that I have done my own version is that for me I’d rather read well commented (overly commented) code to understand how something works than reading a paragraph of text, then associating it with code.</p>

<h2 id="sources">Sources</h2>
<ul>
  <li><a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0&amp;tabs=cs">How bots work</a></li>
</ul>

<h3 id="bot-class">Bot Class</h3>

<pre><code class="language-C#">    public class EnterpriseBotSample : IBot
    {
        private readonly BotServices _services;
        private readonly ConversationState _conversationState;
        private readonly UserState _userState;
        private readonly IBotTelemetryClient _telemetryClient;
        private DialogSet _dialogs;
</code></pre>

<ul>
  <li>The main bot logic is defined in the EnterpriseBotSample class that derives from the IBot interface.</li>
  <li>IBot defines a single method OnTurnAsync.</li>
</ul>

<h3 id="onturnasync">OnTurnAsync</h3>

<pre><code class="language-C#">public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) 
</code></pre>

<p>OnTurnAsync: updated with my code comments. I wouldn’t usually write this many comments in code ;-)</p>

<pre><code class="language-C#">// Turncontext provides information about the incoming activity. 
	public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{

	//The incoming activity corresponds to the inbound HTTP request. 
	// Activities can be of various types, so we check to see if the bot has received a message. 
    if (turnContext.Activity.Type == ActivityTypes.Message)
    {
		//If it is a message, we get the conversation state from the turn context, increment the turn counter, and then persist the new turn counter value into the conversation state. 

        // Get the conversation state from the turn context.
        var oldState = await _accessors.CounterState.GetAsync(turnContext, () =&gt; new CounterState());

        // Bump the turn count for this conversation.
        var newState = new CounterState { TurnCount = oldState.TurnCount + 1 };

        // Set the property using the accessor.
        await _accessors.CounterState.SetAsync(turnContext, newState);

        // Save the new turn count into the conversation state.
        await _accessors.ConversationState.SaveChangesAsync(turnContext);


		// And then send a message back to the user using SendActivityAsync call. 
		// The outgoing activity corresponds to the outbound HTTP request.

        // Echo back to the user whatever they typed.
        var responseMessage = $"Turn {newState.TurnCount}: You sent '{turnContext.Activity.Text}'\n";
        await turnContext.SendActivityAsync(responseMessage);
    }
    else
    {
        await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected");
    }
}
</code></pre>

<h2 id="set-up-services">Set up services</h2>

<p>The ConfigureServices method in the startup.cs file</p>
<ul>
  <li>is where <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2">.NET Core configure Dependency Injection as per the docs</a></li>
  <li>it loads the connected services from .bot file,</li>
  <li>catches any errors that occur during a conversation turn and logs them,</li>
  <li>sets up your credential provider and</li>
  <li>creates a conversation state object to store conversation data in memory.</li>
</ul>

<pre><code class="language-C#">services.AddBot&lt;EchoWithCounterBot&gt;(options =&gt;
{
    // Creates a logger for the application to use.
    ILogger logger = _loggerFactory.CreateLogger&lt;EchoWithCounterBot&gt;();

    var secretKey = Configuration.GetSection("botFileSecret")?.Value;
    var botFilePath = Configuration.GetSection("botFilePath")?.Value;

    // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
    BotConfiguration botConfig = null;
    try
    {
        botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
    }
    catch
    {
        //...
    }

    services.AddSingleton(sp =&gt; botConfig);

    // Retrieve current endpoint.
    var environment = _isProduction ? "production" : "development";
    var service = botConfig.Services.Where(s =&gt; s.Type == "endpoint" &amp;&amp; s.Name == environment).FirstOrDefault();
    if (!(service is EndpointService endpointService))
    {
        throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
    }

    options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

    // Catches any errors that occur during a conversation turn and logs them.
    options.OnTurnError = async (context, exception) =&gt;
    {
        logger.LogError($"Exception caught : {exception}");
        await context.SendActivityAsync("Sorry, it looks like something went wrong.");
    };

    // The Memory Storage used here is for local bot debugging only. When the bot
    // is restarted, everything stored in memory will be gone.
    IStorage dataStore = new MemoryStorage();

    // ...

    // Create Conversation State object.
    // The Conversation State object is where we persist anything at the conversation-scope.
    var conversationState = new ConversationState(dataStore);

    options.State.Add(conversationState);
});
</code></pre>

<h3 id="startupcs---configuring-state">Startup.cs - configuring state</h3>
<p>Note: this is different to the getting started doc. It works differently in the enterprise template - we aren’t configuring the stateaccessors in the ConfigureServices method</p>

<p><a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-state?view=azure-bot-service-4.0&amp;tabs=csharp">Understanding state</a></p>

<pre><code class="language-C#">
var dataStore = new CosmosDbStorage(cosmosOptions);
            var userState = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));


</code></pre>

<h3 id="startupcs---configure-method">startup.cs - Configure method</h3>

<p>The Configure method finishes the configuration of your app by specifying that the app use the Bot Framework and a few other files. All bots using the Bot Framework will need that configuration call. ConfigureServices and Configure are called by the runtime when the app starts.</p>

<pre><code class="language-C#">        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseBotApplicationInsights()
                .UseDefaultFiles()
                .UseStaticFiles()
                .UseBotFramework();
        }
</code></pre>

<h2 id="the-bot-file">The bot file</h2>

<p>The .bot file contains information, including the endpoint, app ID, and password, and references to services that are used by the bot. This file gets created for you when you start building a bot from a template, but you can create your own through the emulator or other tools. You can specify the .bot file to use when testing your bot with the emulator.</p>

<pre><code class="language-JSON">{
    "name": "echobot-with-counter",
    "services": [
        {
            "type": "endpoint",
            "name": "development",
            "endpoint": "http://localhost:3978/api/messages",
            "appId": "",
            "appPassword": "",
            "id": "1"
        }
    ],
    "padlock": "",
    "version": "2.0"
}
</code></pre>

<h2 id="state">State</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- User state is available in any turn that the bot is conversing with that user on that channel, regardless of the conversation
- Conversation state is available in any turn in a specific conversation, regardless of user (i.e. group conversations)
- Private conversation state is scoped to both the specific conversation and to that specific user
</code></pre></div></div>
<p>Source: <a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-state?view=azure-bot-service-4.0">Managing State</a></p>

<pre><code class="language-C#">

    public class OnboardingDialog : EnterpriseDialog
    {
        private static OnboardingResponses _responder = new OnboardingResponses();
        private IStatePropertyAccessor&lt;OnboardingState&gt; _accessor;
        private OnboardingState _state;

        public OnboardingDialog(BotServices botServices, IStatePropertyAccessor&lt;OnboardingState&gt; accessor, IBotTelemetryClient telemetryClient)
            : base(botServices, nameof(OnboardingDialog))
        {
            _accessor = accessor;
            InitialDialogId = nameof(OnboardingDialog);

            var onboarding = new WaterfallStep[]
            {
                AskForName,
                AskForEmail,
                AskForLocation,
                FinishOnboardingDialog,
            };

            // To capture built-in waterfall dialog telemetry, set the telemetry client 
            // to the new waterfall dialog and add it to the component dialog
            TelemetryClient = telemetryClient;
            AddDialog(new WaterfallDialog(InitialDialogId, onboarding) { TelemetryClient = telemetryClient });
            AddDialog(new TextPrompt(DialogIds.NamePrompt));
            AddDialog(new TextPrompt(DialogIds.EmailPrompt));
            AddDialog(new TextPrompt(DialogIds.LocationPrompt));
        }

        public async Task&lt;DialogTurnResult&gt; AskForName(WaterfallStepContext sc, CancellationToken cancellationToken)
        {
            _state = await _accessor.GetAsync(sc.Context, () =&gt; new OnboardingState());

            if (!string.IsNullOrEmpty(_state.Name))
            {
                return await sc.NextAsync(_state.Name);
            }
            else
            {
                return await sc.PromptAsync(DialogIds.NamePrompt, new PromptOptions()
                {
                    Prompt = await _responder.RenderTemplate(sc.Context, sc.Context.Activity.Locale, OnboardingResponses.ResponseIds.NamePrompt),
                });
            }
        }

</code></pre>

<h2 id="dialogues">Dialogues</h2>

<p>See <a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-dialog?view=azure-bot-service-4.0">the docs</a></p>

<p><a href="https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-prompts?view=azure-bot-service-4.0&amp;tabs=csharp">Gathering user input via Dialogues</a></p>]]></content><author><name></name></author><category term="Azure" /><category term="AI" /><category term="Bots" /><category term="Cognitive Services" /><summary type="html"><![CDATA[Understanding the Enterprise Bot Template]]></summary></entry></feed>