Skip to content

Agent wip#140

Open
bedus-creation wants to merge 24 commits into
task/langchain-agent-test-harnessfrom
agent-wip
Open

Agent wip#140
bedus-creation wants to merge 24 commits into
task/langchain-agent-test-harnessfrom
agent-wip

Conversation

@bedus-creation

Copy link
Copy Markdown
Contributor

No description provided.

ViteProvider now binds a Jinja2Templates engine out of the box so fresh
apps get a working template engine and the vite() globals are injected
during boot. An existing 'templates' binding always wins, keeping the
change backward-compatible.

- Add ViteConfig.template and ViteConfig.templates_directory flags
- Auto-bind templates in ViteProvider.register() with a guarded jinja2
  import that points users to the [vite] extra
- Add Template class and template() helper (Laravel view()-style) that
  resolve the request from context or a per-request ContextVar
- Add RequestContextMiddleware to expose the active request
- Export Template and template from fastapi_startkit.vite
- Cover the new behaviour with tests
- Simplify example/vite-app to rely on the auto-bound engine
feat(vite): auto-load templates + Template helper + config flag
…to-templates

Revert "feat(vite): auto-load templates + Template helper + config flag"
Fresh apps got no template engine because ViteProvider only injected the
vite() globals when a "templates" binding already existed. The provider
now binds a Jinja2Templates engine out of the box, config-gated and
backward-compatible.

- Add ViteConfig.template (default True) and
  ViteConfig.templates_directory (default "resources/templates")
- ViteProvider.register() binds "templates" when enabled and none is
  pre-bound; an existing binding always wins. The jinja2 import is
  guarded with a clear "install fastapi-startkit[vite]" message
- Publish the template stub under resources/templates/index.html so all
  scaffolding stays consistent under resources/
- Sync the example app's config/vite.py with the new fields
- Cover binding, override, disabled, post-boot globals and the missing
  jinja2 error in tests/vite/

Rendering stays the standard Starlette way:
app.make("templates").TemplateResponse(request, name, context).
…templates

feat(vite): auto-load Jinja2 templates from the Vite provider
Re-export the full set of public relationship classes (including
MorphMany, MorphOne, MorphToMany, and BaseRelationship) from
fastapi_startkit.masoniteorm so they can be imported directly from the
package root instead of the .relationships submodule.

Switch in-repo example models, fixtures, and tests to the root import.
Pure re-export — no behavior change.
…tionships

Re-export ORM relationship classes from masoniteorm package root
…vider default

Move the example templates into resources/templates to match ViteConfig's
default templates_directory, and drop the bootstrap override so the example
relies on ViteProvider's auto-bound Jinja2Templates engine.
Use `from fastapi_startkit.application import app` -> app().make('templates')
in the example route instead of the bootstrap module, matching the framework's
canonical app accessor (no top-level export).
Relocate providers/ to app/providers/ and update the bootstrap import,
grouping application code under the app/ namespace.
Add HttpTestCase-based tests covering the health endpoint and the index
page render (templates resolve from resources/templates with vite globals).
Wire up pytest config and dev dependencies.
Resolve conflicts in vite-app bootstrap/application.py and routes/web.py,
keeping the app/ provider package layout and canonical app() template
accessor. Restore FastAPIProvider without the stale templates binding so
ViteProvider serves templates from resources/templates.

Remove tests/vite/test_vite.py per request.
Rely on the built manifest so the vite() directive resolves to
production asset URLs, and drop the dev-server hot file setup. Assert
against the built /build/assets/ output instead of the source path.
Also remove the stale ViteProvider comment in bootstrap.
Match the routes/web.py module and the TestWebRoutes class it covers.
Keep the index page test focused on a successful render.
feat(vite): re-export ViteConfig from vite package root
…I intact

Swap the per-provider SDK internals of ai/agent.py (_run/_stream over the
anthropic/openai/google SDKs) for a single LangChain/LangGraph backend:
init_chat_model builds the chat model and create_agent drives the tool loop,
with the final AIMessage mapped back to AgentResponse. The user-facing surface
is unchanged — prompt/stream/fake/assert_prompted/assert_not_prompted/reset,
the lifecycle hooks, and the decorators keep identical signatures.

- _build_model() is the seam tests patch to inject a fake chat model.
- _build_messages() now renders attachments via Document.to_langchain_block().
- Add Document.to_langchain_block(): inline text, base64 image/file blocks.
- Add ai/fakes.py fake_chat_model(): replays scripted AIMessage turns through a
  GenericFakeChatModel (bind_tools no-op) so the real create_agent loop runs
  offline; exported from the ai package root.
- New optional [langgraph] extra (langchain + langchain-core + langgraph).

The 23 tests in tests/ai/test_agent_fake.py stay green and unmodified (fake()
short-circuits before the backend). Adds tests/ai/test_agent_langgraph_backend.py
exercising the real loop offline: simple reply, full tool-calling loop, usage
mapping, attachment blocks, provider mapping, and streaming.
…ent through it

Turn ai/config.py into a config package and resolve models/providers through a
new Lab helper instead of hardcoded dicts on the Agent.

- ai/config/: split provider dataclasses (config.py) from the top-level AIConfig
  (ai.py), add config/__init__.py re-exporting them, and give each provider a
  models map keyed by modality (default / default_image / default_audio /
  default_transcribe). Fix the draft's circular import (AIConfig imported the
  provider configs from the package root mid-init) and the placeholder model
  values (google text default, elevenlabs models).
- AIConfig selects the default provider per modality: default (text),
  default_image, default_audio, default_transcribe. image.py/audio.py now read
  default_image/default_audio (was image_provider/audio_provider).
- ai/lab.py: Lab(StrEnum) + ModelType resolve the provider, default model, and
  the "<langchain-provider>:<model>" URL from Config (google → google_genai).
- Agent: _resolve_model() and _build_model() now go through Lab; removed the
  stale _DEFAULT_MODELS/_LANGCHAIN_PROVIDERS references and the dead
  _execute_tool() (create_agent runs tools itself).
- Tests: drop the _build_model monkeypatch helper; the backend tests now patch
  the real langchain.chat_models.init_chat_model seam via pytest monkeypatch.
  Add test_lab.py; update image/audio provider-selection mocks.

The 23 tests in tests/ai/test_agent_fake.py stay green and unmodified.
…l loop

Replace the LangGraph create_agent backend with a plain init_chat_model call
driven by a Runner that resolves and executes tool calls itself.

- runner.py: Runner(model, tools, max_steps) binds tools, invokes the model,
  executes requested tool calls, feeds results back, loops to a final answer;
  StreamRunner yields content tokens through the same loop. Fully typed.
- Agent._run/_stream delegate to Runner/StreamRunner (threading _max_steps);
  no create_agent.
- System message is declarative via instructions()/_instructions — removed the
  per-call system= and messages= arguments from prompt()/stream().
- Resolve provider/model through Lab directly (dropped the _lab() helper) and
  import Lab at module top.
- Config split into ai/config/{ai,config}.py.

KNOWN RED: ai/config/__init__.py is absent, so 'from fastapi_startkit.ai.config
import AIConfig' fails — the AI test suite does not collect and AIProvider import
breaks. Backend tests also still assume the old create_agent result shape and the
tuple return of _build_messages. Follow-ups.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant