Repository navigation
feat: allow AIO and Logs in default integrations #1235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
44d87d4
b8df80d
63c6f0a
5b30cf1
5d2fcd4
27467a8
50039c9
6f85957
b8f2631
378a23b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -89,7 +89,21 @@ export function renderToolInventory(toolNames: readonly string[]): string { | |
|
|
||
| const TASK_BASICS = `You are one step in a larger PostHog workflow made of several tasks, run as a fresh agent with no memory of the other tasks beyond the context you are given. Other tasks — before and after you — own the rest of the work, so stay strictly on your own task: do not do a neighbouring step's job, redo what an upstream handoff already did, or reach beyond what you were asked. Do only your task, then report exactly once by calling complete_task with a structured handoff: what your goal was, what you did, and what the next agent should know. When you are given context from previous steps, trust it — those agents already did their work, so do not re-verify or re-read what their handoffs tell you. Build on it and move fast. Read a file before you edit it, so your own changes do not duplicate what is already there. Work only inside this project's own directory: never read, list, or search (find, ls, grep, glob) outside it — not the OS, not other projects, not global package caches. If your task seems to need something outside this directory, it does not — skip that part and say so in your handoff rather than hunting across the filesystem. If your task does not apply to this project — there is genuinely nothing for it to do — report it with status \`not needed\` and say why, rather than marking it done.`; | ||
|
|
||
| const SEED_BASICS = `You are the orchestrator. Plan the work and seed the queue with enqueue_task — each call returns an id you can pass as a dependency to a later task. Give each task a short label for the UI — the action in a few words, not file names, class names, or other specifics. The last task you queue, the one that reports on the run, must depend on every other task in the queue — directly, or through a task it already depends on. You are not a task yourself: do not call complete_task and do not edit the project.`; | ||
| const SEED_BASICS = `You are the orchestrator. Plan the work and seed the queue with enqueue_task — each call names the task kind in its \`type\` field (the tool has no \`task\` field) and returns an id you can pass as a dependency to a later task. Give each task a short label for the UI — the action in a few words, not file names, class names, or other specifics. The last task you queue, the one that reports on the run, must depend on every other task in the queue — directly, or through a task it already depends on. You are not a task yourself: do not call complete_task and do not edit the project.`; | ||
|
|
||
| /** | ||
| * Injected only when the run excludes task types (a flag or CI gate), so the | ||
| * seed prompt of an ordinary run is byte-identical to one with no exclusions. | ||
| * Naming the types beats a "check the tool's list" rule: the planner has | ||
| * nothing to infer, and the pre-queued (runner-seeded) tasks — absent from the | ||
| * enqueue list by design — cannot be mistaken for exclusions. | ||
| */ | ||
| function excludedTypesNote(types: readonly string[]): string | null { | ||
| if (types.length === 0) return null; | ||
| return `The plan below may mention these task types, but this run excludes them: ${types.join( | ||
| ', ', | ||
| )}. enqueue_task will not accept them — do not queue them, do not retry them, and hang nothing off them.`; | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's the potential issue: The prompt tells the planner that task types were excluded even when they weren’t available in this flow. Overlapping exclusions can also list the same type twice.
Suggested fix: Build the note from task types actually removed from the flow, and list each type once. |
||
|
|
||
| /** | ||
| * Tasks the wizard queued before the planner ran. It has to see them: they are | ||
|
|
@@ -147,8 +161,15 @@ export function assembleSeedPrompt( | |
| ctx: OrchestratorPromptContext, | ||
| body: string, | ||
| preQueued: readonly { id: string; type: string }[] = [], | ||
| excludedTypes: readonly string[] = [], | ||
| ): string { | ||
| return [projectContext(ctx), SEED_BASICS, preQueuedTasks(preQueued), body] | ||
| return [ | ||
| projectContext(ctx), | ||
| SEED_BASICS, | ||
| excludedTypesNote(excludedTypes), | ||
| preQueuedTasks(preQueued), | ||
| body, | ||
| ] | ||
| .filter(Boolean) | ||
| .join('\n\n'); | ||
| } | ||
|
|
@@ -214,6 +235,8 @@ export interface AgentPrompt { | |
| * one an agent can reach — it can neither invent the task nor forget it. | ||
| */ | ||
| runnerSeeded: boolean; | ||
| /** Marks a supplementary task: terminal failure unblocks dependents and never fails the run. */ | ||
| optional: boolean; | ||
| /** Per-harness model/effort; both profiles also require gateway admission and prompt compatibility. */ | ||
| modelPi?: string; | ||
| effortPi?: ThinkingLevel; | ||
|
|
@@ -258,6 +281,15 @@ export interface AgentRegistry { | |
| readonly sinkTypes: string[]; | ||
| /** The types only the wizard queues, from what it detected before the run. */ | ||
| readonly runnerSeededTypes: string[]; | ||
| /** The types whose terminal failure must not block dependents or fail the run. */ | ||
| readonly optionalTypes: string[]; | ||
| /** | ||
| * The excluded types this flow actually had, deduped — the honest list for | ||
| * the seed prompt's exclusion note. An exclusion naming a type the flow | ||
| * never carried is dropped: telling the planner it was "excluded" would | ||
| * describe work that was never available. | ||
| */ | ||
| readonly excludedTypes: string[]; | ||
| /** The flow's planner, the one prompt marked `seed: true` in its frontmatter. */ | ||
| readonly seed?: AgentPrompt; | ||
| get(type: string): AgentPrompt | undefined; | ||
|
|
@@ -293,11 +325,16 @@ export function buildRegistry( | |
| }); | ||
| const byType = new Map(inFlow.map((p) => [p.type, p])); | ||
| const tasks = inFlow.filter((p) => !p.seed); | ||
| const flowTypes = new Set( | ||
| prompts.filter((p) => p.flow === flow && !p.seed).map((p) => p.type), | ||
| ); | ||
| return { | ||
| types: tasks.map((p) => p.type), | ||
| enqueueableTypes: tasks.filter((p) => !p.runnerSeeded).map((p) => p.type), | ||
| sinkTypes: tasks.filter((p) => p.sink).map((p) => p.type), | ||
| runnerSeededTypes: tasks.filter((p) => p.runnerSeeded).map((p) => p.type), | ||
| optionalTypes: tasks.filter((p) => p.optional).map((p) => p.type), | ||
| excludedTypes: [...excluded].filter((t) => flowTypes.has(t)), | ||
| seed: inFlow.find((p) => p.seed), | ||
| get: (type) => byType.get(type), | ||
| }; | ||
|
|
@@ -391,6 +428,7 @@ export function parseAgentPrompt( | |
| seed: fields.seed === 'true', | ||
| sink: fields.sink === 'true', | ||
| runnerSeeded: fields.runnerSeeded === 'true', | ||
| optional: fields.optional === 'true', | ||
| modelPi: str(fields.model_pi), | ||
| effortPi: effort(fields.effort_pi, 'effort_pi'), | ||
| modelSdk: str(fields.model_sdk), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if excluding tasks from planner agent, include this prompt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mannnn I can't wait for Jev. Jev would be the perfect enqueue agent and prompt assembler