picatz / picatz/flowstate

The model-provider plugin family: openai, anthropic, and OpenAI-compatible peers — distinct from the agent-CLI plugins

Open
#192 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

design enhancement kind/design-record
Dominant language
Go
Stars
9
Forks
0
Avg merge
3h 3m
Merged PRs (30d)
509

Description

A family distinct from codex (#162/#191). The line, stated first because it is the whole design: codex/claude-code are agent binaries — a CLI with its own sandbox, loop, and tools, run as a subprocess. openai/anthropic are model APIs — network clients a developer builds on. Different substrate (subprocess vs HTTP), different containment (ephemeral CODEX_HOME vs egress+key-as-secret), different use case (run an agent vs compose model calls into a workflow). Same discipline, deliberately separate plugins so neither compromises to fit the other.

The openai plugin — model API as composable tasks

A developer using flow to build on the OpenAI API, durably: each API surface a bounded task, results as typed values CEL composes over (#177), key as secret_inputs (#160), egress under netpolicy, HTTP bounded below the library (the RoundTripper lesson). Candidate verbs, gated by real need per the Go-stdlib rule:

  • openai.responses (the modern primary surface — chat/completions is the legacy shape; lead with Responses): prompt/messages in, structured output out, tool-call requests surfaced as typed values a workflow can dispatch on (the agentic-graph payoff — a model's tool call becomes a flowstate step, so the orchestration is the workflow's, durable and inspectable, not hidden in a library loop).
  • Embeddings → typed vectors, feeding a vector-store task or the sql/pgvector path (#181 convergence).
  • Threads / assistants / RAG surfaces: real but stateful and rapidly-changing — the containment question is where the durable state lives. A thread id is a reference; the workflow holds it, the API holds the state. This wants the same source-of-truth-is-upstream discipline #191 established (pin what you build against; the API moves fast), and is the slice most likely to need live testing before it's trusted.
  • Files / vector stores / batch: batch especially is a natural durable-workflow fit (submit → wait on completion → collect — the poll-loop the loop:/wait primitives exist for).

OpenAI-compatible peers, cohesively

The API shape is a de-facto standard (Azure OpenAI, together, groq, vLLM, ollama, openrouter). The plugin takes an explicit base_url + key, so a compatible endpoint is configuration, not a fork — the same no-provider-lock-in property git.* has (#186), applied to inference. Compatibility gaps are documented per-endpoint, not papered (some peers lack Responses, or tool-calling, or embeddings) — declared, with the plugin refusing an unsupported verb against a configured peer rather than failing cryptically.

anthropic / claude, the sibling

Same family, its own plugin (Messages API, its own tool-use shape, prompt caching, its own streaming): a peer, not a variant — because forcing two providers' genuinely-different surfaces through one schema is the wrapper-module antipattern (#172). What they SHARE is a small, honest core worth factoring only if it earns it: secret handling, egress discipline, retry/UnavailableAfter classification, token-usage output shape — candidates for a shared pkg the provider plugins consume, decided when the second plugin makes the duplication real (not before — premature sharing is its own debt).

The cohesion that makes it a family, not a pile

Every model-provider task: typed I/O (#177), key-as-secret (#160), egress-policed, HTTP-bounded, tool-calls-as-workflow-steps (the durable-orchestration thesis), source-of-truth-upstream docs (#191), examples with the live-testing gaps named honestly. The agentic use cases (a model call in a loop: that proposes, a tool call dispatched to a git/sql step, a human wait_for_signal in the middle) compose from primitives already shipping — these plugins are the inputs to those graphs, codex is one kind of input, and the workflow is where the intelligence is orchestrated durably.

Named-not-scheduled; openai.responses + embeddings is the first slice when a workload asks, designed against upstream as truth, claude as the immediately-following sibling.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No implementation files, tests, or entry points are named. Start by reading issues #160, #177, #181, and #191 alongside the existing plugin conventions, then narrow the proposed openai.responses and embeddings slice into an actionable scope with compatibility gaps, live-testing needs, and completion criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
ai, api, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.