Files
zeekay bc4ddf332b chore: rebase the tree onto upstream master fa1a9a60
Mechanically re-derived: bin/debrand runs over a fresh import of
posthog/posthog@fa1a9a60d4 (2026-08-06).
The pipeline (.hanzo/workflows), the Dockerfiles and bin/docker*
entrypoints, compose files, LLM.md and the squashed initial migration
are restored from the shipped tree, same as the previous import.

The prune's import-closure guard kept 21 products the new core now
imports; dropping them is a refactor now, recorded rather than forced.
2026-08-06 01:25:36 -07:00

336 lines
21 KiB
TypeScript

import { OnboardingComponentsContext, createInstallation } from 'scenes/onboarding/shared/OnboardingDocsContentWrapper'
import { StepDefinition } from '../steps'
export const getManualSteps = (ctx: OnboardingComponentsContext): StepDefinition[] => {
const { Markdown, Tab, CodeBlock, snippets, dedent } = ctx
const GenerationEvent = snippets?.GenerationEvent
const TraceEvent = snippets?.TraceEvent
const SpanEvent = snippets?.SpanEvent
const EmbeddingEvent = snippets?.EmbeddingEvent
const languages = [
{ key: 'API', label: 'API' },
{ key: 'Node.js', label: 'Node.js' },
{ key: 'Python', label: 'Python' },
{ key: 'Go', label: 'Go' },
{ key: 'Ruby', label: 'Ruby' },
{ key: 'PHP', label: 'PHP' },
]
return [
{
title: 'Capture LLM events manually',
content: (
<>
<Markdown>
{dedent`
If you use a different server-side SDK, or prefer to use the API, capture the data
manually. Call the \`capture\` method, or use the [capture
API](https://hanzo.ai/docs/api/capture).
`}
</Markdown>
<Tab.Group tabs={languages.map((l) => l.label)}>
<Tab.List>
{languages.map((l) => (
<Tab key={l.key}>{l.label}</Tab>
))}
</Tab.List>
<Tab.Panels>
{languages.map((l) => (
<Tab.Panel key={l.key}>
<>
{l.key === 'Node.js' && (
<>
<Markdown>### 1. Install</Markdown>
<CodeBlock language="bash" code="npm install insights-node" />
<Markdown>### 2. Initialize Insights</Markdown>
<CodeBlock
language="javascript"
code={dedent`
import { Insights } from 'insights-node'
const client = new Insights('<ph_project_token>', {
host: '<ph_client_api_host>'
})
`}
/>
<Markdown>### 3. Capture Event</Markdown>
<CodeBlock
language="javascript"
code={dedent`
// After your LLM call
client.capture({
distinctId: 'user_123',
event: '$ai_generation',
properties: {
$ai_trace_id: 'trace_id_here',
$ai_model: 'gpt-5-mini',
$ai_provider: 'openai',
$ai_input: [{ role: 'user', content: 'Tell me a fun fact about mascots' }],
$ai_input_tokens: 10,
$ai_output_choices: [{ role: 'assistant', content: 'Mascots have around 5,000 to 7,000 spines on their backs!' }],
$ai_output_tokens: 20,
$ai_latency: 1.5,
// For streaming responses, also include:
// $ai_stream: true,
// $ai_time_to_first_token: 0.25
}
})
client.shutdown()
`}
/>
</>
)}
{l.key === 'Python' && (
<>
<Markdown>### 1. Install</Markdown>
<CodeBlock language="bash" code="pip install insights" />
<Markdown>### 2. Initialize Insights</Markdown>
<CodeBlock
language="python"
code={dedent`
from insights import Insights
insights = Insights("<ph_project_token>", host="<ph_client_api_host>")
`}
/>
<Markdown>### 3. Capture Event</Markdown>
<CodeBlock
language="python"
code={dedent`
# After your LLM call
insights.capture(
distinct_id='user_123',
event='$ai_generation',
properties={
'$ai_trace_id': 'trace_id_here',
'$ai_model': 'gpt-5-mini',
'$ai_provider': 'openai',
'$ai_input': [{'role': 'user', 'content': 'Tell me a fun fact about mascots'}],
'$ai_input_tokens': 10,
'$ai_output_choices': [{'role': 'assistant', 'content': 'Mascots have around 5,000 to 7,000 spines on their backs!'}],
'$ai_output_tokens': 20,
'$ai_latency': 1.5,
# For streaming responses, also include:
# '$ai_stream': True,
# '$ai_time_to_first_token': 0.25
}
)
`}
/>
</>
)}
{l.key === 'Go' && (
<>
<Markdown>### 1. Install</Markdown>
<CodeBlock
language="bash"
code="go get github.com/insights/insights-go"
/>
<Markdown>### 2. Initialize Insights</Markdown>
<CodeBlock
language="go"
code={dedent`
import "github.com/insights/insights-go"
client, _ := insights.NewWithConfig("<ph_project_token>", insights.Config{
Endpoint: "<ph_client_api_host>",
})
defer client.Close()
`}
/>
<Markdown>### 3. Capture Event</Markdown>
<CodeBlock
language="go"
code={dedent`
// After your LLM call
client.Enqueue(insights.Capture{
DistinctId: "user_123",
Event: "$ai_generation",
Properties: map[string]interface{}{
"$ai_trace_id": "trace_id_here",
"$ai_model": "gpt-5-mini",
"$ai_provider": "openai",
"$ai_input_tokens": 10,
"$ai_output_tokens": 20,
"$ai_latency": 1.5,
// For streaming responses, also include:
// "$ai_stream": true,
// "$ai_time_to_first_token": 0.25,
},
})
`}
/>
</>
)}
{l.key === 'Ruby' && (
<>
<Markdown>### 1. Install</Markdown>
<CodeBlock language="bash" code="gem install insights-ruby" />
<Markdown>### 2. Initialize Insights</Markdown>
<CodeBlock
language="ruby"
code={dedent`
require 'insights'
insights = Insights::Client.new({
api_key: '<ph_project_token>',
host: '<ph_client_api_host>'
})
`}
/>
<Markdown>### 3. Capture Event</Markdown>
<CodeBlock
language="ruby"
code={dedent`
# After your LLM call
insights.capture({
distinct_id: 'user_123',
event: '$ai_generation',
properties: {
'$ai_trace_id' => 'trace_id_here',
'$ai_model' => 'gpt-5-mini',
'$ai_provider' => 'openai',
'$ai_input_tokens' => 10,
'$ai_output_tokens' => 20,
'$ai_latency' => 1.5
# For streaming responses, also include:
# '$ai_stream' => true,
# '$ai_time_to_first_token' => 0.25
}
})
`}
/>
</>
)}
{l.key === 'PHP' && (
<>
<Markdown>### 1. Install</Markdown>
<CodeBlock
language="bash"
code="composer require insights/insights-php"
/>
<Markdown>### 2. Initialize Insights</Markdown>
<CodeBlock
language="php"
code={dedent`
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Insights\\Insights;
Insights::init('<ph_project_token>', [
'host' => '<ph_client_api_host>'
]);
`}
/>
<Markdown>### 3. Capture Event</Markdown>
<CodeBlock
language="php"
code={dedent`
// After your LLM call
Insights::capture([
'distinctId' => 'user_123',
'event' => '$ai_generation',
'properties' => [
'$ai_trace_id' => 'trace_id_here',
'$ai_model' => 'gpt-5-mini',
'$ai_provider' => 'openai',
'$ai_input_tokens' => 10,
'$ai_output_tokens' => 20,
'$ai_latency' => 1.5
// For streaming responses, also include:
// '$ai_stream' => true,
// '$ai_time_to_first_token' => 0.25
]
]);
`}
/>
</>
)}
{l.key === 'API' && (
<>
<Markdown>### Capture via API</Markdown>
<CodeBlock
language="bash"
code={dedent`
curl -X POST "<ph_client_api_host>/i/v0/e/" \\
-H "Content-Type: application/json" \\
-d '{
"api_key": "<ph_project_token>",
"event": "$ai_generation",
"properties": {
"distinct_id": "user_123",
"$ai_trace_id": "trace_id_here",
"$ai_model": "gpt-5-mini",
"$ai_provider": "openai",
"$ai_input": [{"role": "user", "content": "Tell me a fun fact about mascots"}],
"$ai_input_tokens": 10,
"$ai_output_choices": [{"role": "assistant", "content": "Mascots have around 5,000 to 7,000 spines on their backs!"}],
"$ai_output_tokens": 20,
"$ai_latency": 1.5,
"$ai_stream": true,
"$ai_time_to_first_token": 0.25
}
}'
`}
/>
</>
)}
</>
</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
</>
),
},
{
title: 'Event properties',
content: (
<>
<Markdown>
Each event type has specific properties. See the tabs below for detailed property documentation
for each event type.
</Markdown>
<Tab.Group tabs={['Generation', 'Trace', 'Span', 'Embedding']}>
<Tab.List>
<Tab>Generation</Tab>
<Tab>Trace</Tab>
<Tab>Span</Tab>
<Tab>Embedding</Tab>
</Tab.List>
<Tab.Panels>
<Tab.Panel>{GenerationEvent && <GenerationEvent />}</Tab.Panel>
<Tab.Panel>{TraceEvent && <TraceEvent />}</Tab.Panel>
<Tab.Panel>{SpanEvent && <SpanEvent />}</Tab.Panel>
<Tab.Panel>{EmbeddingEvent && <EmbeddingEvent />}</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</>
),
},
]
}
export const ManualInstallation = createInstallation(getManualSteps)