Test Driving DevExpress Chat Component

Test Driving DevExpress Chat Component

If you’re a Blazor developer looking to integrate AI-powered chat functionality into your applications, the new DevExpress DxAIChat component offers a turnkey solution. It’s designed to make building chat interfaces as easy as possible, with out-of-the-box support for simple chats, virtual assistants, and even Retrieval-Augmented Generation (RAG) scenarios.

The best part? You don’t have to start from scratch—DevExpress provides a range of pre-built examples, making it easy to get started and customize to your needs. Whether you’re aiming for a basic chatbot or a more complex AI assistant, this component has you covered.

To use the examples you can use any open A.I compatible service like Ollama, Open A.I and Azure OpenAI, in current devexpress example they use Azure like this

using DevExpress.AIIntegration;
...
string azureOpenAIEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");
string deploymentName = "YourModelDeploymentName"
...
builder.Services.AddDevExpressBlazor();
builder.Services.AddDevExpressAI((config) => {
    config.RegisterChatClientOpenAIService
        new AzureOpenAIClient(
            new Uri(azureOpenAIEndpoint),
            new AzureKeyCredential(azureOpenAIKey)
        ), deploymentName);
    //or call the following method to use self-hosted Ollama models
    //config.RegisterChatClientOllamaAIService("http://localhost:11434/api/chat", "llama3.1");
});

I tested with OpenA.I  API instead of azure, so my code looks like this

string azureOpenAIEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT");
string azureOpenAIKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY");

string OpenAiKey= Environment.GetEnvironmentVariable("OpenAiTestKey");

builder.Services.AddDevExpressBlazor();
builder.Services.AddDevExpressAI((config) => {
    //var client = new AzureOpenAIClient(
    //    new Uri(azureOpenAIEndpoint),
    //    new AzureKeyCredential(azureOpenAIKey));
    //Open Ai models ID are a bit different than azure, Azure=gtp4o OpenAI=gpt-4o
    var client = new OpenAIClient(new System.ClientModel.ApiKeyCredential(OpenAiKey));
    config.RegisterChatClientOpenAIService(client, "gpt-4o");
    config.RegisterOpenAIAssistants(client, "gpt-4o");
});

 

Notice the IDs of the models in Azure and Open A.I are different

  • Azure=gtp4o
  • OpenAI=gpt-4o

This are the URLs for the different example

  • Chat : https://localhost:53340/
  • Assistant/RAG: https://localhost:53340/assistant
  • Streaming: https://localhost:53340/streaming

I’m super happy that DevExpress components are doing all the heavy lifting and boilerplate code for us, I have developed the same scenarios using semantic kernel even when there is not so much code to write you still have the challenge of develop a responsive U.I

For more information and to see the examples in action, check out the full article.

Using the IMemoryStore Interface and DevExpress XPO ORM to Implement a Custom Memory Store for Semantic Kernel

Using the IMemoryStore Interface and DevExpress XPO ORM to Implement a Custom Memory Store for Semantic Kernel

In today’s AI-driven world, the ability to quickly and efficiently store, retrieve, and manage data is crucial for developing sophisticated applications. One tool that helps facilitate this is the Semantic Kernel, a lightweight, open-source development kit designed for integrating AI models into C#, Python, or Java applications. It enables rapid enterprise-grade solutions by serving as an effective middleware.

One of the key concepts in Semantic Kernel is memory—a collection of records, each containing a timestamp, metadata, embeddings, and a key. These memory records can be stored in various ways, depending on how you implement the interfaces. This flexibility allows you to define the storage mechanism, which means you can choose any database solution that suits your needs.

In this blog post, we’ll walk through how to use the IMemoryStore interface in Semantic Kernel and implement a custom memory store using DevExpress XPO, an ORM (Object-Relational Mapping) tool that can interact with over 14 database engines with a single codebase.

Why Use DevExpress XPO ORM?

DevExpress XPO is a powerful, free-to-use ORM created by DevExpress that abstracts the complexities of database interactions. It supports a wide range of database engines such as SQL Server, MySQL, SQLite, Oracle, and many others, allowing you to write database-independent code. This is particularly helpful when dealing with a distributed or multi-environment system where different databases might be used.

By using XPO, we can seamlessly create, update, and manage memory records in various databases, making our application more flexible and scalable.

Implementing a Custom Memory Store with DevExpress XPO

To integrate XPO with Semantic Kernel’s memory management, we’ll implement a custom memory store by defining a database entry class and a database interaction class. Then, we’ll complete the process by implementing the IMemoryStore interface.

Step 1: Define a Database Entry Class

Our first step is to create a class that represents the memory record. In this case, we’ll define an XpoDatabaseEntry class that maps to a database table where memory records are stored.


public class XpoDatabaseEntry : XPLiteObject {
    private string _oid;
    private string _collection;
    private string _timestamp;
    private string _embeddingString;
    private string _metadataString;
    private string _key;

    [Key(false)]
    public string Oid { get; set; }
    public string Key { get; set; }
    public string MetadataString { get; set; }
    public string EmbeddingString { get; set; }
    public string Timestamp { get; set; }
    public string Collection { get; set; }

    protected override void OnSaving() {
        if (this.Session.IsNewObject(this)) {
            this.Oid = Guid.NewGuid().ToString();
        }
        base.OnSaving();
    }
}

This class extends XPLiteObject from the XPO library, which provides methods to manage the record lifecycle within the database.

Step 2: Create a Database Interaction Class

Next, we’ll define an XpoDatabase class to abstract the interaction with the data store. This class provides methods for creating tables, inserting, updating, and querying records.


internal sealed class XpoDatabase {
    public Task CreateTableAsync(IDataLayer conn) {
        using (Session session = new(conn)) {
            session.UpdateSchema(new[] { typeof(XpoDatabaseEntry).Assembly });
            session.CreateObjectTypeRecords(new[] { typeof(XpoDatabaseEntry).Assembly });
        }
        return Task.CompletedTask;
    }

    // Other database operations such as CreateCollectionAsync, InsertOrIgnoreAsync, etc.
}

This class acts as a bridge between Semantic Kernel and the database, allowing us to manage memory entries without having to write complex SQL queries.

Step 3: Implement the IMemoryStore Interface

Finally, we implement the IMemoryStore interface, which is responsible for defining how the memory store behaves. This includes methods like UpsertAsync, GetAsync, and DeleteCollectionAsync.


public class XpoMemoryStore : IMemoryStore, IDisposable {
    public static async Task ConnectAsync(string connectionString) {
        var memoryStore = new XpoMemoryStore(connectionString);
        await memoryStore._dbConnector.CreateTableAsync(memoryStore._dataLayer).ConfigureAwait(false);
        return memoryStore;
    }

    public async Task CreateCollectionAsync(string collectionName) {
        await this._dbConnector.CreateCollectionAsync(this._dataLayer, collectionName).ConfigureAwait(false);
    }

    // Other methods for interacting with memory records
}

The XpoMemoryStore class takes advantage of XPO’s ORM features, making it easy to create collections, store and retrieve memory records, and perform batch operations. Since Semantic Kernel doesn’t care where memory records are stored as long as the interfaces are correctly implemented, you can now store your memory records in any of the databases supported by XPO.

Advantages of Using XPO with Semantic Kernel

  • Database Independence: You can switch between multiple databases without changing your codebase.
  • Scalability: XPO’s ability to manage complex relationships and large datasets makes it ideal for enterprise-grade solutions.
  • ORM Abstraction: With XPO, you avoid writing SQL queries and focus on high-level operations like creating and updating objects.

Conclusion

In this blog post, we’ve demonstrated how to integrate DevExpress XPO ORM with the Semantic Kernel using the IMemoryStore interface. This approach allows you to store AI-driven memory records in a wide variety of databases while maintaining a flexible, scalable architecture.

In future posts, we’ll explore specific use cases and how you can leverage this memory store in real-world applications. For the complete implementation, you can check out my GitHub fork.

Stay tuned for more insights and examples!

Leveraging Memory in Semantic Kernel: The Role of Microsoft.SemanticKernel.Memory Namespace

Leveraging Memory in Semantic Kernel: The Role of Microsoft.SemanticKernel.Memory Namespace

In our continued exploration of Semantic Kernel, we shift focus towards its memory capabilities, specifically diving into the Microsoft.SemanticKernel.Memory Namespace. Here, we’ll discuss the critical components that allow for efficient memory management and how you can integrate your own custom memory stores for AI applications. One of the standout implementations within this namespace is the VolatileMemoryStore, but equally important is understanding how any class that implements IMemoryStore can serve as a backend for SemanticTextMemory.

What Is “Memory” in Semantic Kernel?

Before we dive into the technical details, let’s clarify what we mean by “memory” within the Semantic Kernel framework. When we refer to “memory,” we are not talking about RAM or the typical computer memory used to store data for a short period of time. In the context of Semantic Kernel, memory refers to a record or a unit of information, much like a piece of information you might recall from personal experience. This could be an entry stored in a memory store, which later can be retrieved, searched, or modified.

The Microsoft.SemanticKernel.Memory Namespace

This namespace contains several important classes that serve as the foundation for memory management in the kernel. These include but are not limited to:

  • MemoryRecord: The primary schema for memory storage.
  • MemoryRecordMetadata: Handles metadata associated with a memory entry.
  • SemanticTextMemory: Implements methods to save, retrieve, and search for text-based information in a memory store.
  • VolatileMemoryStore: A simple, in-memory implementation of a memory store, useful for short-term storage during runtime.
  • IMemoryStore: The interface that defines how a memory store should behave. Any class that implements this interface can act as a memory backend for SemanticTextMemory.

VolatileMemoryStore: A Simple Example

The VolatileMemoryStore is an example of a non-persistent memory store. It operates in-memory and is well-suited for temporary storage needs that do not require long-term persistence. The class implements IMemoryStore, which means that it provides all the essential methods for storing and retrieving records in the memory.

Some of its key methods include:

  • CreateCollectionAsync: Used to create a collection of records.
  • DeleteCollectionAsync: Deletes a collection from the memory.
  • UpsertAsync: Inserts or updates a memory record.
  • GetAsync: Retrieves a memory record by ID.
  • GetNearestMatchesAsync: Finds memory records that are semantically closest to the input.

Given that the VolatileMemoryStore does not offer persistence, it is primarily suited for short-lived applications. However, because it implements IMemoryStore, it can be replaced with a more persistent memory backend if required.

IMemoryStore: The Key to Custom Memory Implementations

The power of the Semantic Kernel lies in its flexibility. As long as a class implements the IMemoryStore interface, it can be used as a memory backend for the kernel’s memory management. This means that you are not limited to using the VolatileMemoryStore. Instead, you can develop your own custom memory stores by following the pattern established by this class.

For instance, if you need to store memory records in a database, or in a distributed cloud storage solution, you can implement the IMemoryStore interface and define how records should be inserted, retrieved, and managed within your custom store. Once implemented, this custom memory store can be used by the SemanticTextMemory class to manage text-based memories.

SemanticTextMemory: Bringing It All Together

At the core of managing memory in the Semantic Kernel is the SemanticTextMemory class. This class interacts with your memory store to save, retrieve, and search for text-based memory records. Whether you’re using the VolatileMemoryStore or a custom implementation of IMemoryStore, the SemanticTextMemory class serves as the interface that facilitates text-based memory operations.

Key methods include:

  • SaveInformationAsync: Saves information into the memory store, maintaining a copy of the original data.
  • SearchAsync: Allows for searching the memory based on specific criteria, such as finding semantically similar records.
  • GetCollectionsAsync: Retrieves available collections of memories from the memory store.

Why Flexible Memory Stores Matter

The flexibility provided by the IMemoryStore interface is critical because it allows developers to integrate the Semantic Kernel into a wide variety of systems, from small-scale in-memory applications to enterprise-grade solutions that require persistent storage across distributed environments. Whether you’re building an AI agent that needs to “remember” user inputs between sessions or a bot that needs to recall relevant details during an interaction, the memory system in the Semantic Kernel is built to scale with your needs.

Final Thoughts

In the world of AI, memory is a crucial component that makes AI agents more intelligent and capable of handling complex interactions. With the Microsoft.SemanticKernel.Memory Namespace, developers have a flexible, scalable solution for memory management. Whether you’re working with the in-memory VolatileMemoryStore or designing your custom memory backend, the IMemoryStore interface ensures seamless integration with the Semantic Kernel’s memory system.

By understanding the relationship between IMemoryStore, VolatileMemoryStore, and SemanticTextMemory, you can harness the full potential of the Semantic Kernel to create more sophisticated AI-driven applications.

Memory Types in Semantic Kernel

Memory Types in Semantic Kernel

Memory Types in Semantic Kernel

In the world of AI and large language models (LLMs), understanding how to manage memory is crucial for creating applications that feel responsive and intelligent. Many developers are turning to Semantic Kernel, a lightweight and open-source development kit, to integrate these capabilities into their applications. For those already familiar with Semantic Kernel, let’s dive into how memory functions within this framework, especially when interacting with LLMs via chat completions.

Chat Completions: The Most Common Interaction with LLMs

When it comes to interacting with LLMs, one of the most intuitive and widely used methods is through chat completions. This allows developers to simulate a conversation between a user and an AI agent, facilitating various use cases like building chatbots, automating business processes, or even generating code.

In Semantic Kernel, chat completions are implemented through models from popular providers like OpenAI, Google, and others. These models enable developers to manage the flow of conversation seamlessly. While using chat completions, one key aspect to keep in mind is how the conversation history is stored and managed.

Temporary Memory: ChatHistory and Kernel String Arguments

Within the Semantic Kernel framework, the memory that a chat completion model uses is managed by the ChatHistory object. This object stores the conversation history temporarily, meaning it captures the back-and-forth between the user and the model during an active session. Alternatively, you can use a string argument passed to the kernel, which contains context information for the conversation. However, like the ChatHistory, this method is also not persistent.

Once the host class is disposed of, all stored context and memory from both the ChatHistory object and the string argument are lost. This transient nature of memory means that these methods are useful only for short-term interactions and are destroyed after the session ends.

What’s Next? Exploring Long-Term Memory Options

In this article, we’ve discussed how Semantic Kernel manages short-term memory with ChatHistory and kernel string arguments. However, for more complex applications that require retaining memory over longer periods—think customer support agents or business process automation—temporary memory might not be sufficient. In the next article, we’ll explore the options available for implementing long-term memory within Semantic Kernel, providing insights on how to make your AI applications even more powerful and context-aware.

Stay tuned for the deep dive into long-term memory solutions!

El Salvador’s Technological Revolution

El Salvador’s Technological Revolution

 

El Salvador, my birthplace, has recently emerged as a focal point for technological innovation under the leadership of President Nayib Bukele. Born in Suchitoto during the civil war and now living as a digital nomad in Saint Petersburg, Russia, I have witnessed El Salvador’s transformation from a distance and feel compelled to share its story. This article is the first in a series exploring how blockchain technology, financial services, and artificial intelligence (AI) can help a small country like El Salvador grow.

 

Historical Context and Economic Challenges

 

El Salvador has faced significant economic challenges over the past few decades, including poverty, gang violence, and a heavy reliance on remittances from abroad. The economy has traditionally been rooted in agriculture, with coffee and sugar being key exports. However, President Bukele, who took office on June 1, 2019, has sought to address these challenges by diversifying the economy and embracing technology as a key driver of growth.

Bukele’s Vision for Economic Transformation

 

President Bukele’s administration has prioritized technological innovation as a catalyst for economic transformation. His vision is to modernize the country’s infrastructure and position El Salvador as a hub for technological innovation in Latin America. This vision includes the strategic shift from an agriculture-based economy to one focused on technology, financial services, and tourism. The goal is to create a more resilient and diverse economic base that can sustain long-term growth and development.

The Adoption of Bitcoin as Legal Tender

 

One of the most groundbreaking moves by Bukele’s administration was the introduction of the Bitcoin Law, passed by the Legislative Assembly on June 9, 2021. This law made Bitcoin legal tender alongside the US dollar, which had been the country’s official currency since 2001. The rationale behind this decision was multifaceted:

 

  • Financial Inclusion: With a significant portion of the population lacking access to traditional banking services, Bitcoin offers an alternative means of financial inclusion.
  • Reduction in Remittance Costs: Remittances make up a substantial part of El Salvador’s economy. Bitcoin’s adoption aims to reduce the high transaction fees associated with remittance services.
  • Economic Innovation: By adopting Bitcoin, El Salvador aims to attract foreign investment and position itself as a leader in cryptocurrency and blockchain technology.

 

The implementation of Bitcoin involved launching the Chivo Wallet, a state-sponsored digital wallet designed to facilitate Bitcoin transactions. The government also incentivized adoption by offering $30 worth of Bitcoin to citizens who registered for the wallet.

Initial Reactions and Impact

 

The reaction to the Bitcoin Law was mixed. While some praised the move as innovative and forward-thinking, others raised concerns about the volatility of Bitcoin and its potential impact on the economy. Despite these concerns, the Bukele administration has remained committed to its Bitcoin strategy, continuing to invest in Bitcoin and integrate it into the national economy.

Digital Transformation Initiatives

I

n addition to Bitcoin adoption, El Salvador has partnered with global tech giants like Google to enhance its digital infrastructure. These partnerships aim to modernize government services, improve healthcare through telemedicine platforms, and revolutionize education by integrating AI-driven tools. For instance, Google’s collaboration with the Salvadoran government includes training government agencies on cloud technologies and developing platforms that allow interoperability between institutions.

Strategic Shift to Technology, Financial Services, and Tourism

 

President Bukele’s broader economic strategy involves shifting El Salvador’s economic focus from traditional agriculture to more dynamic and sustainable sectors like technology, financial services, and tourism. This shift aims to create high-value jobs, attract foreign investment, and build a more diversified economy.

 

  • Technology: By investing in digital infrastructure and fostering a favorable environment for tech startups, El Salvador aims to become a regional tech hub.
  • Financial Services: The adoption of Bitcoin and other fintech innovations is intended to transform the financial landscape, making it more inclusive and efficient.
  • Tourism: Enhancing the country’s tourism sector, with initiatives to promote its natural beauty and cultural heritage, is another key pillar of Bukele’s economic strategy.

Conclusion and Future Prospects

 

El Salvador’s journey towards becoming a technological leader in Latin America is a testament to the transformative power of visionary leadership and innovative policies. Under President Bukele, the country has taken bold steps to embrace technology, from adopting Bitcoin to integrating AI into public services. This series of articles will delve deeper into these initiatives, exploring their impact, challenges, and the future prospects for El Salvador in the global technological landscape.

By understanding El Salvador’s technological revolution, we can gain insights into the potential for other nations to leverage technology for economic and social development. The next article in this series will focus on the detailed implementation of Bitcoin as legal tender, examining the steps taken by the Bukele administration and the outcomes observed so far.

This introductory article sets the stage for a comprehensive exploration of El Salvador’s technological transformation under President Bukele. The subsequent articles will provide in-depth analyses and propose potential AI legislation to ensure the country’s continued leadership in technology within Latin America.

A New Era of Computing: AI-Powered Devices Over Form Factor Innovations

A New Era of Computing: AI-Powered Devices Over Form Factor Innovations

A New Era of Computing: AI-Powered Devices Over Form Factor Innovations

In a recent Microsoft event, the spotlight was on a transformative innovation that highlights the power of AI over the constant pursuit of new device form factors. The unveiling of the new Surface computer, equipped with a Neural Processing Unit (NPU), demonstrates that enhancing existing devices with AI capabilities is more impactful than creating entirely new device types.

The Microsoft Event: Revolutionizing with AI

Microsoft showcased the new Surface computer, integrating an NPU that enhances performance by enabling real-time processing of AI algorithms on the device. This approach allows for advanced capabilities like enhanced voice recognition, real-time language translation, and sophisticated image processing, without relying on cloud services.

Why AI Integration Trumps New Form Factors

For years, the tech industry has focused on new device types, from tablets to foldable screens, often addressing problems that didn’t exist. However, the true advancement lies in making existing devices smarter. AI integration offers:

  • Enhanced Productivity: Automating repetitive tasks and providing intelligent suggestions, allowing users to focus on more complex and creative work.
  • Personalized Experience: Devices learn and adapt to user preferences, offering a highly customized experience.
  • Advanced Capabilities: NPUs enable local processing of complex AI models, reducing latency and dependency on the cloud.
  • Seamless Integration: AI creates a cohesive and efficient workflow across various applications and services.

Comparing to Humane Pin and Rabbit AI Devices

While devices like the Humane Pin and Rabbit AI offer innovative new form factors, they often rely heavily on cloud connectivity for AI functions. In contrast, the Surface’s NPU allows for faster, more secure local processing. This means tasks are completed quicker and more securely, as data doesn’t need to be sent to the cloud.

Conclusion: Embracing AI-Driven Innovation

Microsoft’s AI-enhanced Surface computer signifies a shift towards intelligent augmentation rather than just physical redesign. By embedding AI within existing devices, we unlock new potentials for efficiency, personalization, and functionality, setting a new standard for future tech innovations. This approach not only makes interactions with technology smarter and more intuitive but also emphasizes the importance of on-device processing power for a faster and more secure user experience.

For more information and to pre-order the new Surface laptops, visit Microsoft’s official store.