Skip to content

Commit 3f89e66

Browse files
author
SentienceDEV
committed
Merge pull request #58 from SentienceAPI/auth_inject
Enable auth cookie injection
2 parents 4708be7 + 66b7afc commit 3f89e66

File tree

6 files changed

+539
-8
lines changed

6 files changed

+539
-8
lines changed

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,55 @@ ts-node examples/proxy-example.ts --proxy=http://user:pass@proxy.com:8000
778778

779779
**Note:** The proxy is configured at the browser level, so all traffic (including the Chrome extension) routes through the proxy. No changes to the extension are required.
780780

781+
### Authentication Session Injection
782+
783+
Inject pre-recorded authentication sessions (cookies + localStorage) to start your agent already logged in, bypassing login screens, 2FA, and CAPTCHAs. This saves tokens and reduces costs by eliminating login steps.
784+
785+
```typescript
786+
// Workflow 1: Inject pre-recorded session from file
787+
import { SentienceBrowser, saveStorageState } from 'sentience-ts';
788+
789+
// Save session after manual login
790+
const browser = new SentienceBrowser();
791+
await browser.start();
792+
await browser.getPage().goto('https://example.com');
793+
// ... log in manually ...
794+
await saveStorageState(browser.getContext(), 'auth.json');
795+
796+
// Use saved session in future runs
797+
const browser2 = new SentienceBrowser(
798+
undefined, // apiKey
799+
undefined, // apiUrl
800+
false, // headless
801+
undefined, // proxy
802+
undefined, // userDataDir
803+
'auth.json' // storageState - inject saved session
804+
);
805+
await browser2.start();
806+
// Agent starts already logged in!
807+
808+
// Workflow 2: Persistent sessions (cookies persist across runs)
809+
const browser3 = new SentienceBrowser(
810+
undefined, // apiKey
811+
undefined, // apiUrl
812+
false, // headless
813+
undefined, // proxy
814+
'./chrome_profile', // userDataDir - persist cookies
815+
undefined // storageState
816+
);
817+
await browser3.start();
818+
// First run: Log in
819+
// Second run: Already logged in (cookies persist automatically)
820+
```
821+
822+
**Benefits:**
823+
- Bypass login screens and CAPTCHAs with valid sessions
824+
- Save 5-10 agent steps and hundreds of tokens per run
825+
- Maintain stateful sessions for accessing authenticated pages
826+
- Act as authenticated users (e.g., "Go to my Orders page")
827+
828+
See `examples/auth-injection-agent.ts` for complete examples.
829+
781830
## Best Practices
782831

783832
### 1. Wait for Dynamic Content

examples/auth-injection-agent.ts

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
/**
2+
* Example: Using Authentication Session Injection with Sentience SDK
3+
*
4+
* This example demonstrates how to inject pre-recorded authentication sessions
5+
* (cookies + localStorage) into SentienceBrowser to start agents already logged in.
6+
*
7+
* Two Workflows:
8+
* 1. Inject Pre-recorded Session: Load a saved session from a JSON file
9+
* 2. Persistent Sessions: Use a user data directory to persist sessions across runs
10+
*
11+
* Benefits:
12+
* - Bypass login screens and CAPTCHAs
13+
* - Save tokens and reduce costs (no login steps needed)
14+
* - Maintain stateful sessions across agent runs
15+
* - Act as authenticated users (access "My Orders", "My Account", etc.)
16+
*
17+
* Usage:
18+
* # Workflow 1: Inject pre-recorded session
19+
* ts-node examples/auth-injection-agent.ts --storage-state auth.json
20+
*
21+
* # Workflow 2: Use persistent user data directory
22+
* ts-node examples/auth-injection-agent.ts --user-data-dir ./chrome_profile
23+
*
24+
* Requirements:
25+
* - OpenAI API key (OPENAI_API_KEY) for LLM
26+
* - Optional: Sentience API key (SENTIENCE_API_KEY) for Pro/Enterprise features
27+
* - Optional: Pre-saved storage state file (auth.json) or user data directory
28+
*/
29+
30+
import { SentienceBrowser, SentienceAgent, OpenAIProvider, saveStorageState } from '../src';
31+
import * as fs from 'fs';
32+
import * as readline from 'readline';
33+
34+
async function exampleInjectStorageState() {
35+
console.log('='.repeat(60));
36+
console.log('Example 1: Inject Pre-recorded Session');
37+
console.log('='.repeat(60));
38+
39+
const storageStateFile = 'auth.json';
40+
41+
if (!fs.existsSync(storageStateFile)) {
42+
console.log(`\n⚠️ Storage state file not found: ${storageStateFile}`);
43+
console.log('\n To create this file:');
44+
console.log(' 1. Log in manually to your target website');
45+
console.log(' 2. Use saveStorageState() to save the session');
46+
console.log('\n Example code:');
47+
console.log(' ```typescript');
48+
console.log(' import { SentienceBrowser, saveStorageState } from \'sentience-ts\';');
49+
console.log(' const browser = new SentienceBrowser();');
50+
console.log(' await browser.start();');
51+
console.log(' await browser.getPage().goto(\'https://example.com\');');
52+
console.log(' // ... log in manually ...');
53+
console.log(' await saveStorageState(browser.getContext(), \'auth.json\');');
54+
console.log(' ```');
55+
console.log('\n Skipping this example...\n');
56+
return;
57+
}
58+
59+
const openaiKey = process.env.OPENAI_API_KEY;
60+
if (!openaiKey) {
61+
console.error('❌ Error: OPENAI_API_KEY not set');
62+
return;
63+
}
64+
65+
// Create browser with storage state injection
66+
const browser = new SentienceBrowser(
67+
undefined, // apiKey
68+
undefined, // apiUrl
69+
false, // headless
70+
undefined, // proxy
71+
undefined, // userDataDir
72+
storageStateFile // storageState - inject saved session
73+
);
74+
75+
const llm = new OpenAIProvider(openaiKey, 'gpt-4o-mini');
76+
const agent = new SentienceAgent(browser, llm, 50, true);
77+
78+
try {
79+
console.log('\n🚀 Starting browser with injected session...');
80+
await browser.start();
81+
82+
console.log('🌐 Navigating to authenticated page...');
83+
// Agent starts already logged in!
84+
await browser.getPage().goto('https://example.com/orders'); // Or your authenticated page
85+
await browser.getPage().waitForLoadState('networkidle');
86+
87+
console.log('\n✅ Browser started with pre-injected authentication!');
88+
console.log(' Agent can now access authenticated pages without logging in');
89+
90+
// Example: Use agent on authenticated pages
91+
await agent.act('Show me my recent orders');
92+
await agent.act('Click on the first order');
93+
94+
console.log('\n✅ Agent execution complete!');
95+
96+
} catch (error: any) {
97+
console.error(`\n❌ Error: ${error.message}`);
98+
throw error;
99+
} finally {
100+
await browser.close();
101+
}
102+
}
103+
104+
async function examplePersistentSession() {
105+
console.log('='.repeat(60));
106+
console.log('Example 2: Persistent Session (User Data Directory)');
107+
console.log('='.repeat(60));
108+
109+
const userDataDir = './chrome_profile';
110+
111+
const openaiKey = process.env.OPENAI_API_KEY;
112+
if (!openaiKey) {
113+
console.error('❌ Error: OPENAI_API_KEY not set');
114+
return;
115+
}
116+
117+
// Create browser with persistent user data directory
118+
const browser = new SentienceBrowser(
119+
undefined, // apiKey
120+
undefined, // apiUrl
121+
false, // headless
122+
undefined, // proxy
123+
userDataDir, // userDataDir - persist cookies and localStorage
124+
undefined // storageState
125+
);
126+
127+
const llm = new OpenAIProvider(openaiKey, 'gpt-4o-mini');
128+
const agent = new SentienceAgent(browser, llm, 50, true);
129+
130+
try {
131+
console.log('\n🚀 Starting browser with persistent session...');
132+
await browser.start();
133+
134+
// Check if this is first run (no existing session)
135+
await browser.getPage().goto('https://example.com');
136+
await browser.getPage().waitForLoadState('networkidle');
137+
138+
// First run: Agent needs to log in
139+
// Second run: Agent is already logged in (cookies persist)
140+
if (fs.existsSync(userDataDir)) {
141+
console.log('\n✅ Using existing session from previous run');
142+
console.log(' Cookies and localStorage are loaded automatically');
143+
} else {
144+
console.log('\n📝 First run - session will be saved after login');
145+
console.log(' Next run will automatically use saved session');
146+
}
147+
148+
// Example: Log in (first run) or use existing session (subsequent runs)
149+
await agent.act('Click the sign in button');
150+
await agent.act('Type your email into the email field');
151+
await agent.act('Type your password into the password field');
152+
await agent.act('Click the login button');
153+
154+
console.log('\n✅ Session will persist in:', userDataDir);
155+
console.log(' Next run will automatically use this session');
156+
157+
} catch (error: any) {
158+
console.error(`\n❌ Error: ${error.message}`);
159+
throw error;
160+
} finally {
161+
await browser.close();
162+
}
163+
}
164+
165+
async function exampleSaveStorageState() {
166+
console.log('='.repeat(60));
167+
console.log('Example 3: Save Current Session');
168+
console.log('='.repeat(60));
169+
170+
const openaiKey = process.env.OPENAI_API_KEY;
171+
if (!openaiKey) {
172+
console.error('❌ Error: OPENAI_API_KEY not set');
173+
return;
174+
}
175+
176+
const browser = new SentienceBrowser();
177+
const llm = new OpenAIProvider(openaiKey, 'gpt-4o-mini');
178+
const agent = new SentienceAgent(browser, llm, 50, true);
179+
180+
try {
181+
console.log('\n🚀 Starting browser...');
182+
await browser.start();
183+
184+
console.log('🌐 Navigate to your target website and log in manually...');
185+
await browser.getPage().goto('https://example.com');
186+
await browser.getPage().waitForLoadState('networkidle');
187+
188+
console.log('\n⏸️ Please log in manually in the browser window');
189+
console.log(' Press Enter when you\'re done logging in...');
190+
191+
const rl = readline.createInterface({
192+
input: process.stdin,
193+
output: process.stdout
194+
});
195+
196+
await new Promise<void>(resolve => {
197+
rl.question('', () => {
198+
rl.close();
199+
resolve();
200+
});
201+
});
202+
203+
// Save the current session
204+
const storageStateFile = 'auth.json';
205+
await saveStorageState(browser.getContext(), storageStateFile);
206+
207+
console.log(`\n✅ Session saved to: ${storageStateFile}`);
208+
console.log(' You can now use this file with storageState parameter:');
209+
console.log(` const browser = new SentienceBrowser(..., '${storageStateFile}');`);
210+
211+
} catch (error: any) {
212+
console.error(`\n❌ Error: ${error.message}`);
213+
throw error;
214+
} finally {
215+
await browser.close();
216+
}
217+
}
218+
219+
async function main() {
220+
const args = process.argv.slice(2);
221+
const storageStateArg = args.find(arg => arg.startsWith('--storage-state='));
222+
const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir='));
223+
const saveSession = args.includes('--save-session');
224+
225+
console.log('\n' + '='.repeat(60));
226+
console.log('Sentience SDK - Authentication Session Injection Examples');
227+
console.log('='.repeat(60) + '\n');
228+
229+
if (saveSession) {
230+
await exampleSaveStorageState();
231+
} else if (storageStateArg) {
232+
// Would need to modify example to use provided path
233+
await exampleInjectStorageState();
234+
} else if (userDataDirArg) {
235+
// Would need to modify example to use provided directory
236+
await examplePersistentSession();
237+
} else {
238+
// Run all examples
239+
await exampleSaveStorageState();
240+
console.log('\n');
241+
await exampleInjectStorageState();
242+
console.log('\n');
243+
await examplePersistentSession();
244+
}
245+
246+
console.log('\n' + '='.repeat(60));
247+
console.log('Examples Complete!');
248+
console.log('='.repeat(60));
249+
console.log('\n💡 Tips:');
250+
console.log(' - Use storageState to inject pre-recorded sessions');
251+
console.log(' - Use userDataDir to persist sessions across runs');
252+
console.log(' - Save sessions after manual login for reuse');
253+
console.log(' - Bypass login screens and CAPTCHAs with valid sessions');
254+
console.log(' - Reduce token costs by skipping login steps\n');
255+
}
256+
257+
main().catch(console.error);
258+

0 commit comments

Comments
 (0)