@ycodium-ai/agent-pi 0.0.0-stage → 0.2.3566
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.
- package/README.md +99 -2
- package/assets/icon.svg +1 -0
- package/assets/ui.js +66 -0
- package/dist/index.js +1388 -0
- package/locales/en.json +45 -0
- package/locales/zh-CN.json +42 -0
- package/package.json +76 -3
package/README.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ycodium-ai/agent-pi
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Run Pi in Ycodium with your own model API service. Choose Chat Completions,
|
|
4
|
+
OpenAI Responses or Anthropic Messages, then configure the API base URL, API key
|
|
5
|
+
and model ID in Settings → Providers when adding or editing a Pi
|
|
6
|
+
instance. The connection form is available on Web and Desktop; Mobile uses
|
|
7
|
+
instances configured on the connected machine.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
Install Pi 1.4.0 or newer on the machine running Ycodium:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install -g @earendil-works/pi-coding-agent
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Pi must be on that machine's `PATH`, or its executable path must be set under the
|
|
18
|
+
instance's advanced settings. Choose the request protocol supported by your service.
|
|
19
|
+
For Chat Completions or OpenAI Responses, supply the API base URL, usually ending
|
|
20
|
+
in `/v1`, without `/chat/completions` or `/responses`. For Anthropic Messages,
|
|
21
|
+
supply the service root or a base URL ending in `/v1`; the runtime resolves the
|
|
22
|
+
request route to `/v1/messages`. URLs must not contain embedded credentials,
|
|
23
|
+
query parameters or a fragment. The model ID must be accepted by that service. The instance exposes
|
|
24
|
+
that one configured model; its readiness check does not make a model request or
|
|
25
|
+
verify API credentials. The first request checks access to the service.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
The plugin ships with Ycodium. To restore or install the package explicitly:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
ycodium plugin add @ycodium-ai/agent-pi
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Disabling or uninstalling it stops the plugin's processes. Saved instance settings
|
|
36
|
+
and session files remain. Uninstalling a bundled plugin records the removal, so a
|
|
37
|
+
server restart does not restore it; reinstall the package to restore it.
|
|
38
|
+
|
|
39
|
+
## Connection and sessions
|
|
40
|
+
|
|
41
|
+
The form stores the API key as the sensitive `YCODIUM_PI_API_KEY` environment
|
|
42
|
+
variable. Existing keys are masked; leaving the masked field empty preserves the
|
|
43
|
+
saved key. Enter a new key to replace it. The URL and model are stored in the
|
|
44
|
+
instance's `apiBaseUrl` and `model` configuration fields. The optional `apiProtocol`
|
|
45
|
+
field selects `openai-completions`, `openai-responses` or `anthropic-messages`.
|
|
46
|
+
Connections without that field use Chat Completions. An unknown saved protocol
|
|
47
|
+
is shown as invalid and must be explicitly replaced. Advanced configurations
|
|
48
|
+
can also supply `YCODIUM_PI_API_BASE_URL`.
|
|
49
|
+
|
|
50
|
+
The plugin starts `pi --mode rpc` through Ycodium's managed process API. It
|
|
51
|
+
provides temporary model and MCP configuration, and enables Pi's built-in MCP and tool-search
|
|
52
|
+
extensions. MCP tools are discovered on demand rather than all advertised in the first request.
|
|
53
|
+
Native session files live in a directory specific
|
|
54
|
+
to the instance under `~/.pi/ycodium/`, unless a session directory is configured
|
|
55
|
+
under advanced settings. Keep that directory stable to resume existing sessions;
|
|
56
|
+
use a separate directory for each instance.
|
|
57
|
+
|
|
58
|
+
Pi creates its history file lazily. A thread stopped before its first prompt may have no saved
|
|
59
|
+
history and require a new thread. Missing saved history is reported as an error; the integration
|
|
60
|
+
does not silently replace it with an empty conversation.
|
|
61
|
+
|
|
62
|
+
Pi runs with full process permissions. It provides no sandbox or native per-tool
|
|
63
|
+
approval flow. Context compaction and steering use native RPC operations. This
|
|
64
|
+
integration does not offer OAuth, an auxiliary text-generation assistant,
|
|
65
|
+
mid-session model switching, inline image attachments, or a guarantee that an
|
|
66
|
+
interrupted tool's external side effects have stopped. MCP transports are stdio
|
|
67
|
+
and HTTP; legacy SSE is unsupported.
|
|
68
|
+
|
|
69
|
+
## Developing
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
vp run --filter @ycodium-ai/agent-pi test
|
|
73
|
+
vp run --filter @ycodium-ai/agent-pi typecheck
|
|
74
|
+
vp run --filter @ycodium-ai/agent-pi build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The build emits `dist/index.js` and `assets/ui.js`. The settings view uses the
|
|
78
|
+
public provider-settings extension, the host's React and its shared input
|
|
79
|
+
primitive. English and Simplified Chinese translations ship in `locales/`.
|
|
80
|
+
The icon is a generic Pi symbol drawn for this package.
|
|
81
|
+
|
|
82
|
+
To include the native RPC integration test, set `YCODIUM_PI_TEST_CLI_ENTRY` to the absolute path
|
|
83
|
+
of an installed Pi package's `dist/bundle/cli.js` before running the package tests. The test uses
|
|
84
|
+
local model and MCP fixtures only; it makes no external model requests. Without that variable,
|
|
85
|
+
the native integration test is skipped.
|
|
86
|
+
|
|
87
|
+
Every opt-in native CLI launch passes through the standard wire recorder. Tests print the private
|
|
88
|
+
temporary directory containing its raw recordings; those files require scrubbing before sharing.
|
|
89
|
+
Real-model recording uses the web UI through
|
|
90
|
+
[`scripts/ui-probe/pi-recording.ts`](../../scripts/ui-probe/pi-recording.ts). The
|
|
91
|
+
[recording runbook](../../docs/operations/recording-real-sessions.md#pi真实界面录制与导出) owns setup,
|
|
92
|
+
credential handling and scrubbed export. The four real UI recording assets in the
|
|
93
|
+
[scenario manifest](test/recording-scenarios.json) cover a plain turn, resumed history, a native tool
|
|
94
|
+
call and genuine Anthropic thinking. They were recorded through the real web UI with Pi 1.4.0;
|
|
95
|
+
provenance, scrub and replay tests read the saved protocol files. Approval is explicitly unsupported
|
|
96
|
+
because Pi has no native per-tool approval flow.
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
UNLICENSED.
|
package/assets/icon.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><rect width="32" height="32" rx="7" fill="#e07a30"/><path d="M7 10h19v3h-4v10c0 1 .5 2 2 2h2v3h-3c-3 0-5-2-5-5V13h-5v8c0 4-2 6-5 7l-1-3c2-1 3-2 3-5v-7H7z" fill="#fff"/></svg>
|
package/assets/ui.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var C=window.__ycodiumPluginHost.modules?.["@ycodium-ai/plugin-api/provider-settings"];if(!C)throw new Error("This plugin needs a newer Ycodium app. Update the app.");var{PROVIDER_SETTINGS_VIEW_CAPABILITY:_,accountDirectoryCandidates:G,accountDirectorySlug:W,accountProbeHasSignedInAccount:q,allocateAccountDirectory:J,providerInstanceAccountPaths:Q}=C;var j=window.__ycodiumPluginHost.react;var{Activity:Z,Children:ee,Component:te,Fragment:oe,Profiler:ne,PureComponent:re,StrictMode:ie,Suspense:ae,__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE:se,__COMPILER_RUNTIME:ce,act:pe,cache:le,cacheSignal:ue,captureOwnerStack:de,cloneElement:me,createContext:b,createElement:w,createRef:ge,forwardRef:fe,isValidElement:Pe,lazy:ye,memo:we,startTransition:ve,unstable_useCacheRefresh:he,use:Se,useActionState:Ie,useCallback:xe,useContext:E,useDebugValue:Te,useDeferredValue:Ce,useEffect:A,useEffectEvent:_e,useId:R,useImperativeHandle:be,useInsertionEffect:Ee,useLayoutEffect:Ae,useMemo:Re,useOptimistic:Ne,useReducer:Ue,useRef:ke,useState:Oe,useSyncExternalStore:Le,useTransition:Be,version:De}=j;var N=b(null),U=N.Provider;function l(){let t=E(N);if(t===null)throw new Error("Pi UI has not been registered.");return t}var v=["openai-completions","openai-responses","anthropic-messages"],k="openai-completions";function u(t){return v.some(e=>e===t)}var h="connection",f="YCODIUM_PI_API_KEY";function S(t){try{let e=new URL(t.trim());return(e.protocol==="http:"||e.protocol==="https:")&&!e.username&&!e.password&&!e.search&&!e.hash}catch{return!1}}function O(t){let{apiProtocol:e,apiBaseUrl:i,model:p}=t.config,n=t.environment.find(a=>a.name===f);return(e===void 0||u(e))&&typeof i=="string"&&S(i)&&typeof p=="string"&&p.trim().length>0&&n!==void 0&&(n.valueRedacted===!0||n.value.trim().length>0)}function L(t,e){let i=t.trim();return!i&&e?{}:{environment:[{name:f,value:i,sensitive:!0}]}}function I(t){return w(l().ui.DraftInput,t)}function d(t){return(e=>w(l().ui[t],{...e,className:`ycodium-pi-ui ${typeof e.className=="string"?e.className:""}`}))}var B=d("Select"),D=d("SelectTrigger"),H=d("SelectPopup"),K=d("SelectItem"),V=d("SelectValue");function $(){let t=l().i18n.usePluginTranslation();return{t:(e,i)=>t(e,i)}}var{jsx:r,jsxs:c,Fragment:qe}=window.__ycodiumPluginHost.jsxRuntime;function M({instance:t,readOnly:e,onReport:i,onChange:p}){let{t:n}=$(),a=R(),P=O(t),x=P?n("connectionNotVerified"):void 0;A(()=>i({complete:P,hidesSignIn:!0,signInAfterAdd:!1,notice:x}),[P,x,i]);let T=t.environment.find(o=>o.name===f),m=T?.valueRedacted===!0,y=t.config.apiProtocol,s=y===void 0?k:u(y)?y:null;return c("div",{className:"ycodium-pi-ui grid min-w-0 gap-4",children:[c("div",{className:"grid min-w-0 gap-1",children:[r("span",{id:`${a}-protocol-label`,className:"text-control-4 font-medium",children:n("form.apiProtocol.title")}),c(B,{value:s,disabled:e,onValueChange:o=>{!e&&u(o)&&p({config:{apiProtocol:o}})},children:[r(D,{"aria-labelledby":`${a}-protocol-label`,"aria-describedby":`${a}-protocol-description`,"aria-invalid":s===null,children:r(V,{children:n(s===null?"connection.protocolUnknown":`connection.protocols.${s}`)})}),r(H,{children:v.map(o=>r(K,{value:o,children:n(`connection.protocols.${o}`)},o))})]}),r("span",{id:`${a}-protocol-description`,className:s===null?"text-ui-sm text-destructive-foreground":"text-ui-sm text-muted-foreground",children:n(s===null?"connection.invalidProtocol":"form.apiProtocol.description")})]}),["apiBaseUrl","model"].map(o=>c("label",{className:"grid min-w-0 gap-1",children:[r("span",{className:"text-control-4 font-medium",children:n(`form.${o}.title`)}),r(I,{value:typeof t.config[o]=="string"?t.config[o]:"",onCommit:g=>{e||p({config:{[o]:g.trim()}})},validate:g=>(o==="apiBaseUrl"?S(g):g.trim().length>0)?null:n(o==="apiBaseUrl"?"connection.invalidUrl":"connection.modelRequired"),disabled:e,autoComplete:"off",spellCheck:!1,"aria-label":n(`form.${o}.title`),"aria-describedby":`${a}-${o}-description`}),r("span",{id:`${a}-${o}-description`,className:"text-ui-sm text-muted-foreground",children:n(o==="apiBaseUrl"&&s!==null?`connection.baseUrlGuidance.${s}`:`form.${o}.description`)})]},o)),c("label",{className:"grid min-w-0 gap-1",children:[r("span",{className:"text-control-4 font-medium",children:n("connection.key")}),r(I,{type:"password",autoComplete:"off",spellCheck:!1,disabled:e,"aria-label":n("connection.key"),value:m?"":T?.value??"",placeholder:m?n("connection.stored"):void 0,validate:o=>m||o.trim()?null:n("connection.keyRequired"),onCommit:o=>{e||p(L(o,m))}})]})]})}var Y=`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties, theme, base, components, utilities;
|
|
3
|
+
@layer properties;
|
|
4
|
+
@layer utilities {
|
|
5
|
+
@scope (.ycodium-pi-ui) {
|
|
6
|
+
.relative:where(:scope, *) {
|
|
7
|
+
position: relative;
|
|
8
|
+
}
|
|
9
|
+
.container:where(:scope, *) {
|
|
10
|
+
width: 100%;
|
|
11
|
+
@media (width >= 40rem) {
|
|
12
|
+
max-width: 40rem;
|
|
13
|
+
}
|
|
14
|
+
@media (width >= 48rem) {
|
|
15
|
+
max-width: 48rem;
|
|
16
|
+
}
|
|
17
|
+
@media (width >= 64rem) {
|
|
18
|
+
max-width: 64rem;
|
|
19
|
+
}
|
|
20
|
+
@media (width >= 80rem) {
|
|
21
|
+
max-width: 80rem;
|
|
22
|
+
}
|
|
23
|
+
@media (width >= 96rem) {
|
|
24
|
+
max-width: 96rem;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
.grid:where(:scope, *) {
|
|
28
|
+
display: grid;
|
|
29
|
+
}
|
|
30
|
+
.min-w-0:where(:scope, *) {
|
|
31
|
+
min-width: calc(var(--spacing, 0.25rem) * 0);
|
|
32
|
+
}
|
|
33
|
+
.gap-1:where(:scope, *) {
|
|
34
|
+
gap: calc(var(--spacing, 0.25rem) * 1);
|
|
35
|
+
}
|
|
36
|
+
.gap-4:where(:scope, *) {
|
|
37
|
+
gap: calc(var(--spacing, 0.25rem) * 4);
|
|
38
|
+
}
|
|
39
|
+
.text-control-4:where(:scope, *) {
|
|
40
|
+
font-size: var(--control-text-4);
|
|
41
|
+
line-height: var(--tw-leading, var(--control-leading-4));
|
|
42
|
+
}
|
|
43
|
+
.text-ui-sm:where(:scope, *) {
|
|
44
|
+
font-size: var(--ui-text-sm);
|
|
45
|
+
line-height: var(--tw-leading, var(--ui-leading-sm));
|
|
46
|
+
}
|
|
47
|
+
.font-medium:where(:scope, *) {
|
|
48
|
+
--tw-font-weight: var(--font-weight-medium, 500);
|
|
49
|
+
font-weight: var(--font-weight-medium, 500);
|
|
50
|
+
}
|
|
51
|
+
.text-destructive-foreground:where(:scope, *) {
|
|
52
|
+
color: var(--destructive-foreground);
|
|
53
|
+
}
|
|
54
|
+
.text-muted-foreground:where(:scope, *) {
|
|
55
|
+
color: var(--contrast-muted-foreground);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
@layer properties {
|
|
60
|
+
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
|
61
|
+
*, ::before, ::after, ::backdrop {
|
|
62
|
+
--tw-font-weight: initial;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
`;function F(t){let e=i=>c(U,{value:t,children:[r("style",{children:Y}),r(M,{...i})]});return{pages:{},panels:{},views:{[h]:e},viewCapabilities:{[h]:[_]}}}export{F as default};
|