mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
feat(durable): expose models on ToolExecutionApi and HookApi
closes #10395
This commit is contained in:
parent
68ccef1760
commit
b0114ef5fa
5 changed files with 37 additions and 0 deletions
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- `ToolExecutionApi.models` and `HookApi.models`: the Harness's `models`, so tools and hooks can resolve models and make requests with the same catalog, credentials, and request transforms as generation ([#10395](https://github.com/earendil-works/pi/issues/10395)).
|
||||
|
||||
### Changed
|
||||
|
||||
- Within one task invocation, `runtime.context()` reuses the range its previous read scanned and reads only entries committed since then, unless the head marker changed. A generation's request no longer rereads the whole transcript after its prepare, which roughly halves context reads per turn. The range is dropped when the invocation ends or sleeps.
|
||||
|
|
|
|||
|
|
@ -2561,6 +2561,8 @@ type HookResult<T> = T | undefined | Promise<T | undefined>;
|
|||
interface HookApi extends DocumentReader {
|
||||
readonly taskId: TaskId;
|
||||
readonly conversationId: ConversationId;
|
||||
/** `HarnessOptions.models`. */
|
||||
readonly models: Models;
|
||||
memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;
|
||||
memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;
|
||||
}
|
||||
|
|
@ -2693,6 +2695,8 @@ interface ToolExecutionApi<TDetails extends JsonValue = JsonValue> extends Docum
|
|||
readonly registry: RegistrySnapshot;
|
||||
/** The calling conversation's agent, as the tool task's phase resolved it. */
|
||||
agent(context: Context): Promise<Agent>;
|
||||
/** `HarnessOptions.models`: the catalog, credentials, and request transforms generation uses. */
|
||||
readonly models: Models;
|
||||
/** Built by `HarnessOptions.env` for this call. */
|
||||
readonly env: ExecutionEnv | undefined;
|
||||
output(chunk: string | Uint8Array): void;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ async function run(
|
|||
callId: call.id,
|
||||
registry: runtime.registry,
|
||||
agent: runtime.agent,
|
||||
models: runtime.models,
|
||||
output: (chunk, skipped) => {
|
||||
assertLive();
|
||||
if (reported.output.push(chunk, skipped)) progress.mark();
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ export interface ToolExecutionApi<TDetails extends JsonValue = JsonValue> extend
|
|||
readonly registry: RegistrySnapshot;
|
||||
/** The calling conversation's agent, as the tool task's phase resolved it. */
|
||||
agent(context: Context): Promise<Agent>;
|
||||
/** `HarnessOptions.models`: the catalog, credentials, and request transforms generation uses. */
|
||||
readonly models: Models;
|
||||
/** Built by `HarnessOptions.env` for this call; `undefined` without an environment. */
|
||||
readonly env: ExecutionEnv | undefined;
|
||||
/**
|
||||
|
|
@ -605,6 +607,8 @@ export interface Harness extends Session {
|
|||
export interface HookApi extends DocumentReader {
|
||||
readonly taskId: TaskId;
|
||||
readonly conversationId: ConversationId;
|
||||
/** `HarnessOptions.models`. */
|
||||
readonly models: Models;
|
||||
memo<T extends JsonValue>(name: string, context: Context): Promise<T | undefined>;
|
||||
memo<T extends JsonValue>(name: string, candidate: T, context: Context): Promise<T>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,30 @@ describe("tool round", () => {
|
|||
await harness.close(context);
|
||||
});
|
||||
|
||||
// #10395
|
||||
it("gives tools and hooks the Harness's models", async () => {
|
||||
const setup = chatSetup();
|
||||
const seen: unknown[] = [];
|
||||
addTool(
|
||||
setup.registry,
|
||||
tool("echo", async (_args, api) => {
|
||||
seen.push(api.models);
|
||||
return { content: [] };
|
||||
}),
|
||||
);
|
||||
addHooks(setup.registry, ToolTask, {
|
||||
beforeTool: (_call, api) => {
|
||||
seen.push(api.models);
|
||||
return undefined;
|
||||
},
|
||||
});
|
||||
const { harness, status } = await run(setup, [calls(["echo", {}, "c1"]), DONE]);
|
||||
expect(status).toBe("done");
|
||||
expect(seen).toEqual([setup.models, setup.models]);
|
||||
expect(seen.every((models) => models === setup.models)).toBe(true);
|
||||
await harness.close(context);
|
||||
});
|
||||
|
||||
it("answers calls to tools the request did not offer without a task", async () => {
|
||||
const setup = chatSetup();
|
||||
addTool(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue