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
5 changes: 5 additions & 0 deletions insight-flow-agent-chat/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
VITE_INSFORGE_URL=
VITE_INSFORGE_ANON_KEY=

# Optional comma-separated allowlist, for example: agents.example.com
INSIGHT_FLOW_ALLOWED_HOSTS=
7 changes: 7 additions & 0 deletions insight-flow-agent-chat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
.env
.env.local
.env.*.local
*.log
*.tsbuildinfo
32 changes: 32 additions & 0 deletions insight-flow-agent-chat/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Insight Flow Agent template contract

## Credential boundary

- Configuration belongs on `/settings`, never in the chat composer or sidebar.
- Store the API key as plaintext only in the owner-scoped backend configuration row.
- Default settings reads return only configured state and a masked placeholder. Return the full key only for the explicit authenticated `reveal` action initiated from the settings eye control. This masking prevents accidental display and shoulder surfing; it is not a security boundary against authenticated same-origin code.
- Never place the API key in localStorage, sessionStorage, cookies, analytics, logs, URLs, public environment variables, or generated source packages.
- Keep owner-only RLS on `insight_flow_agent_configs`. The optional `INSIGHT_FLOW_ALLOWED_HOSTS` secret narrows outbound destinations.

## Streaming boundary

- Browser code calls `/functions/insight-flow-chat` with the SDK HTTP client's `rawFetch`; do not replace this with `functions.invoke`, which parses the complete response.
- Preserve `text/event-stream`, `X-Accel-Buffering: no`, and `X-InsForge-Streaming: true` in the Function response.
- Parse OpenAI-compatible `choices[0].delta.content` events and stop at `data: [DONE]`.
- Forward `X-GoClaw-Session-Key` as `X-InsightFlow-Session-Key` so later turns can resume the same Agent session.
- Publish the response session key before consuming SSE so cancellation and stream errors cannot discard it. Surface a warning when the first turn receives no session key.
- Pass request cancellation to the upstream fetch.
- Treat EOF without `data: [DONE]` as a truncated response.

## Insight Flow contract

- Prefer `model: "goclaw:<agent-key>"`.
- Keep the legacy `agent` request field as an explicit compatibility mode; when both are present, Insight Flow gives `agent` precedence.
- `tool_choice: "none"` disables tools.
- PR #666 emits finalized, delivery-safe chunks after Agent lifecycle finalization. Do not describe it as first-token streaming.

## InsForge boundary

- Frontend source contains only the public InsForge endpoint and anon key.
- Both Functions authenticate the user JWT. Configuration rows are isolated by `auth.uid()` RLS.
- The template requires an InsForge v2 runtime with streaming Function responses.
21 changes: 21 additions & 0 deletions insight-flow-agent-chat/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Lexmount

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
41 changes: 41 additions & 0 deletions insight-flow-agent-chat/PRODUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Product

## Register

product

## Platform

web

## Users

People who want to talk to a configured Insight Flow Agent in a familiar, distraction-free chat product.

## Product Purpose

Turn a backend-stored Insight Flow connection into a streaming conversation that stays continuous while the page is open. Success means a signed-in user configures their Agent once in Settings, returns to a clean chat surface, sees finalized SSE chunks arrive, and continues the same Agent session without credentials appearing in the chat UI.

## Positioning

A familiar ChatGPT-style home for a privately configured Insight Flow Agent.

## Brand Personality

Quiet, familiar, and focused. The interface should disappear behind the conversation.

## Anti-references

Avoid neon-on-black AI aesthetics, oversized marketing copy, ornamental dashboards, credential forms inside chat, and unfamiliar chat controls.

## Design Principles

- Keep the main surface about conversation; configuration belongs on a separate Settings route.
- Store API keys in owner-only backend rows, mask them by default to prevent accidental display, and reveal the full value only after an explicit authenticated action.
- Prefer the documented `model: goclaw:<agent-key>` contract while keeping the legacy `agent` alias testable.
- Show streaming, cancellation, session reset, and errors as clear states rather than animations.
- Use a familiar sidebar, centered transcript, and bottom composer; collapse navigation on small screens.

## Accessibility & Inclusion

Use semantic controls, visible focus states, keyboard submission, readable contrast, non-color status cues, and reduced-motion-safe transitions.
78 changes: 78 additions & 0 deletions insight-flow-agent-chat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Insight Flow Agent Chat

一个 ChatGPT 风格的 Insight Flow Agent 流式对话模板。主界面只负责对话;登录用户在独立 `/settings` 页面配置一次 Base URL、API Key 和 model/agent 参数,之后由 InsForge Edge Function 从后端读取配置并代理 `/v1/chat/completions` SSE。

## 功能

- ChatGPT 风格侧栏、居中消息流和底部 composer,支持桌面与移动端。
- InsForge 邮箱 OTP 登录,每个用户拥有独立 Agent 配置。
- API Key 明文保存在用户自己的后端配置行中,由登录认证和 RLS 隔离;设置页默认脱敏,点击眼睛后可查看完整值。
- 推荐 `model: "goclaw:<agent-key>"`,同时兼容 PR #666 的 `agent` 参数。
- 解析 OpenAI-compatible SSE delta 与 `[DONE]`,支持停止生成。
- 回传 `X-GoClaw-Session-Key`,在当前页面存续期间延续 Agent session;缺少会话标识时会明确提示。
- 支持 `tool_choice: "none"`。
- RLS 使用 `auth.uid()` 隔离每个用户的配置。

## 初始化后端

模板安装流程会应用 migration 并部署两个 Functions:

```text
migrations/20260828054000_create-insight-flow-agent-configs.sql
functions/insight-flow-config.ts
functions/insight-flow-chat.ts
```

手动初始化时:

```bash
npx -y @insforge/cli db migrations up --all
npx -y @insforge/cli functions deploy insight-flow-config --file ./functions/insight-flow-config.ts
npx -y @insforge/cli functions deploy insight-flow-chat --file ./functions/insight-flow-chat.ts
```

生产环境建议再限制允许连接的 Insight Flow Host:

```bash
npx -y @insforge/cli secrets add INSIGHT_FLOW_ALLOWED_HOSTS 'insight-flow.example.com,agents.example.com'
```

Function 拒绝 HTTP、本地主机、IPv4-mapped/compatible IPv6、CGNAT 和其他非公网 IP 字面量。Host allowlist 是生产环境更可靠的边界,可降低域名解析到私有网络带来的 SSRF 风险。

API Key 不会进入聊天页、URL、浏览器存储或公共环境变量。默认读取设置时接口只返回脱敏占位符;用户在设置页点击眼睛后,经过身份认证的 Function 才返回该用户自己的完整 Key。这里的脱敏是防止误显示和肩窥的 UX,不是抵御同源脚本的安全边界:当前用户有权读取自己的配置,数据库管理员也能读取明文值。因此该模板适合以部署简洁为优先的场景。

## 前端环境变量

```bash
cp .env.example .env
```

只把 InsForge 公共连接信息提供给 Vite:

```text
VITE_INSFORGE_URL=https://your-app.region.insforge.app
VITE_INSFORGE_ANON_KEY=your-public-anon-key
```

然后运行:

```bash
npm install
npm run dev
```

## 流式语义

Insight Flow PR #666 在 Agent lifecycle finalization 后输出经过 sanitization 和 execution disclosure 处理的 SSE chunks。浏览器会逐块渲染这些 chunks,但这不是模型生成阶段的首 Token 低延迟通道。

`insight-flow-chat` 返回 `Content-Type: text/event-stream`、`X-Accel-Buffering: no` 和 `X-InsForge-Streaming: true`,要求使用支持 Function response streaming 的 InsForge v2 runtime。浏览器只有收到 `[DONE]` 才把本轮视为完整结束;中途 EOF 会显示错误并保留已收到的内容。

## 验证

```bash
npm test
npm run typecheck
npm run build
deno check functions/insight-flow-config.ts functions/insight-flow-chat.ts
deno test --allow-env tests/function_test.ts
```
Loading
Loading