In the previous post in this series, we built a streaming retrieval-augmented generation (RAG) pipeline that parses, chunks, embeds, and writes to Milvus in a single Ray Data script. It works well. But it is a monolithic script. When parsing fails at file 847 of 1,000, you rerun everything from scratch.
The post Orchestrate production RAG with OpenShift AI appeared first on Red Hat Developer.Runbooks provide a way to automate ad-hoc and maintenance tasks, and webhooks allow you to trigger these runbooks from external systems. In this post, you'll create a sample project that demonstrates how to set up runbook webhook triggers.
:::div{.hint} The Octopus AI Assistant will work with an on-premises Octopus instance, but it requires more configuration. The cloud-hosted version of Octopus doesn't need extra configuration. This means the cloud-hosted version is the easiest way to get started. :::
Paste the following prompt into the Octopus AI Assistant and run it:
Create a Script project called "23. Script App with Runbook Webhooks", and then:
* Add a runbook called "Runbook Webhook Trigger" with a script step that echoes "Runbook triggered by webhook".
* Create a webhook trigger for the runbook, using a webhook secret.
The project 23. Script App with Runbook Webhooks will be created, along with a runbook called Runbook Webhook Trigger that contains a script step to echo the message "Runbook triggered by webhook". A webhook trigger will also be set up for the runbook, using a webhook secret.
For security reasons, the AI Assistant does not accept secrets as inputs, and the webhook secret is generated automatically. You must replace the secret with your own value:
:img{ src="/blog/img/octo-easy-mode-23-runbookwebhooks/webhook-secret.png" alt="Webhook Secret" loading="lazy" }
:::div{.hint} Even if you try to define a secret in the prompt, the AI Assistant will ignore it and generate a new random secret that is immediately forgotten and not displayed anywhere. You must replace the secret with your own value.
Webhooks can also use an Octopus API key for authentication. :::
Your webhook has a unique URL that you can use to trigger the runbook. This is displayed in the Endpoint section of the webhook trigger.
Use the following curl command to execute the runbook:
curl -X POST -H "X-Octopus-Webhook-Secret: <webhook-secret>" https://<your-octopus-url>/api/Spaces-<space-id>/webhook/<webhook-id>
You created a sample project with:
Runbook Webhook Trigger that contains a script step to echo a message to the logs.DataGrids are excellent for providing both expansive data and filtered specifics, all in a usable and familiar setup. Just what the medical industry demands.
If you’re part of creating applications in the medical field, many (or most) of your users are going to be medical professionals: trained individuals who are licensed/certified to provide preventative, curative or rehabilitative healthcare to patients. This includes doctors, nurses, paramedics, dentists, their support staff (e.g., pharmacists) and other health professionals (e.g., physiotherapists).
Really, the group of users includes anyone who is certified to provide care (i.e., diagnosing, treating or managing) for either physical or mental illnesses. As broad as that group is, those professionals have a set of shared needs that your application will need to support.
For example, all medical professionals work in evidence-based environments where it’s difficult to have “too much” information … but where it’s essential to find the relevant details quickly. All these professionals (and the applications they use) must also adhere to various regulatory standards, including confidentiality and privacy requirements.
Many medical professionals are working in environments where time is critical and, as result, are environments best described as “high stress”: Too much to do, not enough time to do all of it, and frequent interruptions by new, high priority tasks. Speed and “ease of use” are essential here, but “ease of use” must also include flexibility to meet changing needs.
Finally, as that list of different people suggests, medical professionals work in highly collaborative environments, where they are constantly calling on other professionals in different specialties or departments to support their patients. The ability to share data is also critical.
You can support all those needs with the DataGrid component in your favorite Progress Telerik or Kendo UI library.
A medical professional will often need to handle large volumes of complex patient data, sometimes for multiple patients (doctor’s offices, hospital wards) and sometimes for a single patient (reviewing patient history). Because of the time-critical nature of the field, medical professionals need to get to the data quickly either in real time or near real time.
You can leverage the DataGrid OnRead event and support for Observables to load initial data quickly and to respond to changes in the data as those changes happen.
Being able to find “what matters” in large amounts of is also going to be important to your users. Out of the box, the DataGrid allows users to reorder and pin columns, filter data and group data to pull together what matters to them right now.
See, for example, the React Healthcare Management sample app, with a Progress KendoReact DataGrid displaying a filterable list of patients.

However, users will also want to be able quickly switch between DataGrid configurations they use frequently (grouping, column order, filters) rather than have to recreate those configurations from scratch: switching from viewing patient data grouped and sorted by patient or room to seeing the data grouped and organized by time (either historical dates or future activities). You can implement “one-click” switching between those settings by using DataGrid templates, or you can give users the ability to save DataGrid configurations that are useful to them.
Medical professionals are also going to value having key data highlighted as soon as that data is displayed. But you can also use the DataGrid conditional formatting (at the row or cell level) to highlight critical data. In addition, the DataGrid “scroll to item” option lets you programmatically put critical data on the screen for the user to review.
Much medical data is hierarchical in nature (for example, patients in a ward, patients attending a clinic in any time period, a single patient’s medical history). Your users can take advantage of the DataGrid’s ability to define new groups as needed by dragging and dropping columns.
And you can also leverage the DataGrid’s ability to create nested hierarchies to allow your users to view the groups that matter to them as soon as the data is displayed. The DataGrid’s hierarchical display then allows your users to expand those high-level groups to, for example, drill down to individual patients in a ward or to single events in a patient’s medical history.
Out of the box, the DataGrid (in addition to supporting assistive technologies like Jaws and ZoomText) is designed to be compliant with both the Web Content Accessibility Guidelines and the Americans with Disabilities Act accessibility guidelines. But you can also take advantage of the DataGrid’s ability to dynamically hide columns and mask sensitive data to let you control what data is seen by users (based, for example, on the user’s roles as retrieved from whatever authorization system their organization uses).
The DataGrid also integrates cleanly with server-side data processing, enabling you to decide what data you want to keep on the server and what you’re willing to send to the client.
Because medical professionals are working collaboratively with other professionals to deliver patient care, exporting data is often essential. Out of the box, users can easily support export DataGrid data in either CSV or PDF format. Users can choose to export a single page from the DataGrid, export a filtered subset of the data or export all the data in the grid. The DataGrid also supports integrating your own custom code into the export process so that you can control what data is shared, helping to protect sensitive data from leaving the security parameters of your application.
Because of the nature of the data in medical applications, you’ll also want to take advantage of DataGrid protection against Cross-Site Scripting attacks by using the HtmlEncode property to reduce the attack surface of your grid. When interacting with SQL data sources, using the DataGrid’s Parameter elements can help protect your application’s data from SQL injection attacks.
In the evidence-based environment that medical professionals work in, reporting data is important. Equally important is capturing and recording data quickly without losing accuracy.
Users can rapidly update data within the grid without, for example, having to open a separate form (though you can enable popup forms for individual rows or even navigate to another form in order provide a UI that supports more intensive data entry). The DataGrid supports row-by-row editing to enable updating a single entry in the grid (including locking out cells in a row to prevent inadvertent changes). The DataGrid also support bulk editing that allows the user to update multiple rows before saving their changes with a single button click.
The shortcuts and keyboard navigation built into the DataGrid allow experienced users to move quickly through the grid and update data without having to reach for the mouse. On top of that, the new “smart” AI features in the DataGrid let users enter natural language queries to find or highlight rows that meet the criteria that users provide. The DataGrid has various AI assistants (Chat, Column and Toolbar) to go further in letting users describe what they want the grid to do and have the grid respond without the user having to get involved in the detailed mouse movements.
In a medical environment verifying that only valid entries are made in patient data (including, for example, medication dosages) is essential. The DataGrid has built-in support for validating data entry, including integrating your own custom validation to support maintaining data integrity.
To put it another way: With the DataGrid, you can create applications that integrate with any clinical workflow and provide medical professionals with the tools they need to better meet the needs of their job.
You saw the KendoReact Grid above. Check out the Telerik DevCraft suite of products to learn about the DataGrid in your favorite .NET or JavaScript flavor, like the Blazor Grid or the Angular Grid.
Get your hands on the whole suite free for 30 days:
If you search for "GitHub Copilot budget policy", most posts point you to cost centers: assign a budget to a cost center, map the cost center to a team or business unit, done. Clean story, except for one detail nobody mentions upfront — cost centers require a GitHub Enterprise Cloud account.
That's not the same thing as being on the Copilot Enterprise plan; user-level budgets already work fine on Copilot Business. It's about the account type; a standalone Organization account doesn't have cost centers, and neither does GitHub Enterprise Server if you're self-hosted. If you're not on Enterprise Cloud, cost centers are off the table.
We ran into exactly this. No Enterprise Cloud account, no cost centers, but still a real need to keep Copilot spend under control across a growing user base.
Remark: if you do have GitHub Enterprise Cloud, cost centers are probably still the better fit. This post is for the rest of us.
We have two distinct groups of Copilot users:
A single flat budget per user doesn't work here: set it low enough to control the power users and the daily users are needlessly constrained; set it high enough for the daily users and the power users blow through any real cost control.
Without cost centers, the building block you're left with is the per-user budget. So instead of trying to simulate teams or business units, we built the policy around the two groups we actually have:
The budget itself stays pooled at the enterprise level. We're not carving out separate pots of money per team. What changes is the ceiling: no individual user, regardless of group, can exceed their assigned budget. A daily user is capped at the universal amount. A power user is capped at the universal amount plus their extra allocation.
Remark: the pooling matters. It means unused budget from daily users isn't wasted. It stays available at the enterprise level while still giving you a hard per-user ceiling to prevent runaway individual spend.
This is done under "Budgets and alerts" on your organization or enterprise billing page. Concretely:
Tip: if you don't have usage data yet, don't overthink the starting numbers — set something reasonable for the universal budget and tune it after your first billing cycle using the dashboard.
It's not as granular as cost-center-based reporting per team. If you need to answer "how much did Team X spend this quarter", this approach won't get you there directly. For us, controlling total spend and preventing individual overuse mattered more than per-team attribution, so the trade-off was worth it.
That's it. 2 budget tiers, pooled at the top, capped per user.