diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 528a7fb40..aa1113a2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: node-version: 22 cache: npm - run: npm ci - - run: npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.stream-resource.dev --dry-run + - run: npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.cacheplane.ai --dry-run mcp: name: MCP — build / smoke @@ -239,7 +239,7 @@ jobs: if: steps.affected.outputs.website == 'true' run: npx nx e2e website --skip-nx-cache env: - BASE_URL: https://stream-resource.dev + BASE_URL: https://cacheplane.ai - name: Prepare cockpit Vercel project if: steps.affected.outputs.cockpit == 'true' run: | @@ -259,7 +259,7 @@ jobs: - name: Verify deployed cockpit if: steps.affected.outputs.cockpit == 'true' run: | - npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.stream-resource.dev --retries 20 --retry-delay-ms 5000 + npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.cacheplane.ai --retries 20 --retry-delay-ms 5000 # ── Angular examples deploy ────────────────────────────────────────── - name: Check if examples changed @@ -314,6 +314,6 @@ jobs: - name: Run production smoke tests run: npx playwright test apps/cockpit/e2e/production-smoke.spec.ts --reporter=list env: - BASE_URL: https://cockpit.stream-resource.dev - EXAMPLES_URL: https://examples.stream-resource.dev + BASE_URL: https://cockpit.cacheplane.ai + EXAMPLES_URL: https://examples.cacheplane.ai OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} diff --git a/COMMERCIAL.md b/COMMERCIAL.md index 7fe244ca5..8ab6900dd 100644 --- a/COMMERCIAL.md +++ b/COMMERCIAL.md @@ -23,7 +23,7 @@ Any use in a for-profit product, service, or organization requires a paid commer ## Purchase or inquire -- Website: https://stream-resource.dev/pricing +- Website: https://cacheplane.ai/pricing - Email: hello@cacheplane.ai See [`LICENSE-COMMERCIAL`](./LICENSE-COMMERCIAL) for the full commercial license terms. diff --git a/README.md b/README.md index 1ef81f2df..0452fc388 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Angular Agent Framework — The Enterprise Streaming Resource for LangChain and Angular @@ -17,7 +17,7 @@ License: PolyForm Noncommercial + Commercial - + Angular 20+ @@ -110,7 +110,7 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp

Angular Agent Framework architecture: Angular Component → agent() → StreamManager Bridge → LangGraph Platform, with signals returned reactively @@ -129,17 +129,17 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp | **Application Deployment** | $2,000 / app | One-time per application — covers dev, staging, and prod | | **Enterprise** | Custom | Volume licensing, priority support, custom contract | -[Full pricing details and license terms →](https://stream-resource.dev/pricing) +[Full pricing details and license terms →](https://cacheplane.ai/pricing) --- ## Documentation -- [Getting Started](https://stream-resource.dev/docs/getting-started) -- [API Reference](https://stream-resource.dev/api-reference) -- [Testing with MockAgentTransport](https://stream-resource.dev/docs/testing) -- [Human-in-the-Loop / Interrupts](https://stream-resource.dev/docs/interrupts) -- [Subagent Streaming](https://stream-resource.dev/docs/subagents) +- [Getting Started](https://cacheplane.ai/docs/getting-started) +- [API Reference](https://cacheplane.ai/api-reference) +- [Testing with MockAgentTransport](https://cacheplane.ai/docs/testing) +- [Human-in-the-Loop / Interrupts](https://cacheplane.ai/docs/interrupts) +- [Subagent Streaming](https://cacheplane.ai/docs/subagents) --- @@ -150,4 +150,4 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp - **PolyForm Noncommercial 1.0.0** — free for noncommercial use (personal projects, academic, research, non-profit internal tooling). See [`LICENSE`](./LICENSE). - **Angular Agent Framework Commercial License** — required for any for-profit or revenue-generating use. See [`LICENSE-COMMERCIAL`](./LICENSE-COMMERCIAL) and [`COMMERCIAL.md`](./COMMERCIAL.md). -This is **not** an open-source license. Commercial use — including use in a for-profit product, service, or organization — requires a paid commercial license. See [pricing](https://stream-resource.dev/pricing). +This is **not** an open-source license. Commercial use — including use in a for-profit product, service, or organization — requires a paid commercial license. See [pricing](https://cacheplane.ai/pricing). diff --git a/apps/cockpit/e2e/production-smoke.spec.ts b/apps/cockpit/e2e/production-smoke.spec.ts index 7f00dbad9..fd78774e3 100644 --- a/apps/cockpit/e2e/production-smoke.spec.ts +++ b/apps/cockpit/e2e/production-smoke.spec.ts @@ -4,16 +4,16 @@ import { expect, test } from '@playwright/test'; * Production smoke test — verifies the deployed stack works end-to-end. * * Requires: - * EXAMPLES_URL - e.g., https://examples.stream-resource.dev + * EXAMPLES_URL - e.g., https://examples.cacheplane.ai * OPENAI_API_KEY - for send/receive tests (optional) * * Run: - * BASE_URL=https://cockpit.stream-resource.dev \ - * EXAMPLES_URL=https://examples.stream-resource.dev \ + * BASE_URL=https://cockpit.cacheplane.ai \ + * EXAMPLES_URL=https://examples.cacheplane.ai \ * npx playwright test apps/cockpit/e2e/production-smoke.spec.ts */ -const EXAMPLES_URL = process.env['EXAMPLES_URL'] ?? 'https://examples.stream-resource.dev'; +const EXAMPLES_URL = process.env['EXAMPLES_URL'] ?? 'https://examples.cacheplane.ai'; const CAPABILITIES = [ 'langgraph/streaming', diff --git a/apps/cockpit/scripts/deploy-smoke.spec.ts b/apps/cockpit/scripts/deploy-smoke.spec.ts index b00c951a8..9c1720157 100644 --- a/apps/cockpit/scripts/deploy-smoke.spec.ts +++ b/apps/cockpit/scripts/deploy-smoke.spec.ts @@ -6,7 +6,7 @@ describe('deploy smoke helper', () => { expect( parseDeploySmokeArgs([ '--url', - 'https://cockpit.stream-resource.dev', + 'https://cockpit.cacheplane.ai', '--dry-run', '--retries', '5', @@ -14,7 +14,7 @@ describe('deploy smoke helper', () => { '1000', ]) ).toEqual({ - url: 'https://cockpit.stream-resource.dev', + url: 'https://cockpit.cacheplane.ai', expectedTitle: 'Cockpit', dryRun: true, retries: 5, @@ -25,11 +25,11 @@ describe('deploy smoke helper', () => { it('formats dry-run output without performing a network request', async () => { await expect( runDeploySmoke({ - url: 'https://cockpit.stream-resource.dev', + url: 'https://cockpit.cacheplane.ai', expectedTitle: 'Cockpit', dryRun: true, }) - ).resolves.toBe('dry-run:https://cockpit.stream-resource.dev:Cockpit'); + ).resolves.toBe('dry-run:https://cockpit.cacheplane.ai:Cockpit'); }); it('retries until the deployment responds with the expected title', async () => { @@ -46,13 +46,13 @@ describe('deploy smoke helper', () => { await expect( runDeploySmoke({ - url: 'https://cockpit.stream-resource.dev', + url: 'https://cockpit.cacheplane.ai', retries: 1, retryDelayMs: 1, fetchImpl, sleep, }) - ).resolves.toBe('pass:https://cockpit.stream-resource.dev:Cockpit'); + ).resolves.toBe('pass:https://cockpit.cacheplane.ai:Cockpit'); expect(fetchImpl).toHaveBeenCalledTimes(2); expect(sleep).toHaveBeenCalledTimes(1); diff --git a/apps/cockpit/src/lib/content-bundle.spec.ts b/apps/cockpit/src/lib/content-bundle.spec.ts index 6de2f442f..1e61d58a9 100644 --- a/apps/cockpit/src/lib/content-bundle.spec.ts +++ b/apps/cockpit/src/lib/content-bundle.spec.ts @@ -28,10 +28,10 @@ describe('resolveRuntimeUrl', () => { }); it('uses NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL when set', () => { - vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.stream-resource.dev'); + vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.cacheplane.ai'); expect( resolveRuntimeUrl({ runtimeUrl: 'langgraph/streaming', devPort: 4300 }) - ).toBe('https://examples.stream-resource.dev/langgraph/streaming'); + ).toBe('https://examples.cacheplane.ai/langgraph/streaming'); }); it('falls back to localhost with devPort when no env var is set', () => { @@ -49,7 +49,7 @@ describe('resolveRuntimeUrl', () => { }); it('returns null when runtimeUrl is undefined even with env var set', () => { - vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.stream-resource.dev'); + vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.cacheplane.ai'); expect( resolveRuntimeUrl({ runtimeUrl: undefined, devPort: undefined }) ).toBeNull(); diff --git a/apps/website/content/docs/render/api/views.mdx b/apps/website/content/docs/render/api/views.mdx new file mode 100644 index 000000000..9e88f82fc --- /dev/null +++ b/apps/website/content/docs/render/api/views.mdx @@ -0,0 +1,135 @@ +--- +title: views() +description: Create and compose view registries for generative UI rendering +--- + +# views() + +Creates an immutable view registry mapping names to Angular components. Views are rendered inline in the chat when the agent produces a JSON spec. + +## Usage + +```typescript +import { views } from '@cacheplane/render'; + +const ui = views({ + 'plan-checklist': PlanChecklistComponent, + 'file-preview': FilePreviewComponent, + 'code-output': CodeOutputComponent, +}); +``` + +Pass to the chat component: + +```html + +``` + +Or provide globally via DI: + +```typescript +import { provideViews } from '@cacheplane/render'; + +// app.config.ts +providers: [provideViews(ui)] +``` + +## Composition + +Compose registries via object spread. Last key wins for overrides: + +```typescript +const all = views({ + ...thirdPartyViews, + ...myViews, + 'chart': MyCustomChart, // overrides thirdPartyViews['chart'] +}); +``` + +## API + +### `views(map)` + +Creates a frozen `ViewRegistry` from a `Record>`. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `map` | `Record>` | Name → Angular component mapping | +| **Returns** | `ViewRegistry` | Frozen immutable registry | + +### `withViews(base, additions)` + +Adds new views without overwriting existing entries. Existing keys in `base` are preserved. + +```typescript +const extended = withViews(base, { + 'new-widget': NewWidget, // added + 'existing': Other, // IGNORED — base already has 'existing' +}); +``` + +### `withoutViews(base, ...names)` + +Removes views by name: + +```typescript +const restricted = withoutViews(base, 'dangerous-widget', 'internal-tool'); +``` + +### `provideViews(registry)` + +Angular DI provider. Works at app level or route level: + +```typescript +// Global +providers: [provideViews(ui)] + +// Route-scoped +{ path: 'planning', providers: [provideViews(planningViews)] } +``` + +### `toRenderRegistry(registry)` + +Converts a `ViewRegistry` to the low-level `AngularRegistry` type used by ``. Called internally by the chat component — most developers won't need this. + +## View Components + +View components are standard Angular standalone components. They receive props as `input()` signals: + +```typescript +@Component({ + selector: 'plan-checklist', + standalone: true, + template: ` +

+

{{ title() }}

+ +
+ `, +}) +export class PlanChecklistComponent { + readonly title = input('Plan'); +} +``` + +## How Specs Are Detected + +The chat component checks each message for a `ui` field containing a valid spec: + +```json +{ + "type": "tool", + "content": "...", + "ui": { + "root": "plan", + "elements": { + "plan": { + "type": "plan-checklist", + "props": { "title": "My Plan" } + } + } + } +} +``` + +The `type` in the spec is matched against the view registry to resolve the Angular component. diff --git a/apps/website/emails/drip-whitepaper-followup.ts b/apps/website/emails/drip-whitepaper-followup.ts index dc45d4e91..da4b05e57 100644 --- a/apps/website/emails/drip-whitepaper-followup.ts +++ b/apps/website/emails/drip-whitepaper-followup.ts @@ -9,7 +9,7 @@ export function dripWhitepaperFollowupHtml(day: number): { subject: string; html

Whitepaper Follow-up

Did you get a chance to read Chapter 3?

Chapter 3 covers tool-call rendering — how to surface agent actions as real UI instead of raw JSON. It's the chapter most teams bookmark first.

-
Read the Guide → + Read the Guide → `, showUnsubscribe: true, }), @@ -24,7 +24,7 @@ export function dripWhitepaperFollowupHtml(day: number): { subject: string; html

Production Readiness

The gap between demo and production

Half of GenAI projects die after proof of concept. The gap isn't the model — it's the frontend production path: streaming state, thread persistence, human approval flows, and deterministic testing.

- See How It Works → + See How It Works → `, showUnsubscribe: true, }), @@ -44,7 +44,7 @@ export function dripWhitepaperFollowupHtml(day: number): { subject: string; html

Month 1 · First agent in staging

Month 3 · Production deployment

- Learn About the Pilot → + Learn About the Pilot → `, showUnsubscribe: true, }), diff --git a/apps/website/emails/email-wrapper.ts b/apps/website/emails/email-wrapper.ts index 77bb9d1eb..b12324734 100644 --- a/apps/website/emails/email-wrapper.ts +++ b/apps/website/emails/email-wrapper.ts @@ -16,7 +16,7 @@ export function wrapEmail(opts: { ${opts.body}

Angular Agent Framework — Signal-native streaming for LangGraph.

- ${opts.showUnsubscribe ? '

Unsubscribe

' : ''} + ${opts.showUnsubscribe ? '

Unsubscribe

' : ''}
diff --git a/apps/website/emails/newsletter-welcome.ts b/apps/website/emails/newsletter-welcome.ts index f8701ba05..08c7624ac 100644 --- a/apps/website/emails/newsletter-welcome.ts +++ b/apps/website/emails/newsletter-welcome.ts @@ -5,7 +5,7 @@ export function newsletterWelcomeHtml(): string { body: `

Welcome to Angular Agent Framework updates

You'll receive updates on new capabilities, production patterns, and Angular agent best practices. We keep it focused and infrequent — no spam.

- Explore the Docs + Explore the Docs `, }); } diff --git a/apps/website/emails/whitepaper-download.ts b/apps/website/emails/whitepaper-download.ts index 4c0141b40..5a1978fe9 100644 --- a/apps/website/emails/whitepaper-download.ts +++ b/apps/website/emails/whitepaper-download.ts @@ -1,6 +1,6 @@ import { wrapEmail, esc } from './email-wrapper'; -const DOWNLOAD_URL = 'https://stream-resource.dev/whitepaper.pdf'; +const DOWNLOAD_URL = 'https://cacheplane.ai/whitepaper.pdf'; export function whitepaperDownloadHtml(name?: string): string { return wrapEmail({ diff --git a/apps/website/public/AGENTS.md b/apps/website/public/AGENTS.md index 7e9ff976a..1ed806f13 100644 --- a/apps/website/public/AGENTS.md +++ b/apps/website/public/AGENTS.md @@ -41,4 +41,4 @@ Add to ~/.claude/settings.json: {"mcpServers":{"angular":{"command":"npx","args":["@angular/mcp"]}}} ## Version check -If this file is stale, fetch the latest: https://stream-resource.dev/llms-full.txt +If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt diff --git a/apps/website/public/CLAUDE.md b/apps/website/public/CLAUDE.md index 7e9ff976a..1ed806f13 100644 --- a/apps/website/public/CLAUDE.md +++ b/apps/website/public/CLAUDE.md @@ -41,4 +41,4 @@ Add to ~/.claude/settings.json: {"mcpServers":{"angular":{"command":"npx","args":["@angular/mcp"]}}} ## Version check -If this file is stale, fetch the latest: https://stream-resource.dev/llms-full.txt +If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt diff --git a/apps/website/src/app/llms.txt/route.ts b/apps/website/src/app/llms.txt/route.ts index de348aac3..6068ea8ef 100644 --- a/apps/website/src/app/llms.txt/route.ts +++ b/apps/website/src/app/llms.txt/route.ts @@ -31,7 +31,7 @@ function buildLlmsTxt(): string { 'npx @cacheplane/angular-mcp', '', '## Full reference', - 'https://stream-resource.dev/llms-full.txt', + 'https://cacheplane.ai/llms-full.txt', ].join('\n'); } diff --git a/apps/website/src/components/shared/Footer.tsx b/apps/website/src/components/shared/Footer.tsx index 8e051eace..d26c3646a 100644 --- a/apps/website/src/components/shared/Footer.tsx +++ b/apps/website/src/components/shared/Footer.tsx @@ -146,7 +146,7 @@ export function Footer() { onMouseLeave={(e) => (e.currentTarget.style.color = tokens.colors.textSecondary)}> API Reference - (e.currentTarget.style.color = tokens.colors.accent)} onMouseLeave={(e) => (e.currentTarget.style.color = tokens.colors.textSecondary)}> Examples diff --git a/apps/website/src/components/shared/Nav.tsx b/apps/website/src/components/shared/Nav.tsx index fe44fbe19..813e8cd1e 100644 --- a/apps/website/src/components/shared/Nav.tsx +++ b/apps/website/src/components/shared/Nav.tsx @@ -7,7 +7,7 @@ const links = [ { label: 'Pilot to Prod', href: '/pilot-to-prod', external: false }, { label: 'Docs', href: '/docs', external: false }, { label: 'API', href: '/docs/agent/api/agent', external: false }, - { label: 'Examples', href: 'https://cockpit.stream-resource.dev', external: true }, + { label: 'Examples', href: 'https://cockpit.cacheplane.ai', external: true }, { label: 'Pricing', href: '/pricing', external: false }, ]; diff --git a/cockpit/deep-agents/filesystem/angular/src/app/filesystem.component.ts b/cockpit/deep-agents/filesystem/angular/src/app/filesystem.component.ts index 699ec60fb..70f6eb4d4 100644 --- a/cockpit/deep-agents/filesystem/angular/src/app/filesystem.component.ts +++ b/cockpit/deep-agents/filesystem/angular/src/app/filesystem.component.ts @@ -1,7 +1,9 @@ import { Component, computed } from '@angular/core'; -import { ChatComponent } from '@cacheplane/chat'; +import { ChatComponent, views } from '@cacheplane/chat'; +import { signalStateStore } from '@cacheplane/render'; import { agent } from '@cacheplane/angular'; import { environment } from '../environments/environment'; +import { FilePreviewComponent } from './views/file-preview.component'; /** * Represents a file operation extracted from agent tool calls. @@ -30,7 +32,7 @@ interface FileOperation { imports: [ChatComponent], template: `
- +
+ `, +}) +export class FilePreviewComponent { + readonly path = input(''); + readonly content = input(''); + readonly size = input(''); +} diff --git a/cockpit/deep-agents/planning/angular/src/app/planning.component.ts b/cockpit/deep-agents/planning/angular/src/app/planning.component.ts index 4678db670..669d7d2cf 100644 --- a/cockpit/deep-agents/planning/angular/src/app/planning.component.ts +++ b/cockpit/deep-agents/planning/angular/src/app/planning.component.ts @@ -1,89 +1,27 @@ -import { Component, computed } from '@angular/core'; -import { ChatComponent } from '@cacheplane/chat'; +import { Component } from '@angular/core'; +import { ChatComponent, views } from '@cacheplane/chat'; +import { signalStateStore } from '@cacheplane/render'; import { agent } from '@cacheplane/angular'; import { environment } from '../environments/environment'; +import { PlanChecklistComponent } from './views/plan-checklist.component'; +import { CheckboxRowComponent } from './views/checkbox-row.component'; -/** - * Represents a single step in an agent-generated plan. - */ -interface PlanStep { - title: string; - status: 'pending' | 'in_progress' | 'complete'; -} - -/** - * PlanningComponent demonstrates agent task decomposition. - * - * The agent receives a complex task, breaks it into ordered steps, - * and executes them sequentially. The sidebar displays a live checklist - * of plan steps derived from the `plan` array in the graph state. - * - * Key integration points: - * - `stream.value()` exposes the full graph state, including the `plan` array - * - `planSteps` is derived from `stream.value()` for reactive sidebar rendering - * - Step status icons update in real time as the agent progresses - */ @Component({ selector: 'app-planning', standalone: true, imports: [ChatComponent], - template: ` -
- - -
- `, + template: ``, }) export class PlanningComponent { - /** - * The streaming resource connected to the planning graph. - * - * The graph returns a `plan` array alongside messages in its state. - * Each plan entry has a `title` and `status` that drive the sidebar checklist. - */ protected readonly stream = agent({ apiUrl: environment.langGraphApiUrl, - assistantId: environment.streamingAssistantId, + assistantId: environment.planningAssistantId, }); - /** - * Reactive list of plan steps derived from the graph state. - * - * The Python graph stores the plan as `state.plan` — an array of objects - * with `title` and `status` fields. This signal re-computes whenever - * the stream state changes. - */ - protected readonly planSteps = computed(() => { - const val = this.stream.value() as Record; - const plan = val?.['plan']; - if (!Array.isArray(plan)) return []; - return plan.map((step: Record) => ({ - title: String(step['title'] ?? ''), - status: (['pending', 'in_progress', 'complete'].includes(step['status'] as string) - ? step['status'] - : 'pending') as PlanStep['status'], - })); + readonly ui = views({ + 'plan-checklist': PlanChecklistComponent, + 'checkbox-row': CheckboxRowComponent, }); + + readonly uiStore = signalStateStore({}); } diff --git a/cockpit/deep-agents/planning/angular/src/app/views/checkbox-row.component.ts b/cockpit/deep-agents/planning/angular/src/app/views/checkbox-row.component.ts new file mode 100644 index 000000000..941efbe87 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/src/app/views/checkbox-row.component.ts @@ -0,0 +1,28 @@ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'checkbox-row', + standalone: true, + template: ` + + `, +}) +export class CheckboxRowComponent { + readonly label = input(''); + readonly checked = input(false); + readonly emit = input<(event: string) => void>(() => {}); + + toggle(): void { + this.emit()('toggle'); + } +} diff --git a/cockpit/deep-agents/planning/angular/src/app/views/plan-checklist.component.ts b/cockpit/deep-agents/planning/angular/src/app/views/plan-checklist.component.ts new file mode 100644 index 000000000..84a06a608 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/src/app/views/plan-checklist.component.ts @@ -0,0 +1,15 @@ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'plan-checklist', + standalone: true, + template: ` +
+

{{ title() }}

+ +
+ `, +}) +export class PlanChecklistComponent { + readonly title = input('Plan'); +} diff --git a/cockpit/deep-agents/planning/angular/src/environments/environment.development.ts b/cockpit/deep-agents/planning/angular/src/environments/environment.development.ts index b0133086b..b013bb6d3 100644 --- a/cockpit/deep-agents/planning/angular/src/environments/environment.development.ts +++ b/cockpit/deep-agents/planning/angular/src/environments/environment.development.ts @@ -8,4 +8,5 @@ export const environment = { production: false, langGraphApiUrl: 'http://localhost:4310/api', streamingAssistantId: 'planning', + planningAssistantId: 'planning', }; diff --git a/cockpit/deep-agents/planning/angular/src/environments/environment.ts b/cockpit/deep-agents/planning/angular/src/environments/environment.ts index d0950d618..0fbf05c5b 100644 --- a/cockpit/deep-agents/planning/angular/src/environments/environment.ts +++ b/cockpit/deep-agents/planning/angular/src/environments/environment.ts @@ -8,4 +8,5 @@ export const environment = { production: true, langGraphApiUrl: '/api', streamingAssistantId: 'planning', + planningAssistantId: 'planning', }; diff --git a/cockpit/deep-agents/sandboxes/angular/src/app/sandboxes.component.ts b/cockpit/deep-agents/sandboxes/angular/src/app/sandboxes.component.ts index 1f349ca8b..ff8b1b097 100644 --- a/cockpit/deep-agents/sandboxes/angular/src/app/sandboxes.component.ts +++ b/cockpit/deep-agents/sandboxes/angular/src/app/sandboxes.component.ts @@ -1,7 +1,9 @@ import { Component, computed } from '@angular/core'; -import { ChatComponent } from '@cacheplane/chat'; +import { ChatComponent, views } from '@cacheplane/chat'; +import { signalStateStore } from '@cacheplane/render'; import { agent } from '@cacheplane/angular'; import { environment } from '../environments/environment'; +import { CodeExecutionComponent } from './views/code-execution.component'; /** * Represents a parsed code execution: the code that was run and its output. @@ -28,7 +30,7 @@ interface CodeExecution { imports: [ChatComponent], template: `
- +
+ `, +}) +export class CodeExecutionComponent { + readonly code = input(''); + readonly stdout = input(''); + readonly stderr = input(''); +} diff --git a/cockpit/deep-agents/skills/angular/src/app/skills.component.ts b/cockpit/deep-agents/skills/angular/src/app/skills.component.ts index 71c3cb577..7b436e164 100644 --- a/cockpit/deep-agents/skills/angular/src/app/skills.component.ts +++ b/cockpit/deep-agents/skills/angular/src/app/skills.component.ts @@ -1,7 +1,10 @@ import { Component, computed } from '@angular/core'; -import { ChatComponent } from '@cacheplane/chat'; +import { ChatComponent, views } from '@cacheplane/chat'; +import { signalStateStore } from '@cacheplane/render'; import { agent } from '@cacheplane/angular'; import { environment } from '../environments/environment'; +import { CalculatorResultComponent } from './views/calculator-result.component'; +import { WordCountResultComponent } from './views/word-count-result.component'; /** * Represents a matched skill invocation: tool call paired with its result. @@ -29,7 +32,7 @@ interface SkillInvocation { imports: [ChatComponent], template: `
- +
+ `, +}) +export class CalculatorResultComponent { + readonly expression = input(''); + readonly result = input(''); +} diff --git a/cockpit/deep-agents/skills/angular/src/app/views/word-count-result.component.ts b/cockpit/deep-agents/skills/angular/src/app/views/word-count-result.component.ts new file mode 100644 index 000000000..7ca97bd31 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/src/app/views/word-count-result.component.ts @@ -0,0 +1,25 @@ +import { Component, input } from '@angular/core'; + +@Component({ + selector: 'word-count-result', + standalone: true, + template: ` +
+ + word_count + + + {{ count() }} + + + words + +
+ `, +}) +export class WordCountResultComponent { + readonly count = input(''); + readonly text = input(''); +} diff --git a/cockpit/langgraph/durable-execution/angular/src/app/durable-execution.component.ts b/cockpit/langgraph/durable-execution/angular/src/app/durable-execution.component.ts index f5a63e1be..7efe8d46c 100644 --- a/cockpit/langgraph/durable-execution/angular/src/app/durable-execution.component.ts +++ b/cockpit/langgraph/durable-execution/angular/src/app/durable-execution.component.ts @@ -1,7 +1,9 @@ import { Component, computed } from '@angular/core'; -import { ChatComponent } from '@cacheplane/chat'; +import { ChatComponent, views } from '@cacheplane/chat'; +import { signalStateStore } from '@cacheplane/render'; import { agent } from '@cacheplane/angular'; import { environment } from '../environments/environment'; +import { StepPipelineComponent } from './views/step-pipeline.component'; /** * Pipeline step definition for the vertical progress indicator. @@ -37,7 +39,7 @@ const STEP_LABELS: Record = { imports: [ChatComponent], template: `
- +