import { Directive, Input, OnInit, OnChanges, OnDestroy, SimpleChanges, Inject, } from "@angular/core"; import { CopilotKit } from "../copilotkit"; import type { Context } from "@ag-ui/client"; /** * Directive to manage agent context in CopilotKit. * Automatically adds context on init, updates on changes, and removes on destroy. * * @example * ```html * *
*
* * *
*
* * *
*
* ``` */ @Directive({ selector: "[copilotkitAgentContext]", standalone: true, }) export class CopilotKitAgentContext implements OnInit, OnChanges, OnDestroy { private contextId?: string; constructor(@Inject(CopilotKit) private readonly copilotkit: CopilotKit) {} /** * Context object containing both description and value. * If provided, this takes precedence over individual inputs. */ @Input("copilotkitAgentContext") context?: Context; /** * Description of the context. * Used when context object is not provided. */ @Input() description?: string; /** * Value of the context. * Used when context object is not provided. */ @Input() value?: any; ngOnInit(): void { this.addContext(); } ngOnChanges(changes: SimpleChanges): void { // Check if any relevant input has changed const hasContextChange = "context" in changes; const hasDescriptionChange = "description" in changes; const hasValueChange = "value" in changes; if (hasContextChange || hasDescriptionChange || hasValueChange) { // Skip the first change as ngOnInit handles initial setup if (this.contextId) { this.updateContext(); } } } ngOnDestroy(): void { this.removeContext(); } /** * Adds the context to CopilotKit */ private addContext(): void { const contextToAdd = this.getContext(); if (contextToAdd) { this.contextId = this.copilotkit.core.addContext(contextToAdd); } } /** * Updates the context by removing the old one and adding a new one */ private updateContext(): void { this.removeContext(); this.addContext(); } /** * Removes the current context from CopilotKit */ private removeContext(): void { if (this.contextId) { this.copilotkit.core.removeContext(this.contextId); this.contextId = undefined; } } /** * Gets the context object from inputs */ private getContext(): Context | null { // If context object is provided, use it if (this.context) { return this.context; } // Otherwise, build from individual inputs // Note: null is a valid value, but undefined means not set if (this.description !== undefined && this.value !== undefined) { return { description: this.description, value: this.value, }; } return null; } }