Skip to main content

viz-renderer

IPAI meta-skill for Pulser inline visualizations. Single payload-first contract (viz_payload JSON) consumed by all Pulser agents to emit charts, KPI cards, and insight pills. Three render targets: Teams Adaptive Cards, Odoo QWeb HTML, ops-console React. Use when any Pulser agent (Scrum Master, Finance PPM, BIR, Bank Recon, Scout, Ces, PrismaLab, Tax Guru) needs to emit inline data visualization. All domain skills depend on this meta-skill; none reimplement rendering.

Ir a la instalación

Datos de origen

Repositorio
Insightpulseai/odoo
Última actividad en el origen
17 de abril de 2026 a las 07:19
Idioma detectado de SKILL.md
inglés
Estrellas
6
Forks
2

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
viz-renderer
description
IPAI meta-skill for Pulser inline visualizations. Single payload-first contract (viz_payload JSON) consumed by all Pulser agents to emit charts, KPI cards, and insight pills. Three render targets: Teams Adaptive Cards, Odoo QWeb HTML, ops-console React. Use when any Pulser agent (Scrum Master, Finance PPM, BIR, Bank Recon, Scout, Ces, PrismaLab, Tax Guru) needs to emit inline data visualization. All domain skills depend on this meta-skill; none reimplement rendering.
# Viz Renderer — IPAI Meta-Skill ## Purpose Meta-skill that owns the `viz_payload` contract and render pipeline. Every Pulser agent that emits visualizations depends on this skill; none implement their own renderer. **Architecture:** one contract, three render targets, N emitting agents. ## Scope - **Odoo version:** 18.0 CE (render target for `view_mode="list,form"`) - **OCA-first:** yes — uses `ipai_odoo_copilot` chatter widget for Odoo render - **`ipai_*` delta:** no — meta-skill lives at agent-platform layer - **Azure resources:** - Foundry `ipai-copilot-resource` (East US 2) — **`gpt-4.1`** via Code Interpreter for PNG/SVG generation (R2 baseline; `gpt-5.3-codex` is optional R3+ upgrade when/if value is proven) - Blob `stipaidevagent` — chart artifact storage - Service Bus `sb-ipai-dev-sea` — async render queue (`viz-render` topic) - Key Vault `kv-ipai-dev-sea` — Teams/Odoo credentials - App Insights `appi-ipai-platform-sea` — render latency metrics - **Agents served:** - `scrum_master` — sprint analytics - `tax_guru` — tax calc validation cards - `bank_recon` — reconciliation donuts + discrepancy pills - `finance_close` — D+5 progress tracker - `finance_ppm` — project profitability + cash flow - `ap_invoice` / `ar_collections` — aging buckets + DSO trends - `doc_intel` — extraction confidence KPIs - `scout_analytics` — brand share + SOV - `ces_campaign` — campaign KPIs + channel mix - `prismalab` — PRISMA flow + forest/funnel plots - `pulser` (orchestrator) — cross-domain dashboards ## Prerequisites - [ ] `ipai-agent-platform` loaded (for MAF patterns) - [ ] `ipai-resource-map` loaded (for Foundry/Blob/SB names) - [ ] Spec bundle `spec/pulser-inline-viz/` accessible (contract source of truth) ## Vision (the UX IPAI is building) **"Claude.ai artifact panel + Notion AI + Databricks Genie + SAP Joule + M365 Copilot (Finance / Project Operations) — all consolidated into Pulser-in-Odoo, agentic."** Each reference product gives us one capability Pulser must match: | Reference | What IPAI borrows | |---|---| | **Claude.ai** | Inline artifact generation (charts, docs, code) in chat, with preview + edit + save | | **Notion AI** | Workspace-aware agent grounded in internal docs (our spec bundles + SSOT + doctrine) | | **Databricks Genie** | Natural-language data Q&A against governed data (Scout + Finance gold layers) | | **SAP Joule** | Enterprise AI assistant with RBAC-aware data access | | **M365 Copilot for Finance** | Recon, Collections, Expense agents inside the system of record | | **M365 Copilot for Project Operations** | Services-ERP copilot (timesheets, WIP, invoicing, profitability) | Pulser is the consolidated answer — one agent surface, one identity, one policy gate, embedded in Odoo (system of record) + Teams (collaboration) + ops-console (ops view). ## Sandboxed artifact generation (CRITICAL architectural directive) **Generate → Preview → Save** — every artifact runs in a sandbox before committing to Odoo. Model: Claude.ai artifacts panel, but embedded in Odoo chatter. ### The 3-phase flow ``` ┌──────────────────────────────────────────────────────────────────────┐ │ 1. GENERATE (sandboxed, outside Odoo DB) │ │ - Pulser agent emits viz_payload │ │ - Foundry Code Interpreter runs chart code in isolated container │ │ - PNG/SVG/HTML written to stipaidevagent (staging path) │ │ - Service Bus 'viz-preview' topic notifies Odoo │ │ │ │ 2. PREVIEW (Odoo chatter side-panel, not committed) │ │ - Sandboxed iframe in chatter renders blob_url preview │ │ - User sees chart + KPIs + insight pills inline │ │ - Actions: [Approve] [Edit payload] [Regenerate] [Discard] │ │ - Nothing written to ir.attachment yet │ │ │ │ 3. SAVE (committed to Odoo as ir.attachment + linked artifact) │ │ - User clicks Approve │ │ - Safe Outputs vets final payload │ │ - Blob moved from staging path → canonical path │ │ - ir.attachment created, linked to active record (move/project/…) │ │ - Optionally published: mail.message body, evidence pack, etc. │ └──────────────────────────────────────────────────────────────────────┘ ``` ### Sandbox boundaries | Boundary | What runs in sandbox | What stays outside | |---|---|---| | **Compute** | Chart-gen code (Python in Foundry Code Interpreter container) | Odoo ORM, PG DB, Key Vault | | **Network** | No outbound from chart sandbox except to `stipaidevagent` staging container | All other Azure resources | | **Storage** | Staging blob path: `stipaidevagent/viz-staging/<session>/<payload_id>.*` | Production blob path: `stipaidevagent/viz/<payload_id>.*` — only after save | | **Identity** | Sandbox MI: `id-ipai-viz-sandbox-dev` with RBAC on staging container ONLY | Approved artifacts elevated via `id-ipai-viz-renderer-dev` | | **DB writes** | None from sandbox | Only after user approve: Odoo `ir.attachment.create()` | ### Sandbox implementation (Odoo side) ```python # addons/ipai/ipai_odoo_copilot/models/ipai_viz_session.py class IpaiVizSession(models.Model): _name = 'ipai.viz.session' _description = 'Sandboxed viz preview before save' name = fields.Char() agent_run_id = fields.Char() # FK to overlay agent.agent_runs payload_id = fields.Char(required=True) viz_type = fields.Selection([...]) staging_blob_url = fields.Char() # sandbox location preview_html = fields.Html() state = fields.Selection([ ('generating', 'Generating'), ('preview', 'Awaiting user review'), ('approved', 'Approved — saving'), ('saved', 'Saved'), ('discarded', 'Discarded'), ('failed', 'Failed'), ], default='generating') attachment_id = fields.Many2one('ir.attachment') owner_record_model = fields.Char() # e.g., 'account.move' owner_record_id = fields.Integer() safe_outputs_decision = fields.Char() # allow/redact/block def action_approve(self): # 1. Safe Outputs vet # 2. Move blob staging → canonical path # 3. Create ir.attachment # 4. Link to owner record # 5. Post to chatter via mail.message # 6. Log to agent.artifacts (overlay DBML) pass def action_discard(self): # 1. Delete staging blob # 2. Update state # 3. Log audit.audit_events pass ``` ### Odoo chatter widget (preview UI) `addons/ipai/ipai_odoo_copilot/static/src/js/viz_sandbox_widget.js` — Owl.js component that: - Subscribes to `ipai.viz.session` records in `preview` state - Renders the staging blob in an iframe with `sandbox="allow-scripts allow-same-origin"` - Shows Approve / Edit / Regenerate / Discard buttons - On Approve → RPC to `action_approve()` ### Documents module integration (canonical landing) **All saved artifacts MUST also appear in Odoo Documents module** (`/odoo/action-<dms_id>` — action ID is environment-specific, e.g., `action-1367` on `localhost:8069`). Not just as orphan attachments on arbitrary records. **Why:** Users need ONE place to find all Pulser-generated artifacts — searchable, filterable, shareable. Documents module is the canonical DMS UX. CE 18 has no native Documents app (Enterprise-only), so IPAI uses **OCA `dms`** (already submodule'd at `addons/oca/dms/`). **Integration model (CE/OCA-first, no new custom module):** ```python # On action_approve(), in addition to ir.attachment.create(): def _save_to_documents(self): """Save sandbox artifact to Odoo Documents (OCA dms) for canonical discovery.""" dms_directory = self.env['dms.directory'].search([ ('name', '=', f"Pulser/{self.tenant_slug}/{self.agent_run_id}/{self.create_date:%Y-%m}"), ], limit=1) or self._create_pulser_directory() dms_file = self.env['dms.file'].create({ 'name': f"{self.viz_type}-{self.payload_id}.{self.mime_suffix}", 'directory_id': dms_directory.id, 'attachment_id': self.attachment_id.id, # links to existing ir.attachment # IPAI metadata — queryable in Documents search 'tag_ids': [ self.env.ref('ipai_odoo_copilot.tag_pulser_generated').id, self.env.ref(f'ipai_odoo_copilot.tag_agent_{self.agent_name}').id, self.env.ref(f'ipai_odoo_copilot.tag_viz_{self.viz_type}').id, ], }) return dms_file ``` **Folder structure (per dms.directory tree):** ``` /Pulser Workspace/ /<tenant_slug>/ ← tenant isolation (mirrors res.company) /scrum_master/ ← per-agent folder /2026-04/ ← monthly rollup sprint-burndown-<uuid>.png velocity-<uuid>.svg dora-kpis-<uuid>.png /bank_recon/ /2026-04/ reconciliation-donut-<uuid>.png discrepancy-pills-<uuid>.json /tax_guru/ /2026-Q1/ ← tax periods for BIR 2307-summary-<uuid>.png 2550m-kpis-<uuid>.svg /finance_ppm/ /2026-04/ project-profitability-<uuid>.png /prismalab/ /<research-project-key>/ ← per research project prisma-flow-<uuid>.svg forest-plot-<uuid>.svg /ces_campaign/ /<campaign-key>/ ← per campaign kpi-cards-<uuid>.png channel-mix-donut-<uuid>.png /sora_creative/ /<brief-key>/ ← per creative brief vertical-9x16-<uuid>.mp4 storyboard-<uuid>.png ``` **Tags (queryable in Documents search):** - `pulser-generated` — any artifact from Pulser - `agent:<name>` — filter by source agent (scrum_master, bank_recon, tax_guru, etc.) - `viz:<type>` — filter by viz_type (kpi_cards, line_chart, prisma_flow, etc.) - `tenant:<slug>` — tenant isolation - `period:<YYYY-MM>` — monthly rollups - `classification:<level>` — internal / confidential / restricted - `approved` / `published` / `archived` — lifecycle state **URL routing (action-1367 pattern — env-specific):** - Documents landing: `/odoo/action-<dms_id>` (equivalent of Documents app) - Filtered Pulser view: `/odoo/action-<dms_id>?tag=pulser-generated` - Per-agent: `/odoo/action-<dms_id>?tag=agent:scrum_master` - Per-tenant: `/odoo/action-<dms_id>?tag=tenant:tbwa-smp` The action ID (1367 on localhost) varies per environment — **reference it by xml_id** (e.g., `ipai_odoo_copilot.action_pulser_workspace` or `dms.action_dms_files`), never by numeric ID in code. **Access permissions:** - `dms.directory` group: `ipai_odoo_copilot.group_pulser_user` (read); `ipai_odoo_copilot.group_pulser_admin` (write/delete) - Row-level per tenant: `res.company` match via `ir.rule` on `dms.directory` and `dms.file` - Share links: Pulser artifacts can be shared externally only if `classification IN ('public','internal')` — CONFIDENTIAL and RESTRICTED cannot be share-linked **What this replaces:** - `ir.attachment` orphans scattered across `account.move`, `project.project`, etc. — now findable in ONE Documents view - Ad-hoc screenshot sharing via Slack/Teams — now via Documents share links with audit trail - "Where did Pulser save that chart yesterday?" — now a tag filter in Documents search ### Artifact types saved after approval | Artifact | Saved to | Owner linkage | Documents folder | |---|---|---|---| | Chart PNG/SVG | `ir.attachment` + `agent.artifacts` + `dms.file` | Active record (move / project / partner / etc.) | `/Pulser Workspace/<tenant>/<agent>/<YYYY-MM>/` | | Report PDF | `ir.attachment` (mimetype PDF) + `dms.file` | Active record or evidence pack | `/Pulser Workspace/<tenant>/<agent>/<YYYY-MM>/reports/` | | Excel export | `ir.attachment` (mimetype XLSX) + `dms.file` | Active record | `/Pulser Workspace/<tenant>/<agent>/<YYYY-MM>/exports/` | | Teams Adaptive Card JSON | Posted to Teams channel (no Odoo save) | — | — (ephemeral) | | ops-console preview | React component rendered in-app | Session only | — (ephemeral) | | Sora video | `creative.video_generations` (overlay) + `ir.attachment` + `dms.file` | Active campaign / record | `/Pulser Workspace/<tenant>/sora_creative/<brief-key>/` | | gpt-image-1.5 still | `creative.image_generations` + `ir.attachment` + `dms.file` | Active brief / campaign | `/Pulser Workspace/<tenant>/sora_creative/<brief-key>/` | | PRISMA flow SVG | `research.prisma_flow_snapshots` (overlay) + `ir.attachment` + `dms.file` | Active research project | `/Pulser Workspace/<tenant>/prismalab/<research-project-key>/` | ## The canonical contract See `spec/pulser-inline-viz/spec.md` §F-001 for the authoritative schema. Every Pulser agent output that includes a visualization MUST include a `viz_payload` JSON object alongside the text answer: ```jsonc { "$schema": "https://ipai.internal/viz-payload/v1", "id": "<uuid>", "agent": "<agent-name>", "title": "<card/chart title>",
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub