Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,89 +1,22 @@
import { Component, computed } from '@angular/core';
import { LegacyChatComponent } from '@cacheplane/chat';
import { Component } from '@angular/core';
import { ChatComponent } from '@cacheplane/chat';
import { streamResource } from '@cacheplane/stream-resource';
import { environment } from '../environments/environment';

interface ToolCallEntry {
name: string;
args: string;
result?: string;
}

/**
* FilesystemComponent demonstrates agent file operations.
*
* The agent can read and write files using tool calls. The sidebar
* shows a real-time log of each file operation as it happens.
*
* Key integration points:
* - `stream.messages()` contains all messages including tool call results
* - `computed()` derives tool call entries from AI messages
* - Tool calls update reactively as the agent performs file operations
* The agent can read and write files using tool calls.
*/
@Component({
selector: 'app-filesystem',
standalone: true,
imports: [LegacyChatComponent],
template: `
<cp-chat
[messages]="stream.messages()"
[isLoading]="stream.isLoading()"
[error]="stream.error()"
(sendMessage)="send($event)">
<ng-template #sidebar>
<h3 style="font-size: 0.8rem; font-weight: 600; margin-bottom: 0.75rem; color: #1a1a2e;">File Operations</h3>
@for (entry of toolCallEntries(); track $index) {
<div style="display: flex; align-items: flex-start; gap: 8px; padding: 6px 0; font-size: 0.8rem; border-bottom: 1px solid #e5e7eb;">
<span style="flex-shrink: 0; font-size: 1rem; line-height: 1.2;">
{{ entry.name === 'read_file' ? '📖' : '✏️' }}
</span>
<div style="min-width: 0;">
<div style="font-weight: 500; color: #1a1a2e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
{{ getFilePath(entry.args) }}
</div>
<div style="color: #8b8fa3; font-size: 0.75rem; margin-top: 2px;">
{{ entry.name === 'read_file' ? 'read' : 'write' }}
{{ entry.result ? ' · done' : ' · running…' }}
</div>
</div>
</div>
}
@empty {
<p style="color: #8b8fa3; font-size: 0.8rem;">Ask the agent to read or write a file.</p>
}
</ng-template>
</cp-chat>
`,
imports: [ChatComponent],
template: `<chat [ref]="stream" class="block h-screen" />`,
})
export class FilesystemComponent {
protected readonly stream = streamResource({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});

toolCallEntries = computed(() => {
const msg = this.stream.messages();
const calls: ToolCallEntry[] = [];
for (const m of msg) {
if ((m as any).tool_calls) {
for (const tc of (m as any).tool_calls) {
calls.push({ name: tc.name, args: JSON.stringify(tc.args), result: tc.output });
}
}
}
return calls;
});

getFilePath(args: string): string {
try {
const parsed = JSON.parse(args);
return parsed.path ?? args;
} catch {
return args;
}
}

send(text: string): void {
this.stream.submit({ messages: [{ role: 'human', content: text }] });
}
}
1 change: 1 addition & 0 deletions cockpit/deep-agents/filesystem/angular/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "../../../../../libs/design-tokens/src/lib/tokens.css";
@import "tailwindcss";
@source "../../../../../libs/chat/src/";

@theme {
--color-bg: var(--ds-bg);
Expand Down
44 changes: 5 additions & 39 deletions cockpit/deep-agents/memory/angular/src/app/memory.component.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,23 @@
import { Component, computed } from '@angular/core';
import { LegacyChatComponent } from '@cacheplane/chat';
import { Component } from '@angular/core';
import { ChatComponent } from '@cacheplane/chat';
import { streamResource } from '@cacheplane/stream-resource';
import { environment } from '../environments/environment';

/**
* MemoryComponent demonstrates persistent agent memory across sessions.
*
* The agent extracts facts about the user from each conversation turn
* and stores them in `agent_memory` state. The sidebar shows all learned
* facts in real time as the agent updates its memory.
*
* Key integration points:
* - `stream.value()` contains the agent state including `agent_memory`
* - `computed()` derives key/value pairs for the sidebar
* - Memory entries update reactively as the agent learns new facts
* and stores them in `agent_memory` state.
*/
@Component({
selector: 'app-da-memory',
standalone: true,
imports: [LegacyChatComponent],
template: `
<cp-chat
[messages]="stream.messages()"
[isLoading]="stream.isLoading()"
[error]="stream.error()"
(sendMessage)="send($event)">
<ng-template #sidebar>
<h3 style="font-size: 0.8rem; font-weight: 600; margin-bottom: 0.75rem; color: #1a1a2e;">Learned Facts</h3>
@for (entry of memoryEntries(); track entry[0]) {
<div style="padding: 6px 0; font-size: 0.8rem; border-bottom: 1px solid #e5e7eb;">
<div style="font-weight: 600; color: #1a1a2e; margin-bottom: 2px;">{{ entry[0] }}</div>
<div style="color: #555770;">{{ entry[1] }}</div>
</div>
}
@empty {
<p style="color: #8b8fa3; font-size: 0.8rem;">Tell the agent something about yourself to see it remember.</p>
}
</ng-template>
</cp-chat>
`,
imports: [ChatComponent],
template: `<chat [ref]="stream" class="block h-screen" />`,
})
export class MemoryComponent {
protected readonly stream = streamResource({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});

memoryEntries = computed(() => {
const val = this.stream.value() as { agent_memory?: Record<string, string> } | undefined;
return Object.entries(val?.agent_memory ?? {});
});

send(text: string): void {
this.stream.submit({ messages: [{ role: 'human', content: text }] });
}
}
1 change: 1 addition & 0 deletions cockpit/deep-agents/memory/angular/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "../../../../../libs/design-tokens/src/lib/tokens.css";
@import "tailwindcss";
@source "../../../../../libs/chat/src/";

@theme {
--color-bg: var(--ds-bg);
Expand Down
52 changes: 5 additions & 47 deletions cockpit/deep-agents/planning/angular/src/app/planning.component.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,23 @@
import { Component, computed } from '@angular/core';
import { LegacyChatComponent } from '@cacheplane/chat';
import { Component } from '@angular/core';
import { ChatComponent } from '@cacheplane/chat';
import { streamResource } from '@cacheplane/stream-resource';
import { environment } from '../environments/environment';

interface PlanStep {
title: string;
status: 'pending' | 'running' | 'complete';
}

/**
* PlanningComponent demonstrates agent task decomposition.
*
* The agent receives a complex task, breaks it into ordered steps,
* and executes them. The sidebar shows each step's status in real time.
*
* Key integration points:
* - `stream.value()` contains the plan state with step list
* - `computed()` derives the plan steps for the sidebar
* - Steps update reactively as the agent works through them
* and executes them sequentially.
*/
@Component({
selector: 'app-planning',
standalone: true,
imports: [LegacyChatComponent],
template: `
<cp-chat
[messages]="stream.messages()"
[isLoading]="stream.isLoading()"
[error]="stream.error()"
(sendMessage)="send($event)">
<ng-template #sidebar>
<h3 style="font-size: 0.8rem; font-weight: 600; margin-bottom: 0.75rem; color: #1a1a2e;">Task Plan</h3>
@for (step of planSteps(); track $index) {
<div style="display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 0.8rem;">
<span style="width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;"
[style.background]="step.status === 'complete' ? '#10b981' : step.status === 'running' ? '#004090' : '#d1d5db'"></span>
<span [style.color]="step.status === 'complete' ? '#555770' : '#1a1a2e'"
[style.textDecoration]="step.status === 'complete' ? 'line-through' : 'none'">
{{ step.title }}
</span>
</div>
}
@empty {
<p style="color: #8b8fa3; font-size: 0.8rem;">Ask a complex question to see the plan.</p>
}
</ng-template>
</cp-chat>
`,
imports: [ChatComponent],
template: `<chat [ref]="stream" class="block h-screen" />`,
})
export class PlanningComponent {
protected readonly stream = streamResource({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});

planSteps = computed(() => {
const val = this.stream.value() as { plan?: PlanStep[] } | undefined;
return val?.plan ?? [];
});

send(text: string): void {
this.stream.submit({ messages: [{ role: 'human', content: text }] });
}
}
1 change: 1 addition & 0 deletions cockpit/deep-agents/planning/angular/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "../../../../../libs/design-tokens/src/lib/tokens.css";
@import "tailwindcss";
@source "../../../../../libs/chat/src/";

@theme {
--color-bg: var(--ds-bg);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,96 +1,23 @@
import { Component, computed } from '@angular/core';
import { LegacyChatComponent } from '@cacheplane/chat';
import { Component } from '@angular/core';
import { ChatComponent } from '@cacheplane/chat';
import { streamResource } from '@cacheplane/stream-resource';
import { environment } from '../environments/environment';

interface ExecutionLog {
code: string;
stdout: string;
exitStatus: number;
}

/**
* SandboxesComponent demonstrates a coding agent that executes Python code.
*
* The agent writes and runs code snippets to solve problems using a
* `run_code` tool. The sidebar shows execution logs — code input, stdout
* output, and exit status — for each sandbox execution.
*
* Key integration points:
* - `stream.messages()` contains all messages including tool call results
* - `computed()` derives execution log entries from tool calls in AI messages
* - Logs update reactively as the agent writes and runs code
* `run_code` tool.
*/
@Component({
selector: 'app-sandboxes',
standalone: true,
imports: [LegacyChatComponent],
template: `
<cp-chat
[messages]="stream.messages()"
[isLoading]="stream.isLoading()"
[error]="stream.error()"
(sendMessage)="send($event)">
<ng-template #sidebar>
<h3 style="font-size: 0.8rem; font-weight: 600; margin-bottom: 0.75rem; color: #1a1a2e;">Execution Logs</h3>
@for (log of executionLogs(); track $index) {
<div style="padding: 8px; margin-bottom: 8px; border: 1px solid #e5e7eb; border-radius: 6px; font-size: 0.8rem;">
<div style="display: flex; align-items: center; gap: 6px; margin-bottom: 6px;">
<span style="display: inline-block; padding: 2px 6px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; font-family: monospace;"
[style.background]="log.exitStatus === 0 ? '#d1fae5' : '#fee2e2'"
[style.color]="log.exitStatus === 0 ? '#065f46' : '#991b1b'">
exit {{ log.exitStatus }}
</span>
</div>
<div style="background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 4px; padding: 6px; margin-bottom: 6px; font-family: monospace; font-size: 0.75rem; color: #1a1a2e; white-space: pre-wrap; word-break: break-all;">{{ log.code }}</div>
@if (log.stdout) {
<div style="font-size: 0.7rem; font-weight: 600; color: #6b7280; margin-bottom: 2px; text-transform: uppercase; letter-spacing: 0.04em;">stdout</div>
<div style="background: #f0fdf4; border: 1px solid #bbf7d0; border-radius: 4px; padding: 6px; font-family: monospace; font-size: 0.75rem; color: #166534; white-space: pre-wrap; word-break: break-all;">{{ log.stdout }}</div>
}
</div>
}
@empty {
<p style="color: #8b8fa3; font-size: 0.8rem;">Ask the agent to write and run Python code.</p>
}
</ng-template>
</cp-chat>
`,
imports: [ChatComponent],
template: `<chat [ref]="stream" class="block h-screen" />`,
})
export class SandboxesComponent {
protected readonly stream = streamResource({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});

executionLogs = computed(() => {
const msgs = this.stream.messages();
const logs: ExecutionLog[] = [];
for (const m of msgs) {
if ((m as any).tool_calls) {
for (const tc of (m as any).tool_calls) {
if (tc.name === 'run_code' && tc.output) {
try {
const parsed = JSON.parse(tc.output);
logs.push({
code: tc.args?.code ?? '',
stdout: parsed.stdout ?? '',
exitStatus: parsed.exit_status ?? 0,
});
} catch {
logs.push({
code: tc.args?.code ?? '',
stdout: tc.output,
exitStatus: 0,
});
}
}
}
}
}
return logs;
});

send(text: string): void {
this.stream.submit({ messages: [{ role: 'human', content: text }] });
}
}
1 change: 1 addition & 0 deletions cockpit/deep-agents/sandboxes/angular/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import "../../../../../libs/design-tokens/src/lib/tokens.css";
@import "tailwindcss";
@source "../../../../../libs/chat/src/";

@theme {
--color-bg: var(--ds-bg);
Expand Down
Loading