Revit API tools for extensible storage and OAuth Auth0, notes on AI news, a Mac feature and electrical energy storage:
The atomatiq team including Ilia Ivanov and Sergei Nefedov presents the SchemaMigrations library of comfortable tools for the Revit Extensible Storage API to make its usage similar to the .NET Entity Framework:
SchemaContext
.Schema Migration Generator
to create migration.Models
class, instead of only primitive objects.For further details, check out the SchemaMigrations GitHub repository documentation.
Daily exciting news on AI keeps on coming and continues accelerating. OpenAI published a 20-minute YouTube presentation on Deep Research, allowing the LLM to use agents, Internet access and other tools for longer-lasting partially unsupervised tasks. This functionality already launched in ChatGPT pro.
Some of this functionality was previously available for some other LLMs, e.g., Claude computer use. Deep research is still pushing new boundaries, though, e.g., solving a much larger part of Humanity's Last Exam. Things are certainly moving fast, boundaries pushed and new functionality published daily, with strong competition from many sides.
Daniel christev7HTEL Christev kindly
shared a fix to enable using OAuth
Auth0
in a Revit add-in in
the Revit API discussion forum thread
on WebView2 throws System.Runtime.InteropServices.COMException: 'The requested resource is in use. (0x800700AA)'.
in case –; like me –; you wonder what the difference is between OAuth 2.0 and Auth0, check out the StackOverflow explanation
on OAuth 2.0 vs Auth0.
Daniel says:
Just wanted to post some info on a bug I came across + fix. Maybe no one will run into this problem, but it took me a while to get to the bottom of it.
It started with trying to use Auth0
in a Revit application; the default implementation throws the exception and Revit crashes:
It is possible to fix this by instantiating your client with a WebBrowserBrowser
:
IBrowser browser = new WebBrowserBrowser();
client = new Auth0Client(new Auth0ClientOptions
{
Domain = domain,
ClientId = clientId,
RedirectUri = "http://localhost:3003",
PostLogoutRedirectUri = "http://localhost:3003",
Browser = browser
});
or even creating an implementation to try to use the default SystemBrowser
but I still wanted WebView2
here.
It turns out the prickly bit of code boils down to the default environment that is created.
Generally, when you are generating a WebView2 within an application, you should call the following code:
string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
System.IO.Directory.CreateDirectory(appDataFolder);
var env = await CoreWebView2Environment.CreateAsync(null, appDataFolderACAD);
await webView.EnsureCoreWebView2Async(env);
It's important to create the environment, or else the default implementation will register a data folder running out of a secured folder that can't write like Program Files.. And this was what happened to me. WebView2 in Revit was trying to create a directory at:
which aside from being an absolute eye-sore, requires admin privileges to write to, and thus the resource cannot be used.
As someone new to WebView2, this really tripped me up, so here's to hoping it will help someone else at some point too.
So I created a custom UserEnvironmentWebViewBrowser
where the UserDataFolder
can be set, and defaults to appdata.
(This is by and large identical to the WebViewBrowser
implementation, with the addition of the aforementioned):
public class UserEnvironmentWebViewBrowser : IBrowser
{
private readonly Func<Window> _windowFactory;
private readonly bool _shouldCloseWindow;
public UserEnvironmentWebViewBrowser(Func<Window> windowFactory, bool shouldCloseWindow = true)
{
_windowFactory = windowFactory;
_shouldCloseWindow = shouldCloseWindow;
}
public UserEnvironmentWebViewBrowser(
string title = "Authenticating...",
string? userDataFolder = null,
int width = 1024,
int height = 768)
:
this(() => new Window
{
Name = "WebAuthentication",
Title = title,
Width = width,
Height = height
})
{
if (userDataFolder != null && Directory.Exists(userDataFolder))
{
UserDataFolder = userDataFolder;
}
}
public string UserDataFolder { get; set; }
= Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
public async Task<BrowserResult> InvokeAsync(
BrowserOptions options,
CancellationToken cancellationToken = default(CancellationToken))
{
TaskCompletionSource<BrowserResult> tcs
= new TaskCompletionSource<BrowserResult>();
Window window = _windowFactory();
WebView2 webView = new WebView2();
window.Content = webView;
webView.NavigationStarting += delegate (object? sender,
CoreWebView2NavigationStartingEventArgs e)
{
if (e.Uri.StartsWith(options.EndUrl))
{
tcs.SetResult(new BrowserResult
{
ResultType = BrowserResultType.Success,
Response = e.Uri.ToString()
});
if (_shouldCloseWindow)
{
window.Close();
}
else
{
window.Content = null;
}
}
};
window.Closing += delegate
{
webView.Dispose();
if (!tcs.Task.IsCompleted)
{
tcs.SetResult(new BrowserResult
{
ResultType = BrowserResultType.UserCancel
});
}
};
window.Show();
var webView2Environment = await CoreWebView2Environment.CreateAsync(null, UserDataFolder);
await webView.EnsureCoreWebView2Async(webView2Environment);
webView.CoreWebView2.Navigate(options.StartUrl);
return await tcs.Task;
}
}
You can also check out the solution in my RevitWebView2Bug GitHub repo.
Shoutout to @grahamcook as I found the answer within his [post](https://forums.autodesk.com/t5/net/using-the-webviewer2-package-version-issues/m-p/12941602.
Many thanks, Daniel and Graham, for sharing this.
Docling by IBM simplifies document processing, parsing diverse formats – including advanced PDF understanding – and providing seamless integrations with the gen AI ecosystem, featuring:
I tested docling on an arxiv scientific paper listed in the installation instructions, and it works perfectly right out of the box with very impressive results:
pip install docling
docling https://arxiv.org/pdf/2206.01062
The result is a 1.6 MB markdown file 2206.01062v1.md
complete with images, tables, text, headings, the whole shebang, perfectly formatted.
After thousands of unthinking repetitions, I finally searched and found a note on how to copy and paste text excluding formatting on Mac:
In Windows, the Copy and Paste key combinations are Control-C and Control-V, respectively. On the Mac, it's similar using the Command (⌘) key instead of Control. You can also paste text without its original formatting. Not knowing that this is possible on a Mac, many users paste text into a plain-format text editor to strip it of any styling before copying and pasting it again to its intended destination (that's me). But you don't have to do that. To directly paste the copied text elsewhere as purely plain text, use the key combination Command-Option-Shift-V and it will be automatically stripped of any formatting.
Wow. I should have thought of checking that out years ago.
Now to round off with a non-digital topic: I was previously not aware of any DIY efforts to create battery storage and therefore excited to discover the Flow Battery Research Collective open source project targeted at creating a simple DIY redox flow battery.
This 20-minute video discusses progress so far and current status. The roadmap posits a research kit in the middle of this year to help discover optimal liquid chemical components, and hopes to be able to provide a kit for creating your own working 48V battery sufficient for powering a small home by the end of the year.
By the way, there are a number of non-DIY effort underway as well, with significant interest, support and funding, e.g., the long-term energy storage challenge by SPRIN-D. One example is the Swiss startup Unbound Potential.