Repository navigation
Expand file tree
/
Copy pathrun-agent-quack.ts
More file actions
101 lines (95 loc) · 3.6 KB
/
Copy pathrun-agent-quack.ts
File metadata and controls
101 lines (95 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* eslint-disable no-console -- the example prints to the terminal */
// Run only the agent with runAgent, against a local PostHog stack.
//
// npx tsx --tsconfig tsconfig.json docs/examples/run-agent-quack.ts
//
// Needs local PostHog on :8010 (with its ai-gateway) and context-mill on :8765.
// POSTHOG_PERSONAL_API_KEY logs in. WIZARD_CI_GATEWAY_TOKEN_FILE holds the gateway token.
// QUACK_INSTALL_DIR sets the project the agent runs in (default: the current directory).
import { runAgent, RunOutcome } from '@agent';
import type { RunConfig, RunInput } from '@agent/types';
import {
Harness,
HAIKU_MODEL,
Sequence,
getSkillsBaseUrl,
} from '@shared/constants';
import { resolveApiKeyProject } from '@shared/api-key-login';
import { readCiGatewayCredential } from '@shared/ci-gateway';
import { initLocalDev, POSTHOG_LOCAL_URL } from '@shared/local-dev';
// Point PostHog, skills and MCP at the local stack, like --local-posthog --local-context-mill --local-mcp.
initLocalDev({ localPosthog: true, localContextMill: true, localMcp: true });
// Log in with keys instead of the browser, the same way --ci does.
const apiKey = process.env.POSTHOG_PERSONAL_API_KEY;
if (!apiKey) throw new Error('Set POSTHOG_PERSONAL_API_KEY');
const programId = 'posthog-integration'; // a program the local gateway admits
const { host, project, apiUser } = await resolveApiKeyProject(apiKey, {
baseUrl: POSTHOG_LOCAL_URL,
localMcp: true,
onWarning: (message) => console.warn(message),
});
// What the agent runs: one prompt, a small model, no Write, Edit or Bash.
const config: RunConfig = {
programId, // pins the gateway spend
run: {
integrationLabel: 'quack',
prompt: () => 'Reply with the single word quack. Use no tools.',
collectTranscript: true, // keep the agent's output for snapshot.transcriptTail
requestRemark: false, // no closing remark
spinnerMessage: 'Quacking...',
successMessage: 'Quacked',
estimatedDurationMinutes: 1,
reportFile: '',
docsUrl: 'https://posthog.com/docs',
},
composed: true, // a sub-run: no terminal outro
// Linear on the Anthropic harness keeps the transcript. With no flags, the agent runs this binding as is.
routing: {
binding: {
sequence: Sequence.linear,
harness: Harness.anthropic,
model: HAIKU_MODEL,
},
},
skillsBaseUrl: getSkillsBaseUrl(),
wizardFlags: {},
wizardFlagPayloads: {},
disallowedTools: ['Write', 'Edit', 'Bash'],
};
// Where and as whom: the project, the login and the flags.
const input: RunInput = {
installDir: process.env.QUACK_INSTALL_DIR ?? process.cwd(),
// Use the token in WIZARD_CI_GATEWAY_TOKEN_FILE at WIZARD_CI_GATEWAY_URL instead of minting one.
credentials: {
accessToken: apiKey,
projectApiKey: project.api_token,
host,
projectId: project.id,
gateway: readCiGatewayCredential('us'),
},
project,
apiUser,
flags: {
ci: false,
signup: false,
debug: false,
e2eAsk: false,
localMcp: true,
captureAio: false,
benchmark: false,
yaraReport: false,
},
host: { baseUrl: POSTHOG_LOCAL_URL },
};
// Run it. Each step the agent takes arrives as one activity line.
const result = await runAgent(config, input, {
onProgress: (event) => {
if (event.kind === 'activity') console.log(`activity: ${event.line}`);
},
});
// Every ending resolves to a result. Print the reply and the outcome.
console.log(`transcriptTail: ${result.snapshot.transcriptTail ?? ''}`);
console.log(`outcome: ${result.outcome}`);
if (result.outcome !== RunOutcome.Success)
console.log(`failure: ${result.failure.message}`);
process.exit(result.outcome === RunOutcome.Success ? 0 : 1);