Compare commits

..

8 Commits

Author SHA1 Message Date
Simon c0ce6e7d14 chore(version): bump version to 0.2.0 2026-01-15 20:47:39 +08:00
Simon 8f5f98f889 feat(agent)!: rename brain to reflection; fix undefined lines in panel 2026-01-15 20:45:40 +08:00
Simon ee4719cdcf feat: observation 2026-01-15 20:28:39 +08:00
Simon b4c82b7833 refactor: mv getBrowserState to Controller; simplify Agent 2026-01-15 20:17:50 +08:00
Simon aefc3cfb89 Merge pull request #111 from alibaba/feat/extend-agent-history-for-observation
feat: extend history type
2026-01-15 19:57:41 +08:00
Simon 7f2b8c2766 feat: extend history type 2026-01-15 19:18:25 +08:00
Simon 62e24a3050 chore(version): bump version to 0.1.0 2026-01-14 18:50:06 +08:00
Simon 4f6249a252 feat!: require user to provide LLM api. do not fallback to demo LLM
BREAKING CHANGE: LLM API will be required for agent constructor
2026-01-14 18:49:23 +08:00
19 changed files with 278 additions and 184 deletions
+12 -12
View File
@@ -1,12 +1,12 @@
{
"name": "root",
"version": "0.0.24",
"version": "0.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "root",
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT",
"workspaces": [
"packages/page-controller",
@@ -8147,15 +8147,15 @@
},
"packages/cdn": {
"name": "@page-agent/cdn",
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT",
"dependencies": {
"page-agent": "0.0.24"
"page-agent": "0.2.0"
}
},
"packages/llms": {
"name": "@page-agent/llms",
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT",
"dependencies": {
"chalk": "^5.6.2",
@@ -8163,19 +8163,19 @@
}
},
"packages/page-agent": {
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT",
"dependencies": {
"@page-agent/llms": "0.0.24",
"@page-agent/page-controller": "0.0.24",
"@page-agent/ui": "0.0.24",
"@page-agent/llms": "0.2.0",
"@page-agent/page-controller": "0.2.0",
"@page-agent/ui": "0.2.0",
"chalk": "^5.6.2",
"zod": "^4.3.5"
}
},
"packages/page-controller": {
"name": "@page-agent/page-controller",
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT",
"dependencies": {
"ai-motion": "^0.4.8"
@@ -8183,12 +8183,12 @@
},
"packages/ui": {
"name": "@page-agent/ui",
"version": "0.0.24",
"version": "0.2.0",
"license": "MIT"
},
"packages/website": {
"name": "@page-agent/website",
"version": "0.0.24",
"version": "0.2.0",
"dependencies": {
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-separator": "^1.1.8",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "root",
"private": true,
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"workspaces": [
"packages/page-controller",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@page-agent/cdn",
"private": false,
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"files": [
"dist/"
@@ -18,6 +18,6 @@
"build": "vite build && vite build --mode demo"
},
"dependencies": {
"page-agent": "0.0.24"
"page-agent": "0.2.0"
}
}
+6 -1
View File
@@ -50,7 +50,12 @@ setTimeout(() => {
window.pageAgent = new PageAgent(config)
} else {
console.log('🚀 page-agent.js no current script detected, using default demo config')
window.pageAgent = new PageAgent()
const config = {
model: DEMO_MODEL,
baseURL: DEMO_BASE_URL,
apiKey: DEMO_API_KEY,
}
window.pageAgent = new PageAgent(config)
}
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@page-agent/llms",
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"main": "./dist/lib/page-agent-llms.js",
"module": "./dist/lib/page-agent-llms.js",
+1 -18
View File
@@ -1,20 +1,3 @@
// Dev environment: use .env config if available, otherwise fallback to testing api
export const DEFAULT_MODEL_NAME: string =
import.meta.env.DEV && import.meta.env.LLM_MODEL_NAME
? import.meta.env.LLM_MODEL_NAME
: 'PAGE-AGENT-FREE-TESTING-RANDOM'
export const DEFAULT_API_KEY: string =
import.meta.env.DEV && import.meta.env.LLM_API_KEY
? import.meta.env.LLM_API_KEY
: 'PAGE-AGENT-FREE-TESTING-RANDOM'
export const DEFAULT_BASE_URL: string =
import.meta.env.DEV && import.meta.env.LLM_BASE_URL
? import.meta.env.LLM_BASE_URL
: 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
// internal
// Internal constants
export const LLM_MAX_RETRIES = 2
export const DEFAULT_TEMPERATURE = 0.7 // higher randomness helps auto-recovery
+12 -10
View File
@@ -1,21 +1,23 @@
import { OpenAIClient } from './OpenAIClient'
import {
DEFAULT_API_KEY,
DEFAULT_BASE_URL,
DEFAULT_MODEL_NAME,
DEFAULT_TEMPERATURE,
LLM_MAX_RETRIES,
} from './constants'
import { DEFAULT_TEMPERATURE, LLM_MAX_RETRIES } from './constants'
import { InvokeError } from './errors'
import type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool } from './types'
export type { InvokeOptions, InvokeResult, LLMClient, LLMConfig, Message, Tool }
export function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {
// Runtime validation as defensive programming (types already guarantee these)
if (!config.baseURL || !config.apiKey || !config.model) {
throw new Error(
'[PageAgent] LLM configuration required. Please provide: baseURL, apiKey, model. ' +
'See: https://alibaba.github.io/page-agent/#/docs/features/models'
)
}
return {
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
apiKey: config.apiKey ?? DEFAULT_API_KEY,
model: config.model ?? DEFAULT_MODEL_NAME,
baseURL: config.baseURL,
apiKey: config.apiKey,
model: config.model,
temperature: config.temperature ?? DEFAULT_TEMPERATURE,
maxRetries: config.maxRetries ?? LLM_MAX_RETRIES,
customFetch: (config.customFetch ?? fetch).bind(globalThis), // fetch will be illegal unless bound
+3 -3
View File
@@ -87,9 +87,9 @@ export interface InvokeResult<TResult = unknown> {
* LLM configuration
*/
export interface LLMConfig {
baseURL?: string
apiKey?: string
model?: string
baseURL: string
apiKey: string
model: string
temperature?: number
maxRetries?: number
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "page-agent",
"private": false,
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"main": "./dist/esm/page-agent.js",
"module": "./dist/esm/page-agent.js",
@@ -46,8 +46,8 @@
"dependencies": {
"chalk": "^5.6.2",
"zod": "^4.3.5",
"@page-agent/llms": "0.0.24",
"@page-agent/page-controller": "0.0.24",
"@page-agent/ui": "0.0.24"
"@page-agent/llms": "0.2.0",
"@page-agent/page-controller": "0.2.0",
"@page-agent/ui": "0.2.0"
}
}
+141 -79
View File
@@ -16,7 +16,7 @@ import { normalizeResponse, trimLines, uid, waitUntil } from './utils'
import { assert } from './utils/assert'
/**
* Agent brain state - the reflection-before-action model
* Agent reflection state - the reflection-before-action model
*
* Every tool call must first reflect on:
* - evaluation_previous_goal: How well did the previous action achieve its goal?
@@ -50,8 +50,12 @@ export interface MacroToolResult {
export type { PageAgentConfig }
export { tool, type PageAgentTool } from './tools'
export interface AgentHistory {
brain: Partial<AgentReflection>
/**
* A single agent step with reflection and action
*/
export interface AgentStep {
type: 'step'
reflection: Partial<AgentReflection>
action: {
name: string
input: any
@@ -66,10 +70,33 @@ export interface AgentHistory {
}
}
/**
* Persistent observation event (stays in memory)
*/
export interface ObservationEvent {
type: 'observation'
content: string
}
/**
* User takeover event
*/
export interface UserTakeoverEvent {
type: 'user_takeover'
}
/**
* Union type for all history events
*/
export type HistoryEvent = AgentStep | ObservationEvent | UserTakeoverEvent
/** @deprecated Use AgentStep instead */
export type AgentHistory = AgentStep
export interface ExecutionResult {
success: boolean
data: string
history: AgentHistory[]
history: HistoryEvent[]
}
export class PageAgent extends EventTarget {
@@ -83,7 +110,6 @@ export class PageAgent extends EventTarget {
taskId = ''
#llm: LLM
#totalWaitTime = 0
#abortController = new AbortController()
#llmRetryListener: ((e: Event) => void) | null = null
#llmErrorListener: ((e: Event) => void) | null = null
@@ -92,10 +118,18 @@ export class PageAgent extends EventTarget {
/** PageController for DOM operations */
pageController: PageController
/** History records */
history: AgentHistory[] = []
/** Runtime states for tracking across steps */
states = {
/** Accumulated wait time in seconds, used by wait tool */
totalWaitTime: 0,
/** Last known URL for detecting navigation */
lastURL: '',
}
constructor(config: PageAgentConfig = {}) {
/** History event stream */
history: HistoryEvent[] = []
constructor(config: PageAgentConfig) {
super()
this.config = config
@@ -150,6 +184,14 @@ export class PageAgent extends EventTarget {
window.addEventListener('beforeunload', this.#beforeUnloadListener)
}
/**
* Push a persistent observation to the history event stream.
* This will be visible in <agent_history> and remain in memory across steps.
*/
pushObservation(content: string): void {
this.history.push({ type: 'observation', content })
}
async execute(task: string): Promise<ExecutionResult> {
if (!task) throw new Error('Task is required')
this.task = task
@@ -177,10 +219,18 @@ export class PageAgent extends EventTarget {
this.history = []
// Reset states
this.states = {
totalWaitTime: 0,
lastURL: '',
}
try {
let step = 0
while (true) {
await this.#generateObservations(step)
await onBeforeStep.call(this, step)
console.group(`step: ${step}`)
@@ -216,23 +266,24 @@ export class PageAgent extends EventTarget {
const macroResult = result.toolResult as MacroToolResult
const input = macroResult.input
const output = macroResult.output
const brain = {
evaluation_previous_goal: input.evaluation_previous_goal || '',
memory: input.memory || '',
next_goal: input.next_goal || '',
const reflection: Partial<AgentReflection> = {
evaluation_previous_goal: input.evaluation_previous_goal,
memory: input.memory,
next_goal: input.next_goal,
}
const actionName = Object.keys(input.action)[0]
const action = {
const action: AgentStep['action'] = {
name: actionName,
input: input.action[actionName],
output: output,
}
this.history.push({
brain,
type: 'step',
reflection,
action,
usage: result.usage,
})
} as AgentStep)
console.log(chalk.green('Step finished:'), actionName)
console.groupEnd()
@@ -319,13 +370,20 @@ export class PageAgent extends EventTarget {
const toolName = Object.keys(action)[0]
const toolInput = action[toolName]
const brain = trimLines(`✅: ${input.evaluation_previous_goal}
💾: ${input.memory}
🎯: ${input.next_goal}
`)
console.log(brain)
this.panel.update({ type: 'thinking', text: brain })
// Build reflection text, only include non-empty fields
const reflectionLines: string[] = []
if (input.evaluation_previous_goal)
reflectionLines.push(`✅: ${input.evaluation_previous_goal}`)
if (input.memory) reflectionLines.push(`💾: ${input.memory}`)
if (input.next_goal) reflectionLines.push(`🎯: ${input.next_goal}`)
const reflectionText = reflectionLines.length > 0 ? reflectionLines.join('\n') : ''
if (reflectionText) {
console.log(reflectionText)
this.panel.update({ type: 'thinking', text: reflectionText })
}
// Find the corresponding tool
const tool = tools.get(toolName)
@@ -337,20 +395,14 @@ export class PageAgent extends EventTarget {
const startTime = Date.now()
// Execute tool, bind `this` to PageAgent
let result = await tool.execute.bind(this)(toolInput)
const result = await tool.execute.bind(this)(toolInput)
const duration = Date.now() - startTime
console.log(chalk.green.bold(`Tool (${toolName}) executed for ${duration}ms`), result)
if (toolName === 'wait') {
this.#totalWaitTime += Math.round(toolInput.seconds + duration / 1000)
result += `\n<sys> You have waited ${this.#totalWaitTime} seconds accumulatively.`
if (this.#totalWaitTime >= 3)
result += '\nDo NOT wait any longer unless you have a good reason.\n'
result += '</sys>'
} else {
// For other tools, reset wait time
this.#totalWaitTime = 0
// Reset wait time for non-wait tools
if (toolName !== 'wait') {
this.states.totalWaitTime = 0
}
// Briefly display execution result
@@ -427,6 +479,34 @@ export class PageAgent extends EventTarget {
return result
}
/**
* Generate observations before each step
* - URL change detection
* - Too many steps warning
* @todo loop detection
* @todo console error
*/
async #generateObservations(stepCount: number): Promise<void> {
// Detect URL change
const currentURL = await this.pageController.getCurrentUrl()
if (currentURL !== this.states.lastURL) {
this.pushObservation(`Page navigated to → ${currentURL}`)
this.states.lastURL = currentURL
}
// Warn about remaining steps
const remaining = MAX_STEPS - stepCount
if (remaining === 5) {
this.pushObservation(
`⚠️ Only ${remaining} steps remaining. Consider wrapping up or calling done with partial results.`
)
} else if (remaining === 2) {
this.pushObservation(
`⚠️ Critical: Only ${remaining} steps left! You must finish the task or call done immediately.`
)
}
}
async #assembleUserPrompt(): Promise<string> {
let prompt = ''
@@ -438,31 +518,42 @@ export class PageAgent extends EventTarget {
// - <step_info>
// <agent_state>
const stepCount = this.history.filter((e) => e.type === 'step').length
prompt += `<agent_state>
<user_request>
${this.task}
</user_request>
<step_info>
Step ${this.history.length + 1} of ${MAX_STEPS} max possible steps
Step ${stepCount + 1} of ${MAX_STEPS} max possible steps
Current date and time: ${new Date().toISOString()}
</step_info>
</agent_state>
`
// <agent_history>
// - <step_>
// - <step_N> for steps
// - <sys> for observations and system messages
prompt += '\n<agent_history>\n'
this.history.forEach((history, index) => {
prompt += `<step_${index + 1}>
Evaluation of Previous Step: ${history.brain.evaluation_previous_goal}
Memory: ${history.brain.memory}
Next Goal: ${history.brain.next_goal}
Action Results: ${history.action.output}
</step_${index + 1}>
let stepIndex = 0
for (const event of this.history) {
if (event.type === 'step') {
stepIndex++
prompt += `<step_${stepIndex}>
Evaluation of Previous Step: ${event.reflection.evaluation_previous_goal}
Memory: ${event.reflection.memory}
Next Goal: ${event.reflection.next_goal}
Action Results: ${event.action.output}
</step_${stepIndex}>
`
})
} else if (event.type === 'observation') {
prompt += `<sys>${event.content}</sys>\n`
} else if (event.type === 'user_takeover') {
prompt += `<sys>User took over control and made changes to the page.</sys>\n`
}
}
prompt += '</agent_history>\n\n'
@@ -492,51 +583,22 @@ export class PageAgent extends EventTarget {
}
async #getBrowserState(): Promise<string> {
const pageUrl = await this.pageController.getCurrentUrl()
const pageTitle = await this.pageController.getPageTitle()
const pi = await this.pageController.getPageInfo()
const viewportExpansion = await this.pageController.getViewportExpansion()
await this.pageController.updateTree()
let simplifiedHTML = await this.pageController.getSimplifiedHTML()
const state = await this.pageController.getBrowserState()
let content = state.content
if (this.config.transformPageContent) {
simplifiedHTML = await this.config.transformPageContent(simplifiedHTML)
content = await this.config.transformPageContent(content)
}
let prompt = trimLines(`<browser_state>
Current Page: [${pageTitle}](${pageUrl})
return trimLines(`<browser_state>
Current Page: [${state.title}](${state.url})
Page info: ${pi.viewport_width}x${pi.viewport_height}px viewport, ${pi.page_width}x${pi.page_height}px total page size, ${pi.pages_above.toFixed(1)} pages above, ${pi.pages_below.toFixed(1)} pages below, ${pi.total_pages.toFixed(1)} total pages, at ${(pi.current_page_position * 100).toFixed(0)}% of page
${viewportExpansion === -1 ? 'Interactive elements from top layer of the current page (full page):' : 'Interactive elements from top layer of the current page inside the viewport:'}
${state.header}
${content}
${state.footer}
</browser_state>
`)
// Page header info
const has_content_above = pi.pixels_above > 4
if (has_content_above && viewportExpansion !== -1) {
prompt += `... ${pi.pixels_above} pixels above (${pi.pages_above.toFixed(1)} pages) - scroll to see more ...\n`
} else {
prompt += `[Start of page]\n`
}
// Current viewport info
prompt += simplifiedHTML
prompt += `\n`
// Page footer info
const has_content_below = pi.pixels_below > 4
if (has_content_below && viewportExpansion !== -1) {
prompt += `... ${pi.pixels_below} pixels below (${pi.pages_below.toFixed(1)} pages) - scroll to see more ...\n`
} else {
prompt += `[End of page]\n`
}
prompt += `</browser_state>\n`
return prompt
}
dispose(reason?: string) {
+2 -2
View File
@@ -2,7 +2,7 @@ import type { LLMConfig } from '@page-agent/llms'
import type { PageControllerConfig } from '@page-agent/page-controller'
import type { SupportedLanguage } from '@page-agent/ui'
import type { AgentHistory, ExecutionResult, PageAgent } from '../PageAgent'
import type { ExecutionResult, HistoryEvent, PageAgent } from '../PageAgent'
import type { PageAgentTool } from '../tools'
export type { LLMConfig }
@@ -65,7 +65,7 @@ export interface AgentConfig {
// @todo: remove `this` binding, pass agent as explicit parameter instead
onBeforeStep?: (this: PageAgent, stepCnt: number) => Promise<void> | void
onAfterStep?: (this: PageAgent, stepCnt: number, history: AgentHistory[]) => Promise<void> | void
onAfterStep?: (this: PageAgent, stepCnt: number, history: HistoryEvent[]) => Promise<void> | void
onBeforeTask?: (this: PageAgent) => Promise<void> | void
onAfterTask?: (this: PageAgent, result: ExecutionResult) => Promise<void> | void
+9
View File
@@ -57,6 +57,15 @@ tools.set(
const actualWaitTime = Math.max(0, input.seconds - (Date.now() - lastTimeUpdate) / 1000)
console.log(`actualWaitTime: ${actualWaitTime} seconds`)
await waitFor(actualWaitTime)
this.states.totalWaitTime += input.seconds
if (this.states.totalWaitTime >= 3) {
this.pushObservation(
`You have waited ${this.states.totalWaitTime} seconds accumulatively. Do NOT wait any longer unless you have a good reason.`
)
}
return `✅ Waited for ${input.seconds} seconds.`
},
})
+6 -1
View File
@@ -35,7 +35,12 @@ setTimeout(() => {
window.pageAgent = new PageAgent(config)
} else {
console.log('🚀 page-agent.js no current script detected, using default demo config')
window.pageAgent = new PageAgent()
const config: PageAgentConfig = {
model: DEMO_MODEL,
baseURL: DEMO_BASE_URL,
apiKey: DEMO_API_KEY,
}
window.pageAgent = new PageAgent(config)
}
console.log('🚀 page-agent.js initialized with config:', window.pageAgent.config)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@page-agent/page-controller",
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"main": "./dist/lib/page-controller.js",
"module": "./dist/lib/page-controller.js",
+50 -39
View File
@@ -32,6 +32,20 @@ export interface PageControllerConfig extends dom.DomConfig {
enableMask?: boolean
}
/**
* Structured browser state for LLM consumption
*/
export interface BrowserState {
url: string
title: string
/** Page info + scroll position hint (e.g. "Page info: 1920x1080px...\n[Start of page]") */
header: string
/** Simplified HTML of interactive elements */
content: string
/** Page footer hint (e.g. "... 300 pixels below ..." or "[End of page]") */
footer: string
}
interface ActionResult {
success: boolean
message: string
@@ -93,42 +107,6 @@ export class PageController extends EventTarget {
return window.location.href
}
/**
* Get current page title
*/
async getPageTitle(): Promise<string> {
return document.title
}
/**
* Get page scroll and size info
*/
async getPageInfo() {
return getPageInfo()
}
/**
* Get the simplified HTML representation of the page.
* This is used by LLM to understand the page structure.
*/
async getSimplifiedHTML(): Promise<string> {
return this.simplifiedHTML
}
/**
* Get text description for an element by index
*/
async getElementText(index: number): Promise<string | undefined> {
return this.elementTextMap.get(index)
}
/**
* Get total number of indexed interactive elements
*/
async getElementCount(): Promise<number> {
return this.selectorMap.size
}
/**
* Get last tree update timestamp
*/
@@ -137,10 +115,43 @@ export class PageController extends EventTarget {
}
/**
* Get the viewport expansion setting
* Get structured browser state for LLM consumption.
* Automatically calls updateTree() to refresh the DOM state.
*/
async getViewportExpansion(): Promise<number> {
return this.config.viewportExpansion ?? VIEWPORT_EXPANSION
async getBrowserState(): Promise<BrowserState> {
const url = window.location.href
const title = document.title
const pi = getPageInfo()
const viewportExpansion = this.config.viewportExpansion ?? VIEWPORT_EXPANSION
await this.updateTree()
const content = this.simplifiedHTML
// Build header: page info + scroll position hint
const pageInfoLine = `Page info: ${pi.viewport_width}x${pi.viewport_height}px viewport, ${pi.page_width}x${pi.page_height}px total page size, ${pi.pages_above.toFixed(1)} pages above, ${pi.pages_below.toFixed(1)} pages below, ${pi.total_pages.toFixed(1)} total pages, at ${(pi.current_page_position * 100).toFixed(0)}% of page`
const elementsLabel =
viewportExpansion === -1
? 'Interactive elements from top layer of the current page (full page):'
: 'Interactive elements from top layer of the current page inside the viewport:'
const hasContentAbove = pi.pixels_above > 4
const scrollHintAbove =
hasContentAbove && viewportExpansion !== -1
? `... ${pi.pixels_above} pixels above (${pi.pages_above.toFixed(1)} pages) - scroll to see more ...`
: '[Start of page]'
const header = `${pageInfoLine}\n\n${elementsLabel}\n\n${scrollHintAbove}`
// Build footer: scroll position hint
const hasContentBelow = pi.pixels_below > 4
const footer =
hasContentBelow && viewportExpansion !== -1
? `... ${pi.pixels_below} pixels below (${pi.pages_below.toFixed(1)} pages) - scroll to see more ...`
: '[End of page]'
return { url, title, header, content, footer }
}
// ======= DOM Tree Operations =======
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@page-agent/ui",
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"main": "./dist/lib/page-agent-ui.js",
"module": "./dist/lib/page-agent-ui.js",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@page-agent/website",
"private": true,
"version": "0.0.24",
"version": "0.2.0",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
+6
View File
@@ -7,3 +7,9 @@ export const CDN_DEMO_CN_URL =
export const CDN_FULL_URL = 'https://cdn.jsdelivr.net/npm/@page-agent/cdn/dist/page-agent.js'
export const CDN_FULL_CN_URL =
'https://registry.npmmirror.com/@page-agent/cdn/latest/files/dist/page-agent.js'
// Demo LLM for website testing
export const DEMO_MODEL = 'PAGE-AGENT-FREE-TESTING-RANDOM'
export const DEMO_BASE_URL =
'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'
export const DEMO_API_KEY = 'PAGE-AGENT-FREE-TESTING-RANDOM'
+19 -8
View File
@@ -12,7 +12,13 @@ import { Highlighter } from '../components/ui/highlighter'
import { NeonGradientCard } from '../components/ui/neon-gradient-card'
import { Particles } from '../components/ui/particles'
import { SparklesText } from '../components/ui/sparkles-text'
import { CDN_DEMO_CN_URL, CDN_DEMO_URL } from '../constants'
import {
CDN_DEMO_CN_URL,
CDN_DEMO_URL,
DEMO_API_KEY,
DEMO_BASE_URL,
DEMO_MODEL,
} from '../constants'
function getInjection(useCN?: boolean) {
const cdn = useCN ? CDN_DEMO_CN_URL : CDN_DEMO_URL
@@ -73,13 +79,18 @@ export default function HomePage() {
},
},
// experimentalScriptExecutionTool: true,
// testing server
// @note: rate limit. prompt limit.
// model: DEMO_MODEL,
// baseURL: DEMO_BASE_URL,
// apiKey: DEMO_API_KEY,
model:
import.meta.env.DEV && import.meta.env.LLM_MODEL_NAME
? import.meta.env.LLM_MODEL_NAME
: DEMO_MODEL,
baseURL:
import.meta.env.DEV && import.meta.env.LLM_BASE_URL
? import.meta.env.LLM_BASE_URL
: DEMO_BASE_URL,
apiKey:
import.meta.env.DEV && import.meta.env.LLM_API_KEY
? import.meta.env.LLM_API_KEY
: DEMO_API_KEY,
})
win.pageAgent = pageAgent
}