@pmcollab/coworkstream-engine-http
v0.1.0
Published
Universal HTTP AgentRunner adapter for @pmcollab/coworkstream-engine. Wraps any agent reachable over HTTP — covers Python frameworks (LangChain Python, CrewAI, AutoGen, Google ADK, Semantic Kernel) and any custom backend.
Downloads
181
Readme
@pmcollab/coworkstream-engine-http
Coding agents: read
packages/workstream-engine/AGENTS.mdfor the engine integration recipe before wiring this adapter. Migrating an existing setup? Seepackages/workstream-engine/MIGRATION.md.
Universal HTTP AgentRunner adapter. POSTs items to a customer-hosted endpoint and reads the response.
This is the bridge for non-JS agents. Host your Python LangChain / CrewAI / AutoGen / Google ADK / Semantic Kernel agent behind FastAPI, LiteServe, or whatever HTTP runtime you prefer; this adapter is the JS-side glue.
Install
npm install @pmcollab/coworkstream-engine-httpUse
import { createEngine } from '@pmcollab/coworkstream-engine'
import { createHttpAgent } from '@pmcollab/coworkstream-engine-http'
const agent = createHttpAgent({
id: 'risk-py',
url: 'https://agents.internal.example.com/risk/decide',
headers: { authorization: `Bearer ${process.env.AGENT_TOKEN}` },
timeoutMs: 30_000,
retries: 1,
})
const engine = createEngine({ agents: [agent], /* ... */ })Server contract
The endpoint must accept POST and respond with JSON:
POST /<your-endpoint>
Content-Type: application/json
X-Workstream-Trace-Id: <uuid> # auto-set by the adapter
X-Workstream-Attempt: 1Request body:
{
"item": { /* WorkStreamItem */ },
"ctx": { "trust": 0.5 }
}Response body:
{ "position": "approve", "reasoning": "within budget", "confidence": 0.8 }Python example (FastAPI + LangChain)
from fastapi import FastAPI
from pydantic import BaseModel
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
app = FastAPI()
llm = ChatAnthropic(model='claude-sonnet-4-6')
class Request(BaseModel):
item: dict
ctx: dict
@app.post('/risk/decide')
async def decide(req: Request):
prompt = ChatPromptTemplate.from_messages([
('system', 'You are a risk reviewer. Respond with JSON.'),
('user', f"Decide on: {req.item['title']}"),
])
response = await (prompt | llm).ainvoke({})
# parse `response.content` into { position, reasoning, confidence } and return
return { 'position': 'approve', 'reasoning': response.content, 'confidence': 0.7 }Options
createHttpAgent({
id, url, // required
name?, avatar?, capabilities?,
headers?: Record<string, string>,
timeoutMs?: number, // default 30_000
fetchFn?: typeof fetch, // override global fetch
defaultConfidence?: number, // default 0.7
toRequestBody?: (item, ctx) => unknown,
fromResponse?: (json, item, ctx) => { position, reasoning, confidence },
retries?: number, // default 0
retryDelayMs?: number, // default 500 (exponential backoff)
})License
Commercial. See LICENSE in the repository root.
