@caupulican/pi-adaptative 0.81.15 → 0.81.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/bundled-resources/runtimes/hf-transformers-openai-server.py +427 -0
  3. package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +14 -7
  4. package/dist/core/agent-session.d.ts +9 -3
  5. package/dist/core/agent-session.d.ts.map +1 -1
  6. package/dist/core/agent-session.js +92 -16
  7. package/dist/core/agent-session.js.map +1 -1
  8. package/dist/core/local-runtime-controller.d.ts +17 -9
  9. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  10. package/dist/core/local-runtime-controller.js +124 -20
  11. package/dist/core/local-runtime-controller.js.map +1 -1
  12. package/dist/core/models/adaptation-store.d.ts +2 -0
  13. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  14. package/dist/core/models/adaptation-store.js +4 -0
  15. package/dist/core/models/adaptation-store.js.map +1 -1
  16. package/dist/core/models/default-model-suggestions.d.ts +4 -4
  17. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  18. package/dist/core/models/default-model-suggestions.js +9 -0
  19. package/dist/core/models/default-model-suggestions.js.map +1 -1
  20. package/dist/core/models/local-registration.d.ts +12 -0
  21. package/dist/core/models/local-registration.d.ts.map +1 -1
  22. package/dist/core/models/local-registration.js +68 -0
  23. package/dist/core/models/local-registration.js.map +1 -1
  24. package/dist/core/models/local-runtime.d.ts +77 -1
  25. package/dist/core/models/local-runtime.d.ts.map +1 -1
  26. package/dist/core/models/local-runtime.js +295 -4
  27. package/dist/core/models/local-runtime.js.map +1 -1
  28. package/dist/core/models/model-ref.d.ts +4 -0
  29. package/dist/core/models/model-ref.d.ts.map +1 -1
  30. package/dist/core/models/model-ref.js +12 -3
  31. package/dist/core/models/model-ref.js.map +1 -1
  32. package/dist/core/tool-repair-health.d.ts.map +1 -1
  33. package/dist/core/tool-repair-health.js +2 -1
  34. package/dist/core/tool-repair-health.js.map +1 -1
  35. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  36. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  37. package/dist/modes/interactive/interactive-mode.js +4 -0
  38. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  39. package/dist/modes/interactive/local-model-commands.d.ts +3 -1
  40. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  41. package/dist/modes/interactive/local-model-commands.js +133 -19
  42. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  43. package/docs/models.md +19 -1
  44. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  45. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  46. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  47. package/examples/extensions/sandbox/package-lock.json +2 -2
  48. package/examples/extensions/sandbox/package.json +1 -1
  49. package/examples/extensions/with-deps/package-lock.json +2 -2
  50. package/examples/extensions/with-deps/package.json +1 -1
  51. package/npm-shrinkwrap.json +12 -12
  52. package/package.json +4 -4
@@ -1,4 +1,5 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFileSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
2
3
  import { basename, dirname, join } from "node:path";
3
4
  import { classifyFailure, compactToolResultDetailsForRetention, computeRetryDelayMs, createCustomMessage, DEFAULT_RETRY_POLICY, RetryController, sleepAbortable, withStreamIdleWatchdog, } from "@caupulican/pi-agent-core";
4
5
  import { calculateContextTokens, compact, createDeterministicCompaction, estimateContextTokens, getLatestCompactionEntry, prepareCompaction, runCompactionLoop, shouldCompact, } from "@caupulican/pi-agent-core/node";
@@ -60,12 +61,22 @@ const MODEL_ADAPTATION_REPAIR_THRESHOLD = 3;
60
61
  const TEXT_TOOL_PROTOCOL_VERSION = 1;
61
62
  const TEXT_TOOL_PROTOCOL_TRIALS_PER_VARIANT = 2;
62
63
  const TEXT_TOOL_PROTOCOL_PARSE_FAILURE_THRESHOLD = 3;
63
- const TEXT_TOOL_PROTOCOL_VARIANTS = ["tool-tag", "tool-call", "fenced-json"];
64
+ const TEXT_TOOL_PROTOCOL_VARIANTS = [
65
+ "tool-tag",
66
+ "tool-call",
67
+ "fenced-json",
68
+ "function-xml",
69
+ ];
64
70
  const TEXT_TOOL_PROTOCOL_ECHO_TOOL = {
65
71
  name: "echo",
66
72
  description: "Echo calibration data",
67
73
  parameters: Type.Object({ data: Type.String() }),
68
74
  };
75
+ const NATIVE_TOOL_PROBE_READ_TOOL = {
76
+ name: "read",
77
+ description: "Read file contents",
78
+ parameters: Type.Object({ path: Type.String() }),
79
+ };
69
80
  /** Test-only override of the stream-idle bounds. Read per-request by the wiring's resolver. */
70
81
  let streamIdleOptionsOverride;
71
82
  /**
@@ -841,18 +852,56 @@ export class AgentSession {
841
852
  messages: [{ role: "user", content: [{ type: "text", text: instruction }], timestamp: Date.now() }],
842
853
  };
843
854
  }
844
- _messageHasEchoProbe(message, token) {
845
- return message.content.some((block) => block.type === "toolCall" && block.name === "echo" && block.arguments.data === token);
855
+ _messageHasToolCallWithStringArgument(message, toolName, argName, argValue) {
856
+ return message.content.some((block) => {
857
+ if (block.type !== "toolCall" || block.name !== toolName)
858
+ return false;
859
+ const args = block.arguments;
860
+ return (typeof args === "object" &&
861
+ args !== null &&
862
+ !Array.isArray(args) &&
863
+ args[argName] === argValue);
864
+ });
846
865
  }
847
- async _runNativeToolProbeTrial(model, token) {
848
- const instruction = `Native tool-call capability probe. Use provider-native tool calling, not prose. ` +
866
+ _nativeToolProbeSystemPrompt(instruction) {
867
+ const base = (this.agent.state.systemPrompt ?? "").trim();
868
+ return base ? `${base}\n\n${instruction}` : instruction;
869
+ }
870
+ async _runNativeReadTaskProbeTrial(model, path) {
871
+ const instruction = `Native tool-call capability probe: task-scale read. Use provider-native tool calling, not prose. ` +
872
+ `Call read exactly once with path exactly "${path}".`;
873
+ const stream = await this._streamForToolProbe(model, {
874
+ systemPrompt: this._nativeToolProbeSystemPrompt(instruction),
875
+ messages: [{ role: "user", content: [{ type: "text", text: instruction }], timestamp: Date.now() }],
876
+ tools: [NATIVE_TOOL_PROBE_READ_TOOL],
877
+ }, { textToolCallProtocol: false, maxRetries: 0, temperature: 0, maxTokens: 768 });
878
+ return this._messageHasToolCallWithStringArgument(await stream.result(), "read", "path", path);
879
+ }
880
+ async _runNativeEchoToolProbeTrial(model, token) {
881
+ const instruction = `Native tool-call capability probe: echo-only. Use provider-native tool calling, not prose. ` +
849
882
  `Call echo with data exactly "${token}".`;
850
883
  const stream = await this._streamForToolProbe(model, {
851
- systemPrompt: instruction,
884
+ systemPrompt: this._nativeToolProbeSystemPrompt(instruction),
852
885
  messages: [{ role: "user", content: [{ type: "text", text: instruction }], timestamp: Date.now() }],
853
886
  tools: [TEXT_TOOL_PROTOCOL_ECHO_TOOL],
854
887
  }, { textToolCallProtocol: false, maxRetries: 0, temperature: 0, maxTokens: 256 });
855
- return this._messageHasEchoProbe(await stream.result(), token);
888
+ return this._messageHasToolCallWithStringArgument(await stream.result(), "echo", "data", token);
889
+ }
890
+ async _gradeNativeToolCallingForModel(model, token) {
891
+ const path = join(tmpdir(), `pi-native-probe-${process.pid}-${Date.now()}.txt`);
892
+ writeFileSync(path, token, "utf-8");
893
+ try {
894
+ const taskPassed = await this._runNativeReadTaskProbeTrial(model, path);
895
+ if (taskPassed)
896
+ return "task";
897
+ const echoPassed = await this._runNativeEchoToolProbeTrial(model, token);
898
+ if (echoPassed)
899
+ return "echo-only";
900
+ return "absent";
901
+ }
902
+ finally {
903
+ rmSync(path, { force: true });
904
+ }
856
905
  }
857
906
  async _runTextProtocolTrial(model, variant, token) {
858
907
  const stream = await this._streamForToolProbe(model, this._textProtocolCalibrationContext(variant, token), {
@@ -933,12 +982,17 @@ export class AgentSession {
933
982
  return `${model.provider}/${model.id}`;
934
983
  }
935
984
  _formatToolProbeReport(results) {
936
- const lines = ["Tool probe results:", "Model | Verdict | Variant | Diagnostic", "--- | --- | --- | ---"];
985
+ const lines = [
986
+ "Tool probe results:",
987
+ "Model | Verdict | Variant | Native grade | Diagnostic",
988
+ "--- | --- | --- | --- | ---",
989
+ ];
937
990
  for (const result of results) {
938
991
  lines.push([
939
992
  result.model,
940
993
  result.verdict,
941
994
  result.variant ?? "-",
995
+ result.nativeGrade ?? "-",
942
996
  result.diagnostic ? result.diagnostic.replace(/\s+/g, " ").slice(0, 160) : "-",
943
997
  ].join(" | "));
944
998
  }
@@ -950,12 +1004,23 @@ export class AgentSession {
950
1004
  async _probeToolCallingForModel(model) {
951
1005
  const modelKey = this._modelRef(model);
952
1006
  const probedAt = new Date().toISOString();
1007
+ let nativeGrade = "absent";
953
1008
  let diagnostic;
954
1009
  try {
955
- if (await this._runNativeToolProbeTrial(model, "pi-native-probe")) {
956
- this._storeToolProbe(modelKey, { version: TEXT_TOOL_PROTOCOL_VERSION, status: "native", probedAt });
957
- return { model: modelKey, verdict: "native" };
1010
+ nativeGrade = await this._gradeNativeToolCallingForModel(model, "pi-native-probe");
1011
+ if (nativeGrade === "task") {
1012
+ this._storeToolProbe(modelKey, {
1013
+ version: TEXT_TOOL_PROTOCOL_VERSION,
1014
+ status: "native",
1015
+ probedAt,
1016
+ nativeGrade,
1017
+ });
1018
+ return { model: modelKey, verdict: "native", nativeGrade };
958
1019
  }
1020
+ diagnostic =
1021
+ nativeGrade === "echo-only"
1022
+ ? "Native echo probe passed but task-scale read probe failed."
1023
+ : "Native task-scale read and echo probes did not produce provider-native tool calls.";
959
1024
  }
960
1025
  catch (error) {
961
1026
  diagnostic = error instanceof Error ? error.message : String(error);
@@ -968,16 +1033,24 @@ export class AgentSession {
968
1033
  status: "text-protocol",
969
1034
  probedAt: calibrated.calibratedAt,
970
1035
  variant: calibrated.variant,
1036
+ nativeGrade,
1037
+ diagnostic,
971
1038
  });
972
- return { model: modelKey, verdict: "text-protocol", variant: calibrated.variant };
1039
+ return { model: modelKey, verdict: "text-protocol", variant: calibrated.variant, nativeGrade, diagnostic };
973
1040
  }
974
- diagnostic ??= `Text protocol variants failed: ${calibrated.variantsTried.join(", ")}`;
1041
+ diagnostic = `${diagnostic ? `${diagnostic} ` : ""}Text protocol variants failed: ${calibrated.variantsTried.join(", ")}`;
975
1042
  }
976
1043
  catch (error) {
977
1044
  diagnostic = error instanceof Error ? error.message : String(error);
978
1045
  }
979
- this._storeToolProbe(modelKey, { version: TEXT_TOOL_PROTOCOL_VERSION, status: "none", probedAt, diagnostic });
980
- return { model: modelKey, verdict: "none", diagnostic };
1046
+ this._storeToolProbe(modelKey, {
1047
+ version: TEXT_TOOL_PROTOCOL_VERSION,
1048
+ status: "none",
1049
+ probedAt,
1050
+ nativeGrade,
1051
+ diagnostic,
1052
+ });
1053
+ return { model: modelKey, verdict: "none", nativeGrade, diagnostic };
981
1054
  }
982
1055
  async _resolveToolProbeModels(target) {
983
1056
  const trimmed = target?.trim();
@@ -1935,6 +2008,9 @@ export class AgentSession {
1935
2008
  getLocalRuntime(baseUrl) {
1936
2009
  return this._localRuntimeController.getLocalRuntime(baseUrl);
1937
2010
  }
2011
+ getTransformersRuntime(modelId, baseUrl) {
2012
+ return this._localRuntimeController.getTransformersRuntime(modelId, baseUrl);
2013
+ }
1938
2014
  /** models.json registers a local model's baseUrl as `<server>/v1` (OpenAI-compat); the runtime's
1939
2015
  * own health/boot endpoints are on the Ollama-native server root. Delegates to
1940
2016
  * {@link LocalRuntimeController}; kept here for `_warnIfManualModelChoiceIsRisky`'s own use. */